1; RUN: opt < %s -basicaa -licm -S | FileCheck %s
2; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' -S %s | FileCheck %s
3
4target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
5target triple = "x86_64-unknown-linux-gnu"
6
7; Make sure we don't hoist the store out of the loop; %a would
8; have the wrong value if f() unwinds
9
10define void @test1(i32* nocapture noalias %a, i1 zeroext %y) uwtable {
11entry:
12  br label %for.body
13
14for.body:
15  %i.03 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
16  %0 = load i32, i32* %a, align 4
17  %add = add nsw i32 %0, 1
18  store i32 %add, i32* %a, align 4
19  br i1 %y, label %if.then, label %for.inc
20
21; CHECK: define void @test1
22; CHECK: load i32, i32*
23; CHECK-NEXT: add
24; CHECK-NEXT: store i32
25
26if.then:
27  tail call void @f()
28  br label %for.inc
29
30for.inc:
31  %inc = add nuw nsw i32 %i.03, 1
32  %exitcond = icmp eq i32 %inc, 10000
33  br i1 %exitcond, label %for.cond.cleanup, label %for.body
34
35for.cond.cleanup:
36  ret void
37}
38
39; We can hoist the store out of the loop here; if f() unwinds,
40; the lifetime of %a ends.
41
42define void @test2(i1 zeroext %y) uwtable {
43entry:
44  %a = alloca i32
45  br label %for.body
46
47for.body:
48  %i.03 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
49  %0 = load i32, i32* %a, align 4
50  %add = add nsw i32 %0, 1
51  store i32 %add, i32* %a, align 4
52  br i1 %y, label %if.then, label %for.inc
53
54if.then:
55  tail call void @f()
56  br label %for.inc
57
58for.inc:
59  %inc = add nuw nsw i32 %i.03, 1
60  %exitcond = icmp eq i32 %inc, 10000
61  br i1 %exitcond, label %for.cond.cleanup, label %for.body
62
63for.cond.cleanup:
64; CHECK: define void @test2
65; CHECK: store i32
66; CHECK-NEXT: ret void
67  ret void
68}
69
70@_ZTIi = external constant i8*
71
72; In this test, the loop is within a try block. There is an explicit unwind edge out of the loop.
73; Make sure this edge is treated as a loop exit, and that the loads and stores are promoted as
74; expected
75define void @loop_within_tryblock() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
76entry:
77  %a = alloca i32, align 4
78  store i32 0, i32* %a, align 4
79  br label %for.cond
80
81for.cond:
82  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
83  %cmp = icmp slt i32 %i.0, 1024
84  br i1 %cmp, label %for.body, label %for.end
85
86; CHECK: for.body:
87; CHECK-NOT: load
88; CHECK-NOT: store
89; CHECK: invoke
90for.body:
91  %0 = load i32, i32* %a, align 4
92  %add = add nsw i32 %0, 1
93  store i32 %add, i32* %a, align 4
94  invoke void @boo()
95          to label %invoke.cont unwind label %lpad
96
97invoke.cont:
98  br label %for.inc
99
100for.inc:
101  %inc = add nsw i32 %i.0, 1
102  br label %for.cond
103
104; CHECK: lpad:
105; CHECK: store
106; CHECK: br
107lpad:
108  %1 = landingpad { i8*, i32 }
109          catch i8* bitcast (i8** @_ZTIi to i8*)
110  %2 = extractvalue { i8*, i32 } %1, 0
111  %3 = extractvalue { i8*, i32 } %1, 1
112  br label %catch.dispatch
113
114catch.dispatch:
115  %4 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*)) #3
116  %matches = icmp eq i32 %3, %4
117  br i1 %matches, label %catch, label %eh.resume
118
119catch:
120  %5 = call i8* @__cxa_begin_catch(i8* %2) #3
121  %6 = bitcast i8* %5 to i32*
122  %7 = load i32, i32* %6, align 4
123  call void @__cxa_end_catch() #3
124  br label %try.cont
125
126try.cont:
127  ret void
128
129for.end:
130  br label %try.cont
131
132eh.resume:
133  %lpad.val = insertvalue { i8*, i32 } undef, i8* %2, 0
134  %lpad.val3 = insertvalue { i8*, i32 } %lpad.val, i32 %3, 1
135  resume { i8*, i32 } %lpad.val3
136}
137
138
139; The malloc'ed memory is not capture and therefore promoted.
140define void @malloc_no_capture() #0 personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
141entry:
142  %call = call i8* @malloc(i64 4)
143  %0 = bitcast i8* %call to i32*
144  br label %for.body
145
146; CHECK: for.body:
147; CHECK-NOT: load
148; CHECK-NOT: store
149; CHECK: br
150for.body:
151  %i.0 = phi i32 [ 0, %entry  ], [ %inc, %for.latch ]
152  %1 = load i32, i32* %0, align 4
153  %add = add nsw i32 %1, 1
154  store i32 %add, i32* %0, align 4
155  br label %for.call
156
157for.call:
158  invoke void @boo()
159          to label %invoke.cont unwind label %lpad
160
161invoke.cont:
162  br label %for.latch
163
164for.latch:
165  %inc = add i32 %i.0, 1
166  %cmp = icmp slt i32 %i.0, 1024
167  br i1 %cmp, label %for.body, label %for.end
168
169for.end:
170  br label %fun.ret
171
172lpad:
173  %2 = landingpad { i8*, i32 }
174          catch i8* null
175  %3 = extractvalue { i8*, i32 } %2, 0
176  %4 = extractvalue { i8*, i32 } %2, 1
177  br label %catch
178
179catch:
180  %5 = call i8* @__cxa_begin_catch(i8* %3) #4
181  %6 = bitcast i32* %0 to i8*
182  call void @free(i8* %6)
183  call void @__cxa_end_catch()
184  br label %fun.ret
185
186fun.ret:
187  ret void
188}
189
190; The malloc'ed memory can be captured and therefore not promoted.
191define void @malloc_capture(i32** noalias %A) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
192entry:
193  %call = call i8* @malloc(i64 4)
194  %0 = bitcast i8* %call to i32*
195  br label %for.body
196
197; CHECK: for.body:
198; CHECK: load
199; CHECK: store
200; CHECK: br
201for.body:
202  %i.0 = phi i32 [ 0, %entry  ], [ %inc, %for.latch ]
203  %1 = load i32, i32* %0, align 4
204  %add = add nsw i32 %1, 1
205  store i32 %add, i32* %0, align 4
206  br label %for.call
207
208for.call:
209  invoke void @boo_readnone()
210          to label %invoke.cont unwind label %lpad
211
212invoke.cont:
213  br label %for.latch
214
215for.latch:
216  store i32* %0, i32** %A
217  %inc = add i32 %i.0, 1
218  %cmp = icmp slt i32 %i.0, 1024
219  br i1 %cmp, label %for.body, label %for.end
220
221for.end:
222  br label %fun.ret
223
224lpad:
225  %2 = landingpad { i8*, i32 }
226          catch i8* null
227  %3 = extractvalue { i8*, i32 } %2, 0
228  %4 = extractvalue { i8*, i32 } %2, 1
229  br label %catch
230
231catch:
232  %5 = call i8* @__cxa_begin_catch(i8* %3) #4
233  %6 = bitcast i32* %0 to i8*
234  call void @free(i8* %6)
235  call void @__cxa_end_catch()
236  br label %fun.ret
237
238fun.ret:
239  ret void
240}
241
242; Function Attrs: nounwind
243declare noalias i8* @malloc(i64)
244
245; Function Attrs: nounwind
246declare void @free(i8* nocapture)
247
248declare void @boo()
249
250; This is an artifical example, readnone functions by definition cannot unwind
251; exceptions by calling the C++ exception throwing methods
252; This function should only be used to test malloc_capture.
253declare void @boo_readnone() readnone
254
255declare i32 @__gxx_personality_v0(...)
256
257declare i8* @__cxa_begin_catch(i8*)
258
259declare void @__cxa_end_catch()
260
261declare i32 @llvm.eh.typeid.for(i8*)
262
263declare void @f() uwtable
264