diff options
author | Chris Lattner <sabre@nondot.org> | 2004-07-21 20:14:10 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2004-07-21 20:14:10 +0000 |
commit | f0cacc0ae7f5be5aed9d4c1eb36be0d686ad8880 (patch) | |
tree | 4991252d07946e05b47abcd4dc56283cf6e49114 | |
parent | 97a296f743c3cb78ae106a8e4800a5daa0ca6fc9 (diff) | |
download | external_llvm-f0cacc0ae7f5be5aed9d4c1eb36be0d686ad8880.zip external_llvm-f0cacc0ae7f5be5aed9d4c1eb36be0d686ad8880.tar.gz external_llvm-f0cacc0ae7f5be5aed9d4c1eb36be0d686ad8880.tar.bz2 |
* Further cleanup.
* Test for whether bits are shifted out during the optzn.
If so, the fold is illegal, though it can be handled explicitly for setne/seteq
This fixes the miscompilation of 254.gap last night, which was a latent bug
exposed by other optimizer improvements.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@15085 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Transforms/Scalar/InstructionCombining.cpp | 36 |
1 files changed, 27 insertions, 9 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index 61f7396..f4910e4 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -1471,22 +1471,40 @@ Instruction *InstCombiner::visitSetCondInst(BinaryOperator &I) { if (ShAmt) { bool CanFold = Shift->getOpcode() != Instruction::Shr || Shift->getType()->isUnsigned(); - if (!CanFold && + if (!CanFold) { // To test for the bad case of the signed shr, see if any // of the bits shifted in could be tested after the mask. - ConstantExpr::getAnd(ConstantExpr::getShl(ConstantInt::getAllOnesValue(Ty), ConstantUInt::get(Type::UByteTy, Ty->getPrimitiveSize()*8-ShAmt->getValue())), AndCST)->isNullValue()) { - CanFold = true; + Constant *OShAmt = ConstantUInt::get(Type::UByteTy, + Ty->getPrimitiveSize()*8-ShAmt->getValue()); + Constant *ShVal = + ConstantExpr::getShl(ConstantInt::getAllOnesValue(Ty), OShAmt); + if (ConstantExpr::getAnd(ShVal, AndCST)->isNullValue()) + CanFold = true; } if (CanFold) { unsigned ShiftOp = Shift->getOpcode() == Instruction::Shl ? Instruction::Shr : Instruction::Shl; - I.setOperand(1, ConstantExpr::get(ShiftOp, CI, ShAmt)); - LHSI->setOperand(1,ConstantExpr::get(ShiftOp,AndCST,ShAmt)); - LHSI->setOperand(0, Shift->getOperand(0)); - WorkList.push_back(Shift); // Shift is dead. - AddUsesToWorkList(I); - return &I; + Constant *NewCst = ConstantExpr::get(ShiftOp, CI, ShAmt); + + // Check to see if we are shifting out any of the bits being + // compared. + if (ConstantExpr::get(Shift->getOpcode(), NewCst, ShAmt) != CI){ + // If we shifted bits out, the fold is not going to work out. + // As a special case, check to see if this means that the + // result is always true or false now. + if (I.getOpcode() == Instruction::SetEQ) + return ReplaceInstUsesWith(I, ConstantBool::False); + if (I.getOpcode() == Instruction::SetNE) + return ReplaceInstUsesWith(I, ConstantBool::True); + } else { + I.setOperand(1, NewCst); + LHSI->setOperand(1, ConstantExpr::get(ShiftOp, AndCST,ShAmt)); + LHSI->setOperand(0, Shift->getOperand(0)); + WorkList.push_back(Shift); // Shift is dead. + AddUsesToWorkList(I); + return &I; + } } } } |