1 ; RUN: opt -instcombine -S < %s | FileCheck -check-prefix=NODL %s
2 ; RUN: opt -instcombine -S -default-data-layout="p:32:32:32-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]
6 @GD = internal constant [6 x double]
7 [double -10.0, double 1.0, double 4.0, double 2.0, double -20.0, double -40.0]
9 %Foo = type { i32, i32, i32, i32 }
11 @GS = internal constant %Foo { i32 1, i32 4, i32 9, i32 14 }
13 @GStructArr = internal constant [4 x %Foo] [ %Foo { i32 1, i32 4, i32 9, i32 14 },
14 %Foo { i32 5, i32 4, i32 6, i32 11 },
15 %Foo { i32 6, i32 5, i32 9, i32 20 },
16 %Foo { i32 12, i32 3, i32 9, i32 8 } ]
19 define i1 @test1(i32 %X) {
20 %P = getelementptr inbounds [10 x i16]* @G16, i32 0, i32 %X
22 %R = icmp eq i16 %Q, 0
25 ; NODL-NEXT: %R = icmp eq i32 %X, 9
26 ; NODL-NEXT: ret i1 %R
29 ; P32-NEXT: %R = icmp eq i32 %X, 9
33 define i1 @test1_noinbounds(i32 %X) {
34 %P = getelementptr [10 x i16]* @G16, i32 0, i32 %X
36 %R = icmp eq i16 %Q, 0
38 ; NODL-LABEL: @test1_noinbounds(
39 ; NODL-NEXT: %P = getelementptr [10 x i16]* @G16, i32 0, i32 %X
41 ; P32-LABEL: @test1_noinbounds(
42 ; P32-NEXT: %R = icmp eq i32 %X, 9
46 define i1 @test1_noinbounds_i64(i64 %X) {
47 %P = getelementptr [10 x i16]* @G16, i64 0, i64 %X
49 %R = icmp eq i16 %Q, 0
51 ; NODL-LABEL: @test1_noinbounds_i64(
52 ; NODL-NEXT: %P = getelementptr [10 x i16]* @G16, i64 0, i64 %X
54 ; P32-LABEL: @test1_noinbounds_i64(
55 ; P32: %R = icmp eq i32 %1, 9
59 define i1 @test2(i32 %X) {
60 %P = getelementptr inbounds [10 x i16]* @G16, i32 0, i32 %X
62 %R = icmp slt i16 %Q, 85
65 ; NODL-NEXT: %R = icmp ne i32 %X, 4
66 ; NODL-NEXT: ret i1 %R
69 define i1 @test3(i32 %X) {
70 %P = getelementptr inbounds [6 x double]* @GD, i32 0, i32 %X
72 %R = fcmp oeq double %Q, 1.0
75 ; NODL-NEXT: %R = icmp eq i32 %X, 1
76 ; NODL-NEXT: ret i1 %R
79 ; P32-NEXT: %R = icmp eq i32 %X, 1
84 define i1 @test4(i32 %X) {
85 %P = getelementptr inbounds [10 x i16]* @G16, i32 0, i32 %X
87 %R = icmp sle i16 %Q, 73
90 ; NODL-NEXT: lshr i32 933, %X
91 ; NODL-NEXT: and i32 {{.*}}, 1
92 ; NODL-NEXT: %R = icmp ne i32 {{.*}}, 0
93 ; NODL-NEXT: ret i1 %R
96 ; P32-NEXT: lshr i32 933, %X
97 ; P32-NEXT: and i32 {{.*}}, 1
98 ; P32-NEXT: %R = icmp ne i32 {{.*}}, 0
102 define i1 @test4_i16(i16 %X) {
103 %P = getelementptr inbounds [10 x i16]* @G16, i32 0, i16 %X
105 %R = icmp sle i16 %Q, 73
108 ; NODL-LABEL: @test4_i16(
109 ; NODL-NEXT: lshr i16 933, %X
110 ; NODL-NEXT: and i16 {{.*}}, 1
111 ; NODL-NEXT: %R = icmp ne i16 {{.*}}, 0
112 ; NODL-NEXT: ret i1 %R
114 ; P32-LABEL: @test4_i16(
115 ; P32-NEXT: sext i16 %X to i32
116 ; P32-NEXT: lshr i32 933, %1
117 ; P32-NEXT: and i32 {{.*}}, 1
118 ; P32-NEXT: %R = icmp ne i32 {{.*}}, 0
119 ; P32-NEXT: ret i1 %R
122 define i1 @test5(i32 %X) {
123 %P = getelementptr inbounds [10 x i16]* @G16, i32 0, i32 %X
125 %R = icmp eq i16 %Q, 69
127 ; NODL-LABEL: @test5(
128 ; NODL-NEXT: icmp eq i32 %X, 2
129 ; NODL-NEXT: icmp eq i32 %X, 7
130 ; NODL-NEXT: %R = or i1
131 ; NODL-NEXT: ret i1 %R
134 ; P32-NEXT: icmp eq i32 %X, 2
135 ; P32-NEXT: icmp eq i32 %X, 7
136 ; P32-NEXT: %R = or i1
137 ; P32-NEXT: ret i1 %R
140 define i1 @test6(i32 %X) {
141 %P = getelementptr inbounds [6 x double]* @GD, i32 0, i32 %X
143 %R = fcmp ogt double %Q, 0.0
145 ; NODL-LABEL: @test6(
146 ; NODL-NEXT: add i32 %X, -1
147 ; NODL-NEXT: %R = icmp ult i32 {{.*}}, 3
148 ; NODL-NEXT: ret i1 %R
151 ; P32-NEXT: add i32 %X, -1
152 ; P32-NEXT: %R = icmp ult i32 {{.*}}, 3
153 ; P32-NEXT: ret i1 %R
156 define i1 @test7(i32 %X) {
157 %P = getelementptr inbounds [6 x double]* @GD, i32 0, i32 %X
159 %R = fcmp olt double %Q, 0.0
161 ; NODL-LABEL: @test7(
162 ; NODL-NEXT: add i32 %X, -1
163 ; NODL-NEXT: %R = icmp ugt i32 {{.*}}, 2
164 ; NODL-NEXT: ret i1 %R
167 ; P32-NEXT: add i32 %X, -1
168 ; P32-NEXT: %R = icmp ugt i32 {{.*}}, 2
169 ; P32-NEXT: ret i1 %R
172 define i1 @test8(i32 %X) {
173 %P = getelementptr inbounds [10 x i16]* @G16, i32 0, i32 %X
176 %S = icmp eq i16 %R, 0
178 ; NODL-LABEL: @test8(
179 ; NODL-NEXT: and i32 %X, -2
180 ; NODL-NEXT: icmp eq i32 {{.*}}, 8
184 ; P32-NEXT: and i32 %X, -2
185 ; P32-NEXT: icmp eq i32 {{.*}}, 8
189 @GA = internal constant [4 x { i32, i32 } ] [
190 { i32, i32 } { i32 1, i32 0 },
191 { i32, i32 } { i32 2, i32 1 },
192 { i32, i32 } { i32 3, i32 1 },
193 { i32, i32 } { i32 4, i32 0 }
196 define i1 @test9(i32 %X) {
197 %P = getelementptr inbounds [4 x { i32, i32 } ]* @GA, i32 0, i32 %X, i32 1
199 %R = icmp eq i32 %Q, 1
201 ; NODL-LABEL: @test9(
202 ; NODL-NEXT: add i32 %X, -1
203 ; NODL-NEXT: icmp ult i32 {{.*}}, 2
207 ; P32-NEXT: add i32 %X, -1
208 ; P32-NEXT: icmp ult i32 {{.*}}, 2
212 define i1 @test10_struct(i32 %x) {
213 ; NODL-LABEL: @test10_struct(
214 ; NODL: getelementptr inbounds %Foo* @GS, i32 %x, i32 0
216 ; P32-LABEL: @test10_struct(
217 ; P32: getelementptr inbounds %Foo* @GS, i32 %x, i32 0
218 %p = getelementptr inbounds %Foo* @GS, i32 %x, i32 0
220 %r = icmp eq i32 %q, 9
224 define i1 @test10_struct_noinbounds(i32 %x) {
225 ; NODL-LABEL: @test10_struct_noinbounds(
226 ; NODL: getelementptr %Foo* @GS, i32 %x, i32 0
228 ; P32-LABEL: @test10_struct_noinbounds(
229 ; P32: getelementptr %Foo* @GS, i32 %x, i32 0
230 %p = getelementptr %Foo* @GS, i32 %x, i32 0
232 %r = icmp eq i32 %q, 9
236 ; Test that the GEP indices are converted before we ever get here
238 define i1 @test10_struct_i16(i16 %x){
239 ; NODL-LABEL: @test10_struct_i16(
240 ; NODL: getelementptr inbounds %Foo* @GS, i16 %x, i32 0
242 ; P32-LABEL: @test10_struct_i16(
243 ; P32: %1 = sext i16 %x to i32
244 ; P32: getelementptr inbounds %Foo* @GS, i32 %1, i32 0
245 %p = getelementptr inbounds %Foo* @GS, i16 %x, i32 0
247 %r = icmp eq i32 %q, 0
251 ; Test that the GEP indices are converted before we ever get here
253 define i1 @test10_struct_i64(i64 %x){
254 ; NODL-LABEL: @test10_struct_i64(
255 ; NODL: getelementptr inbounds %Foo* @GS, i64 %x, i32 0
257 ; P32-LABEL: @test10_struct_i64(
258 ; P32: %1 = trunc i64 %x to i32
259 ; P32: getelementptr inbounds %Foo* @GS, i32 %1, i32 0
260 %p = getelementptr inbounds %Foo* @GS, i64 %x, i32 0
262 %r = icmp eq i32 %q, 0
266 define i1 @test10_struct_noinbounds_i16(i16 %x) {
267 ; NODL-LABEL: @test10_struct_noinbounds_i16(
268 ; NODL: getelementptr %Foo* @GS, i16 %x, i32 0
270 ; P32-LABEL: @test10_struct_noinbounds_i16(
271 ; P32: %1 = sext i16 %x to i32
272 ; P32: getelementptr %Foo* @GS, i32 %1, i32 0
273 %p = getelementptr %Foo* @GS, i16 %x, i32 0
275 %r = icmp eq i32 %q, 0
279 define i1 @test10_struct_arr(i32 %x) {
280 ; NODL-LABEL: @test10_struct_arr(
281 ; NODL-NEXT: %r = icmp ne i32 %x, 1
282 ; NODL-NEXT: ret i1 %r
284 ; P32-LABEL: @test10_struct_arr(
285 ; P32-NEXT: %r = icmp ne i32 %x, 1
286 ; P32-NEXT: ret i1 %r
287 %p = getelementptr inbounds [4 x %Foo]* @GStructArr, i32 0, i32 %x, i32 2
289 %r = icmp eq i32 %q, 9
293 define i1 @test10_struct_arr_noinbounds(i32 %x) {
294 ; NODL-LABEL: @test10_struct_arr_noinbounds(
295 ; NODL-NEXT %p = getelementptr [4 x %Foo]* @GStructArr, i32 0, i32 %x, i32 2
297 ; P32-LABEL: @test10_struct_arr_noinbounds(
298 ; P32-NEXT %p = getelementptr [4 x %Foo]* @GStructArr, i32 0, i32 %x, i32 2
299 %p = getelementptr [4 x %Foo]* @GStructArr, i32 0, i32 %x, i32 2
301 %r = icmp eq i32 %q, 9
305 define i1 @test10_struct_arr_i16(i16 %x) {
306 ; NODL-LABEL: @test10_struct_arr_i16(
307 ; NODL-NEXT: %r = icmp ne i16 %x, 1
308 ; NODL-NEXT: ret i1 %r
310 ; P32-LABEL: @test10_struct_arr_i16(
311 ; P32-NEXT: %r = icmp ne i16 %x, 1
312 ; P32-NEXT: ret i1 %r
313 %p = getelementptr inbounds [4 x %Foo]* @GStructArr, i16 0, i16 %x, i32 2
315 %r = icmp eq i32 %q, 9
319 define i1 @test10_struct_arr_i64(i64 %x) {
320 ; NODL-LABEL: @test10_struct_arr_i64(
321 ; NODL-NEXT: %r = icmp ne i64 %x, 1
322 ; NODL-NEXT: ret i1 %r
324 ; P32-LABEL: @test10_struct_arr_i64(
325 ; P32-NEXT: trunc i64 %x to i32
326 ; P32-NEXT: %r = icmp ne i32 %1, 1
327 ; P32-NEXT: ret i1 %r
328 %p = getelementptr inbounds [4 x %Foo]* @GStructArr, i64 0, i64 %x, i32 2
330 %r = icmp eq i32 %q, 9
334 define i1 @test10_struct_arr_noinbounds_i16(i16 %x) {
335 ; NODL-LABEL: @test10_struct_arr_noinbounds_i16(
336 ; NODL-NEXT: %p = getelementptr [4 x %Foo]* @GStructArr, i32 0, i16 %x, i32 2
338 ; P32-LABEL: @test10_struct_arr_noinbounds_i16(
339 ; P32-NEXT: %r = icmp ne i16 %x, 1
340 %p = getelementptr [4 x %Foo]* @GStructArr, i32 0, i16 %x, i32 2
342 %r = icmp eq i32 %q, 9
346 define i1 @test10_struct_arr_noinbounds_i64(i64 %x) {
347 ; FIXME: Should be no trunc?
348 ; NODL-LABEL: @test10_struct_arr_noinbounds_i64(
349 ; NODL-NEXT: %p = getelementptr [4 x %Foo]* @GStructArr, i32 0, i64 %x, i32 2
351 ; P32-LABEL: @test10_struct_arr_noinbounds_i64(
352 ; P32: %r = icmp ne i32 %1, 1
353 ; P32-NEXT: ret i1 %r
354 %p = getelementptr [4 x %Foo]* @GStructArr, i32 0, i64 %x, i32 2
356 %r = icmp eq i32 %q, 9