Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / SimplifyCFG / hoist-with-metadata.ll
blobcbf2924b281988014538bae6bb6aa0bc3d5b3939
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals
2 ; RUN: opt < %s -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -hoist-common-insts=true -S | FileCheck %s
4 define void @hoist_range(i1 %c, ptr %p) {
5 ; CHECK-LABEL: @hoist_range(
6 ; CHECK-NEXT:  if:
7 ; CHECK-NEXT:    [[T:%.*]] = load i8, ptr [[P:%.*]], align 1, !range [[RNG0:![0-9]+]]
8 ; CHECK-NEXT:    ret void
10 if:
11   br i1 %c, label %then, label %else
12 then:
13   %t = load i8, ptr %p, !range !0
14   br label %out
15 else:
16   %e = load i8, ptr %p, !range !1
17   br label %out
18 out:
19   ret void
22 define void @hoist_range_switch(i64 %i, ptr %p) {
23 ; CHECK-LABEL: @hoist_range_switch(
24 ; CHECK-NEXT:  out:
25 ; CHECK-NEXT:    [[T:%.*]] = load i8, ptr [[P:%.*]], align 1, !range [[RNG1:![0-9]+]]
26 ; CHECK-NEXT:    ret void
28   switch i64 %i, label %bb0 [
29   i64 1, label %bb1
30   i64 2, label %bb2
31   ]
32 bb0:
33   %t = load i8, ptr %p, !range !0
34   br label %out
35 bb1:
36   %e = load i8, ptr %p, !range !1
37   br label %out
38 bb2:
39   %f = load i8, ptr %p, !range !3
40   br label %out
41 out:
42   ret void
45 define void @hoist_both_noundef(i1 %c, ptr %p) {
46 ; CHECK-LABEL: @hoist_both_noundef(
47 ; CHECK-NEXT:  if:
48 ; CHECK-NEXT:    [[T:%.*]] = load i8, ptr [[P:%.*]], align 1, !noundef [[META2:![0-9]+]]
49 ; CHECK-NEXT:    ret void
51 if:
52   br i1 %c, label %then, label %else
54 then:
55   %t = load i8, ptr %p, !noundef !2
56   br label %out
58 else:
59   %e = load i8, ptr %p, !noundef !2
60   br label %out
62 out:
63   ret void
67 define void @hoist_both_noundef_switch(i64 %i, ptr %p) {
68 ; CHECK-LABEL: @hoist_both_noundef_switch(
69 ; CHECK-NEXT:  out:
70 ; CHECK-NEXT:    [[T:%.*]] = load i8, ptr [[P:%.*]], align 1, !noundef [[META2]]
71 ; CHECK-NEXT:    ret void
73   switch i64 %i, label %bb0 [
74   i64 1, label %bb1
75   i64 2, label %bb2
76   ]
77 bb0:
78   %t = load i8, ptr %p, !noundef !2
79   br label %out
80 bb1:
81   %e = load i8, ptr %p, !noundef !2
82   br label %out
83 bb2:
84   %f = load i8, ptr %p, !noundef !2
85   br label %out
86 out:
87   ret void
90 define void @hoist_one_noundef(i1 %c, ptr %p) {
91 ; CHECK-LABEL: @hoist_one_noundef(
92 ; CHECK-NEXT:  if:
93 ; CHECK-NEXT:    [[T:%.*]] = load i8, ptr [[P:%.*]], align 1
94 ; CHECK-NEXT:    ret void
96 if:
97   br i1 %c, label %then, label %else
99 then:
100   %t = load i8, ptr %p, !noundef !2
101   br label %out
103 else:
104   %e = load i8, ptr %p
105   br label %out
107 out:
108   ret void
111 define void @hoist_one_noundef_switch(i64 %i, ptr %p) {
112 ; CHECK-LABEL: @hoist_one_noundef_switch(
113 ; CHECK-NEXT:  out:
114 ; CHECK-NEXT:    [[T:%.*]] = load i8, ptr [[P:%.*]], align 1
115 ; CHECK-NEXT:    ret void
117   switch i64 %i, label %bb0 [
118   i64 1, label %bb1
119   i64 2, label %bb2
120   ]
121 bb0:
122   %t = load i8, ptr %p, !noundef !2
123   br label %out
124 bb1:
125   %e = load i8, ptr %p
126   br label %out
127 bb2:
128   %f = load i8, ptr %p, !noundef !2
129   br label %out
130 out:
131   ret void
134 define void @hoist_dereferenceable(i1 %c, ptr %p) {
135 ; CHECK-LABEL: @hoist_dereferenceable(
136 ; CHECK-NEXT:  if:
137 ; CHECK-NEXT:    [[T:%.*]] = load ptr, ptr [[P:%.*]], align 8, !dereferenceable [[META3:![0-9]+]]
138 ; CHECK-NEXT:    ret void
141   br i1 %c, label %then, label %else
142 then:
143   %t = load ptr, ptr %p, !dereferenceable !{i64 10}
144   br label %out
145 else:
146   %e = load ptr, ptr %p, !dereferenceable !{i64 20}
147   br label %out
148 out:
149   ret void
152 define void @hoist_dereferenceable_switch(i64 %i, ptr %p) {
153 ; CHECK-LABEL: @hoist_dereferenceable_switch(
154 ; CHECK-NEXT:  out:
155 ; CHECK-NEXT:    [[T:%.*]] = load ptr, ptr [[P:%.*]], align 8, !dereferenceable [[META3]]
156 ; CHECK-NEXT:    ret void
158   switch i64 %i, label %bb0 [
159   i64 1, label %bb1
160   i64 2, label %bb2
161   ]
162 bb0:
163   %t = load ptr, ptr %p, !dereferenceable !{i64 10}
164   br label %out
165 bb1:
166   %e = load ptr, ptr %p, !dereferenceable !{i64 20}
167   br label %out
168 bb2:
169   %f = load ptr, ptr %p, !dereferenceable !{i64 30}
170   br label %out
171 out:
172   ret void
175 define void @hoist_dereferenceable_or_null(i1 %c, ptr %p) {
176 ; CHECK-LABEL: @hoist_dereferenceable_or_null(
177 ; CHECK-NEXT:  if:
178 ; CHECK-NEXT:    [[T:%.*]] = load ptr, ptr [[P:%.*]], align 8, !dereferenceable_or_null [[META3]]
179 ; CHECK-NEXT:    ret void
182   br i1 %c, label %then, label %else
183 then:
184   %t = load ptr, ptr %p, !dereferenceable_or_null !{i64 20}
185   br label %out
186 else:
187   %e = load ptr, ptr %p, !dereferenceable_or_null !{i64 10}
188   br label %out
189 out:
190   ret void
193 define void @hoist_dereferenceable_or_null_switch(i64 %i, ptr %p) {
194 ; CHECK-LABEL: @hoist_dereferenceable_or_null_switch(
195 ; CHECK-NEXT:  out:
196 ; CHECK-NEXT:    [[T:%.*]] = load ptr, ptr [[P:%.*]], align 8, !dereferenceable_or_null [[META3]]
197 ; CHECK-NEXT:    ret void
199   switch i64 %i, label %bb0 [
200   i64 1, label %bb1
201   i64 2, label %bb2
202   ]
203 bb0:
204   %t = load ptr, ptr %p, !dereferenceable_or_null !{i64 20}
205   br label %out
206 bb1:
207   %e = load ptr, ptr %p, !dereferenceable_or_null !{i64 10}
208   br label %out
209 bb2:
210   %f = load ptr, ptr %p, !dereferenceable_or_null !{i64 30}
211   br label %out
212 out:
213   ret void
216 ; !range violation only returns poison, and is thus safe to speculate.
217 define i32 @speculate_range(i1 %c, ptr dereferenceable(8) align 8 %p) {
218 ; CHECK-LABEL: @speculate_range(
219 ; CHECK-NEXT:  entry:
220 ; CHECK-NEXT:    [[V:%.*]] = load i32, ptr [[P:%.*]], align 4, !range [[RNG4:![0-9]+]]
221 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[C:%.*]], i32 [[V]], i32 0
222 ; CHECK-NEXT:    ret i32 [[SPEC_SELECT]]
224 entry:
225   br i1 %c, label %if, label %join
228   %v = load i32, ptr %p, !range !{i32 0, i32 10}
229   br label %join
231 join:
232   %phi = phi i32 [ %v, %if ], [ 0, %entry ]
233   ret i32 %phi
236 ; !nonnull is safe to speculate, but !noundef is not, as the latter causes
237 ; immediate undefined behavior.
238 define ptr @speculate_nonnull(i1 %c, ptr dereferenceable(8) align 8 %p) {
239 ; CHECK-LABEL: @speculate_nonnull(
240 ; CHECK-NEXT:  entry:
241 ; CHECK-NEXT:    [[V:%.*]] = load ptr, ptr [[P:%.*]], align 8, !nonnull [[META2]]
242 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[C:%.*]], ptr [[V]], ptr null
243 ; CHECK-NEXT:    ret ptr [[SPEC_SELECT]]
245 entry:
246   br i1 %c, label %if, label %join
249   %v = load ptr, ptr %p, !nonnull !{}, !noundef !{}
250   br label %join
252 join:
253   %phi = phi ptr [ %v, %if ], [ null, %entry ]
254   ret ptr %phi
257 ; !align is safe to speculate, but !dereferenceable is not, as the latter causes
258 ; immediate undefined behavior.
259 define ptr @speculate_align(i1 %c, ptr dereferenceable(8) align 8 %p) {
260 ; CHECK-LABEL: @speculate_align(
261 ; CHECK-NEXT:  entry:
262 ; CHECK-NEXT:    [[V:%.*]] = load ptr, ptr [[P:%.*]], align 8, !align [[META5:![0-9]+]]
263 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[C:%.*]], ptr [[V]], ptr null
264 ; CHECK-NEXT:    ret ptr [[SPEC_SELECT]]
266 entry:
267   br i1 %c, label %if, label %join
270   %v = load ptr, ptr %p, !align !{i64 4}, !dereferenceable !{i64 4}
271   br label %join
273 join:
274   %phi = phi ptr [ %v, %if ], [ null, %entry ]
275   ret ptr %phi
278 define void @hoist_fpmath(i1 %c, double %x) {
279 ; CHECK-LABEL: @hoist_fpmath(
280 ; CHECK-NEXT:  if:
281 ; CHECK-NEXT:    [[T:%.*]] = fadd double [[X:%.*]], 1.000000e+00, !fpmath [[META6:![0-9]+]]
282 ; CHECK-NEXT:    ret void
285   br i1 %c, label %then, label %else
286 then:
287   %t = fadd double %x, 1.0, !fpmath !{ float 2.5 }
288   br label %out
289 else:
290   %e = fadd double %x, 1.0, !fpmath !{ float 5.0 }
291   br label %out
292 out:
293   ret void
296 define void @hoist_fpmath_switch(i64 %i, double %x) {
297 ; CHECK-LABEL: @hoist_fpmath_switch(
298 ; CHECK-NEXT:  out:
299 ; CHECK-NEXT:    [[T:%.*]] = fadd double [[X:%.*]], 1.000000e+00, !fpmath [[META6]]
300 ; CHECK-NEXT:    ret void
302   switch i64 %i, label %bb0 [
303   i64 1, label %bb1
304   i64 2, label %bb2
305   ]
306 bb0:
307   %t = fadd double %x, 1.0, !fpmath !{ float 2.5 }
308   br label %out
309 bb1:
310   %e = fadd double %x, 1.0, !fpmath !{ float 5.0 }
311   br label %out
312 bb2:
313   %f = fadd double %x, 1.0, !fpmath !{ float 7.5 }
314   br label %out
315 out:
316   ret void
319 !0 = !{ i8 0, i8 1 }
320 !1 = !{ i8 3, i8 5 }
321 !2 = !{}
322 !3 = !{ i8 7, i8 9 }
324 ; CHECK: [[RNG0]] = !{i8 0, i8 1, i8 3, i8 5}
325 ; CHECK: [[RNG1]] = !{i8 0, i8 1, i8 3, i8 5, i8 7, i8 9}
326 ; CHECK: [[META2]] = !{}
327 ; CHECK: [[META3]] = !{i64 10}
328 ; CHECK: [[RNG4]] = !{i32 0, i32 10}
329 ; CHECK: [[META5]] = !{i64 4}
330 ; CHECK: [[META6]] = !{float 2.500000e+00}