[AMDGPU] Add True16 register classes.
[llvm-project.git] / llvm / test / Transforms / SimplifyCFG / hoist-with-metadata.ll
blobb53224c944f11018574c3751bb714684f5214716
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:    switch i64 [[I:%.*]], label [[BB0:%.*]] [
25 ; CHECK-NEXT:    i64 1, label [[BB1:%.*]]
26 ; CHECK-NEXT:    i64 2, label [[BB2:%.*]]
27 ; CHECK-NEXT:    ]
28 ; CHECK:       bb0:
29 ; CHECK-NEXT:    [[T:%.*]] = load i8, ptr [[P:%.*]], align 1, !range [[RNG1:![0-9]+]]
30 ; CHECK-NEXT:    br label [[OUT:%.*]]
31 ; CHECK:       bb1:
32 ; CHECK-NEXT:    [[E:%.*]] = load i8, ptr [[P]], align 1, !range [[RNG2:![0-9]+]]
33 ; CHECK-NEXT:    br label [[OUT]]
34 ; CHECK:       bb2:
35 ; CHECK-NEXT:    [[F:%.*]] = load i8, ptr [[P]], align 1, !range [[RNG3:![0-9]+]]
36 ; CHECK-NEXT:    br label [[OUT]]
37 ; CHECK:       out:
38 ; CHECK-NEXT:    ret void
40   switch i64 %i, label %bb0 [
41   i64 1, label %bb1
42   i64 2, label %bb2
43   ]
44 bb0:
45   %t = load i8, ptr %p, !range !0
46   br label %out
47 bb1:
48   %e = load i8, ptr %p, !range !1
49   br label %out
50 bb2:
51   %f = load i8, ptr %p, !range !3
52   br label %out
53 out:
54   ret void
57 define void @hoist_both_noundef(i1 %c, ptr %p) {
58 ; CHECK-LABEL: @hoist_both_noundef(
59 ; CHECK-NEXT:  if:
60 ; CHECK-NEXT:    [[T:%.*]] = load i8, ptr [[P:%.*]], align 1, !noundef !4
61 ; CHECK-NEXT:    ret void
63 if:
64   br i1 %c, label %then, label %else
66 then:
67   %t = load i8, ptr %p, !noundef !2
68   br label %out
70 else:
71   %e = load i8, ptr %p, !noundef !2
72   br label %out
74 out:
75   ret void
79 define void @hoist_both_noundef_switch(i64 %i, ptr %p) {
80 ; CHECK-LABEL: @hoist_both_noundef_switch(
81 ; CHECK-NEXT:    switch i64 [[I:%.*]], label [[BB0:%.*]] [
82 ; CHECK-NEXT:    i64 1, label [[BB1:%.*]]
83 ; CHECK-NEXT:    i64 2, label [[BB2:%.*]]
84 ; CHECK-NEXT:    ]
85 ; CHECK:       bb0:
86 ; CHECK-NEXT:    [[T:%.*]] = load i8, ptr [[P:%.*]], align 1, !noundef !4
87 ; CHECK-NEXT:    br label [[OUT:%.*]]
88 ; CHECK:       bb1:
89 ; CHECK-NEXT:    [[E:%.*]] = load i8, ptr [[P]], align 1, !noundef !4
90 ; CHECK-NEXT:    br label [[OUT]]
91 ; CHECK:       bb2:
92 ; CHECK-NEXT:    [[F:%.*]] = load i8, ptr [[P]], align 1, !noundef !4
93 ; CHECK-NEXT:    br label [[OUT]]
94 ; CHECK:       out:
95 ; CHECK-NEXT:    ret void
97   switch i64 %i, label %bb0 [
98   i64 1, label %bb1
99   i64 2, label %bb2
100   ]
101 bb0:
102   %t = load i8, ptr %p, !noundef !2
103   br label %out
104 bb1:
105   %e = load i8, ptr %p, !noundef !2
106   br label %out
107 bb2:
108   %f = load i8, ptr %p, !noundef !2
109   br label %out
110 out:
111   ret void
114 define void @hoist_one_noundef(i1 %c, ptr %p) {
115 ; CHECK-LABEL: @hoist_one_noundef(
116 ; CHECK-NEXT:  if:
117 ; CHECK-NEXT:    [[T:%.*]] = load i8, ptr [[P:%.*]], align 1
118 ; CHECK-NEXT:    ret void
121   br i1 %c, label %then, label %else
123 then:
124   %t = load i8, ptr %p, !noundef !2
125   br label %out
127 else:
128   %e = load i8, ptr %p
129   br label %out
131 out:
132   ret void
135 define void @hoist_one_noundef_switch(i64 %i, ptr %p) {
136 ; CHECK-LABEL: @hoist_one_noundef_switch(
137 ; CHECK-NEXT:    switch i64 [[I:%.*]], label [[BB0:%.*]] [
138 ; CHECK-NEXT:    i64 1, label [[BB1:%.*]]
139 ; CHECK-NEXT:    i64 2, label [[BB2:%.*]]
140 ; CHECK-NEXT:    ]
141 ; CHECK:       bb0:
142 ; CHECK-NEXT:    [[T:%.*]] = load i8, ptr [[P:%.*]], align 1, !noundef !4
143 ; CHECK-NEXT:    br label [[OUT:%.*]]
144 ; CHECK:       bb1:
145 ; CHECK-NEXT:    [[E:%.*]] = load i8, ptr [[P]], align 1
146 ; CHECK-NEXT:    br label [[OUT]]
147 ; CHECK:       bb2:
148 ; CHECK-NEXT:    [[F:%.*]] = load i8, ptr [[P]], align 1, !noundef !4
149 ; CHECK-NEXT:    br label [[OUT]]
150 ; CHECK:       out:
151 ; CHECK-NEXT:    ret void
153   switch i64 %i, label %bb0 [
154   i64 1, label %bb1
155   i64 2, label %bb2
156   ]
157 bb0:
158   %t = load i8, ptr %p, !noundef !2
159   br label %out
160 bb1:
161   %e = load i8, ptr %p
162   br label %out
163 bb2:
164   %f = load i8, ptr %p, !noundef !2
165   br label %out
166 out:
167   ret void
170 define void @hoist_dereferenceable(i1 %c, ptr %p) {
171 ; CHECK-LABEL: @hoist_dereferenceable(
172 ; CHECK-NEXT:  if:
173 ; CHECK-NEXT:    [[T:%.*]] = load ptr, ptr [[P:%.*]], align 8, !dereferenceable !5
174 ; CHECK-NEXT:    ret void
177   br i1 %c, label %then, label %else
178 then:
179   %t = load ptr, ptr %p, !dereferenceable !{i64 10}
180   br label %out
181 else:
182   %e = load ptr, ptr %p, !dereferenceable !{i64 20}
183   br label %out
184 out:
185   ret void
188 define void @hoist_dereferenceable_switch(i64 %i, ptr %p) {
189 ; CHECK-LABEL: @hoist_dereferenceable_switch(
190 ; CHECK-NEXT:    switch i64 [[I:%.*]], label [[BB0:%.*]] [
191 ; CHECK-NEXT:    i64 1, label [[BB1:%.*]]
192 ; CHECK-NEXT:    i64 2, label [[BB2:%.*]]
193 ; CHECK-NEXT:    ]
194 ; CHECK:       bb0:
195 ; CHECK-NEXT:    [[T:%.*]] = load ptr, ptr [[P:%.*]], align 8, !dereferenceable !5
196 ; CHECK-NEXT:    br label [[OUT:%.*]]
197 ; CHECK:       bb1:
198 ; CHECK-NEXT:    [[E:%.*]] = load ptr, ptr [[P]], align 8, !dereferenceable !6
199 ; CHECK-NEXT:    br label [[OUT]]
200 ; CHECK:       bb2:
201 ; CHECK-NEXT:    [[F:%.*]] = load ptr, ptr [[P]], align 8, !dereferenceable !7
202 ; CHECK-NEXT:    br label [[OUT]]
203 ; CHECK:       out:
204 ; CHECK-NEXT:    ret void
206   switch i64 %i, label %bb0 [
207   i64 1, label %bb1
208   i64 2, label %bb2
209   ]
210 bb0:
211   %t = load ptr, ptr %p, !dereferenceable !{i64 10}
212   br label %out
213 bb1:
214   %e = load ptr, ptr %p, !dereferenceable !{i64 20}
215   br label %out
216 bb2:
217   %f = load ptr, ptr %p, !dereferenceable !{i64 30}
218   br label %out
219 out:
220   ret void
223 define void @hoist_dereferenceable_or_null(i1 %c, ptr %p) {
224 ; CHECK-LABEL: @hoist_dereferenceable_or_null(
225 ; CHECK-NEXT:  if:
226 ; CHECK-NEXT:    [[T:%.*]] = load ptr, ptr [[P:%.*]], align 8, !dereferenceable_or_null !5
227 ; CHECK-NEXT:    ret void
230   br i1 %c, label %then, label %else
231 then:
232   %t = load ptr, ptr %p, !dereferenceable_or_null !{i64 20}
233   br label %out
234 else:
235   %e = load ptr, ptr %p, !dereferenceable_or_null !{i64 10}
236   br label %out
237 out:
238   ret void
241 define void @hoist_dereferenceable_or_null_switch(i64 %i, ptr %p) {
242 ; CHECK-LABEL: @hoist_dereferenceable_or_null_switch(
243 ; CHECK-NEXT:    switch i64 [[I:%.*]], label [[BB0:%.*]] [
244 ; CHECK-NEXT:    i64 1, label [[BB1:%.*]]
245 ; CHECK-NEXT:    i64 2, label [[BB2:%.*]]
246 ; CHECK-NEXT:    ]
247 ; CHECK:       bb0:
248 ; CHECK-NEXT:    [[T:%.*]] = load ptr, ptr [[P:%.*]], align 8, !dereferenceable_or_null !6
249 ; CHECK-NEXT:    br label [[OUT:%.*]]
250 ; CHECK:       bb1:
251 ; CHECK-NEXT:    [[E:%.*]] = load ptr, ptr [[P]], align 8, !dereferenceable_or_null !5
252 ; CHECK-NEXT:    br label [[OUT]]
253 ; CHECK:       bb2:
254 ; CHECK-NEXT:    [[F:%.*]] = load ptr, ptr [[P]], align 8, !dereferenceable_or_null !7
255 ; CHECK-NEXT:    br label [[OUT]]
256 ; CHECK:       out:
257 ; CHECK-NEXT:    ret void
259   switch i64 %i, label %bb0 [
260   i64 1, label %bb1
261   i64 2, label %bb2
262   ]
263 bb0:
264   %t = load ptr, ptr %p, !dereferenceable_or_null !{i64 20}
265   br label %out
266 bb1:
267   %e = load ptr, ptr %p, !dereferenceable_or_null !{i64 10}
268   br label %out
269 bb2:
270   %f = load ptr, ptr %p, !dereferenceable_or_null !{i64 30}
271   br label %out
272 out:
273   ret void
276 ; !range violation only returns poison, and is thus safe to speculate.
277 define i32 @speculate_range(i1 %c, ptr dereferenceable(8) align 8 %p) {
278 ; CHECK-LABEL: @speculate_range(
279 ; CHECK-NEXT:  entry:
280 ; CHECK-NEXT:    [[V:%.*]] = load i32, ptr [[P:%.*]], align 4, !range [[RNG8:![0-9]+]]
281 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[C:%.*]], i32 [[V]], i32 0
282 ; CHECK-NEXT:    ret i32 [[SPEC_SELECT]]
284 entry:
285   br i1 %c, label %if, label %join
288   %v = load i32, ptr %p, !range !{i32 0, i32 10}
289   br label %join
291 join:
292   %phi = phi i32 [ %v, %if ], [ 0, %entry ]
293   ret i32 %phi
296 ; !nonnull is safe to speculate, but !noundef is not, as the latter causes
297 ; immediate undefined behavior.
298 define ptr @speculate_nonnull(i1 %c, ptr dereferenceable(8) align 8 %p) {
299 ; CHECK-LABEL: @speculate_nonnull(
300 ; CHECK-NEXT:  entry:
301 ; CHECK-NEXT:    [[V:%.*]] = load ptr, ptr [[P:%.*]], align 8, !nonnull !4
302 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[C:%.*]], ptr [[V]], ptr null
303 ; CHECK-NEXT:    ret ptr [[SPEC_SELECT]]
305 entry:
306   br i1 %c, label %if, label %join
309   %v = load ptr, ptr %p, !nonnull !{}, !noundef !{}
310   br label %join
312 join:
313   %phi = phi ptr [ %v, %if ], [ null, %entry ]
314   ret ptr %phi
317 ; !align is safe to speculate, but !dereferenceable is not, as the latter causes
318 ; immediate undefined behavior.
319 define ptr @speculate_align(i1 %c, ptr dereferenceable(8) align 8 %p) {
320 ; CHECK-LABEL: @speculate_align(
321 ; CHECK-NEXT:  entry:
322 ; CHECK-NEXT:    [[V:%.*]] = load ptr, ptr [[P:%.*]], align 8, !align !9
323 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[C:%.*]], ptr [[V]], ptr null
324 ; CHECK-NEXT:    ret ptr [[SPEC_SELECT]]
326 entry:
327   br i1 %c, label %if, label %join
330   %v = load ptr, ptr %p, !align !{i64 4}, !dereferenceable !{i64 4}
331   br label %join
333 join:
334   %phi = phi ptr [ %v, %if ], [ null, %entry ]
335   ret ptr %phi
338 define void @hoist_fpmath(i1 %c, double %x) {
339 ; CHECK-LABEL: @hoist_fpmath(
340 ; CHECK-NEXT:  if:
341 ; CHECK-NEXT:    [[T:%.*]] = fadd double [[X:%.*]], 1.000000e+00, !fpmath !10
342 ; CHECK-NEXT:    ret void
345   br i1 %c, label %then, label %else
346 then:
347   %t = fadd double %x, 1.0, !fpmath !{ float 2.5 }
348   br label %out
349 else:
350   %e = fadd double %x, 1.0, !fpmath !{ float 5.0 }
351   br label %out
352 out:
353   ret void
356 define void @hoist_fpmath_switch(i64 %i, double %x) {
357 ; CHECK-LABEL: @hoist_fpmath_switch(
358 ; CHECK-NEXT:    switch i64 [[I:%.*]], label [[BB0:%.*]] [
359 ; CHECK-NEXT:    i64 1, label [[BB1:%.*]]
360 ; CHECK-NEXT:    i64 2, label [[BB2:%.*]]
361 ; CHECK-NEXT:    ]
362 ; CHECK:       bb0:
363 ; CHECK-NEXT:    [[T:%.*]] = fadd double [[X:%.*]], 1.000000e+00, !fpmath !10
364 ; CHECK-NEXT:    br label [[OUT:%.*]]
365 ; CHECK:       bb1:
366 ; CHECK-NEXT:    [[E:%.*]] = fadd double [[X]], 1.000000e+00, !fpmath !11
367 ; CHECK-NEXT:    br label [[OUT]]
368 ; CHECK:       bb2:
369 ; CHECK-NEXT:    [[F:%.*]] = fadd double [[X]], 1.000000e+00, !fpmath !12
370 ; CHECK-NEXT:    br label [[OUT]]
371 ; CHECK:       out:
372 ; CHECK-NEXT:    ret void
374   switch i64 %i, label %bb0 [
375   i64 1, label %bb1
376   i64 2, label %bb2
377   ]
378 bb0:
379   %t = fadd double %x, 1.0, !fpmath !{ float 2.5 }
380   br label %out
381 bb1:
382   %e = fadd double %x, 1.0, !fpmath !{ float 5.0 }
383   br label %out
384 bb2:
385   %f = fadd double %x, 1.0, !fpmath !{ float 7.5 }
386   br label %out
387 out:
388   ret void
391 !0 = !{ i8 0, i8 1 }
392 !1 = !{ i8 3, i8 5 }
393 !2 = !{}
394 !3 = !{ i8 7, i8 9 }
396 ; CHECK: [[RNG0]] = !{i8 0, i8 1, i8 3, i8 5}
397 ; CHECK: [[RNG1]] = !{i8 0, i8 1}
398 ; CHECK: [[RNG2]] = !{i8 3, i8 5}
399 ; CHECK: [[RNG3]] = !{i8 7, i8 9}
400 ; CHECK: [[META4:![0-9]+]] = !{}
401 ; CHECK: [[META5:![0-9]+]] = !{i64 10}
402 ; CHECK: [[META6:![0-9]+]] = !{i64 20}
403 ; CHECK: [[META7:![0-9]+]] = !{i64 30}
404 ; CHECK: [[RNG8]] = !{i32 0, i32 10}
405 ; CHECK: [[META9:![0-9]+]] = !{i64 4}
406 ; CHECK: [[META10:![0-9]+]] = !{float 2.500000e+00}
407 ; CHECK: [[META11:![0-9]+]] = !{float 5.000000e+00}
408 ; CHECK: [[META12:![0-9]+]] = !{float 7.500000e+00}