From e7695bca0f0a3011523d406fa9bb195b1524238e Mon Sep 17 00:00:00 2001 From: James Molloy Date: Thu, 13 Aug 2015 17:28:10 +0000 Subject: [PATCH] [AArch64] Small rejig of fmax tests, NFCI. These tests relied on -enable-no-nans-fp-math, whereas soon they'll take their no-nans hint from the FCMP instruction itself, so split the no-nans stuff out into its own test. Also do a slight rejig of instruction order. The old FMIN/MAX backend matching had to deal with looking through casts, which it never did particularly well. Now, instcombine will recognize such patterns and canonicalize the cast outside the select. So modify the test inputs to assume that instcombine has already run. llvm-svn: 244913 --- llvm/test/CodeGen/AArch64/arm64-fmax-safe.ll | 53 ++++++++++++++++++++ llvm/test/CodeGen/AArch64/arm64-fmax.ll | 35 +++++-------- 2 files changed, 66 insertions(+), 22 deletions(-) create mode 100644 llvm/test/CodeGen/AArch64/arm64-fmax-safe.ll diff --git a/llvm/test/CodeGen/AArch64/arm64-fmax-safe.ll b/llvm/test/CodeGen/AArch64/arm64-fmax-safe.ll new file mode 100644 index 000000000000..e83f0251f3a4 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/arm64-fmax-safe.ll @@ -0,0 +1,53 @@ +; RUN: llc -march=arm64 < %s | FileCheck %s + +define double @test_direct(float %in) { +; CHECK-LABEL: test_direct: + %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 + +; CHECK: fmax +} + +define double @test_cross(float %in) { +; CHECK-LABEL: test_cross: + %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 + +; CHECK: fmin +} + +; 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: + %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 + +; CHECK: fcsel s0, s0, s1, mi +} + +; 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: + %tst = fcmp une float %lhs, %rhs + %res = select i1 %tst, float %rhs, float %lhs + ret float %res + + ; The register allocator would have to decide to be deliberately obtuse before + ; other register were used. +; CHECK: fcsel s0, s1, s0, ne +} + +; Make sure the transformation isn't triggered for integers +define i64 @test_integer(i64 %in) { + %cmp = icmp slt i64 %in, 0 + %val = select i1 %cmp, i64 0, i64 %in + ret i64 %val +} diff --git a/llvm/test/CodeGen/AArch64/arm64-fmax.ll b/llvm/test/CodeGen/AArch64/arm64-fmax.ll index ea281528b84c..470be6aa5df4 100644 --- a/llvm/test/CodeGen/AArch64/arm64-fmax.ll +++ b/llvm/test/CodeGen/AArch64/arm64-fmax.ll @@ -1,57 +1,48 @@ ; RUN: llc -march=arm64 -enable-no-nans-fp-math < %s | FileCheck %s -; RUN: llc -march=arm64 < %s | FileCheck %s --check-prefix=CHECK-SAFE define double @test_direct(float %in) { ; CHECK-LABEL: test_direct: -; CHECK-SAFE-LABEL: test_direct: - %cmp = fcmp olt float %in, 0.000000e+00 - %longer = fpext float %in to double - %val = select i1 %cmp, double 0.000000e+00, double %longer - ret double %val + %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 ; CHECK: fmax -; CHECK-SAFE: fmax } define double @test_cross(float %in) { ; CHECK-LABEL: test_cross: -; CHECK-SAFE-LABEL: test_cross: - %cmp = fcmp ult float %in, 0.000000e+00 - %longer = fpext float %in to double - %val = select i1 %cmp, double %longer, double 0.000000e+00 - ret double %val + %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 ; CHECK: fmin -; CHECK-SAFE: fmin } ; 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-SAFE-LABEL: test_cross_fail_nan: - %cmp = fcmp olt float %in, 0.000000e+00 - %longer = fpext float %in to double - %val = select i1 %cmp, double %longer, double 0.000000e+00 - ret double %val + %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 ; CHECK: fmin -; CHECK-SAFE: fcsel d0, d1, d0, mi } ; 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-SAFE-LABEL: test_cross_fail: - %tst = fcmp une float %lhs, %rhs + %tst = fcmp nnan une float %lhs, %rhs %res = select i1 %tst, float %rhs, float %lhs ret float %res ; The register allocator would have to decide to be deliberately obtuse before ; other register were used. ; CHECK: fcsel s0, s1, s0, ne -; CHECK-SAFE: fcsel s0, s1, s0, ne } ; Make sure the transformation isn't triggered for integers