; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc < %s -mtriple=arm64-eabi -enable-no-nans-fp-math | FileCheck %s define double @test_direct(float %in) { ; CHECK-LABEL: test_direct: ; CHECK: // %bb.0: ; CHECK-NEXT: movi d1, #0000000000000000 ; CHECK-NEXT: fmaxnm s0, s0, s1 ; CHECK-NEXT: fcvt d0, s0 ; CHECK-NEXT: ret %cmp = fcmp nnan olt float %in, 0.000000e+00 %val = select i1 %cmp, float 0.000000e+00, float %in %longer = fpext float %val to double ret double %longer } define double @test_cross(float %in) { ; CHECK-LABEL: test_cross: ; CHECK: // %bb.0: ; CHECK-NEXT: movi d1, #0000000000000000 ; CHECK-NEXT: fminnm s0, s0, s1 ; CHECK-NEXT: fcvt d0, s0 ; CHECK-NEXT: ret %cmp = fcmp nnan ult float %in, 0.000000e+00 %val = select i1 %cmp, float %in, float 0.000000e+00 %longer = fpext float %val to double ret double %longer } ; Same as previous, but with ordered comparison; ; can't be converted in safe-math mode. define double @test_cross_fail_nan(float %in) { ; CHECK-LABEL: test_cross_fail_nan: ; CHECK: // %bb.0: ; CHECK-NEXT: movi d1, #0000000000000000 ; CHECK-NEXT: fminnm s0, s0, s1 ; CHECK-NEXT: fcvt d0, s0 ; CHECK-NEXT: ret %cmp = fcmp nnan olt float %in, 0.000000e+00 %val = select i1 %cmp, float %in, float 0.000000e+00 %longer = fpext float %val to double ret double %longer } ; This isn't a min or a max, but passes the first condition for swapping the ; results. Make sure they're put back before we resort to the normal fcsel. define float @test_cross_fail(float %lhs, float %rhs) { ; CHECK-LABEL: test_cross_fail: ; CHECK: // %bb.0: ; CHECK-NEXT: fcmp s0, s1 ; CHECK-NEXT: fcsel s0, s1, s0, ne ; CHECK-NEXT: ret %tst = fcmp nnan une float %lhs, %rhs %res = select i1 %tst, float %rhs, float %lhs ret float %res } ; Make sure the transformation isn't triggered for integers define i64 @test_integer(i64 %in) { ; CHECK-LABEL: test_integer: ; CHECK: // %bb.0: ; CHECK-NEXT: cmp x0, #0 ; CHECK-NEXT: csel x0, xzr, x0, lt ; CHECK-NEXT: ret %cmp = icmp slt i64 %in, 0 %val = select i1 %cmp, i64 0, i64 %in ret i64 %val } ; FIXME: It'd be nice for this to create an fmin instruction! define float @test_f16(half %in) { ; CHECK-LABEL: test_f16: ; CHECK: // %bb.0: ; CHECK-NEXT: // kill: def $h0 killed $h0 def $s0 ; CHECK-NEXT: fcvt s1, h0 ; CHECK-NEXT: movi d2, #0000000000000000 ; CHECK-NEXT: fcmp s1, #0.0 ; CHECK-NEXT: fcsel s0, s0, s2, lt ; CHECK-NEXT: fcvt s0, h0 ; CHECK-NEXT: ret %cmp = fcmp nnan ult half %in, 0.000000e+00 %val = select i1 %cmp, half %in, half 0.000000e+00 %longer = fpext half %val to float ret float %longer }