1; Test 64-bit comparison in which the second operand is a sign-extended i32.
2;
3; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
4
5; Check signed register comparison.
6define double @f1(double %a, double %b, i64 %i1, i32 %unext) {
7; CHECK: f1:
8; CHECK: cgfr %r2, %r3
9; CHECK-NEXT: jl
10; CHECK: ldr %f0, %f2
11; CHECK: br %r14
12  %i2 = sext i32 %unext to i64
13  %cond = icmp slt i64 %i1, %i2
14  %res = select i1 %cond, double %a, double %b
15  ret double %res
16}
17
18; Check unsigned register comparison, which can't use CGFR.
19define double @f2(double %a, double %b, i64 %i1, i32 %unext) {
20; CHECK: f2:
21; CHECK-NOT: cgfr
22; CHECK: br %r14
23  %i2 = sext i32 %unext to i64
24  %cond = icmp ult i64 %i1, %i2
25  %res = select i1 %cond, double %a, double %b
26  ret double %res
27}
28
29; Check register equality.
30define double @f3(double %a, double %b, i64 %i1, i32 %unext) {
31; CHECK: f3:
32; CHECK: cgfr %r2, %r3
33; CHECK-NEXT: je
34; CHECK: ldr %f0, %f2
35; CHECK: br %r14
36  %i2 = sext i32 %unext to i64
37  %cond = icmp eq i64 %i1, %i2
38  %res = select i1 %cond, double %a, double %b
39  ret double %res
40}
41
42; Check register inequality.
43define double @f4(double %a, double %b, i64 %i1, i32 %unext) {
44; CHECK: f4:
45; CHECK: cgfr %r2, %r3
46; CHECK-NEXT: jlh
47; CHECK: ldr %f0, %f2
48; CHECK: br %r14
49  %i2 = sext i32 %unext to i64
50  %cond = icmp ne i64 %i1, %i2
51  %res = select i1 %cond, double %a, double %b
52  ret double %res
53}
54
55; Check signed comparisonn with memory.
56define double @f5(double %a, double %b, i64 %i1, i32 *%ptr) {
57; CHECK: f5:
58; CHECK: cgf %r2, 0(%r3)
59; CHECK-NEXT: jl
60; CHECK: ldr %f0, %f2
61; CHECK: br %r14
62  %unext = load i32 *%ptr
63  %i2 = sext i32 %unext to i64
64  %cond = icmp slt i64 %i1, %i2
65  %res = select i1 %cond, double %a, double %b
66  ret double %res
67}
68
69; Check unsigned comparison with memory.
70define double @f6(double %a, double %b, i64 %i1, i32 *%ptr) {
71; CHECK: f6:
72; CHECK-NOT: cgf
73; CHECK: br %r14
74  %unext = load i32 *%ptr
75  %i2 = sext i32 %unext to i64
76  %cond = icmp ult i64 %i1, %i2
77  %res = select i1 %cond, double %a, double %b
78  ret double %res
79}
80
81; Check memory equality.
82define double @f7(double %a, double %b, i64 %i1, i32 *%ptr) {
83; CHECK: f7:
84; CHECK: cgf %r2, 0(%r3)
85; CHECK-NEXT: je
86; CHECK: ldr %f0, %f2
87; CHECK: br %r14
88  %unext = load i32 *%ptr
89  %i2 = sext i32 %unext to i64
90  %cond = icmp eq i64 %i1, %i2
91  %res = select i1 %cond, double %a, double %b
92  ret double %res
93}
94
95; Check memory inequality.
96define double @f8(double %a, double %b, i64 %i1, i32 *%ptr) {
97; CHECK: f8:
98; CHECK: cgf %r2, 0(%r3)
99; CHECK-NEXT: jlh
100; CHECK: ldr %f0, %f2
101; CHECK: br %r14
102  %unext = load i32 *%ptr
103  %i2 = sext i32 %unext to i64
104  %cond = icmp ne i64 %i1, %i2
105  %res = select i1 %cond, double %a, double %b
106  ret double %res
107}
108
109; Check the high end of the aligned CGF range.
110define double @f9(double %a, double %b, i64 %i1, i32 *%base) {
111; CHECK: f9:
112; CHECK: cgf %r2, 524284(%r3)
113; CHECK-NEXT: jl
114; CHECK: ldr %f0, %f2
115; CHECK: br %r14
116  %ptr = getelementptr i32 *%base, i64 131071
117  %unext = load i32 *%ptr
118  %i2 = sext i32 %unext to i64
119  %cond = icmp slt i64 %i1, %i2
120  %res = select i1 %cond, double %a, double %b
121  ret double %res
122}
123
124; Check the next word up, which needs separate address logic.
125; Other sequences besides this one would be OK.
126define double @f10(double %a, double %b, i64 %i1, i32 *%base) {
127; CHECK: f10:
128; CHECK: agfi %r3, 524288
129; CHECK: cgf %r2, 0(%r3)
130; CHECK-NEXT: jl
131; CHECK: ldr %f0, %f2
132; CHECK: br %r14
133  %ptr = getelementptr i32 *%base, i64 131072
134  %unext = load i32 *%ptr
135  %i2 = sext i32 %unext to i64
136  %cond = icmp slt i64 %i1, %i2
137  %res = select i1 %cond, double %a, double %b
138  ret double %res
139}
140
141; Check the high end of the negative aligned CGF range.
142define double @f11(double %a, double %b, i64 %i1, i32 *%base) {
143; CHECK: f11:
144; CHECK: cgf %r2, -4(%r3)
145; CHECK-NEXT: jl
146; CHECK: ldr %f0, %f2
147; CHECK: br %r14
148  %ptr = getelementptr i32 *%base, i64 -1
149  %unext = load i32 *%ptr
150  %i2 = sext i32 %unext to i64
151  %cond = icmp slt i64 %i1, %i2
152  %res = select i1 %cond, double %a, double %b
153  ret double %res
154}
155
156; Check the low end of the CGF range.
157define double @f12(double %a, double %b, i64 %i1, i32 *%base) {
158; CHECK: f12:
159; CHECK: cgf %r2, -524288(%r3)
160; CHECK-NEXT: jl
161; CHECK: ldr %f0, %f2
162; CHECK: br %r14
163  %ptr = getelementptr i32 *%base, i64 -131072
164  %unext = load i32 *%ptr
165  %i2 = sext i32 %unext to i64
166  %cond = icmp slt i64 %i1, %i2
167  %res = select i1 %cond, double %a, double %b
168  ret double %res
169}
170
171; Check the next word down, which needs separate address logic.
172; Other sequences besides this one would be OK.
173define double @f13(double %a, double %b, i64 %i1, i32 *%base) {
174; CHECK: f13:
175; CHECK: agfi %r3, -524292
176; CHECK: cgf %r2, 0(%r3)
177; CHECK-NEXT: jl
178; CHECK: ldr %f0, %f2
179; CHECK: br %r14
180  %ptr = getelementptr i32 *%base, i64 -131073
181  %unext = load i32 *%ptr
182  %i2 = sext i32 %unext to i64
183  %cond = icmp slt i64 %i1, %i2
184  %res = select i1 %cond, double %a, double %b
185  ret double %res
186}
187
188; Check that CGF allows an index.
189define double @f14(double %a, double %b, i64 %i1, i64 %base, i64 %index) {
190; CHECK: f14:
191; CHECK: cgf %r2, 524284({{%r4,%r3|%r3,%r4}})
192; CHECK-NEXT: jl
193; CHECK: ldr %f0, %f2
194; CHECK: br %r14
195  %add1 = add i64 %base, %index
196  %add2 = add i64 %add1, 524284
197  %ptr = inttoptr i64 %add2 to i32 *
198  %unext = load i32 *%ptr
199  %i2 = sext i32 %unext to i64
200  %cond = icmp slt i64 %i1, %i2
201  %res = select i1 %cond, double %a, double %b
202  ret double %res
203}
204