aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Transforms
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2006-01-07 01:32:28 +0000
committerChris Lattner <sabre@nondot.org>2006-01-07 01:32:28 +0000
commite8d56c536d0a8a73aa31da79079f9f2855d1a153 (patch)
tree1975c68a2d9b057501baf68f5a34c2e87877015e /lib/Transforms
parent948f343a2f3ec8fc75401ea2465262dd7f43edf7 (diff)
downloadexternal_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.cpp40
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;