1; Test 32-bit floating-point comparison.  The tests assume a z10 implementation
2; of select, using conditional branches rather than LOCGR.
3;
4; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 \
5; RUN:   | FileCheck -check-prefix=CHECK -check-prefix=CHECK-SCALAR %s
6; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z14 \
7; RUN:   | FileCheck -check-prefix=CHECK -check-prefix=CHECK-VECTOR %s
8
9declare float @foo()
10
11; Check comparison with registers.
12define i64 @f1(i64 %a, i64 %b, float %f1, float %f2) {
13; CHECK-LABEL: f1:
14; CHECK: cebr %f0, %f2
15; CHECK-SCALAR-NEXT: ber %r14
16; CHECK-SCALAR: lgr %r2, %r3
17; CHECK-VECTOR-NEXT: locgrne %r2, %r3
18; CHECK: br %r14
19  %cond = fcmp oeq float %f1, %f2
20  %res = select i1 %cond, i64 %a, i64 %b
21  ret i64 %res
22}
23
24; Check the low end of the CEB range.
25define i64 @f2(i64 %a, i64 %b, float %f1, float *%ptr) {
26; CHECK-LABEL: f2:
27; CHECK: ceb %f0, 0(%r4)
28; CHECK-SCALAR-NEXT: ber %r14
29; CHECK-SCALAR: lgr %r2, %r3
30; CHECK-VECTOR-NEXT: locgrne %r2, %r3
31; CHECK: br %r14
32  %f2 = load float, float *%ptr
33  %cond = fcmp oeq float %f1, %f2
34  %res = select i1 %cond, i64 %a, i64 %b
35  ret i64 %res
36}
37
38; Check the high end of the aligned CEB range.
39define i64 @f3(i64 %a, i64 %b, float %f1, float *%base) {
40; CHECK-LABEL: f3:
41; CHECK: ceb %f0, 4092(%r4)
42; CHECK-SCALAR-NEXT: ber %r14
43; CHECK-SCALAR: lgr %r2, %r3
44; CHECK-VECTOR-NEXT: locgrne %r2, %r3
45; CHECK: br %r14
46  %ptr = getelementptr float, float *%base, i64 1023
47  %f2 = load float, float *%ptr
48  %cond = fcmp oeq float %f1, %f2
49  %res = select i1 %cond, i64 %a, i64 %b
50  ret i64 %res
51}
52
53; Check the next word up, which needs separate address logic.
54; Other sequences besides this one would be OK.
55define i64 @f4(i64 %a, i64 %b, float %f1, float *%base) {
56; CHECK-LABEL: f4:
57; CHECK: aghi %r4, 4096
58; CHECK: ceb %f0, 0(%r4)
59; CHECK-SCALAR-NEXT: ber %r14
60; CHECK-SCALAR: lgr %r2, %r3
61; CHECK-VECTOR-NEXT: locgrne %r2, %r3
62; CHECK: br %r14
63  %ptr = getelementptr float, float *%base, i64 1024
64  %f2 = load float, float *%ptr
65  %cond = fcmp oeq float %f1, %f2
66  %res = select i1 %cond, i64 %a, i64 %b
67  ret i64 %res
68}
69
70; Check negative displacements, which also need separate address logic.
71define i64 @f5(i64 %a, i64 %b, float %f1, float *%base) {
72; CHECK-LABEL: f5:
73; CHECK: aghi %r4, -4
74; CHECK: ceb %f0, 0(%r4)
75; CHECK-SCALAR-NEXT: ber %r14
76; CHECK-SCALAR: lgr %r2, %r3
77; CHECK-VECTOR-NEXT: locgrne %r2, %r3
78; CHECK: br %r14
79  %ptr = getelementptr float, float *%base, i64 -1
80  %f2 = load float, float *%ptr
81  %cond = fcmp oeq float %f1, %f2
82  %res = select i1 %cond, i64 %a, i64 %b
83  ret i64 %res
84}
85
86; Check that CEB allows indices.
87define i64 @f6(i64 %a, i64 %b, float %f1, float *%base, i64 %index) {
88; CHECK-LABEL: f6:
89; CHECK: sllg %r1, %r5, 2
90; CHECK: ceb %f0, 400(%r1,%r4)
91; CHECK-SCALAR-NEXT: ber %r14
92; CHECK-SCALAR: lgr %r2, %r3
93; CHECK-VECTOR-NEXT: locgrne %r2, %r3
94; CHECK: br %r14
95  %ptr1 = getelementptr float, float *%base, i64 %index
96  %ptr2 = getelementptr float, float *%ptr1, i64 100
97  %f2 = load float, float *%ptr2
98  %cond = fcmp oeq float %f1, %f2
99  %res = select i1 %cond, i64 %a, i64 %b
100  ret i64 %res
101}
102
103; Check that comparisons of spilled values can use CEB rather than CEBR.
104define float @f7(float *%ptr0) {
105; CHECK-LABEL: f7:
106; CHECK: brasl %r14, foo@PLT
107; CHECK-SCALAR: ceb {{%f[0-9]+}}, 16{{[04]}}(%r15)
108; CHECK: br %r14
109  %ptr1 = getelementptr float, float *%ptr0, i64 2
110  %ptr2 = getelementptr float, float *%ptr0, i64 4
111  %ptr3 = getelementptr float, float *%ptr0, i64 6
112  %ptr4 = getelementptr float, float *%ptr0, i64 8
113  %ptr5 = getelementptr float, float *%ptr0, i64 10
114  %ptr6 = getelementptr float, float *%ptr0, i64 12
115  %ptr7 = getelementptr float, float *%ptr0, i64 14
116  %ptr8 = getelementptr float, float *%ptr0, i64 16
117  %ptr9 = getelementptr float, float *%ptr0, i64 18
118  %ptr10 = getelementptr float, float *%ptr0, i64 20
119
120  %val0 = load float, float *%ptr0
121  %val1 = load float, float *%ptr1
122  %val2 = load float, float *%ptr2
123  %val3 = load float, float *%ptr3
124  %val4 = load float, float *%ptr4
125  %val5 = load float, float *%ptr5
126  %val6 = load float, float *%ptr6
127  %val7 = load float, float *%ptr7
128  %val8 = load float, float *%ptr8
129  %val9 = load float, float *%ptr9
130  %val10 = load float, float *%ptr10
131
132  %ret = call float @foo()
133
134  %cmp0 = fcmp olt float %ret, %val0
135  %cmp1 = fcmp olt float %ret, %val1
136  %cmp2 = fcmp olt float %ret, %val2
137  %cmp3 = fcmp olt float %ret, %val3
138  %cmp4 = fcmp olt float %ret, %val4
139  %cmp5 = fcmp olt float %ret, %val5
140  %cmp6 = fcmp olt float %ret, %val6
141  %cmp7 = fcmp olt float %ret, %val7
142  %cmp8 = fcmp olt float %ret, %val8
143  %cmp9 = fcmp olt float %ret, %val9
144  %cmp10 = fcmp olt float %ret, %val10
145
146  %sel0 = select i1 %cmp0, float %ret, float 0.0
147  %sel1 = select i1 %cmp1, float %sel0, float 1.0
148  %sel2 = select i1 %cmp2, float %sel1, float 2.0
149  %sel3 = select i1 %cmp3, float %sel2, float 3.0
150  %sel4 = select i1 %cmp4, float %sel3, float 4.0
151  %sel5 = select i1 %cmp5, float %sel4, float 5.0
152  %sel6 = select i1 %cmp6, float %sel5, float 6.0
153  %sel7 = select i1 %cmp7, float %sel6, float 7.0
154  %sel8 = select i1 %cmp8, float %sel7, float 8.0
155  %sel9 = select i1 %cmp9, float %sel8, float 9.0
156  %sel10 = select i1 %cmp10, float %sel9, float 10.0
157
158  ret float %sel10
159}
160
161; Check comparison with zero.
162define i64 @f8(i64 %a, i64 %b, float %f) {
163; CHECK-LABEL: f8:
164; CHECK: ltebr %f0, %f0
165; CHECK-SCALAR-NEXT: ber %r14
166; CHECK-SCALAR: lgr %r2, %r3
167; CHECK-VECTOR-NEXT: locgrne %r2, %r3
168; CHECK: br %r14
169  %cond = fcmp oeq float %f, 0.0
170  %res = select i1 %cond, i64 %a, i64 %b
171  ret i64 %res
172}
173
174; Check the comparison can be reversed if that allows CEB to be used,
175; first with oeq.
176define i64 @f9(i64 %a, i64 %b, float %f2, float *%ptr) {
177; CHECK-LABEL: f9:
178; CHECK: ceb %f0, 0(%r4)
179; CHECK-SCALAR-NEXT: ber %r14
180; CHECK-SCALAR: lgr %r2, %r3
181; CHECK-VECTOR-NEXT: locgrne %r2, %r3
182; CHECK: br %r14
183  %f1 = load float, float *%ptr
184  %cond = fcmp oeq float %f1, %f2
185  %res = select i1 %cond, i64 %a, i64 %b
186  ret i64 %res
187}
188
189; ...then one.
190define i64 @f10(i64 %a, i64 %b, float %f2, float *%ptr) {
191; CHECK-LABEL: f10:
192; CHECK: ceb %f0, 0(%r4)
193; CHECK-SCALAR-NEXT: blhr %r14
194; CHECK-SCALAR: lgr %r2, %r3
195; CHECK-VECTOR-NEXT: locgrnlh %r2, %r3
196; CHECK: br %r14
197  %f1 = load float, float *%ptr
198  %cond = fcmp one float %f1, %f2
199  %res = select i1 %cond, i64 %a, i64 %b
200  ret i64 %res
201}
202
203; ...then olt.
204define i64 @f11(i64 %a, i64 %b, float %f2, float *%ptr) {
205; CHECK-LABEL: f11:
206; CHECK: ceb %f0, 0(%r4)
207; CHECK-SCALAR-NEXT: bhr %r14
208; CHECK-SCALAR: lgr %r2, %r3
209; CHECK-VECTOR-NEXT: locgrnh %r2, %r3
210; CHECK: br %r14
211  %f1 = load float, float *%ptr
212  %cond = fcmp olt float %f1, %f2
213  %res = select i1 %cond, i64 %a, i64 %b
214  ret i64 %res
215}
216
217; ...then ole.
218define i64 @f12(i64 %a, i64 %b, float %f2, float *%ptr) {
219; CHECK-LABEL: f12:
220; CHECK: ceb %f0, 0(%r4)
221; CHECK-SCALAR-NEXT: bher %r14
222; CHECK-SCALAR: lgr %r2, %r3
223; CHECK-VECTOR-NEXT: locgrnhe %r2, %r3
224; CHECK: br %r14
225  %f1 = load float, float *%ptr
226  %cond = fcmp ole float %f1, %f2
227  %res = select i1 %cond, i64 %a, i64 %b
228  ret i64 %res
229}
230
231; ...then oge.
232define i64 @f13(i64 %a, i64 %b, float %f2, float *%ptr) {
233; CHECK-LABEL: f13:
234; CHECK: ceb %f0, 0(%r4)
235; CHECK-SCALAR-NEXT: bler %r14
236; CHECK-SCALAR: lgr %r2, %r3
237; CHECK-VECTOR-NEXT: locgrnle %r2, %r3
238; CHECK: br %r14
239  %f1 = load float, float *%ptr
240  %cond = fcmp oge float %f1, %f2
241  %res = select i1 %cond, i64 %a, i64 %b
242  ret i64 %res
243}
244
245; ...then ogt.
246define i64 @f14(i64 %a, i64 %b, float %f2, float *%ptr) {
247; CHECK-LABEL: f14:
248; CHECK: ceb %f0, 0(%r4)
249; CHECK-SCALAR-NEXT: blr %r14
250; CHECK-SCALAR: lgr %r2, %r3
251; CHECK-VECTOR-NEXT: locgrnl %r2, %r3
252; CHECK: br %r14
253  %f1 = load float, float *%ptr
254  %cond = fcmp ogt float %f1, %f2
255  %res = select i1 %cond, i64 %a, i64 %b
256  ret i64 %res
257}
258
259; ...then ueq.
260define i64 @f15(i64 %a, i64 %b, float %f2, float *%ptr) {
261; CHECK-LABEL: f15:
262; CHECK: ceb %f0, 0(%r4)
263; CHECK-SCALAR-NEXT: bnlhr %r14
264; CHECK-SCALAR: lgr %r2, %r3
265; CHECK-VECTOR-NEXT: locgrlh %r2, %r3
266; CHECK: br %r14
267  %f1 = load float, float *%ptr
268  %cond = fcmp ueq float %f1, %f2
269  %res = select i1 %cond, i64 %a, i64 %b
270  ret i64 %res
271}
272
273; ...then une.
274define i64 @f16(i64 %a, i64 %b, float %f2, float *%ptr) {
275; CHECK-LABEL: f16:
276; CHECK: ceb %f0, 0(%r4)
277; CHECK-SCALAR-NEXT: bner %r14
278; CHECK-SCALAR: lgr %r2, %r3
279; CHECK-VECTOR-NEXT: locgre %r2, %r3
280; CHECK: br %r14
281  %f1 = load float, float *%ptr
282  %cond = fcmp une float %f1, %f2
283  %res = select i1 %cond, i64 %a, i64 %b
284  ret i64 %res
285}
286
287; ...then ult.
288define i64 @f17(i64 %a, i64 %b, float %f2, float *%ptr) {
289; CHECK-LABEL: f17:
290; CHECK: ceb %f0, 0(%r4)
291; CHECK-SCALAR-NEXT: bnler %r14
292; CHECK-SCALAR: lgr %r2, %r3
293; CHECK-VECTOR-NEXT: locgrle %r2, %r3
294; CHECK: br %r14
295  %f1 = load float, float *%ptr
296  %cond = fcmp ult float %f1, %f2
297  %res = select i1 %cond, i64 %a, i64 %b
298  ret i64 %res
299}
300
301; ...then ule.
302define i64 @f18(i64 %a, i64 %b, float %f2, float *%ptr) {
303; CHECK-LABEL: f18:
304; CHECK: ceb %f0, 0(%r4)
305; CHECK-SCALAR-NEXT: bnlr %r14
306; CHECK-SCALAR: lgr %r2, %r3
307; CHECK-VECTOR-NEXT: locgrl %r2, %r3
308; CHECK: br %r14
309  %f1 = load float, float *%ptr
310  %cond = fcmp ule float %f1, %f2
311  %res = select i1 %cond, i64 %a, i64 %b
312  ret i64 %res
313}
314
315; ...then uge.
316define i64 @f19(i64 %a, i64 %b, float %f2, float *%ptr) {
317; CHECK-LABEL: f19:
318; CHECK: ceb %f0, 0(%r4)
319; CHECK-SCALAR-NEXT: bnhr %r14
320; CHECK-SCALAR: lgr %r2, %r3
321; CHECK-VECTOR-NEXT: locgrh %r2, %r3
322; CHECK: br %r14
323  %f1 = load float, float *%ptr
324  %cond = fcmp uge float %f1, %f2
325  %res = select i1 %cond, i64 %a, i64 %b
326  ret i64 %res
327}
328
329; ...then ugt.
330define i64 @f20(i64 %a, i64 %b, float %f2, float *%ptr) {
331; CHECK-LABEL: f20:
332; CHECK: ceb %f0, 0(%r4)
333; CHECK-SCALAR-NEXT: bnher %r14
334; CHECK-SCALAR: lgr %r2, %r3
335; CHECK-VECTOR-NEXT: locgrhe %r2, %r3
336; CHECK: br %r14
337  %f1 = load float, float *%ptr
338  %cond = fcmp ugt float %f1, %f2
339  %res = select i1 %cond, i64 %a, i64 %b
340  ret i64 %res
341}
342