mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-03 17:02:03 +00:00
[IndVars] Fix a bug noticed by inspection
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. llvm-svn: 369730
This commit is contained in:
parent
71ceca8ea9
commit
46bf481c61
@ -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))
|
||||
|
@ -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(
|
||||
|
Loading…
Reference in New Issue
Block a user