xref: /llvm-project/llvm/test/Transforms/InstCombine/phi-pointercasts.ll (revision 2caaec65c04ea7d0e9568b7895b7a46d6100cb75)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -passes=instcombine -S < %s | FileCheck %s
3
4define void @test_bitcast_1(i1 %c, ptr %ptr) {
5; CHECK-LABEL: @test_bitcast_1(
6; CHECK-NEXT:  entry:
7; CHECK-NEXT:    br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
8; CHECK:       b0:
9; CHECK-NEXT:    call void @use(ptr [[PTR:%.*]])
10; CHECK-NEXT:    br label [[END:%.*]]
11; CHECK:       b1:
12; CHECK-NEXT:    br label [[END]]
13; CHECK:       end:
14; CHECK-NEXT:    store i8 0, ptr [[PTR]], align 1
15; CHECK-NEXT:    ret void
16;
17entry:
18  br i1 %c, label %b0, label %b1
19
20b0:
21  call void @use(ptr %ptr)
22  br label %end
23
24b1:
25  br label %end
26
27end:
28  %p = phi ptr [ %ptr, %b0 ], [ %ptr, %b1 ]
29  store i8 0, ptr %p
30  ret void
31}
32
33define void @test_bitcast_2(i1 %c, ptr %ptr) {
34; CHECK-LABEL: @test_bitcast_2(
35; CHECK-NEXT:  entry:
36; CHECK-NEXT:    br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
37; CHECK:       b0:
38; CHECK-NEXT:    br label [[END:%.*]]
39; CHECK:       b1:
40; CHECK-NEXT:    call void @use(ptr [[PTR:%.*]])
41; CHECK-NEXT:    br label [[END]]
42; CHECK:       end:
43; CHECK-NEXT:    store i8 0, ptr [[PTR]], align 1
44; CHECK-NEXT:    ret void
45;
46entry:
47  br i1 %c, label %b0, label %b1
48
49b0:
50  br label %end
51
52b1:
53  call void @use(ptr %ptr)
54  br label %end
55
56end:
57  %p = phi ptr [ %ptr, %b0 ], [ %ptr, %b1 ]
58  store i8 0, ptr %p
59  ret void
60}
61
62
63define void @test_bitcast_3(i1 %c, ptr %ptr) {
64; CHECK-LABEL: @test_bitcast_3(
65; CHECK-NEXT:  entry:
66; CHECK-NEXT:    [[LOAD_PTR:%.*]] = load ptr, ptr [[PTR:%.*]], align 8
67; CHECK-NEXT:    br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
68; CHECK:       b0:
69; CHECK-NEXT:    br label [[END:%.*]]
70; CHECK:       b1:
71; CHECK-NEXT:    call void @use(ptr [[LOAD_PTR]])
72; CHECK-NEXT:    br label [[END]]
73; CHECK:       end:
74; CHECK-NEXT:    store i8 0, ptr [[LOAD_PTR]], align 1
75; CHECK-NEXT:    ret void
76;
77entry:
78  %load.ptr = load ptr, ptr %ptr
79  br i1 %c, label %b0, label %b1
80
81b0:
82  br label %end
83
84b1:
85  call void @use(ptr %load.ptr)
86  br label %end
87
88end:
89  %p = phi ptr [ %load.ptr, %b0 ], [ %load.ptr, %b1 ]
90  store i8 0, ptr %p
91  ret void
92}
93
94define void @test_bitcast_loads_in_different_bbs(i1 %c, ptr %ptr.0, ptr %ptr.1) {
95; CHECK-LABEL: @test_bitcast_loads_in_different_bbs(
96; CHECK-NEXT:  entry:
97; CHECK-NEXT:    br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
98; CHECK:       b0:
99; CHECK-NEXT:    [[LOAD_PTR_0:%.*]] = load ptr, ptr [[PTR_0:%.*]], align 8
100; CHECK-NEXT:    call void @use(ptr [[LOAD_PTR_0]])
101; CHECK-NEXT:    br label [[END:%.*]]
102; CHECK:       b1:
103; CHECK-NEXT:    [[LOAD_PTR_1:%.*]] = load ptr, ptr [[PTR_1:%.*]], align 8
104; CHECK-NEXT:    br label [[END]]
105; CHECK:       end:
106; CHECK-NEXT:    [[P:%.*]] = phi ptr [ [[LOAD_PTR_0]], [[B0]] ], [ [[LOAD_PTR_1]], [[B1]] ]
107; CHECK-NEXT:    store i8 0, ptr [[P]], align 1
108; CHECK-NEXT:    ret void
109;
110entry:
111  br i1 %c, label %b0, label %b1
112
113b0:
114  %load.ptr.0 = load ptr, ptr %ptr.0
115  call void @use(ptr %load.ptr.0)
116  br label %end
117
118b1:
119  %load.ptr.1 = load ptr, ptr %ptr.1
120  br label %end
121
122end:
123  %p = phi ptr [ %load.ptr.0, %b0 ], [ %load.ptr.1, %b1 ]
124  store i8 0, ptr %p
125  ret void
126}
127
128define void @test_gep_1(i1 %c, ptr %ptr) {
129; CHECK-LABEL: @test_gep_1(
130; CHECK-NEXT:  entry:
131; CHECK-NEXT:    br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
132; CHECK:       b0:
133; CHECK-NEXT:    call void @use.i32(ptr [[PTR:%.*]])
134; CHECK-NEXT:    br label [[END:%.*]]
135; CHECK:       b1:
136; CHECK-NEXT:    br label [[END]]
137; CHECK:       end:
138; CHECK-NEXT:    store i32 0, ptr [[PTR]], align 4
139; CHECK-NEXT:    ret void
140;
141entry:
142  br i1 %c, label %b0, label %b1
143
144b0:
145  call void @use.i32(ptr %ptr)
146  br label %end
147
148b1:
149  br label %end
150
151end:
152  %p = phi ptr [ %ptr, %b0 ], [ %ptr, %b1 ]
153  store i32 0, ptr %p
154  ret void
155}
156
157define void @test_bitcast_not_foldable(i1 %c, ptr %ptr.0, ptr %ptr.1) {
158; CHECK-LABEL: @test_bitcast_not_foldable(
159; CHECK-NEXT:  entry:
160; CHECK-NEXT:    br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
161; CHECK:       b0:
162; CHECK-NEXT:    br label [[END:%.*]]
163; CHECK:       b1:
164; CHECK-NEXT:    call void @use(ptr [[PTR_1:%.*]])
165; CHECK-NEXT:    br label [[END]]
166; CHECK:       end:
167; CHECK-NEXT:    [[P:%.*]] = phi ptr [ [[PTR_0:%.*]], [[B0]] ], [ [[PTR_1]], [[B1]] ]
168; CHECK-NEXT:    store i8 0, ptr [[P]], align 1
169; CHECK-NEXT:    ret void
170;
171entry:
172  br i1 %c, label %b0, label %b1
173
174b0:
175  br label %end
176
177b1:
178  call void @use(ptr %ptr.1)
179  br label %end
180
181end:
182  %p = phi ptr [ %ptr.0, %b0 ], [ %ptr.1, %b1 ]
183  store i8 0, ptr %p
184  ret void
185}
186
187define void @test_bitcast_with_extra_use(i1 %c, ptr %ptr) {
188; CHECK-LABEL: @test_bitcast_with_extra_use(
189; CHECK-NEXT:  entry:
190; CHECK-NEXT:    br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
191; CHECK:       b0:
192; CHECK-NEXT:    call void @use(ptr [[PTR:%.*]])
193; CHECK-NEXT:    br label [[END:%.*]]
194; CHECK:       b1:
195; CHECK-NEXT:    br label [[END]]
196; CHECK:       end:
197; CHECK-NEXT:    store i8 0, ptr [[PTR]], align 1
198; CHECK-NEXT:    ret void
199;
200entry:
201  br i1 %c, label %b0, label %b1
202
203b0:
204  call void @use(ptr %ptr)
205  br label %end
206
207b1:
208  br label %end
209
210end:
211  %p = phi ptr [ %ptr, %b0 ], [ %ptr, %b1 ]
212  store i8 0, ptr %p
213  ret void
214}
215
216define void @test_bitcast_different_bases(i1 %c, ptr %ptr.0, ptr %ptr.1) {
217; CHECK-LABEL: @test_bitcast_different_bases(
218; CHECK-NEXT:  entry:
219; CHECK-NEXT:    br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
220; CHECK:       b0:
221; CHECK-NEXT:    call void @use(ptr [[PTR_0:%.*]])
222; CHECK-NEXT:    br label [[END:%.*]]
223; CHECK:       b1:
224; CHECK-NEXT:    br label [[END]]
225; CHECK:       end:
226; CHECK-NEXT:    [[P:%.*]] = phi ptr [ [[PTR_0]], [[B0]] ], [ [[PTR_1:%.*]], [[B1]] ]
227; CHECK-NEXT:    store i8 0, ptr [[P]], align 1
228; CHECK-NEXT:    ret void
229;
230entry:
231  br i1 %c, label %b0, label %b1
232
233b0:
234  call void @use(ptr %ptr.0)
235  br label %end
236
237b1:
238  br label %end
239
240end:
241  %p = phi ptr [ %ptr.0, %b0 ], [ %ptr.1, %b1 ]
242  store i8 0, ptr %p
243  ret void
244}
245
246define void @test_bitcast_gep_chains(i1 %c, ptr %ptr) {
247; CHECK-LABEL: @test_bitcast_gep_chains(
248; CHECK-NEXT:  entry:
249; CHECK-NEXT:    br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
250; CHECK:       b0:
251; CHECK-NEXT:    call void @use(ptr [[PTR:%.*]])
252; CHECK-NEXT:    br label [[END:%.*]]
253; CHECK:       b1:
254; CHECK-NEXT:    call void @use.i32(ptr [[PTR]])
255; CHECK-NEXT:    br label [[END]]
256; CHECK:       end:
257; CHECK-NEXT:    store i8 0, ptr [[PTR]], align 1
258; CHECK-NEXT:    ret void
259;
260entry:
261  br i1 %c, label %b0, label %b1
262
263b0:
264  call void @use(ptr %ptr)
265  br label %end
266
267b1:
268  call void @use.i32(ptr %ptr)
269  br label %end
270
271end:
272  %p = phi ptr [ %ptr, %b0 ], [ %ptr, %b1 ]
273  store i8 0, ptr %p
274  ret void
275}
276
277define void @test_4_incoming_values_different_bases_1(i32 %c, ptr %ptr.0, ptr %ptr.1) {
278; CHECK-LABEL: @test_4_incoming_values_different_bases_1(
279; CHECK-NEXT:  entry:
280; CHECK-NEXT:    switch i32 [[C:%.*]], label [[END_2:%.*]] [
281; CHECK-NEXT:    i32 0, label [[B0:%.*]]
282; CHECK-NEXT:    i32 1, label [[B1:%.*]]
283; CHECK-NEXT:    i32 2, label [[B2:%.*]]
284; CHECK-NEXT:    i32 3, label [[B3:%.*]]
285; CHECK-NEXT:    ]
286; CHECK:       b0:
287; CHECK-NEXT:    call void @use(ptr [[PTR_0:%.*]])
288; CHECK-NEXT:    br label [[END:%.*]]
289; CHECK:       b1:
290; CHECK-NEXT:    br label [[END]]
291; CHECK:       b2:
292; CHECK-NEXT:    br label [[END]]
293; CHECK:       b3:
294; CHECK-NEXT:    br label [[END]]
295; CHECK:       end:
296; CHECK-NEXT:    [[P:%.*]] = phi ptr [ [[PTR_0]], [[B0]] ], [ [[PTR_1:%.*]], [[B1]] ], [ [[PTR_0]], [[B2]] ], [ [[PTR_0]], [[B3]] ]
297; CHECK-NEXT:    store i8 0, ptr [[P]], align 1
298; CHECK-NEXT:    ret void
299; CHECK:       end.2:
300; CHECK-NEXT:    ret void
301;
302entry:
303  switch i32 %c, label %end.2 [ i32 0, label %b0
304  i32 1, label %b1
305  i32 2, label %b2
306  i32 3, label %b3]
307
308b0:
309  call void @use(ptr %ptr.0)
310  br label %end
311
312b1:
313  br label %end
314
315b2:
316  br label %end
317
318b3:
319  br label %end
320
321end:
322  %p = phi ptr [ %ptr.0, %b0 ], [ %ptr.1, %b1 ], [ %ptr.0, %b2 ], [ %ptr.0, %b3]
323  store i8 0, ptr %p
324  ret void
325
326end.2:
327  ret void
328}
329
330define void @test_4_incoming_values_different_bases_2(i32 %c, ptr %ptr.0, ptr %ptr.1) {
331; CHECK-LABEL: @test_4_incoming_values_different_bases_2(
332; CHECK-NEXT:  entry:
333; CHECK-NEXT:    switch i32 [[C:%.*]], label [[END_2:%.*]] [
334; CHECK-NEXT:    i32 0, label [[B0:%.*]]
335; CHECK-NEXT:    i32 1, label [[B1:%.*]]
336; CHECK-NEXT:    i32 2, label [[B2:%.*]]
337; CHECK-NEXT:    i32 3, label [[B3:%.*]]
338; CHECK-NEXT:    ]
339; CHECK:       b0:
340; CHECK-NEXT:    br label [[END:%.*]]
341; CHECK:       b1:
342; CHECK-NEXT:    call void @use(ptr [[PTR_0:%.*]])
343; CHECK-NEXT:    br label [[END]]
344; CHECK:       b2:
345; CHECK-NEXT:    br label [[END]]
346; CHECK:       b3:
347; CHECK-NEXT:    br label [[END]]
348; CHECK:       end:
349; CHECK-NEXT:    [[P:%.*]] = phi ptr [ [[PTR_1:%.*]], [[B0]] ], [ [[PTR_0]], [[B1]] ], [ [[PTR_0]], [[B2]] ], [ [[PTR_0]], [[B3]] ]
350; CHECK-NEXT:    store i8 0, ptr [[P]], align 1
351; CHECK-NEXT:    ret void
352; CHECK:       end.2:
353; CHECK-NEXT:    ret void
354;
355entry:
356  switch i32 %c, label %end.2 [ i32 0, label %b0
357  i32 1, label %b1
358  i32 2, label %b2
359  i32 3, label %b3]
360
361b0:
362  br label %end
363
364b1:
365  call void @use(ptr %ptr.0)
366  br label %end
367
368b2:
369  br label %end
370
371b3:
372  br label %end
373
374end:
375  %p = phi ptr [ %ptr.1, %b0 ], [ %ptr.0, %b1 ], [ %ptr.0, %b2 ], [ %ptr.0, %b3]
376  store i8 0, ptr %p
377  ret void
378
379end.2:
380  ret void
381}
382
383define void @test_4_incoming_values_different_bases_3(i32 %c, ptr %ptr.0, ptr %ptr.1) {
384; CHECK-LABEL: @test_4_incoming_values_different_bases_3(
385; CHECK-NEXT:  entry:
386; CHECK-NEXT:    switch i32 [[C:%.*]], label [[END_2:%.*]] [
387; CHECK-NEXT:    i32 0, label [[B0:%.*]]
388; CHECK-NEXT:    i32 1, label [[B1:%.*]]
389; CHECK-NEXT:    i32 2, label [[B2:%.*]]
390; CHECK-NEXT:    i32 3, label [[B3:%.*]]
391; CHECK-NEXT:    ]
392; CHECK:       b0:
393; CHECK-NEXT:    br label [[END:%.*]]
394; CHECK:       b1:
395; CHECK-NEXT:    br label [[END]]
396; CHECK:       b2:
397; CHECK-NEXT:    call void @use(ptr [[PTR_0:%.*]])
398; CHECK-NEXT:    br label [[END]]
399; CHECK:       b3:
400; CHECK-NEXT:    br label [[END]]
401; CHECK:       end:
402; CHECK-NEXT:    [[P:%.*]] = phi ptr [ [[PTR_0]], [[B0]] ], [ [[PTR_0]], [[B1]] ], [ [[PTR_0]], [[B2]] ], [ [[PTR_1:%.*]], [[B3]] ]
403; CHECK-NEXT:    store i8 0, ptr [[P]], align 1
404; CHECK-NEXT:    ret void
405; CHECK:       end.2:
406; CHECK-NEXT:    ret void
407;
408entry:
409  switch i32 %c, label %end.2 [ i32 0, label %b0
410  i32 1, label %b1
411  i32 2, label %b2
412  i32 3, label %b3]
413
414b0:
415  br label %end
416
417b1:
418  br label %end
419
420b2:
421  call void @use(ptr %ptr.0)
422  br label %end
423
424b3:
425  br label %end
426
427end:
428  %p = phi ptr [ %ptr.0, %b0 ], [ %ptr.0, %b1 ], [ %ptr.0, %b2 ], [ %ptr.1, %b3]
429  store i8 0, ptr %p
430  ret void
431
432end.2:
433  ret void
434}
435
436define void @test_addrspacecast_1(i1 %c, ptr %ptr) {
437; CHECK-LABEL: @test_addrspacecast_1(
438; CHECK-NEXT:  entry:
439; CHECK-NEXT:    br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
440; CHECK:       b0:
441; CHECK-NEXT:    br label [[END:%.*]]
442; CHECK:       b1:
443; CHECK-NEXT:    [[CAST_1:%.*]] = addrspacecast ptr [[PTR:%.*]] to ptr addrspace(1)
444; CHECK-NEXT:    call void @use.i8.addrspace1(ptr addrspace(1) [[CAST_1]])
445; CHECK-NEXT:    br label [[END]]
446; CHECK:       end:
447; CHECK-NEXT:    [[P:%.*]] = addrspacecast ptr [[PTR]] to ptr addrspace(1)
448; CHECK-NEXT:    store i8 0, ptr addrspace(1) [[P]], align 1
449; CHECK-NEXT:    ret void
450;
451entry:
452  %cast.0 = addrspacecast ptr %ptr to ptr addrspace(1)
453  %cast.1 = addrspacecast ptr %ptr to ptr addrspace(1)
454  br i1 %c, label %b0, label %b1
455
456b0:
457  br label %end
458
459b1:
460  call void @use.i8.addrspace1(ptr addrspace(1) %cast.1)
461  br label %end
462
463end:
464  %p = phi ptr addrspace(1) [ %cast.0, %b0 ], [ %cast.1, %b1 ]
465  store i8 0, ptr addrspace(1) %p
466  ret void
467}
468
469declare void @use(ptr)
470declare void @use.i32(ptr)
471declare void @use.i8.addrspace1(ptr addrspace(1))
472