[InstCombine] Signed saturation patterns
[llvm-complete.git] / test / CodeGen / SystemZ / int-cmp-05.ll
blob2f048aefe8dc3952dcf6a7fb52c52099569c471c
1 ; Test 64-bit comparison in which the second operand is a sign-extended i32.
3 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
5 declare i64 @foo()
7 ; Check signed register comparison.
8 define double @f1(double %a, double %b, i64 %i1, i32 %unext) {
9 ; CHECK-LABEL: f1:
10 ; CHECK: cgfr %r2, %r3
11 ; CHECK-NEXT: blr %r14
12 ; CHECK: ldr %f0, %f2
13 ; CHECK: br %r14
14   %i2 = sext i32 %unext to i64
15   %cond = icmp slt i64 %i1, %i2
16   %res = select i1 %cond, double %a, double %b
17   ret double %res
20 ; Check unsigned register comparison, which can't use CGFR.
21 define double @f2(double %a, double %b, i64 %i1, i32 %unext) {
22 ; CHECK-LABEL: f2:
23 ; CHECK-NOT: cgfr
24 ; CHECK: br %r14
25   %i2 = sext i32 %unext to i64
26   %cond = icmp ult i64 %i1, %i2
27   %res = select i1 %cond, double %a, double %b
28   ret double %res
31 ; Check register equality.
32 define double @f3(double %a, double %b, i64 %i1, i32 %unext) {
33 ; CHECK-LABEL: f3:
34 ; CHECK: cgfr %r2, %r3
35 ; CHECK-NEXT: ber %r14
36 ; CHECK: ldr %f0, %f2
37 ; CHECK: br %r14
38   %i2 = sext i32 %unext to i64
39   %cond = icmp eq i64 %i1, %i2
40   %res = select i1 %cond, double %a, double %b
41   ret double %res
44 ; Check register inequality.
45 define double @f4(double %a, double %b, i64 %i1, i32 %unext) {
46 ; CHECK-LABEL: f4:
47 ; CHECK: cgfr %r2, %r3
48 ; CHECK-NEXT: blhr %r14
49 ; CHECK: ldr %f0, %f2
50 ; CHECK: br %r14
51   %i2 = sext i32 %unext to i64
52   %cond = icmp ne i64 %i1, %i2
53   %res = select i1 %cond, double %a, double %b
54   ret double %res
57 ; Check signed comparison with memory.
58 define double @f5(double %a, double %b, i64 %i1, i32 *%ptr) {
59 ; CHECK-LABEL: f5:
60 ; CHECK: cgf %r2, 0(%r3)
61 ; CHECK-NEXT: blr %r14
62 ; CHECK: ldr %f0, %f2
63 ; CHECK: br %r14
64   %unext = load i32, i32 *%ptr
65   %i2 = sext i32 %unext to i64
66   %cond = icmp slt i64 %i1, %i2
67   %res = select i1 %cond, double %a, double %b
68   ret double %res
71 ; Check unsigned comparison with memory.
72 define double @f6(double %a, double %b, i64 %i1, i32 *%ptr) {
73 ; CHECK-LABEL: f6:
74 ; CHECK-NOT: cgf
75 ; CHECK: br %r14
76   %unext = load i32, i32 *%ptr
77   %i2 = sext i32 %unext to i64
78   %cond = icmp ult i64 %i1, %i2
79   %res = select i1 %cond, double %a, double %b
80   ret double %res
83 ; Check memory equality.
84 define double @f7(double %a, double %b, i64 %i1, i32 *%ptr) {
85 ; CHECK-LABEL: f7:
86 ; CHECK: cgf %r2, 0(%r3)
87 ; CHECK-NEXT: ber %r14
88 ; CHECK: ldr %f0, %f2
89 ; CHECK: br %r14
90   %unext = load i32, i32 *%ptr
91   %i2 = sext i32 %unext to i64
92   %cond = icmp eq i64 %i1, %i2
93   %res = select i1 %cond, double %a, double %b
94   ret double %res
97 ; Check memory inequality.
98 define double @f8(double %a, double %b, i64 %i1, i32 *%ptr) {
99 ; CHECK-LABEL: f8:
100 ; CHECK: cgf %r2, 0(%r3)
101 ; CHECK-NEXT: blhr %r14
102 ; CHECK: ldr %f0, %f2
103 ; CHECK: br %r14
104   %unext = load i32, i32 *%ptr
105   %i2 = sext i32 %unext to i64
106   %cond = icmp ne i64 %i1, %i2
107   %res = select i1 %cond, double %a, double %b
108   ret double %res
111 ; Check the high end of the aligned CGF range.
112 define double @f9(double %a, double %b, i64 %i1, i32 *%base) {
113 ; CHECK-LABEL: f9:
114 ; CHECK: cgf %r2, 524284(%r3)
115 ; CHECK-NEXT: blr %r14
116 ; CHECK: ldr %f0, %f2
117 ; CHECK: br %r14
118   %ptr = getelementptr i32, i32 *%base, i64 131071
119   %unext = load i32, i32 *%ptr
120   %i2 = sext i32 %unext to i64
121   %cond = icmp slt i64 %i1, %i2
122   %res = select i1 %cond, double %a, double %b
123   ret double %res
126 ; Check the next word up, which needs separate address logic.
127 ; Other sequences besides this one would be OK.
128 define double @f10(double %a, double %b, i64 %i1, i32 *%base) {
129 ; CHECK-LABEL: f10:
130 ; CHECK: agfi %r3, 524288
131 ; CHECK: cgf %r2, 0(%r3)
132 ; CHECK-NEXT: blr %r14
133 ; CHECK: ldr %f0, %f2
134 ; CHECK: br %r14
135   %ptr = getelementptr i32, i32 *%base, i64 131072
136   %unext = load i32, i32 *%ptr
137   %i2 = sext i32 %unext to i64
138   %cond = icmp slt i64 %i1, %i2
139   %res = select i1 %cond, double %a, double %b
140   ret double %res
143 ; Check the high end of the negative aligned CGF range.
144 define double @f11(double %a, double %b, i64 %i1, i32 *%base) {
145 ; CHECK-LABEL: f11:
146 ; CHECK: cgf %r2, -4(%r3)
147 ; CHECK-NEXT: blr %r14
148 ; CHECK: ldr %f0, %f2
149 ; CHECK: br %r14
150   %ptr = getelementptr i32, i32 *%base, i64 -1
151   %unext = load i32, i32 *%ptr
152   %i2 = sext i32 %unext to i64
153   %cond = icmp slt i64 %i1, %i2
154   %res = select i1 %cond, double %a, double %b
155   ret double %res
158 ; Check the low end of the CGF range.
159 define double @f12(double %a, double %b, i64 %i1, i32 *%base) {
160 ; CHECK-LABEL: f12:
161 ; CHECK: cgf %r2, -524288(%r3)
162 ; CHECK-NEXT: blr %r14
163 ; CHECK: ldr %f0, %f2
164 ; CHECK: br %r14
165   %ptr = getelementptr i32, i32 *%base, i64 -131072
166   %unext = load i32, i32 *%ptr
167   %i2 = sext i32 %unext to i64
168   %cond = icmp slt i64 %i1, %i2
169   %res = select i1 %cond, double %a, double %b
170   ret double %res
173 ; Check the next word down, which needs separate address logic.
174 ; Other sequences besides this one would be OK.
175 define double @f13(double %a, double %b, i64 %i1, i32 *%base) {
176 ; CHECK-LABEL: f13:
177 ; CHECK: agfi %r3, -524292
178 ; CHECK: cgf %r2, 0(%r3)
179 ; CHECK-NEXT: blr %r14
180 ; CHECK: ldr %f0, %f2
181 ; CHECK: br %r14
182   %ptr = getelementptr i32, i32 *%base, i64 -131073
183   %unext = load i32, i32 *%ptr
184   %i2 = sext i32 %unext to i64
185   %cond = icmp slt i64 %i1, %i2
186   %res = select i1 %cond, double %a, double %b
187   ret double %res
190 ; Check that CGF allows an index.
191 define double @f14(double %a, double %b, i64 %i1, i64 %base, i64 %index) {
192 ; CHECK-LABEL: f14:
193 ; CHECK: cgf %r2, 524284({{%r4,%r3|%r3,%r4}})
194 ; CHECK-NEXT: blr %r14
195 ; CHECK: ldr %f0, %f2
196 ; CHECK: br %r14
197   %add1 = add i64 %base, %index
198   %add2 = add i64 %add1, 524284
199   %ptr = inttoptr i64 %add2 to i32 *
200   %unext = load i32, i32 *%ptr
201   %i2 = sext i32 %unext to i64
202   %cond = icmp slt i64 %i1, %i2
203   %res = select i1 %cond, double %a, double %b
204   ret double %res
207 ; Check that comparisons of spilled values can use CGF rather than CGFR.
208 define i64 @f15(i32 *%ptr0) {
209 ; CHECK-LABEL: f15:
210 ; CHECK: brasl %r14, foo@PLT
211 ; CHECK: cgf {{%r[0-9]+}}, 16{{[04]}}(%r15)
212 ; CHECK: br %r14
213   %ptr1 = getelementptr i32, i32 *%ptr0, i64 2
214   %ptr2 = getelementptr i32, i32 *%ptr0, i64 4
215   %ptr3 = getelementptr i32, i32 *%ptr0, i64 6
216   %ptr4 = getelementptr i32, i32 *%ptr0, i64 8
217   %ptr5 = getelementptr i32, i32 *%ptr0, i64 10
218   %ptr6 = getelementptr i32, i32 *%ptr0, i64 12
219   %ptr7 = getelementptr i32, i32 *%ptr0, i64 14
220   %ptr8 = getelementptr i32, i32 *%ptr0, i64 16
221   %ptr9 = getelementptr i32, i32 *%ptr0, i64 18
223   %val0 = load i32, i32 *%ptr0
224   %val1 = load i32, i32 *%ptr1
225   %val2 = load i32, i32 *%ptr2
226   %val3 = load i32, i32 *%ptr3
227   %val4 = load i32, i32 *%ptr4
228   %val5 = load i32, i32 *%ptr5
229   %val6 = load i32, i32 *%ptr6
230   %val7 = load i32, i32 *%ptr7
231   %val8 = load i32, i32 *%ptr8
232   %val9 = load i32, i32 *%ptr9
234   %frob0 = add i32 %val0, 100
235   %frob1 = add i32 %val1, 100
236   %frob2 = add i32 %val2, 100
237   %frob3 = add i32 %val3, 100
238   %frob4 = add i32 %val4, 100
239   %frob5 = add i32 %val5, 100
240   %frob6 = add i32 %val6, 100
241   %frob7 = add i32 %val7, 100
242   %frob8 = add i32 %val8, 100
243   %frob9 = add i32 %val9, 100
245   store i32 %frob0, i32 *%ptr0
246   store i32 %frob1, i32 *%ptr1
247   store i32 %frob2, i32 *%ptr2
248   store i32 %frob3, i32 *%ptr3
249   store i32 %frob4, i32 *%ptr4
250   store i32 %frob5, i32 *%ptr5
251   store i32 %frob6, i32 *%ptr6
252   store i32 %frob7, i32 *%ptr7
253   store i32 %frob8, i32 *%ptr8
254   store i32 %frob9, i32 *%ptr9
256   %ret = call i64 @foo()
258   %ext0 = sext i32 %frob0 to i64
259   %ext1 = sext i32 %frob1 to i64
260   %ext2 = sext i32 %frob2 to i64
261   %ext3 = sext i32 %frob3 to i64
262   %ext4 = sext i32 %frob4 to i64
263   %ext5 = sext i32 %frob5 to i64
264   %ext6 = sext i32 %frob6 to i64
265   %ext7 = sext i32 %frob7 to i64
266   %ext8 = sext i32 %frob8 to i64
267   %ext9 = sext i32 %frob9 to i64
269   %cmp0 = icmp slt i64 %ret, %ext0
270   %cmp1 = icmp slt i64 %ret, %ext1
271   %cmp2 = icmp slt i64 %ret, %ext2
272   %cmp3 = icmp slt i64 %ret, %ext3
273   %cmp4 = icmp slt i64 %ret, %ext4
274   %cmp5 = icmp slt i64 %ret, %ext5
275   %cmp6 = icmp slt i64 %ret, %ext6
276   %cmp7 = icmp slt i64 %ret, %ext7
277   %cmp8 = icmp slt i64 %ret, %ext8
278   %cmp9 = icmp slt i64 %ret, %ext9
280   %sel0 = select i1 %cmp0, i64 %ret, i64 0
281   %sel1 = select i1 %cmp1, i64 %sel0, i64 1
282   %sel2 = select i1 %cmp2, i64 %sel1, i64 2
283   %sel3 = select i1 %cmp3, i64 %sel2, i64 3
284   %sel4 = select i1 %cmp4, i64 %sel3, i64 4
285   %sel5 = select i1 %cmp5, i64 %sel4, i64 5
286   %sel6 = select i1 %cmp6, i64 %sel5, i64 6
287   %sel7 = select i1 %cmp7, i64 %sel6, i64 7
288   %sel8 = select i1 %cmp8, i64 %sel7, i64 8
289   %sel9 = select i1 %cmp9, i64 %sel8, i64 9
291   ret i64 %sel9
294 ; Check the comparison can be reversed if that allows CGFR to be used.
295 define double @f16(double %a, double %b, i64 %i1, i32 %unext) {
296 ; CHECK-LABEL: f16:
297 ; CHECK: cgfr %r2, %r3
298 ; CHECK-NEXT: bhr %r14
299 ; CHECK: ldr %f0, %f2
300 ; CHECK: br %r14
301   %i2 = sext i32 %unext to i64
302   %cond = icmp slt i64 %i2, %i1
303   %res = select i1 %cond, double %a, double %b
304   ret double %res
307 ; Likewise CGF.
308 define double @f17(double %a, double %b, i64 %i2, i32 *%ptr) {
309 ; CHECK-LABEL: f17:
310 ; CHECK: cgf %r2, 0(%r3)
311 ; CHECK-NEXT: bhr %r14
312 ; CHECK: ldr %f0, %f2
313 ; CHECK: br %r14
314   %unext = load i32, i32 *%ptr
315   %i1 = sext i32 %unext to i64
316   %cond = icmp slt i64 %i1, %i2
317   %res = select i1 %cond, double %a, double %b
318   ret double %res