xref: /llvm-project/llvm/test/CodeGen/AArch64/arm64-fmax.ll (revision b0bfbad19b0698c51a0b932f82f778e67f2d7e0c)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=arm64-eabi -enable-no-nans-fp-math | FileCheck %s
3
4define double @test_direct(float %in) {
5; CHECK-LABEL: test_direct:
6; CHECK:       // %bb.0:
7; CHECK-NEXT:    movi d1, #0000000000000000
8; CHECK-NEXT:    fmaxnm s0, s0, s1
9; CHECK-NEXT:    fcvt d0, s0
10; CHECK-NEXT:    ret
11  %cmp = fcmp nnan olt float %in, 0.000000e+00
12  %val = select i1 %cmp, float 0.000000e+00, float %in
13  %longer = fpext float %val to double
14  ret double %longer
15}
16
17define double @test_cross(float %in) {
18; CHECK-LABEL: test_cross:
19; CHECK:       // %bb.0:
20; CHECK-NEXT:    movi d1, #0000000000000000
21; CHECK-NEXT:    fminnm s0, s0, s1
22; CHECK-NEXT:    fcvt d0, s0
23; CHECK-NEXT:    ret
24  %cmp = fcmp nnan ult float %in, 0.000000e+00
25  %val = select i1 %cmp, float %in, float 0.000000e+00
26  %longer = fpext float %val to double
27  ret double %longer
28}
29
30; Same as previous, but with ordered comparison;
31; can't be converted in safe-math mode.
32define double @test_cross_fail_nan(float %in) {
33; CHECK-LABEL: test_cross_fail_nan:
34; CHECK:       // %bb.0:
35; CHECK-NEXT:    movi d1, #0000000000000000
36; CHECK-NEXT:    fminnm s0, s0, s1
37; CHECK-NEXT:    fcvt d0, s0
38; CHECK-NEXT:    ret
39  %cmp = fcmp nnan olt float %in, 0.000000e+00
40  %val = select i1 %cmp, float %in, float 0.000000e+00
41  %longer = fpext float %val to double
42  ret double %longer
43}
44
45; This isn't a min or a max, but passes the first condition for swapping the
46; results. Make sure they're put back before we resort to the normal fcsel.
47define float @test_cross_fail(float %lhs, float %rhs) {
48; CHECK-LABEL: test_cross_fail:
49; CHECK:       // %bb.0:
50; CHECK-NEXT:    fcmp s0, s1
51; CHECK-NEXT:    fcsel s0, s1, s0, ne
52; CHECK-NEXT:    ret
53  %tst = fcmp nnan une float %lhs, %rhs
54  %res = select i1 %tst, float %rhs, float %lhs
55  ret float %res
56}
57
58; Make sure the transformation isn't triggered for integers
59define i64 @test_integer(i64  %in) {
60; CHECK-LABEL: test_integer:
61; CHECK:       // %bb.0:
62; CHECK-NEXT:    cmp x0, #0
63; CHECK-NEXT:    csel x0, xzr, x0, lt
64; CHECK-NEXT:    ret
65  %cmp = icmp slt i64 %in, 0
66  %val = select i1 %cmp, i64 0, i64 %in
67  ret i64 %val
68}
69
70; FIXME: It'd be nice for this to create an fmin instruction!
71define float @test_f16(half %in) {
72; CHECK-LABEL: test_f16:
73; CHECK:       // %bb.0:
74; CHECK-NEXT:    // kill: def $h0 killed $h0 def $s0
75; CHECK-NEXT:    fcvt s1, h0
76; CHECK-NEXT:    movi d2, #0000000000000000
77; CHECK-NEXT:    fcmp s1, #0.0
78; CHECK-NEXT:    fcsel s0, s0, s2, lt
79; CHECK-NEXT:    fcvt s0, h0
80; CHECK-NEXT:    ret
81  %cmp = fcmp nnan ult half %in, 0.000000e+00
82  %val = select i1 %cmp, half %in, half 0.000000e+00
83  %longer = fpext half %val to float
84  ret float %longer
85}
86