aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-03-20 22:41:15 +0000
committerChris Lattner <sabre@nondot.org>2009-03-20 22:41:15 +0000
commit344c7c5cc4dd76e3f538dcc3d4f487be0b6ca067 (patch)
treec11e8bf54bfc283e12675a7217fb9dc97c276038 /lib
parentab6b226978644c438a3a7768a06dcd48509d000c (diff)
downloadexternal_llvm-344c7c5cc4dd76e3f538dcc3d4f487be0b6ca067.zip
external_llvm-344c7c5cc4dd76e3f538dcc3d4f487be0b6ca067.tar.gz
external_llvm-344c7c5cc4dd76e3f538dcc3d4f487be0b6ca067.tar.bz2
Fix instcombine to not introduce undefined shifts when merging two
shifts together. This fixes PR3851. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@67411 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Transforms/Scalar/InstructionCombining.cpp16
1 files changed, 14 insertions, 2 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp
index 10671cd..6af0afd 100644
--- a/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -7307,22 +7307,34 @@ Instruction *InstCombiner::FoldShiftByConstant(Value *Op0, ConstantInt *Op1,
Value *X = ShiftOp->getOperand(0);
uint32_t AmtSum = ShiftAmt1+ShiftAmt2; // Fold into one big shift.
- if (AmtSum > TypeBits)
- AmtSum = TypeBits;
const IntegerType *Ty = cast<IntegerType>(I.getType());
// Check for (X << c1) << c2 and (X >> c1) >> c2
if (I.getOpcode() == ShiftOp->getOpcode()) {
+ // If this is oversized composite shift, then unsigned shifts get 0, ashr
+ // saturates.
+ if (AmtSum >= TypeBits) {
+ if (I.getOpcode() != Instruction::AShr)
+ return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
+ AmtSum = TypeBits-1; // Saturate to 31 for i32 ashr.
+ }
+
return BinaryOperator::Create(I.getOpcode(), X,
ConstantInt::get(Ty, AmtSum));
} else if (ShiftOp->getOpcode() == Instruction::LShr &&
I.getOpcode() == Instruction::AShr) {
+ if (AmtSum >= TypeBits)
+ return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
+
// ((X >>u C1) >>s C2) -> (X >>u (C1+C2)) since C1 != 0.
return BinaryOperator::CreateLShr(X, ConstantInt::get(Ty, AmtSum));
} else if (ShiftOp->getOpcode() == Instruction::AShr &&
I.getOpcode() == Instruction::LShr) {
// ((X >>s C1) >>u C2) -> ((X >>s (C1+C2)) & mask) since C1 != 0.
+ if (AmtSum >= TypeBits)
+ AmtSum = TypeBits-1;
+
Instruction *Shift =
BinaryOperator::CreateAShr(X, ConstantInt::get(Ty, AmtSum));
InsertNewInstBefore(Shift, I);