Mercurial > hg > CbC > CbC_llvm
comparison llvm/test/Transforms/LICM/scalar-promote-unwind.ll @ 236:c4bab56944e8 llvm-original
LLVM 16
author | kono |
---|---|
date | Wed, 09 Nov 2022 17:45:10 +0900 |
parents | 79ff65ed7e25 |
children | 1f2b6ac9f198 |
comparison
equal
deleted
inserted
replaced
232:70dce7da266c | 236:c4bab56944e8 |
---|---|
1 ; RUN: opt < %s -basic-aa -licm -S | FileCheck %s | 1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py |
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 | 2 ; RUN: opt < %s -licm -S | FileCheck %s |
3 ; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop-mssa(licm)' -S %s | FileCheck %s | |
3 | 4 |
4 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | 5 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" |
5 target triple = "x86_64-unknown-linux-gnu" | 6 target triple = "x86_64-unknown-linux-gnu" |
6 | 7 |
7 ; Make sure we don't hoist the store out of the loop; %a would | 8 ; Make sure we don't hoist the store out of the loop; %a would |
8 ; have the wrong value if f() unwinds | 9 ; have the wrong value if f() unwinds |
9 | 10 define void @test1(ptr nocapture noalias %a, i1 zeroext %y) uwtable { |
10 define void @test1(i32* nocapture noalias %a, i1 zeroext %y) uwtable { | 11 ; CHECK-LABEL: @test1( |
12 ; CHECK-NEXT: entry: | |
13 ; CHECK-NEXT: [[A_PROMOTED:%.*]] = load i32, ptr [[A:%.*]], align 4 | |
14 ; CHECK-NEXT: br label [[FOR_BODY:%.*]] | |
15 ; CHECK: for.body: | |
16 ; CHECK-NEXT: [[ADD1:%.*]] = phi i32 [ [[A_PROMOTED]], [[ENTRY:%.*]] ], [ [[ADD:%.*]], [[FOR_INC:%.*]] ] | |
17 ; CHECK-NEXT: [[I_03:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC:%.*]], [[FOR_INC]] ] | |
18 ; CHECK-NEXT: [[ADD]] = add nsw i32 [[ADD1]], 1 | |
19 ; CHECK-NEXT: store i32 [[ADD]], ptr [[A]], align 4 | |
20 ; CHECK-NEXT: br i1 [[Y:%.*]], label [[IF_THEN:%.*]], label [[FOR_INC]] | |
21 ; CHECK: if.then: | |
22 ; CHECK-NEXT: tail call void @f() | |
23 ; CHECK-NEXT: br label [[FOR_INC]] | |
24 ; CHECK: for.inc: | |
25 ; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_03]], 1 | |
26 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 10000 | |
27 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]] | |
28 ; CHECK: for.cond.cleanup: | |
29 ; CHECK-NEXT: ret void | |
30 ; | |
11 entry: | 31 entry: |
12 br label %for.body | 32 br label %for.body |
13 | 33 |
14 for.body: | 34 for.body: |
15 %i.03 = phi i32 [ 0, %entry ], [ %inc, %for.inc ] | 35 %i.03 = phi i32 [ 0, %entry ], [ %inc, %for.inc ] |
16 %0 = load i32, i32* %a, align 4 | 36 %0 = load i32, ptr %a, align 4 |
17 %add = add nsw i32 %0, 1 | 37 %add = add nsw i32 %0, 1 |
18 store i32 %add, i32* %a, align 4 | 38 store i32 %add, ptr %a, align 4 |
19 br i1 %y, label %if.then, label %for.inc | 39 br i1 %y, label %if.then, label %for.inc |
20 | 40 |
21 ; CHECK: define void @test1 | |
22 ; CHECK: load i32, i32* | |
23 ; CHECK-NEXT: add | |
24 ; CHECK-NEXT: store i32 | |
25 | 41 |
26 if.then: | 42 if.then: |
27 tail call void @f() | 43 tail call void @f() |
28 br label %for.inc | 44 br label %for.inc |
29 | 45 |
36 ret void | 52 ret void |
37 } | 53 } |
38 | 54 |
39 ; We can hoist the store out of the loop here; if f() unwinds, | 55 ; We can hoist the store out of the loop here; if f() unwinds, |
40 ; the lifetime of %a ends. | 56 ; the lifetime of %a ends. |
41 | 57 define void @test_alloca(i1 zeroext %y) uwtable { |
42 define void @test2(i1 zeroext %y) uwtable { | 58 ; CHECK-LABEL: @test_alloca( |
59 ; CHECK-NEXT: entry: | |
60 ; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 | |
61 ; CHECK-NEXT: [[A_PROMOTED:%.*]] = load i32, ptr [[A]], align 4 | |
62 ; CHECK-NEXT: br label [[FOR_BODY:%.*]] | |
63 ; CHECK: for.body: | |
64 ; CHECK-NEXT: [[ADD1:%.*]] = phi i32 [ [[A_PROMOTED]], [[ENTRY:%.*]] ], [ [[ADD:%.*]], [[FOR_INC:%.*]] ] | |
65 ; CHECK-NEXT: [[I_03:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC:%.*]], [[FOR_INC]] ] | |
66 ; CHECK-NEXT: [[ADD]] = add nsw i32 [[ADD1]], 1 | |
67 ; CHECK-NEXT: br i1 [[Y:%.*]], label [[IF_THEN:%.*]], label [[FOR_INC]] | |
68 ; CHECK: if.then: | |
69 ; CHECK-NEXT: tail call void @f() | |
70 ; CHECK-NEXT: br label [[FOR_INC]] | |
71 ; CHECK: for.inc: | |
72 ; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_03]], 1 | |
73 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 10000 | |
74 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]] | |
75 ; CHECK: for.cond.cleanup: | |
76 ; CHECK-NEXT: [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_INC]] ] | |
77 ; CHECK-NEXT: store i32 [[ADD_LCSSA]], ptr [[A]], align 4 | |
78 ; CHECK-NEXT: ret void | |
79 ; | |
43 entry: | 80 entry: |
44 %a = alloca i32 | 81 %a = alloca i32 |
45 br label %for.body | 82 br label %for.body |
46 | 83 |
47 for.body: | 84 for.body: |
48 %i.03 = phi i32 [ 0, %entry ], [ %inc, %for.inc ] | 85 %i.03 = phi i32 [ 0, %entry ], [ %inc, %for.inc ] |
49 %0 = load i32, i32* %a, align 4 | 86 %0 = load i32, ptr %a, align 4 |
50 %add = add nsw i32 %0, 1 | 87 %add = add nsw i32 %0, 1 |
51 store i32 %add, i32* %a, align 4 | 88 store i32 %add, ptr %a, align 4 |
52 br i1 %y, label %if.then, label %for.inc | 89 br i1 %y, label %if.then, label %for.inc |
53 | 90 |
54 if.then: | 91 if.then: |
55 tail call void @f() | 92 tail call void @f() |
56 br label %for.inc | 93 br label %for.inc |
59 %inc = add nuw nsw i32 %i.03, 1 | 96 %inc = add nuw nsw i32 %i.03, 1 |
60 %exitcond = icmp eq i32 %inc, 10000 | 97 %exitcond = icmp eq i32 %inc, 10000 |
61 br i1 %exitcond, label %for.cond.cleanup, label %for.body | 98 br i1 %exitcond, label %for.cond.cleanup, label %for.body |
62 | 99 |
63 for.cond.cleanup: | 100 for.cond.cleanup: |
64 ; CHECK: define void @test2 | 101 ret void |
65 ; CHECK: store i32 | 102 } |
66 ; CHECK-NEXT: ret void | 103 |
104 ; byval memory cannot be accessed on unwind either. | |
105 define void @test_byval(ptr byval(i32) %a, i1 zeroext %y) uwtable { | |
106 ; CHECK-LABEL: @test_byval( | |
107 ; CHECK-NEXT: entry: | |
108 ; CHECK-NEXT: [[A_PROMOTED:%.*]] = load i32, ptr [[A:%.*]], align 4 | |
109 ; CHECK-NEXT: br label [[FOR_BODY:%.*]] | |
110 ; CHECK: for.body: | |
111 ; CHECK-NEXT: [[ADD1:%.*]] = phi i32 [ [[A_PROMOTED]], [[ENTRY:%.*]] ], [ [[ADD:%.*]], [[FOR_INC:%.*]] ] | |
112 ; CHECK-NEXT: [[I_03:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC:%.*]], [[FOR_INC]] ] | |
113 ; CHECK-NEXT: [[ADD]] = add nsw i32 [[ADD1]], 1 | |
114 ; CHECK-NEXT: br i1 [[Y:%.*]], label [[IF_THEN:%.*]], label [[FOR_INC]] | |
115 ; CHECK: if.then: | |
116 ; CHECK-NEXT: tail call void @f() | |
117 ; CHECK-NEXT: br label [[FOR_INC]] | |
118 ; CHECK: for.inc: | |
119 ; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_03]], 1 | |
120 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 10000 | |
121 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]] | |
122 ; CHECK: for.cond.cleanup: | |
123 ; CHECK-NEXT: [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_INC]] ] | |
124 ; CHECK-NEXT: store i32 [[ADD_LCSSA]], ptr [[A]], align 4 | |
125 ; CHECK-NEXT: ret void | |
126 ; | |
127 entry: | |
128 br label %for.body | |
129 | |
130 for.body: | |
131 %i.03 = phi i32 [ 0, %entry ], [ %inc, %for.inc ] | |
132 %0 = load i32, ptr %a, align 4 | |
133 %add = add nsw i32 %0, 1 | |
134 store i32 %add, ptr %a, align 4 | |
135 br i1 %y, label %if.then, label %for.inc | |
136 | |
137 if.then: | |
138 tail call void @f() | |
139 br label %for.inc | |
140 | |
141 for.inc: | |
142 %inc = add nuw nsw i32 %i.03, 1 | |
143 %exitcond = icmp eq i32 %inc, 10000 | |
144 br i1 %exitcond, label %for.cond.cleanup, label %for.body | |
145 | |
146 for.cond.cleanup: | |
147 ret void | |
148 } | |
149 | |
150 ; TODO: sret could be specified to not be accessed on unwind either. | |
151 define void @test_sret(ptr noalias sret(i32) %a, i1 zeroext %y) uwtable { | |
152 ; CHECK-LABEL: @test_sret( | |
153 ; CHECK-NEXT: entry: | |
154 ; CHECK-NEXT: [[A_PROMOTED:%.*]] = load i32, ptr [[A:%.*]], align 4 | |
155 ; CHECK-NEXT: br label [[FOR_BODY:%.*]] | |
156 ; CHECK: for.body: | |
157 ; CHECK-NEXT: [[ADD1:%.*]] = phi i32 [ [[A_PROMOTED]], [[ENTRY:%.*]] ], [ [[ADD:%.*]], [[FOR_INC:%.*]] ] | |
158 ; CHECK-NEXT: [[I_03:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC:%.*]], [[FOR_INC]] ] | |
159 ; CHECK-NEXT: [[ADD]] = add nsw i32 [[ADD1]], 1 | |
160 ; CHECK-NEXT: store i32 [[ADD]], ptr [[A]], align 4 | |
161 ; CHECK-NEXT: br i1 [[Y:%.*]], label [[IF_THEN:%.*]], label [[FOR_INC]] | |
162 ; CHECK: if.then: | |
163 ; CHECK-NEXT: tail call void @f() | |
164 ; CHECK-NEXT: br label [[FOR_INC]] | |
165 ; CHECK: for.inc: | |
166 ; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_03]], 1 | |
167 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 10000 | |
168 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]] | |
169 ; CHECK: for.cond.cleanup: | |
170 ; CHECK-NEXT: ret void | |
171 ; | |
172 entry: | |
173 br label %for.body | |
174 | |
175 for.body: | |
176 %i.03 = phi i32 [ 0, %entry ], [ %inc, %for.inc ] | |
177 %0 = load i32, ptr %a, align 4 | |
178 %add = add nsw i32 %0, 1 | |
179 store i32 %add, ptr %a, align 4 | |
180 br i1 %y, label %if.then, label %for.inc | |
181 | |
182 if.then: | |
183 tail call void @f() | |
184 br label %for.inc | |
185 | |
186 for.inc: | |
187 %inc = add nuw nsw i32 %i.03, 1 | |
188 %exitcond = icmp eq i32 %inc, 10000 | |
189 br i1 %exitcond, label %for.cond.cleanup, label %for.body | |
190 | |
191 for.cond.cleanup: | |
67 ret void | 192 ret void |
68 } | 193 } |
69 | 194 |
70 ;; We can promote if the load can be proven safe to speculate, and the | 195 ;; We can promote if the load can be proven safe to speculate, and the |
71 ;; store safe to sink, even if the the store *isn't* must execute. | 196 ;; store safe to sink, even if the the store *isn't* must execute. |
72 define void @test3(i1 zeroext %y) uwtable { | 197 define void @test3(i1 zeroext %y) uwtable { |
73 ; CHECK-LABEL: @test3 | 198 ; CHECK-LABEL: @test3( |
74 entry: | 199 ; CHECK-NEXT: entry: |
75 ; CHECK-LABEL: entry: | 200 ; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 |
76 ; CHECK-NEXT: %a = alloca i32 | 201 ; CHECK-NEXT: [[A_PROMOTED:%.*]] = load i32, ptr [[A]], align 4 |
77 ; CHECK-NEXT: %a.promoted = load i32, i32* %a, align 4 | 202 ; CHECK-NEXT: br label [[FOR_BODY:%.*]] |
203 ; CHECK: for.body: | |
204 ; CHECK-NEXT: [[ADD1:%.*]] = phi i32 [ [[A_PROMOTED]], [[ENTRY:%.*]] ], [ [[ADD:%.*]], [[FOR_BODY]] ] | |
205 ; CHECK-NEXT: [[I_03:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC:%.*]], [[FOR_BODY]] ] | |
206 ; CHECK-NEXT: [[ADD]] = add nsw i32 [[ADD1]], 1 | |
207 ; CHECK-NEXT: tail call void @f() | |
208 ; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_03]], 1 | |
209 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 10000 | |
210 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]] | |
211 ; CHECK: for.cond.cleanup: | |
212 ; CHECK-NEXT: [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_BODY]] ] | |
213 ; CHECK-NEXT: store i32 [[ADD_LCSSA]], ptr [[A]], align 4 | |
214 ; CHECK-NEXT: ret void | |
215 ; | |
216 entry: | |
78 %a = alloca i32 | 217 %a = alloca i32 |
79 br label %for.body | 218 br label %for.body |
80 | 219 |
81 for.body: | 220 for.body: |
82 %i.03 = phi i32 [ 0, %entry ], [ %inc, %for.body ] | 221 %i.03 = phi i32 [ 0, %entry ], [ %inc, %for.body ] |
83 %0 = load i32, i32* %a, align 4 | 222 %0 = load i32, ptr %a, align 4 |
84 %add = add nsw i32 %0, 1 | 223 %add = add nsw i32 %0, 1 |
85 tail call void @f() | 224 tail call void @f() |
86 store i32 %add, i32* %a, align 4 | 225 store i32 %add, ptr %a, align 4 |
87 %inc = add nuw nsw i32 %i.03, 1 | 226 %inc = add nuw nsw i32 %i.03, 1 |
88 %exitcond = icmp eq i32 %inc, 10000 | 227 %exitcond = icmp eq i32 %inc, 10000 |
89 br i1 %exitcond, label %for.cond.cleanup, label %for.body | 228 br i1 %exitcond, label %for.cond.cleanup, label %for.body |
90 | 229 |
91 for.cond.cleanup: | 230 for.cond.cleanup: |
92 ; CHECK-LABEL: for.cond.cleanup: | |
93 ; CHECK: store i32 %add.lcssa, i32* %a, align 4 | |
94 ; CHECK-NEXT: ret void | |
95 ret void | 231 ret void |
96 } | 232 } |
97 | 233 |
98 ;; Same as test3, but with unordered atomics | 234 ;; Same as test3, but with unordered atomics |
99 define void @test3b(i1 zeroext %y) uwtable { | 235 define void @test3b(i1 zeroext %y) uwtable { |
100 ; CHECK-LABEL: @test3 | 236 ; CHECK-LABEL: @test3b( |
101 entry: | 237 ; CHECK-NEXT: entry: |
102 ; CHECK-LABEL: entry: | 238 ; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 |
103 ; CHECK-NEXT: %a = alloca i32 | 239 ; CHECK-NEXT: [[A_PROMOTED:%.*]] = load atomic i32, ptr [[A]] unordered, align 4 |
104 ; CHECK-NEXT: %a.promoted = load atomic i32, i32* %a unordered, align 4 | 240 ; CHECK-NEXT: br label [[FOR_BODY:%.*]] |
241 ; CHECK: for.body: | |
242 ; CHECK-NEXT: [[ADD1:%.*]] = phi i32 [ [[A_PROMOTED]], [[ENTRY:%.*]] ], [ [[ADD:%.*]], [[FOR_BODY]] ] | |
243 ; CHECK-NEXT: [[I_03:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC:%.*]], [[FOR_BODY]] ] | |
244 ; CHECK-NEXT: [[ADD]] = add nsw i32 [[ADD1]], 1 | |
245 ; CHECK-NEXT: tail call void @f() | |
246 ; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_03]], 1 | |
247 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 10000 | |
248 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]] | |
249 ; CHECK: for.cond.cleanup: | |
250 ; CHECK-NEXT: [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_BODY]] ] | |
251 ; CHECK-NEXT: store atomic i32 [[ADD_LCSSA]], ptr [[A]] unordered, align 4 | |
252 ; CHECK-NEXT: ret void | |
253 ; | |
254 entry: | |
105 %a = alloca i32 | 255 %a = alloca i32 |
106 br label %for.body | 256 br label %for.body |
107 | 257 |
108 for.body: | 258 for.body: |
109 %i.03 = phi i32 [ 0, %entry ], [ %inc, %for.body ] | 259 %i.03 = phi i32 [ 0, %entry ], [ %inc, %for.body ] |
110 %0 = load atomic i32, i32* %a unordered, align 4 | 260 %0 = load atomic i32, ptr %a unordered, align 4 |
111 %add = add nsw i32 %0, 1 | 261 %add = add nsw i32 %0, 1 |
112 tail call void @f() | 262 tail call void @f() |
113 store atomic i32 %add, i32* %a unordered, align 4 | 263 store atomic i32 %add, ptr %a unordered, align 4 |
114 %inc = add nuw nsw i32 %i.03, 1 | 264 %inc = add nuw nsw i32 %i.03, 1 |
115 %exitcond = icmp eq i32 %inc, 10000 | 265 %exitcond = icmp eq i32 %inc, 10000 |
116 br i1 %exitcond, label %for.cond.cleanup, label %for.body | 266 br i1 %exitcond, label %for.cond.cleanup, label %for.body |
117 | 267 |
118 for.cond.cleanup: | 268 for.cond.cleanup: |
119 ; CHECK-LABEL: for.cond.cleanup: | 269 ret void |
120 ; CHECK: store atomic i32 %add.lcssa, i32* %a unordered, align 4 | 270 } |
121 ; CHECK-NEXT: ret void | 271 |
122 ret void | 272 @_ZTIi = external constant ptr |
123 } | |
124 | |
125 @_ZTIi = external constant i8* | |
126 | 273 |
127 ; In this test, the loop is within a try block. There is an explicit unwind edge out of the loop. | 274 ; In this test, the loop is within a try block. There is an explicit unwind edge out of the loop. |
128 ; Make sure this edge is treated as a loop exit, and that the loads and stores are promoted as | 275 ; Make sure this edge is treated as a loop exit, and that the loads and stores are promoted as |
129 ; expected | 276 ; expected |
130 define void @loop_within_tryblock() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { | 277 define void @loop_within_tryblock() personality ptr @__gxx_personality_v0 { |
278 ; CHECK-LABEL: @loop_within_tryblock( | |
279 ; CHECK-NEXT: entry: | |
280 ; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 | |
281 ; CHECK-NEXT: store i32 0, ptr [[A]], align 4 | |
282 ; CHECK-NEXT: [[A_PROMOTED:%.*]] = load i32, ptr [[A]], align 4 | |
283 ; CHECK-NEXT: br label [[FOR_COND:%.*]] | |
284 ; CHECK: for.cond: | |
285 ; CHECK-NEXT: [[ADD1:%.*]] = phi i32 [ [[A_PROMOTED]], [[ENTRY:%.*]] ], [ [[ADD:%.*]], [[FOR_INC:%.*]] ] | |
286 ; CHECK-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC:%.*]], [[FOR_INC]] ] | |
287 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_0]], 1024 | |
288 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]] | |
289 ; CHECK: for.body: | |
290 ; CHECK-NEXT: [[ADD]] = add nsw i32 [[ADD1]], 1 | |
291 ; CHECK-NEXT: invoke void @boo() | |
292 ; CHECK-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] | |
293 ; CHECK: invoke.cont: | |
294 ; CHECK-NEXT: br label [[FOR_INC]] | |
295 ; CHECK: for.inc: | |
296 ; CHECK-NEXT: [[INC]] = add nsw i32 [[I_0]], 1 | |
297 ; CHECK-NEXT: br label [[FOR_COND]] | |
298 ; CHECK: lpad: | |
299 ; CHECK-NEXT: [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_BODY]] ] | |
300 ; CHECK-NEXT: [[TMP0:%.*]] = landingpad { ptr, i32 } | |
301 ; CHECK-NEXT: catch ptr @_ZTIi | |
302 ; CHECK-NEXT: store i32 [[ADD_LCSSA]], ptr [[A]], align 4 | |
303 ; CHECK-NEXT: [[TMP1:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 0 | |
304 ; CHECK-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 1 | |
305 ; CHECK-NEXT: br label [[CATCH_DISPATCH:%.*]] | |
306 ; CHECK: catch.dispatch: | |
307 ; CHECK-NEXT: [[TMP3:%.*]] = call i32 @llvm.eh.typeid.for(ptr @_ZTIi) | |
308 ; CHECK-NEXT: [[MATCHES:%.*]] = icmp eq i32 [[TMP2]], [[TMP3]] | |
309 ; CHECK-NEXT: br i1 [[MATCHES]], label [[CATCH:%.*]], label [[EH_RESUME:%.*]] | |
310 ; CHECK: catch: | |
311 ; CHECK-NEXT: [[TMP4:%.*]] = call ptr @__cxa_begin_catch(ptr [[TMP1]]) | |
312 ; CHECK-NEXT: [[TMP6:%.*]] = load i32, ptr [[TMP4]], align 4 | |
313 ; CHECK-NEXT: call void @__cxa_end_catch() | |
314 ; CHECK-NEXT: br label [[TRY_CONT:%.*]] | |
315 ; CHECK: try.cont: | |
316 ; CHECK-NEXT: ret void | |
317 ; CHECK: for.end: | |
318 ; CHECK-NEXT: [[ADD1_LCSSA:%.*]] = phi i32 [ [[ADD1]], [[FOR_COND]] ] | |
319 ; CHECK-NEXT: store i32 [[ADD1_LCSSA]], ptr [[A]], align 4 | |
320 ; CHECK-NEXT: br label [[TRY_CONT]] | |
321 ; CHECK: eh.resume: | |
322 ; CHECK-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } undef, ptr [[TMP1]], 0 | |
323 ; CHECK-NEXT: [[LPAD_VAL3:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[TMP2]], 1 | |
324 ; CHECK-NEXT: resume { ptr, i32 } [[LPAD_VAL3]] | |
325 ; | |
131 entry: | 326 entry: |
132 %a = alloca i32, align 4 | 327 %a = alloca i32, align 4 |
133 store i32 0, i32* %a, align 4 | 328 store i32 0, ptr %a, align 4 |
134 br label %for.cond | 329 br label %for.cond |
135 | 330 |
136 for.cond: | 331 for.cond: |
137 %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ] | 332 %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ] |
138 %cmp = icmp slt i32 %i.0, 1024 | 333 %cmp = icmp slt i32 %i.0, 1024 |
139 br i1 %cmp, label %for.body, label %for.end | 334 br i1 %cmp, label %for.body, label %for.end |
140 | 335 |
141 ; CHECK: for.body: | 336 for.body: |
142 ; CHECK-NOT: load | 337 %0 = load i32, ptr %a, align 4 |
143 ; CHECK-NOT: store | 338 %add = add nsw i32 %0, 1 |
144 ; CHECK: invoke | 339 store i32 %add, ptr %a, align 4 |
145 for.body: | |
146 %0 = load i32, i32* %a, align 4 | |
147 %add = add nsw i32 %0, 1 | |
148 store i32 %add, i32* %a, align 4 | |
149 invoke void @boo() | 340 invoke void @boo() |
150 to label %invoke.cont unwind label %lpad | 341 to label %invoke.cont unwind label %lpad |
151 | 342 |
152 invoke.cont: | 343 invoke.cont: |
153 br label %for.inc | 344 br label %for.inc |
154 | 345 |
155 for.inc: | 346 for.inc: |
156 %inc = add nsw i32 %i.0, 1 | 347 %inc = add nsw i32 %i.0, 1 |
157 br label %for.cond | 348 br label %for.cond |
158 | 349 |
159 ; CHECK: lpad: | |
160 ; CHECK: store | |
161 ; CHECK: br | |
162 lpad: | 350 lpad: |
163 %1 = landingpad { i8*, i32 } | 351 %1 = landingpad { ptr, i32 } |
164 catch i8* bitcast (i8** @_ZTIi to i8*) | 352 catch ptr @_ZTIi |
165 %2 = extractvalue { i8*, i32 } %1, 0 | 353 %2 = extractvalue { ptr, i32 } %1, 0 |
166 %3 = extractvalue { i8*, i32 } %1, 1 | 354 %3 = extractvalue { ptr, i32 } %1, 1 |
167 br label %catch.dispatch | 355 br label %catch.dispatch |
168 | 356 |
169 catch.dispatch: | 357 catch.dispatch: |
170 %4 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*)) #3 | 358 %4 = call i32 @llvm.eh.typeid.for(ptr @_ZTIi) #3 |
171 %matches = icmp eq i32 %3, %4 | 359 %matches = icmp eq i32 %3, %4 |
172 br i1 %matches, label %catch, label %eh.resume | 360 br i1 %matches, label %catch, label %eh.resume |
173 | 361 |
174 catch: | 362 catch: |
175 %5 = call i8* @__cxa_begin_catch(i8* %2) #3 | 363 %5 = call ptr @__cxa_begin_catch(ptr %2) #3 |
176 %6 = bitcast i8* %5 to i32* | 364 %6 = load i32, ptr %5, align 4 |
177 %7 = load i32, i32* %6, align 4 | |
178 call void @__cxa_end_catch() #3 | 365 call void @__cxa_end_catch() #3 |
179 br label %try.cont | 366 br label %try.cont |
180 | 367 |
181 try.cont: | 368 try.cont: |
182 ret void | 369 ret void |
183 | 370 |
184 for.end: | 371 for.end: |
185 br label %try.cont | 372 br label %try.cont |
186 | 373 |
187 eh.resume: | 374 eh.resume: |
188 %lpad.val = insertvalue { i8*, i32 } undef, i8* %2, 0 | 375 %lpad.val = insertvalue { ptr, i32 } undef, ptr %2, 0 |
189 %lpad.val3 = insertvalue { i8*, i32 } %lpad.val, i32 %3, 1 | 376 %lpad.val3 = insertvalue { ptr, i32 } %lpad.val, i32 %3, 1 |
190 resume { i8*, i32 } %lpad.val3 | 377 resume { ptr, i32 } %lpad.val3 |
191 } | 378 } |
192 | 379 |
193 | 380 |
194 ; The malloc'ed memory is not capture and therefore promoted. | 381 ; The malloc'ed memory is not capture and therefore promoted. |
195 define void @malloc_no_capture() #0 personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { | 382 define void @malloc_no_capture() #0 personality ptr @__gxx_personality_v0 { |
196 entry: | 383 ; CHECK-LABEL: @malloc_no_capture( |
197 %call = call i8* @malloc(i64 4) | 384 ; CHECK-NEXT: entry: |
198 %0 = bitcast i8* %call to i32* | 385 ; CHECK-NEXT: [[CALL:%.*]] = call ptr @malloc(i64 4) |
199 br label %for.body | 386 ; CHECK-NEXT: [[DOTPROMOTED:%.*]] = load i32, ptr [[CALL]], align 4 |
200 | 387 ; CHECK-NEXT: br label [[FOR_BODY:%.*]] |
201 ; CHECK: for.body: | 388 ; CHECK: for.body: |
202 ; CHECK-NOT: load | 389 ; CHECK-NEXT: [[ADD1:%.*]] = phi i32 [ [[DOTPROMOTED]], [[ENTRY:%.*]] ], [ [[ADD:%.*]], [[FOR_LATCH:%.*]] ] |
203 ; CHECK-NOT: store | 390 ; CHECK-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC:%.*]], [[FOR_LATCH]] ] |
204 ; CHECK: br | 391 ; CHECK-NEXT: [[ADD]] = add nsw i32 [[ADD1]], 1 |
392 ; CHECK-NEXT: br label [[FOR_CALL:%.*]] | |
393 ; CHECK: for.call: | |
394 ; CHECK-NEXT: invoke void @boo() | |
395 ; CHECK-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] | |
396 ; CHECK: invoke.cont: | |
397 ; CHECK-NEXT: br label [[FOR_LATCH]] | |
398 ; CHECK: for.latch: | |
399 ; CHECK-NEXT: [[INC]] = add i32 [[I_0]], 1 | |
400 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_0]], 1024 | |
401 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] | |
402 ; CHECK: for.end: | |
403 ; CHECK-NEXT: [[ADD_LCSSA2:%.*]] = phi i32 [ [[ADD]], [[FOR_LATCH]] ] | |
404 ; CHECK-NEXT: store i32 [[ADD_LCSSA2]], ptr [[CALL]], align 4 | |
405 ; CHECK-NEXT: br label [[FUN_RET:%.*]] | |
406 ; CHECK: lpad: | |
407 ; CHECK-NEXT: [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[FOR_CALL]] ] | |
408 ; CHECK-NEXT: [[TMP1:%.*]] = landingpad { ptr, i32 } | |
409 ; CHECK-NEXT: catch ptr null | |
410 ; CHECK-NEXT: store i32 [[ADD_LCSSA]], ptr [[CALL]], align 4 | |
411 ; CHECK-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 0 | |
412 ; CHECK-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 1 | |
413 ; CHECK-NEXT: br label [[CATCH:%.*]] | |
414 ; CHECK: catch: | |
415 ; CHECK-NEXT: [[TMP4:%.*]] = call ptr @__cxa_begin_catch(ptr [[TMP2]]) | |
416 ; CHECK-NEXT: call void @free(ptr [[CALL]]) | |
417 ; CHECK-NEXT: call void @__cxa_end_catch() | |
418 ; CHECK-NEXT: br label [[FUN_RET]] | |
419 ; CHECK: fun.ret: | |
420 ; CHECK-NEXT: ret void | |
421 ; | |
422 entry: | |
423 %call = call ptr @malloc(i64 4) | |
424 br label %for.body | |
425 | |
205 for.body: | 426 for.body: |
206 %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.latch ] | 427 %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.latch ] |
207 %1 = load i32, i32* %0, align 4 | 428 %0 = load i32, ptr %call, align 4 |
208 %add = add nsw i32 %1, 1 | 429 %add = add nsw i32 %0, 1 |
209 store i32 %add, i32* %0, align 4 | 430 store i32 %add, ptr %call, align 4 |
210 br label %for.call | 431 br label %for.call |
211 | 432 |
212 for.call: | 433 for.call: |
213 invoke void @boo() | 434 invoke void @boo() |
214 to label %invoke.cont unwind label %lpad | 435 to label %invoke.cont unwind label %lpad |
215 | 436 |
216 invoke.cont: | 437 invoke.cont: |
217 br label %for.latch | 438 br label %for.latch |
218 | 439 |
219 for.latch: | 440 for.latch: |
223 | 444 |
224 for.end: | 445 for.end: |
225 br label %fun.ret | 446 br label %fun.ret |
226 | 447 |
227 lpad: | 448 lpad: |
228 %2 = landingpad { i8*, i32 } | 449 %1 = landingpad { ptr, i32 } |
229 catch i8* null | 450 catch ptr null |
230 %3 = extractvalue { i8*, i32 } %2, 0 | 451 %2 = extractvalue { ptr, i32 } %1, 0 |
231 %4 = extractvalue { i8*, i32 } %2, 1 | 452 %3 = extractvalue { ptr, i32 } %1, 1 |
232 br label %catch | 453 br label %catch |
233 | 454 |
234 catch: | 455 catch: |
235 %5 = call i8* @__cxa_begin_catch(i8* %3) #4 | 456 %4 = call ptr @__cxa_begin_catch(ptr %2) #4 |
236 %6 = bitcast i32* %0 to i8* | 457 call void @free(ptr %call) |
237 call void @free(i8* %6) | |
238 call void @__cxa_end_catch() | 458 call void @__cxa_end_catch() |
239 br label %fun.ret | 459 br label %fun.ret |
240 | 460 |
241 fun.ret: | 461 fun.ret: |
242 ret void | 462 ret void |
243 } | 463 } |
244 | 464 |
245 ; The malloc'ed memory can be captured and therefore not promoted. | 465 ; The malloc'ed memory can be captured and therefore only loads can be promoted. |
246 define void @malloc_capture(i32** noalias %A) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { | 466 define void @malloc_capture(ptr noalias %A) personality ptr @__gxx_personality_v0 { |
247 entry: | 467 ; CHECK-LABEL: @malloc_capture( |
248 %call = call i8* @malloc(i64 4) | 468 ; CHECK-NEXT: entry: |
249 %0 = bitcast i8* %call to i32* | 469 ; CHECK-NEXT: [[CALL:%.*]] = call ptr @malloc(i64 4) |
250 br label %for.body | 470 ; CHECK-NEXT: [[DOTPROMOTED:%.*]] = load i32, ptr [[CALL]], align 4 |
251 | 471 ; CHECK-NEXT: br label [[FOR_BODY:%.*]] |
252 ; CHECK: for.body: | 472 ; CHECK: for.body: |
253 ; CHECK: load | 473 ; CHECK-NEXT: [[ADD1:%.*]] = phi i32 [ [[DOTPROMOTED]], [[ENTRY:%.*]] ], [ [[ADD:%.*]], [[FOR_LATCH:%.*]] ] |
254 ; CHECK: store | 474 ; CHECK-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC:%.*]], [[FOR_LATCH]] ] |
255 ; CHECK: br | 475 ; CHECK-NEXT: [[ADD]] = add nsw i32 [[ADD1]], 1 |
476 ; CHECK-NEXT: store i32 [[ADD]], ptr [[CALL]], align 4 | |
477 ; CHECK-NEXT: br label [[FOR_CALL:%.*]] | |
478 ; CHECK: for.call: | |
479 ; CHECK-NEXT: invoke void @boo_readnone() | |
480 ; CHECK-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] | |
481 ; CHECK: invoke.cont: | |
482 ; CHECK-NEXT: br label [[FOR_LATCH]] | |
483 ; CHECK: for.latch: | |
484 ; CHECK-NEXT: store ptr [[CALL]], ptr [[A:%.*]], align 8 | |
485 ; CHECK-NEXT: [[INC]] = add i32 [[I_0]], 1 | |
486 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_0]], 1024 | |
487 ; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] | |
488 ; CHECK: for.end: | |
489 ; CHECK-NEXT: br label [[FUN_RET:%.*]] | |
490 ; CHECK: lpad: | |
491 ; CHECK-NEXT: [[TMP1:%.*]] = landingpad { ptr, i32 } | |
492 ; CHECK-NEXT: catch ptr null | |
493 ; CHECK-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 0 | |
494 ; CHECK-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 1 | |
495 ; CHECK-NEXT: br label [[CATCH:%.*]] | |
496 ; CHECK: catch: | |
497 ; CHECK-NEXT: [[TMP4:%.*]] = call ptr @__cxa_begin_catch(ptr [[TMP2]]) | |
498 ; CHECK-NEXT: call void @free(ptr [[CALL]]) | |
499 ; CHECK-NEXT: call void @__cxa_end_catch() | |
500 ; CHECK-NEXT: br label [[FUN_RET]] | |
501 ; CHECK: fun.ret: | |
502 ; CHECK-NEXT: ret void | |
503 ; | |
504 entry: | |
505 %call = call ptr @malloc(i64 4) | |
506 br label %for.body | |
507 | |
256 for.body: | 508 for.body: |
257 %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.latch ] | 509 %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.latch ] |
258 %1 = load i32, i32* %0, align 4 | 510 %0 = load i32, ptr %call, align 4 |
259 %add = add nsw i32 %1, 1 | 511 %add = add nsw i32 %0, 1 |
260 store i32 %add, i32* %0, align 4 | 512 store i32 %add, ptr %call, align 4 |
261 br label %for.call | 513 br label %for.call |
262 | 514 |
263 for.call: | 515 for.call: |
264 invoke void @boo_readnone() | 516 invoke void @boo_readnone() |
265 to label %invoke.cont unwind label %lpad | 517 to label %invoke.cont unwind label %lpad |
266 | 518 |
267 invoke.cont: | 519 invoke.cont: |
268 br label %for.latch | 520 br label %for.latch |
269 | 521 |
270 for.latch: | 522 for.latch: |
271 store i32* %0, i32** %A | 523 store ptr %call, ptr %A |
272 %inc = add i32 %i.0, 1 | 524 %inc = add i32 %i.0, 1 |
273 %cmp = icmp slt i32 %i.0, 1024 | 525 %cmp = icmp slt i32 %i.0, 1024 |
274 br i1 %cmp, label %for.body, label %for.end | 526 br i1 %cmp, label %for.body, label %for.end |
275 | 527 |
276 for.end: | 528 for.end: |
277 br label %fun.ret | 529 br label %fun.ret |
278 | 530 |
279 lpad: | 531 lpad: |
280 %2 = landingpad { i8*, i32 } | 532 %1 = landingpad { ptr, i32 } |
281 catch i8* null | 533 catch ptr null |
282 %3 = extractvalue { i8*, i32 } %2, 0 | 534 %2 = extractvalue { ptr, i32 } %1, 0 |
283 %4 = extractvalue { i8*, i32 } %2, 1 | 535 %3 = extractvalue { ptr, i32 } %1, 1 |
284 br label %catch | 536 br label %catch |
285 | 537 |
286 catch: | 538 catch: |
287 %5 = call i8* @__cxa_begin_catch(i8* %3) #4 | 539 %4 = call ptr @__cxa_begin_catch(ptr %2) #4 |
288 %6 = bitcast i32* %0 to i8* | 540 call void @free(ptr %call) |
289 call void @free(i8* %6) | |
290 call void @__cxa_end_catch() | 541 call void @__cxa_end_catch() |
291 br label %fun.ret | 542 br label %fun.ret |
292 | 543 |
293 fun.ret: | 544 fun.ret: |
294 ret void | 545 ret void |
295 } | 546 } |
296 | 547 |
297 ; Function Attrs: nounwind | 548 ; Function Attrs: nounwind |
298 declare noalias i8* @malloc(i64) | 549 declare noalias ptr @malloc(i64) |
299 | 550 |
300 ; Function Attrs: nounwind | 551 ; Function Attrs: nounwind |
301 declare void @free(i8* nocapture) | 552 declare void @free(ptr nocapture) |
302 | 553 |
303 declare void @boo() | 554 declare void @boo() |
304 | 555 |
305 ; This is an artifical example, readnone functions by definition cannot unwind | 556 ; This is an artifical example, readnone functions by definition cannot unwind |
306 ; exceptions by calling the C++ exception throwing methods | 557 ; exceptions by calling the C++ exception throwing methods |
307 ; This function should only be used to test malloc_capture. | 558 ; This function should only be used to test malloc_capture. |
308 declare void @boo_readnone() readnone | 559 declare void @boo_readnone() readnone |
309 | 560 |
310 declare i32 @__gxx_personality_v0(...) | 561 declare i32 @__gxx_personality_v0(...) |
311 | 562 |
312 declare i8* @__cxa_begin_catch(i8*) | 563 declare ptr @__cxa_begin_catch(ptr) |
313 | 564 |
314 declare void @__cxa_end_catch() | 565 declare void @__cxa_end_catch() |
315 | 566 |
316 declare i32 @llvm.eh.typeid.for(i8*) | 567 declare i32 @llvm.eh.typeid.for(ptr) |
317 | 568 |
318 declare void @f() uwtable | 569 declare void @f() uwtable |