1; RUN: llc -march=arm64 -enable-no-nans-fp-math < %s | FileCheck %s 2 3define 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 13define 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. 25define 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. 37define 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 49define 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 55define 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