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