1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -instcombine -S < %s | FileCheck %s
4 define void @test_bitcast_1(i1 %c, i32* %ptr) {
5 ; CHECK-LABEL: @test_bitcast_1(
7 ; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
9 ; CHECK-NEXT: [[CAST_0:%.*]] = bitcast i32* [[PTR:%.*]] to i8*
10 ; CHECK-NEXT: call void @use(i8* [[CAST_0]])
11 ; CHECK-NEXT: br label [[END:%.*]]
13 ; CHECK-NEXT: br label [[END]]
15 ; CHECK-NEXT: [[P:%.*]] = bitcast i32* [[PTR]] to i8*
16 ; CHECK-NEXT: store i8 0, i8* [[P]], align 1
17 ; CHECK-NEXT: ret void
20 %cast.0 = bitcast i32* %ptr to i8*
21 %cast.1 = bitcast i32* %ptr to i8*
22 br i1 %c, label %b0, label %b1
25 call void @use(i8* %cast.0)
32 %p = phi i8* [ %cast.0, %b0 ], [ %cast.1, %b1 ]
37 define void @test_bitcast_2(i1 %c, i32* %ptr) {
38 ; CHECK-LABEL: @test_bitcast_2(
40 ; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
42 ; CHECK-NEXT: br label [[END:%.*]]
44 ; CHECK-NEXT: [[CAST_1:%.*]] = bitcast i32* [[PTR:%.*]] to i8*
45 ; CHECK-NEXT: call void @use(i8* [[CAST_1]])
46 ; CHECK-NEXT: br label [[END]]
48 ; CHECK-NEXT: [[P:%.*]] = bitcast i32* [[PTR]] to i8*
49 ; CHECK-NEXT: store i8 0, i8* [[P]], align 1
50 ; CHECK-NEXT: ret void
53 br i1 %c, label %b0, label %b1
56 %cast.0 = bitcast i32* %ptr to i8*
60 %cast.1 = bitcast i32* %ptr to i8*
61 call void @use(i8* %cast.1)
65 %p = phi i8* [ %cast.0, %b0 ], [ %cast.1, %b1 ]
71 define void @test_bitcast_3(i1 %c, i32** %ptr) {
72 ; CHECK-LABEL: @test_bitcast_3(
74 ; CHECK-NEXT: [[LOAD_PTR:%.*]] = load i32*, i32** [[PTR:%.*]], align 8
75 ; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
77 ; CHECK-NEXT: br label [[END:%.*]]
79 ; CHECK-NEXT: [[CAST_1:%.*]] = bitcast i32* [[LOAD_PTR]] to i8*
80 ; CHECK-NEXT: call void @use(i8* [[CAST_1]])
81 ; CHECK-NEXT: br label [[END]]
83 ; CHECK-NEXT: [[P:%.*]] = bitcast i32* [[LOAD_PTR]] to i8*
84 ; CHECK-NEXT: store i8 0, i8* [[P]], align 1
85 ; CHECK-NEXT: ret void
88 %load.ptr = load i32*, i32** %ptr
89 br i1 %c, label %b0, label %b1
92 %cast.0 = bitcast i32* %load.ptr to i8*
96 %cast.1 = bitcast i32* %load.ptr to i8*
97 call void @use(i8* %cast.1)
101 %p = phi i8* [ %cast.0, %b0 ], [ %cast.1, %b1 ]
106 define void @test_bitcast_loads_in_different_bbs(i1 %c, i32** %ptr.0, i32** %ptr.1) {
107 ; CHECK-LABEL: @test_bitcast_loads_in_different_bbs(
109 ; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
111 ; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32** [[PTR_0:%.*]] to i8**
112 ; CHECK-NEXT: [[LOAD_PTR_02:%.*]] = load i8*, i8** [[TMP0]], align 8
113 ; CHECK-NEXT: call void @use(i8* [[LOAD_PTR_02]])
114 ; CHECK-NEXT: br label [[END:%.*]]
116 ; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32** [[PTR_1:%.*]] to i8**
117 ; CHECK-NEXT: [[LOAD_PTR_11:%.*]] = load i8*, i8** [[TMP1]], align 8
118 ; CHECK-NEXT: br label [[END]]
120 ; CHECK-NEXT: [[P:%.*]] = phi i8* [ [[LOAD_PTR_02]], [[B0]] ], [ [[LOAD_PTR_11]], [[B1]] ]
121 ; CHECK-NEXT: store i8 0, i8* [[P]], align 1
122 ; CHECK-NEXT: ret void
125 br i1 %c, label %b0, label %b1
128 %load.ptr.0 = load i32*, i32** %ptr.0
129 %cast.0 = bitcast i32* %load.ptr.0 to i8*
130 call void @use(i8* %cast.0)
134 %load.ptr.1 = load i32*, i32** %ptr.1
135 %cast.1 = bitcast i32* %load.ptr.1 to i8*
139 %p = phi i8* [ %cast.0, %b0 ], [ %cast.1, %b1 ]
144 define void @test_gep_1(i1 %c, i32* %ptr) {
145 ; CHECK-LABEL: @test_gep_1(
147 ; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
149 ; CHECK-NEXT: call void @use.i32(i32* [[PTR:%.*]])
150 ; CHECK-NEXT: br label [[END:%.*]]
152 ; CHECK-NEXT: br label [[END]]
154 ; CHECK-NEXT: store i32 0, i32* [[PTR]], align 4
155 ; CHECK-NEXT: ret void
158 br i1 %c, label %b0, label %b1
161 %cast.0 = getelementptr i32, i32* %ptr, i32 0
162 call void @use.i32(i32* %cast.0)
166 %cast.1 = getelementptr i32, i32* %ptr, i32 0
170 %p = phi i32* [ %cast.0, %b0 ], [ %cast.1, %b1 ]
175 define void @test_bitcast_not_foldable(i1 %c, i32* %ptr.0, i32* %ptr.1) {
176 ; CHECK-LABEL: @test_bitcast_not_foldable(
178 ; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
180 ; CHECK-NEXT: [[CAST_0:%.*]] = bitcast i32* [[PTR_0:%.*]] to i8*
181 ; CHECK-NEXT: br label [[END:%.*]]
183 ; CHECK-NEXT: [[CAST_1:%.*]] = bitcast i32* [[PTR_1:%.*]] to i8*
184 ; CHECK-NEXT: call void @use(i8* [[CAST_1]])
185 ; CHECK-NEXT: br label [[END]]
187 ; CHECK-NEXT: [[P:%.*]] = phi i8* [ [[CAST_0]], [[B0]] ], [ [[CAST_1]], [[B1]] ]
188 ; CHECK-NEXT: store i8 0, i8* [[P]], align 1
189 ; CHECK-NEXT: ret void
192 br i1 %c, label %b0, label %b1
195 %cast.0 = bitcast i32* %ptr.0 to i8*
199 %cast.1 = bitcast i32* %ptr.1 to i8*
200 call void @use(i8* %cast.1)
204 %p = phi i8* [ %cast.0, %b0 ], [ %cast.1, %b1 ]
209 define void @test_bitcast_with_extra_use(i1 %c, i32* %ptr) {
210 ; CHECK-LABEL: @test_bitcast_with_extra_use(
212 ; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
214 ; CHECK-NEXT: [[CAST_0:%.*]] = bitcast i32* [[PTR:%.*]] to i8*
215 ; CHECK-NEXT: call void @use(i8* [[CAST_0]])
216 ; CHECK-NEXT: br label [[END:%.*]]
218 ; CHECK-NEXT: br label [[END]]
220 ; CHECK-NEXT: [[P:%.*]] = bitcast i32* [[PTR]] to i8*
221 ; CHECK-NEXT: store i8 0, i8* [[P]], align 1
222 ; CHECK-NEXT: ret void
225 br i1 %c, label %b0, label %b1
228 %cast.0 = bitcast i32* %ptr to i8*
229 call void @use(i8* %cast.0)
233 %cast.1 = bitcast i32* %ptr to i8*
237 %p = phi i8* [ %cast.0, %b0 ], [ %cast.1, %b1 ]
242 define void @test_bitcast_different_bases(i1 %c, i32* %ptr.0, i32* %ptr.1) {
243 ; CHECK-LABEL: @test_bitcast_different_bases(
245 ; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
247 ; CHECK-NEXT: [[CAST_0:%.*]] = bitcast i32* [[PTR_0:%.*]] to i8*
248 ; CHECK-NEXT: call void @use(i8* [[CAST_0]])
249 ; CHECK-NEXT: br label [[END:%.*]]
251 ; CHECK-NEXT: [[CAST_1:%.*]] = bitcast i32* [[PTR_1:%.*]] to i8*
252 ; CHECK-NEXT: br label [[END]]
254 ; CHECK-NEXT: [[P:%.*]] = phi i8* [ [[CAST_0]], [[B0]] ], [ [[CAST_1]], [[B1]] ]
255 ; CHECK-NEXT: store i8 0, i8* [[P]], align 1
256 ; CHECK-NEXT: ret void
259 br i1 %c, label %b0, label %b1
262 %cast.0 = bitcast i32* %ptr.0 to i8*
263 call void @use(i8* %cast.0)
267 %cast.1 = bitcast i32* %ptr.1 to i8*
271 %p = phi i8* [ %cast.0, %b0 ], [ %cast.1, %b1 ]
276 define void @test_bitcast_gep_chains(i1 %c, i32* %ptr) {
277 ; CHECK-LABEL: @test_bitcast_gep_chains(
279 ; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
281 ; CHECK-NEXT: [[CAST_0:%.*]] = bitcast i32* [[PTR:%.*]] to i8*
282 ; CHECK-NEXT: call void @use(i8* [[CAST_0]])
283 ; CHECK-NEXT: br label [[END:%.*]]
285 ; CHECK-NEXT: call void @use.i32(i32* [[PTR]])
286 ; CHECK-NEXT: br label [[END]]
288 ; CHECK-NEXT: [[P:%.*]] = bitcast i32* [[PTR]] to i8*
289 ; CHECK-NEXT: store i8 0, i8* [[P]], align 1
290 ; CHECK-NEXT: ret void
293 %gep = getelementptr i32, i32* %ptr, i32 0
294 br i1 %c, label %b0, label %b1
297 %cast.0 = bitcast i32* %gep to i8*
298 call void @use(i8* %cast.0)
302 %cast.1 = bitcast i32* %ptr to i8*
303 %cast.2 = bitcast i8* %cast.1 to i32*
304 call void @use.i32(i32* %cast.2)
305 %cast.3 = bitcast i32* %cast.2 to i8*
309 %p = phi i8* [ %cast.0, %b0 ], [ %cast.3, %b1 ]
314 define void @test_4_incoming_values_different_bases_1(i32 %c, i32* %ptr.0, i32* %ptr.1) {
315 ; CHECK-LABEL: @test_4_incoming_values_different_bases_1(
317 ; CHECK-NEXT: switch i32 [[C:%.*]], label [[END_2:%.*]] [
318 ; CHECK-NEXT: i32 0, label [[B0:%.*]]
319 ; CHECK-NEXT: i32 1, label [[B1:%.*]]
320 ; CHECK-NEXT: i32 2, label [[B2:%.*]]
321 ; CHECK-NEXT: i32 3, label [[B3:%.*]]
324 ; CHECK-NEXT: [[CAST_0:%.*]] = bitcast i32* [[PTR_0:%.*]] to i8*
325 ; CHECK-NEXT: call void @use(i8* [[CAST_0]])
326 ; CHECK-NEXT: br label [[END:%.*]]
328 ; CHECK-NEXT: [[CAST_3:%.*]] = bitcast i32* [[PTR_1:%.*]] to i8*
329 ; CHECK-NEXT: br label [[END]]
331 ; CHECK-NEXT: [[CAST_4:%.*]] = bitcast i32* [[PTR_0]] to i8*
332 ; CHECK-NEXT: br label [[END]]
334 ; CHECK-NEXT: [[CAST_5:%.*]] = bitcast i32* [[PTR_0]] to i8*
335 ; CHECK-NEXT: br label [[END]]
337 ; CHECK-NEXT: [[P:%.*]] = phi i8* [ [[CAST_0]], [[B0]] ], [ [[CAST_3]], [[B1]] ], [ [[CAST_4]], [[B2]] ], [ [[CAST_5]], [[B3]] ]
338 ; CHECK-NEXT: store i8 0, i8* [[P]], align 1
339 ; CHECK-NEXT: ret void
341 ; CHECK-NEXT: ret void
344 %gep = getelementptr i32, i32* %ptr.0, i32 0
345 switch i32 %c, label %end.2 [ i32 0, label %b0
351 %cast.0 = bitcast i32* %gep to i8*
352 call void @use(i8* %cast.0)
356 %cast.1 = bitcast i32* %ptr.1 to i8*
357 %cast.2 = bitcast i8* %cast.1 to i64*
358 %cast.3 = bitcast i64* %cast.2 to i8*
362 %cast.4 = bitcast i32* %gep to i8*
366 %cast.5 = bitcast i32 * %ptr.0 to i8*
370 %p = phi i8* [ %cast.0, %b0 ], [ %cast.3, %b1 ], [ %cast.4, %b2 ], [ %cast.5, %b3]
378 define void @test_4_incoming_values_different_bases_2(i32 %c, i32* %ptr.0, i32* %ptr.1) {
379 ; CHECK-LABEL: @test_4_incoming_values_different_bases_2(
381 ; CHECK-NEXT: switch i32 [[C:%.*]], label [[END_2:%.*]] [
382 ; CHECK-NEXT: i32 0, label [[B0:%.*]]
383 ; CHECK-NEXT: i32 1, label [[B1:%.*]]
384 ; CHECK-NEXT: i32 2, label [[B2:%.*]]
385 ; CHECK-NEXT: i32 3, label [[B3:%.*]]
388 ; CHECK-NEXT: br label [[END:%.*]]
390 ; CHECK-NEXT: [[CAST_1:%.*]] = bitcast i32* [[PTR_0:%.*]] to i8*
391 ; CHECK-NEXT: call void @use(i8* [[CAST_1]])
392 ; CHECK-NEXT: br label [[END]]
394 ; CHECK-NEXT: br label [[END]]
396 ; CHECK-NEXT: br label [[END]]
398 ; CHECK-NEXT: [[P_IN:%.*]] = phi i32* [ [[PTR_1:%.*]], [[B0]] ], [ [[PTR_0]], [[B1]] ], [ [[PTR_0]], [[B2]] ], [ [[PTR_0]], [[B3]] ]
399 ; CHECK-NEXT: [[P:%.*]] = bitcast i32* [[P_IN]] to i8*
400 ; CHECK-NEXT: store i8 0, i8* [[P]], align 1
401 ; CHECK-NEXT: ret void
403 ; CHECK-NEXT: ret void
406 %gep = getelementptr i32, i32* %ptr.0, i32 0
407 switch i32 %c, label %end.2 [ i32 0, label %b0
413 %cast.0 = bitcast i32* %ptr.1 to i8*
417 %cast.1 = bitcast i32* %ptr.0 to i8*
418 call void @use(i8* %cast.1)
419 %cast.2 = bitcast i8* %cast.1 to i64*
420 %cast.3 = bitcast i64* %cast.2 to i8*
424 %cast.4 = bitcast i32* %gep to i8*
428 %cast.5 = bitcast i32 * %ptr.0 to i8*
432 %p = phi i8* [ %cast.0, %b0 ], [ %cast.3, %b1 ], [ %cast.4, %b2 ], [ %cast.5, %b3]
440 define void @test_4_incoming_values_different_bases_3(i32 %c, i32* %ptr.0, i32* %ptr.1) {
441 ; CHECK-LABEL: @test_4_incoming_values_different_bases_3(
443 ; CHECK-NEXT: switch i32 [[C:%.*]], label [[END_2:%.*]] [
444 ; CHECK-NEXT: i32 0, label [[B0:%.*]]
445 ; CHECK-NEXT: i32 1, label [[B1:%.*]]
446 ; CHECK-NEXT: i32 2, label [[B2:%.*]]
447 ; CHECK-NEXT: i32 3, label [[B3:%.*]]
450 ; CHECK-NEXT: [[CAST_0:%.*]] = bitcast i32* [[PTR_0:%.*]] to i8*
451 ; CHECK-NEXT: br label [[END:%.*]]
453 ; CHECK-NEXT: [[CAST_3:%.*]] = bitcast i32* [[PTR_0]] to i8*
454 ; CHECK-NEXT: br label [[END]]
456 ; CHECK-NEXT: [[CAST_4:%.*]] = bitcast i32* [[PTR_0]] to i8*
457 ; CHECK-NEXT: call void @use(i8* [[CAST_4]])
458 ; CHECK-NEXT: br label [[END]]
460 ; CHECK-NEXT: [[CAST_5:%.*]] = bitcast i32* [[PTR_1:%.*]] to i8*
461 ; CHECK-NEXT: br label [[END]]
463 ; CHECK-NEXT: [[P:%.*]] = phi i8* [ [[CAST_0]], [[B0]] ], [ [[CAST_3]], [[B1]] ], [ [[CAST_4]], [[B2]] ], [ [[CAST_5]], [[B3]] ]
464 ; CHECK-NEXT: store i8 0, i8* [[P]], align 1
465 ; CHECK-NEXT: ret void
467 ; CHECK-NEXT: ret void
470 %gep = getelementptr i32, i32* %ptr.0, i32 0
471 switch i32 %c, label %end.2 [ i32 0, label %b0
477 %cast.0 = bitcast i32* %ptr.0 to i8*
481 %cast.1 = bitcast i32* %ptr.0 to i8*
482 %cast.2 = bitcast i8* %cast.1 to i64*
483 %cast.3 = bitcast i64* %cast.2 to i8*
487 %cast.4 = bitcast i32* %gep to i8*
488 call void @use(i8* %cast.4)
492 %cast.5 = bitcast i32 * %ptr.1 to i8*
496 %p = phi i8* [ %cast.0, %b0 ], [ %cast.3, %b1 ], [ %cast.4, %b2 ], [ %cast.5, %b3]
504 define void @test_addrspacecast_1(i1 %c, i32* %ptr) {
505 ; CHECK-LABEL: @test_addrspacecast_1(
507 ; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
509 ; CHECK-NEXT: br label [[END:%.*]]
511 ; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[PTR:%.*]] to i8*
512 ; CHECK-NEXT: [[CAST_1:%.*]] = addrspacecast i8* [[TMP0]] to i8 addrspace(1)*
513 ; CHECK-NEXT: call void @use.i8.addrspace1(i8 addrspace(1)* [[CAST_1]])
514 ; CHECK-NEXT: br label [[END]]
516 ; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32* [[PTR]] to i8*
517 ; CHECK-NEXT: [[P:%.*]] = addrspacecast i8* [[TMP1]] to i8 addrspace(1)*
518 ; CHECK-NEXT: store i8 0, i8 addrspace(1)* [[P]], align 1
519 ; CHECK-NEXT: ret void
522 %cast.0 = addrspacecast i32* %ptr to i8 addrspace(1)*
523 %cast.1 = addrspacecast i32* %ptr to i8 addrspace(1)*
524 br i1 %c, label %b0, label %b1
530 call void @use.i8.addrspace1(i8 addrspace(1)* %cast.1)
534 %p = phi i8 addrspace(1)* [ %cast.0, %b0 ], [ %cast.1, %b1 ]
535 store i8 0, i8 addrspace(1)* %p
539 declare void @use(i8*)
540 declare void @use.i32(i32*)
541 declare void @use.i8.addrspace1(i8 addrspace(1)*)