]> granicus.if.org Git - llvm/commitdiff
[IndVars] Fix a bug noticed by inspection
authorPhilip Reames <listmail@philipreames.com>
Fri, 23 Aug 2019 04:03:23 +0000 (04:03 +0000)
committerPhilip Reames <listmail@philipreames.com>
Fri, 23 Aug 2019 04:03:23 +0000 (04:03 +0000)
We were computing the loop exit value, but not ensuring the addrec belonged to the loop whose exit value we were computing.  I couldn't actually trip this; the test case shows the basic setup which *might* trip this, but none of the variations I've tried actually do.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@369730 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/IndVarSimplify.cpp
test/Transforms/IndVarSimplify/rlev-add-me.ll

index bb524f7ad6922cf430604000ba01bd05c6701afc..aa35fa11f67b96d1e9f2d1fce5c6efcdd754a3f4 100644 (file)
@@ -644,7 +644,8 @@ bool IndVarSimplify::rewriteLoopExitValues(Loop *L, SCEVExpander &Rewriter) {
           if (isa<SCEVCouldNotCompute>(ExitCount))
             continue;
           if (auto *AddRec = dyn_cast<SCEVAddRecExpr>(SE->getSCEV(Inst)))
-            ExitValue = AddRec->evaluateAtIteration(ExitCount, *SE);
+            if (AddRec->getLoop() == L)
+              ExitValue = AddRec->evaluateAtIteration(ExitCount, *SE);
           if (isa<SCEVCouldNotCompute>(ExitValue) ||
               !SE->isLoopInvariant(ExitValue, L) ||
               !isSafeToExpand(ExitValue, *SE))
index c41bdf45186a72b1eeed694328b3aea1d4851d78..9520f86b37028c79bbf48c63b52b0da46fa16cfa 100644 (file)
@@ -81,6 +81,67 @@ exit2:
   ret i32 %iv.next
 }
 
+define i32 @neg_wrong_loop(i32 %n) {
+; CHECK-LABEL: @neg_wrong_loop(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br label [[WRONG_LOOP:%.*]]
+; CHECK:       wrong_loop:
+; CHECK-NEXT:    [[IV2:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV2_NEXT:%.*]], [[WRONG_LOOP]] ]
+; CHECK-NEXT:    [[IV2_NEXT]] = add i32 [[IV2]], 1
+; CHECK-NEXT:    [[UNKNOWN:%.*]] = load volatile i32, i32* @G
+; CHECK-NEXT:    [[CMP_UNK:%.*]] = icmp eq i32 [[UNKNOWN]], 0
+; CHECK-NEXT:    br i1 [[CMP_UNK]], label [[HEADER_PREHEADER:%.*]], label [[WRONG_LOOP]]
+; CHECK:       header.preheader:
+; CHECK-NEXT:    [[IV2_LCSSA:%.*]] = phi i32 [ [[IV2]], [[WRONG_LOOP]] ]
+; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[N:%.*]], 1
+; CHECK-NEXT:    br label [[HEADER:%.*]]
+; CHECK:       header:
+; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[HEADER_PREHEADER]] ], [ [[IV_NEXT:%.*]], [[LATCH:%.*]] ]
+; CHECK-NEXT:    [[V:%.*]] = load volatile i32, i32* @G
+; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[V]], 0
+; CHECK-NEXT:    br i1 [[CMP1]], label [[LATCH]], label [[EXIT1:%.*]]
+; CHECK:       latch:
+; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
+; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i32 [[IV_NEXT]], [[TMP0]]
+; CHECK-NEXT:    br i1 [[EXITCOND]], label [[HEADER]], label [[EXIT2:%.*]]
+; CHECK:       exit1:
+; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i32 [ [[IV]], [[HEADER]] ]
+; CHECK-NEXT:    ret i32 [[IV_LCSSA]]
+; CHECK:       exit2:
+; CHECK-NEXT:    [[EXITVAL:%.*]] = phi i32 [ [[IV2_LCSSA]], [[LATCH]] ]
+; CHECK-NEXT:    ret i32 [[EXITVAL]]
+;
+entry:
+  br label %wrong_loop
+
+wrong_loop:
+  %iv2 = phi i32 [0, %entry], [%iv2.next, %wrong_loop]
+  %iv2.next = add i32 %iv2, 1
+  %unknown = load volatile i32, i32* @G
+  %cmp_unk = icmp eq i32 %unknown, 0
+  br i1 %cmp_unk, label %header.preheader, label %wrong_loop
+
+header.preheader:
+  %iv2.lcssa = phi i32 [%iv2, %wrong_loop]
+  br label %header
+
+header:
+  %iv = phi i32 [0, %header.preheader], [%iv.next, %latch]
+  %v = load volatile i32, i32* @G
+  %cmp1 = icmp eq i32 %v, 0
+  br i1 %cmp1, label %latch, label %exit1
+
+latch:
+  %iv.next = add i32 %iv, 1
+  %cmp2 = icmp ult i32 %iv, %n
+  br i1 %cmp2, label %header, label %exit2
+exit1:
+  ret i32 %iv
+exit2:
+  %exitval = phi i32 [%iv2.lcssa, %latch]
+  ret i32 %exitval
+}
+
 ; TODO: Generalize the code to handle other SCEV expressions
 define i32 @test3(i32 %n) {
 ; CHECK-LABEL: @test3(