1+ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
12; RUN: opt -S -passes=licm %s | FileCheck %s
23; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<target-ir>,require<scalar-evolution>,require<opt-remark-emit>,loop-mssa(licm)' < %s -S | FileCheck %s
34
45declare i32 @load (ptr %p ) argmemonly readonly nounwind
56
67define void @test_load (ptr noalias %loc , ptr noalias %sink ) {
7- ; CHECK-LABEL: @test_load
8- ; CHECK-LABEL: entry:
9- ; CHECK: call i32 @load
10- ; CHECK-LABEL: loop:
8+ ; CHECK-LABEL: define void @test_load(
9+ ; CHECK-SAME: ptr noalias [[LOC:%.*]], ptr noalias [[SINK:%.*]]) {
10+ ; CHECK-NEXT: [[ENTRY:.*]]:
11+ ; CHECK-NEXT: [[RET:%.*]] = call i32 @load(ptr [[LOC]])
12+ ; CHECK-NEXT: br label %[[LOOP:.*]]
13+ ; CHECK: [[LOOP]]:
14+ ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
15+ ; CHECK-NEXT: store volatile i32 [[RET]], ptr [[SINK]], align 4
16+ ; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
17+ ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[IV]], 200
18+ ; CHECK-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT:.*]]
19+ ; CHECK: [[EXIT]]:
20+ ; CHECK-NEXT: ret void
21+ ;
1122entry:
1223 br label %loop
1324
@@ -30,15 +41,26 @@ declare i32 @spec(ptr %p, ptr %q) readonly argmemonly nounwind speculatable
3041; However, we need not strip the nonnull attribute since it just propagates
3142; poison if the parameter was indeed null.
3243define void @test_strip_attribute (ptr noalias %loc , ptr noalias %sink , ptr %q ) {
33- ; CHECK-LABEL: @test_strip_attribute(
34- ; CHECK-NEXT: entry:
35- ; CHECK-NEXT: [[RET:%.*]] = call i32 @load(ptr [[LOC:%.*]])
36- ; CHECK-NEXT: [[NULLCHK:%.*]] = icmp eq ptr [[Q:%.*]], null
44+ ; CHECK-LABEL: define void @test_strip_attribute(
45+ ; CHECK-SAME: ptr noalias [[LOC:%.*]], ptr noalias [[SINK:%.*]], ptr [[Q:%.*]]) {
46+ ; CHECK-NEXT: [[ENTRY:.*]]:
47+ ; CHECK-NEXT: [[RET:%.*]] = call i32 @load(ptr [[LOC]])
48+ ; CHECK-NEXT: [[NULLCHK:%.*]] = icmp eq ptr [[Q]], null
3749; CHECK-NEXT: [[RET2:%.*]] = call i32 @spec(ptr nonnull [[Q]], ptr [[LOC]])
38- ; CHECK-NEXT: br label [[LOOP:%.*]]
39- ; CHECK: loop:
40- ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[ISNULL:%.*]] ]
41- ; CHECK-NEXT: br i1 [[NULLCHK]], label [[ISNULL]], label [[NONNULLBB:%.*]]
50+ ; CHECK-NEXT: br label %[[LOOP:.*]]
51+ ; CHECK: [[LOOP]]:
52+ ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[ISNULL:.*]] ]
53+ ; CHECK-NEXT: br i1 [[NULLCHK]], label %[[ISNULL]], label %[[NONNULLBB:.*]]
54+ ; CHECK: [[NONNULLBB]]:
55+ ; CHECK-NEXT: br label %[[ISNULL]]
56+ ; CHECK: [[ISNULL]]:
57+ ; CHECK-NEXT: store volatile i32 [[RET]], ptr [[SINK]], align 4
58+ ; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
59+ ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[IV]], 200
60+ ; CHECK-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT:.*]]
61+ ; CHECK: [[EXIT]]:
62+ ; CHECK-NEXT: ret void
63+ ;
4264entry:
4365 br label %loop
4466
@@ -65,10 +87,19 @@ exit:
6587declare void @store (i32 %val , ptr %p ) argmemonly writeonly nounwind
6688
6789define void @test (ptr %loc ) {
68- ; CHECK-LABEL: @test
69- ; CHECK-LABEL: loop:
70- ; CHECK: call void @store
71- ; CHECK-LABEL: exit:
90+ ; CHECK-LABEL: define void @test(
91+ ; CHECK-SAME: ptr [[LOC:%.*]]) {
92+ ; CHECK-NEXT: [[ENTRY:.*]]:
93+ ; CHECK-NEXT: br label %[[LOOP:.*]]
94+ ; CHECK: [[LOOP]]:
95+ ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
96+ ; CHECK-NEXT: call void @store(i32 0, ptr [[LOC]])
97+ ; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
98+ ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[IV]], 200
99+ ; CHECK-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT:.*]]
100+ ; CHECK: [[EXIT]]:
101+ ; CHECK-NEXT: ret void
102+ ;
72103entry:
73104 br label %loop
74105
@@ -84,10 +115,23 @@ exit:
84115}
85116
86117define void @test_multiexit (ptr %loc , i1 %earlycnd ) {
87- ; CHECK-LABEL: @test_multiexit
88- ; CHECK-LABEL: loop:
89- ; CHECK: call void @store
90- ; CHECK-LABEL: backedge:
118+ ; CHECK-LABEL: define void @test_multiexit(
119+ ; CHECK-SAME: ptr [[LOC:%.*]], i1 [[EARLYCND:%.*]]) {
120+ ; CHECK-NEXT: [[ENTRY:.*]]:
121+ ; CHECK-NEXT: br label %[[LOOP:.*]]
122+ ; CHECK: [[LOOP]]:
123+ ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[BACKEDGE:.*]] ]
124+ ; CHECK-NEXT: call void @store(i32 0, ptr [[LOC]])
125+ ; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
126+ ; CHECK-NEXT: br i1 [[EARLYCND]], label %[[EXIT1:.*]], label %[[BACKEDGE]]
127+ ; CHECK: [[BACKEDGE]]:
128+ ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[IV]], 200
129+ ; CHECK-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT2:.*]]
130+ ; CHECK: [[EXIT1]]:
131+ ; CHECK-NEXT: ret void
132+ ; CHECK: [[EXIT2]]:
133+ ; CHECK-NEXT: ret void
134+ ;
91135entry:
92136 br label %loop
93137
@@ -108,10 +152,19 @@ exit2:
108152}
109153
110154define void @neg_lv_value (ptr %loc ) {
111- ; CHECK-LABEL: @neg_lv_value
112- ; CHECK-LABEL: loop:
113- ; CHECK: call void @store
114- ; CHECK-LABEL: exit:
155+ ; CHECK-LABEL: define void @neg_lv_value(
156+ ; CHECK-SAME: ptr [[LOC:%.*]]) {
157+ ; CHECK-NEXT: [[ENTRY:.*]]:
158+ ; CHECK-NEXT: br label %[[LOOP:.*]]
159+ ; CHECK: [[LOOP]]:
160+ ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
161+ ; CHECK-NEXT: call void @store(i32 [[IV]], ptr [[LOC]])
162+ ; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
163+ ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[IV]], 200
164+ ; CHECK-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT:.*]]
165+ ; CHECK: [[EXIT]]:
166+ ; CHECK-NEXT: ret void
167+ ;
115168entry:
116169 br label %loop
117170
@@ -127,10 +180,20 @@ exit:
127180}
128181
129182define void @neg_lv_addr (ptr %loc ) {
130- ; CHECK-LABEL: @neg_lv_addr
131- ; CHECK-LABEL: loop:
132- ; CHECK: call void @store
133- ; CHECK-LABEL: exit:
183+ ; CHECK-LABEL: define void @neg_lv_addr(
184+ ; CHECK-SAME: ptr [[LOC:%.*]]) {
185+ ; CHECK-NEXT: [[ENTRY:.*]]:
186+ ; CHECK-NEXT: br label %[[LOOP:.*]]
187+ ; CHECK: [[LOOP]]:
188+ ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
189+ ; CHECK-NEXT: [[P:%.*]] = getelementptr i32, ptr [[LOC]], i32 [[IV]]
190+ ; CHECK-NEXT: call void @store(i32 0, ptr [[P]])
191+ ; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
192+ ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[IV]], 200
193+ ; CHECK-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT:.*]]
194+ ; CHECK: [[EXIT]]:
195+ ; CHECK-NEXT: ret void
196+ ;
134197entry:
135198 br label %loop
136199
@@ -147,10 +210,20 @@ exit:
147210}
148211
149212define void @neg_mod (ptr %loc ) {
150- ; CHECK-LABEL: @neg_mod
151- ; CHECK-LABEL: loop:
152- ; CHECK: call void @store
153- ; CHECK-LABEL: exit:
213+ ; CHECK-LABEL: define void @neg_mod(
214+ ; CHECK-SAME: ptr [[LOC:%.*]]) {
215+ ; CHECK-NEXT: [[ENTRY:.*]]:
216+ ; CHECK-NEXT: br label %[[LOOP:.*]]
217+ ; CHECK: [[LOOP]]:
218+ ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
219+ ; CHECK-NEXT: call void @store(i32 0, ptr [[LOC]])
220+ ; CHECK-NEXT: store i32 [[IV]], ptr [[LOC]], align 4
221+ ; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
222+ ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[IV]], 200
223+ ; CHECK-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT:.*]]
224+ ; CHECK: [[EXIT]]:
225+ ; CHECK-NEXT: ret void
226+ ;
154227entry:
155228 br label %loop
156229
@@ -167,10 +240,25 @@ exit:
167240}
168241
169242define void @neg_ref (ptr %loc ) {
170- ; CHECK-LABEL: @neg_ref
171- ; CHECK-LABEL: loop:
172- ; CHECK: call void @store
173- ; CHECK-LABEL: exit1:
243+ ; CHECK-LABEL: define void @neg_ref(
244+ ; CHECK-SAME: ptr [[LOC:%.*]]) {
245+ ; CHECK-NEXT: [[ENTRY:.*]]:
246+ ; CHECK-NEXT: br label %[[LOOP:.*]]
247+ ; CHECK: [[LOOP]]:
248+ ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[BACKEDGE:.*]] ]
249+ ; CHECK-NEXT: call void @store(i32 0, ptr [[LOC]])
250+ ; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[LOC]], align 4
251+ ; CHECK-NEXT: [[EARLYCND:%.*]] = icmp eq i32 [[V]], 198
252+ ; CHECK-NEXT: br i1 [[EARLYCND]], label %[[EXIT1:.*]], label %[[BACKEDGE]]
253+ ; CHECK: [[BACKEDGE]]:
254+ ; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
255+ ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[IV]], 200
256+ ; CHECK-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT2:.*]]
257+ ; CHECK: [[EXIT1]]:
258+ ; CHECK-NEXT: ret void
259+ ; CHECK: [[EXIT2]]:
260+ ; CHECK-NEXT: ret void
261+ ;
174262entry:
175263 br label %loop
176264
@@ -195,10 +283,20 @@ exit2:
195283declare void @modref ()
196284
197285define void @neg_modref (ptr %loc ) {
198- ; CHECK-LABEL: @neg_modref
199- ; CHECK-LABEL: loop:
200- ; CHECK: call void @store
201- ; CHECK-LABEL: exit:
286+ ; CHECK-LABEL: define void @neg_modref(
287+ ; CHECK-SAME: ptr [[LOC:%.*]]) {
288+ ; CHECK-NEXT: [[ENTRY:.*]]:
289+ ; CHECK-NEXT: br label %[[LOOP:.*]]
290+ ; CHECK: [[LOOP]]:
291+ ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
292+ ; CHECK-NEXT: call void @store(i32 0, ptr [[LOC]])
293+ ; CHECK-NEXT: call void @modref()
294+ ; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
295+ ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[IV]], 200
296+ ; CHECK-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT:.*]]
297+ ; CHECK: [[EXIT]]:
298+ ; CHECK-NEXT: ret void
299+ ;
202300entry:
203301 br label %loop
204302
@@ -215,10 +313,20 @@ exit:
215313}
216314
217315define void @neg_fence (ptr %loc ) {
218- ; CHECK-LABEL: @neg_fence
219- ; CHECK-LABEL: loop:
220- ; CHECK: call void @store
221- ; CHECK-LABEL: exit:
316+ ; CHECK-LABEL: define void @neg_fence(
317+ ; CHECK-SAME: ptr [[LOC:%.*]]) {
318+ ; CHECK-NEXT: [[ENTRY:.*]]:
319+ ; CHECK-NEXT: br label %[[LOOP:.*]]
320+ ; CHECK: [[LOOP]]:
321+ ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
322+ ; CHECK-NEXT: call void @store(i32 0, ptr [[LOC]])
323+ ; CHECK-NEXT: fence seq_cst
324+ ; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
325+ ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[IV]], 200
326+ ; CHECK-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT:.*]]
327+ ; CHECK: [[EXIT]]:
328+ ; CHECK-NEXT: ret void
329+ ;
222330entry:
223331 br label %loop
224332
@@ -239,10 +347,19 @@ declare void @not_argmemonly(i32 %v, ptr %p) writeonly nounwind
239347declare void @not_writeonly (i32 %v , ptr %p ) argmemonly nounwind
240348
241349define void @neg_not_nounwind (ptr %loc ) {
242- ; CHECK-LABEL: @neg_not_nounwind
243- ; CHECK-LABEL: loop:
244- ; CHECK: call void @not_nounwind
245- ; CHECK-LABEL: exit:
350+ ; CHECK-LABEL: define void @neg_not_nounwind(
351+ ; CHECK-SAME: ptr [[LOC:%.*]]) {
352+ ; CHECK-NEXT: [[ENTRY:.*]]:
353+ ; CHECK-NEXT: br label %[[LOOP:.*]]
354+ ; CHECK: [[LOOP]]:
355+ ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
356+ ; CHECK-NEXT: call void @not_nounwind(i32 0, ptr [[LOC]])
357+ ; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
358+ ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[IV]], 200
359+ ; CHECK-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT:.*]]
360+ ; CHECK: [[EXIT]]:
361+ ; CHECK-NEXT: ret void
362+ ;
246363entry:
247364 br label %loop
248365
@@ -258,10 +375,19 @@ exit:
258375}
259376
260377define void @neg_not_argmemonly (ptr %loc ) {
261- ; CHECK-LABEL: @neg_not_argmemonly
262- ; CHECK-LABEL: loop:
263- ; CHECK: call void @not_argmemonly
264- ; CHECK-LABEL: exit:
378+ ; CHECK-LABEL: define void @neg_not_argmemonly(
379+ ; CHECK-SAME: ptr [[LOC:%.*]]) {
380+ ; CHECK-NEXT: [[ENTRY:.*]]:
381+ ; CHECK-NEXT: br label %[[LOOP:.*]]
382+ ; CHECK: [[LOOP]]:
383+ ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
384+ ; CHECK-NEXT: call void @not_argmemonly(i32 0, ptr [[LOC]])
385+ ; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
386+ ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[IV]], 200
387+ ; CHECK-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT:.*]]
388+ ; CHECK: [[EXIT]]:
389+ ; CHECK-NEXT: ret void
390+ ;
265391entry:
266392 br label %loop
267393
@@ -277,10 +403,19 @@ exit:
277403}
278404
279405define void @neg_not_writeonly (ptr %loc ) {
280- ; CHECK-LABEL: @neg_not_writeonly
281- ; CHECK-LABEL: loop:
282- ; CHECK: call void @not_writeonly
283- ; CHECK-LABEL: exit:
406+ ; CHECK-LABEL: define void @neg_not_writeonly(
407+ ; CHECK-SAME: ptr [[LOC:%.*]]) {
408+ ; CHECK-NEXT: [[ENTRY:.*]]:
409+ ; CHECK-NEXT: br label %[[LOOP:.*]]
410+ ; CHECK: [[LOOP]]:
411+ ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
412+ ; CHECK-NEXT: call void @not_writeonly(i32 0, ptr [[LOC]])
413+ ; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
414+ ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[IV]], 200
415+ ; CHECK-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT:.*]]
416+ ; CHECK: [[EXIT]]:
417+ ; CHECK-NEXT: ret void
418+ ;
284419entry:
285420 br label %loop
286421
0 commit comments