From f0cacc0ae7f5be5aed9d4c1eb36be0d686ad8880 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Wed, 21 Jul 2004 20:14:10 +0000 Subject: [PATCH] * 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 --- .../Scalar/InstructionCombining.cpp | 36 ++++++++++++++----- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index 61f73961089..f4910e4cc3d 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; + } } } } -- 2.34.1