Skip to content

Commit 8f99f46

Browse files
fhahnJaddyen
authored andcommitted
[LoopPeel] Handle constants when updating exit values when peeling last.
Account for constant values when updating exit values after peeling an iteration from the end. This can happen if the inner loop gets unrolled and simplified. Fixes llvm#140442.
1 parent 31325b7 commit 8f99f46

File tree

2 files changed

+80
-1
lines changed

2 files changed

+80
-1
lines changed

llvm/lib/Transforms/Utils/LoopPeel.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1214,7 +1214,7 @@ bool llvm::peelLoop(Loop *L, unsigned PeelCount, bool PeelLast, LoopInfo *LI,
12141214
// Now adjust users of the original exit values by replacing them with the
12151215
// exit value from the peeled iteration.
12161216
for (const auto &[P, E] : ExitValues)
1217-
P->replaceAllUsesWith(VMap.lookup(E));
1217+
P->replaceAllUsesWith(isa<Constant>(E) ? E : &*VMap.lookup(E));
12181218
formLCSSA(*L, DT, LI, SE);
12191219
} else {
12201220
// Now adjust the phi nodes in the loop header to get their initial values
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2+
; RUN: opt -p loop-unroll -S %s | FileCheck %s
3+
4+
; Test case for https://github.com/llvm/llvm-project/issues/140442.
5+
define i32 @peel_last_iter_of_outer_lcssa_phi_with_constant_after_unrolling_inner() {
6+
; CHECK-LABEL: define i32 @peel_last_iter_of_outer_lcssa_phi_with_constant_after_unrolling_inner() {
7+
; CHECK-NEXT: [[ENTRY:.*]]:
8+
; CHECK-NEXT: br label %[[OUTER_HEADER:.*]]
9+
; CHECK: [[OUTER_HEADER]]:
10+
; CHECK-NEXT: [[IV:%.*]] = phi i16 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[INNER_LATCH:.*]] ]
11+
; CHECK-NEXT: br label %[[INNER_HEADER:.*]]
12+
; CHECK: [[INNER_HEADER]]:
13+
; CHECK-NEXT: br i1 false, label %[[THEN:.*]], label %[[INNER_LATCH]]
14+
; CHECK: [[THEN]]:
15+
; CHECK-NEXT: call void @foo(i32 0)
16+
; CHECK-NEXT: br label %[[INNER_LATCH]]
17+
; CHECK: [[INNER_LATCH]]:
18+
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i16 [[IV]], 1
19+
; CHECK-NEXT: [[EC:%.*]] = icmp eq i16 [[IV_NEXT]], 999
20+
; CHECK-NEXT: br i1 [[EC]], label %[[EXIT_PEEL_BEGIN:.*]], label %[[OUTER_HEADER]], !llvm.loop [[LOOP0:![0-9]+]]
21+
; CHECK: [[EXIT_PEEL_BEGIN]]:
22+
; CHECK-NEXT: [[IV_NEXT_LCSSA:%.*]] = phi i16 [ [[IV_NEXT]], %[[INNER_LATCH]] ]
23+
; CHECK-NEXT: [[DOTLCSSA_LCSSA:%.*]] = phi i32 [ 1, %[[INNER_LATCH]] ]
24+
; CHECK-NEXT: br label %[[OUTER_HEADER_PEEL:.*]]
25+
; CHECK: [[OUTER_HEADER_PEEL]]:
26+
; CHECK-NEXT: [[TMP0:%.*]] = icmp eq i16 [[IV_NEXT_LCSSA]], 999
27+
; CHECK-NEXT: br label %[[INNER_HEADER_PEEL:.*]]
28+
; CHECK: [[INNER_HEADER_PEEL]]:
29+
; CHECK-NEXT: br i1 [[TMP0]], label %[[THEN_PEEL:.*]], label %[[INNER_LATCH_PEEL:.*]]
30+
; CHECK: [[THEN_PEEL]]:
31+
; CHECK-NEXT: call void @foo(i32 0)
32+
; CHECK-NEXT: br label %[[INNER_LATCH_PEEL]]
33+
; CHECK: [[INNER_LATCH_PEEL]]:
34+
; CHECK-NEXT: [[IV_NEXT_PEEL:%.*]] = add i16 [[IV_NEXT_LCSSA]], 1
35+
; CHECK-NEXT: [[EC_PEEL:%.*]] = icmp eq i16 [[IV_NEXT_PEEL]], 1000
36+
; CHECK-NEXT: br i1 [[EC_PEEL]], label %[[EXIT_PEEL_NEXT:.*]], label %[[EXIT_PEEL_NEXT]]
37+
; CHECK: [[EXIT_PEEL_NEXT]]:
38+
; CHECK-NEXT: br label %[[OUTER_HEADER_PEEL_NEXT:.*]]
39+
; CHECK: [[OUTER_HEADER_PEEL_NEXT]]:
40+
; CHECK-NEXT: br label %[[EXIT:.*]]
41+
; CHECK: [[EXIT]]:
42+
; CHECK-NEXT: ret i32 1
43+
;
44+
entry:
45+
br label %outer.header
46+
47+
outer.header:
48+
%iv = phi i16 [ 0, %entry ], [ %iv.next, %outer.latch ]
49+
%0 = icmp eq i16 %iv, 999
50+
br label %inner.header
51+
52+
inner.header:
53+
%inner.iv = phi i32 [ 0, %outer.header ], [ %inner.iv.next, %inner.latch ]
54+
%1 = add i32 %inner.iv, 1
55+
br i1 %0, label %then, label %inner.latch
56+
57+
then:
58+
call void @foo(i32 %inner.iv)
59+
br label %inner.latch
60+
61+
inner.latch:
62+
%inner.iv.next = add i32 %inner.iv, 1
63+
%inner.ec = icmp eq i32 %inner.iv.next, 1
64+
br i1 %inner.ec, label %outer.latch, label %inner.header
65+
66+
outer.latch:
67+
%iv.next = add i16 %iv, 1
68+
%ec = icmp eq i16 %iv.next, 1000
69+
br i1 %ec, label %exit, label %outer.header
70+
71+
exit:
72+
ret i32 %1
73+
}
74+
75+
declare void @foo(i32)
76+
;.
77+
; CHECK: [[LOOP0]] = distinct !{[[LOOP0]], [[META1:![0-9]+]]}
78+
; CHECK: [[META1]] = !{!"llvm.loop.peeled.count", i32 1}
79+
;.

0 commit comments

Comments
 (0)