• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: opt -instcombine -S -default-data-layout="p:32:32:32-p1:16:16:16-n8:16:32:64" < %s | FileCheck %s
2
3@G16 = internal constant [10 x i16] [i16 35, i16 82, i16 69, i16 81, i16 85,
4                                     i16 73, i16 82, i16 69, i16 68, i16 0]
5
6@G16_as1 = internal addrspace(1) constant [10 x i16] [i16 35, i16 82, i16 69, i16 81, i16 85,
7                                                      i16 73, i16 82, i16 69, i16 68, i16 0]
8
9@GD = internal constant [6 x double]
10   [double -10.0, double 1.0, double 4.0, double 2.0, double -20.0, double -40.0]
11
12%Foo = type { i32, i32, i32, i32 }
13
14@GS = internal constant %Foo { i32 1, i32 4, i32 9, i32 14 }
15
16@GStructArr = internal constant [4 x %Foo] [ %Foo { i32 1, i32 4, i32 9, i32 14 },
17                                             %Foo { i32 5, i32 4, i32 6, i32 11 },
18                                             %Foo { i32 6, i32 5, i32 9, i32 20 },
19                                             %Foo { i32 12, i32 3, i32 9, i32 8 } ]
20
21
22define i1 @test1(i32 %X) {
23  %P = getelementptr inbounds [10 x i16], [10 x i16]* @G16, i32 0, i32 %X
24  %Q = load i16, i16* %P
25  %R = icmp eq i16 %Q, 0
26  ret i1 %R
27; CHECK-LABEL: @test1(
28; CHECK-NEXT: %R = icmp eq i32 %X, 9
29; CHECK-NEXT: ret i1 %R
30}
31
32define i1 @test1_noinbounds(i32 %X) {
33  %P = getelementptr [10 x i16], [10 x i16]* @G16, i32 0, i32 %X
34  %Q = load i16, i16* %P
35  %R = icmp eq i16 %Q, 0
36  ret i1 %R
37; CHECK-LABEL: @test1_noinbounds(
38; CHECK-NEXT: %R = icmp eq i32 %X, 9
39; CHECK-NEXT: ret i1 %R
40}
41
42define i1 @test1_noinbounds_i64(i64 %X) {
43  %P = getelementptr [10 x i16], [10 x i16]* @G16, i64 0, i64 %X
44  %Q = load i16, i16* %P
45  %R = icmp eq i16 %Q, 0
46  ret i1 %R
47; CHECK-LABEL: @test1_noinbounds_i64(
48; CHECK: %R = icmp eq i32 %1, 9
49; CHECK-NEXT: ret i1 %R
50}
51
52define i1 @test1_noinbounds_as1(i32 %x) {
53  %p = getelementptr [10 x i16], [10 x i16] addrspace(1)* @G16_as1, i16 0, i32 %x
54  %q = load i16, i16 addrspace(1)* %p
55  %r = icmp eq i16 %q, 0
56  ret i1 %r
57
58; CHECK-LABEL: @test1_noinbounds_as1(
59; CHECK-NEXT: trunc i32 %x to i16
60; CHECK-NEXT: %r = icmp eq i16 %1, 9
61; CHECK-NEXT: ret i1 %r
62}
63
64define i1 @test2(i32 %X) {
65  %P = getelementptr inbounds [10 x i16], [10 x i16]* @G16, i32 0, i32 %X
66  %Q = load i16, i16* %P
67  %R = icmp slt i16 %Q, 85
68  ret i1 %R
69; CHECK-LABEL: @test2(
70; CHECK-NEXT:  %R = icmp ne i32 %X, 4
71; CHECK-NEXT:  ret i1 %R
72}
73
74define i1 @test3(i32 %X) {
75  %P = getelementptr inbounds [6 x double], [6 x double]* @GD, i32 0, i32 %X
76  %Q = load double, double* %P
77  %R = fcmp oeq double %Q, 1.0
78  ret i1 %R
79; CHECK-LABEL: @test3(
80; CHECK-NEXT: %R = icmp eq i32 %X, 1
81; CHECK-NEXT: ret i1 %R
82
83}
84
85define i1 @test4(i32 %X) {
86  %P = getelementptr inbounds [10 x i16], [10 x i16]* @G16, i32 0, i32 %X
87  %Q = load i16, i16* %P
88  %R = icmp sle i16 %Q, 73
89  ret i1 %R
90; CHECK-LABEL: @test4(
91; CHECK-NEXT: lshr i32 933, %X
92; CHECK-NEXT: and i32 {{.*}}, 1
93; CHECK-NEXT: %R = icmp ne i32 {{.*}}, 0
94; CHECK-NEXT: ret i1 %R
95}
96
97define i1 @test4_i16(i16 %X) {
98  %P = getelementptr inbounds [10 x i16], [10 x i16]* @G16, i32 0, i16 %X
99  %Q = load i16, i16* %P
100  %R = icmp sle i16 %Q, 73
101  ret i1 %R
102; CHECK-LABEL: @test4_i16(
103; CHECK-NEXT: sext i16 %X to i32
104; CHECK-NEXT: lshr i32 933, %1
105; CHECK-NEXT: and i32 {{.*}}, 1
106; CHECK-NEXT: %R = icmp ne i32 {{.*}}, 0
107; CHECK-NEXT: ret i1 %R
108}
109
110define i1 @test5(i32 %X) {
111  %P = getelementptr inbounds [10 x i16], [10 x i16]* @G16, i32 0, i32 %X
112  %Q = load i16, i16* %P
113  %R = icmp eq i16 %Q, 69
114  ret i1 %R
115; CHECK-LABEL: @test5(
116; CHECK-NEXT: icmp eq i32 %X, 2
117; CHECK-NEXT: icmp eq i32 %X, 7
118; CHECK-NEXT: %R = or i1
119; CHECK-NEXT: ret i1 %R
120}
121
122define i1 @test6(i32 %X) {
123  %P = getelementptr inbounds [6 x double], [6 x double]* @GD, i32 0, i32 %X
124  %Q = load double, double* %P
125  %R = fcmp ogt double %Q, 0.0
126  ret i1 %R
127; CHECK-LABEL: @test6(
128; CHECK-NEXT: add i32 %X, -1
129; CHECK-NEXT: %R = icmp ult i32 {{.*}}, 3
130; CHECK-NEXT: ret i1 %R
131}
132
133define i1 @test7(i32 %X) {
134  %P = getelementptr inbounds [6 x double], [6 x double]* @GD, i32 0, i32 %X
135  %Q = load double, double* %P
136  %R = fcmp olt double %Q, 0.0
137  ret i1 %R
138; CHECK-LABEL: @test7(
139; CHECK-NEXT: add i32 %X, -1
140; CHECK-NEXT: %R = icmp ugt i32 {{.*}}, 2
141; CHECK-NEXT: ret i1 %R
142}
143
144define i1 @test8(i32 %X) {
145  %P = getelementptr inbounds [10 x i16], [10 x i16]* @G16, i32 0, i32 %X
146  %Q = load i16, i16* %P
147  %R = and i16 %Q, 3
148  %S = icmp eq i16 %R, 0
149  ret i1 %S
150; CHECK-LABEL: @test8(
151; CHECK-NEXT: or i32 %X, 1
152; CHECK-NEXT: icmp eq i32 {{.*}}, 9
153; CHECK-NEXT: ret i1
154}
155
156@GA = internal constant [4 x { i32, i32 } ] [
157  { i32, i32 } { i32 1, i32 0 },
158  { i32, i32 } { i32 2, i32 1 },
159  { i32, i32 } { i32 3, i32 1 },
160  { i32, i32 } { i32 4, i32 0 }
161]
162
163define i1 @test9(i32 %X) {
164  %P = getelementptr inbounds [4 x { i32, i32 } ], [4 x { i32, i32 } ]* @GA, i32 0, i32 %X, i32 1
165  %Q = load i32, i32* %P
166  %R = icmp eq i32 %Q, 1
167  ret i1 %R
168; CHECK-LABEL: @test9(
169; CHECK-NEXT: add i32 %X, -1
170; CHECK-NEXT: icmp ult i32 {{.*}}, 2
171; CHECK-NEXT: ret i1
172}
173
174define i1 @test10_struct(i32 %x) {
175; CHECK-LABEL: @test10_struct(
176; CHECK: ret i1 false
177  %p = getelementptr inbounds %Foo, %Foo* @GS, i32 %x, i32 0
178  %q = load i32, i32* %p
179  %r = icmp eq i32 %q, 9
180  ret i1 %r
181}
182
183define i1 @test10_struct_noinbounds(i32 %x) {
184; CHECK-LABEL: @test10_struct_noinbounds(
185; CHECK: getelementptr %Foo, %Foo* @GS, i32 %x, i32 0
186  %p = getelementptr %Foo, %Foo* @GS, i32 %x, i32 0
187  %q = load i32, i32* %p
188  %r = icmp eq i32 %q, 9
189  ret i1 %r
190}
191
192; Test that the GEP indices are converted before we ever get here
193; Index < ptr size
194define i1 @test10_struct_i16(i16 %x){
195; CHECK-LABEL: @test10_struct_i16(
196; CHECK: ret i1 false
197  %p = getelementptr inbounds %Foo, %Foo* @GS, i16 %x, i32 0
198  %q = load i32, i32* %p
199  %r = icmp eq i32 %q, 0
200  ret i1 %r
201}
202
203; Test that the GEP indices are converted before we ever get here
204; Index > ptr size
205define i1 @test10_struct_i64(i64 %x){
206; CHECK-LABEL: @test10_struct_i64(
207; CHECK: ret i1 false
208  %p = getelementptr inbounds %Foo, %Foo* @GS, i64 %x, i32 0
209  %q = load i32, i32* %p
210  %r = icmp eq i32 %q, 0
211  ret i1 %r
212}
213
214define i1 @test10_struct_noinbounds_i16(i16 %x) {
215; CHECK-LABEL: @test10_struct_noinbounds_i16(
216; CHECK: %1 = sext i16 %x to i32
217; CHECK: getelementptr %Foo, %Foo* @GS, i32 %1, i32 0
218  %p = getelementptr %Foo, %Foo* @GS, i16 %x, i32 0
219  %q = load i32, i32* %p
220  %r = icmp eq i32 %q, 0
221  ret i1 %r
222}
223
224define i1 @test10_struct_arr(i32 %x) {
225; CHECK-LABEL: @test10_struct_arr(
226; CHECK-NEXT: %r = icmp ne i32 %x, 1
227; CHECK-NEXT: ret i1 %r
228  %p = getelementptr inbounds [4 x %Foo], [4 x %Foo]* @GStructArr, i32 0, i32 %x, i32 2
229  %q = load i32, i32* %p
230  %r = icmp eq i32 %q, 9
231  ret i1 %r
232}
233
234define i1 @test10_struct_arr_noinbounds(i32 %x) {
235; CHECK-LABEL: @test10_struct_arr_noinbounds(
236; CHECK-NEXT: %r = icmp ne i32 %x, 1
237; CHECK-NEXT: ret i1 %r
238  %p = getelementptr [4 x %Foo], [4 x %Foo]* @GStructArr, i32 0, i32 %x, i32 2
239  %q = load i32, i32* %p
240  %r = icmp eq i32 %q, 9
241  ret i1 %r
242}
243
244define i1 @test10_struct_arr_i16(i16 %x) {
245; CHECK-LABEL: @test10_struct_arr_i16(
246; CHECK-NEXT: %r = icmp ne i16 %x, 1
247; CHECK-NEXT: ret i1 %r
248  %p = getelementptr inbounds [4 x %Foo], [4 x %Foo]* @GStructArr, i16 0, i16 %x, i32 2
249  %q = load i32, i32* %p
250  %r = icmp eq i32 %q, 9
251  ret i1 %r
252}
253
254define i1 @test10_struct_arr_i64(i64 %x) {
255; CHECK-LABEL: @test10_struct_arr_i64(
256; CHECK-NEXT: trunc i64 %x to i32
257; CHECK-NEXT: %r = icmp ne i32 %1, 1
258; CHECK-NEXT: ret i1 %r
259  %p = getelementptr inbounds [4 x %Foo], [4 x %Foo]* @GStructArr, i64 0, i64 %x, i32 2
260  %q = load i32, i32* %p
261  %r = icmp eq i32 %q, 9
262  ret i1 %r
263}
264
265define i1 @test10_struct_arr_noinbounds_i16(i16 %x) {
266; CHECK-LABEL: @test10_struct_arr_noinbounds_i16(
267; CHECK-NEXT: %r = icmp ne i16 %x, 1
268  %p = getelementptr [4 x %Foo], [4 x %Foo]* @GStructArr, i32 0, i16 %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_noinbounds_i64(i64 %x) {
275; CHECK-LABEL: @test10_struct_arr_noinbounds_i64(
276; CHECK: %r = icmp ne i32 %1, 1
277; CHECK-NEXT: ret i1 %r
278  %p = getelementptr [4 x %Foo], [4 x %Foo]* @GStructArr, i32 0, i64 %x, i32 2
279  %q = load i32, i32* %p
280  %r = icmp eq i32 %q, 9
281  ret i1 %r
282}
283