1 ; RUN: opt -instcombine -S < %s | FileCheck -check-prefix=NODL %s
2 ; RUN: opt -instcombine -S -default-data-layout="p:32:32:32-p1:16:16:16-n8:16:32:64" < %s | FileCheck -check-prefix=P32 %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 %P = getelementptr inbounds [10 x i16], [10 x i16]* @G16, i32 0, i32 %X
25 %Q = load i16, i16* %P
26 %R = icmp eq i16 %Q, 0
29 ; NODL-NEXT: %R = icmp eq i32 %X, 9
30 ; NODL-NEXT: ret i1 %R
33 ; P32-NEXT: %R = icmp eq i32 %X, 9
37 define i1 @test1_noinbounds(i32 %X) {
38 %P = getelementptr [10 x i16], [10 x i16]* @G16, i32 0, i32 %X
39 %Q = load i16, i16* %P
40 %R = icmp eq i16 %Q, 0
42 ; NODL-LABEL: @test1_noinbounds(
43 ; NODL-NEXT: %P = getelementptr [10 x i16], [10 x i16]* @G16, i32 0, i32 %X
45 ; P32-LABEL: @test1_noinbounds(
46 ; P32-NEXT: %R = icmp eq i32 %X, 9
50 define i1 @test1_noinbounds_i64(i64 %X) {
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
55 ; NODL-LABEL: @test1_noinbounds_i64(
56 ; NODL-NEXT: %P = getelementptr [10 x i16], [10 x i16]* @G16, i64 0, i64 %X
58 ; P32-LABEL: @test1_noinbounds_i64(
59 ; P32: %R = icmp eq i32 %1, 9
63 define i1 @test1_noinbounds_as1(i32 %x) {
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
69 ; P32-LABEL: @test1_noinbounds_as1(
70 ; P32-NEXT: trunc i32 %x to i16
71 ; P32-NEXT: %r = icmp eq i16 %1, 9
75 define i1 @test2(i32 %X) {
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
81 ; NODL-NEXT: %R = icmp ne i32 %X, 4
82 ; NODL-NEXT: ret i1 %R
85 define i1 @test3(i32 %X) {
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
91 ; NODL-NEXT: %R = icmp eq i32 %X, 1
92 ; NODL-NEXT: ret i1 %R
95 ; P32-NEXT: %R = icmp eq i32 %X, 1
100 define i1 @test4(i32 %X) {
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
105 ; NODL-LABEL: @test4(
106 ; NODL-NEXT: lshr i32 933, %X
107 ; NODL-NEXT: and i32 {{.*}}, 1
108 ; NODL-NEXT: %R = icmp ne i32 {{.*}}, 0
109 ; NODL-NEXT: ret i1 %R
112 ; P32-NEXT: lshr i32 933, %X
113 ; P32-NEXT: and i32 {{.*}}, 1
114 ; P32-NEXT: %R = icmp ne i32 {{.*}}, 0
115 ; P32-NEXT: ret i1 %R
118 define i1 @test4_i16(i16 %X) {
119 %P = getelementptr inbounds [10 x i16], [10 x i16]* @G16, i32 0, i16 %X
120 %Q = load i16, i16* %P
121 %R = icmp sle i16 %Q, 73
124 ; NODL-LABEL: @test4_i16(
125 ; NODL-NEXT: lshr i16 933, %X
126 ; NODL-NEXT: and i16 {{.*}}, 1
127 ; NODL-NEXT: %R = icmp ne i16 {{.*}}, 0
128 ; NODL-NEXT: ret i1 %R
130 ; P32-LABEL: @test4_i16(
131 ; P32-NEXT: sext i16 %X to i32
132 ; P32-NEXT: lshr i32 933, %1
133 ; P32-NEXT: and i32 {{.*}}, 1
134 ; P32-NEXT: %R = icmp ne i32 {{.*}}, 0
135 ; P32-NEXT: ret i1 %R
138 define i1 @test5(i32 %X) {
139 %P = getelementptr inbounds [10 x i16], [10 x i16]* @G16, i32 0, i32 %X
140 %Q = load i16, i16* %P
141 %R = icmp eq i16 %Q, 69
143 ; NODL-LABEL: @test5(
144 ; NODL-NEXT: icmp eq i32 %X, 2
145 ; NODL-NEXT: icmp eq i32 %X, 7
146 ; NODL-NEXT: %R = or i1
147 ; NODL-NEXT: ret i1 %R
150 ; P32-NEXT: icmp eq i32 %X, 2
151 ; P32-NEXT: icmp eq i32 %X, 7
152 ; P32-NEXT: %R = or i1
153 ; P32-NEXT: ret i1 %R
156 define i1 @test6(i32 %X) {
157 %P = getelementptr inbounds [6 x double], [6 x double]* @GD, i32 0, i32 %X
158 %Q = load double, double* %P
159 %R = fcmp ogt double %Q, 0.0
161 ; NODL-LABEL: @test6(
162 ; NODL-NEXT: add i32 %X, -1
163 ; NODL-NEXT: %R = icmp ult i32 {{.*}}, 3
164 ; NODL-NEXT: ret i1 %R
167 ; P32-NEXT: add i32 %X, -1
168 ; P32-NEXT: %R = icmp ult i32 {{.*}}, 3
169 ; P32-NEXT: ret i1 %R
172 define i1 @test7(i32 %X) {
173 %P = getelementptr inbounds [6 x double], [6 x double]* @GD, i32 0, i32 %X
174 %Q = load double, double* %P
175 %R = fcmp olt double %Q, 0.0
177 ; NODL-LABEL: @test7(
178 ; NODL-NEXT: add i32 %X, -1
179 ; NODL-NEXT: %R = icmp ugt i32 {{.*}}, 2
180 ; NODL-NEXT: ret i1 %R
183 ; P32-NEXT: add i32 %X, -1
184 ; P32-NEXT: %R = icmp ugt i32 {{.*}}, 2
185 ; P32-NEXT: ret i1 %R
188 define i1 @test8(i32 %X) {
189 %P = getelementptr inbounds [10 x i16], [10 x i16]* @G16, i32 0, i32 %X
190 %Q = load i16, i16* %P
192 %S = icmp eq i16 %R, 0
194 ; NODL-LABEL: @test8(
195 ; NODL-NEXT: and i32 %X, -2
196 ; NODL-NEXT: icmp eq i32 {{.*}}, 8
200 ; P32-NEXT: and i32 %X, -2
201 ; P32-NEXT: icmp eq i32 {{.*}}, 8
205 @GA = internal constant [4 x { i32, i32 } ] [
206 { i32, i32 } { i32 1, i32 0 },
207 { i32, i32 } { i32 2, i32 1 },
208 { i32, i32 } { i32 3, i32 1 },
209 { i32, i32 } { i32 4, i32 0 }
212 define i1 @test9(i32 %X) {
213 %P = getelementptr inbounds [4 x { i32, i32 } ], [4 x { i32, i32 } ]* @GA, i32 0, i32 %X, i32 1
214 %Q = load i32, i32* %P
215 %R = icmp eq i32 %Q, 1
217 ; NODL-LABEL: @test9(
218 ; NODL-NEXT: add i32 %X, -1
219 ; NODL-NEXT: icmp ult i32 {{.*}}, 2
223 ; P32-NEXT: add i32 %X, -1
224 ; P32-NEXT: icmp ult i32 {{.*}}, 2
228 define i1 @test10_struct(i32 %x) {
229 ; NODL-LABEL: @test10_struct(
230 ; NODL: getelementptr inbounds %Foo, %Foo* @GS, i32 %x, i32 0
232 ; P32-LABEL: @test10_struct(
234 %p = getelementptr inbounds %Foo, %Foo* @GS, i32 %x, i32 0
235 %q = load i32, i32* %p
236 %r = icmp eq i32 %q, 9
240 define i1 @test10_struct_noinbounds(i32 %x) {
241 ; NODL-LABEL: @test10_struct_noinbounds(
242 ; NODL: getelementptr %Foo, %Foo* @GS, i32 %x, i32 0
244 ; P32-LABEL: @test10_struct_noinbounds(
245 ; P32: getelementptr %Foo, %Foo* @GS, i32 %x, i32 0
246 %p = getelementptr %Foo, %Foo* @GS, i32 %x, i32 0
247 %q = load i32, i32* %p
248 %r = icmp eq i32 %q, 9
252 ; Test that the GEP indices are converted before we ever get here
254 define i1 @test10_struct_i16(i16 %x){
255 ; NODL-LABEL: @test10_struct_i16(
256 ; NODL: getelementptr inbounds %Foo, %Foo* @GS, i16 %x, i32 0
258 ; P32-LABEL: @test10_struct_i16(
260 %p = getelementptr inbounds %Foo, %Foo* @GS, i16 %x, i32 0
261 %q = load i32, i32* %p
262 %r = icmp eq i32 %q, 0
266 ; Test that the GEP indices are converted before we ever get here
268 define i1 @test10_struct_i64(i64 %x){
269 ; NODL-LABEL: @test10_struct_i64(
270 ; NODL: getelementptr inbounds %Foo, %Foo* @GS, i64 %x, i32 0
272 ; P32-LABEL: @test10_struct_i64(
274 %p = getelementptr inbounds %Foo, %Foo* @GS, i64 %x, i32 0
275 %q = load i32, i32* %p
276 %r = icmp eq i32 %q, 0
280 define i1 @test10_struct_noinbounds_i16(i16 %x) {
281 ; NODL-LABEL: @test10_struct_noinbounds_i16(
282 ; NODL: getelementptr %Foo, %Foo* @GS, i16 %x, i32 0
284 ; P32-LABEL: @test10_struct_noinbounds_i16(
285 ; P32: %1 = sext i16 %x to i32
286 ; P32: getelementptr %Foo, %Foo* @GS, i32 %1, i32 0
287 %p = getelementptr %Foo, %Foo* @GS, i16 %x, i32 0
288 %q = load i32, i32* %p
289 %r = icmp eq i32 %q, 0
293 define i1 @test10_struct_arr(i32 %x) {
294 ; NODL-LABEL: @test10_struct_arr(
295 ; NODL-NEXT: %r = icmp ne i32 %x, 1
296 ; NODL-NEXT: ret i1 %r
298 ; P32-LABEL: @test10_struct_arr(
299 ; P32-NEXT: %r = icmp ne i32 %x, 1
300 ; P32-NEXT: ret i1 %r
301 %p = getelementptr inbounds [4 x %Foo], [4 x %Foo]* @GStructArr, i32 0, i32 %x, i32 2
302 %q = load i32, i32* %p
303 %r = icmp eq i32 %q, 9
307 define i1 @test10_struct_arr_noinbounds(i32 %x) {
308 ; NODL-LABEL: @test10_struct_arr_noinbounds(
309 ; NODL-NEXT %p = getelementptr [4 x %Foo], [4 x %Foo]* @GStructArr, i32 0, i32 %x, i32 2
311 ; P32-LABEL: @test10_struct_arr_noinbounds(
312 ; P32-NEXT %p = getelementptr [4 x %Foo], [4 x %Foo]* @GStructArr, i32 0, i32 %x, i32 2
313 %p = getelementptr [4 x %Foo], [4 x %Foo]* @GStructArr, i32 0, i32 %x, i32 2
314 %q = load i32, i32* %p
315 %r = icmp eq i32 %q, 9
319 define i1 @test10_struct_arr_i16(i16 %x) {
320 ; NODL-LABEL: @test10_struct_arr_i16(
321 ; NODL-NEXT: %r = icmp ne i16 %x, 1
322 ; NODL-NEXT: ret i1 %r
324 ; P32-LABEL: @test10_struct_arr_i16(
325 ; P32-NEXT: %r = icmp ne i16 %x, 1
326 ; P32-NEXT: ret i1 %r
327 %p = getelementptr inbounds [4 x %Foo], [4 x %Foo]* @GStructArr, i16 0, i16 %x, i32 2
328 %q = load i32, i32* %p
329 %r = icmp eq i32 %q, 9
333 define i1 @test10_struct_arr_i64(i64 %x) {
334 ; NODL-LABEL: @test10_struct_arr_i64(
335 ; NODL-NEXT: %r = icmp ne i64 %x, 1
336 ; NODL-NEXT: ret i1 %r
338 ; P32-LABEL: @test10_struct_arr_i64(
339 ; P32-NEXT: trunc i64 %x to i32
340 ; P32-NEXT: %r = icmp ne i32 %1, 1
341 ; P32-NEXT: ret i1 %r
342 %p = getelementptr inbounds [4 x %Foo], [4 x %Foo]* @GStructArr, i64 0, i64 %x, i32 2
343 %q = load i32, i32* %p
344 %r = icmp eq i32 %q, 9
348 define i1 @test10_struct_arr_noinbounds_i16(i16 %x) {
349 ; NODL-LABEL: @test10_struct_arr_noinbounds_i16(
350 ; NODL-NEXT: %p = getelementptr [4 x %Foo], [4 x %Foo]* @GStructArr, i32 0, i16 %x, i32 2
352 ; P32-LABEL: @test10_struct_arr_noinbounds_i16(
353 ; P32-NEXT: %r = icmp ne i16 %x, 1
354 %p = getelementptr [4 x %Foo], [4 x %Foo]* @GStructArr, i32 0, i16 %x, i32 2
355 %q = load i32, i32* %p
356 %r = icmp eq i32 %q, 9
360 define i1 @test10_struct_arr_noinbounds_i64(i64 %x) {
361 ; FIXME: Should be no trunc?
362 ; NODL-LABEL: @test10_struct_arr_noinbounds_i64(
363 ; NODL-NEXT: %p = getelementptr [4 x %Foo], [4 x %Foo]* @GStructArr, i32 0, i64 %x, i32 2
365 ; P32-LABEL: @test10_struct_arr_noinbounds_i64(
366 ; P32: %r = icmp ne i32 %1, 1
367 ; P32-NEXT: ret i1 %r
368 %p = getelementptr [4 x %Foo], [4 x %Foo]* @GStructArr, i32 0, i64 %x, i32 2
369 %q = load i32, i32* %p
370 %r = icmp eq i32 %q, 9