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: fcmp 11; CHECK: fcsel 12} 13 14define double @test_cross(float %in) { 15; CHECK-LABEL: test_cross: 16 %cmp = fcmp ult float %in, 0.000000e+00 17 %val = select i1 %cmp, float %in, float 0.000000e+00 18 %longer = fpext float %val to double 19 ret double %longer 20 21; CHECK: fcmp 22; CHECK: fcsel 23} 24 25; Same as previous, but with ordered comparison; 26; must become fminnm, not fmin. 27define double @test_cross_fail_nan(float %in) { 28; CHECK-LABEL: test_cross_fail_nan: 29 %cmp = fcmp olt float %in, 0.000000e+00 30 %val = select i1 %cmp, float %in, float 0.000000e+00 31 %longer = fpext float %val to double 32 ret double %longer 33 34; CHECK: fminnm s 35} 36 37; This isn't a min or a max, but passes the first condition for swapping the 38; results. Make sure they're put back before we resort to the normal fcsel. 39define float @test_cross_fail(float %lhs, float %rhs) { 40; CHECK-LABEL: test_cross_fail: 41 %tst = fcmp une float %lhs, %rhs 42 %res = select i1 %tst, float %rhs, float %lhs 43 ret float %res 44 45 ; The register allocator would have to decide to be deliberately obtuse before 46 ; other register were used. 47; CHECK: fcsel s0, s1, s0, ne 48} 49 50; Make sure the transformation isn't triggered for integers 51define i64 @test_integer(i64 %in) { 52 %cmp = icmp slt i64 %in, 0 53 %val = select i1 %cmp, i64 0, i64 %in 54 ret i64 %val 55} 56