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