Skip to content

Commit 78461d7

Browse files
fhahngithub-actions[bot]
authored andcommitted
Automerge: [LoopUnroll] Add AArch64 tests for multi-exit loop unrolling.
Test coverage to llvm/llvm-project#124751.
2 parents f4e589e + 3007f31 commit 78461d7

File tree

1 file changed

+395
-0
lines changed

1 file changed

+395
-0
lines changed
Lines changed: 395 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,395 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2+
; RUN: opt -p loop-unroll -mcpu=apple-m1 -S %s | FileCheck --check-prefix=APPLE %s
3+
; RUN: opt -p loop-unroll -mcpu=apple-m2 -S %s | FileCheck --check-prefix=APPLE %s
4+
; RUN: opt -p loop-unroll -mcpu=apple-m3 -S %s | FileCheck --check-prefix=APPLE %s
5+
; RUN: opt -p loop-unroll -mcpu=apple-m4 -S %s | FileCheck --check-prefix=APPLE %s
6+
; RUN: opt -p loop-unroll -mcpu=cortex-a57 -S %s | FileCheck --check-prefix=OTHER %s
7+
8+
target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32"
9+
target triple = "arm64-apple-macosx15.0.0"
10+
11+
define i1 @multi_2_exit_find_i8_loop(ptr %vec, i8 %tgt) {
12+
; APPLE-LABEL: define i1 @multi_2_exit_find_i8_loop(
13+
; APPLE-SAME: ptr [[VEC:%.*]], i8 [[TGT:%.*]]) #[[ATTR0:[0-9]+]] {
14+
; APPLE-NEXT: [[ENTRY:.*]]:
15+
; APPLE-NEXT: [[START:%.*]] = load ptr, ptr [[VEC]], align 8
16+
; APPLE-NEXT: [[GEP_END:%.*]] = getelementptr inbounds nuw i8, ptr [[VEC]], i64 1
17+
; APPLE-NEXT: [[END:%.*]] = load ptr, ptr [[GEP_END]], align 8
18+
; APPLE-NEXT: br label %[[LOOP_HEADER:.*]]
19+
; APPLE: [[LOOP_HEADER]]:
20+
; APPLE-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[PTR_IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ], [ [[START]], %[[ENTRY]] ]
21+
; APPLE-NEXT: [[L:%.*]] = load i8, ptr [[PTR_IV]], align 8
22+
; APPLE-NEXT: [[C_1:%.*]] = icmp eq i8 [[L]], [[TGT]]
23+
; APPLE-NEXT: br i1 [[C_1]], label %[[EXIT:.*]], label %[[LOOP_LATCH]]
24+
; APPLE: [[LOOP_LATCH]]:
25+
; APPLE-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds nuw i8, ptr [[PTR_IV]], i64 1
26+
; APPLE-NEXT: [[C_2:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END]]
27+
; APPLE-NEXT: br i1 [[C_2]], label %[[EXIT]], label %[[LOOP_HEADER]]
28+
; APPLE: [[EXIT]]:
29+
; APPLE-NEXT: [[RES:%.*]] = phi ptr [ [[PTR_IV]], %[[LOOP_HEADER]] ], [ [[END]], %[[LOOP_LATCH]] ]
30+
; APPLE-NEXT: [[C_3:%.*]] = icmp eq ptr [[RES]], [[END]]
31+
; APPLE-NEXT: ret i1 [[C_3]]
32+
;
33+
; OTHER-LABEL: define i1 @multi_2_exit_find_i8_loop(
34+
; OTHER-SAME: ptr [[VEC:%.*]], i8 [[TGT:%.*]]) #[[ATTR0:[0-9]+]] {
35+
; OTHER-NEXT: [[ENTRY:.*]]:
36+
; OTHER-NEXT: [[START:%.*]] = load ptr, ptr [[VEC]], align 8
37+
; OTHER-NEXT: [[GEP_END:%.*]] = getelementptr inbounds nuw i8, ptr [[VEC]], i64 1
38+
; OTHER-NEXT: [[END:%.*]] = load ptr, ptr [[GEP_END]], align 8
39+
; OTHER-NEXT: br label %[[LOOP_HEADER:.*]]
40+
; OTHER: [[LOOP_HEADER]]:
41+
; OTHER-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[PTR_IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ], [ [[START]], %[[ENTRY]] ]
42+
; OTHER-NEXT: [[L:%.*]] = load i8, ptr [[PTR_IV]], align 8
43+
; OTHER-NEXT: [[C_1:%.*]] = icmp eq i8 [[L]], [[TGT]]
44+
; OTHER-NEXT: br i1 [[C_1]], label %[[EXIT:.*]], label %[[LOOP_LATCH]]
45+
; OTHER: [[LOOP_LATCH]]:
46+
; OTHER-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds nuw i8, ptr [[PTR_IV]], i64 1
47+
; OTHER-NEXT: [[C_2:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END]]
48+
; OTHER-NEXT: br i1 [[C_2]], label %[[EXIT]], label %[[LOOP_HEADER]]
49+
; OTHER: [[EXIT]]:
50+
; OTHER-NEXT: [[RES:%.*]] = phi ptr [ [[PTR_IV]], %[[LOOP_HEADER]] ], [ [[END]], %[[LOOP_LATCH]] ]
51+
; OTHER-NEXT: [[C_3:%.*]] = icmp eq ptr [[RES]], [[END]]
52+
; OTHER-NEXT: ret i1 [[C_3]]
53+
;
54+
entry:
55+
%start = load ptr, ptr %vec, align 8
56+
%gep.end = getelementptr inbounds nuw i8, ptr %vec, i64 1
57+
%end = load ptr, ptr %gep.end, align 8
58+
br label %loop.header
59+
60+
loop.header:
61+
%ptr.iv = phi ptr [ %ptr.iv.next, %loop.latch ], [ %start, %entry ]
62+
%l = load i8, ptr %ptr.iv, align 8
63+
%c.1 = icmp eq i8 %l, %tgt
64+
br i1 %c.1, label %exit, label %loop.latch
65+
66+
loop.latch:
67+
%ptr.iv.next = getelementptr inbounds nuw i8, ptr %ptr.iv, i64 1
68+
%c.2 = icmp eq ptr %ptr.iv.next, %end
69+
br i1 %c.2, label %exit, label %loop.header
70+
71+
exit:
72+
%res = phi ptr [ %ptr.iv, %loop.header ], [ %end, %loop.latch ]
73+
%c.3 = icmp eq ptr %res, %end
74+
ret i1 %c.3
75+
}
76+
77+
78+
define i1 @multi_2_exit_find_ptr_loop(ptr %vec, ptr %tgt) {
79+
; APPLE-LABEL: define i1 @multi_2_exit_find_ptr_loop(
80+
; APPLE-SAME: ptr [[VEC:%.*]], ptr [[TGT:%.*]]) #[[ATTR0]] {
81+
; APPLE-NEXT: [[ENTRY:.*]]:
82+
; APPLE-NEXT: [[START:%.*]] = load ptr, ptr [[VEC]], align 8
83+
; APPLE-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[START]], i64 8) ]
84+
; APPLE-NEXT: [[GEP_END:%.*]] = getelementptr inbounds nuw i8, ptr [[VEC]], i64 8
85+
; APPLE-NEXT: [[END:%.*]] = load ptr, ptr [[GEP_END]], align 8
86+
; APPLE-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[END]], i64 8) ]
87+
; APPLE-NEXT: br label %[[LOOP_HEADER:.*]]
88+
; APPLE: [[LOOP_HEADER]]:
89+
; APPLE-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[PTR_IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ], [ [[START]], %[[ENTRY]] ]
90+
; APPLE-NEXT: [[L:%.*]] = load ptr, ptr [[PTR_IV]], align 8
91+
; APPLE-NEXT: [[C_1:%.*]] = icmp eq ptr [[L]], [[TGT]]
92+
; APPLE-NEXT: br i1 [[C_1]], label %[[EXIT:.*]], label %[[LOOP_LATCH]]
93+
; APPLE: [[LOOP_LATCH]]:
94+
; APPLE-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds nuw i8, ptr [[PTR_IV]], i64 8
95+
; APPLE-NEXT: [[C_2:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END]]
96+
; APPLE-NEXT: br i1 [[C_2]], label %[[EXIT]], label %[[LOOP_HEADER]]
97+
; APPLE: [[EXIT]]:
98+
; APPLE-NEXT: [[RES:%.*]] = phi ptr [ [[PTR_IV]], %[[LOOP_HEADER]] ], [ [[END]], %[[LOOP_LATCH]] ]
99+
; APPLE-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[END]], i64 8) ]
100+
; APPLE-NEXT: [[C_3:%.*]] = icmp eq ptr [[RES]], [[END]]
101+
; APPLE-NEXT: ret i1 [[C_3]]
102+
;
103+
; OTHER-LABEL: define i1 @multi_2_exit_find_ptr_loop(
104+
; OTHER-SAME: ptr [[VEC:%.*]], ptr [[TGT:%.*]]) #[[ATTR0]] {
105+
; OTHER-NEXT: [[ENTRY:.*]]:
106+
; OTHER-NEXT: [[START:%.*]] = load ptr, ptr [[VEC]], align 8
107+
; OTHER-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[START]], i64 8) ]
108+
; OTHER-NEXT: [[GEP_END:%.*]] = getelementptr inbounds nuw i8, ptr [[VEC]], i64 8
109+
; OTHER-NEXT: [[END:%.*]] = load ptr, ptr [[GEP_END]], align 8
110+
; OTHER-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[END]], i64 8) ]
111+
; OTHER-NEXT: br label %[[LOOP_HEADER:.*]]
112+
; OTHER: [[LOOP_HEADER]]:
113+
; OTHER-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[PTR_IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ], [ [[START]], %[[ENTRY]] ]
114+
; OTHER-NEXT: [[L:%.*]] = load ptr, ptr [[PTR_IV]], align 8
115+
; OTHER-NEXT: [[C_1:%.*]] = icmp eq ptr [[L]], [[TGT]]
116+
; OTHER-NEXT: br i1 [[C_1]], label %[[EXIT:.*]], label %[[LOOP_LATCH]]
117+
; OTHER: [[LOOP_LATCH]]:
118+
; OTHER-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds nuw i8, ptr [[PTR_IV]], i64 8
119+
; OTHER-NEXT: [[C_2:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END]]
120+
; OTHER-NEXT: br i1 [[C_2]], label %[[EXIT]], label %[[LOOP_HEADER]]
121+
; OTHER: [[EXIT]]:
122+
; OTHER-NEXT: [[RES:%.*]] = phi ptr [ [[PTR_IV]], %[[LOOP_HEADER]] ], [ [[END]], %[[LOOP_LATCH]] ]
123+
; OTHER-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[END]], i64 8) ]
124+
; OTHER-NEXT: [[C_3:%.*]] = icmp eq ptr [[RES]], [[END]]
125+
; OTHER-NEXT: ret i1 [[C_3]]
126+
;
127+
entry:
128+
%start = load ptr, ptr %vec, align 8
129+
call void @llvm.assume(i1 true) [ "align"(ptr %start, i64 8) ]
130+
%gep.end = getelementptr inbounds nuw i8, ptr %vec, i64 8
131+
%end = load ptr, ptr %gep.end, align 8
132+
call void @llvm.assume(i1 true) [ "align"(ptr %end, i64 8) ]
133+
br label %loop.header
134+
135+
loop.header:
136+
%ptr.iv = phi ptr [ %ptr.iv.next, %loop.latch ], [ %start, %entry ]
137+
%l = load ptr, ptr %ptr.iv, align 8
138+
%c.1 = icmp eq ptr %l, %tgt
139+
br i1 %c.1, label %exit, label %loop.latch
140+
141+
loop.latch:
142+
%ptr.iv.next = getelementptr inbounds nuw i8, ptr %ptr.iv, i64 8
143+
%c.2 = icmp eq ptr %ptr.iv.next, %end
144+
br i1 %c.2, label %exit, label %loop.header
145+
146+
exit:
147+
%res = phi ptr [ %ptr.iv, %loop.header ], [ %end, %loop.latch ]
148+
call void @llvm.assume(i1 true) [ "align"(ptr %end, i64 8) ]
149+
%c.3 = icmp eq ptr %res, %end
150+
ret i1 %c.3
151+
}
152+
153+
define i1 @multi_2_exit_find_i8_loop_too_large(ptr %vec, i8 %tgt) {
154+
; APPLE-LABEL: define i1 @multi_2_exit_find_i8_loop_too_large(
155+
; APPLE-SAME: ptr [[VEC:%.*]], i8 [[TGT:%.*]]) #[[ATTR0]] {
156+
; APPLE-NEXT: [[ENTRY:.*]]:
157+
; APPLE-NEXT: [[START:%.*]] = load ptr, ptr [[VEC]], align 8
158+
; APPLE-NEXT: [[GEP_END:%.*]] = getelementptr inbounds nuw i8, ptr [[VEC]], i64 1
159+
; APPLE-NEXT: [[END:%.*]] = load ptr, ptr [[GEP_END]], align 8
160+
; APPLE-NEXT: br label %[[LOOP_HEADER:.*]]
161+
; APPLE: [[LOOP_HEADER]]:
162+
; APPLE-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[PTR_IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ], [ [[START]], %[[ENTRY]] ]
163+
; APPLE-NEXT: [[L:%.*]] = load i8, ptr [[PTR_IV]], align 8
164+
; APPLE-NEXT: [[UDIV:%.*]] = udiv i8 [[L]], [[TGT]]
165+
; APPLE-NEXT: [[UDIV_2:%.*]] = udiv i8 [[UDIV]], 10
166+
; APPLE-NEXT: [[C_1:%.*]] = icmp eq i8 [[UDIV_2]], 2
167+
; APPLE-NEXT: br i1 [[C_1]], label %[[EXIT:.*]], label %[[LOOP_LATCH]]
168+
; APPLE: [[LOOP_LATCH]]:
169+
; APPLE-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds nuw i8, ptr [[PTR_IV]], i64 1
170+
; APPLE-NEXT: [[C_2:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END]]
171+
; APPLE-NEXT: br i1 [[C_2]], label %[[EXIT]], label %[[LOOP_HEADER]]
172+
; APPLE: [[EXIT]]:
173+
; APPLE-NEXT: [[RES:%.*]] = phi ptr [ [[PTR_IV]], %[[LOOP_HEADER]] ], [ [[END]], %[[LOOP_LATCH]] ]
174+
; APPLE-NEXT: [[C_3:%.*]] = icmp eq ptr [[RES]], [[END]]
175+
; APPLE-NEXT: ret i1 [[C_3]]
176+
;
177+
; OTHER-LABEL: define i1 @multi_2_exit_find_i8_loop_too_large(
178+
; OTHER-SAME: ptr [[VEC:%.*]], i8 [[TGT:%.*]]) #[[ATTR0]] {
179+
; OTHER-NEXT: [[ENTRY:.*]]:
180+
; OTHER-NEXT: [[START:%.*]] = load ptr, ptr [[VEC]], align 8
181+
; OTHER-NEXT: [[GEP_END:%.*]] = getelementptr inbounds nuw i8, ptr [[VEC]], i64 1
182+
; OTHER-NEXT: [[END:%.*]] = load ptr, ptr [[GEP_END]], align 8
183+
; OTHER-NEXT: br label %[[LOOP_HEADER:.*]]
184+
; OTHER: [[LOOP_HEADER]]:
185+
; OTHER-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[PTR_IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ], [ [[START]], %[[ENTRY]] ]
186+
; OTHER-NEXT: [[L:%.*]] = load i8, ptr [[PTR_IV]], align 8
187+
; OTHER-NEXT: [[UDIV:%.*]] = udiv i8 [[L]], [[TGT]]
188+
; OTHER-NEXT: [[UDIV_2:%.*]] = udiv i8 [[UDIV]], 10
189+
; OTHER-NEXT: [[C_1:%.*]] = icmp eq i8 [[UDIV_2]], 2
190+
; OTHER-NEXT: br i1 [[C_1]], label %[[EXIT:.*]], label %[[LOOP_LATCH]]
191+
; OTHER: [[LOOP_LATCH]]:
192+
; OTHER-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds nuw i8, ptr [[PTR_IV]], i64 1
193+
; OTHER-NEXT: [[C_2:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END]]
194+
; OTHER-NEXT: br i1 [[C_2]], label %[[EXIT]], label %[[LOOP_HEADER]]
195+
; OTHER: [[EXIT]]:
196+
; OTHER-NEXT: [[RES:%.*]] = phi ptr [ [[PTR_IV]], %[[LOOP_HEADER]] ], [ [[END]], %[[LOOP_LATCH]] ]
197+
; OTHER-NEXT: [[C_3:%.*]] = icmp eq ptr [[RES]], [[END]]
198+
; OTHER-NEXT: ret i1 [[C_3]]
199+
;
200+
entry:
201+
%start = load ptr, ptr %vec, align 8
202+
%gep.end = getelementptr inbounds nuw i8, ptr %vec, i64 1
203+
%end = load ptr, ptr %gep.end, align 8
204+
br label %loop.header
205+
206+
loop.header:
207+
%ptr.iv = phi ptr [ %ptr.iv.next, %loop.latch ], [ %start, %entry ]
208+
%l = load i8, ptr %ptr.iv, align 8
209+
%udiv = udiv i8 %l, %tgt
210+
%udiv.2 = udiv i8 %udiv, 10
211+
%c.1 = icmp eq i8 %udiv.2, 2
212+
br i1 %c.1, label %exit, label %loop.latch
213+
214+
loop.latch:
215+
%ptr.iv.next = getelementptr inbounds nuw i8, ptr %ptr.iv, i64 1
216+
%c.2 = icmp eq ptr %ptr.iv.next, %end
217+
br i1 %c.2, label %exit, label %loop.header
218+
219+
exit:
220+
%res = phi ptr [ %ptr.iv, %loop.header ], [ %end, %loop.latch ]
221+
%c.3 = icmp eq ptr %res, %end
222+
ret i1 %c.3
223+
}
224+
define i1 @multi_3_exit_find_ptr_loop(ptr %vec, ptr %tgt, ptr %tgt2) {
225+
; APPLE-LABEL: define i1 @multi_3_exit_find_ptr_loop(
226+
; APPLE-SAME: ptr [[VEC:%.*]], ptr [[TGT:%.*]], ptr [[TGT2:%.*]]) #[[ATTR0]] {
227+
; APPLE-NEXT: [[ENTRY:.*]]:
228+
; APPLE-NEXT: [[START:%.*]] = load ptr, ptr [[VEC]], align 8
229+
; APPLE-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[START]], i64 8) ]
230+
; APPLE-NEXT: [[GEP_END:%.*]] = getelementptr inbounds nuw i8, ptr [[VEC]], i64 8
231+
; APPLE-NEXT: [[END:%.*]] = load ptr, ptr [[GEP_END]], align 8
232+
; APPLE-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[END]], i64 8) ]
233+
; APPLE-NEXT: br label %[[LOOP_HEADER:.*]]
234+
; APPLE: [[LOOP_HEADER]]:
235+
; APPLE-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[PTR_IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ], [ [[START]], %[[ENTRY]] ]
236+
; APPLE-NEXT: [[L:%.*]] = load ptr, ptr [[PTR_IV]], align 8
237+
; APPLE-NEXT: [[C_1:%.*]] = icmp eq ptr [[L]], [[TGT]]
238+
; APPLE-NEXT: [[C_2:%.*]] = icmp eq ptr [[L]], [[TGT2]]
239+
; APPLE-NEXT: [[OR_COND:%.*]] = select i1 [[C_1]], i1 true, i1 [[C_2]]
240+
; APPLE-NEXT: br i1 [[OR_COND]], label %[[EXIT:.*]], label %[[LOOP_LATCH]]
241+
; APPLE: [[LOOP_LATCH]]:
242+
; APPLE-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds nuw i8, ptr [[PTR_IV]], i64 8
243+
; APPLE-NEXT: [[C_3:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END]]
244+
; APPLE-NEXT: br i1 [[C_3]], label %[[EXIT]], label %[[LOOP_HEADER]]
245+
; APPLE: [[EXIT]]:
246+
; APPLE-NEXT: [[RES:%.*]] = phi ptr [ [[PTR_IV]], %[[LOOP_HEADER]] ], [ [[END]], %[[LOOP_LATCH]] ]
247+
; APPLE-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[END]], i64 8) ]
248+
; APPLE-NEXT: [[C_4:%.*]] = icmp eq ptr [[RES]], [[END]]
249+
; APPLE-NEXT: ret i1 [[C_4]]
250+
;
251+
; OTHER-LABEL: define i1 @multi_3_exit_find_ptr_loop(
252+
; OTHER-SAME: ptr [[VEC:%.*]], ptr [[TGT:%.*]], ptr [[TGT2:%.*]]) #[[ATTR0]] {
253+
; OTHER-NEXT: [[ENTRY:.*]]:
254+
; OTHER-NEXT: [[START:%.*]] = load ptr, ptr [[VEC]], align 8
255+
; OTHER-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[START]], i64 8) ]
256+
; OTHER-NEXT: [[GEP_END:%.*]] = getelementptr inbounds nuw i8, ptr [[VEC]], i64 8
257+
; OTHER-NEXT: [[END:%.*]] = load ptr, ptr [[GEP_END]], align 8
258+
; OTHER-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[END]], i64 8) ]
259+
; OTHER-NEXT: br label %[[LOOP_HEADER:.*]]
260+
; OTHER: [[LOOP_HEADER]]:
261+
; OTHER-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[PTR_IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ], [ [[START]], %[[ENTRY]] ]
262+
; OTHER-NEXT: [[L:%.*]] = load ptr, ptr [[PTR_IV]], align 8
263+
; OTHER-NEXT: [[C_1:%.*]] = icmp eq ptr [[L]], [[TGT]]
264+
; OTHER-NEXT: [[C_2:%.*]] = icmp eq ptr [[L]], [[TGT2]]
265+
; OTHER-NEXT: [[OR_COND:%.*]] = select i1 [[C_1]], i1 true, i1 [[C_2]]
266+
; OTHER-NEXT: br i1 [[OR_COND]], label %[[EXIT:.*]], label %[[LOOP_LATCH]]
267+
; OTHER: [[LOOP_LATCH]]:
268+
; OTHER-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds nuw i8, ptr [[PTR_IV]], i64 8
269+
; OTHER-NEXT: [[C_3:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END]]
270+
; OTHER-NEXT: br i1 [[C_3]], label %[[EXIT]], label %[[LOOP_HEADER]]
271+
; OTHER: [[EXIT]]:
272+
; OTHER-NEXT: [[RES:%.*]] = phi ptr [ [[PTR_IV]], %[[LOOP_HEADER]] ], [ [[END]], %[[LOOP_LATCH]] ]
273+
; OTHER-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[END]], i64 8) ]
274+
; OTHER-NEXT: [[C_4:%.*]] = icmp eq ptr [[RES]], [[END]]
275+
; OTHER-NEXT: ret i1 [[C_4]]
276+
;
277+
entry:
278+
%start = load ptr, ptr %vec, align 8
279+
call void @llvm.assume(i1 true) [ "align"(ptr %start, i64 8) ]
280+
%gep.end = getelementptr inbounds nuw i8, ptr %vec, i64 8
281+
%end = load ptr, ptr %gep.end, align 8
282+
call void @llvm.assume(i1 true) [ "align"(ptr %end, i64 8) ]
283+
br label %loop.header
284+
285+
loop.header:
286+
%ptr.iv = phi ptr [ %ptr.iv.next, %loop.latch ], [ %start, %entry ]
287+
%l = load ptr, ptr %ptr.iv, align 8
288+
%c.1 = icmp eq ptr %l, %tgt
289+
br i1 %c.1, label %exit, label %then
290+
291+
then:
292+
%c.2 = icmp eq ptr %l, %tgt2
293+
br i1 %c.2, label %exit, label %loop.latch
294+
295+
loop.latch:
296+
%ptr.iv.next = getelementptr inbounds nuw i8, ptr %ptr.iv, i64 8
297+
%c.3 = icmp eq ptr %ptr.iv.next, %end
298+
br i1 %c.3, label %exit, label %loop.header
299+
300+
exit:
301+
%res = phi ptr [ %ptr.iv, %loop.header ], [ %ptr.iv, %then], [ %end, %loop.latch ]
302+
call void @llvm.assume(i1 true) [ "align"(ptr %end, i64 8) ]
303+
%c.4 = icmp eq ptr %res, %end
304+
ret i1 %c.4
305+
}
306+
307+
define i1 @multi_3_exit_find_i8_loop_switch(ptr %vec, i8 %tgt) {
308+
; APPLE-LABEL: define i1 @multi_3_exit_find_i8_loop_switch(
309+
; APPLE-SAME: ptr [[VEC:%.*]], i8 [[TGT:%.*]]) #[[ATTR0]] {
310+
; APPLE-NEXT: [[ENTRY:.*]]:
311+
; APPLE-NEXT: [[START:%.*]] = load ptr, ptr [[VEC]], align 8
312+
; APPLE-NEXT: [[GEP_END:%.*]] = getelementptr inbounds nuw i8, ptr [[VEC]], i64 1
313+
; APPLE-NEXT: [[END:%.*]] = load ptr, ptr [[GEP_END]], align 8
314+
; APPLE-NEXT: br label %[[LOOP_HEADER:.*]]
315+
; APPLE: [[LOOP_HEADER]]:
316+
; APPLE-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[PTR_IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ], [ [[START]], %[[ENTRY]] ]
317+
; APPLE-NEXT: [[L:%.*]] = load i8, ptr [[PTR_IV]], align 8
318+
; APPLE-NEXT: switch i8 [[L]], label %[[LOOP_LATCH]] [
319+
; APPLE-NEXT: i8 0, label %[[EXIT_1:.*]]
320+
; APPLE-NEXT: i8 1, label %[[EXIT_2:.*]]
321+
; APPLE-NEXT: i8 2, label %[[EXIT:.*]]
322+
; APPLE-NEXT: ]
323+
; APPLE: [[LOOP_LATCH]]:
324+
; APPLE-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds nuw i8, ptr [[PTR_IV]], i64 1
325+
; APPLE-NEXT: [[C_2:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END]]
326+
; APPLE-NEXT: br i1 [[C_2]], label %[[EXIT]], label %[[LOOP_HEADER]]
327+
; APPLE: [[EXIT]]:
328+
; APPLE-NEXT: [[RES:%.*]] = phi ptr [ [[PTR_IV]], %[[LOOP_HEADER]] ], [ [[END]], %[[LOOP_LATCH]] ]
329+
; APPLE-NEXT: [[C_3:%.*]] = icmp eq ptr [[RES]], [[END]]
330+
; APPLE-NEXT: ret i1 [[C_3]]
331+
; APPLE: [[EXIT_1]]:
332+
; APPLE-NEXT: ret i1 false
333+
; APPLE: [[EXIT_2]]:
334+
; APPLE-NEXT: ret i1 true
335+
;
336+
; OTHER-LABEL: define i1 @multi_3_exit_find_i8_loop_switch(
337+
; OTHER-SAME: ptr [[VEC:%.*]], i8 [[TGT:%.*]]) #[[ATTR0]] {
338+
; OTHER-NEXT: [[ENTRY:.*]]:
339+
; OTHER-NEXT: [[START:%.*]] = load ptr, ptr [[VEC]], align 8
340+
; OTHER-NEXT: [[GEP_END:%.*]] = getelementptr inbounds nuw i8, ptr [[VEC]], i64 1
341+
; OTHER-NEXT: [[END:%.*]] = load ptr, ptr [[GEP_END]], align 8
342+
; OTHER-NEXT: br label %[[LOOP_HEADER:.*]]
343+
; OTHER: [[LOOP_HEADER]]:
344+
; OTHER-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[PTR_IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ], [ [[START]], %[[ENTRY]] ]
345+
; OTHER-NEXT: [[L:%.*]] = load i8, ptr [[PTR_IV]], align 8
346+
; OTHER-NEXT: switch i8 [[L]], label %[[LOOP_LATCH]] [
347+
; OTHER-NEXT: i8 0, label %[[EXIT_1:.*]]
348+
; OTHER-NEXT: i8 1, label %[[EXIT_2:.*]]
349+
; OTHER-NEXT: i8 2, label %[[EXIT:.*]]
350+
; OTHER-NEXT: ]
351+
; OTHER: [[LOOP_LATCH]]:
352+
; OTHER-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds nuw i8, ptr [[PTR_IV]], i64 1
353+
; OTHER-NEXT: [[C_2:%.*]] = icmp eq ptr [[PTR_IV_NEXT]], [[END]]
354+
; OTHER-NEXT: br i1 [[C_2]], label %[[EXIT]], label %[[LOOP_HEADER]]
355+
; OTHER: [[EXIT]]:
356+
; OTHER-NEXT: [[RES:%.*]] = phi ptr [ [[PTR_IV]], %[[LOOP_HEADER]] ], [ [[END]], %[[LOOP_LATCH]] ]
357+
; OTHER-NEXT: [[C_3:%.*]] = icmp eq ptr [[RES]], [[END]]
358+
; OTHER-NEXT: ret i1 [[C_3]]
359+
; OTHER: [[EXIT_1]]:
360+
; OTHER-NEXT: ret i1 false
361+
; OTHER: [[EXIT_2]]:
362+
; OTHER-NEXT: ret i1 true
363+
;
364+
entry:
365+
%start = load ptr, ptr %vec, align 8
366+
%gep.end = getelementptr inbounds nuw i8, ptr %vec, i64 1
367+
%end = load ptr, ptr %gep.end, align 8
368+
br label %loop.header
369+
370+
loop.header:
371+
%ptr.iv = phi ptr [ %ptr.iv.next, %loop.latch ], [ %start, %entry ]
372+
%l = load i8, ptr %ptr.iv, align 8
373+
switch i8 %l, label %loop.latch [
374+
i8 0, label %exit.1
375+
i8 1, label %exit.2
376+
i8 2, label %exit ]
377+
378+
loop.latch:
379+
%ptr.iv.next = getelementptr inbounds nuw i8, ptr %ptr.iv, i64 1
380+
%c.2 = icmp eq ptr %ptr.iv.next, %end
381+
br i1 %c.2, label %exit, label %loop.header
382+
383+
exit:
384+
%res = phi ptr [ %ptr.iv, %loop.header ], [ %end, %loop.latch ]
385+
%c.3 = icmp eq ptr %res, %end
386+
ret i1 %c.3
387+
388+
exit.1:
389+
ret i1 0
390+
391+
exit.2:
392+
ret i1 1
393+
}
394+
395+
declare void @llvm.assume(i1 noundef)

0 commit comments

Comments
 (0)