xref: /llvm-project/llvm/test/Transforms/InstCombine/gepofconstgepi8.ll (revision 74aa1abfaec64e45a402f4601f9c228113fc0bbb)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
2; RUN: opt < %s -S -passes=instcombine | FileCheck %s
3
4declare void @use64(i64)
5declare void @useptr(ptr)
6
7define ptr @test_zero(ptr %base, i64 %a) {
8; CHECK-LABEL: define ptr @test_zero(
9; CHECK-SAME: ptr [[BASE:%.*]], i64 [[A:%.*]]) {
10; CHECK-NEXT:  entry:
11; CHECK-NEXT:    [[P2:%.*]] = getelementptr i32, ptr [[BASE]], i64 [[A]]
12; CHECK-NEXT:    ret ptr [[P2]]
13;
14entry:
15  %p1 = getelementptr i8, ptr %base, i64 -4
16  %index = add i64 %a, 1
17  %p2 = getelementptr i32, ptr %p1, i64 %index
18  ret ptr %p2
19}
20
21define ptr @test_nonzero(ptr %base, i64 %a) {
22; CHECK-LABEL: define ptr @test_nonzero(
23; CHECK-SAME: ptr [[BASE:%.*]], i64 [[A:%.*]]) {
24; CHECK-NEXT:  entry:
25; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr i8, ptr [[BASE]], i64 4
26; CHECK-NEXT:    [[P2:%.*]] = getelementptr i32, ptr [[TMP0]], i64 [[A]]
27; CHECK-NEXT:    ret ptr [[P2]]
28;
29entry:
30  %p1 = getelementptr i8, ptr %base, i64 -4
31  %index = add i64 %a, 2
32  %p2 = getelementptr i32, ptr %p1, i64 %index
33  ret ptr %p2
34}
35
36define ptr @test_or_disjoint(ptr %base, i64 %a) {
37; CHECK-LABEL: define ptr @test_or_disjoint(
38; CHECK-SAME: ptr [[BASE:%.*]], i64 [[A:%.*]]) {
39; CHECK-NEXT:  entry:
40; CHECK-NEXT:    [[P2:%.*]] = getelementptr i32, ptr [[BASE]], i64 [[A]]
41; CHECK-NEXT:    ret ptr [[P2]]
42;
43entry:
44  %p1 = getelementptr i8, ptr %base, i64 -4
45  %index = or disjoint i64 %a, 1
46  %p2 = getelementptr i32, ptr %p1, i64 %index
47  ret ptr %p2
48}
49
50define ptr @test_zero_multiuse_index(ptr %base, i64 %a) {
51; CHECK-LABEL: define ptr @test_zero_multiuse_index(
52; CHECK-SAME: ptr [[BASE:%.*]], i64 [[A:%.*]]) {
53; CHECK-NEXT:  entry:
54; CHECK-NEXT:    [[INDEX:%.*]] = add i64 [[A]], 1
55; CHECK-NEXT:    call void @use64(i64 [[INDEX]])
56; CHECK-NEXT:    [[P2:%.*]] = getelementptr i32, ptr [[BASE]], i64 [[A]]
57; CHECK-NEXT:    ret ptr [[P2]]
58;
59entry:
60  %p1 = getelementptr i8, ptr %base, i64 -4
61  %index = add i64 %a, 1
62  call void @use64(i64 %index)
63  %p2 = getelementptr i32, ptr %p1, i64 %index
64  ret ptr %p2
65}
66
67define ptr @test_zero_multiuse_ptr(ptr %base, i64 %a) {
68; CHECK-LABEL: define ptr @test_zero_multiuse_ptr(
69; CHECK-SAME: ptr [[BASE:%.*]], i64 [[A:%.*]]) {
70; CHECK-NEXT:  entry:
71; CHECK-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[BASE]], i64 -4
72; CHECK-NEXT:    call void @useptr(ptr [[P1]])
73; CHECK-NEXT:    [[P2:%.*]] = getelementptr i32, ptr [[BASE]], i64 [[A]]
74; CHECK-NEXT:    ret ptr [[P2]]
75;
76entry:
77  %p1 = getelementptr i8, ptr %base, i64 -4
78  call void @useptr(ptr %p1)
79  %index = add i64 %a, 1
80  %p2 = getelementptr i32, ptr %p1, i64 %index
81  ret ptr %p2
82}
83
84define ptr @test_zero_sext_add_nsw(ptr %base, i32 %a) {
85; CHECK-LABEL: define ptr @test_zero_sext_add_nsw(
86; CHECK-SAME: ptr [[BASE:%.*]], i32 [[A:%.*]]) {
87; CHECK-NEXT:  entry:
88; CHECK-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[BASE]], i64 -4
89; CHECK-NEXT:    [[TMP0:%.*]] = sext i32 [[A]] to i64
90; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr i32, ptr [[P1]], i64 [[TMP0]]
91; CHECK-NEXT:    [[P2:%.*]] = getelementptr i8, ptr [[TMP1]], i64 4
92; CHECK-NEXT:    ret ptr [[P2]]
93;
94entry:
95  %p1 = getelementptr i8, ptr %base, i64 -4
96  %index = add nsw i32 %a, 1
97  %p2 = getelementptr i32, ptr %p1, i32 %index
98  ret ptr %p2
99}
100
101define ptr @test_zero_trunc_add(ptr %base, i128 %a) {
102; CHECK-LABEL: define ptr @test_zero_trunc_add(
103; CHECK-SAME: ptr [[BASE:%.*]], i128 [[A:%.*]]) {
104; CHECK-NEXT:  entry:
105; CHECK-NEXT:    [[TMP0:%.*]] = trunc i128 [[A]] to i64
106; CHECK-NEXT:    [[P2:%.*]] = getelementptr i32, ptr [[BASE]], i64 [[TMP0]]
107; CHECK-NEXT:    ret ptr [[P2]]
108;
109entry:
110  %p1 = getelementptr i8, ptr %base, i64 -4
111  %index = add i128 %a, 1
112  %p2 = getelementptr i32, ptr %p1, i128 %index
113  ret ptr %p2
114}
115
116define ptr @test_non_i8(ptr %base, i64 %a) {
117; CHECK-LABEL: define ptr @test_non_i8(
118; CHECK-SAME: ptr [[BASE:%.*]], i64 [[A:%.*]]) {
119; CHECK-NEXT:  entry:
120; CHECK-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[BASE]], i64 -4
121; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr i32, ptr [[P1]], i64 [[A]]
122; CHECK-NEXT:    ret ptr [[TMP0]]
123;
124entry:
125  %p1 = getelementptr i16, ptr %base, i64 -4
126  %index = add i64 %a, 1
127  %p2 = getelementptr i32, ptr %p1, i64 %index
128  ret ptr %p2
129}
130
131define ptr @test_non_const(ptr %base, i64 %a, i64 %b) {
132; CHECK-LABEL: define ptr @test_non_const(
133; CHECK-SAME: ptr [[BASE:%.*]], i64 [[A:%.*]], i64 [[B:%.*]]) {
134; CHECK-NEXT:  entry:
135; CHECK-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[BASE]], i64 [[B]]
136; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr i32, ptr [[P1]], i64 [[A]]
137; CHECK-NEXT:    [[P2:%.*]] = getelementptr i8, ptr [[TMP0]], i64 4
138; CHECK-NEXT:    ret ptr [[P2]]
139;
140entry:
141  %p1 = getelementptr i8, ptr %base, i64 %b
142  %index = add i64 %a, 1
143  %p2 = getelementptr i32, ptr %p1, i64 %index
144  ret ptr %p2
145}
146
147define ptr @test_too_many_indices(ptr %base, i64 %a, i64 %b) {
148; CHECK-LABEL: define ptr @test_too_many_indices(
149; CHECK-SAME: ptr [[BASE:%.*]], i64 [[A:%.*]], i64 [[B:%.*]]) {
150; CHECK-NEXT:  entry:
151; CHECK-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[BASE]], i64 [[B]]
152; CHECK-NEXT:    [[INDEX:%.*]] = add i64 [[A]], 1
153; CHECK-NEXT:    [[P2:%.*]] = getelementptr [8 x i32], ptr [[P1]], i64 1, i64 [[INDEX]]
154; CHECK-NEXT:    ret ptr [[P2]]
155;
156entry:
157  %p1 = getelementptr i8, ptr %base, i64 %b
158  %index = add i64 %a, 1
159  %p2 = getelementptr [8 x i32], ptr %p1, i64 1, i64 %index
160  ret ptr %p2
161}
162
163define ptr @test_wrong_op(ptr %base, i64 %a) {
164; CHECK-LABEL: define ptr @test_wrong_op(
165; CHECK-SAME: ptr [[BASE:%.*]], i64 [[A:%.*]]) {
166; CHECK-NEXT:  entry:
167; CHECK-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[BASE]], i64 -4
168; CHECK-NEXT:    [[INDEX:%.*]] = xor i64 [[A]], 1
169; CHECK-NEXT:    [[P2:%.*]] = getelementptr i32, ptr [[P1]], i64 [[INDEX]]
170; CHECK-NEXT:    ret ptr [[P2]]
171;
172entry:
173  %p1 = getelementptr i8, ptr %base, i64 -4
174  %index = xor i64 %a, 1
175  %p2 = getelementptr i32, ptr %p1, i64 %index
176  ret ptr %p2
177}
178
179define ptr @test_sext_add_without_nsw(ptr %base, i32 %a) {
180; CHECK-LABEL: define ptr @test_sext_add_without_nsw(
181; CHECK-SAME: ptr [[BASE:%.*]], i32 [[A:%.*]]) {
182; CHECK-NEXT:  entry:
183; CHECK-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[BASE]], i64 -4
184; CHECK-NEXT:    [[INDEX:%.*]] = add i32 [[A]], 1
185; CHECK-NEXT:    [[TMP0:%.*]] = sext i32 [[INDEX]] to i64
186; CHECK-NEXT:    [[P2:%.*]] = getelementptr i32, ptr [[P1]], i64 [[TMP0]]
187; CHECK-NEXT:    ret ptr [[P2]]
188;
189entry:
190  %p1 = getelementptr i8, ptr %base, i64 -4
191  %index = add i32 %a, 1
192  %p2 = getelementptr i32, ptr %p1, i32 %index
193  ret ptr %p2
194}
195
196define ptr @test_or_without_disjoint(ptr %base, i64 %a) {
197; CHECK-LABEL: define ptr @test_or_without_disjoint(
198; CHECK-SAME: ptr [[BASE:%.*]], i64 [[A:%.*]]) {
199; CHECK-NEXT:  entry:
200; CHECK-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[BASE]], i64 -4
201; CHECK-NEXT:    [[INDEX:%.*]] = or i64 [[A]], 1
202; CHECK-NEXT:    [[P2:%.*]] = getelementptr i32, ptr [[P1]], i64 [[INDEX]]
203; CHECK-NEXT:    ret ptr [[P2]]
204;
205entry:
206  %p1 = getelementptr i8, ptr %base, i64 -4
207  %index = or i64 %a, 1
208  %p2 = getelementptr i32, ptr %p1, i64 %index
209  ret ptr %p2
210}
211
212define ptr @test_smul_overflow(ptr %base, i64 %a) {
213; CHECK-LABEL: define ptr @test_smul_overflow(
214; CHECK-SAME: ptr [[BASE:%.*]], i64 [[A:%.*]]) {
215; CHECK-NEXT:  entry:
216; CHECK-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[BASE]], i64 -12
217; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr i32, ptr [[P1]], i64 [[A]]
218; CHECK-NEXT:    ret ptr [[TMP0]]
219;
220entry:
221  %p1 = getelementptr i8, ptr %base, i64 -4
222  %index = add i64 %a, 9223372036854775806
223  %p2 = getelementptr i32, ptr %p1, i64 %index
224  ret ptr %p2
225}
226
227define ptr @test_sadd_overflow(ptr %base, i64 %a) {
228; CHECK-LABEL: define ptr @test_sadd_overflow(
229; CHECK-SAME: ptr [[BASE:%.*]], i64 [[A:%.*]]) {
230; CHECK-NEXT:  entry:
231; CHECK-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[BASE]], i64 -9223372036854775808
232; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr i32, ptr [[P1]], i64 [[A]]
233; CHECK-NEXT:    ret ptr [[TMP0]]
234;
235entry:
236  %p1 = getelementptr i8, ptr %base, i64 9223372036854775804
237  %index = add i64 %a, 1
238  %p2 = getelementptr i32, ptr %p1, i64 %index
239  ret ptr %p2
240}
241
242define ptr @test_nonzero_multiuse_index(ptr %base, i64 %a) {
243; CHECK-LABEL: define ptr @test_nonzero_multiuse_index(
244; CHECK-SAME: ptr [[BASE:%.*]], i64 [[A:%.*]]) {
245; CHECK-NEXT:  entry:
246; CHECK-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[BASE]], i64 -4
247; CHECK-NEXT:    [[INDEX:%.*]] = add i64 [[A]], 2
248; CHECK-NEXT:    call void @use64(i64 [[INDEX]])
249; CHECK-NEXT:    [[P2:%.*]] = getelementptr i32, ptr [[P1]], i64 [[INDEX]]
250; CHECK-NEXT:    ret ptr [[P2]]
251;
252entry:
253  %p1 = getelementptr i8, ptr %base, i64 -4
254  %index = add i64 %a, 2
255  call void @use64(i64 %index)
256  %p2 = getelementptr i32, ptr %p1, i64 %index
257  ret ptr %p2
258}
259
260define ptr @test_nonzero_multiuse_ptr(ptr %base, i64 %a) {
261; CHECK-LABEL: define ptr @test_nonzero_multiuse_ptr(
262; CHECK-SAME: ptr [[BASE:%.*]], i64 [[A:%.*]]) {
263; CHECK-NEXT:  entry:
264; CHECK-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[BASE]], i64 -4
265; CHECK-NEXT:    call void @useptr(ptr [[P1]])
266; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr i32, ptr [[P1]], i64 [[A]]
267; CHECK-NEXT:    [[P2:%.*]] = getelementptr i8, ptr [[TMP0]], i64 8
268; CHECK-NEXT:    ret ptr [[P2]]
269;
270entry:
271  %p1 = getelementptr i8, ptr %base, i64 -4
272  call void @useptr(ptr %p1)
273  %index = add i64 %a, 2
274  %p2 = getelementptr i32, ptr %p1, i64 %index
275  ret ptr %p2
276}
277
278define ptr @test_scalable(ptr %base, i64 %a) {
279; CHECK-LABEL: define ptr @test_scalable(
280; CHECK-SAME: ptr [[BASE:%.*]], i64 [[A:%.*]]) {
281; CHECK-NEXT:  entry:
282; CHECK-NEXT:    [[P1:%.*]] = getelementptr i8, ptr [[BASE]], i64 -4
283; CHECK-NEXT:    [[INDEX:%.*]] = add i64 [[A]], 1
284; CHECK-NEXT:    [[TMP0:%.*]] = call i64 @llvm.vscale.i64()
285; CHECK-NEXT:    [[TMP1:%.*]] = shl i64 [[TMP0]], 4
286; CHECK-NEXT:    [[P2_IDX:%.*]] = mul i64 [[INDEX]], [[TMP1]]
287; CHECK-NEXT:    [[P2:%.*]] = getelementptr i8, ptr [[P1]], i64 [[P2_IDX]]
288; CHECK-NEXT:    ret ptr [[P2]]
289;
290entry:
291  %p1 = getelementptr i8, ptr %base, i64 -4
292  %index = add i64 %a, 1
293  %p2 = getelementptr <vscale x 4 x i32>, ptr %p1, i64 %index
294  ret ptr %p2
295}
296