1; Test strict f32 and v4f32 comparisons on z14.
2;
3; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z14 | FileCheck %s
4
5; Test oeq.
6define <4 x i32> @f1(<4 x i32> %dummy, <4 x float> %val1, <4 x float> %val2) #0 {
7; CHECK-LABEL: f1:
8; CHECK: vfcesb %v24, %v26, %v28
9; CHECK-NEXT: br %r14
10  %cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
11                                               <4 x float> %val1, <4 x float> %val2,
12                                               metadata !"oeq",
13                                               metadata !"fpexcept.strict") #0
14  %ret = sext <4 x i1> %cmp to <4 x i32>
15  ret <4 x i32> %ret
16}
17
18; Test one.
19define <4 x i32> @f2(<4 x i32> %dummy, <4 x float> %val1, <4 x float> %val2) #0 {
20; CHECK-LABEL: f2:
21; CHECK-DAG: vfchsb [[REG1:%v[0-9]+]], %v28, %v26
22; CHECK-DAG: vfchsb [[REG2:%v[0-9]+]], %v26, %v28
23; CHECK: vo %v24, [[REG1]], [[REG2]]
24; CHECK-NEXT: br %r14
25  %cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
26                                               <4 x float> %val1, <4 x float> %val2,
27                                               metadata !"one",
28                                               metadata !"fpexcept.strict") #0
29  %ret = sext <4 x i1> %cmp to <4 x i32>
30  ret <4 x i32> %ret
31}
32
33; Test ogt.
34define <4 x i32> @f3(<4 x i32> %dummy, <4 x float> %val1, <4 x float> %val2) #0 {
35; CHECK-LABEL: f3:
36; CHECK: vfchsb %v24, %v26, %v28
37; CHECK-NEXT: br %r14
38  %cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
39                                               <4 x float> %val1, <4 x float> %val2,
40                                               metadata !"ogt",
41                                               metadata !"fpexcept.strict") #0
42  %ret = sext <4 x i1> %cmp to <4 x i32>
43  ret <4 x i32> %ret
44}
45
46; Test oge.
47define <4 x i32> @f4(<4 x i32> %dummy, <4 x float> %val1, <4 x float> %val2) #0 {
48; CHECK-LABEL: f4:
49; CHECK: vfchesb %v24, %v26, %v28
50; CHECK-NEXT: br %r14
51  %cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
52                                               <4 x float> %val1, <4 x float> %val2,
53                                               metadata !"oge",
54                                               metadata !"fpexcept.strict") #0
55  %ret = sext <4 x i1> %cmp to <4 x i32>
56  ret <4 x i32> %ret
57}
58
59; Test ole.
60define <4 x i32> @f5(<4 x i32> %dummy, <4 x float> %val1, <4 x float> %val2) #0 {
61; CHECK-LABEL: f5:
62; CHECK: vfchesb %v24, %v28, %v26
63; CHECK-NEXT: br %r14
64  %cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
65                                               <4 x float> %val1, <4 x float> %val2,
66                                               metadata !"ole",
67                                               metadata !"fpexcept.strict") #0
68  %ret = sext <4 x i1> %cmp to <4 x i32>
69  ret <4 x i32> %ret
70}
71
72; Test olt.
73define <4 x i32> @f6(<4 x i32> %dummy, <4 x float> %val1, <4 x float> %val2) #0 {
74; CHECK-LABEL: f6:
75; CHECK: vfchsb %v24, %v28, %v26
76; CHECK-NEXT: br %r14
77  %cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
78                                               <4 x float> %val1, <4 x float> %val2,
79                                               metadata !"olt",
80                                               metadata !"fpexcept.strict") #0
81  %ret = sext <4 x i1> %cmp to <4 x i32>
82  ret <4 x i32> %ret
83}
84
85; Test ueq.
86define <4 x i32> @f7(<4 x i32> %dummy, <4 x float> %val1, <4 x float> %val2) #0 {
87; CHECK-LABEL: f7:
88; CHECK-DAG: vfchsb [[REG1:%v[0-9]+]], %v28, %v26
89; CHECK-DAG: vfchsb [[REG2:%v[0-9]+]], %v26, %v28
90; CHECK: vno %v24, [[REG1]], [[REG2]]
91; CHECK-NEXT: br %r14
92  %cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
93                                               <4 x float> %val1, <4 x float> %val2,
94                                               metadata !"ueq",
95                                               metadata !"fpexcept.strict") #0
96  %ret = sext <4 x i1> %cmp to <4 x i32>
97  ret <4 x i32> %ret
98}
99
100; Test une.
101define <4 x i32> @f8(<4 x i32> %dummy, <4 x float> %val1, <4 x float> %val2) #0 {
102; CHECK-LABEL: f8:
103; CHECK: vfcesb [[REG:%v[0-9]+]], %v26, %v28
104; CHECK-NEXT: vno %v24, [[REG]], [[REG]]
105; CHECK-NEXT: br %r14
106  %cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
107                                               <4 x float> %val1, <4 x float> %val2,
108                                               metadata !"une",
109                                               metadata !"fpexcept.strict") #0
110  %ret = sext <4 x i1> %cmp to <4 x i32>
111  ret <4 x i32> %ret
112}
113
114; Test ugt.
115define <4 x i32> @f9(<4 x i32> %dummy, <4 x float> %val1, <4 x float> %val2) #0 {
116; CHECK-LABEL: f9:
117; CHECK: vfchesb [[REG:%v[0-9]+]], %v28, %v26
118; CHECK-NEXT: vno %v24, [[REG]], [[REG]]
119; CHECK-NEXT: br %r14
120  %cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
121                                               <4 x float> %val1, <4 x float> %val2,
122                                               metadata !"ugt",
123                                               metadata !"fpexcept.strict") #0
124  %ret = sext <4 x i1> %cmp to <4 x i32>
125  ret <4 x i32> %ret
126}
127
128; Test uge.
129define <4 x i32> @f10(<4 x i32> %dummy, <4 x float> %val1,
130                      <4 x float> %val2) #0 {
131; CHECK-LABEL: f10:
132; CHECK: vfchsb [[REG:%v[0-9]+]], %v28, %v26
133; CHECK-NEXT: vno %v24, [[REG]], [[REG]]
134; CHECK-NEXT: br %r14
135  %cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
136                                               <4 x float> %val1, <4 x float> %val2,
137                                               metadata !"uge",
138                                               metadata !"fpexcept.strict") #0
139  %ret = sext <4 x i1> %cmp to <4 x i32>
140  ret <4 x i32> %ret
141}
142
143; Test ule.
144define <4 x i32> @f11(<4 x i32> %dummy, <4 x float> %val1,
145                      <4 x float> %val2) #0 {
146; CHECK-LABEL: f11:
147; CHECK: vfchsb [[REG:%v[0-9]+]], %v26, %v28
148; CHECK-NEXT: vno %v24, [[REG]], [[REG]]
149; CHECK-NEXT: br %r14
150  %cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
151                                               <4 x float> %val1, <4 x float> %val2,
152                                               metadata !"ule",
153                                               metadata !"fpexcept.strict") #0
154  %ret = sext <4 x i1> %cmp to <4 x i32>
155  ret <4 x i32> %ret
156}
157
158; Test ult.
159define <4 x i32> @f12(<4 x i32> %dummy, <4 x float> %val1,
160                      <4 x float> %val2) #0 {
161; CHECK-LABEL: f12:
162; CHECK: vfchesb [[REG:%v[0-9]+]], %v26, %v28
163; CHECK-NEXT: vno %v24, [[REG]], [[REG]]
164; CHECK-NEXT: br %r14
165  %cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
166                                               <4 x float> %val1, <4 x float> %val2,
167                                               metadata !"ult",
168                                               metadata !"fpexcept.strict") #0
169  %ret = sext <4 x i1> %cmp to <4 x i32>
170  ret <4 x i32> %ret
171}
172
173; Test ord.
174define <4 x i32> @f13(<4 x i32> %dummy, <4 x float> %val1,
175                      <4 x float> %val2) #0 {
176; CHECK-LABEL: f13:
177; CHECK-DAG: vfchsb [[REG1:%v[0-9]+]], %v28, %v26
178; CHECK-DAG: vfchesb [[REG2:%v[0-9]+]], %v26, %v28
179; CHECK: vo %v24, [[REG1]], [[REG2]]
180; CHECK-NEXT: br %r14
181  %cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
182                                               <4 x float> %val1, <4 x float> %val2,
183                                               metadata !"ord",
184                                               metadata !"fpexcept.strict") #0
185  %ret = sext <4 x i1> %cmp to <4 x i32>
186  ret <4 x i32> %ret
187}
188
189; Test uno.
190define <4 x i32> @f14(<4 x i32> %dummy, <4 x float> %val1,
191                      <4 x float> %val2) #0 {
192; CHECK-LABEL: f14:
193; CHECK-DAG: vfchsb [[REG1:%v[0-9]+]], %v28, %v26
194; CHECK-DAG: vfchesb [[REG2:%v[0-9]+]], %v26, %v28
195; CHECK: vno %v24, [[REG1]], [[REG2]]
196; CHECK-NEXT: br %r14
197  %cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
198                                               <4 x float> %val1, <4 x float> %val2,
199                                               metadata !"uno",
200                                               metadata !"fpexcept.strict") #0
201  %ret = sext <4 x i1> %cmp to <4 x i32>
202  ret <4 x i32> %ret
203}
204
205; Test oeq selects.
206define <4 x float> @f15(<4 x float> %val1, <4 x float> %val2,
207                        <4 x float> %val3, <4 x float> %val4) #0 {
208; CHECK-LABEL: f15:
209; CHECK: vfcesb [[REG:%v[0-9]+]], %v24, %v26
210; CHECK-NEXT: vsel %v24, %v28, %v30, [[REG]]
211; CHECK-NEXT: br %r14
212  %cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
213                                               <4 x float> %val1, <4 x float> %val2,
214                                               metadata !"oeq",
215                                               metadata !"fpexcept.strict") #0
216  %ret = select <4 x i1> %cmp, <4 x float> %val3, <4 x float> %val4
217  ret <4 x float> %ret
218}
219
220; Test one selects.
221define <4 x float> @f16(<4 x float> %val1, <4 x float> %val2,
222                        <4 x float> %val3, <4 x float> %val4) #0 {
223; CHECK-LABEL: f16:
224; CHECK-DAG: vfchsb [[REG1:%v[0-9]+]], %v26, %v24
225; CHECK-DAG: vfchsb [[REG2:%v[0-9]+]], %v24, %v26
226; CHECK: vo [[REG:%v[0-9]+]], [[REG1]], [[REG2]]
227; CHECK-NEXT: vsel %v24, %v28, %v30, [[REG]]
228; CHECK-NEXT: br %r14
229  %cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
230                                               <4 x float> %val1, <4 x float> %val2,
231                                               metadata !"one",
232                                               metadata !"fpexcept.strict") #0
233  %ret = select <4 x i1> %cmp, <4 x float> %val3, <4 x float> %val4
234  ret <4 x float> %ret
235}
236
237; Test ogt selects.
238define <4 x float> @f17(<4 x float> %val1, <4 x float> %val2,
239                        <4 x float> %val3, <4 x float> %val4) #0 {
240; CHECK-LABEL: f17:
241; CHECK: vfchsb [[REG:%v[0-9]+]], %v24, %v26
242; CHECK-NEXT: vsel %v24, %v28, %v30, [[REG]]
243; CHECK-NEXT: br %r14
244  %cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
245                                               <4 x float> %val1, <4 x float> %val2,
246                                               metadata !"ogt",
247                                               metadata !"fpexcept.strict") #0
248  %ret = select <4 x i1> %cmp, <4 x float> %val3, <4 x float> %val4
249  ret <4 x float> %ret
250}
251
252; Test oge selects.
253define <4 x float> @f18(<4 x float> %val1, <4 x float> %val2,
254                        <4 x float> %val3, <4 x float> %val4) #0 {
255; CHECK-LABEL: f18:
256; CHECK: vfchesb [[REG:%v[0-9]+]], %v24, %v26
257; CHECK-NEXT: vsel %v24, %v28, %v30, [[REG]]
258; CHECK-NEXT: br %r14
259  %cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
260                                               <4 x float> %val1, <4 x float> %val2,
261                                               metadata !"oge",
262                                               metadata !"fpexcept.strict") #0
263  %ret = select <4 x i1> %cmp, <4 x float> %val3, <4 x float> %val4
264  ret <4 x float> %ret
265}
266
267; Test ole selects.
268define <4 x float> @f19(<4 x float> %val1, <4 x float> %val2,
269                        <4 x float> %val3, <4 x float> %val4) #0 {
270; CHECK-LABEL: f19:
271; CHECK: vfchesb [[REG:%v[0-9]+]], %v26, %v24
272; CHECK-NEXT: vsel %v24, %v28, %v30, [[REG]]
273; CHECK-NEXT: br %r14
274  %cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
275                                               <4 x float> %val1, <4 x float> %val2,
276                                               metadata !"ole",
277                                               metadata !"fpexcept.strict") #0
278  %ret = select <4 x i1> %cmp, <4 x float> %val3, <4 x float> %val4
279  ret <4 x float> %ret
280}
281
282; Test olt selects.
283define <4 x float> @f20(<4 x float> %val1, <4 x float> %val2,
284                        <4 x float> %val3, <4 x float> %val4) #0 {
285; CHECK-LABEL: f20:
286; CHECK: vfchsb [[REG:%v[0-9]+]], %v26, %v24
287; CHECK-NEXT: vsel %v24, %v28, %v30, [[REG]]
288; CHECK-NEXT: br %r14
289  %cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
290                                               <4 x float> %val1, <4 x float> %val2,
291                                               metadata !"olt",
292                                               metadata !"fpexcept.strict") #0
293  %ret = select <4 x i1> %cmp, <4 x float> %val3, <4 x float> %val4
294  ret <4 x float> %ret
295}
296
297; Test ueq selects.
298define <4 x float> @f21(<4 x float> %val1, <4 x float> %val2,
299                        <4 x float> %val3, <4 x float> %val4) #0 {
300; CHECK-LABEL: f21:
301; CHECK-DAG: vfchsb [[REG1:%v[0-9]+]], %v26, %v24
302; CHECK-DAG: vfchsb [[REG2:%v[0-9]+]], %v24, %v26
303; CHECK: vo [[REG:%v[0-9]+]], [[REG1]], [[REG2]]
304; CHECK-NEXT: vsel %v24, %v30, %v28, [[REG]]
305; CHECK-NEXT: br %r14
306  %cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
307                                               <4 x float> %val1, <4 x float> %val2,
308                                               metadata !"ueq",
309                                               metadata !"fpexcept.strict") #0
310  %ret = select <4 x i1> %cmp, <4 x float> %val3, <4 x float> %val4
311  ret <4 x float> %ret
312}
313
314; Test une selects.
315define <4 x float> @f22(<4 x float> %val1, <4 x float> %val2,
316                        <4 x float> %val3, <4 x float> %val4) #0 {
317; CHECK-LABEL: f22:
318; CHECK: vfcesb [[REG:%v[0-9]+]], %v24, %v26
319; CHECK-NEXT: vsel %v24, %v30, %v28, [[REG]]
320; CHECK-NEXT: br %r14
321  %cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
322                                               <4 x float> %val1, <4 x float> %val2,
323                                               metadata !"une",
324                                               metadata !"fpexcept.strict") #0
325  %ret = select <4 x i1> %cmp, <4 x float> %val3, <4 x float> %val4
326  ret <4 x float> %ret
327}
328
329; Test ugt selects.
330define <4 x float> @f23(<4 x float> %val1, <4 x float> %val2,
331                        <4 x float> %val3, <4 x float> %val4) #0 {
332; CHECK-LABEL: f23:
333; CHECK: vfchesb [[REG:%v[0-9]+]], %v26, %v24
334; CHECK-NEXT: vsel %v24, %v30, %v28, [[REG]]
335; CHECK-NEXT: br %r14
336  %cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
337                                               <4 x float> %val1, <4 x float> %val2,
338                                               metadata !"ugt",
339                                               metadata !"fpexcept.strict") #0
340  %ret = select <4 x i1> %cmp, <4 x float> %val3, <4 x float> %val4
341  ret <4 x float> %ret
342}
343
344; Test uge selects.
345define <4 x float> @f24(<4 x float> %val1, <4 x float> %val2,
346                        <4 x float> %val3, <4 x float> %val4) #0 {
347; CHECK-LABEL: f24:
348; CHECK: vfchsb [[REG:%v[0-9]+]], %v26, %v24
349; CHECK-NEXT: vsel %v24, %v30, %v28, [[REG]]
350; CHECK-NEXT: br %r14
351  %cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
352                                               <4 x float> %val1, <4 x float> %val2,
353                                               metadata !"uge",
354                                               metadata !"fpexcept.strict") #0
355  %ret = select <4 x i1> %cmp, <4 x float> %val3, <4 x float> %val4
356  ret <4 x float> %ret
357}
358
359; Test ule selects.
360define <4 x float> @f25(<4 x float> %val1, <4 x float> %val2,
361                        <4 x float> %val3, <4 x float> %val4) #0 {
362; CHECK-LABEL: f25:
363; CHECK: vfchsb [[REG:%v[0-9]+]], %v24, %v26
364; CHECK-NEXT: vsel %v24, %v30, %v28, [[REG]]
365; CHECK-NEXT: br %r14
366  %cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
367                                               <4 x float> %val1, <4 x float> %val2,
368                                               metadata !"ule",
369                                               metadata !"fpexcept.strict") #0
370  %ret = select <4 x i1> %cmp, <4 x float> %val3, <4 x float> %val4
371  ret <4 x float> %ret
372}
373
374; Test ult selects.
375define <4 x float> @f26(<4 x float> %val1, <4 x float> %val2,
376                        <4 x float> %val3, <4 x float> %val4) #0 {
377; CHECK-LABEL: f26:
378; CHECK: vfchesb [[REG:%v[0-9]+]], %v24, %v26
379; CHECK-NEXT: vsel %v24, %v30, %v28, [[REG]]
380; CHECK-NEXT: br %r14
381  %cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
382                                               <4 x float> %val1, <4 x float> %val2,
383                                               metadata !"ult",
384                                               metadata !"fpexcept.strict") #0
385  %ret = select <4 x i1> %cmp, <4 x float> %val3, <4 x float> %val4
386  ret <4 x float> %ret
387}
388
389; Test ord selects.
390define <4 x float> @f27(<4 x float> %val1, <4 x float> %val2,
391                        <4 x float> %val3, <4 x float> %val4) #0 {
392; CHECK-LABEL: f27:
393; CHECK-DAG: vfchsb [[REG1:%v[0-9]+]], %v26, %v24
394; CHECK-DAG: vfchesb [[REG2:%v[0-9]+]], %v24, %v26
395; CHECK: vo [[REG:%v[0-9]+]], [[REG1]], [[REG2]]
396; CHECK-NEXT: vsel %v24, %v28, %v30, [[REG]]
397; CHECK-NEXT: br %r14
398  %cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
399                                               <4 x float> %val1, <4 x float> %val2,
400                                               metadata !"ord",
401                                               metadata !"fpexcept.strict") #0
402  %ret = select <4 x i1> %cmp, <4 x float> %val3, <4 x float> %val4
403  ret <4 x float> %ret
404}
405
406; Test uno selects.
407define <4 x float> @f28(<4 x float> %val1, <4 x float> %val2,
408                        <4 x float> %val3, <4 x float> %val4) #0 {
409; CHECK-LABEL: f28:
410; CHECK-DAG: vfchsb [[REG1:%v[0-9]+]], %v26, %v24
411; CHECK-DAG: vfchesb [[REG2:%v[0-9]+]], %v24, %v26
412; CHECK: vo [[REG:%v[0-9]+]], [[REG1]], [[REG2]]
413; CHECK-NEXT: vsel %v24, %v30, %v28, [[REG]]
414; CHECK-NEXT: br %r14
415  %cmp = call <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(
416                                               <4 x float> %val1, <4 x float> %val2,
417                                               metadata !"uno",
418                                               metadata !"fpexcept.strict") #0
419  %ret = select <4 x i1> %cmp, <4 x float> %val3, <4 x float> %val4
420  ret <4 x float> %ret
421}
422
423; Test an f32 comparison that uses vector registers.
424define i64 @f29(i64 %a, i64 %b, float %f1, <4 x float> %vec) #0 {
425; CHECK-LABEL: f29:
426; CHECK: wfcsb %f0, %v24
427; CHECK-NEXT: locgrne %r2, %r3
428; CHECK: br %r14
429  %f2 = extractelement <4 x float> %vec, i32 0
430  %cond = call i1 @llvm.experimental.constrained.fcmp.f32(
431                                               float %f1, float %f2,
432                                               metadata !"oeq",
433                                               metadata !"fpexcept.strict") #0
434  %res = select i1 %cond, i64 %a, i64 %b
435  ret i64 %res
436}
437
438attributes #0 = { strictfp }
439
440declare <4 x i1> @llvm.experimental.constrained.fcmp.v4f32(<4 x float>, <4 x float>, metadata, metadata)
441declare i1 @llvm.experimental.constrained.fcmp.f32(float, float, metadata, metadata)
442
443