; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6 ; RUN: llc < %s -mtriple=arm64-eabi | FileCheck %s define double @test_direct(float %in) { ; CHECK-LABEL: test_direct: ; CHECK: // %bb.0: ; CHECK-NEXT: movi d1, #0000000000000000 ; CHECK-NEXT: fcmp s0, #0.0 ; CHECK-NEXT: fcsel s0, s1, s0, mi ; CHECK-NEXT: fcvt d0, s0 ; CHECK-NEXT: ret %cmp = fcmp 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: fcmp s0, #0.0 ; CHECK-NEXT: fcsel s0, s0, s1, lt ; CHECK-NEXT: fcvt d0, s0 ; CHECK-NEXT: ret %cmp = fcmp 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; ; Should not become either fminnm or fmin, because neither have the correct ; behavior for sNaN. define double @test_cross_fail_nan(float %in) { ; CHECK-LABEL: test_cross_fail_nan: ; CHECK: // %bb.0: ; CHECK-NEXT: movi d1, #0000000000000000 ; CHECK-NEXT: fcmp s0, #0.0 ; CHECK-NEXT: fcsel s0, s0, s1, mi ; CHECK-NEXT: fcvt d0, s0 ; CHECK-NEXT: ret %cmp = fcmp 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 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, mi ; CHECK-NEXT: ret %cmp = icmp slt i64 %in, 0 %val = select i1 %cmp, i64 0, i64 %in ret i64 %val } ; Make sure we don't translate it into fminnm when the nsz flag is set on the fcmp. define float @minnum_fcmp_nsz(float %x, float %y) { ; CHECK-LABEL: minnum_fcmp_nsz: ; CHECK: // %bb.0: ; CHECK-NEXT: fcmp s0, s1 ; CHECK-NEXT: fcsel s0, s0, s1, le ; CHECK-NEXT: ret %cmp = fcmp nnan nsz ole float %x, %y %sel = select i1 %cmp, float %x, float %y ret float %sel } ; Make sure we translate it into fminnm when the nsz flag is set on the select. define float @minnum_select_nsz(float %x, float %y) { ; CHECK-LABEL: minnum_select_nsz: ; CHECK: // %bb.0: ; CHECK-NEXT: fminnm s0, s0, s1 ; CHECK-NEXT: ret %cmp = fcmp nnan ole float %x, %y %sel = select nsz i1 %cmp, float %x, float %y ret float %sel }