xref: /llvm-project/llvm/test/Transforms/InstCombine/getelementptr.ll (revision 10f315dc9c96ec2413881ab55a285e35d80def88)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
4target datalayout = "e-p:64:64-p1:16:16-p2:32:32:32-p3:64:64:64-f16:32"
5
6%intstruct = type { i32 }
7%pair = type { i32, i32 }
8%struct.B = type { double }
9%struct.A = type { %struct.B, i32, i32 }
10%struct.C = type { [7 x i8] }
11
12
13@Global = external global [10 x i8]
14@Global_as1 = external addrspace(1) global [10 x i8]
15
16declare void @use(ptr)
17declare void @use.i64(i64)
18
19; Test noop elimination
20define ptr @test1(ptr %I) {
21; CHECK-LABEL: @test1(
22; CHECK-NEXT:    ret ptr [[I:%.*]]
23;
24  ret ptr %I
25}
26
27define ptr addrspace(1) @test1_as1(ptr addrspace(1) %I) {
28; CHECK-LABEL: @test1_as1(
29; CHECK-NEXT:    ret ptr addrspace(1) [[I:%.*]]
30;
31  ret ptr addrspace(1) %I
32}
33
34; Test noop elimination
35define ptr @test2(ptr %I) {
36; CHECK-LABEL: @test2(
37; CHECK-NEXT:    ret ptr [[I:%.*]]
38;
39  %A = getelementptr i32, ptr %I
40  ret ptr %A
41}
42
43; Test that two array indexing geps fold
44define ptr @test3(ptr %I) {
45; CHECK-LABEL: @test3(
46; CHECK-NEXT:    [[B:%.*]] = getelementptr i8, ptr [[I:%.*]], i64 84
47; CHECK-NEXT:    ret ptr [[B]]
48;
49  %A = getelementptr i32, ptr %I, i64 17
50  %B = getelementptr i32, ptr %A, i64 4
51  ret ptr %B
52}
53
54; Test that two getelementptr insts fold
55define ptr @test4(ptr %I) {
56; CHECK-LABEL: @test4(
57; CHECK-NEXT:    [[A:%.*]] = getelementptr i8, ptr [[I:%.*]], i64 4
58; CHECK-NEXT:    ret ptr [[A]]
59;
60  %A = getelementptr { i32 }, ptr %I, i64 1
61  ret ptr %A
62}
63
64define void @test5(i8 %B) {
65        ; This should be turned into a constexpr instead of being an instruction
66; CHECK-LABEL: @test5(
67; CHECK-NEXT:    store i8 [[B:%.*]], ptr getelementptr inbounds nuw (i8, ptr @Global, i64 4), align 1
68; CHECK-NEXT:    ret void
69;
70  %A = getelementptr [10 x i8], ptr @Global, i64 0, i64 4
71  store i8 %B, ptr %A
72  ret void
73}
74
75define void @test5_as1(i8 %B) {
76        ; This should be turned into a constexpr instead of being an instruction
77; CHECK-LABEL: @test5_as1(
78; CHECK-NEXT:    store i8 [[B:%.*]], ptr addrspace(1) getelementptr inbounds nuw (i8, ptr addrspace(1) @Global_as1, i16 4), align 1
79; CHECK-NEXT:    ret void
80;
81  %A = getelementptr [10 x i8], ptr addrspace(1) @Global_as1, i16 0, i16 4
82  store i8 %B, ptr addrspace(1) %A
83  ret void
84}
85
86%as1_ptr_struct = type { ptr addrspace(1) }
87%as2_ptr_struct = type { ptr addrspace(2) }
88
89@global_as2 = addrspace(2) global i32 zeroinitializer
90@global_as1_as2_ptr = addrspace(1) global %as2_ptr_struct { ptr addrspace(2) @global_as2 }
91
92; This should be turned into a constexpr instead of being an instruction
93define void @test_evaluate_gep_nested_as_ptrs(ptr addrspace(2) %B) {
94; CHECK-LABEL: @test_evaluate_gep_nested_as_ptrs(
95; CHECK-NEXT:    store ptr addrspace(2) [[B:%.*]], ptr addrspace(1) @global_as1_as2_ptr, align 4
96; CHECK-NEXT:    ret void
97;
98  store ptr addrspace(2) %B, ptr addrspace(1) @global_as1_as2_ptr
99  ret void
100}
101
102@arst = addrspace(1) global [4 x ptr addrspace(2)] zeroinitializer
103
104define void @test_evaluate_gep_as_ptrs_array(ptr addrspace(2) %B) {
105; CHECK-LABEL: @test_evaluate_gep_as_ptrs_array(
106; CHECK-NEXT:    store ptr addrspace(2) [[B:%.*]], ptr addrspace(1) getelementptr inbounds nuw (i8, ptr addrspace(1) @arst, i16 8), align 4
107; CHECK-NEXT:    ret void
108;
109
110  %A = getelementptr [4 x ptr addrspace(2)], ptr addrspace(1) @arst, i16 0, i16 2
111  store ptr addrspace(2) %B, ptr addrspace(1) %A
112  ret void
113}
114
115; This should be turned into a constexpr instead of being an instruction
116define void @test_overaligned_vec(i8 %B) {
117; CHECK-LABEL: @test_overaligned_vec(
118; CHECK-NEXT:    store i8 [[B:%.*]], ptr getelementptr inbounds nuw (i8, ptr @Global, i64 2), align 1
119; CHECK-NEXT:    ret void
120;
121  %A = getelementptr <2 x half>, ptr @Global, i64 0, i64 1
122  store i8 %B, ptr %A
123  ret void
124}
125
126define ptr @test7(ptr %I, i64 %C, i64 %D) {
127; CHECK-LABEL: @test7(
128; CHECK-NEXT:    [[A:%.*]] = getelementptr i32, ptr [[I:%.*]], i64 [[C:%.*]]
129; CHECK-NEXT:    [[B:%.*]] = getelementptr i32, ptr [[A]], i64 [[D:%.*]]
130; CHECK-NEXT:    ret ptr [[B]]
131;
132  %A = getelementptr i32, ptr %I, i64 %C
133  %B = getelementptr i32, ptr %A, i64 %D
134  ret ptr %B
135}
136
137define ptr @test8(ptr %X) {
138        ;; Fold into the cast.
139; CHECK-LABEL: @test8(
140; CHECK-NEXT:    ret ptr [[X:%.*]]
141;
142  ret ptr %X
143}
144
145define i32 @test9() {
146; CHECK-LABEL: @test9(
147; CHECK-NEXT:    ret i32 8
148;
149  %A = getelementptr { i32, double }, ptr null, i32 0, i32 1
150  %B = ptrtoint ptr %A to i32
151  ret i32 %B
152}
153
154define i1 @test10(ptr %x, ptr %y) {
155; CHECK-LABEL: @test10(
156; CHECK-NEXT:    [[T4:%.*]] = icmp eq ptr [[X:%.*]], [[Y:%.*]]
157; CHECK-NEXT:    ret i1 [[T4]]
158;
159  %t1 = getelementptr { i32, i32 }, ptr %x, i32 0, i32 1
160  %t3 = getelementptr { i32, i32 }, ptr %y, i32 0, i32 1
161  %t4 = icmp eq ptr %t1, %t3
162  ret i1 %t4
163}
164
165define i1 @test10_addrspacecast(ptr %x, ptr addrspace(3) %y) {
166; CHECK-LABEL: @test10_addrspacecast(
167; CHECK-NEXT:    [[T1:%.*]] = getelementptr i8, ptr [[X:%.*]], i64 4
168; CHECK-NEXT:    [[T3:%.*]] = getelementptr i8, ptr addrspace(3) [[Y:%.*]], i64 4
169; CHECK-NEXT:    [[T3_C:%.*]] = addrspacecast ptr addrspace(3) [[T3]] to ptr
170; CHECK-NEXT:    [[T4:%.*]] = icmp eq ptr [[T1]], [[T3_C]]
171; CHECK-NEXT:    ret i1 [[T4]]
172;
173  %t1 = getelementptr { i32, i32 }, ptr %x, i32 0, i32 1
174  %t3 = getelementptr { i32, i32 }, ptr addrspace(3) %y, i32 0, i32 1
175  %t3.c = addrspacecast ptr addrspace(3) %t3 to ptr
176  %t4 = icmp eq ptr %t1, %t3.c
177  ret i1 %t4
178}
179
180define i1 @test11(ptr %X) {
181; CHECK-LABEL: @test11(
182; CHECK-NEXT:    [[Q:%.*]] = icmp eq ptr [[X:%.*]], null
183; CHECK-NEXT:    ret i1 [[Q]]
184;
185  %P = getelementptr { i32, i32 }, ptr %X, i32 0, i32 0
186  %Q = icmp eq ptr %P, null
187  ret i1 %Q
188}
189
190
191; PR4748
192define i32 @test12(ptr %a) {
193; CHECK-LABEL: @test12(
194; CHECK-NEXT:  entry:
195; CHECK-NEXT:    [[G3:%.*]] = getelementptr i8, ptr [[A:%.*]], i64 8
196; CHECK-NEXT:    store i32 10, ptr [[G3]], align 4
197; CHECK-NEXT:    ret i32 10
198;
199entry:
200  %g3 = getelementptr %struct.A, ptr %a, i32 0, i32 1
201  store i32 10, ptr %g3, align 4
202
203
204
205  %g5 = getelementptr %struct.A, ptr %a, i32 0, i32 1
206  %a_a = load i32, ptr %g5, align 4
207  ret i32 %a_a
208}
209
210
211; PR2235
212%S = type { i32, [ 100 x i32] }
213define i1 @test13(i64 %X, ptr %P) {
214; CHECK-LABEL: @test13(
215; CHECK-NEXT:    [[C:%.*]] = icmp eq i64 [[X:%.*]], -1
216; CHECK-NEXT:    ret i1 [[C]]
217;
218  %A = getelementptr inbounds %S, ptr %P, i32 0, i32 1, i64 %X
219  %C = icmp eq ptr %A, %P
220  ret i1 %C
221}
222
223define <2 x i1> @test13_vector(<2 x i64> %X, <2 x ptr> %P) nounwind {
224; CHECK-LABEL: @test13_vector(
225; CHECK-NEXT:    [[C:%.*]] = icmp eq <2 x i64> [[X:%.*]], splat (i64 -1)
226; CHECK-NEXT:    ret <2 x i1> [[C]]
227;
228  %A = getelementptr inbounds %S, <2 x ptr> %P, <2 x i64> zeroinitializer, <2 x i32> <i32 1, i32 1>, <2 x i64> %X
229  %B = getelementptr inbounds %S, <2 x ptr> %P, <2 x i64> <i64 0, i64 0>, <2 x i32> <i32 0, i32 0>
230  %C = icmp eq <2 x ptr> %A, %B
231  ret <2 x i1> %C
232}
233
234define <2 x i1> @test13_vector2(i64 %X, <2 x ptr> %P) nounwind {
235; CHECK-LABEL: @test13_vector2(
236; CHECK-NEXT:    [[DOTSPLATINSERT:%.*]] = insertelement <2 x i64> poison, i64 [[X:%.*]], i64 0
237; CHECK-NEXT:    [[TMP1:%.*]] = shl <2 x i64> [[DOTSPLATINSERT]], <i64 2, i64 0>
238; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq <2 x i64> [[TMP1]], <i64 -4, i64 poison>
239; CHECK-NEXT:    [[C:%.*]] = shufflevector <2 x i1> [[TMP2]], <2 x i1> poison, <2 x i32> zeroinitializer
240; CHECK-NEXT:    ret <2 x i1> [[C]]
241;
242  %A = getelementptr inbounds %S, <2 x ptr> %P, <2 x i64> zeroinitializer, <2 x i32> <i32 1, i32 1>, i64 %X
243  %B = getelementptr inbounds %S, <2 x ptr> %P, <2 x i64> <i64 0, i64 0>, <2 x i32> <i32 0, i32 0>
244  %C = icmp eq <2 x ptr> %A, %B
245  ret <2 x i1> %C
246}
247
248define <2 x i1> @test13_fixed_fixed(i64 %X, ptr %P, <2 x i64> %y) nounwind {
249; CHECK-LABEL: @test13_fixed_fixed(
250; CHECK-NEXT:    [[DOTSPLATINSERT:%.*]] = insertelement <2 x i64> poison, i64 [[X:%.*]], i64 0
251; CHECK-NEXT:    [[TMP1:%.*]] = shl <2 x i64> [[DOTSPLATINSERT]], <i64 3, i64 0>
252; CHECK-NEXT:    [[A_IDX:%.*]] = shufflevector <2 x i64> [[TMP1]], <2 x i64> poison, <2 x i32> zeroinitializer
253; CHECK-NEXT:    [[B_IDX:%.*]] = shl nsw <2 x i64> [[Y:%.*]], splat (i64 4)
254; CHECK-NEXT:    [[C:%.*]] = icmp eq <2 x i64> [[A_IDX]], [[B_IDX]]
255; CHECK-NEXT:    ret <2 x i1> [[C]]
256;
257  %A = getelementptr inbounds <2 x i64>, ptr %P, <2 x i64> zeroinitializer, i64 %X
258  %B = getelementptr inbounds <2 x i64>, ptr %P, <2 x i64> %y
259  %C = icmp eq <2 x ptr> %A, %B
260  ret <2 x i1> %C
261}
262
263define <2 x i1> @test13_fixed_scalable(i64 %X, ptr %P, <2 x i64> %y) nounwind {
264; CHECK-LABEL: @test13_fixed_scalable(
265; CHECK-NEXT:    [[DOTSPLATINSERT:%.*]] = insertelement <2 x i64> poison, i64 [[X:%.*]], i64 0
266; CHECK-NEXT:    [[TMP1:%.*]] = shl <2 x i64> [[DOTSPLATINSERT]], <i64 3, i64 0>
267; CHECK-NEXT:    [[A_IDX:%.*]] = shufflevector <2 x i64> [[TMP1]], <2 x i64> poison, <2 x i32> zeroinitializer
268; CHECK-NEXT:    [[TMP2:%.*]] = call i64 @llvm.vscale.i64()
269; CHECK-NEXT:    [[TMP3:%.*]] = shl i64 [[TMP2]], 4
270; CHECK-NEXT:    [[DOTSPLATINSERT1:%.*]] = insertelement <2 x i64> poison, i64 [[TMP3]], i64 0
271; CHECK-NEXT:    [[DOTSPLAT:%.*]] = shufflevector <2 x i64> [[DOTSPLATINSERT1]], <2 x i64> poison, <2 x i32> zeroinitializer
272; CHECK-NEXT:    [[B_IDX:%.*]] = mul nsw <2 x i64> [[Y:%.*]], [[DOTSPLAT]]
273; CHECK-NEXT:    [[C:%.*]] = icmp eq <2 x i64> [[A_IDX]], [[B_IDX]]
274; CHECK-NEXT:    ret <2 x i1> [[C]]
275;
276  %A = getelementptr inbounds <vscale x 2 x i64>, ptr %P, <2 x i64> zeroinitializer, i64 %X
277  %B = getelementptr inbounds <vscale x 2 x i64>, ptr %P, <2 x i64> %y
278  %C = icmp eq <2 x ptr> %A, %B
279  ret <2 x i1> %C
280}
281
282define <vscale x 2 x i1> @test13_scalable_scalable(i64 %X, ptr %P, <vscale x 2 x i64> %y) nounwind {
283; CHECK-LABEL: @test13_scalable_scalable(
284; CHECK-NEXT:    [[DOTSPLATINSERT:%.*]] = insertelement <vscale x 2 x i64> poison, i64 [[X:%.*]], i64 0
285; CHECK-NEXT:    [[DOTSPLAT:%.*]] = shufflevector <vscale x 2 x i64> [[DOTSPLATINSERT]], <vscale x 2 x i64> poison, <vscale x 2 x i32> zeroinitializer
286; CHECK-NEXT:    [[A_IDX:%.*]] = shl nsw <vscale x 2 x i64> [[DOTSPLAT]], splat (i64 3)
287; CHECK-NEXT:    [[TMP1:%.*]] = call i64 @llvm.vscale.i64()
288; CHECK-NEXT:    [[TMP2:%.*]] = shl i64 [[TMP1]], 4
289; CHECK-NEXT:    [[DOTSPLATINSERT1:%.*]] = insertelement <vscale x 2 x i64> poison, i64 [[TMP2]], i64 0
290; CHECK-NEXT:    [[DOTSPLAT2:%.*]] = shufflevector <vscale x 2 x i64> [[DOTSPLATINSERT1]], <vscale x 2 x i64> poison, <vscale x 2 x i32> zeroinitializer
291; CHECK-NEXT:    [[B_IDX:%.*]] = mul nsw <vscale x 2 x i64> [[Y:%.*]], [[DOTSPLAT2]]
292; CHECK-NEXT:    [[C:%.*]] = icmp eq <vscale x 2 x i64> [[A_IDX]], [[B_IDX]]
293; CHECK-NEXT:    ret <vscale x 2 x i1> [[C]]
294;
295  %A = getelementptr inbounds <vscale x 2 x i64>, ptr %P, <vscale x 2 x i64> zeroinitializer, i64 %X
296  %B = getelementptr inbounds <vscale x 2 x i64>, ptr %P, <vscale x 2 x i64> %y
297  %C = icmp eq <vscale x 2 x ptr> %A, %B
298  ret <vscale x 2 x i1> %C
299}
300
301; This is a test of icmp + shl nuw in disguise - 4611... is 0x3fff...
302define <2 x i1> @test13_vector3(i64 %X, <2 x ptr> %P) nounwind {
303; CHECK-LABEL: @test13_vector3(
304; CHECK-NEXT:    [[DOTSPLATINSERT:%.*]] = insertelement <2 x i64> poison, i64 [[X:%.*]], i64 0
305; CHECK-NEXT:    [[TMP1:%.*]] = shl <2 x i64> [[DOTSPLATINSERT]], <i64 2, i64 0>
306; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq <2 x i64> [[TMP1]], <i64 4, i64 poison>
307; CHECK-NEXT:    [[C:%.*]] = shufflevector <2 x i1> [[TMP2]], <2 x i1> poison, <2 x i32> zeroinitializer
308; CHECK-NEXT:    ret <2 x i1> [[C]]
309;
310  %A = getelementptr inbounds %S, <2 x ptr> %P, <2 x i64> zeroinitializer, <2 x i32> <i32 1, i32 1>, i64 %X
311  %B = getelementptr inbounds %S, <2 x ptr> %P, <2 x i64> <i64 0, i64 0>, <2 x i32> <i32 1, i32 1>, i64 1
312  %C = icmp eq <2 x ptr> %A, %B
313  ret <2 x i1> %C
314}
315
316define i1 @test13_as1(i16 %X, ptr addrspace(1) %P) {
317; CHECK-LABEL: @test13_as1(
318; CHECK-NEXT:    [[C:%.*]] = icmp eq i16 [[X:%.*]], -1
319; CHECK-NEXT:    ret i1 [[C]]
320;
321  %A = getelementptr inbounds %S, ptr addrspace(1) %P, i16 0, i32 1, i16 %X
322  %C = icmp eq ptr addrspace(1) %A, %P
323  ret i1 %C
324}
325
326define <2 x i1> @test13_vector_as1(<2 x i16> %X, <2 x ptr addrspace(1)> %P) {
327; CHECK-LABEL: @test13_vector_as1(
328; CHECK-NEXT:    [[C:%.*]] = icmp eq <2 x i16> [[X:%.*]], splat (i16 -1)
329; CHECK-NEXT:    ret <2 x i1> [[C]]
330;
331  %A = getelementptr inbounds %S, <2 x ptr addrspace(1)> %P, <2 x i16> <i16 0, i16 0>, <2 x i32> <i32 1, i32 1>, <2 x i16> %X
332  %B = getelementptr inbounds %S, <2 x ptr addrspace(1)> %P, <2 x i16> <i16 0, i16 0>, <2 x i32> <i32 0, i32 0>
333  %C = icmp eq <2 x ptr addrspace(1)> %A, %B
334  ret <2 x i1> %C
335}
336
337define i1 @test13_i32(i32 %X, ptr %P) {
338; CHECK-LABEL: @test13_i32(
339; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[X:%.*]], -1
340; CHECK-NEXT:    ret i1 [[C]]
341;
342  %A = getelementptr inbounds %S, ptr %P, i32 0, i32 1, i32 %X
343  %C = icmp eq ptr %A, %P
344  ret i1 %C
345}
346
347define i1 @test13_i16(i16 %X, ptr %P) {
348; CHECK-LABEL: @test13_i16(
349; CHECK-NEXT:    [[C:%.*]] = icmp eq i16 [[X:%.*]], -1
350; CHECK-NEXT:    ret i1 [[C]]
351;
352  %A = getelementptr inbounds %S, ptr %P, i16 0, i32 1, i16 %X
353  %C = icmp eq ptr %A, %P
354  ret i1 %C
355}
356
357define i1 @test13_i128(i128 %X, ptr %P) {
358; CHECK-LABEL: @test13_i128(
359; CHECK-NEXT:    [[TMP1:%.*]] = trunc i128 [[X:%.*]] to i64
360; CHECK-NEXT:    [[C:%.*]] = icmp eq i64 [[TMP1]], -1
361; CHECK-NEXT:    ret i1 [[C]]
362;
363  %A = getelementptr inbounds %S, ptr %P, i128 0, i32 1, i128 %X
364  %C = icmp eq ptr %A, %P
365  ret i1 %C
366}
367
368
369@G = external global [3 x i8]
370define ptr @test14(i32 %idx) {
371; CHECK-LABEL: @test14(
372; CHECK-NEXT:    [[ZEXT:%.*]] = zext i32 [[IDX:%.*]] to i64
373; CHECK-NEXT:    [[T:%.*]] = getelementptr i8, ptr @G, i64 [[ZEXT]]
374; CHECK-NEXT:    ret ptr [[T]]
375;
376  %zext = zext i32 %idx to i64
377  %t = getelementptr i8, ptr @G, i64 %zext
378  ret ptr %t
379}
380
381
382; Test folding of constantexpr geps into normal geps.
383@Array = external global [40 x i32]
384define ptr @test15(i64 %X) {
385; CHECK-LABEL: @test15(
386; CHECK-NEXT:    [[A:%.*]] = getelementptr i32, ptr @Array, i64 [[X:%.*]]
387; CHECK-NEXT:    ret ptr [[A]]
388;
389  %A = getelementptr i32, ptr @Array, i64 %X
390  ret ptr %A
391}
392
393define ptr @test_index_canon(ptr %X, i32 %Idx) {
394; CHECK-LABEL: @test_index_canon(
395; CHECK-NEXT:    [[TMP1:%.*]] = sext i32 [[IDX:%.*]] to i64
396; CHECK-NEXT:    [[R:%.*]] = getelementptr i32, ptr [[X:%.*]], i64 [[TMP1]]
397; CHECK-NEXT:    ret ptr [[R]]
398;
399  %R = getelementptr i32, ptr %X, i32 %Idx
400  ret ptr %R
401}
402
403define ptr @test_index_canon_inbounds(ptr %X, i32 %Idx) {
404; CHECK-LABEL: @test_index_canon_inbounds(
405; CHECK-NEXT:    [[TMP1:%.*]] = sext i32 [[IDX:%.*]] to i64
406; CHECK-NEXT:    [[R:%.*]] = getelementptr inbounds i32, ptr [[X:%.*]], i64 [[TMP1]]
407; CHECK-NEXT:    ret ptr [[R]]
408;
409  %R = getelementptr inbounds i32, ptr %X, i32 %Idx
410  ret ptr %R
411}
412
413define ptr @test_index_canon_nusw_nuw(ptr %X, i32 %Idx) {
414; CHECK-LABEL: @test_index_canon_nusw_nuw(
415; CHECK-NEXT:    [[TMP1:%.*]] = sext i32 [[IDX:%.*]] to i64
416; CHECK-NEXT:    [[R:%.*]] = getelementptr nusw nuw i32, ptr [[X:%.*]], i64 [[TMP1]]
417; CHECK-NEXT:    ret ptr [[R]]
418;
419  %R = getelementptr nusw nuw i32, ptr %X, i32 %Idx
420  ret ptr %R
421}
422
423define ptr @test_index_canon_const_expr_inbounds() {
424; CHECK-LABEL: @test_index_canon_const_expr_inbounds(
425; CHECK-NEXT:    ret ptr getelementptr inbounds nuw (i8, ptr @Global, i64 123)
426;
427  ret ptr getelementptr inbounds (i8, ptr @Global, i32 123)
428}
429
430define ptr @test_index_canon_const_expr_nuw_nusw() {
431; CHECK-LABEL: @test_index_canon_const_expr_nuw_nusw(
432; CHECK-NEXT:    ret ptr getelementptr nusw nuw (i8, ptr @Global, i64 123)
433;
434  ret ptr getelementptr nusw nuw (i8, ptr @Global, i32 123)
435}
436
437define ptr @test_const_gep_gep_nuw() {
438; CHECK-LABEL: @test_const_gep_gep_nuw(
439; CHECK-NEXT:    ret ptr getelementptr nuw (i8, ptr @Global, i64 246)
440;
441  ret ptr getelementptr nuw (i8, ptr getelementptr nuw (i8, ptr @Global, i64 123), i64 123)
442}
443
444define ptr @test_const_gep_gep_nusw_no_overflow() {
445; CHECK-LABEL: @test_const_gep_gep_nusw_no_overflow(
446; CHECK-NEXT:    ret ptr getelementptr nusw nuw (i8, ptr @Global, i64 246)
447;
448  ret ptr getelementptr nusw (i8, ptr getelementptr nusw (i8, ptr @Global, i64 123), i64 123)
449}
450
451define ptr @test_const_gep_gep_nusw_no_overflow_neg() {
452; CHECK-LABEL: @test_const_gep_gep_nusw_no_overflow_neg(
453; CHECK-NEXT:    ret ptr getelementptr nusw (i8, ptr @Global, i64 -246)
454;
455  ret ptr getelementptr nusw (i8, ptr getelementptr nusw (i8, ptr @Global, i64 -123), i64 -123)
456}
457
458define ptr @test_const_gep_gep_nusw_overflow() {
459; CHECK-LABEL: @test_const_gep_gep_nusw_overflow(
460; CHECK-NEXT:    ret ptr getelementptr (i8, ptr @Global, i64 -2)
461;
462  ret ptr getelementptr nusw (i8, ptr getelementptr nusw (i8, ptr @Global, i64 u0x7fffffffffffffff), i64 u0x7fffffffffffffff)
463}
464
465define i1 @test17(ptr %P, i32 %I, i32 %J) {
466; CHECK-LABEL: @test17(
467; CHECK-NEXT:    [[C:%.*]] = icmp slt i32 [[I:%.*]], [[J:%.*]]
468; CHECK-NEXT:    ret i1 [[C]]
469;
470  %X = getelementptr inbounds i16, ptr %P, i32 %I
471  %Y = getelementptr inbounds i16, ptr %P, i32 %J
472  %C = icmp ult ptr %X, %Y
473  ret i1 %C
474}
475
476define i1 @test18(ptr %P, i32 %I) {
477; CHECK-LABEL: @test18(
478; CHECK-NEXT:    [[C:%.*]] = icmp slt i32 [[I:%.*]], 0
479; CHECK-NEXT:    ret i1 [[C]]
480;
481  %X = getelementptr inbounds i16, ptr %P, i32 %I
482  %C = icmp ult ptr %X, %P
483  ret i1 %C
484}
485
486; Larger than the pointer size for a non-zero address space
487define i1 @test18_as1(ptr addrspace(1) %P, i32 %I) {
488; CHECK-LABEL: @test18_as1(
489; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[I:%.*]], 32768
490; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[TMP1]], 0
491; CHECK-NEXT:    ret i1 [[C]]
492;
493  %X = getelementptr inbounds i16, ptr addrspace(1) %P, i32 %I
494  %C = icmp ult ptr addrspace(1) %X, %P
495  ret i1 %C
496}
497
498; Smaller than the pointer size for a non-zero address space
499define i1 @test18_as1_i32(ptr addrspace(1) %P, i32 %I) {
500; CHECK-LABEL: @test18_as1_i32(
501; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[I:%.*]], 32768
502; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[TMP1]], 0
503; CHECK-NEXT:    ret i1 [[C]]
504;
505  %X = getelementptr inbounds i16, ptr addrspace(1) %P, i32 %I
506  %C = icmp ult ptr addrspace(1) %X, %P
507  ret i1 %C
508}
509
510; Smaller than pointer size
511define i1 @test18_i16(ptr %P, i16 %I) {
512; CHECK-LABEL: @test18_i16(
513; CHECK-NEXT:    [[C:%.*]] = icmp slt i16 [[I:%.*]], 0
514; CHECK-NEXT:    ret i1 [[C]]
515;
516  %X = getelementptr inbounds i16, ptr %P, i16 %I
517  %C = icmp ult ptr %X, %P
518  ret i1 %C
519}
520
521; Same as pointer size
522define i1 @test18_i64(ptr %P, i64 %I) {
523; CHECK-LABEL: @test18_i64(
524; CHECK-NEXT:    [[C:%.*]] = icmp slt i64 [[I:%.*]], 0
525; CHECK-NEXT:    ret i1 [[C]]
526;
527  %X = getelementptr inbounds i16, ptr %P, i64 %I
528  %C = icmp ult ptr %X, %P
529  ret i1 %C
530}
531
532; Larger than the pointer size
533define i1 @test18_i128(ptr %P, i128 %I) {
534; CHECK-LABEL: @test18_i128(
535; CHECK-NEXT:    [[TMP1:%.*]] = and i128 [[I:%.*]], 9223372036854775808
536; CHECK-NEXT:    [[C:%.*]] = icmp ne i128 [[TMP1]], 0
537; CHECK-NEXT:    ret i1 [[C]]
538;
539  %X = getelementptr inbounds i16, ptr %P, i128 %I
540  %C = icmp ult ptr %X, %P
541  ret i1 %C
542}
543
544define i32 @test19(ptr %P, i32 %A, i32 %B) {
545; CHECK-LABEL: @test19(
546; CHECK-NEXT:    [[T10:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
547; CHECK-NEXT:    [[T11:%.*]] = zext i1 [[T10]] to i32
548; CHECK-NEXT:    ret i32 [[T11]]
549;
550  %t4 = getelementptr inbounds i32, ptr %P, i32 %A
551  %t9 = getelementptr inbounds i32, ptr %P, i32 %B
552  %t10 = icmp eq ptr %t4, %t9
553  %t11 = zext i1 %t10 to i32
554  ret i32 %t11
555}
556
557define i32 @test20(ptr %P, i32 %A, i32 %B) {
558; CHECK-LABEL: @test20(
559; CHECK-NEXT:    [[T6:%.*]] = icmp eq i32 [[A:%.*]], 0
560; CHECK-NEXT:    [[T7:%.*]] = zext i1 [[T6]] to i32
561; CHECK-NEXT:    ret i32 [[T7]]
562;
563  %t4 = getelementptr inbounds i32, ptr %P, i32 %A
564  %t6 = icmp eq ptr %t4, %P
565  %t7 = zext i1 %t6 to i32
566  ret i32 %t7
567}
568
569define i32 @test20_as1(ptr addrspace(1) %P, i32 %A, i32 %B) {
570; CHECK-LABEL: @test20_as1(
571; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[A:%.*]] to i16
572; CHECK-NEXT:    [[T6:%.*]] = icmp eq i16 [[TMP1]], 0
573; CHECK-NEXT:    [[T7:%.*]] = zext i1 [[T6]] to i32
574; CHECK-NEXT:    ret i32 [[T7]]
575;
576  %t4 = getelementptr inbounds i32, ptr addrspace(1) %P, i32 %A
577  %t6 = icmp eq ptr addrspace(1) %t4, %P
578  %t7 = zext i1 %t6 to i32
579  ret i32 %t7
580}
581
582
583define i32 @test21() {
584; CHECK-LABEL: @test21(
585; CHECK-NEXT:    [[PBOB1:%.*]] = alloca [[INTSTRUCT:%.*]], align 8
586; CHECK-NEXT:    [[RVAL:%.*]] = load i32, ptr [[PBOB1]], align 4
587; CHECK-NEXT:    ret i32 [[RVAL]]
588;
589  %pbob1 = alloca %intstruct
590  %pbob2 = getelementptr %intstruct, ptr %pbob1
591  %rval = load i32, ptr %pbob2
592  ret i32 %rval
593}
594
595
596@A = global i32 1                 ; <ptr> [#uses=1]
597@B = global i32 2                 ; <ptr> [#uses=1]
598
599define i1 @test22() {
600; CHECK-LABEL: @test22(
601; CHECK-NEXT:    [[C:%.*]] = icmp ult ptr getelementptr inbounds nuw (i8, ptr @A, i64 4), getelementptr (i8, ptr @B, i64 8)
602; CHECK-NEXT:    ret i1 [[C]]
603;
604  %C = icmp ult ptr getelementptr (i32, ptr @A, i64 1),
605  getelementptr (i32, ptr @B, i64 2)
606  ret i1 %C
607}
608
609
610%X = type { [10 x i32], float }
611
612define i1 @test23() {
613; CHECK-LABEL: @test23(
614; CHECK-NEXT:    ret i1 false
615;
616  %A = getelementptr %X, ptr null, i64 0, i32 0, i64 0                  ; <ptr> [#uses=1]
617  %B = icmp ne ptr %A, null                ; <i1> [#uses=1]
618  ret i1 %B
619}
620
621define void @test25() {
622; CHECK-LABEL: @test25(
623; CHECK-NEXT:  entry:
624; CHECK-NEXT:    unreachable
625;
626entry:
627  %t = getelementptr { i64, i64, i64, i64 }, ptr null, i32 0, i32 3
628  %t.upgrd.1 = load i64, ptr %t
629  %t8.ui = load i64, ptr null
630  %t8 = bitcast i64 %t8.ui to i64
631  %t9 = and i64 %t8, %t.upgrd.1
632  %sext = trunc i64 %t9 to i32
633  %t27.i = sext i32 %sext to i64
634  tail call void @foo25( i32 0, i64 %t27.i )
635  unreachable
636}
637
638declare void @foo25(i32, i64)
639
640
641; PR1637
642define i1 @test26(ptr %arr) {
643; CHECK-LABEL: @test26(
644; CHECK-NEXT:    ret i1 true
645;
646  %X = getelementptr i8, ptr %arr, i32 1
647  %Y = getelementptr i8, ptr %arr, i32 1
648  %test = icmp uge ptr %X, %Y
649  ret i1 %test
650}
651
652  %struct.__large_struct = type { [100 x i64] }
653  %struct.compat_siginfo = type { i32, i32, i32, { [29 x i32] } }
654  %struct.siginfo_t = type { i32, i32, i32, { { i32, i32, [0 x i8], %struct.sigval_t, i32 }, [88 x i8] } }
655  %struct.sigval_t = type { ptr }
656
657define i32 @test27(ptr %to, ptr %from) {
658; CHECK-LABEL: @test27(
659; CHECK-NEXT:  entry:
660; CHECK-NEXT:    [[FROM_ADDR:%.*]] = alloca ptr, align 8
661; CHECK-NEXT:    [[T344:%.*]] = load ptr, ptr [[FROM_ADDR]], align 8
662; CHECK-NEXT:    [[T348:%.*]] = getelementptr i8, ptr [[T344]], i64 24
663; CHECK-NEXT:    [[T351:%.*]] = load i32, ptr [[T348]], align 8
664; CHECK-NEXT:    [[T360:%.*]] = call i32 asm sideeffect "...", "=r,ir,*m,i,0,~{dirflag},~{fpsr},~{flags}"(i32 [[T351]], ptr elementtype([[STRUCT___LARGE_STRUCT:%.*]]) null, i32 -14, i32 0) #[[ATTR0:[0-9]+]]
665; CHECK-NEXT:    unreachable
666;
667entry:
668  %from_addr = alloca ptr
669  %t344 = load ptr, ptr %from_addr, align 8
670  %t345 = getelementptr %struct.siginfo_t, ptr %t344, i32 0, i32 3
671  %t346 = getelementptr { { i32, i32, [0 x i8], %struct.sigval_t, i32 }, [88 x i8] }, ptr %t345, i32 0, i32 0
672  %t348 = getelementptr { i32, i32, %struct.sigval_t }, ptr %t346, i32 0, i32 2
673  %t351 = load i32, ptr %t348, align 8
674  %t360 = call i32 asm sideeffect "...",
675  "=r,ir,*m,i,0,~{dirflag},~{fpsr},~{flags}"( i32 %t351, ptr elementtype(%struct.__large_struct) null, i32 -14, i32 0 )
676  unreachable
677}
678
679; PR1978
680  %struct.x = type <{ i8 }>
681@.str = internal constant [6 x i8] c"Main!\00"
682@.str1 = internal constant [12 x i8] c"destroy %p\0A\00"
683
684define i32 @test28() nounwind  {
685; CHECK-LABEL: @test28(
686; CHECK-NEXT:  entry:
687; CHECK-NEXT:    [[ORIENTATIONS:%.*]] = alloca [1 x [1 x %struct.x]], align 8
688; CHECK-NEXT:    [[T3:%.*]] = call i32 @puts(ptr noundef nonnull dereferenceable(1) @.str) #[[ATTR0]]
689; CHECK-NEXT:    [[T45:%.*]] = getelementptr inbounds nuw i8, ptr [[ORIENTATIONS]], i64 1
690; CHECK-NEXT:    br label [[BB10:%.*]]
691; CHECK:       bb10:
692; CHECK-NEXT:    [[INDVAR:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INDVAR_NEXT:%.*]], [[BB10]] ]
693; CHECK-NEXT:    [[T12_REC:%.*]] = xor i32 [[INDVAR]], -1
694; CHECK-NEXT:    [[TMP0:%.*]] = sext i32 [[T12_REC]] to i64
695; CHECK-NEXT:    [[T12:%.*]] = getelementptr inbounds [[STRUCT_X:%.*]], ptr [[T45]], i64 [[TMP0]]
696; CHECK-NEXT:    [[T16:%.*]] = call i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str1, ptr nonnull [[T12]]) #[[ATTR0]]
697; CHECK-NEXT:    [[T84:%.*]] = icmp eq ptr [[T12]], [[ORIENTATIONS]]
698; CHECK-NEXT:    [[INDVAR_NEXT]] = add i32 [[INDVAR]], 1
699; CHECK-NEXT:    br i1 [[T84]], label [[BB17:%.*]], label [[BB10]]
700; CHECK:       bb17:
701; CHECK-NEXT:    ret i32 0
702;
703entry:
704  %orientations = alloca [1 x [1 x %struct.x]]
705  %t3 = call i32 @puts( ptr @.str ) nounwind
706  %t45 = getelementptr inbounds [1 x [1 x %struct.x]], ptr %orientations, i32 1, i32 0, i32 0
707  br label %bb10
708
709bb10:
710  %indvar = phi i32 [ 0, %entry ], [ %indvar.next, %bb10 ]
711  %t.0.reg2mem.0.rec = mul i32 %indvar, -1
712  %t12.rec = add i32 %t.0.reg2mem.0.rec, -1
713  %t12 = getelementptr inbounds %struct.x, ptr %t45, i32 %t12.rec
714  %t16 = call i32 (ptr, ...) @printf( ptr nonnull dereferenceable(1) @.str1, ptr %t12 ) nounwind
715  %t84 = icmp eq ptr %t12, %orientations
716  %indvar.next = add i32 %indvar, 1
717  br i1 %t84, label %bb17, label %bb10
718
719bb17:
720  ret i32 0
721}
722
723declare i32 @puts(ptr)
724
725declare i32 @printf(ptr, ...)
726
727
728
729
730; rdar://6762290
731  %T = type <{ i64, i64, i64 }>
732define i32 @test29(ptr %start, i32 %X) nounwind {
733; CHECK-LABEL: @test29(
734; CHECK-NEXT:  entry:
735; CHECK-NEXT:    store i1 true, ptr poison, align 1
736; CHECK-NEXT:    br i1 poison, label [[IF_THEN216:%.*]], label [[IF_END363:%.*]]
737; CHECK:       if.then216:
738; CHECK-NEXT:    ret i32 1
739; CHECK:       if.end363:
740; CHECK-NEXT:    ret i32 0
741;
742entry:
743  %t3 = load i64, ptr null
744  %add.ptr = getelementptr i8, ptr %start, i64 %t3
745  %t158 = load i32, ptr null
746  %add.ptr159 = getelementptr %T, ptr null, i32 %t158
747  %add.ptr212 = getelementptr i8, ptr %start, i32 %X
748  %cmp214 = icmp ugt ptr %add.ptr212, %add.ptr
749  br i1 %cmp214, label %if.then216, label %if.end363
750
751if.then216:
752  ret i32 1
753
754if.end363:
755  ret i32 0
756}
757
758
759; PR3694
760define i32 @test30(i32 %m, i32 %n) nounwind {
761; CHECK-LABEL: @test30(
762; CHECK-NEXT:  entry:
763; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[N:%.*]] to i64
764; CHECK-NEXT:    [[TMP1:%.*]] = alloca i32, i64 [[TMP0]], align 4
765; CHECK-NEXT:    call void @test30f(ptr nonnull [[TMP1]]) #[[ATTR0]]
766; CHECK-NEXT:    [[TMP2:%.*]] = sext i32 [[M:%.*]] to i64
767; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr [0 x i32], ptr [[TMP1]], i64 0, i64 [[TMP2]]
768; CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4
769; CHECK-NEXT:    ret i32 [[TMP4]]
770;
771entry:
772  %0 = alloca i32, i32 %n, align 4
773  call void @test30f(ptr %0) nounwind
774  %1 = getelementptr [0 x i32], ptr %0, i32 0, i32 %m
775  %2 = load i32, ptr %1, align 4
776  ret i32 %2
777}
778
779declare void @test30f(ptr)
780
781
782
783define i1 @test31(ptr %A) {
784; CHECK-LABEL: @test31(
785; CHECK-NEXT:    ret i1 true
786;
787  %B = getelementptr i32, ptr %A, i32 1
788  %C = getelementptr i32, ptr %A, i64 1
789  %V = icmp eq ptr %B, %C
790  ret i1 %V
791}
792
793
794; PR1345
795define ptr @test32(ptr %v) {
796; CHECK-LABEL: @test32(
797; CHECK-NEXT:    [[A:%.*]] = alloca [4 x ptr], align 16
798; CHECK-NEXT:    store ptr null, ptr [[A]], align 8
799; CHECK-NEXT:    [[D:%.*]] = getelementptr inbounds nuw i8, ptr [[A]], i64 8
800; CHECK-NEXT:    store ptr [[V:%.*]], ptr [[D]], align 8
801; CHECK-NEXT:    [[F:%.*]] = getelementptr inbounds nuw i8, ptr [[A]], i64 16
802; CHECK-NEXT:    [[G:%.*]] = load ptr, ptr [[F]], align 8
803; CHECK-NEXT:    ret ptr [[G]]
804;
805  %A = alloca [4 x ptr], align 16
806  store ptr null, ptr %A
807  %D = getelementptr { [16 x i8] }, ptr %A, i32 0, i32 0, i32 8
808  store ptr %v, ptr %D
809  %F = getelementptr [4 x ptr], ptr %A, i32 0, i32 2
810  %G = load ptr, ptr %F
811  ret ptr %G
812}
813
814; PR3290
815%struct.Key = type { { i32, i32 } }
816%struct.anon = type <{ i8, [3 x i8], i32 }>
817
818define ptr @test33(ptr %A) {
819; CHECK-LABEL: @test33(
820; CHECK-NEXT:    [[C:%.*]] = getelementptr i8, ptr [[A:%.*]], i64 4
821; CHECK-NEXT:    ret ptr [[C]]
822;
823  %C = getelementptr %struct.anon, ptr %A, i32 0, i32 2
824  ret ptr %C
825}
826
827define ptr addrspace(1) @test33_as1(ptr addrspace(1) %A) {
828; CHECK-LABEL: @test33_as1(
829; CHECK-NEXT:    [[C:%.*]] = getelementptr i8, ptr addrspace(1) [[A:%.*]], i16 4
830; CHECK-NEXT:    ret ptr addrspace(1) [[C]]
831;
832  %C = getelementptr %struct.anon, ptr addrspace(1) %A, i32 0, i32 2
833  ret ptr addrspace(1) %C
834}
835
836define ptr addrspace(1) @test33_array_as1(ptr addrspace(1) %A) {
837; CHECK-LABEL: @test33_array_as1(
838; CHECK-NEXT:    [[C:%.*]] = getelementptr i8, ptr addrspace(1) [[A:%.*]], i16 8
839; CHECK-NEXT:    ret ptr addrspace(1) [[C]]
840;
841  %C = getelementptr [5 x i32], ptr addrspace(1) %A, i32 0, i32 2
842  ret ptr addrspace(1) %C
843}
844
845; Make sure the GEP indices use the right pointer sized integer
846define ptr addrspace(1) @test33_array_struct_as1(ptr addrspace(1) %A) {
847; CHECK-LABEL: @test33_array_struct_as1(
848; CHECK-NEXT:    [[C:%.*]] = getelementptr i8, ptr addrspace(1) [[A:%.*]], i16 8
849; CHECK-NEXT:    ret ptr addrspace(1) [[C]]
850;
851  %C = getelementptr [20 x i32], ptr addrspace(1) %A, i32 0, i32 2
852  ret ptr addrspace(1) %C
853}
854
855define ptr addrspace(1) @test33_addrspacecast(ptr %A) {
856; CHECK-LABEL: @test33_addrspacecast(
857; CHECK-NEXT:    [[B:%.*]] = addrspacecast ptr [[A:%.*]] to ptr addrspace(1)
858; CHECK-NEXT:    [[C:%.*]] = getelementptr i8, ptr addrspace(1) [[B]], i16 4
859; CHECK-NEXT:    ret ptr addrspace(1) [[C]]
860;
861  %B = addrspacecast ptr %A to ptr addrspace(1)
862  %C = getelementptr %struct.anon, ptr addrspace(1) %B, i32 0, i32 2
863  ret ptr addrspace(1) %C
864}
865
866  %T2 = type { ptr, i8 }
867define ptr @test34(ptr %Val, i64 %V) nounwind {
868; CHECK-LABEL: @test34(
869; CHECK-NEXT:  entry:
870; CHECK-NEXT:    [[C_CAST:%.*]] = inttoptr i64 [[V:%.*]] to ptr
871; CHECK-NEXT:    ret ptr [[C_CAST]]
872;
873entry:
874  %A = alloca %T2, align 8
875
876  store i64 %V, ptr %A
877  %C = load ptr, ptr %A, align 8
878  ret ptr %C
879}
880
881%t0 = type { ptr, [19 x i8] }
882%t1 = type { ptr, [0 x i8] }
883
884@array = external global [11 x i8]
885
886@s = external global %t0
887@"\01LC8" = external constant [17 x i8]
888
889; Instcombine should be able to fold this getelementptr.
890
891define i32 @test35() nounwind {
892; CHECK-LABEL: @test35(
893; CHECK-NEXT:    [[TMP1:%.*]] = call i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @"\01LC8", ptr nonnull getelementptr inbounds nuw (i8, ptr @s, i64 8)) #[[ATTR0]]
894; CHECK-NEXT:    ret i32 0
895;
896  call i32 (ptr, ...) @printf(ptr @"\01LC8",
897  ptr getelementptr (%t1, ptr @s, i32 0, i32 1, i32 0)) nounwind
898  ret i32 0
899}
900
901; Don't treat signed offsets as unsigned.
902define ptr @test36() nounwind {
903; CHECK-LABEL: @test36(
904; CHECK-NEXT:    ret ptr getelementptr (i8, ptr @array, i64 -1)
905;
906  ret ptr getelementptr ([11 x i8], ptr @array, i32 0, i64 -1)
907}
908
909; Instcombine shouldn't assume that gep(A,0,1) != gep(A,1,0).
910@A37 = external constant [1 x i8]
911define i1 @test37() nounwind {
912; CHECK-LABEL: @test37(
913; CHECK-NEXT:    ret i1 true
914;
915  %t = icmp eq ptr getelementptr ([1 x i8], ptr @A37, i64 0, i64 1),
916  getelementptr ([1 x i8], ptr @A37, i64 1, i64 0)
917  ret i1 %t
918}
919
920; Test index promotion
921define ptr @test38(ptr %I, i32 %n) {
922; CHECK-LABEL: @test38(
923; CHECK-NEXT:    [[TMP1:%.*]] = sext i32 [[N:%.*]] to i64
924; CHECK-NEXT:    [[A:%.*]] = getelementptr i32, ptr [[I:%.*]], i64 [[TMP1]]
925; CHECK-NEXT:    ret ptr [[A]]
926;
927  %A = getelementptr i32, ptr %I, i32 %n
928  ret ptr %A
929}
930
931; Test that we don't duplicate work when the second gep is a "bitcast".
932%pr10322_t = type { ptr }
933declare void @pr10322_f2(ptr)
934declare void @pr10322_f3(ptr)
935define void @pr10322_f1(ptr %foo) {
936; CHECK-LABEL: @pr10322_f1(
937; CHECK-NEXT:  entry:
938; CHECK-NEXT:    [[ARRAYIDX8:%.*]] = getelementptr inbounds nuw i8, ptr [[FOO:%.*]], i64 16
939; CHECK-NEXT:    call void @pr10322_f2(ptr nonnull [[ARRAYIDX8]]) #[[ATTR0]]
940; CHECK-NEXT:    call void @pr10322_f3(ptr nonnull [[ARRAYIDX8]]) #[[ATTR0]]
941; CHECK-NEXT:    ret void
942;
943entry:
944  %arrayidx8 = getelementptr inbounds %pr10322_t, ptr %foo, i64 2
945  call void @pr10322_f2(ptr %arrayidx8) nounwind
946  call void @pr10322_f3(ptr %arrayidx8) nounwind
947  ret void
948
949}
950
951; Test that we combine the last two geps in this sequence, before we
952; would wait for gep1 and gep2 to be combined and never combine 2 and 3.
953%three_gep_t = type {i32}
954%three_gep_t2 = type {%three_gep_t}
955
956define void @three_gep_f(ptr %x) {
957; CHECK-LABEL: @three_gep_f(
958; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr i8, ptr [[X:%.*]], i64 8
959; CHECK-NEXT:    call void @three_gep_h(ptr [[GEP1]])
960; CHECK-NEXT:    call void @three_gep_g(ptr [[GEP1]])
961; CHECK-NEXT:    ret void
962;
963  %gep1 = getelementptr %three_gep_t2, ptr %x, i64 2
964  call void @three_gep_h(ptr %gep1)
965  call void @three_gep_g(ptr %gep1)
966
967  ret void
968}
969
970declare void @three_gep_g(ptr)
971declare void @three_gep_h(ptr)
972
973%struct.ham = type { i32, ptr, ptr, ptr }
974%struct.zot = type { i64, i8 }
975
976define void @test39(ptr %arg, i8 %arg1) nounwind {
977; CHECK-LABEL: @test39(
978; CHECK-NEXT:    [[T:%.*]] = getelementptr inbounds nuw i8, ptr [[ARG:%.*]], i64 16
979; CHECK-NEXT:    [[T2:%.*]] = load ptr, ptr [[T]], align 8
980; CHECK-NEXT:    [[T4:%.*]] = getelementptr inbounds i8, ptr [[T2]], i64 -8
981; CHECK-NEXT:    store i8 [[ARG1:%.*]], ptr [[T4]], align 8
982; CHECK-NEXT:    ret void
983;
984  %t = getelementptr inbounds %struct.ham, ptr %arg, i64 0, i32 2
985  %t2 = load ptr, ptr %t, align 8
986  %t4 = getelementptr inbounds i8, ptr %t2, i64 -8
987  store i8 %arg1, ptr %t4, align 8
988  ret void
989
990}
991
992define i1 @pr16483(ptr %a, ptr %b) {
993; CHECK-LABEL: @pr16483(
994; CHECK-NEXT:    [[CMP:%.*]] = icmp ult ptr [[A:%.*]], [[B:%.*]]
995; CHECK-NEXT:    ret i1 [[CMP]]
996;
997  %cmp = icmp ult ptr %a, %b
998  ret i1 %cmp
999
1000}
1001
1002define i8 @test_gep_bitcast_as1(ptr addrspace(1) %arr, i16 %N) {
1003; CHECK-LABEL: @test_gep_bitcast_as1(
1004; CHECK-NEXT:    [[V:%.*]] = shl i16 [[N:%.*]], 2
1005; CHECK-NEXT:    [[T:%.*]] = getelementptr i8, ptr addrspace(1) [[ARR:%.*]], i16 [[V]]
1006; CHECK-NEXT:    [[X:%.*]] = load i8, ptr addrspace(1) [[T]], align 1
1007; CHECK-NEXT:    ret i8 [[X]]
1008;
1009  %V = mul i16 %N, 4
1010  %t = getelementptr i8, ptr addrspace(1) %arr, i16 %V
1011  %x = load i8, ptr addrspace(1) %t
1012  ret i8 %x
1013}
1014
1015; The element size of the array matches the element size of the pointer
1016define i64 @test_gep_bitcast_array_same_size_element(ptr %arr, i64 %N) {
1017; CHECK-LABEL: @test_gep_bitcast_array_same_size_element(
1018; CHECK-NEXT:    [[T_IDX:%.*]] = shl i64 [[N:%.*]], 6
1019; CHECK-NEXT:    [[T:%.*]] = getelementptr i8, ptr [[ARR:%.*]], i64 [[T_IDX]]
1020; CHECK-NEXT:    [[X:%.*]] = load i64, ptr [[T]], align 4
1021; CHECK-NEXT:    ret i64 [[X]]
1022;
1023  %V = mul i64 %N, 8
1024  %t = getelementptr i64, ptr %arr, i64 %V
1025  %x = load i64, ptr %t
1026  ret i64 %x
1027}
1028
1029; gep should be done in the original address space.
1030define i64 @test_gep_bitcast_array_same_size_element_addrspacecast(ptr %arr, i64 %N) {
1031; CHECK-LABEL: @test_gep_bitcast_array_same_size_element_addrspacecast(
1032; CHECK-NEXT:    [[CAST:%.*]] = addrspacecast ptr [[ARR:%.*]] to ptr addrspace(3)
1033; CHECK-NEXT:    [[T_IDX:%.*]] = shl i64 [[N:%.*]], 6
1034; CHECK-NEXT:    [[T:%.*]] = getelementptr i8, ptr addrspace(3) [[CAST]], i64 [[T_IDX]]
1035; CHECK-NEXT:    [[X:%.*]] = load i64, ptr addrspace(3) [[T]], align 4
1036; CHECK-NEXT:    ret i64 [[X]]
1037;
1038  %cast = addrspacecast ptr %arr to ptr addrspace(3)
1039  %V = mul i64 %N, 8
1040  %t = getelementptr i64, ptr addrspace(3) %cast, i64 %V
1041  %x = load i64, ptr addrspace(3) %t
1042  ret i64 %x
1043}
1044
1045; The element size of the array is different the element size of the pointer
1046define i8 @test_gep_bitcast_array_different_size_element(ptr %arr, i64 %N) {
1047; CHECK-LABEL: @test_gep_bitcast_array_different_size_element(
1048; CHECK-NEXT:    [[V:%.*]] = shl i64 [[N:%.*]], 3
1049; CHECK-NEXT:    [[T:%.*]] = getelementptr i8, ptr [[ARR:%.*]], i64 [[V]]
1050; CHECK-NEXT:    [[X:%.*]] = load i8, ptr [[T]], align 1
1051; CHECK-NEXT:    ret i8 [[X]]
1052;
1053  %V = mul i64 %N, 8
1054  %t = getelementptr i8, ptr %arr, i64 %V
1055  %x = load i8, ptr %t
1056  ret i8 %x
1057}
1058
1059define i64 @test_gep_bitcast_array_same_size_element_as1(ptr addrspace(1) %arr, i16 %N) {
1060; CHECK-LABEL: @test_gep_bitcast_array_same_size_element_as1(
1061; CHECK-NEXT:    [[T_IDX:%.*]] = shl i16 [[N:%.*]], 6
1062; CHECK-NEXT:    [[T:%.*]] = getelementptr i8, ptr addrspace(1) [[ARR:%.*]], i16 [[T_IDX]]
1063; CHECK-NEXT:    [[X:%.*]] = load i64, ptr addrspace(1) [[T]], align 4
1064; CHECK-NEXT:    ret i64 [[X]]
1065;
1066  %V = mul i16 %N, 8
1067  %t = getelementptr i64, ptr addrspace(1) %arr, i16 %V
1068  %x = load i64, ptr addrspace(1) %t
1069  ret i64 %x
1070}
1071
1072define i8 @test_gep_bitcast_array_different_size_element_as1(ptr addrspace(1) %arr, i16 %N) {
1073; CHECK-LABEL: @test_gep_bitcast_array_different_size_element_as1(
1074; CHECK-NEXT:    [[V:%.*]] = shl i16 [[N:%.*]], 3
1075; CHECK-NEXT:    [[T:%.*]] = getelementptr i8, ptr addrspace(1) [[ARR:%.*]], i16 [[V]]
1076; CHECK-NEXT:    [[X:%.*]] = load i8, ptr addrspace(1) [[T]], align 1
1077; CHECK-NEXT:    ret i8 [[X]]
1078;
1079  %V = mul i16 %N, 8
1080  %t = getelementptr i8, ptr addrspace(1) %arr, i16 %V
1081  %x = load i8, ptr addrspace(1) %t
1082  ret i8 %x
1083}
1084
1085define i64 @test40() {
1086; CHECK-LABEL: @test40(
1087; CHECK-NEXT:    ret i64 8
1088;
1089  %array = alloca [3 x i32], align 4
1090  %gep = getelementptr inbounds [3 x i32], ptr %array, i64 0, i64 2
1091  %p = ptrtoint ptr %array to i64
1092  %np = sub i64 0, %p
1093  %gep2 = getelementptr i8, ptr %gep, i64 %np
1094  %ret = ptrtoint ptr %gep2 to i64
1095  ret i64 %ret
1096
1097}
1098
1099define i16 @test41(ptr addrspace(1) %array) {
1100; CHECK-LABEL: @test41(
1101; CHECK-NEXT:    ret i16 8
1102;
1103  %gep = getelementptr inbounds [3 x i32], ptr addrspace(1) %array, i16 0, i16 2
1104  %p = ptrtoint ptr addrspace(1) %array to i16
1105  %np = sub i16 0, %p
1106  %gep2 = getelementptr i8, ptr addrspace(1) %gep, i16 %np
1107  %ret = ptrtoint ptr addrspace(1) %gep2 to i16
1108  ret i16 %ret
1109
1110}
1111
1112define ptr @test42i(ptr %c1, ptr %c2) {
1113; CHECK-LABEL: @test42i(
1114; CHECK-NEXT:    [[PTRTOINT:%.*]] = ptrtoint ptr [[C1:%.*]] to i64
1115; CHECK-NEXT:    [[SUB:%.*]] = sub i64 0, [[PTRTOINT]]
1116; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, ptr [[C2:%.*]], i64 [[SUB]]
1117; CHECK-NEXT:    ret ptr [[GEP]]
1118;
1119  %ptrtoint = ptrtoint ptr %c1 to i64
1120  %sub = sub i64 0, %ptrtoint
1121  %gep = getelementptr inbounds i8, ptr %c2, i64 %sub
1122  ret ptr %gep
1123
1124}
1125
1126define ptr @test42(ptr %c1, ptr %c2) {
1127; CHECK-LABEL: @test42(
1128; CHECK-NEXT:    [[PTRTOINT:%.*]] = ptrtoint ptr [[C1:%.*]] to i64
1129; CHECK-NEXT:    [[SUB:%.*]] = sub i64 0, [[PTRTOINT]]
1130; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i8, ptr [[C2:%.*]], i64 [[SUB]]
1131; CHECK-NEXT:    ret ptr [[GEP]]
1132;
1133  %ptrtoint = ptrtoint ptr %c1 to i64
1134  %sub = sub i64 0, %ptrtoint
1135  %gep = getelementptr i8, ptr %c2, i64 %sub
1136  ret ptr %gep
1137
1138}
1139
1140define ptr @test43i(ptr %c1, ptr %c2) {
1141; CHECK-LABEL: @test43i(
1142; CHECK-NEXT:    [[PTRTOINT:%.*]] = ptrtoint ptr [[C1:%.*]] to i64
1143; CHECK-NEXT:    [[SUB:%.*]] = sub i64 0, [[PTRTOINT]]
1144; CHECK-NEXT:    [[SHR:%.*]] = ashr i64 [[SUB]], 1
1145; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i16, ptr [[C2:%.*]], i64 [[SHR]]
1146; CHECK-NEXT:    ret ptr [[GEP]]
1147;
1148  %ptrtoint = ptrtoint ptr %c1 to i64
1149  %sub = sub i64 0, %ptrtoint
1150  %shr = ashr i64 %sub, 1
1151  %gep = getelementptr inbounds i16, ptr %c2, i64 %shr
1152  ret ptr %gep
1153
1154}
1155
1156define ptr @test44i(ptr %c1, ptr %c2) {
1157; CHECK-LABEL: @test44i(
1158; CHECK-NEXT:    [[PTRTOINT:%.*]] = ptrtoint ptr [[C1:%.*]] to i64
1159; CHECK-NEXT:    [[SUB:%.*]] = sub i64 0, [[PTRTOINT]]
1160; CHECK-NEXT:    [[SHR:%.*]] = sdiv i64 [[SUB]], 7
1161; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [[STRUCT_C:%.*]], ptr [[C2:%.*]], i64 [[SHR]]
1162; CHECK-NEXT:    ret ptr [[GEP]]
1163;
1164  %ptrtoint = ptrtoint ptr %c1 to i64
1165  %sub = sub i64 0, %ptrtoint
1166  %shr = sdiv i64 %sub, 7
1167  %gep = getelementptr inbounds %struct.C, ptr %c2, i64 %shr
1168  ret ptr %gep
1169
1170}
1171
1172define ptr @test45(ptr %c1, ptr %c2) {
1173; CHECK-LABEL: @test45(
1174; CHECK-NEXT:    [[PTRTOINT1:%.*]] = ptrtoint ptr [[C1:%.*]] to i64
1175; CHECK-NEXT:    [[PTRTOINT2:%.*]] = ptrtoint ptr [[C2:%.*]] to i64
1176; CHECK-NEXT:    [[SUB:%.*]] = sub i64 [[PTRTOINT2]], [[PTRTOINT1]]
1177; CHECK-NEXT:    [[SHR:%.*]] = sdiv i64 [[SUB]], 7
1178; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [[STRUCT_C:%.*]], ptr [[C1]], i64 [[SHR]]
1179; CHECK-NEXT:    ret ptr [[GEP]]
1180;
1181  %ptrtoint1 = ptrtoint ptr %c1 to i64
1182  %ptrtoint2 = ptrtoint ptr %c2 to i64
1183  %sub = sub i64 %ptrtoint2, %ptrtoint1   ; C2 - C1
1184  %shr = sdiv i64 %sub, 7
1185  %gep = getelementptr inbounds %struct.C, ptr %c1, i64 %shr   ; C1 + (C2 - C1)
1186  ret ptr %gep
1187}
1188
1189define ptr @test46(ptr %c1, ptr %c2, i64 %N) {
1190; CHECK-LABEL: @test46(
1191; CHECK-NEXT:    [[PTRTOINT:%.*]] = ptrtoint ptr [[C1:%.*]] to i64
1192; CHECK-NEXT:    [[SUB:%.*]] = sub i64 0, [[PTRTOINT]]
1193; CHECK-NEXT:    [[SDIV:%.*]] = sdiv i64 [[SUB]], [[N:%.*]]
1194; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [[STRUCT_C:%.*]], ptr [[C2:%.*]], i64 [[SDIV]]
1195; CHECK-NEXT:    ret ptr [[GEP]]
1196;
1197  %ptrtoint = ptrtoint ptr %c1 to i64
1198  %sub = sub i64 0, %ptrtoint
1199  %sdiv = sdiv i64 %sub, %N
1200  %gep = getelementptr inbounds %struct.C, ptr %c2, i64 %sdiv
1201  ret ptr %gep
1202
1203}
1204
1205define ptr @test47(ptr %I, i64 %C, i64 %D) {
1206; CHECK-LABEL: @test47(
1207; CHECK-NEXT:    [[B:%.*]] = getelementptr i32, ptr [[I:%.*]], i64 [[D:%.*]]
1208; CHECK-NEXT:    ret ptr [[B]]
1209;
1210  %sub = sub i64 %D, %C
1211  %A = getelementptr i32, ptr %I, i64 %C
1212  %B = getelementptr i32, ptr %A, i64 %sub
1213  ret ptr %B
1214}
1215
1216define ptr @test48(ptr %I, i64 %C, i64 %D) {
1217; CHECK-LABEL: @test48(
1218; CHECK-NEXT:    [[B:%.*]] = getelementptr i32, ptr [[I:%.*]], i64 [[D:%.*]]
1219; CHECK-NEXT:    ret ptr [[B]]
1220;
1221  %sub = sub i64 %D, %C
1222  %A = getelementptr i32, ptr %I, i64 %sub
1223  %B = getelementptr i32, ptr %A, i64 %C
1224  ret ptr %B
1225}
1226
1227define ptr @test49(ptr %I, i64 %C) {
1228; CHECK-LABEL: @test49(
1229; CHECK-NEXT:    [[B:%.*]] = getelementptr i8, ptr [[I:%.*]], i64 -4
1230; CHECK-NEXT:    ret ptr [[B]]
1231;
1232  %notC = xor i64 -1, %C
1233  %A = getelementptr i32, ptr %I, i64 %C
1234  %B = getelementptr i32, ptr %A, i64 %notC
1235  ret ptr %B
1236}
1237
1238define ptr addrspace(1) @ascast_0_gep(ptr %p) nounwind {
1239; CHECK-LABEL: @ascast_0_gep(
1240; CHECK-NEXT:    [[X:%.*]] = addrspacecast ptr [[P:%.*]] to ptr addrspace(1)
1241; CHECK-NEXT:    ret ptr addrspace(1) [[X]]
1242;
1243  %x = addrspacecast ptr %p to ptr addrspace(1)
1244  ret ptr addrspace(1) %x
1245}
1246
1247; Do not merge the GEP and the addrspacecast, because it would undo the
1248; addrspacecast canonicalization.
1249define ptr addrspace(1) @ascast_0_0_gep(ptr %p) nounwind {
1250; CHECK-LABEL: @ascast_0_0_gep(
1251; CHECK-NEXT:    [[X:%.*]] = addrspacecast ptr [[P:%.*]] to ptr addrspace(1)
1252; CHECK-NEXT:    ret ptr addrspace(1) [[X]]
1253;
1254  %x = addrspacecast ptr %p to ptr addrspace(1)
1255  ret ptr addrspace(1) %x
1256}
1257
1258define <2 x ptr> @PR32414(ptr %ptr) {
1259; CHECK-LABEL: @PR32414(
1260; CHECK-NEXT:    [[T1:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], <2 x i64> <i64 0, i64 1>
1261; CHECK-NEXT:    ret <2 x ptr> [[T1]]
1262;
1263  %t1 = getelementptr inbounds i32, ptr %ptr, <2 x i64> <i64 0, i64 1>
1264  ret <2 x ptr> %t1
1265}
1266
1267define ptr @test_bitcast_nzgep(ptr %base, i64 %idx) {
1268; CHECK-LABEL: @test_bitcast_nzgep(
1269; CHECK-NEXT:    [[PTR:%.*]] = getelementptr inbounds i32, ptr [[BASE:%.*]], i64 [[IDX:%.*]]
1270; CHECK-NEXT:    ret ptr [[PTR]]
1271;
1272  %ptr = getelementptr inbounds i32, ptr %base, i64 %idx
1273  ret ptr %ptr
1274}
1275
1276define ptr @test_zgep_nzgep(ptr %base, i64 %idx) {
1277; CHECK-LABEL: @test_zgep_nzgep(
1278; CHECK-NEXT:    [[PTR:%.*]] = getelementptr inbounds i32, ptr [[BASE:%.*]], i64 [[IDX:%.*]]
1279; CHECK-NEXT:    ret ptr [[PTR]]
1280;
1281  %ptr = getelementptr inbounds i32, ptr %base, i64 %idx
1282  ret ptr %ptr
1283}
1284
1285define ptr @test_nzgep_zgep(ptr %base, i64 %idx) {
1286; CHECK-LABEL: @test_nzgep_zgep(
1287; CHECK-NEXT:    [[BASE2:%.*]] = getelementptr inbounds [1 x i32], ptr [[BASE:%.*]], i64 [[IDX:%.*]]
1288; CHECK-NEXT:    ret ptr [[BASE2]]
1289;
1290  %base2 = getelementptr inbounds [1 x i32], ptr %base, i64 %idx
1291  ret ptr %base2
1292}
1293
1294define ptr @test_gep_inbounds_of_gep(ptr %base) {
1295; CHECK-LABEL: @test_gep_inbounds_of_gep(
1296; CHECK-NEXT:    [[PTR2:%.*]] = getelementptr i8, ptr [[BASE:%.*]], i64 32
1297; CHECK-NEXT:    ret ptr [[PTR2]]
1298;
1299  %ptr1 = getelementptr i32, ptr %base, i64 4
1300  %ptr2 = getelementptr inbounds i32, ptr %ptr1, i64 4
1301  ret ptr %ptr2
1302}
1303
1304%struct.f = type { i32 }
1305
1306@g0 = internal unnamed_addr constant %struct.f zeroinitializer, align 4
1307@g1 = internal unnamed_addr constant %struct.f { i32 -1 }, align 4
1308
1309define ptr @PR45084(i1 %cond) {
1310; CHECK-LABEL: @PR45084(
1311; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND:%.*]], ptr @g0, ptr @g1, !prof [[PROF0:![0-9]+]]
1312; CHECK-NEXT:    ret ptr [[SEL]]
1313;
1314  %sel = select i1 %cond, ptr @g0, ptr @g1, !prof !0
1315  ret ptr %sel
1316}
1317
1318define ptr @PR45084_extra_use(i1 %cond, ptr %p) {
1319; CHECK-LABEL: @PR45084_extra_use(
1320; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND:%.*]], ptr @g0, ptr @g1
1321; CHECK-NEXT:    store ptr [[SEL]], ptr [[P:%.*]], align 8
1322; CHECK-NEXT:    ret ptr [[SEL]]
1323;
1324  %sel = select i1 %cond, ptr @g0, ptr @g1
1325  store ptr %sel, ptr %p
1326  ret ptr %sel
1327}
1328
1329define ptr @gep_null_inbounds(i64 %idx) {
1330; CHECK-LABEL: @gep_null_inbounds(
1331; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, ptr null, i64 [[IDX:%.*]]
1332; CHECK-NEXT:    ret ptr [[GEP]]
1333;
1334  %gep = getelementptr inbounds i8, ptr null, i64 %idx
1335  ret ptr %gep
1336}
1337
1338define ptr @gep_null_not_inbounds(i64 %idx) {
1339; CHECK-LABEL: @gep_null_not_inbounds(
1340; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i8, ptr null, i64 [[IDX:%.*]]
1341; CHECK-NEXT:    ret ptr [[GEP]]
1342;
1343  %gep = getelementptr i8, ptr null, i64 %idx
1344  ret ptr %gep
1345}
1346
1347define ptr @gep_null_defined(i64 %idx) null_pointer_is_valid {
1348; CHECK-LABEL: @gep_null_defined(
1349; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, ptr null, i64 [[IDX:%.*]]
1350; CHECK-NEXT:    ret ptr [[GEP]]
1351;
1352  %gep = getelementptr inbounds i8, ptr null, i64 %idx
1353  ret ptr %gep
1354}
1355
1356define ptr @gep_null_inbounds_different_type(i64 %idx1, i64 %idx2) {
1357; CHECK-LABEL: @gep_null_inbounds_different_type(
1358; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [0 x i8], ptr null, i64 0, i64 [[IDX2:%.*]]
1359; CHECK-NEXT:    ret ptr [[GEP]]
1360;
1361  %gep = getelementptr inbounds [0 x i8], ptr null, i64 %idx1, i64 %idx2
1362  ret ptr %gep
1363}
1364
1365define ptr @D98588(ptr %c1, i64 %offset) {
1366; CHECK-LABEL: @D98588(
1367; CHECK-NEXT:    [[C2_NEXT_IDX:%.*]] = shl nsw i64 [[OFFSET:%.*]], 3
1368; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, ptr [[C1:%.*]], i64 [[C2_NEXT_IDX]]
1369; CHECK-NEXT:    ret ptr [[GEP]]
1370;
1371  %c2_next = getelementptr inbounds i64, ptr %c1, i64 %offset
1372  %ptrtoint1 = ptrtoint ptr %c1 to i64
1373  %ptrtoint2 = ptrtoint ptr %c2_next to i64
1374  %sub = sub i64 %ptrtoint2, %ptrtoint1   ; C2 - C1
1375  %gep = getelementptr inbounds i8, ptr %c1, i64 %sub   ; C1 + (C2 - C1)
1376  ret ptr %gep
1377}
1378
1379declare noalias ptr @malloc(i64) nounwind allockind("alloc,uninitialized") allocsize(0)
1380
1381define i32 @test_gep_bitcast_malloc(ptr %a) {
1382; CHECK-LABEL: @test_gep_bitcast_malloc(
1383; CHECK-NEXT:  entry:
1384; CHECK-NEXT:    [[CALL:%.*]] = call noalias dereferenceable_or_null(16) ptr @malloc(i64 16)
1385; CHECK-NEXT:    [[G3:%.*]] = getelementptr i8, ptr [[CALL]], i64 12
1386; CHECK-NEXT:    [[A_C:%.*]] = load i32, ptr [[G3]], align 4
1387; CHECK-NEXT:    ret i32 [[A_C]]
1388;
1389entry:
1390  %call = call noalias ptr @malloc(i64 16) #2
1391  %g3 = getelementptr %struct.A, ptr %call, i32 0, i32 2
1392  %a_c = load i32, ptr %g3, align 4
1393  ret i32 %a_c
1394}
1395
1396define ptr @gep_of_gep_multiuse_const_and_const(ptr %p, i64 %idx) {
1397; CHECK-LABEL: @gep_of_gep_multiuse_const_and_const(
1398; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 8
1399; CHECK-NEXT:    call void @use(ptr [[GEP1]])
1400; CHECK-NEXT:    [[GEP2:%.*]] = getelementptr i8, ptr [[P]], i64 12
1401; CHECK-NEXT:    ret ptr [[GEP2]]
1402;
1403  %gep1 = getelementptr { i32, i32 }, ptr %p, i64 1
1404  call void @use(ptr %gep1)
1405  %gep2 = getelementptr { i32, i32 }, ptr %gep1, i64 0, i32 1
1406  ret ptr %gep2
1407}
1408
1409define ptr @gep_of_gep_multiuse_var_and_const(ptr %p, i64 %idx) {
1410; CHECK-LABEL: @gep_of_gep_multiuse_var_and_const(
1411; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr { i32, i32 }, ptr [[P:%.*]], i64 [[IDX:%.*]]
1412; CHECK-NEXT:    call void @use(ptr [[GEP1]])
1413; CHECK-NEXT:    [[GEP2:%.*]] = getelementptr i8, ptr [[GEP1]], i64 4
1414; CHECK-NEXT:    ret ptr [[GEP2]]
1415;
1416  %gep1 = getelementptr { i32, i32 }, ptr %p, i64 %idx
1417  call void @use(ptr %gep1)
1418  %gep2 = getelementptr { i32, i32 }, ptr %gep1, i64 0, i32 1
1419  ret ptr %gep2
1420}
1421
1422define ptr @gep_of_gep_multiuse_var_and_var(ptr %p, i64 %idx, i64 %idx2) {
1423; CHECK-LABEL: @gep_of_gep_multiuse_var_and_var(
1424; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr [4 x i32], ptr [[P:%.*]], i64 [[IDX:%.*]]
1425; CHECK-NEXT:    call void @use(ptr [[GEP1]])
1426; CHECK-NEXT:    [[GEP2:%.*]] = getelementptr [4 x i32], ptr [[P]], i64 [[IDX]], i64 [[IDX2:%.*]]
1427; CHECK-NEXT:    ret ptr [[GEP2]]
1428;
1429  %gep1 = getelementptr [4 x i32], ptr %p, i64 %idx
1430  call void @use(ptr %gep1)
1431  %gep2 = getelementptr [4 x i32], ptr %gep1, i64 0, i64 %idx2
1432  ret ptr %gep2
1433}
1434
1435@g_i32_di = global i32 0
1436@g_i32_e = external global i32
1437@g_i32_ew = extern_weak global i32
1438@g_0xi8_e = external global [0 x i8]
1439
1440define ptr @const_gep_global_di_i8_smaller() {
1441; CHECK-LABEL: @const_gep_global_di_i8_smaller(
1442; CHECK-NEXT:    ret ptr getelementptr inbounds nuw (i8, ptr @g_i32_di, i64 3)
1443;
1444  ret ptr getelementptr (i8, ptr @g_i32_di, i64 3)
1445}
1446
1447define ptr @const_gep_global_di_i8_exact() {
1448; CHECK-LABEL: @const_gep_global_di_i8_exact(
1449; CHECK-NEXT:    ret ptr getelementptr inbounds nuw (i8, ptr @g_i32_di, i64 4)
1450;
1451  ret ptr getelementptr (i8, ptr @g_i32_di, i64 4)
1452}
1453
1454define ptr @const_gep_global_di_i8_larger() {
1455; CHECK-LABEL: @const_gep_global_di_i8_larger(
1456; CHECK-NEXT:    ret ptr getelementptr (i8, ptr @g_i32_di, i64 5)
1457;
1458  ret ptr getelementptr (i8, ptr @g_i32_di, i64 5)
1459}
1460
1461define ptr @const_gep_global_di_i64_larger() {
1462; CHECK-LABEL: @const_gep_global_di_i64_larger(
1463; CHECK-NEXT:    ret ptr getelementptr (i8, ptr @g_i32_di, i64 8)
1464;
1465  ret ptr getelementptr (i64, ptr @g_i32_di, i64 1)
1466}
1467
1468define ptr @const_gep_global_e_smaller() {
1469; CHECK-LABEL: @const_gep_global_e_smaller(
1470; CHECK-NEXT:    ret ptr getelementptr inbounds nuw (i8, ptr @g_i32_e, i64 3)
1471;
1472  ret ptr getelementptr (i8, ptr @g_i32_e, i64 3)
1473}
1474
1475define ptr @const_gep_global_e_exact() {
1476; CHECK-LABEL: @const_gep_global_e_exact(
1477; CHECK-NEXT:    ret ptr getelementptr inbounds nuw (i8, ptr @g_i32_e, i64 4)
1478;
1479  ret ptr getelementptr (i8, ptr @g_i32_e, i64 4)
1480}
1481
1482define ptr @const_gep_global_e_larger() {
1483; CHECK-LABEL: @const_gep_global_e_larger(
1484; CHECK-NEXT:    ret ptr getelementptr (i8, ptr @g_i32_e, i64 5)
1485;
1486  ret ptr getelementptr (i8, ptr @g_i32_e, i64 5)
1487}
1488
1489define ptr @const_gep_global_ew_smaller() {
1490; CHECK-LABEL: @const_gep_global_ew_smaller(
1491; CHECK-NEXT:    ret ptr getelementptr (i8, ptr @g_i32_ew, i64 3)
1492;
1493  ret ptr getelementptr (i8, ptr @g_i32_ew, i64 3)
1494}
1495
1496define ptr @const_gep_global_ew_exact() {
1497; CHECK-LABEL: @const_gep_global_ew_exact(
1498; CHECK-NEXT:    ret ptr getelementptr (i8, ptr @g_i32_ew, i64 4)
1499;
1500  ret ptr getelementptr (i8, ptr @g_i32_ew, i64 4)
1501}
1502
1503define ptr @const_gep_global_ew_larger() {
1504; CHECK-LABEL: @const_gep_global_ew_larger(
1505; CHECK-NEXT:    ret ptr getelementptr (i8, ptr @g_i32_ew, i64 5)
1506;
1507  ret ptr getelementptr (i8, ptr @g_i32_ew, i64 5)
1508}
1509
1510define ptr @const_gep_0xi8_global() {
1511; CHECK-LABEL: @const_gep_0xi8_global(
1512; CHECK-NEXT:    ret ptr getelementptr (i8, ptr @g_0xi8_e, i64 10)
1513;
1514  ret ptr getelementptr ([0 x i8], ptr @g_0xi8_e, i64 0, i64 10)
1515}
1516
1517define ptr @const_gep_chain(ptr %p, i64 %a) {
1518; CHECK-LABEL: @const_gep_chain(
1519; CHECK-NEXT:    [[P1:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 [[A:%.*]]
1520; CHECK-NEXT:    [[P4:%.*]] = getelementptr inbounds nuw i8, ptr [[P1]], i64 6
1521; CHECK-NEXT:    ret ptr [[P4]]
1522;
1523  %p1 = getelementptr inbounds i8, ptr %p, i64 %a
1524  %p2 = getelementptr inbounds i8, ptr %p1, i64 1
1525  %p3 = getelementptr inbounds i8, ptr %p2, i64 2
1526  %p4 = getelementptr inbounds i8, ptr %p3, i64 3
1527  ret ptr %p4
1528}
1529
1530define ptr @gep_sdiv(ptr %p, i64 %off) {
1531; CHECK-LABEL: @gep_sdiv(
1532; CHECK-NEXT:    [[PTR:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[OFF:%.*]]
1533; CHECK-NEXT:    ret ptr [[PTR]]
1534;
1535  %index = sdiv exact i64 %off, 7
1536  %ptr = getelementptr %struct.C, ptr %p, i64 %index
1537  ret ptr %ptr
1538}
1539
1540define ptr @gep_udiv(ptr %p, i64 %off) {
1541; CHECK-LABEL: @gep_udiv(
1542; CHECK-NEXT:    [[PTR:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[OFF:%.*]]
1543; CHECK-NEXT:    ret ptr [[PTR]]
1544;
1545  %index = udiv exact i64 %off, 7
1546  %ptr = getelementptr %struct.C, ptr %p, i64 %index
1547  ret ptr %ptr
1548}
1549
1550define <2 x ptr> @gep_sdiv_vec(<2 x ptr> %p, <2 x i64> %off) {
1551; CHECK-LABEL: @gep_sdiv_vec(
1552; CHECK-NEXT:    [[PTR:%.*]] = getelementptr i8, <2 x ptr> [[P:%.*]], <2 x i64> [[OFF:%.*]]
1553; CHECK-NEXT:    ret <2 x ptr> [[PTR]]
1554;
1555  %index = sdiv exact <2 x i64> %off, <i64 7, i64 7>
1556  %ptr = getelementptr %struct.C, <2 x ptr> %p, <2 x i64> %index
1557  ret <2 x ptr> %ptr
1558}
1559
1560define ptr @gep_sdiv_inbounds(ptr %p, i64 %off) {
1561; CHECK-LABEL: @gep_sdiv_inbounds(
1562; CHECK-NEXT:    [[PTR:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 [[OFF:%.*]]
1563; CHECK-NEXT:    ret ptr [[PTR]]
1564;
1565  %index = sdiv exact i64 %off, 7
1566  %ptr = getelementptr inbounds %struct.C, ptr %p, i64 %index
1567  ret ptr %ptr
1568}
1569
1570define ptr @gep_sdiv_nuw(ptr %p, i64 %off) {
1571; CHECK-LABEL: @gep_sdiv_nuw(
1572; CHECK-NEXT:    [[PTR:%.*]] = getelementptr nuw i8, ptr [[P:%.*]], i64 [[OFF:%.*]]
1573; CHECK-NEXT:    ret ptr [[PTR]]
1574;
1575  %index = sdiv exact i64 %off, 7
1576  %ptr = getelementptr nuw %struct.C, ptr %p, i64 %index
1577  ret ptr %ptr
1578}
1579
1580define ptr @gep_ashr(ptr %p, i64 %off) {
1581; CHECK-LABEL: @gep_ashr(
1582; CHECK-NEXT:    [[PTR:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[OFF:%.*]]
1583; CHECK-NEXT:    ret ptr [[PTR]]
1584;
1585  %index = ashr exact i64 %off, 2
1586  %ptr = getelementptr i32, ptr %p, i64 %index
1587  ret ptr %ptr
1588}
1589
1590define ptr @gep_lshr(ptr %p, i64 %off) {
1591; CHECK-LABEL: @gep_lshr(
1592; CHECK-NEXT:    [[PTR:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[OFF:%.*]]
1593; CHECK-NEXT:    ret ptr [[PTR]]
1594;
1595  %index = lshr exact i64 %off, 2
1596  %ptr = getelementptr i32, ptr %p, i64 %index
1597  ret ptr %ptr
1598}
1599
1600; Negative tests
1601
1602define ptr @gep_i8(ptr %p, i64 %off) {
1603; CHECK-LABEL: @gep_i8(
1604; CHECK-NEXT:    [[PTR:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[OFF:%.*]]
1605; CHECK-NEXT:    ret ptr [[PTR]]
1606;
1607  %ptr = getelementptr i8, ptr %p, i64 %off
1608  ret ptr %ptr
1609}
1610
1611define ptr @gep_sdiv_mismatched_size(ptr %p, i64 %off) {
1612; CHECK-LABEL: @gep_sdiv_mismatched_size(
1613; CHECK-NEXT:    [[INDEX:%.*]] = sdiv exact i64 [[OFF:%.*]], 20
1614; CHECK-NEXT:    [[PTR:%.*]] = getelementptr [[STRUCT_C:%.*]], ptr [[P:%.*]], i64 [[INDEX]]
1615; CHECK-NEXT:    ret ptr [[PTR]]
1616;
1617  %index = sdiv exact i64 %off, 20
1618  %ptr = getelementptr %struct.C, ptr %p, i64 %index
1619  ret ptr %ptr
1620}
1621
1622define ptr @gep_udiv_mismatched_size(ptr %p, i64 %off) {
1623; CHECK-LABEL: @gep_udiv_mismatched_size(
1624; CHECK-NEXT:    [[INDEX:%.*]] = udiv exact i64 [[OFF:%.*]], 20
1625; CHECK-NEXT:    [[PTR:%.*]] = getelementptr [[STRUCT_C:%.*]], ptr [[P:%.*]], i64 [[INDEX]]
1626; CHECK-NEXT:    ret ptr [[PTR]]
1627;
1628  %index = udiv exact i64 %off, 20
1629  %ptr = getelementptr %struct.C, ptr %p, i64 %index
1630  ret ptr %ptr
1631}
1632
1633define ptr @gep_sdiv_without_exact(ptr %p, i64 %off) {
1634; CHECK-LABEL: @gep_sdiv_without_exact(
1635; CHECK-NEXT:    [[INDEX:%.*]] = sdiv i64 [[OFF:%.*]], 7
1636; CHECK-NEXT:    [[PTR:%.*]] = getelementptr [[STRUCT_C:%.*]], ptr [[P:%.*]], i64 [[INDEX]]
1637; CHECK-NEXT:    ret ptr [[PTR]]
1638;
1639  %index = sdiv i64 %off, 7
1640  %ptr = getelementptr %struct.C, ptr %p, i64 %index
1641  ret ptr %ptr
1642}
1643
1644define ptr @gep_udiv_without_exact(ptr %p, i64 %off) {
1645; CHECK-LABEL: @gep_udiv_without_exact(
1646; CHECK-NEXT:    [[INDEX:%.*]] = udiv i64 [[OFF:%.*]], 7
1647; CHECK-NEXT:    [[PTR:%.*]] = getelementptr [[STRUCT_C:%.*]], ptr [[P:%.*]], i64 [[INDEX]]
1648; CHECK-NEXT:    ret ptr [[PTR]]
1649;
1650  %index = udiv i64 %off, 7
1651  %ptr = getelementptr %struct.C, ptr %p, i64 %index
1652  ret ptr %ptr
1653}
1654
1655define ptr @gep_ashr_without_exact(ptr %p, i64 %off) {
1656; CHECK-LABEL: @gep_ashr_without_exact(
1657; CHECK-NEXT:    [[INDEX:%.*]] = ashr i64 [[OFF:%.*]], 2
1658; CHECK-NEXT:    [[PTR:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[INDEX]]
1659; CHECK-NEXT:    ret ptr [[PTR]]
1660;
1661  %index = ashr i64 %off, 2
1662  %ptr = getelementptr i32, ptr %p, i64 %index
1663  ret ptr %ptr
1664}
1665
1666define ptr @gep_lshr_without_exact(ptr %p, i64 %off) {
1667; CHECK-LABEL: @gep_lshr_without_exact(
1668; CHECK-NEXT:    [[INDEX:%.*]] = lshr i64 [[OFF:%.*]], 2
1669; CHECK-NEXT:    [[PTR:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[INDEX]]
1670; CHECK-NEXT:    ret ptr [[PTR]]
1671;
1672  %index = lshr i64 %off, 2
1673  %ptr = getelementptr i32, ptr %p, i64 %index
1674  ret ptr %ptr
1675}
1676
1677define i1 @test_only_used_by_icmp(ptr %a, ptr %b, ptr %c) {
1678; CHECK-LABEL: @test_only_used_by_icmp(
1679; CHECK-NEXT:    [[CMP:%.*]] = icmp eq ptr [[B:%.*]], [[C:%.*]]
1680; CHECK-NEXT:    ret i1 [[CMP]]
1681;
1682  %pa = ptrtoint ptr %a to i64
1683  %pb = ptrtoint ptr %b to i64
1684  %sub = sub i64 %pb, %pa
1685  %gep = getelementptr i8, ptr %a, i64 %sub
1686  %cmp = icmp eq ptr %gep, %c
1687  ret i1 %cmp
1688}
1689
1690define i64 @test_only_used_by_ptrtoint(ptr %a, ptr %b) {
1691; CHECK-LABEL: @test_only_used_by_ptrtoint(
1692; CHECK-NEXT:    [[VAL:%.*]] = ptrtoint ptr [[B:%.*]] to i64
1693; CHECK-NEXT:    ret i64 [[VAL]]
1694;
1695  %pa = ptrtoint ptr %a to i64
1696  %pb = ptrtoint ptr %b to i64
1697  %sub = sub i64 %pb, %pa
1698  %gep = getelementptr i8, ptr %a, i64 %sub
1699  %val = ptrtoint ptr %gep to i64
1700  ret i64 %val
1701}
1702
1703define i64 @test_used_by_both(ptr %a, ptr %b, ptr %c) {
1704; CHECK-LABEL: @test_used_by_both(
1705; CHECK-NEXT:    [[CMP:%.*]] = icmp eq ptr [[B:%.*]], [[C:%.*]]
1706; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
1707; CHECK:       if.then:
1708; CHECK-NEXT:    [[VAL:%.*]] = ptrtoint ptr [[B]] to i64
1709; CHECK-NEXT:    ret i64 [[VAL]]
1710; CHECK:       if.else:
1711; CHECK-NEXT:    ret i64 0
1712;
1713  %pa = ptrtoint ptr %a to i64
1714  %pb = ptrtoint ptr %b to i64
1715  %sub = sub i64 %pb, %pa
1716  %gep = getelementptr i8, ptr %a, i64 %sub
1717  %cmp = icmp eq ptr %gep, %c
1718  br i1 %cmp, label %if.then, label %if.else
1719if.then:
1720  %val = ptrtoint ptr %gep to i64
1721  ret i64 %val
1722if.else:
1723  ret i64 0
1724}
1725
1726; Negative tests
1727
1728define i64 @test_used_by_both_invalid(ptr %a, ptr %b, ptr %c) {
1729; CHECK-LABEL: @test_used_by_both_invalid(
1730; CHECK-NEXT:    [[CMP:%.*]] = icmp eq ptr [[B:%.*]], [[C:%.*]]
1731; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
1732; CHECK:       if.then:
1733; CHECK-NEXT:    [[PB:%.*]] = ptrtoint ptr [[B]] to i64
1734; CHECK-NEXT:    [[PA:%.*]] = ptrtoint ptr [[A:%.*]] to i64
1735; CHECK-NEXT:    [[SUB:%.*]] = sub i64 [[PB]], [[PA]]
1736; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i8, ptr [[A]], i64 [[SUB]]
1737; CHECK-NEXT:    [[VAL:%.*]] = load i64, ptr [[GEP]], align 8
1738; CHECK-NEXT:    ret i64 [[VAL]]
1739; CHECK:       if.else:
1740; CHECK-NEXT:    ret i64 0
1741;
1742  %pa = ptrtoint ptr %a to i64
1743  %pb = ptrtoint ptr %b to i64
1744  %sub = sub i64 %pb, %pa
1745  %gep = getelementptr i8, ptr %a, i64 %sub
1746  %cmp = icmp eq ptr %gep, %c
1747  br i1 %cmp, label %if.then, label %if.else
1748if.then:
1749  %val = load i64, ptr %gep, align 8
1750  ret i64 %val
1751if.else:
1752  ret i64 0
1753}
1754
1755
1756@g = external global i8
1757
1758define ptr @constexpr_gep_of_gep_with_narrow_type() {
1759; CHECK-LABEL: @constexpr_gep_of_gep_with_narrow_type(
1760; CHECK-NEXT:    ret ptr getelementptr (i8, ptr @g, i64 254)
1761;
1762  ret ptr getelementptr (i8, ptr getelementptr (i8, ptr @g, i8 127), i8 127)
1763}
1764
1765define ptr @gep_to_i8_nusw_nuw(ptr %p) {
1766; CHECK-LABEL: @gep_to_i8_nusw_nuw(
1767; CHECK-NEXT:    [[GEP:%.*]] = getelementptr nusw nuw i8, ptr [[P:%.*]], i64 4
1768; CHECK-NEXT:    ret ptr [[GEP]]
1769;
1770  %gep = getelementptr nusw nuw i32, ptr %p, i64 1
1771  ret ptr %gep
1772}
1773
1774define ptr @gep_sel_const(i1 %c) {
1775; CHECK-LABEL: @gep_sel_const(
1776; CHECK-NEXT:    [[GEP:%.*]] = select i1 [[C:%.*]], ptr getelementptr (i8, ptr @A, i64 5), ptr getelementptr (i8, ptr @B, i64 5)
1777; CHECK-NEXT:    ret ptr [[GEP]]
1778;
1779  %sel = select i1 %c, ptr @A, ptr @B
1780  %gep = getelementptr i8, ptr %sel, i64 5
1781  ret ptr %gep
1782}
1783
1784define ptr @gep_sel_const_nuw(i1 %c) {
1785; CHECK-LABEL: @gep_sel_const_nuw(
1786; CHECK-NEXT:    [[GEP:%.*]] = select i1 [[C:%.*]], ptr getelementptr nuw (i8, ptr @A, i64 5), ptr getelementptr nuw (i8, ptr @B, i64 5)
1787; CHECK-NEXT:    ret ptr [[GEP]]
1788;
1789  %sel = select i1 %c, ptr @A, ptr @B
1790  %gep = getelementptr nuw i8, ptr %sel, i64 5
1791  ret ptr %gep
1792}
1793
1794define ptr @gep_of_udiv(ptr %p, i64 %x) {
1795; CHECK-LABEL: @gep_of_udiv(
1796; CHECK-NEXT:    [[TMP1:%.*]] = udiv exact i64 [[X:%.*]], 3
1797; CHECK-NEXT:    [[R:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[TMP1]]
1798; CHECK-NEXT:    ret ptr [[R]]
1799;
1800  %idx = udiv exact i64 %x, 12
1801  %r = getelementptr i32, ptr %p, i64 %idx
1802  ret ptr %r
1803}
1804
1805define ptr @gep_of_udiv_fail_not_divisible(ptr %p, i64 %x) {
1806; CHECK-LABEL: @gep_of_udiv_fail_not_divisible(
1807; CHECK-NEXT:    [[IDX:%.*]] = udiv exact i64 [[X:%.*]], 13
1808; CHECK-NEXT:    [[R:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[IDX]]
1809; CHECK-NEXT:    ret ptr [[R]]
1810;
1811  %idx = udiv exact i64 %x, 13
1812  %r = getelementptr i32, ptr %p, i64 %idx
1813  ret ptr %r
1814}
1815
1816
1817define ptr @gep_of_sdiv(ptr %p, i64 %x) {
1818; CHECK-LABEL: @gep_of_sdiv(
1819; CHECK-NEXT:    [[TMP1:%.*]] = sdiv exact i64 [[X:%.*]], -9
1820; CHECK-NEXT:    [[R:%.*]] = getelementptr nusw nuw i8, ptr [[P:%.*]], i64 [[TMP1]]
1821; CHECK-NEXT:    ret ptr [[R]]
1822;
1823  %idx = sdiv exact i64 %x, -36
1824  %r = getelementptr nusw nuw i32, ptr %p, i64 %idx
1825  ret ptr %r
1826}
1827
1828
1829define ptr @gep_of_sdiv_fail_not_divisible(ptr %p, i64 %x) {
1830; CHECK-LABEL: @gep_of_sdiv_fail_not_divisible(
1831; CHECK-NEXT:    [[IDX:%.*]] = sdiv exact i64 [[X:%.*]], -35
1832; CHECK-NEXT:    [[R:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[IDX]]
1833; CHECK-NEXT:    ret ptr [[R]]
1834;
1835  %idx = sdiv exact i64 %x, -35
1836  %r = getelementptr i32, ptr %p, i64 %idx
1837  ret ptr %r
1838}
1839
1840define ptr @gep_of_sdiv_fail_ub(ptr %p, i64 %x) {
1841; CHECK-LABEL: @gep_of_sdiv_fail_ub(
1842; CHECK-NEXT:    [[IDX:%.*]] = sdiv i64 [[X:%.*]], -4
1843; CHECK-NEXT:    [[R:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[IDX]]
1844; CHECK-NEXT:    ret ptr [[R]]
1845;
1846  %idx = sdiv i64 %x, -4
1847  %r = getelementptr i32, ptr %p, i64 %idx
1848  ret ptr %r
1849}
1850
1851define ptr @gep_of_lshr(ptr %p, i64 %x) {
1852; CHECK-LABEL: @gep_of_lshr(
1853; CHECK-NEXT:    [[TMP1:%.*]] = lshr exact i64 [[X:%.*]], 1
1854; CHECK-NEXT:    [[R:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[TMP1]]
1855; CHECK-NEXT:    ret ptr [[R]]
1856;
1857  %idx = lshr exact i64 %x, 3
1858  %r = getelementptr i32, ptr %p, i64 %idx
1859  ret ptr %r
1860}
1861
1862define ptr @gep_of_ashr(ptr %p, i64 %x) {
1863; CHECK-LABEL: @gep_of_ashr(
1864; CHECK-NEXT:    [[TMP1:%.*]] = ashr exact i64 [[X:%.*]], 1
1865; CHECK-NEXT:    [[R:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 [[TMP1]]
1866; CHECK-NEXT:    ret ptr [[R]]
1867;
1868  %idx = ashr exact i64 %x, 3
1869  %r = getelementptr inbounds i32, ptr %p, i64 %idx
1870  ret ptr %r
1871}
1872
1873define ptr @gep_of_ashr_fail_multiuse(ptr %p, i64 %x) {
1874; CHECK-LABEL: @gep_of_ashr_fail_multiuse(
1875; CHECK-NEXT:    [[IDX:%.*]] = ashr exact i64 [[X:%.*]], 3
1876; CHECK-NEXT:    call void @use.i64(i64 [[IDX]])
1877; CHECK-NEXT:    [[R:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 [[IDX]]
1878; CHECK-NEXT:    ret ptr [[R]]
1879;
1880  %idx = ashr exact i64 %x, 3
1881  call void @use.i64(i64 %idx)
1882  %r = getelementptr inbounds i32, ptr %p, i64 %idx
1883  ret ptr %r
1884}
1885
1886define ptr @gep_of_lshr_fail_missing_exact(ptr %p, i64 %x) {
1887; CHECK-LABEL: @gep_of_lshr_fail_missing_exact(
1888; CHECK-NEXT:    [[IDX:%.*]] = lshr i64 [[X:%.*]], 3
1889; CHECK-NEXT:    [[R:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[IDX]]
1890; CHECK-NEXT:    ret ptr [[R]]
1891;
1892  %idx = lshr i64 %x, 3
1893  %r = getelementptr i32, ptr %p, i64 %idx
1894  ret ptr %r
1895}
1896
1897define ptr @gep_of_ashr_fail_not_divisible(ptr %p, i64 %x) {
1898; CHECK-LABEL: @gep_of_ashr_fail_not_divisible(
1899; CHECK-NEXT:    [[IDX:%.*]] = ashr exact i64 [[X:%.*]], 1
1900; CHECK-NEXT:    [[R:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[IDX]]
1901; CHECK-NEXT:    ret ptr [[R]]
1902;
1903  %idx = ashr exact i64 %x, 1
1904  %r = getelementptr i32, ptr %p, i64 %idx
1905  ret ptr %r
1906}
1907
1908define ptr @gep_merge_not_nuw(ptr %p, i64 %idx) {
1909; CHECK-LABEL: @gep_merge_not_nuw(
1910; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 -1
1911; CHECK-NEXT:    ret ptr [[GEP]]
1912;
1913  %idx.neg = sub i64 0, %idx
1914  %add = add i64 %idx, -1
1915  %gep1 = getelementptr inbounds i8, ptr %p, i64 %idx.neg
1916  %gep = getelementptr inbounds nuw i8, ptr %gep1, i64 %add
1917  ret ptr %gep
1918}
1919
1920define ptr @gep_merge_nuw(ptr %p, i64 %x, i64 %y) {
1921; CHECK-LABEL: @gep_merge_nuw(
1922; CHECK-NEXT:    [[GEP:%.*]] = getelementptr nuw i8, ptr [[P:%.*]], i64 [[Y:%.*]]
1923; CHECK-NEXT:    ret ptr [[GEP]]
1924;
1925  %sub = sub i64 %y, %x
1926  %gep1 = getelementptr nuw i8, ptr %p, i64 %x
1927  %gep = getelementptr nuw i8, ptr %gep1, i64 %sub
1928  ret ptr %gep
1929}
1930
1931define ptr @gep_merge_nuw_only_one1(ptr %p, i64 %x, i64 %y) {
1932; CHECK-LABEL: @gep_merge_nuw_only_one1(
1933; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[Y:%.*]]
1934; CHECK-NEXT:    ret ptr [[GEP]]
1935;
1936  %sub = sub i64 %y, %x
1937  %gep1 = getelementptr i8, ptr %p, i64 %x
1938  %gep = getelementptr nuw i8, ptr %gep1, i64 %sub
1939  ret ptr %gep
1940}
1941
1942define ptr @gep_merge_nuw_only_one2(ptr %p, i64 %x, i64 %y) {
1943; CHECK-LABEL: @gep_merge_nuw_only_one2(
1944; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[Y:%.*]]
1945; CHECK-NEXT:    ret ptr [[GEP]]
1946;
1947  %sub = sub i64 %y, %x
1948  %gep1 = getelementptr nuw i8, ptr %p, i64 %x
1949  %gep = getelementptr i8, ptr %gep1, i64 %sub
1950  ret ptr %gep
1951}
1952
1953; Cannot preserve nusw, unless we know that the addition x + (y-x)
1954; does not overflow.
1955define ptr @gep_merge_nusw(ptr %p, i64 %x, i64 %y) {
1956; CHECK-LABEL: @gep_merge_nusw(
1957; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[Y:%.*]]
1958; CHECK-NEXT:    ret ptr [[GEP]]
1959;
1960  %sub = sub i64 %y, %x
1961  %gep1 = getelementptr nusw i8, ptr %p, i64 %x
1962  %gep = getelementptr nusw i8, ptr %gep1, i64 %sub
1963  ret ptr %gep
1964}
1965
1966define ptr @gep_merge_nuw_add_zero(ptr %p, i64 %idx, i64 %idx2) {
1967; CHECK-LABEL: @gep_merge_nuw_add_zero(
1968; CHECK-NEXT:    [[GEP:%.*]] = getelementptr nuw [2 x i32], ptr [[P:%.*]], i64 [[IDX:%.*]], i64 [[IDX2:%.*]]
1969; CHECK-NEXT:    ret ptr [[GEP]]
1970;
1971  %gep1 = getelementptr nuw [2 x i32], ptr %p, i64 %idx
1972  %gep = getelementptr nuw [2 x i32], ptr %gep1, i64 0, i64 %idx2
1973  ret ptr %gep
1974}
1975
1976; Cannot preserve nusw, even if the merge only involves an add with a zero
1977; index. This is because the whole offset calculation is required to be nsw
1978; after the merge.
1979define ptr @gep_merge_nusw_add_zero(ptr %p, i64 %idx, i64 %idx2) {
1980; CHECK-LABEL: @gep_merge_nusw_add_zero(
1981; CHECK-NEXT:    [[GEP:%.*]] = getelementptr [2 x i32], ptr [[P:%.*]], i64 [[IDX:%.*]], i64 [[IDX2:%.*]]
1982; CHECK-NEXT:    ret ptr [[GEP]]
1983;
1984  %gep1 = getelementptr nusw [2 x i32], ptr %p, i64 %idx
1985  %gep = getelementptr nusw [2 x i32], ptr %gep1, i64 0, i64 %idx2
1986  ret ptr %gep
1987}
1988
1989define ptr @gep_merge_nuw_const(ptr %p, i64 %idx, i64 %idx2) {
1990; CHECK-LABEL: @gep_merge_nuw_const(
1991; CHECK-NEXT:    [[GEP:%.*]] = getelementptr nuw [2 x i32], ptr [[P:%.*]], i64 [[IDX:%.*]], i64 1
1992; CHECK-NEXT:    ret ptr [[GEP]]
1993;
1994  %gep1 = getelementptr nuw [2 x i32], ptr %p, i64 %idx
1995  %gep = getelementptr nuw i8, ptr %gep1, i64 4
1996  ret ptr %gep
1997}
1998
1999define ptr @gep_merge_nuw_const_neg(ptr %p, i64 %idx, i64 %idx2) {
2000; CHECK-LABEL: @gep_merge_nuw_const_neg(
2001; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr nuw [2 x i32], ptr [[P:%.*]], i64 [[IDX:%.*]]
2002; CHECK-NEXT:    [[GEP:%.*]] = getelementptr nuw i8, ptr [[GEP1]], i64 -4
2003; CHECK-NEXT:    ret ptr [[GEP]]
2004;
2005  %gep1 = getelementptr nuw [2 x i32], ptr %p, i64 %idx
2006  %gep = getelementptr nuw i8, ptr %gep1, i64 -4
2007  ret ptr %gep
2008}
2009
2010; Cannot preserve nusw, because we don't know that the new offset calculation
2011; does not overflow.
2012define ptr @gep_merge_nusw_const(ptr %p, i64 %idx, i64 %idx2) {
2013; CHECK-LABEL: @gep_merge_nusw_const(
2014; CHECK-NEXT:    [[GEP:%.*]] = getelementptr [2 x i32], ptr [[P:%.*]], i64 [[IDX:%.*]], i64 1
2015; CHECK-NEXT:    ret ptr [[GEP]]
2016;
2017  %gep1 = getelementptr nusw [2 x i32], ptr %p, i64 %idx
2018  %gep = getelementptr nusw i8, ptr %gep1, i64 4
2019  ret ptr %gep
2020}
2021
2022
2023!0 = !{!"branch_weights", i32 2, i32 10}
2024