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]* @G16, i32 0, i32 %X
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]* @G16, i32 0, i32 %X
40 %R = icmp eq i16 %Q, 0
42 ; NODL-LABEL: @test1_noinbounds(
43 ; NODL-NEXT: %P = getelementptr [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]* @G16, i64 0, i64 %X
53 %R = icmp eq i16 %Q, 0
55 ; NODL-LABEL: @test1_noinbounds_i64(
56 ; NODL-NEXT: %P = getelementptr [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] addrspace(1)* @G16_as1, i16 0, i32 %x
65 %q = load 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]* @G16, i32 0, i32 %X
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]* @GD, i32 0, i32 %X
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]* @G16, i32 0, i32 %X
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]* @G16, i32 0, i16 %X
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]* @G16, i32 0, i32 %X
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]* @GD, i32 0, i32 %X
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]* @GD, i32 0, i32 %X
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]* @G16, i32 0, i32 %X
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 } ]* @GA, i32 0, i32 %X, i32 1
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* @GS, i32 %x, i32 0
232 ; P32-LABEL: @test10_struct(
233 ; P32: getelementptr inbounds %Foo* @GS, i32 %x, i32 0
234 %p = getelementptr inbounds %Foo* @GS, i32 %x, i32 0
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* @GS, i32 %x, i32 0
244 ; P32-LABEL: @test10_struct_noinbounds(
245 ; P32: getelementptr %Foo* @GS, i32 %x, i32 0
246 %p = getelementptr %Foo* @GS, i32 %x, i32 0
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* @GS, i16 %x, i32 0
258 ; P32-LABEL: @test10_struct_i16(
259 ; P32: %1 = sext i16 %x to i32
260 ; P32: getelementptr inbounds %Foo* @GS, i32 %1, i32 0
261 %p = getelementptr inbounds %Foo* @GS, i16 %x, i32 0
263 %r = icmp eq i32 %q, 0
267 ; Test that the GEP indices are converted before we ever get here
269 define i1 @test10_struct_i64(i64 %x){
270 ; NODL-LABEL: @test10_struct_i64(
271 ; NODL: getelementptr inbounds %Foo* @GS, i64 %x, i32 0
273 ; P32-LABEL: @test10_struct_i64(
274 ; P32: %1 = trunc i64 %x to i32
275 ; P32: getelementptr inbounds %Foo* @GS, i32 %1, i32 0
276 %p = getelementptr inbounds %Foo* @GS, i64 %x, i32 0
278 %r = icmp eq i32 %q, 0
282 define i1 @test10_struct_noinbounds_i16(i16 %x) {
283 ; NODL-LABEL: @test10_struct_noinbounds_i16(
284 ; NODL: getelementptr %Foo* @GS, i16 %x, i32 0
286 ; P32-LABEL: @test10_struct_noinbounds_i16(
287 ; P32: %1 = sext i16 %x to i32
288 ; P32: getelementptr %Foo* @GS, i32 %1, i32 0
289 %p = getelementptr %Foo* @GS, i16 %x, i32 0
291 %r = icmp eq i32 %q, 0
295 define i1 @test10_struct_arr(i32 %x) {
296 ; NODL-LABEL: @test10_struct_arr(
297 ; NODL-NEXT: %r = icmp ne i32 %x, 1
298 ; NODL-NEXT: ret i1 %r
300 ; P32-LABEL: @test10_struct_arr(
301 ; P32-NEXT: %r = icmp ne i32 %x, 1
302 ; P32-NEXT: ret i1 %r
303 %p = getelementptr inbounds [4 x %Foo]* @GStructArr, i32 0, i32 %x, i32 2
305 %r = icmp eq i32 %q, 9
309 define i1 @test10_struct_arr_noinbounds(i32 %x) {
310 ; NODL-LABEL: @test10_struct_arr_noinbounds(
311 ; NODL-NEXT %p = getelementptr [4 x %Foo]* @GStructArr, i32 0, i32 %x, i32 2
313 ; P32-LABEL: @test10_struct_arr_noinbounds(
314 ; P32-NEXT %p = getelementptr [4 x %Foo]* @GStructArr, i32 0, i32 %x, i32 2
315 %p = getelementptr [4 x %Foo]* @GStructArr, i32 0, i32 %x, i32 2
317 %r = icmp eq i32 %q, 9
321 define i1 @test10_struct_arr_i16(i16 %x) {
322 ; NODL-LABEL: @test10_struct_arr_i16(
323 ; NODL-NEXT: %r = icmp ne i16 %x, 1
324 ; NODL-NEXT: ret i1 %r
326 ; P32-LABEL: @test10_struct_arr_i16(
327 ; P32-NEXT: %r = icmp ne i16 %x, 1
328 ; P32-NEXT: ret i1 %r
329 %p = getelementptr inbounds [4 x %Foo]* @GStructArr, i16 0, i16 %x, i32 2
331 %r = icmp eq i32 %q, 9
335 define i1 @test10_struct_arr_i64(i64 %x) {
336 ; NODL-LABEL: @test10_struct_arr_i64(
337 ; NODL-NEXT: %r = icmp ne i64 %x, 1
338 ; NODL-NEXT: ret i1 %r
340 ; P32-LABEL: @test10_struct_arr_i64(
341 ; P32-NEXT: trunc i64 %x to i32
342 ; P32-NEXT: %r = icmp ne i32 %1, 1
343 ; P32-NEXT: ret i1 %r
344 %p = getelementptr inbounds [4 x %Foo]* @GStructArr, i64 0, i64 %x, i32 2
346 %r = icmp eq i32 %q, 9
350 define i1 @test10_struct_arr_noinbounds_i16(i16 %x) {
351 ; NODL-LABEL: @test10_struct_arr_noinbounds_i16(
352 ; NODL-NEXT: %p = getelementptr [4 x %Foo]* @GStructArr, i32 0, i16 %x, i32 2
354 ; P32-LABEL: @test10_struct_arr_noinbounds_i16(
355 ; P32-NEXT: %r = icmp ne i16 %x, 1
356 %p = getelementptr [4 x %Foo]* @GStructArr, i32 0, i16 %x, i32 2
358 %r = icmp eq i32 %q, 9
362 define i1 @test10_struct_arr_noinbounds_i64(i64 %x) {
363 ; FIXME: Should be no trunc?
364 ; NODL-LABEL: @test10_struct_arr_noinbounds_i64(
365 ; NODL-NEXT: %p = getelementptr [4 x %Foo]* @GStructArr, i32 0, i64 %x, i32 2
367 ; P32-LABEL: @test10_struct_arr_noinbounds_i64(
368 ; P32: %r = icmp ne i32 %1, 1
369 ; P32-NEXT: ret i1 %r
370 %p = getelementptr [4 x %Foo]* @GStructArr, i32 0, i64 %x, i32 2
372 %r = icmp eq i32 %q, 9