Skip to content

Commit 96d5a50

Browse files
committed
[LoopUnroll] Add peeling tests with unreachable exits.
1 parent c973189 commit 96d5a50

File tree

1 file changed

+165
-0
lines changed

1 file changed

+165
-0
lines changed
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2+
; RUN: opt -loop-unroll -S %s | FileCheck %s
3+
4+
declare void @foo()
5+
6+
define void @unroll_unreachable_exit_and_latch_exit(i32* %ptr, i32 %N, i32 %x) {
7+
; CHECK-LABEL: @unroll_unreachable_exit_and_latch_exit(
8+
; CHECK-NEXT: entry:
9+
; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
10+
; CHECK: loop.header:
11+
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
12+
; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], 2
13+
; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]]
14+
; CHECK: then:
15+
; CHECK-NEXT: br label [[LOOP_LATCH]]
16+
; CHECK: else:
17+
; CHECK-NEXT: [[C_2:%.*]] = icmp eq i32 [[IV]], [[X:%.*]]
18+
; CHECK-NEXT: br i1 [[C_2]], label [[UNREACHABLE_EXIT:%.*]], label [[LOOP_LATCH]]
19+
; CHECK: loop.latch:
20+
; CHECK-NEXT: [[M:%.*]] = phi i32 [ 0, [[THEN]] ], [ [[X]], [[ELSE]] ]
21+
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, i32* [[PTR:%.*]], i32 [[IV]]
22+
; CHECK-NEXT: store i32 [[M]], i32* [[GEP]], align 4
23+
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
24+
; CHECK-NEXT: [[C_3:%.*]] = icmp ult i32 [[IV]], 1000
25+
; CHECK-NEXT: br i1 [[C_3]], label [[LOOP_HEADER]], label [[EXIT:%.*]]
26+
; CHECK: exit:
27+
; CHECK-NEXT: ret void
28+
; CHECK: unreachable.exit:
29+
; CHECK-NEXT: call void @foo()
30+
; CHECK-NEXT: unreachable
31+
;
32+
entry:
33+
br label %loop.header
34+
35+
loop.header:
36+
%iv = phi i32 [ 1, %entry ], [ %iv.next, %loop.latch ]
37+
%c = icmp ult i32 %iv, 2
38+
br i1 %c, label %then, label %else
39+
40+
then:
41+
br label %loop.latch
42+
43+
else:
44+
%c.2 = icmp eq i32 %iv, %x
45+
br i1 %c.2, label %unreachable.exit, label %loop.latch
46+
47+
loop.latch:
48+
%m = phi i32 [ 0, %then ], [ %x, %else ]
49+
%gep = getelementptr i32, i32* %ptr, i32 %iv
50+
store i32 %m, i32* %gep
51+
%iv.next = add nuw nsw i32 %iv, 1
52+
%c.3 = icmp ult i32 %iv, 1000
53+
br i1 %c.3, label %loop.header, label %exit
54+
55+
exit:
56+
ret void
57+
58+
unreachable.exit:
59+
call void @foo()
60+
unreachable
61+
}
62+
63+
define void @unroll_unreachable_exit_and_header_exit(i32* %ptr, i32 %N, i32 %x) {
64+
; CHECK-LABEL: @unroll_unreachable_exit_and_header_exit(
65+
; CHECK-NEXT: entry:
66+
; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
67+
; CHECK: loop.header:
68+
; CHECK-NEXT: br i1 true, label [[EXIT:%.*]], label [[ELSE:%.*]]
69+
; CHECK: else:
70+
; CHECK-NEXT: [[C_2:%.*]] = icmp eq i32 1, [[X:%.*]]
71+
; CHECK-NEXT: br i1 [[C_2]], label [[UNREACHABLE_EXIT:%.*]], label [[LOOP_LATCH:%.*]]
72+
; CHECK: loop.latch:
73+
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, i32* [[PTR:%.*]], i32 1
74+
; CHECK-NEXT: store i32 [[X]], i32* [[GEP]], align 4
75+
; CHECK-NEXT: unreachable
76+
; CHECK: exit:
77+
; CHECK-NEXT: ret void
78+
; CHECK: unreachable.exit:
79+
; CHECK-NEXT: call void @foo()
80+
; CHECK-NEXT: unreachable
81+
;
82+
entry:
83+
br label %loop.header
84+
85+
loop.header:
86+
%iv = phi i32 [ 1, %entry ], [ %iv.next, %loop.latch ]
87+
%c = icmp ult i32 %iv, 1000
88+
br i1 %c, label %exit, label %else
89+
90+
else:
91+
%c.2 = icmp eq i32 %iv, %x
92+
br i1 %c.2, label %unreachable.exit, label %loop.latch
93+
94+
loop.latch:
95+
%gep = getelementptr i32, i32* %ptr, i32 %iv
96+
store i32 %x, i32* %gep
97+
%iv.next = add nuw nsw i32 %iv, 1
98+
br label %loop.header
99+
100+
exit:
101+
ret void
102+
103+
unreachable.exit:
104+
call void @foo()
105+
unreachable
106+
}
107+
108+
define void @unroll_unreachable_and_multiple_reachable_exits(i32* %ptr, i32 %N, i32 %x) {
109+
; CHECK-LABEL: @unroll_unreachable_and_multiple_reachable_exits(
110+
; CHECK-NEXT: entry:
111+
; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
112+
; CHECK: loop.header:
113+
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
114+
; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], 2
115+
; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]]
116+
; CHECK: then:
117+
; CHECK-NEXT: [[C_2:%.*]] = icmp sgt i32 [[IV]], [[X:%.*]]
118+
; CHECK-NEXT: br i1 [[C_2]], label [[EXIT:%.*]], label [[LOOP_LATCH]]
119+
; CHECK: else:
120+
; CHECK-NEXT: [[C_3:%.*]] = icmp eq i32 [[IV]], [[X]]
121+
; CHECK-NEXT: br i1 [[C_3]], label [[UNREACHABLE_EXIT:%.*]], label [[LOOP_LATCH]]
122+
; CHECK: loop.latch:
123+
; CHECK-NEXT: [[M:%.*]] = phi i32 [ 0, [[THEN]] ], [ [[X]], [[ELSE]] ]
124+
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, i32* [[PTR:%.*]], i32 [[IV]]
125+
; CHECK-NEXT: store i32 [[M]], i32* [[GEP]], align 4
126+
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
127+
; CHECK-NEXT: [[C_4:%.*]] = icmp ult i32 [[IV]], 1000
128+
; CHECK-NEXT: br i1 [[C_4]], label [[LOOP_HEADER]], label [[EXIT]]
129+
; CHECK: exit:
130+
; CHECK-NEXT: ret void
131+
; CHECK: unreachable.exit:
132+
; CHECK-NEXT: call void @foo()
133+
; CHECK-NEXT: unreachable
134+
;
135+
entry:
136+
br label %loop.header
137+
138+
loop.header:
139+
%iv = phi i32 [ 1, %entry ], [ %iv.next, %loop.latch ]
140+
%c = icmp ult i32 %iv, 2
141+
br i1 %c, label %then, label %else
142+
143+
then:
144+
%c.2 = icmp sgt i32 %iv, %x
145+
br i1 %c.2, label %exit, label %loop.latch
146+
147+
else:
148+
%c.3 = icmp eq i32 %iv, %x
149+
br i1 %c.3, label %unreachable.exit, label %loop.latch
150+
151+
loop.latch:
152+
%m = phi i32 [ 0, %then ], [ %x, %else ]
153+
%gep = getelementptr i32, i32* %ptr, i32 %iv
154+
store i32 %m, i32* %gep
155+
%iv.next = add nuw nsw i32 %iv, 1
156+
%c.4 = icmp ult i32 %iv, 1000
157+
br i1 %c.4, label %loop.header, label %exit
158+
159+
exit:
160+
ret void
161+
162+
unreachable.exit:
163+
call void @foo()
164+
unreachable
165+
}

0 commit comments

Comments
 (0)