1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -instcombine -S -default-data-layout="p:32:32:32-p1:16:16:16-n8:16:32:64" < %s | FileCheck %s
3
4@G16 = internal constant [10 x i16] [i16 35, i16 82, i16 69, i16 81, i16 85,
5                                     i16 73, i16 82, i16 69, i16 68, i16 0]
6
7@G16_as1 = internal addrspace(1) constant [10 x i16] [i16 35, i16 82, i16 69, i16 81, i16 85,
8                                                      i16 73, i16 82, i16 69, i16 68, i16 0]
9
10@GD = internal constant [6 x double]
11   [double -10.0, double 1.0, double 4.0, double 2.0, double -20.0, double -40.0]
12
13%Foo = type { i32, i32, i32, i32 }
14
15@GS = internal constant %Foo { i32 1, i32 4, i32 9, i32 14 }
16
17@GStructArr = internal constant [4 x %Foo] [ %Foo { i32 1, i32 4, i32 9, i32 14 },
18                                             %Foo { i32 5, i32 4, i32 6, i32 11 },
19                                             %Foo { i32 6, i32 5, i32 9, i32 20 },
20                                             %Foo { i32 12, i32 3, i32 9, i32 8 } ]
21
22
23define i1 @test1(i32 %X) {
24; CHECK-LABEL: @test1(
25; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 %X, 9
26; CHECK-NEXT:    ret i1 [[R]]
27;
28  %P = getelementptr inbounds [10 x i16], [10 x i16]* @G16, i32 0, i32 %X
29  %Q = load i16, i16* %P
30  %R = icmp eq i16 %Q, 0
31  ret i1 %R
32}
33
34define i1 @test1_noinbounds(i32 %X) {
35; CHECK-LABEL: @test1_noinbounds(
36; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 %X, 9
37; CHECK-NEXT:    ret i1 [[R]]
38;
39  %P = getelementptr [10 x i16], [10 x i16]* @G16, i32 0, i32 %X
40  %Q = load i16, i16* %P
41  %R = icmp eq i16 %Q, 0
42  ret i1 %R
43}
44
45define i1 @test1_noinbounds_i64(i64 %X) {
46; CHECK-LABEL: @test1_noinbounds_i64(
47; CHECK-NEXT:    [[TMP1:%.*]] = trunc i64 %X to i32
48; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[TMP1]], 9
49; CHECK-NEXT:    ret i1 [[R]]
50;
51  %P = getelementptr [10 x i16], [10 x i16]* @G16, i64 0, i64 %X
52  %Q = load i16, i16* %P
53  %R = icmp eq i16 %Q, 0
54  ret i1 %R
55}
56
57define i1 @test1_noinbounds_as1(i32 %x) {
58; CHECK-LABEL: @test1_noinbounds_as1(
59; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 %x to i16
60; CHECK-NEXT:    [[R:%.*]] = icmp eq i16 [[TMP1]], 9
61; CHECK-NEXT:    ret i1 [[R]]
62;
63  %p = getelementptr [10 x i16], [10 x i16] addrspace(1)* @G16_as1, i16 0, i32 %x
64  %q = load i16, i16 addrspace(1)* %p
65  %r = icmp eq i16 %q, 0
66  ret i1 %r
67
68}
69
70define i1 @test2(i32 %X) {
71; CHECK-LABEL: @test2(
72; CHECK-NEXT:    [[R:%.*]] = icmp ne i32 %X, 4
73; CHECK-NEXT:    ret i1 [[R]]
74;
75  %P = getelementptr inbounds [10 x i16], [10 x i16]* @G16, i32 0, i32 %X
76  %Q = load i16, i16* %P
77  %R = icmp slt i16 %Q, 85
78  ret i1 %R
79}
80
81define i1 @test3(i32 %X) {
82; CHECK-LABEL: @test3(
83; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 %X, 1
84; CHECK-NEXT:    ret i1 [[R]]
85;
86  %P = getelementptr inbounds [6 x double], [6 x double]* @GD, i32 0, i32 %X
87  %Q = load double, double* %P
88  %R = fcmp oeq double %Q, 1.0
89  ret i1 %R
90
91}
92
93define i1 @test4(i32 %X) {
94; CHECK-LABEL: @test4(
95; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 933, %X
96; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], 1
97; CHECK-NEXT:    [[R:%.*]] = icmp ne i32 [[TMP2]], 0
98; CHECK-NEXT:    ret i1 [[R]]
99;
100  %P = getelementptr inbounds [10 x i16], [10 x i16]* @G16, i32 0, i32 %X
101  %Q = load i16, i16* %P
102  %R = icmp sle i16 %Q, 73
103  ret i1 %R
104}
105
106define i1 @test4_i16(i16 %X) {
107; CHECK-LABEL: @test4_i16(
108; CHECK-NEXT:    [[TMP1:%.*]] = sext i16 %X to i32
109; CHECK-NEXT:    [[TMP2:%.*]] = lshr i32 933, [[TMP1]]
110; CHECK-NEXT:    [[TMP3:%.*]] = and i32 [[TMP2]], 1
111; CHECK-NEXT:    [[R:%.*]] = icmp ne i32 [[TMP3]], 0
112; CHECK-NEXT:    ret i1 [[R]]
113;
114  %P = getelementptr inbounds [10 x i16], [10 x i16]* @G16, i32 0, i16 %X
115  %Q = load i16, i16* %P
116  %R = icmp sle i16 %Q, 73
117  ret i1 %R
118}
119
120define i1 @test5(i32 %X) {
121; CHECK-LABEL: @test5(
122; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 %X, 2
123; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 %X, 7
124; CHECK-NEXT:    [[R:%.*]] = or i1 [[TMP1]], [[TMP2]]
125; CHECK-NEXT:    ret i1 [[R]]
126;
127  %P = getelementptr inbounds [10 x i16], [10 x i16]* @G16, i32 0, i32 %X
128  %Q = load i16, i16* %P
129  %R = icmp eq i16 %Q, 69
130  ret i1 %R
131}
132
133define i1 @test6(i32 %X) {
134; CHECK-LABEL: @test6(
135; CHECK-NEXT:    [[TMP1:%.*]] = add i32 %X, -1
136; CHECK-NEXT:    [[R:%.*]] = icmp ult i32 [[TMP1]], 3
137; CHECK-NEXT:    ret i1 [[R]]
138;
139  %P = getelementptr inbounds [6 x double], [6 x double]* @GD, i32 0, i32 %X
140  %Q = load double, double* %P
141  %R = fcmp ogt double %Q, 0.0
142  ret i1 %R
143}
144
145define i1 @test7(i32 %X) {
146; CHECK-LABEL: @test7(
147; CHECK-NEXT:    [[TMP1:%.*]] = add i32 %X, -1
148; CHECK-NEXT:    [[R:%.*]] = icmp ugt i32 [[TMP1]], 2
149; CHECK-NEXT:    ret i1 [[R]]
150;
151  %P = getelementptr inbounds [6 x double], [6 x double]* @GD, i32 0, i32 %X
152  %Q = load double, double* %P
153  %R = fcmp olt double %Q, 0.0
154  ret i1 %R
155}
156
157define i1 @test8(i32 %X) {
158; CHECK-LABEL: @test8(
159; CHECK-NEXT:    [[TMP1:%.*]] = or i32 %X, 1
160; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 9
161; CHECK-NEXT:    ret i1 [[TMP2]]
162;
163  %P = getelementptr inbounds [10 x i16], [10 x i16]* @G16, i32 0, i32 %X
164  %Q = load i16, i16* %P
165  %R = and i16 %Q, 3
166  %S = icmp eq i16 %R, 0
167  ret i1 %S
168}
169
170@GA = internal constant [4 x { i32, i32 } ] [
171  { i32, i32 } { i32 1, i32 0 },
172  { i32, i32 } { i32 2, i32 1 },
173  { i32, i32 } { i32 3, i32 1 },
174  { i32, i32 } { i32 4, i32 0 }
175]
176
177define i1 @test9(i32 %X) {
178; CHECK-LABEL: @test9(
179; CHECK-NEXT:    [[X_OFF:%.*]] = add i32 %X, -1
180; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[X_OFF]], 2
181; CHECK-NEXT:    ret i1 [[TMP1]]
182;
183  %P = getelementptr inbounds [4 x { i32, i32 } ], [4 x { i32, i32 } ]* @GA, i32 0, i32 %X, i32 1
184  %Q = load i32, i32* %P
185  %R = icmp eq i32 %Q, 1
186  ret i1 %R
187}
188
189define i1 @test10_struct(i32 %x) {
190; CHECK-LABEL: @test10_struct(
191; CHECK-NEXT:    ret i1 false
192;
193  %p = getelementptr inbounds %Foo, %Foo* @GS, i32 %x, i32 0
194  %q = load i32, i32* %p
195  %r = icmp eq i32 %q, 9
196  ret i1 %r
197}
198
199define i1 @test10_struct_noinbounds(i32 %x) {
200; CHECK-LABEL: @test10_struct_noinbounds(
201; CHECK-NEXT:    [[P:%.*]] = getelementptr %Foo, %Foo* @GS, i32 %x, i32 0
202; CHECK-NEXT:    [[Q:%.*]] = load i32, i32* [[P]], align 8
203; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[Q]], 9
204; CHECK-NEXT:    ret i1 [[R]]
205;
206  %p = getelementptr %Foo, %Foo* @GS, i32 %x, i32 0
207  %q = load i32, i32* %p
208  %r = icmp eq i32 %q, 9
209  ret i1 %r
210}
211
212; Test that the GEP indices are converted before we ever get here
213; Index < ptr size
214define i1 @test10_struct_i16(i16 %x){
215; CHECK-LABEL: @test10_struct_i16(
216; CHECK-NEXT:    ret i1 false
217;
218  %p = getelementptr inbounds %Foo, %Foo* @GS, i16 %x, i32 0
219  %q = load i32, i32* %p
220  %r = icmp eq i32 %q, 0
221  ret i1 %r
222}
223
224; Test that the GEP indices are converted before we ever get here
225; Index > ptr size
226define i1 @test10_struct_i64(i64 %x){
227; CHECK-LABEL: @test10_struct_i64(
228; CHECK-NEXT:    ret i1 false
229;
230  %p = getelementptr inbounds %Foo, %Foo* @GS, i64 %x, i32 0
231  %q = load i32, i32* %p
232  %r = icmp eq i32 %q, 0
233  ret i1 %r
234}
235
236define i1 @test10_struct_noinbounds_i16(i16 %x) {
237; CHECK-LABEL: @test10_struct_noinbounds_i16(
238; CHECK-NEXT:    [[TMP1:%.*]] = sext i16 %x to i32
239; CHECK-NEXT:    [[P:%.*]] = getelementptr %Foo, %Foo* @GS, i32 [[TMP1]], i32 0
240; CHECK-NEXT:    [[Q:%.*]] = load i32, i32* [[P]], align 8
241; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[Q]], 0
242; CHECK-NEXT:    ret i1 [[R]]
243;
244  %p = getelementptr %Foo, %Foo* @GS, i16 %x, i32 0
245  %q = load i32, i32* %p
246  %r = icmp eq i32 %q, 0
247  ret i1 %r
248}
249
250define i1 @test10_struct_arr(i32 %x) {
251; CHECK-LABEL: @test10_struct_arr(
252; CHECK-NEXT:    [[R:%.*]] = icmp ne i32 %x, 1
253; CHECK-NEXT:    ret i1 [[R]]
254;
255  %p = getelementptr inbounds [4 x %Foo], [4 x %Foo]* @GStructArr, i32 0, i32 %x, i32 2
256  %q = load i32, i32* %p
257  %r = icmp eq i32 %q, 9
258  ret i1 %r
259}
260
261define i1 @test10_struct_arr_noinbounds(i32 %x) {
262; CHECK-LABEL: @test10_struct_arr_noinbounds(
263; CHECK-NEXT:    [[R:%.*]] = icmp ne i32 %x, 1
264; CHECK-NEXT:    ret i1 [[R]]
265;
266  %p = getelementptr [4 x %Foo], [4 x %Foo]* @GStructArr, i32 0, i32 %x, i32 2
267  %q = load i32, i32* %p
268  %r = icmp eq i32 %q, 9
269  ret i1 %r
270}
271
272define i1 @test10_struct_arr_i16(i16 %x) {
273; CHECK-LABEL: @test10_struct_arr_i16(
274; CHECK-NEXT:    [[R:%.*]] = icmp ne i16 %x, 1
275; CHECK-NEXT:    ret i1 [[R]]
276;
277  %p = getelementptr inbounds [4 x %Foo], [4 x %Foo]* @GStructArr, i16 0, i16 %x, i32 2
278  %q = load i32, i32* %p
279  %r = icmp eq i32 %q, 9
280  ret i1 %r
281}
282
283define i1 @test10_struct_arr_i64(i64 %x) {
284; CHECK-LABEL: @test10_struct_arr_i64(
285; CHECK-NEXT:    [[TMP1:%.*]] = trunc i64 %x to i32
286; CHECK-NEXT:    [[R:%.*]] = icmp ne i32 [[TMP1]], 1
287; CHECK-NEXT:    ret i1 [[R]]
288;
289  %p = getelementptr inbounds [4 x %Foo], [4 x %Foo]* @GStructArr, i64 0, i64 %x, i32 2
290  %q = load i32, i32* %p
291  %r = icmp eq i32 %q, 9
292  ret i1 %r
293}
294
295define i1 @test10_struct_arr_noinbounds_i16(i16 %x) {
296; CHECK-LABEL: @test10_struct_arr_noinbounds_i16(
297; CHECK-NEXT:    [[R:%.*]] = icmp ne i16 %x, 1
298; CHECK-NEXT:    ret i1 [[R]]
299;
300  %p = getelementptr [4 x %Foo], [4 x %Foo]* @GStructArr, i32 0, i16 %x, i32 2
301  %q = load i32, i32* %p
302  %r = icmp eq i32 %q, 9
303  ret i1 %r
304}
305
306define i1 @test10_struct_arr_noinbounds_i64(i64 %x) {
307; CHECK-LABEL: @test10_struct_arr_noinbounds_i64(
308; CHECK-NEXT:    [[TMP1:%.*]] = trunc i64 %x to i32
309; CHECK-NEXT:    [[R:%.*]] = icmp ne i32 [[TMP1]], 1
310; CHECK-NEXT:    ret i1 [[R]]
311;
312  %p = getelementptr [4 x %Foo], [4 x %Foo]* @GStructArr, i32 0, i64 %x, i32 2
313  %q = load i32, i32* %p
314  %r = icmp eq i32 %q, 9
315  ret i1 %r
316}
317