1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -instcombine -S -data-layout="p:32:32:32-p1:16:16:16-n8:16:32:64" < %s | FileCheck %s
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]
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]
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]
13 %Foo = type { i32, i32, i32, i32 }
15 @GS = internal constant %Foo { i32 1, i32 4, i32 9, i32 14 }
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 } ]
23 define i1 @test1(i32 %X) {
24 ; CHECK-LABEL: @test1(
25 ; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[X:%.*]], 9
26 ; CHECK-NEXT: ret i1 [[R]]
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
34 define 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]]
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
46 define 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]]
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
58 define 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]]
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
71 define i1 @test2(i32 %X) {
72 ; CHECK-LABEL: @test2(
73 ; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[X:%.*]], 4
74 ; CHECK-NEXT: ret i1 [[R]]
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
82 define i1 @test3(i32 %X) {
83 ; CHECK-LABEL: @test3(
84 ; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[X:%.*]], 1
85 ; CHECK-NEXT: ret i1 [[R]]
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
94 define 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]]
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
107 define 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]]
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
121 define 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]]
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
134 define 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]]
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
146 define i1 @test7(i32 %X) {
147 ; CHECK-LABEL: @test7(
148 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -1
149 ; CHECK-NEXT: [[R:%.*]] = icmp ugt i32 [[TMP1]], 2
150 ; CHECK-NEXT: ret i1 [[R]]
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
158 define 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]]
164 %P = getelementptr inbounds [10 x i16], [10 x i16]* @G16, i32 0, i32 %X
165 %Q = load i16, i16* %P
167 %S = icmp eq i16 %R, 0
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 }
178 define 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]]
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
190 define i1 @test10_struct(i32 %x) {
191 ; CHECK-LABEL: @test10_struct(
192 ; CHECK-NEXT: ret i1 false
194 %p = getelementptr inbounds %Foo, %Foo* @GS, i32 %x, i32 0
195 %q = load i32, i32* %p
196 %r = icmp eq i32 %q, 9
200 define 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]]
207 %p = getelementptr %Foo, %Foo* @GS, i32 %x, i32 0
208 %q = load i32, i32* %p
209 %r = icmp eq i32 %q, 9
213 ; Test that the GEP indices are converted before we ever get here
215 define i1 @test10_struct_i16(i16 %x){
216 ; CHECK-LABEL: @test10_struct_i16(
217 ; CHECK-NEXT: ret i1 false
219 %p = getelementptr inbounds %Foo, %Foo* @GS, i16 %x, i32 0
220 %q = load i32, i32* %p
221 %r = icmp eq i32 %q, 0
225 ; Test that the GEP indices are converted before we ever get here
227 define i1 @test10_struct_i64(i64 %x){
228 ; CHECK-LABEL: @test10_struct_i64(
229 ; CHECK-NEXT: ret i1 false
231 %p = getelementptr inbounds %Foo, %Foo* @GS, i64 %x, i32 0
232 %q = load i32, i32* %p
233 %r = icmp eq i32 %q, 0
237 define 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]]
245 %p = getelementptr %Foo, %Foo* @GS, i16 %x, i32 0
246 %q = load i32, i32* %p
247 %r = icmp eq i32 %q, 0
251 define 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]]
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
262 define 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]]
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
274 define 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]]
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
285 define i1 @test10_struct_arr_i64(i64 %x) {
286 ; CHECK-LABEL: @test10_struct_arr_i64(
287 ; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[X:%.*]] to i32
288 ; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[TMP1]], 1
289 ; CHECK-NEXT: ret i1 [[R]]
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
297 define 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]]
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
310 define 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]]
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