diff options
author | Chris Lattner <sabre@nondot.org> | 2006-01-07 01:32:28 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2006-01-07 01:32:28 +0000 |
commit | e8d56c536d0a8a73aa31da79079f9f2855d1a153 (patch) | |
tree | 1975c68a2d9b057501baf68f5a34c2e87877015e /lib/Transforms | |
parent | 948f343a2f3ec8fc75401ea2465262dd7f43edf7 (diff) | |
download | external_llvm-e8d56c536d0a8a73aa31da79079f9f2855d1a153.zip external_llvm-e8d56c536d0a8a73aa31da79079f9f2855d1a153.tar.gz external_llvm-e8d56c536d0a8a73aa31da79079f9f2855d1a153.tar.bz2 |
fix some 176.gcc miscompilation from my previous patch.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@25137 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms')
-rw-r--r-- | lib/Transforms/Scalar/InstructionCombining.cpp | 40 |
1 files changed, 33 insertions, 7 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index 179d695..1f59f4c 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -3669,7 +3669,7 @@ Instruction *InstCombiner::FoldShiftByConstant(Value *Op0, ConstantUInt *Op1, // is a noop cast between the two. bool isShiftOfLeftShift = ShiftOp->getOpcode() == Instruction::Shl; bool isShiftOfSignedShift = ShiftOp->getType()->isSigned(); - bool isShiftOfUnsignedShift = !isSignedShift; + bool isShiftOfUnsignedShift = !isShiftOfSignedShift; ConstantUInt *ShiftAmt1C = cast<ConstantUInt>(ShiftOp->getOperand(1)); @@ -3704,7 +3704,7 @@ Instruction *InstCombiner::FoldShiftByConstant(Value *Op0, ConstantUInt *Op1, if (isLeftShift) C = ConstantExpr::getShl(C, ShiftAmt1C); else - C = ConstantExpr::getShr(C, ShiftAmt1C); // must be an unsigned shr. + C = ConstantExpr::getUShr(C, ShiftAmt1C); Value *Op = ShiftOp->getOperand(0); if (isShiftOfSignedShift != isSignedShift) @@ -3715,17 +3715,43 @@ Instruction *InstCombiner::FoldShiftByConstant(Value *Op0, ConstantUInt *Op1, InsertNewInstBefore(Mask, I); // Figure out what flavor of shift we should use... - if (ShiftAmt1 == ShiftAmt2) + if (ShiftAmt1 == ShiftAmt2) { return ReplaceInstUsesWith(I, Mask); // (A << c) >> c === A & c2 - else if (ShiftAmt1 < ShiftAmt2) { + } else if (ShiftAmt1 < ShiftAmt2) { return new ShiftInst(I.getOpcode(), Mask, ConstantUInt::get(Type::UByteTy, ShiftAmt2-ShiftAmt1)); - } else { - return new ShiftInst(ShiftOp->getOpcode(), Mask, + } else if (isShiftOfUnsignedShift || isShiftOfLeftShift) { + if (isShiftOfUnsignedShift && !isShiftOfLeftShift && isSignedShift) { + // Make sure to emit an unsigned shift right, not a signed one. + Mask = InsertNewInstBefore(new CastInst(Mask, + Mask->getType()->getUnsignedVersion(), + Op->getName()), I); + Mask = new ShiftInst(Instruction::Shr, Mask, ConstantUInt::get(Type::UByteTy, ShiftAmt1-ShiftAmt2)); + InsertNewInstBefore(Mask, I); + return new CastInst(Mask, I.getType()); + } else { + return new ShiftInst(ShiftOp->getOpcode(), Mask, + ConstantUInt::get(Type::UByteTy, ShiftAmt1-ShiftAmt2)); + } + } else { + // (X >>s C1) << C2 where C1 > C2 === (X >>s (C1-C2)) & mask + Op = InsertNewInstBefore(new CastInst(Mask, + I.getType()->getSignedVersion(), + Mask->getName()), I); + Instruction *Shift = + new ShiftInst(ShiftOp->getOpcode(), Op, + ConstantUInt::get(Type::UByteTy, ShiftAmt1-ShiftAmt2)); + InsertNewInstBefore(Shift, I); + + C = ConstantIntegral::getAllOnesValue(Shift->getType()); + C = ConstantExpr::getShl(C, Op1); + Mask = BinaryOperator::createAnd(Shift, C, Op->getName()+".mask"); + InsertNewInstBefore(Mask, I); + return new CastInst(Mask, I.getType()); } } else { - // We can handle signed (X << C1) >> C2 if it's a sign extend. In + // We can handle signed (X << C1) >>s C2 if it's a sign extend. In // this case, C1 == C2 and C1 is 8, 16, or 32. if (ShiftAmt1 == ShiftAmt2) { const Type *SExtType = 0; |