diff --git a/lib/Transforms/Scalar/IndVarSimplify.cpp b/lib/Transforms/Scalar/IndVarSimplify.cpp index bb524f7ad69..aa35fa11f67 100644 --- a/lib/Transforms/Scalar/IndVarSimplify.cpp +++ b/lib/Transforms/Scalar/IndVarSimplify.cpp @@ -644,7 +644,8 @@ bool IndVarSimplify::rewriteLoopExitValues(Loop *L, SCEVExpander &Rewriter) { if (isa(ExitCount)) continue; if (auto *AddRec = dyn_cast(SE->getSCEV(Inst))) - ExitValue = AddRec->evaluateAtIteration(ExitCount, *SE); + if (AddRec->getLoop() == L) + ExitValue = AddRec->evaluateAtIteration(ExitCount, *SE); if (isa(ExitValue) || !SE->isLoopInvariant(ExitValue, L) || !isSafeToExpand(ExitValue, *SE)) diff --git a/test/Transforms/IndVarSimplify/rlev-add-me.ll b/test/Transforms/IndVarSimplify/rlev-add-me.ll index c41bdf45186..9520f86b370 100644 --- a/test/Transforms/IndVarSimplify/rlev-add-me.ll +++ b/test/Transforms/IndVarSimplify/rlev-add-me.ll @@ -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(