OSDN Git Service

Make sure both operands have binary instructions have the same type.
authorEvan Cheng <evan.cheng@apple.com>
Wed, 22 Apr 2009 23:39:28 +0000 (23:39 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Wed, 22 Apr 2009 23:39:28 +0000 (23:39 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@69844 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/IndVarSimplify.cpp
test/Transforms/IndVarSimplify/2009-04-22-IndvarCrash.ll

index 1dd84b1..63ef021 100644 (file)
@@ -751,11 +751,14 @@ bool IndVarSimplify::runOnLoop(Loop *L, LPPassManager &LPM) {
             // We've determined this is (i+constant) and it won't overflow.
             if (isa<SExtInst>(UInst->use_begin())) {
               SExtInst* oldSext = dyn_cast<SExtInst>(UInst->use_begin());
+              uint64_t truncSize = oldSext->getType()->getPrimitiveSizeInBits();
               Value *TruncIndVar = getSignExtendedTruncVar(AR, SE, LargestType,
                                                 L, oldSext->getType(), Rewriter,
                                                 InsertPt);
-              APInt APcopy = APInt(AddRHS->getValue());
-              ConstantInt* newAddRHS =ConstantInt::get(APcopy.sext(newBitSize));
+              APInt APnewAddRHS = APInt(AddRHS->getValue()).sext(newBitSize);
+              if (newBitSize > truncSize)
+                APnewAddRHS = APnewAddRHS.trunc(truncSize);
+              ConstantInt* newAddRHS =ConstantInt::get(APnewAddRHS);
               Value *NewAdd = 
                     BinaryOperator::CreateAdd(TruncIndVar, newAddRHS,
                                               UInst->getName()+".nosex", UInst);
@@ -779,18 +782,21 @@ bool IndVarSimplify::runOnLoop(Loop *L, LPPassManager &LPM) {
           if (!RHS->getValue().isNegative()) {
             uint64_t newBitSize = LargestType->getPrimitiveSizeInBits();
             SExtInst* oldSext = dyn_cast<SExtInst>(UInst->use_begin());
+            uint64_t truncSize = oldSext->getType()->getPrimitiveSizeInBits();
             Value *TruncIndVar = getSignExtendedTruncVar(AR, SE, LargestType,
                                               L, oldSext->getType(), Rewriter,
                                               InsertPt);
-            APInt APcopy = APInt(RHS->getValue());
-            ConstantInt* newRHS =ConstantInt::get(APcopy.sext(newBitSize));
-            Value *NewAdd = 
-                  BinaryOperator::CreateOr(TruncIndVar, newRHS,
+            APInt APnewOrRHS = APInt(RHS->getValue()).sext(newBitSize);
+            if (newBitSize > truncSize)
+              APnewOrRHS = APnewOrRHS.trunc(truncSize);
+            ConstantInt* newOrRHS =ConstantInt::get(APnewOrRHS);
+            Value *NewOr = 
+                  BinaryOperator::CreateOr(TruncIndVar, newOrRHS,
                                             UInst->getName()+".nosex", UInst);
             for (Value::use_iterator UI2 = UInst->use_begin(), 
                   UE2 = UInst->use_end(); UI2 != UE2; ++UI2) {
               Instruction *II = dyn_cast<Instruction>(UI2);
-              II->replaceAllUsesWith(NewAdd);
+              II->replaceAllUsesWith(NewOr);
               DeadInsts.insert(II);
             }
             DeadInsts.insert(UInst);
@@ -814,10 +820,13 @@ bool IndVarSimplify::runOnLoop(Loop *L, LPPassManager &LPM) {
           uint64_t newBitSize = LargestType->getPrimitiveSizeInBits();
           ConstantInt* AndRHS = dyn_cast<ConstantInt>(UInst->getOperand(1));
           ZExtInst* oldZext = dyn_cast<ZExtInst>(UInst->use_begin());
+          uint64_t truncSize = oldZext->getType()->getPrimitiveSizeInBits();
           Value *TruncIndVar = getSignExtendedTruncVar(AR, SE, LargestType,
                                   L, oldZext->getType(), Rewriter, InsertPt);
-          APInt APcopy = APInt(AndRHS->getValue());
-          ConstantInt* newAndRHS = ConstantInt::get(APcopy.zext(newBitSize));
+          APInt APnewAndRHS = APInt(AndRHS->getValue()).zext(newBitSize);
+          if (newBitSize > truncSize)
+            APnewAndRHS = APnewAndRHS.trunc(truncSize);
+          ConstantInt* newAndRHS = ConstantInt::get(APnewAndRHS);
           Value *NewAnd = 
                 BinaryOperator::CreateAnd(TruncIndVar, newAndRHS,
                                           UInst->getName()+".nozex", UInst);
@@ -847,11 +856,14 @@ bool IndVarSimplify::runOnLoop(Loop *L, LPPassManager &LPM) {
               allUsesAreSameTyped(Instruction::ZExt, UInst2) &&
               isa<ConstantInt>(UInst2->getOperand(1))) {
             ZExtInst* oldZext = dyn_cast<ZExtInst>(UInst2->use_begin());
+            uint64_t truncSize = oldZext->getType()->getPrimitiveSizeInBits();
             Value *TruncIndVar = getSignExtendedTruncVar(AR, SE, LargestType,
                                     L, oldZext->getType(), Rewriter, InsertPt);
             ConstantInt* AndRHS = dyn_cast<ConstantInt>(UInst2->getOperand(1));
-            APInt APcopy = APInt(AddRHS->getValue());
-            ConstantInt* newAddRHS = ConstantInt::get(APcopy.zext(newBitSize));
+            APInt APnewAddRHS = APInt(AddRHS->getValue()).zext(newBitSize);
+            if (newBitSize > truncSize)
+              APnewAddRHS = APnewAddRHS.trunc(truncSize);
+            ConstantInt* newAddRHS = ConstantInt::get(APnewAddRHS);
             Value *NewAdd = ((UInst->getOpcode()==Instruction::Add) ?
                   BinaryOperator::CreateAdd(TruncIndVar, newAddRHS,
                                             UInst->getName()+".nozex", UInst2) :
index e42f3b3..f39458f 100644 (file)
@@ -1,6 +1,7 @@
 ; RUN: llvm-as < %s | opt -indvars
+; rdar://6817574
 
-define i32 @t() nounwind ssp {
+define i32 @t1() nounwind ssp {
 entry:
        br label %bb32
 
@@ -15,3 +16,20 @@ bb32:                ; preds = %bb32, %entry
 bb41:          ; preds = %bb32
        ret i32 0
 }
+
+define i32 @t2() nounwind ssp {
+entry:
+       br label %bb116
+
+bb116:         ; preds = %bb116, %entry
+       %mbPartIdx.1.reg2mem.0 = phi i8 [ %3, %bb116 ], [ 0, %entry ]           ; <i8> [#uses=3]
+       %0 = and i8 %mbPartIdx.1.reg2mem.0, 1           ; <i8> [#uses=1]
+       %1 = zext i8 %mbPartIdx.1.reg2mem.0 to i64              ; <i64> [#uses=0]
+       %2 = zext i8 %0 to i32          ; <i32> [#uses=0]
+       %3 = add i8 %mbPartIdx.1.reg2mem.0, 1           ; <i8> [#uses=2]
+       %4 = icmp ugt i8 %3, 3          ; <i1> [#uses=1]
+       br i1 %4, label %bb131, label %bb116
+
+bb131:         ; preds = %bb116
+       unreachable
+}