[X86] combineTargetShuffle - commute VPERMV3 shuffles so any load is on the RHS
[llvm-project.git] / llvm / test / CodeGen / SystemZ / fp-cmp-04.ll
blobc1773abe92305d2cb46492146e37e18855f341a7
1 ; Test that floating-point compares are omitted if CC already has the
2 ; right value.
4 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 -no-integrated-as | FileCheck %s
6 declare float @llvm.fabs.f32(float %f)
8 ; Test addition followed by EQ, which can use the CC result of the addition.
9 define float @f1(float %a, float %b, ptr %dest) {
10 ; CHECK-LABEL: f1:
11 ; CHECK: aebr %f0, %f2
12 ; CHECK-NEXT: ber %r14
13 ; CHECK: br %r14
14 entry:
15   %res = fadd float %a, %b
16   %cmp = fcmp oeq float %res, 0.0
17   br i1 %cmp, label %exit, label %store
19 store:
20   store float %b, ptr %dest
21   br label %exit
23 exit:
24   ret float %res
27 ; ...and again with LT.
28 define float @f2(float %a, float %b, ptr %dest) {
29 ; CHECK-LABEL: f2:
30 ; CHECK: aebr %f0, %f2
31 ; CHECK-NEXT: blr %r14
32 ; CHECK: br %r14
33 entry:
34   %res = fadd float %a, %b
35   %cmp = fcmp olt float %res, 0.0
36   br i1 %cmp, label %exit, label %store
38 store:
39   store float %b, ptr %dest
40   br label %exit
42 exit:
43   ret float %res
46 ; ...and again with GT.
47 define float @f3(float %a, float %b, ptr %dest) {
48 ; CHECK-LABEL: f3:
49 ; CHECK: aebr %f0, %f2
50 ; CHECK-NEXT: bhr %r14
51 ; CHECK: br %r14
52 entry:
53   %res = fadd float %a, %b
54   %cmp = fcmp ogt float %res, 0.0
55   br i1 %cmp, label %exit, label %store
57 store:
58   store float %b, ptr %dest
59   br label %exit
61 exit:
62   ret float %res
65 ; ...and again with UEQ.
66 define float @f4(float %a, float %b, ptr %dest) {
67 ; CHECK-LABEL: f4:
68 ; CHECK: aebr %f0, %f2
69 ; CHECK-NEXT: bnlhr %r14
70 ; CHECK: br %r14
71 entry:
72   %res = fadd float %a, %b
73   %cmp = fcmp ueq float %res, 0.0
74   br i1 %cmp, label %exit, label %store
76 store:
77   store float %b, ptr %dest
78   br label %exit
80 exit:
81   ret float %res
84 ; Subtraction also provides a zero-based CC value.
85 define float @f5(float %a, float %b, ptr %dest) {
86 ; CHECK-LABEL: f5:
87 ; CHECK: seb %f0, 0(%r2)
88 ; CHECK-NEXT: bnher %r14
89 ; CHECK: br %r14
90 entry:
91   %cur = load float, ptr %dest
92   %res = fsub float %a, %cur
93   %cmp = fcmp ult float %res, 0.0
94   br i1 %cmp, label %exit, label %store
96 store:
97   store float %b, ptr %dest
98   br label %exit
100 exit:
101   ret float %res
104 ; Test the result of LOAD POSITIVE.
105 define float @f6(float %dummy, float %a, ptr %dest) {
106 ; CHECK-LABEL: f6:
107 ; CHECK: lpebr %f0, %f2
108 ; CHECK-NEXT: bhr %r14
109 ; CHECK: br %r14
110 entry:
111   %res = call float @llvm.fabs.f32(float %a)
112   %cmp = fcmp ogt float %res, 0.0
113   br i1 %cmp, label %exit, label %store
115 store:
116   store float %res, ptr %dest
117   br label %exit
119 exit:
120   ret float %res
123 ; Test the result of LOAD NEGATIVE.
124 define float @f7(float %dummy, float %a, ptr %dest) {
125 ; CHECK-LABEL: f7:
126 ; CHECK: lnebr %f0, %f2
127 ; CHECK-NEXT: blr %r14
128 ; CHECK: br %r14
129 entry:
130   %abs = call float @llvm.fabs.f32(float %a)
131   %res = fneg float %abs
132   %cmp = fcmp olt float %res, 0.0
133   br i1 %cmp, label %exit, label %store
135 store:
136   store float %res, ptr %dest
137   br label %exit
139 exit:
140   ret float %res
143 ; Test the result of LOAD COMPLEMENT.
144 define float @f8(float %dummy, float %a, ptr %dest) {
145 ; CHECK-LABEL: f8:
146 ; CHECK: lcebr %f0, %f2
147 ; CHECK-NEXT: bler %r14
148 ; CHECK: br %r14
149 entry:
150   %res = fneg float %a
151   %cmp = fcmp ole float %res, 0.0
152   br i1 %cmp, label %exit, label %store
154 store:
155   store float %res, ptr %dest
156   br label %exit
158 exit:
159   ret float %res
162 ; Multiplication (for example) does not modify CC.
163 define float @f9(float %a, float %b, ptr %dest) {
164 ; CHECK-LABEL: f9:
165 ; CHECK: meebr %f0, %f2
166 ; CHECK-NEXT: ltebr %f1, %f0
167 ; CHECK-NEXT: blhr %r14
168 ; CHECK: br %r14
169 entry:
170   %res = fmul float %a, %b
171   %cmp = fcmp one float %res, 0.0
172   br i1 %cmp, label %exit, label %store
174 store:
175   store float %b, ptr %dest
176   br label %exit
178 exit:
179   ret float %res
182 ; Test a combination involving a CC-setting instruction followed by
183 ; a non-CC-setting instruction.
184 define float @f10(float %a, float %b, float %c, ptr %dest) {
185 ; CHECK-LABEL: f10:
186 ; CHECK: aebr %f0, %f2
187 ; CHECK-NEXT: debr %f0, %f4
188 ; CHECK-NEXT: ltebr %f1, %f0
189 ; CHECK-NEXT: bner %r14
190 ; CHECK: br %r14
191 entry:
192   %add = fadd float %a, %b
193   %res = fdiv float %add, %c
194   %cmp = fcmp une float %res, 0.0
195   br i1 %cmp, label %exit, label %store
197 store:
198   store float %b, ptr %dest
199   br label %exit
201 exit:
202   ret float %res
205 ; Test a case where CC is set based on a different register from the
206 ; compare input.
207 define float @f11(float %a, float %b, float %c, ptr %dest1, ptr %dest2) {
208 ; CHECK-LABEL: f11:
209 ; CHECK: aebr %f0, %f2
210 ; CHECK-NEXT: sebr %f4, %f0
211 ; CHECK-DAG: ste %f4, 0(%r2)
212 ; CHECK-DAG: ltebr %f1, %f0
213 ; CHECK-NEXT: ber %r14
214 ; CHECK: br %r14
215 entry:
216   %add = fadd float %a, %b
217   %sub = fsub float %c, %add
218   store float %sub, ptr %dest1
219   %cmp = fcmp oeq float %add, 0.0
220   br i1 %cmp, label %exit, label %store
222 store:
223   store float %sub, ptr %dest2
224   br label %exit
226 exit:
227   ret float %add
230 ; %val in %f2 must be preserved during comparison and also copied to %f0.
231 define float @f12(float %dummy, float %val, ptr %dest) {
232 ; CHECK-LABEL: f12:
233 ; CHECK: ler %f0, %f2
234 ; CHECK-NEXT: ltebr %f1, %f2
235 ; CHECK-NEXT: #APP
236 ; CHECK-NEXT: blah %f0
237 ; CHECK-NEXT: #NO_APP
238 ; CHECK-NEXT: blr %r14
239 ; CHECK: br %r14
240 entry:
241   call void asm sideeffect "blah $0", "{f0}"(float %val)
242   %cmp = fcmp olt float %val, 0.0
243   br i1 %cmp, label %exit, label %store
245 store:
246   store float %val, ptr %dest
247   br label %exit
249 exit:
250   ret float %val
253 ; Same for double.
254 define double @f13(double %dummy, double %val, ptr %dest) {
255 ; CHECK-LABEL: f13:
256 ; CHECK: ldr %f0, %f2
257 ; CHECK-NEXT: ltdbr %f1, %f2
258 ; CHECK-NEXT: #APP
259 ; CHECK-NEXT: blah %f0
260 ; CHECK-NEXT: #NO_APP
261 ; CHECK-NEXT: blr %r14
262 ; CHECK: br %r14
263 entry:
264   call void asm sideeffect "blah $0", "{f0}"(double %val)
265   %cmp = fcmp olt double %val, 0.0
266   br i1 %cmp, label %exit, label %store
268 store:
269   store double %val, ptr %dest
270   br label %exit
272 exit:
273   ret double %val
276 ; LXR cannot be converted to LTXBR as its input is live after it.
277 define void @f14(ptr %ptr1, ptr %ptr2) {
278 ; CHECK-LABEL: f14:
279 ; CHECK: lxr
280 ; CHECK-NEXT: dxbr
281 ; CHECK-NEXT: std
282 ; CHECK-NEXT: std
283 ; CHECK-NEXT: mxbr
284 ; CHECK-NEXT: ltxbr
285 ; CHECK-NEXT: std
286 ; CHECK-NEXT: std
287 ; CHECK-NEXT: blr %r14
288 ; CHECK: br %r14
289 entry:
290   %val1 = load fp128, ptr %ptr1
291   %val2 = load fp128, ptr %ptr2
292   %div = fdiv fp128 %val1, %val2
293   store fp128 %div, ptr %ptr1
294   %mul = fmul fp128 %val1, %val2
295   store fp128 %mul, ptr %ptr2
296   %cmp = fcmp olt fp128 %val1, 0xL00000000000000000000000000000000
297   br i1 %cmp, label %exit, label %store
299 store:
300   call void asm sideeffect "blah", ""()
301   br label %exit
303 exit:
304   ret void
307 define float @f15(float %val, float %dummy, ptr %dest) {
308 ; CHECK-LABEL: f15:
309 ; CHECK: ltebr %f1, %f0
310 ; CHECK-NEXT: ler %f2, %f0
311 ; CHECK-NEXT: #APP
312 ; CHECK-NEXT: blah %f2
313 ; CHECK-NEXT: #NO_APP
314 ; CHECK-NEXT: blr %r14
315 ; CHECK: br %r14
316 entry:
317   call void asm sideeffect "blah $0", "{f2}"(float %val)
318   %cmp = fcmp olt float %val, 0.0
319   br i1 %cmp, label %exit, label %store
321 store:
322   store float %val, ptr %dest
323   br label %exit
325 exit:
326   ret float %val
329 define double @f16(double %val, double %dummy, ptr %dest) {
330 ; CHECK-LABEL: f16:
331 ; CHECK: ltdbr %f1, %f0
332 ; CHECK: ldr %f2, %f0
333 ; CHECK-NEXT: #APP
334 ; CHECK-NEXT: blah %f2
335 ; CHECK-NEXT: #NO_APP
336 ; CHECK-NEXT: blr %r14
337 ; CHECK: br %r14
338 entry:
339   call void asm sideeffect "blah $0", "{f2}"(double %val)
340   %cmp = fcmp olt double %val, 0.0
341   br i1 %cmp, label %exit, label %store
343 store:
344   store double %val, ptr %dest
345   br label %exit
347 exit:
348   ret double %val
351 ; Repeat f2 with a comparison against -0.
352 define float @f17(float %a, float %b, ptr %dest) {
353 ; CHECK-LABEL: f17:
354 ; CHECK: aebr %f0, %f2
355 ; CHECK-NEXT: blr %r14
356 ; CHECK: br %r14
357 entry:
358   %res = fadd float %a, %b
359   %cmp = fcmp olt float %res, -0.0
360   br i1 %cmp, label %exit, label %store
362 store:
363   store float %b, ptr %dest
364   br label %exit
366 exit:
367   ret float %res
370 ; Test another form of f7 in which the condition is based on the unnegated
371 ; result.  This is what InstCombine would produce.
372 define float @f18(float %dummy, float %a, ptr %dest) {
373 ; CHECK-LABEL: f18:
374 ; CHECK:       # %bb.0: # %entry
375 ; CHECK-NEXT:    lnebr %f0, %f2
376 ; CHECK-NEXT:    blr %r14
377 ; CHECK-NEXT:  .LBB17_1: # %store
378 ; CHECK-NEXT:    ste %f0, 0(%r2)
379 ; CHECK-NEXT:    br %r14
380 entry:
381   %abs = call float @llvm.fabs.f32(float %a)
382   %res = fneg float %abs
383   %cmp = fcmp ogt float %abs, 0.0
384   br i1 %cmp, label %exit, label %store
386 store:
387   store float %res, ptr %dest
388   br label %exit
390 exit:
391   ret float %res
394 ; Similarly for f8.
395 define float @f19(float %dummy, float %a, ptr %dest) {
396 ; CHECK-LABEL: f19:
397 ; CHECK:       # %bb.0: # %entry
398 ; CHECK-NEXT:    lcebr %f0, %f2
399 ; CHECK-NEXT:    bler %r14
400 ; CHECK-NEXT:  .LBB18_1: # %store
401 ; CHECK-NEXT:    ste %f0, 0(%r2)
402 ; CHECK-NEXT:    br %r14
403 entry:
404   %res = fneg float %a
405   %cmp = fcmp oge float %a, 0.0
406   br i1 %cmp, label %exit, label %store
408 store:
409   store float %res, ptr %dest
410   br label %exit
412 exit:
413   ret float %res