1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=arm64-eabi -enable-no-nans-fp-math | FileCheck %s 3 4define double @test_direct(float %in) { 5; CHECK-LABEL: test_direct: 6; CHECK: // %bb.0: 7; CHECK-NEXT: movi d1, #0000000000000000 8; CHECK-NEXT: fmaxnm s0, s0, s1 9; CHECK-NEXT: fcvt d0, s0 10; CHECK-NEXT: ret 11 %cmp = fcmp nnan olt float %in, 0.000000e+00 12 %val = select i1 %cmp, float 0.000000e+00, float %in 13 %longer = fpext float %val to double 14 ret double %longer 15} 16 17define double @test_cross(float %in) { 18; CHECK-LABEL: test_cross: 19; CHECK: // %bb.0: 20; CHECK-NEXT: movi d1, #0000000000000000 21; CHECK-NEXT: fminnm s0, s0, s1 22; CHECK-NEXT: fcvt d0, s0 23; CHECK-NEXT: ret 24 %cmp = fcmp nnan ult float %in, 0.000000e+00 25 %val = select i1 %cmp, float %in, float 0.000000e+00 26 %longer = fpext float %val to double 27 ret double %longer 28} 29 30; Same as previous, but with ordered comparison; 31; can't be converted in safe-math mode. 32define double @test_cross_fail_nan(float %in) { 33; CHECK-LABEL: test_cross_fail_nan: 34; CHECK: // %bb.0: 35; CHECK-NEXT: movi d1, #0000000000000000 36; CHECK-NEXT: fminnm s0, s0, s1 37; CHECK-NEXT: fcvt d0, s0 38; CHECK-NEXT: ret 39 %cmp = fcmp nnan olt float %in, 0.000000e+00 40 %val = select i1 %cmp, float %in, float 0.000000e+00 41 %longer = fpext float %val to double 42 ret double %longer 43} 44 45; This isn't a min or a max, but passes the first condition for swapping the 46; results. Make sure they're put back before we resort to the normal fcsel. 47define float @test_cross_fail(float %lhs, float %rhs) { 48; CHECK-LABEL: test_cross_fail: 49; CHECK: // %bb.0: 50; CHECK-NEXT: fcmp s0, s1 51; CHECK-NEXT: fcsel s0, s1, s0, ne 52; CHECK-NEXT: ret 53 %tst = fcmp nnan une float %lhs, %rhs 54 %res = select i1 %tst, float %rhs, float %lhs 55 ret float %res 56} 57 58; Make sure the transformation isn't triggered for integers 59define i64 @test_integer(i64 %in) { 60; CHECK-LABEL: test_integer: 61; CHECK: // %bb.0: 62; CHECK-NEXT: cmp x0, #0 63; CHECK-NEXT: csel x0, xzr, x0, lt 64; CHECK-NEXT: ret 65 %cmp = icmp slt i64 %in, 0 66 %val = select i1 %cmp, i64 0, i64 %in 67 ret i64 %val 68} 69 70; FIXME: It'd be nice for this to create an fmin instruction! 71define float @test_f16(half %in) { 72; CHECK-LABEL: test_f16: 73; CHECK: // %bb.0: 74; CHECK-NEXT: // kill: def $h0 killed $h0 def $s0 75; CHECK-NEXT: fcvt s1, h0 76; CHECK-NEXT: movi d2, #0000000000000000 77; CHECK-NEXT: fcmp s1, #0.0 78; CHECK-NEXT: fcsel s0, s0, s2, lt 79; CHECK-NEXT: fcvt s0, h0 80; CHECK-NEXT: ret 81 %cmp = fcmp nnan ult half %in, 0.000000e+00 82 %val = select i1 %cmp, half %in, half 0.000000e+00 83 %longer = fpext half %val to float 84 ret float %longer 85} 86