Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / InstCombine / opaque-ptr.ll
blobdf85547f56d74ff72740ce4392cc9063b969ef05
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -passes=instcombine < %s | FileCheck %s
4 define ptr @bitcast_opaque_to_opaque(ptr %a) {
5 ; CHECK-LABEL: @bitcast_opaque_to_opaque(
6 ; CHECK-NEXT:    ret ptr [[A:%.*]]
8   ret ptr %a
11 define ptr @bitcast_typed_to_opaque(ptr %a) {
12 ; CHECK-LABEL: @bitcast_typed_to_opaque(
13 ; CHECK-NEXT:    ret ptr [[A:%.*]]
15   ret ptr %a
18 define ptr @bitcast_opaque_to_typed(ptr %a) {
19 ; CHECK-LABEL: @bitcast_opaque_to_typed(
20 ; CHECK-NEXT:    ret ptr [[A:%.*]]
22   ret ptr %a
25 @g = global i8 0
26 define ptr @bitcast_typed_to_opaque_constexpr() {
27 ; CHECK-LABEL: @bitcast_typed_to_opaque_constexpr(
28 ; CHECK-NEXT:    ret ptr @g
30   ret ptr @g
33 define ptr @addrspacecast_opaque_to_opaque(ptr addrspace(1) %a) {
34 ; CHECK-LABEL: @addrspacecast_opaque_to_opaque(
35 ; CHECK-NEXT:    [[B:%.*]] = addrspacecast ptr addrspace(1) [[A:%.*]] to ptr
36 ; CHECK-NEXT:    ret ptr [[B]]
38   %b = addrspacecast ptr addrspace(1) %a to ptr
39   ret ptr %b
42 define ptr @addrspacecast_typed_to_opaque(ptr addrspace(1) %a) {
43 ; CHECK-LABEL: @addrspacecast_typed_to_opaque(
44 ; CHECK-NEXT:    [[B:%.*]] = addrspacecast ptr addrspace(1) [[A:%.*]] to ptr
45 ; CHECK-NEXT:    ret ptr [[B]]
47   %b = addrspacecast ptr addrspace(1) %a to ptr
48   ret ptr %b
51 define ptr @addrspacecast_opaque_to_typed(ptr addrspace(1) %a) {
52 ; CHECK-LABEL: @addrspacecast_opaque_to_typed(
53 ; CHECK-NEXT:    [[B:%.*]] = addrspacecast ptr addrspace(1) [[A:%.*]] to ptr
54 ; CHECK-NEXT:    ret ptr [[B]]
56   %b = addrspacecast ptr addrspace(1) %a to ptr
57   ret ptr %b
60 define ptr addrspace(1) @bitcast_and_addrspacecast_eliminable(ptr %a) {
61 ; CHECK-LABEL: @bitcast_and_addrspacecast_eliminable(
62 ; CHECK-NEXT:    [[C:%.*]] = addrspacecast ptr [[A:%.*]] to ptr addrspace(1)
63 ; CHECK-NEXT:    ret ptr addrspace(1) [[C]]
65   %c = addrspacecast ptr %a to ptr addrspace(1)
66   ret ptr addrspace(1) %c
69 define ptr addrspace(1) @addrspacecast_typed_to_opaque_constexpr() {
70 ; CHECK-LABEL: @addrspacecast_typed_to_opaque_constexpr(
71 ; CHECK-NEXT:    ret ptr addrspace(1) addrspacecast (ptr @g to ptr addrspace(1))
73   ret ptr addrspace(1) addrspacecast (ptr @g to ptr addrspace(1))
76 define ptr @gep_constexpr_1(ptr %a) {
77 ; CHECK-LABEL: @gep_constexpr_1(
78 ; CHECK-NEXT:    ret ptr inttoptr (i64 6 to ptr)
80   ret ptr getelementptr (i16, ptr null, i32 3)
83 define ptr @gep_constexpr_2(ptr %a) {
84 ; CHECK-LABEL: @gep_constexpr_2(
85 ; CHECK-NEXT:    ret ptr getelementptr (i8, ptr @g, i64 3)
87   ret ptr getelementptr (i8, ptr @g, i32 3)
90 define ptr addrspace(1) @gep_constexpr_3(ptr %a) {
91 ; CHECK-LABEL: @gep_constexpr_3(
92 ; CHECK-NEXT:    ret ptr addrspace(1) getelementptr (i8, ptr addrspace(1) addrspacecast (ptr @g to ptr addrspace(1)), i64 3)
94   ret ptr addrspace(1) getelementptr ([0 x i8], ptr addrspace(1) addrspacecast (ptr @g to ptr addrspace(1)), i64 0, i32 3)
97 define ptr @load_bitcast_1(ptr %a) {
98 ; CHECK-LABEL: @load_bitcast_1(
99 ; CHECK-NEXT:    [[B:%.*]] = load ptr, ptr [[A:%.*]], align 8
100 ; CHECK-NEXT:    ret ptr [[B]]
102   %b = load ptr, ptr %a
103   ret ptr %b
106 define ptr @load_bitcast_2(ptr %a) {
107 ; CHECK-LABEL: @load_bitcast_2(
108 ; CHECK-NEXT:    [[C:%.*]] = load ptr, ptr [[A:%.*]], align 8
109 ; CHECK-NEXT:    ret ptr [[C]]
111   %c = load ptr, ptr %a
112   ret ptr %c
115 define void @call(ptr %a) {
116 ; CHECK-LABEL: @call(
117 ; CHECK-NEXT:    call void [[A:%.*]]()
118 ; CHECK-NEXT:    ret void
120   call void %a()
121   ret void
124 declare void @varargs(...)
125 define void @varargs_cast_typed_to_opaque_same_type(ptr %a) {
126 ; CHECK-LABEL: @varargs_cast_typed_to_opaque_same_type(
127 ; CHECK-NEXT:    call void (...) @varargs(ptr byval(i32) [[A:%.*]])
128 ; CHECK-NEXT:    ret void
130   call void (...) @varargs(ptr byval(i32) %a)
131   ret void
134 define void @varargs_cast_typed_to_opaque_different_type(ptr %a) {
135 ; CHECK-LABEL: @varargs_cast_typed_to_opaque_different_type(
136 ; CHECK-NEXT:    call void (...) @varargs(ptr byval(float) [[A:%.*]])
137 ; CHECK-NEXT:    ret void
139   call void (...) @varargs(ptr byval(float) %a)
140   ret void
143 define void @varargs_cast_typed_to_opaque_different_size(ptr %a) {
144 ; CHECK-LABEL: @varargs_cast_typed_to_opaque_different_size(
145 ; CHECK-NEXT:    call void (...) @varargs(ptr byval(i64) [[A:%.*]])
146 ; CHECK-NEXT:    ret void
148   call void (...) @varargs(ptr byval(i64) %a)
149   ret void
152 define void @varargs_cast_opaque_to_typed(ptr %a) {
153 ; CHECK-LABEL: @varargs_cast_opaque_to_typed(
154 ; CHECK-NEXT:    call void (...) @varargs(ptr byval(i8) [[A:%.*]])
155 ; CHECK-NEXT:    ret void
157   call void (...) @varargs(ptr byval(i8) %a)
158   ret void
161 define ptr @geps_combinable(ptr %a) {
162 ; CHECK-LABEL: @geps_combinable(
163 ; CHECK-NEXT:    [[A3:%.*]] = getelementptr i8, ptr [[A:%.*]], i64 8
164 ; CHECK-NEXT:    ret ptr [[A3]]
166   %a2 = getelementptr { i32, { i32, i32 } }, ptr %a, i32 0, i32 1
167   %a3 = getelementptr { i32, i32 }, ptr %a2, i32 0, i32 1
168   ret ptr %a3
171 define ptr @geps_combinable_different_elem_type1(ptr %a) {
172 ; CHECK-LABEL: @geps_combinable_different_elem_type1(
173 ; CHECK-NEXT:    [[A3:%.*]] = getelementptr i8, ptr [[A:%.*]], i64 8
174 ; CHECK-NEXT:    ret ptr [[A3]]
176   %a2 = getelementptr { i32, i32 }, ptr %a, i32 0, i32 1
177   %a3 = getelementptr { i32, i32 }, ptr %a2, i32 0, i32 1
178   ret ptr %a3
181 define ptr @geps_combinable_different_elem_type2(ptr %a) {
182 ; CHECK-LABEL: @geps_combinable_different_elem_type2(
183 ; CHECK-NEXT:    [[A3:%.*]] = getelementptr i8, ptr [[A:%.*]], i64 8
184 ; CHECK-NEXT:    ret ptr [[A3]]
186   %a2 = getelementptr { i32, i32 }, ptr %a, i32 0, i32 1
187   %a3 = getelementptr i8, ptr %a2, i64 4
188   ret ptr %a3
191 define ptr @geps_combinable_different_elem_type3(ptr %a) {
192 ; CHECK-LABEL: @geps_combinable_different_elem_type3(
193 ; CHECK-NEXT:    [[A3:%.*]] = getelementptr i8, ptr [[A:%.*]], i64 12
194 ; CHECK-NEXT:    ret ptr [[A3]]
196   %a2 = getelementptr { i32, i32 }, ptr %a, i32 0, i32 1
197   %a3 = getelementptr i8, ptr %a2, i64 8
198   ret ptr %a3
201 define ptr @geps_combinable_different_elem_type4(ptr %a) {
202 ; CHECK-LABEL: @geps_combinable_different_elem_type4(
203 ; CHECK-NEXT:    [[A3:%.*]] = getelementptr i8, ptr [[A:%.*]], i64 14
204 ; CHECK-NEXT:    ret ptr [[A3]]
206   %a2 = getelementptr { i32, i32 }, ptr %a, i32 0, i32 1
207   %a3 = getelementptr i8, ptr %a2, i64 10
208   ret ptr %a3
211 define ptr @geps_combinable_different_elem_type5(ptr %a) {
212 ; CHECK-LABEL: @geps_combinable_different_elem_type5(
213 ; CHECK-NEXT:    ret ptr [[A:%.*]]
215   %a2 = getelementptr { i32, i32 }, ptr %a, i32 0, i32 1
216   %a3 = getelementptr i8, ptr %a2, i64 -4
217   ret ptr %a3
220 define ptr @geps_combinable_different_elem_type6(ptr %a, i64 %idx) {
221 ; CHECK-LABEL: @geps_combinable_different_elem_type6(
222 ; CHECK-NEXT:    [[A3:%.*]] = getelementptr { i32, i32 }, ptr [[A:%.*]], i64 [[IDX:%.*]], i32 1
223 ; CHECK-NEXT:    ret ptr [[A3]]
225   %a2 = getelementptr { i32, i32 }, ptr %a, i64 %idx
226   %a3 = getelementptr i8, ptr %a2, i64 4
227   ret ptr %a3
230 define ptr @geps_combinable_different_elem_type7(ptr %a, i64 %idx) {
231 ; CHECK-LABEL: @geps_combinable_different_elem_type7(
232 ; CHECK-NEXT:    [[A2:%.*]] = getelementptr { i32, i32 }, ptr [[A:%.*]], i64 [[IDX:%.*]], i32 1
233 ; CHECK-NEXT:    [[A3:%.*]] = getelementptr i8, ptr [[A2]], i64 4
234 ; CHECK-NEXT:    ret ptr [[A3]]
236   %a2 = getelementptr { i32, i32 }, ptr %a, i64 %idx, i32 1
237   %a3 = getelementptr i8, ptr %a2, i64 4
238   ret ptr %a3
241 define ptr @geps_combinable_different_elem_type8(ptr %a, i64 %idx) {
242 ; CHECK-LABEL: @geps_combinable_different_elem_type8(
243 ; CHECK-NEXT:    [[A2:%.*]] = getelementptr inbounds { { i32, i32 } }, ptr [[A:%.*]], i64 [[IDX:%.*]], i32 0, i32 1
244 ; CHECK-NEXT:    [[A3:%.*]] = getelementptr inbounds i8, ptr [[A2]], i64 4
245 ; CHECK-NEXT:    ret ptr [[A3]]
247   %a2 = getelementptr inbounds { { i32, i32 } }, ptr %a, i64 %idx, i32 0, i32 1
248   %a3 = getelementptr inbounds i8, ptr %a2, i32 4
249   ret ptr %a3
252 define ptr @geps_combinable_different_elem_type9(ptr %a, i64 %idx) {
253 ; CHECK-LABEL: @geps_combinable_different_elem_type9(
254 ; CHECK-NEXT:    [[A3:%.*]] = getelementptr inbounds { { i32, i32 } }, ptr [[A:%.*]], i64 [[IDX:%.*]]
255 ; CHECK-NEXT:    ret ptr [[A3]]
257   %a2 = getelementptr inbounds { { i32, i32 } }, ptr %a, i64 %idx, i32 0, i32 1
258   %a3 = getelementptr inbounds i8, ptr %a2, i32 -4
259   ret ptr %a3
262 declare void @use(ptr)
264 define ptr @geps_combinable_different_elem_type_extra_use1(ptr %a) {
265 ; CHECK-LABEL: @geps_combinable_different_elem_type_extra_use1(
266 ; CHECK-NEXT:    [[A2:%.*]] = getelementptr i8, ptr [[A:%.*]], i64 4
267 ; CHECK-NEXT:    call void @use(ptr [[A2]])
268 ; CHECK-NEXT:    [[A3:%.*]] = getelementptr i8, ptr [[A]], i64 8
269 ; CHECK-NEXT:    ret ptr [[A3]]
271   %a2 = getelementptr { i32, i32 }, ptr %a, i32 0, i32 1
272   call void @use(ptr %a2)
273   %a3 = getelementptr i8, ptr %a2, i64 4
274   ret ptr %a3
277 define ptr @geps_combinable_different_elem_type_extra_use2(ptr %a, i64 %idx) {
278 ; CHECK-LABEL: @geps_combinable_different_elem_type_extra_use2(
279 ; CHECK-NEXT:    [[A2:%.*]] = getelementptr { i32, i32 }, ptr [[A:%.*]], i64 [[IDX:%.*]]
280 ; CHECK-NEXT:    call void @use(ptr [[A2]])
281 ; CHECK-NEXT:    [[A3:%.*]] = getelementptr i8, ptr [[A2]], i64 4
282 ; CHECK-NEXT:    ret ptr [[A3]]
284   %a2 = getelementptr { i32, i32 }, ptr %a, i64 %idx
285   call void @use(ptr %a2)
286   %a3 = getelementptr i8, ptr %a2, i64 4
287   ret ptr %a3
290 define ptr @geps_combinable_scalable(ptr %a, i64 %idx) {
291 ; CHECK-LABEL: @geps_combinable_scalable(
292 ; CHECK-NEXT:    [[TMP1:%.*]] = call i64 @llvm.vscale.i64()
293 ; CHECK-NEXT:    [[TMP2:%.*]] = shl i64 [[TMP1]], 3
294 ; CHECK-NEXT:    [[A2:%.*]] = getelementptr inbounds i8, ptr [[A:%.*]], i64 [[TMP2]]
295 ; CHECK-NEXT:    [[A3:%.*]] = getelementptr inbounds i8, ptr [[A2]], i64 4
296 ; CHECK-NEXT:    ret ptr [[A3]]
298   %a2 = getelementptr inbounds <vscale x 2 x i32>, ptr %a, i64 1
299   %a3 = getelementptr inbounds i8, ptr %a2, i32 4
300   ret ptr %a3
303 define ptr @geps_combinable_scalable_vector_array(ptr %a, i64 %idx) {
304 ; CHECK-LABEL: @geps_combinable_scalable_vector_array(
305 ; CHECK-NEXT:    [[TMP1:%.*]] = call i64 @llvm.vscale.i64()
306 ; CHECK-NEXT:    [[TMP2:%.*]] = shl i64 [[TMP1]], 5
307 ; CHECK-NEXT:    [[A2:%.*]] = getelementptr inbounds i8, ptr [[A:%.*]], i64 [[TMP2]]
308 ; CHECK-NEXT:    [[A3:%.*]] = getelementptr inbounds i8, ptr [[A2]], i64 4
309 ; CHECK-NEXT:    ret ptr [[A3]]
311   %a2 = getelementptr inbounds [4 x <vscale x 2 x i32>], ptr %a, i64 1
312   %a3 = getelementptr inbounds i8, ptr %a2, i32 4
313   ret ptr %a3
316 define i1 @compare_geps_same_indices(ptr %a, ptr %b, i64 %idx) {
317 ; CHECK-LABEL: @compare_geps_same_indices(
318 ; CHECK-NEXT:    [[C:%.*]] = icmp eq ptr [[A:%.*]], [[B:%.*]]
319 ; CHECK-NEXT:    ret i1 [[C]]
321   %a2 = getelementptr i32, ptr %a, i64 %idx
322   %b2 = getelementptr i32, ptr %b, i64 %idx
323   %c = icmp eq ptr %a2, %b2
324   ret i1 %c
327 define i1 @compare_geps_same_indices_different_types(ptr %a, ptr %b, i64 %idx) {
328 ; CHECK-LABEL: @compare_geps_same_indices_different_types(
329 ; CHECK-NEXT:    [[A2:%.*]] = getelementptr i32, ptr [[A:%.*]], i64 [[IDX:%.*]]
330 ; CHECK-NEXT:    [[B2:%.*]] = getelementptr i64, ptr [[B:%.*]], i64 [[IDX]]
331 ; CHECK-NEXT:    [[C:%.*]] = icmp eq ptr [[A2]], [[B2]]
332 ; CHECK-NEXT:    ret i1 [[C]]
334   %a2 = getelementptr i32, ptr %a, i64 %idx
335   %b2 = getelementptr i64, ptr %b, i64 %idx
336   %c = icmp eq ptr %a2, %b2
337   ret i1 %c
340 define i1 @compare_gep_with_base(ptr %p, i64 %idx) {
341 ; CHECK-LABEL: @compare_gep_with_base(
342 ; CHECK-NEXT:    [[C:%.*]] = icmp eq i64 [[IDX:%.*]], 0
343 ; CHECK-NEXT:    ret i1 [[C]]
345   %gep = getelementptr inbounds i32, ptr %p, i64 %idx
346   %c = icmp eq ptr %gep, %p
347   ret i1 %c
350 define <2 x i1> @compare_gep_with_base_vector1(<2 x ptr> %p, i64 %idx) {
351 ; CHECK-LABEL: @compare_gep_with_base_vector1(
352 ; CHECK-NEXT:    [[DOTSPLATINSERT:%.*]] = insertelement <2 x i64> poison, i64 [[IDX:%.*]], i64 0
353 ; CHECK-NEXT:    [[TMP1:%.*]] = shl <2 x i64> [[DOTSPLATINSERT]], <i64 2, i64 0>
354 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq <2 x i64> [[TMP1]], zeroinitializer
355 ; CHECK-NEXT:    [[C:%.*]] = shufflevector <2 x i1> [[TMP2]], <2 x i1> poison, <2 x i32> zeroinitializer
356 ; CHECK-NEXT:    ret <2 x i1> [[C]]
358   %gep = getelementptr inbounds i32, <2 x ptr> %p, i64 %idx
359   %c = icmp eq <2 x ptr> %gep, %p
360   ret <2 x i1> %c
363 define <2 x i1> @compare_gep_with_base_vector2(<2 x ptr> %p, <2 x i64> %idx) {
364 ; CHECK-LABEL: @compare_gep_with_base_vector2(
365 ; CHECK-NEXT:    [[C:%.*]] = icmp eq <2 x i64> [[IDX:%.*]], zeroinitializer
366 ; CHECK-NEXT:    ret <2 x i1> [[C]]
368   %gep = getelementptr inbounds i32, <2 x ptr> %p, <2 x i64> %idx
369   %c = icmp eq <2 x ptr> %gep, %p
370   ret <2 x i1> %c
373 define <4 x i1> @compare_geps_same_indices_scalar_vector_base_mismatch(ptr %ptr, <4 x ptr> %ptrs) {
374 ; CHECK-LABEL: @compare_geps_same_indices_scalar_vector_base_mismatch(
375 ; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr i16, <4 x ptr> [[PTRS:%.*]], <4 x i64> <i64 1, i64 2, i64 3, i64 4>
376 ; CHECK-NEXT:    [[GEP2:%.*]] = getelementptr i16, ptr [[PTR:%.*]], <4 x i64> <i64 1, i64 2, i64 3, i64 4>
377 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <4 x ptr> [[GEP1]], [[GEP2]]
378 ; CHECK-NEXT:    ret <4 x i1> [[CMP]]
380   %gep1 = getelementptr i16, <4 x ptr> %ptrs, <4 x i64> <i64 1, i64 2, i64 3, i64 4>
381   %gep2 = getelementptr i16, ptr %ptr, <4 x i64> <i64 1, i64 2, i64 3, i64 4>
382   %cmp = icmp eq <4 x ptr> %gep1, %gep2
383   ret <4 x i1> %cmp
386 define ptr @indexed_compare(ptr %A, i64 %offset) {
387 ; CHECK-LABEL: @indexed_compare(
388 ; CHECK-NEXT:  entry:
389 ; CHECK-NEXT:    [[TMP_IDX:%.*]] = shl nsw i64 [[OFFSET:%.*]], 2
390 ; CHECK-NEXT:    br label [[BB:%.*]]
391 ; CHECK:       bb:
392 ; CHECK-NEXT:    [[RHS_IDX:%.*]] = phi i64 [ [[RHS_ADD:%.*]], [[BB]] ], [ [[TMP_IDX]], [[ENTRY:%.*]] ]
393 ; CHECK-NEXT:    [[RHS_ADD]] = add nsw i64 [[RHS_IDX]], 4
394 ; CHECK-NEXT:    [[COND:%.*]] = icmp sgt i64 [[RHS_IDX]], 400
395 ; CHECK-NEXT:    br i1 [[COND]], label [[BB2:%.*]], label [[BB]]
396 ; CHECK:       bb2:
397 ; CHECK-NEXT:    [[RHS_PTR:%.*]] = getelementptr inbounds i8, ptr [[A:%.*]], i64 [[RHS_IDX]]
398 ; CHECK-NEXT:    ret ptr [[RHS_PTR]]
400 entry:
401   %tmp = getelementptr inbounds i32, ptr %A, i64 %offset
402   br label %bb
405   %RHS = phi ptr [ %RHS.next, %bb ], [ %tmp, %entry ]
406   %LHS = getelementptr inbounds i32, ptr %A, i32 100
407   %RHS.next = getelementptr inbounds i32, ptr %RHS, i64 1
408   %cond = icmp ult ptr %LHS, %RHS
409   br i1 %cond, label %bb2, label %bb
411 bb2:
412   ret ptr %RHS
415 define ptr @indexed_compare_different_types(ptr %A, i64 %offset) {
416 ; CHECK-LABEL: @indexed_compare_different_types(
417 ; CHECK-NEXT:  entry:
418 ; CHECK-NEXT:    [[TMP_IDX:%.*]] = shl nsw i64 [[OFFSET:%.*]], 2
419 ; CHECK-NEXT:    br label [[BB:%.*]]
420 ; CHECK:       bb:
421 ; CHECK-NEXT:    [[RHS_IDX:%.*]] = phi i64 [ [[RHS_ADD:%.*]], [[BB]] ], [ [[TMP_IDX]], [[ENTRY:%.*]] ]
422 ; CHECK-NEXT:    [[RHS_ADD]] = add nsw i64 [[RHS_IDX]], 4
423 ; CHECK-NEXT:    [[COND:%.*]] = icmp sgt i64 [[RHS_IDX]], 800
424 ; CHECK-NEXT:    br i1 [[COND]], label [[BB2:%.*]], label [[BB]]
425 ; CHECK:       bb2:
426 ; CHECK-NEXT:    [[RHS_PTR:%.*]] = getelementptr inbounds i8, ptr [[A:%.*]], i64 [[RHS_IDX]]
427 ; CHECK-NEXT:    ret ptr [[RHS_PTR]]
429 entry:
430   %tmp = getelementptr inbounds i32, ptr %A, i64 %offset
431   br label %bb
434   %RHS = phi ptr [ %RHS.next, %bb ], [ %tmp, %entry ]
435   %LHS = getelementptr inbounds i64, ptr %A, i32 100
436   %RHS.next = getelementptr inbounds i32, ptr %RHS, i64 1
437   %cond = icmp ult ptr %LHS, %RHS
438   br i1 %cond, label %bb2, label %bb
440 bb2:
441   ret ptr %RHS
444 define ptr addrspace(1) @gep_of_addrspace_cast(ptr %ptr) {
445 ; CHECK-LABEL: @gep_of_addrspace_cast(
446 ; CHECK-NEXT:    [[CAST1:%.*]] = addrspacecast ptr [[PTR:%.*]] to ptr addrspace(1)
447 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, ptr addrspace(1) [[CAST1]], i64 4
448 ; CHECK-NEXT:    ret ptr addrspace(1) [[GEP]]
450   %cast1 = addrspacecast ptr %ptr to ptr addrspace(1)
451   %gep = getelementptr inbounds i32, ptr addrspace(1) %cast1, i64 1
452   ret ptr addrspace(1) %gep
455 define i1 @cmp_gep_same_base_same_type(ptr %ptr, i64 %idx1, i64 %idx2) {
456 ; CHECK-LABEL: @cmp_gep_same_base_same_type(
457 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i64 [[IDX1:%.*]], [[IDX2:%.*]]
458 ; CHECK-NEXT:    ret i1 [[CMP]]
460   %gep1 = getelementptr inbounds i32, ptr %ptr, i64 %idx1
461   %gep2 = getelementptr inbounds i32, ptr %ptr, i64 %idx2
462   %cmp = icmp ult ptr %gep1, %gep2
463   ret i1 %cmp
466 define i1 @cmp_gep_same_base_different_type(ptr %ptr, i64 %idx1, i64 %idx2) {
467 ; CHECK-LABEL: @cmp_gep_same_base_different_type(
468 ; CHECK-NEXT:    [[GEP1_IDX:%.*]] = shl nsw i64 [[IDX1:%.*]], 2
469 ; CHECK-NEXT:    [[GEP2_IDX:%.*]] = shl nsw i64 [[IDX2:%.*]], 3
470 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i64 [[GEP1_IDX]], [[GEP2_IDX]]
471 ; CHECK-NEXT:    ret i1 [[CMP]]
473   %gep1 = getelementptr inbounds i32, ptr %ptr, i64 %idx1
474   %gep2 = getelementptr inbounds i64, ptr %ptr, i64 %idx2
475   %cmp = icmp ult ptr %gep1, %gep2
476   ret i1 %cmp
479 @ary = constant [4 x i8] [i8 1, i8 2, i8 3, i8 4]
481 define i1 @cmp_load_gep_global(i64 %idx) {
482 ; CHECK-LABEL: @cmp_load_gep_global(
483 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[IDX:%.*]], 2
484 ; CHECK-NEXT:    ret i1 [[CMP]]
486   %gep = getelementptr [4 x i8], ptr @ary, i64 0, i64 %idx
487   %load = load i8, ptr %gep
488   %cmp = icmp eq i8 %load, 3
489   ret i1 %cmp
492 define i1 @cmp_load_gep_global_different_load_type(i64 %idx) {
493 ; CHECK-LABEL: @cmp_load_gep_global_different_load_type(
494 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr [4 x i8], ptr @ary, i64 0, i64 [[IDX:%.*]]
495 ; CHECK-NEXT:    [[LOAD:%.*]] = load i16, ptr [[GEP]], align 2
496 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i16 [[LOAD]], 3
497 ; CHECK-NEXT:    ret i1 [[CMP]]
499   %gep = getelementptr [4 x i8], ptr @ary, i64 0, i64 %idx
500   %load = load i16, ptr %gep
501   %cmp = icmp eq i16 %load, 3
502   ret i1 %cmp
505 define i1 @cmp_load_gep_global_different_gep_type(i64 %idx) {
506 ; CHECK-LABEL: @cmp_load_gep_global_different_gep_type(
507 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr [4 x i16], ptr @ary, i64 0, i64 [[IDX:%.*]]
508 ; CHECK-NEXT:    [[LOAD:%.*]] = load i16, ptr [[GEP]], align 2
509 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i16 [[LOAD]], 3
510 ; CHECK-NEXT:    ret i1 [[CMP]]
512   %gep = getelementptr [4 x i16], ptr @ary, i64 0, i64 %idx
513   %load = load i16, ptr %gep
514   %cmp = icmp eq i16 %load, 3
515   ret i1 %cmp
518 define ptr @phi_of_gep(i1 %c, ptr %p) {
519 ; CHECK-LABEL: @phi_of_gep(
520 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
521 ; CHECK:       if:
522 ; CHECK-NEXT:    br label [[JOIN:%.*]]
523 ; CHECK:       else:
524 ; CHECK-NEXT:    br label [[JOIN]]
525 ; CHECK:       join:
526 ; CHECK-NEXT:    [[PHI:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 4
527 ; CHECK-NEXT:    ret ptr [[PHI]]
529   br i1 %c, label %if, label %else
532   %gep1 = getelementptr i32, ptr %p, i64 1
533   br label %join
535 else:
536   %gep2 = getelementptr i32, ptr %p, i64 1
537   br label %join
539 join:
540   %phi = phi ptr [ %gep1, %if ], [ %gep2, %else ]
541   ret ptr %phi
544 define ptr @phi_of_gep_flags_1(i1 %c, ptr %p) {
545 ; CHECK-LABEL: @phi_of_gep_flags_1(
546 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
547 ; CHECK:       if:
548 ; CHECK-NEXT:    br label [[JOIN:%.*]]
549 ; CHECK:       else:
550 ; CHECK-NEXT:    br label [[JOIN]]
551 ; CHECK:       join:
552 ; CHECK-NEXT:    [[PHI:%.*]] = getelementptr nusw nuw i8, ptr [[P:%.*]], i64 4
553 ; CHECK-NEXT:    ret ptr [[PHI]]
555   br i1 %c, label %if, label %else
558   %gep1 = getelementptr inbounds i32, ptr %p, i64 1
559   br label %join
561 else:
562   %gep2 = getelementptr nusw nuw i32, ptr %p, i64 1
563   br label %join
565 join:
566   %phi = phi ptr [ %gep1, %if ], [ %gep2, %else ]
567   ret ptr %phi
570 define ptr @phi_of_gep_flags_2(i1 %c, ptr %p) {
571 ; CHECK-LABEL: @phi_of_gep_flags_2(
572 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
573 ; CHECK:       if:
574 ; CHECK-NEXT:    br label [[JOIN:%.*]]
575 ; CHECK:       else:
576 ; CHECK-NEXT:    br label [[JOIN]]
577 ; CHECK:       join:
578 ; CHECK-NEXT:    [[PHI:%.*]] = getelementptr nuw i8, ptr [[P:%.*]], i64 4
579 ; CHECK-NEXT:    ret ptr [[PHI]]
581   br i1 %c, label %if, label %else
584   %gep1 = getelementptr nusw nuw i32, ptr %p, i64 1
585   br label %join
587 else:
588   %gep2 = getelementptr nuw i32, ptr %p, i64 1
589   br label %join
591 join:
592   %phi = phi ptr [ %gep1, %if ], [ %gep2, %else ]
593   ret ptr %phi
596 define ptr @phi_of_gep_different_type(i1 %c, ptr %p) {
597 ; CHECK-LABEL: @phi_of_gep_different_type(
598 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
599 ; CHECK:       if:
600 ; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 4
601 ; CHECK-NEXT:    br label [[JOIN:%.*]]
602 ; CHECK:       else:
603 ; CHECK-NEXT:    [[GEP2:%.*]] = getelementptr i8, ptr [[P]], i64 8
604 ; CHECK-NEXT:    br label [[JOIN]]
605 ; CHECK:       join:
606 ; CHECK-NEXT:    [[PHI:%.*]] = phi ptr [ [[GEP1]], [[IF]] ], [ [[GEP2]], [[ELSE]] ]
607 ; CHECK-NEXT:    ret ptr [[PHI]]
609   br i1 %c, label %if, label %else
612   %gep1 = getelementptr i32, ptr %p, i64 1
613   br label %join
615 else:
616   %gep2 = getelementptr i64, ptr %p, i64 1
617   br label %join
619 join:
620   %phi = phi ptr [ %gep1, %if ], [ %gep2, %else ]
621   ret ptr %phi
624 define ptr @gep_of_phi_of_gep(i1 %c, ptr %p) {
625 ; CHECK-LABEL: @gep_of_phi_of_gep(
626 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
627 ; CHECK:       if:
628 ; CHECK-NEXT:    br label [[JOIN:%.*]]
629 ; CHECK:       else:
630 ; CHECK-NEXT:    br label [[JOIN]]
631 ; CHECK:       join:
632 ; CHECK-NEXT:    [[TMP1:%.*]] = phi i64 [ 4, [[IF]] ], [ 8, [[ELSE]] ]
633 ; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[TMP1]]
634 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i8, ptr [[TMP2]], i64 4
635 ; CHECK-NEXT:    ret ptr [[GEP]]
637   br i1 %c, label %if, label %else
640   %gep1 = getelementptr i32, ptr %p, i64 1
641   br label %join
643 else:
644   %gep2 = getelementptr i32, ptr %p, i64 2
645   br label %join
647 join:
648   %phi = phi ptr [ %gep1, %if ], [ %gep2, %else ]
649   %gep = getelementptr i32, ptr %phi, i64 1
650   ret ptr %gep
653 define ptr @gep_of_phi_of_gep_different_type(i1 %c, ptr %p) {
654 ; CHECK-LABEL: @gep_of_phi_of_gep_different_type(
655 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
656 ; CHECK:       if:
657 ; CHECK-NEXT:    br label [[JOIN:%.*]]
658 ; CHECK:       else:
659 ; CHECK-NEXT:    br label [[JOIN]]
660 ; CHECK:       join:
661 ; CHECK-NEXT:    [[TMP1:%.*]] = phi i64 [ 4, [[IF]] ], [ 16, [[ELSE]] ]
662 ; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[TMP1]]
663 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i8, ptr [[TMP2]], i64 4
664 ; CHECK-NEXT:    ret ptr [[GEP]]
666   br i1 %c, label %if, label %else
669   %gep1 = getelementptr i32, ptr %p, i64 1
670   br label %join
672 else:
673   %gep2 = getelementptr i64, ptr %p, i64 2
674   br label %join
676 join:
677   %phi = phi ptr [ %gep1, %if ], [ %gep2, %else ]
678   %gep = getelementptr i32, ptr %phi, i64 1
679   ret ptr %gep
682 define ptr @select_of_gep(i1 %c, ptr %p) {
683 ; CHECK-LABEL: @select_of_gep(
684 ; CHECK-NEXT:    [[S_V:%.*]] = select i1 [[C:%.*]], i64 4, i64 8
685 ; CHECK-NEXT:    [[S:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[S_V]]
686 ; CHECK-NEXT:    ret ptr [[S]]
688   %gep1 = getelementptr i32, ptr %p, i64 1
689   %gep2 = getelementptr i32, ptr %p, i64 2
690   %s = select i1 %c, ptr %gep1, ptr %gep2
691   ret ptr %s
694 define ptr @select_of_gep_flags_1(i1 %c, ptr %p) {
695 ; CHECK-LABEL: @select_of_gep_flags_1(
696 ; CHECK-NEXT:    [[S_V:%.*]] = select i1 [[C:%.*]], i64 4, i64 8
697 ; CHECK-NEXT:    [[S:%.*]] = getelementptr nusw i8, ptr [[P:%.*]], i64 [[S_V]]
698 ; CHECK-NEXT:    ret ptr [[S]]
700   %gep1 = getelementptr inbounds i32, ptr %p, i64 1
701   %gep2 = getelementptr nusw nuw i32, ptr %p, i64 2
702   %s = select i1 %c, ptr %gep1, ptr %gep2
703   ret ptr %s
706 define ptr @select_of_gep_flags_2(i1 %c, ptr %p) {
707 ; CHECK-LABEL: @select_of_gep_flags_2(
708 ; CHECK-NEXT:    [[S_V:%.*]] = select i1 [[C:%.*]], i64 4, i64 8
709 ; CHECK-NEXT:    [[S:%.*]] = getelementptr nuw i8, ptr [[P:%.*]], i64 [[S_V]]
710 ; CHECK-NEXT:    ret ptr [[S]]
712   %gep1 = getelementptr nuw i32, ptr %p, i64 1
713   %gep2 = getelementptr nusw nuw i32, ptr %p, i64 2
714   %s = select i1 %c, ptr %gep1, ptr %gep2
715   ret ptr %s
718 define ptr @select_of_gep_different_type(i1 %c, ptr %p) {
719 ; CHECK-LABEL: @select_of_gep_different_type(
720 ; CHECK-NEXT:    [[S_V:%.*]] = select i1 [[C:%.*]], i64 4, i64 16
721 ; CHECK-NEXT:    [[S:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[S_V]]
722 ; CHECK-NEXT:    ret ptr [[S]]
724   %gep1 = getelementptr i32, ptr %p, i64 1
725   %gep2 = getelementptr i64, ptr %p, i64 2
726   %s = select i1 %c, ptr %gep1, ptr %gep2
727   ret ptr %s
730 define void @dse(ptr %p) {
731 ; CHECK-LABEL: @dse(
732 ; CHECK-NEXT:    store i32 0, ptr [[P:%.*]], align 4
733 ; CHECK-NEXT:    store i8 1, ptr [[P]], align 1
734 ; CHECK-NEXT:    ret void
736   store i32 0, ptr %p
737   store i8 1, ptr %p
738   ret void
741 declare void @call_i64(i64)
742 declare void @call_byval(i64, ptr byval(i64))
744 define void @call_cast_ptr_to_int(ptr %p) {
745 ; CHECK-LABEL: @call_cast_ptr_to_int(
746 ; CHECK-NEXT:    [[TMP1:%.*]] = ptrtoint ptr [[P:%.*]] to i64
747 ; CHECK-NEXT:    call void @call_i64(i64 [[TMP1]])
748 ; CHECK-NEXT:    ret void
750   call void @call_i64(ptr %p)
751   ret void
754 define void @call_cast_byval(ptr %p, ptr %p2) {
755 ; CHECK-LABEL: @call_cast_byval(
756 ; CHECK-NEXT:    [[TMP1:%.*]] = ptrtoint ptr [[P:%.*]] to i64
757 ; CHECK-NEXT:    call void @call_byval(i64 [[TMP1]], ptr byval(double) [[P2:%.*]])
758 ; CHECK-NEXT:    ret void
760   call void @call_byval(ptr %p, ptr byval(double) %p2)
761   ret void
764 declare float @fmodf(float, float)
766 define i32 @const_fold_call_with_func_type_mismatch() {
767 ; CHECK-LABEL: @const_fold_call_with_func_type_mismatch(
768 ; CHECK-NEXT:    [[V:%.*]] = call float @fmodf(float 0x40091EB860000000, float 2.000000e+00)
769 ; CHECK-NEXT:    ret i32 1066527622
771   %v = call i32 @fmodf(float 0x40091EB860000000, float 2.000000e+00)
772   ret i32 %v