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