1; RUN: llc < %s -mtriple=arm64-eabi | FileCheck %s 2 3define double @test_direct(float %in) { 4; CHECK-LABEL: test_direct: 5 %cmp = fcmp 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 s 11} 12 13define double @test_cross(float %in) { 14; CHECK-LABEL: test_cross: 15 %cmp = fcmp 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 s 21} 22 23; Same as previous, but with ordered comparison; 24; must become fminnm, not fmin. 25define double @test_cross_fail_nan(float %in) { 26; CHECK-LABEL: test_cross_fail_nan: 27 %cmp = fcmp 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: fminnm s 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 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