Move code out of indentation one level to make it easier to read.

Disable the xform for < > cases.  It turns out that the following is being
miscompiled:

bool %test(sbyte %S) {
        %T = cast sbyte %S to uint
        %V = setgt uint %T, 255
        ret bool %V
}


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@19628 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2005-01-17 03:20:02 +00:00
parent 7ece380440
commit b352fa5853

View File

@ -2438,13 +2438,11 @@ Instruction *InstCombiner::visitSetCondInst(BinaryOperator &I) {
break; break;
// (setcc (cast X to larger), CI) // (setcc (cast X to larger), CI)
case Instruction::Cast: { case Instruction::Cast:
Instruction* replacement = if (Instruction *R =
visitSetCondInstWithCastAndConstant(I,cast<CastInst>(LHSI),CI); visitSetCondInstWithCastAndConstant(I,cast<CastInst>(LHSI),CI))
if (replacement) return R;
return replacement;
break; break;
}
case Instruction::Shl: // (setcc (shl X, ShAmt), CI) case Instruction::Shl: // (setcc (shl X, ShAmt), CI)
if (ConstantUInt *ShAmt = dyn_cast<ConstantUInt>(LHSI->getOperand(1))) { if (ConstantUInt *ShAmt = dyn_cast<ConstantUInt>(LHSI->getOperand(1))) {
@ -2919,61 +2917,67 @@ InstCombiner::visitSetCondInstWithCastAndConstant(BinaryOperator&I,
ConstantInt* CI) { ConstantInt* CI) {
const Type *SrcTy = LHSI->getOperand(0)->getType(); const Type *SrcTy = LHSI->getOperand(0)->getType();
const Type *DestTy = LHSI->getType(); const Type *DestTy = LHSI->getType();
if (SrcTy->isIntegral() && DestTy->isIntegral()) { if (!SrcTy->isIntegral() || !DestTy->isIntegral())
unsigned SrcBits = SrcTy->getPrimitiveSize()*8; return 0;
unsigned DestBits = DestTy->getPrimitiveSize()*8;
if (SrcTy == Type::BoolTy) unsigned SrcBits = SrcTy->getPrimitiveSize()*8;
SrcBits = 1; unsigned DestBits = DestTy->getPrimitiveSize()*8;
if (DestTy == Type::BoolTy) if (SrcTy == Type::BoolTy)
DestBits = 1; SrcBits = 1;
if (SrcBits < DestBits) { if (DestTy == Type::BoolTy)
// There are fewer bits in the source of the cast than in the result DestBits = 1;
// of the cast. Any other case doesn't matter because the constant if (SrcBits < DestBits) {
// value won't have changed due to sign extension. // There are fewer bits in the source of the cast than in the result
Constant *NewCst = ConstantExpr::getCast(CI, SrcTy); // of the cast. Any other case doesn't matter because the constant
if (ConstantExpr::getCast(NewCst, DestTy) == CI) { // value won't have changed due to sign extension.
// The constant value operand of the setCC before and after a Constant *NewCst = ConstantExpr::getCast(CI, SrcTy);
// cast to the source type of the cast instruction is the same if (ConstantExpr::getCast(NewCst, DestTy) == CI) {
// value, so we just replace with the same setcc opcode, but // The constant value operand of the setCC before and after a
// using the source value compared to the constant casted to the // cast to the source type of the cast instruction is the same
// source type. // value, so we just replace with the same setcc opcode, but
if (SrcTy->isSigned() && DestTy->isUnsigned()) { // using the source value compared to the constant casted to the
CastInst* Cst = new CastInst(LHSI->getOperand(0), // source type.
SrcTy->getUnsignedVersion(), LHSI->getName()); if (SrcTy->isSigned() && DestTy->isUnsigned()) {
InsertNewInstBefore(Cst,I); CastInst* Cst = new CastInst(LHSI->getOperand(0),
return new SetCondInst(I.getOpcode(), Cst, SrcTy->getUnsignedVersion(),
ConstantExpr::getCast(CI, SrcTy->getUnsignedVersion())); LHSI->getName());
} InsertNewInstBefore(Cst,I);
return new SetCondInst(I.getOpcode(), LHSI->getOperand(0),NewCst); return new SetCondInst(I.getOpcode(), Cst,
} ConstantExpr::getCast(CI,
// The constant value before and after a cast to the source type SrcTy->getUnsignedVersion()));
// is different, so various cases are possible depending on the
// opcode and the signs of the types involved in the cast.
switch (I.getOpcode()) {
case Instruction::SetLT: {
Constant* Max = ConstantIntegral::getMaxValue(SrcTy);
Max = ConstantExpr::getCast(Max, DestTy);
return ReplaceInstUsesWith(I, ConstantExpr::getSetLT(Max, CI));
}
case Instruction::SetGT: {
Constant* Min = ConstantIntegral::getMinValue(SrcTy);
Min = ConstantExpr::getCast(Min, DestTy);
return ReplaceInstUsesWith(I, ConstantExpr::getSetGT(Min, CI));
}
case Instruction::SetEQ:
// We're looking for equality, and we know the values are not
// equal so replace with constant False.
return ReplaceInstUsesWith(I, ConstantBool::False);
case Instruction::SetNE:
// We're testing for inequality, and we know the values are not
// equal so replace with constant True.
return ReplaceInstUsesWith(I, ConstantBool::True);
case Instruction::SetLE:
case Instruction::SetGE:
assert(!"SetLE and SetGE should be handled elsewhere");
default:
assert(!"unknown integer comparison");
} }
return new SetCondInst(I.getOpcode(), LHSI->getOperand(0),NewCst);
}
// The constant value before and after a cast to the source type
// is different, so various cases are possible depending on the
// opcode and the signs of the types involved in the cast.
switch (I.getOpcode()) {
case Instruction::SetLT: {
return 0;
Constant* Max = ConstantIntegral::getMaxValue(SrcTy);
Max = ConstantExpr::getCast(Max, DestTy);
return ReplaceInstUsesWith(I, ConstantExpr::getSetLT(Max, CI));
}
case Instruction::SetGT: {
return 0; // FIXME! RENABLE. This breaks for (cast sbyte to uint) > 255
Constant* Min = ConstantIntegral::getMinValue(SrcTy);
Min = ConstantExpr::getCast(Min, DestTy);
return ReplaceInstUsesWith(I, ConstantExpr::getSetGT(Min, CI));
}
case Instruction::SetEQ:
// We're looking for equality, and we know the values are not
// equal so replace with constant False.
return ReplaceInstUsesWith(I, ConstantBool::False);
case Instruction::SetNE:
// We're testing for inequality, and we know the values are not
// equal so replace with constant True.
return ReplaceInstUsesWith(I, ConstantBool::True);
case Instruction::SetLE:
case Instruction::SetGE:
assert(0 && "SetLE and SetGE should be handled elsewhere");
default:
assert(0 && "unknown integer comparison");
} }
} }
return 0; return 0;