1 ; RUN: llc -march=arm64 -enable-no-nans-fp-math < %s | FileCheck %s 2 3 define double @test_direct(float %in) { 4 ; CHECK-LABEL: test_direct: 5 %cmp = fcmp nnan olt float %in, 0.000000e+00 6 %val = select i1 %cmp, float 0.000000e+00, float %in 7 %longer = fpext float %val to double 8 ret double %longer 9 10 ; CHECK: fmax 11 } 12 13 define double @test_cross(float %in) { 14 ; CHECK-LABEL: test_cross: 15 %cmp = fcmp nnan ult float %in, 0.000000e+00 16 %val = select i1 %cmp, float %in, float 0.000000e+00 17 %longer = fpext float %val to double 18 ret double %longer 19 20 ; CHECK: fmin 21 } 22 23 ; Same as previous, but with ordered comparison; 24 ; can't be converted in safe-math mode. 25 define double @test_cross_fail_nan(float %in) { 26 ; CHECK-LABEL: test_cross_fail_nan: 27 %cmp = fcmp nnan olt float %in, 0.000000e+00 28 %val = select i1 %cmp, float %in, float 0.000000e+00 29 %longer = fpext float %val to double 30 ret double %longer 31 32 ; CHECK: fmin 33 } 34 35 ; This isn't a min or a max, but passes the first condition for swapping the 36 ; results. Make sure they're put back before we resort to the normal fcsel. 37 define float @test_cross_fail(float %lhs, float %rhs) { 38 ; CHECK-LABEL: test_cross_fail: 39 %tst = fcmp nnan une float %lhs, %rhs 40 %res = select i1 %tst, float %rhs, float %lhs 41 ret float %res 42 43 ; The register allocator would have to decide to be deliberately obtuse before 44 ; other register were used. 45 ; CHECK: fcsel s0, s1, s0, ne 46 } 47 48 ; Make sure the transformation isn't triggered for integers 49 define i64 @test_integer(i64 %in) { 50 %cmp = icmp slt i64 %in, 0 51 %val = select i1 %cmp, i64 0, i64 %in 52 ret i64 %val 53 } 54 55 define float @test_f16(half %in) { 56 ; CHECK-LABEL: test_f16: 57 %cmp = fcmp nnan ult half %in, 0.000000e+00 58 %val = select i1 %cmp, half %in, half 0.000000e+00 59 %longer = fpext half %val to float 60 ret float %longer 61 ; FIXME: It'd be nice for this to create an fmin instruction! 62 ; CHECK: fcvt 63 ; CHECK: fcsel 64 } 65