[llvm] 30abc1a - [ConstantFolding] Eliminate atan and atan2 calls

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 10 08:01:57 PDT 2022


Author: Mohammed Nurul Hoque
Date: 2022-08-10T11:01:50-04:00
New Revision: 30abc1a6a18e843fd0470157d4d2ec285aaac8cd

URL: https://github.com/llvm/llvm-project/commit/30abc1a6a18e843fd0470157d4d2ec285aaac8cd
DIFF: https://github.com/llvm/llvm-project/commit/30abc1a6a18e843fd0470157d4d2ec285aaac8cd.diff

LOG: [ConstantFolding] Eliminate atan and atan2 calls

>From the opengroup specifications, atan2 may fail if the result
underflows and atan may fail if the argument is subnormal, but
we assume that does not happen and eliminate the calls if we
can constant fold the result at compile-time.

Differential Revision: https://reviews.llvm.org/D127964

Added: 
    

Modified: 
    llvm/lib/Analysis/ConstantFolding.cpp
    llvm/test/Transforms/EarlyCSE/atan.ll
    llvm/test/Transforms/EarlyCSE/math-1.ll
    llvm/test/Transforms/EarlyCSE/math-2.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index 1803a69bee741..46c29870407da 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -3296,6 +3296,13 @@ bool llvm::isMathLibCallNoop(const CallBase *Call,
         break;
       }
 
+      case LibFunc_atan:
+      case LibFunc_atanf:
+      case LibFunc_atanl:
+        // Per POSIX, this MAY fail if Op is denormal. We choose not failing.
+        return true;
+
+
       case LibFunc_asinl:
       case LibFunc_asin:
       case LibFunc_asinf:
@@ -3361,6 +3368,14 @@ bool llvm::isMathLibCallNoop(const CallBase *Call,
         return Op0.isNaN() || Op1.isNaN() ||
                (!Op0.isInfinity() && !Op1.isZero());
 
+      case LibFunc_atan2:
+      case LibFunc_atan2f:
+      case LibFunc_atan2l:
+        // POSIX, GLIBC and MSVC dictate atan2(0,0) is 0 and no error is raised.
+        // C11 says that a domain error may optionally occur.
+        // This is consistent with both.
+        return true;
+
       default:
         break;
       }

diff  --git a/llvm/test/Transforms/EarlyCSE/atan.ll b/llvm/test/Transforms/EarlyCSE/atan.ll
index a917087a73b76..a50403bcb0277 100644
--- a/llvm/test/Transforms/EarlyCSE/atan.ll
+++ b/llvm/test/Transforms/EarlyCSE/atan.ll
@@ -4,13 +4,13 @@
 
 define float @callatan0() {
 ; CHECK-LABEL: @callatan0(
-; CHECK-NEXT:    [[CALL:%.*]] = call float @atanf(float -0.000000e+00)
 ; CHECK-NEXT:    ret float -0.000000e+00
 ;
   %call = call float @atanf(float -0.0)
   ret float %call
 }
 
+; TODO: constant should be folded
 define float @callatanInf() {
 ; CHECK-LABEL: @callatanInf(
 ; CHECK-NEXT:    [[CALL:%.*]] = call float @atanf(float 0x7FF0000000000000)
@@ -20,6 +20,7 @@ define float @callatanInf() {
   ret float %call
 }
 
+; TODO: constant should be folded
 define float @callatanNaN() {
 ; CHECK-LABEL: @callatanNaN(
 ; CHECK-NEXT:    [[CALL:%.*]] = call float @atanf(float 0x7FF8000000000000)
@@ -29,16 +30,16 @@ define float @callatanNaN() {
   ret float %call
 }
 
+; POSIX: May fail with Range Error. We choose not to fail.
 define float @callatanDenorm() {
 ; CHECK-LABEL: @callatanDenorm(
-; CHECK-NEXT:    [[CALL:%.*]] = call float @atanf(float 0x37A16C2000000000)
 ; CHECK-NEXT:    ret float 0x37A16C2000000000
 ;
   %call = call float @atanf(float 0x37A16C2000000000)
   ret float %call
 }
 
-; long double calls currently not folded
+; TODO: long double calls currently not folded
 define x86_fp80 @atanl_x86(x86_fp80 %x) {
 ; CHECK-LABEL: @atanl_x86(
 ; CHECK-NEXT:    [[CALL:%.*]] = call x86_fp80 @atanl(x86_fp80 noundef 0xK3FFF8CCCCCCCCCCCCCCD)
@@ -50,7 +51,6 @@ define x86_fp80 @atanl_x86(x86_fp80 %x) {
 
 define float @callatan2_00() {
 ; CHECK-LABEL: @callatan2_00(
-; CHECK-NEXT:    [[CALL:%.*]] = call float @atan2f(float -0.000000e+00, float 0.000000e+00)
 ; CHECK-NEXT:    ret float -0.000000e+00
 ;
   %call = call float @atan2f(float -0.0, float 0.0)
@@ -59,7 +59,6 @@ define float @callatan2_00() {
 
 define float @callatan2_x0() {
 ; CHECK-LABEL: @callatan2_x0(
-; CHECK-NEXT:    [[CALL:%.*]] = call float @atan2f(float 1.000000e+00, float -0.000000e+00)
 ; CHECK-NEXT:    ret float 0x3FF921FB60000000
 ;
   %call = call float @atan2f(float 1.0, float -0.000000e+00)
@@ -68,7 +67,6 @@ define float @callatan2_x0() {
 
 define float @callatan2_0x() {
 ; CHECK-LABEL: @callatan2_0x(
-; CHECK-NEXT:    [[CALL:%.*]] = call float @atan2f(float -0.000000e+00, float 1.000000e+00)
 ; CHECK-NEXT:    ret float -0.000000e+00
 ;
   %call = call float @atan2f(float -0.0, float 1.0)
@@ -77,7 +75,6 @@ define float @callatan2_0x() {
 
 define float @callatan2_xx() {
 ; CHECK-LABEL: @callatan2_xx(
-; CHECK-NEXT:    [[CALL:%.*]] = call float @atan2f(float -1.000000e+00, float 1.000000e+00)
 ; CHECK-NEXT:    ret float 0xBFE921FB60000000
 ;
   %call = call float @atan2f(float -1.0, float 1.0)
@@ -86,7 +83,6 @@ define float @callatan2_xx() {
 
 define float @callatan2_denorm() {
 ; CHECK-LABEL: @callatan2_denorm(
-; CHECK-NEXT:    [[CALL:%.*]] = call float @atan2f(float 0x39B4484C00000000, float 1.000000e+10)
 ; CHECK-NEXT:    ret float 0x37A16C2000000000
 ;
   %call = call float @atan2f(float 0x39B4484C00000000, float 1.0e+10)
@@ -95,7 +91,6 @@ define float @callatan2_denorm() {
 
 define float @callatan2_flush_to_zero() {
 ; CHECK-LABEL: @callatan2_flush_to_zero(
-; CHECK-NEXT:    [[CALL:%.*]] = call float @atan2f(float 0x39B4484C00000000, float 0x4415AF1D80000000)
 ; CHECK-NEXT:    ret float 0.000000e+00
 ;
   %call = call float @atan2f(float 0x39B4484C00000000, float 0x4415AF1D80000000)
@@ -104,7 +99,6 @@ define float @callatan2_flush_to_zero() {
 
 define float @callatan2_NaN() {
 ; CHECK-LABEL: @callatan2_NaN(
-; CHECK-NEXT:    [[CALL:%.*]] = call float @atan2f(float 0x7FF8000000000000, float 0x7FF8000000000000)
 ; CHECK-NEXT:    ret float 0x7FF8000000000000
 ;
   %call = call float @atan2f(float 0x7FF8000000000000, float 0x7FF8000000000000)
@@ -113,7 +107,6 @@ define float @callatan2_NaN() {
 
 define float @callatan2_Inf() {
 ; CHECK-LABEL: @callatan2_Inf(
-; CHECK-NEXT:    [[CALL:%.*]] = call float @atan2f(float 0x7FF0000000000000, float 0x7FF0000000000000)
 ; CHECK-NEXT:    ret float 0x3FE921FB60000000
 ;
   %call = call float @atan2f(float 0x7FF0000000000000, float 0x7FF0000000000000)

diff  --git a/llvm/test/Transforms/EarlyCSE/math-1.ll b/llvm/test/Transforms/EarlyCSE/math-1.ll
index 47357ab936150..ed24525bff96f 100644
--- a/llvm/test/Transforms/EarlyCSE/math-1.ll
+++ b/llvm/test/Transforms/EarlyCSE/math-1.ll
@@ -22,7 +22,6 @@ define float @f_asinf() {
 declare double @atan(double) #0
 define double @f_atan() {
 ; CHECK-LABEL: @f_atan(
-; CHECK-NEXT:    [[RES:%.*]] = tail call fast double @atan(double 1.000000e+00)
 ; CHECK-NEXT:    ret double 0x3FE921FB
 ;
   %res = tail call fast double @atan(double 1.0)

diff  --git a/llvm/test/Transforms/EarlyCSE/math-2.ll b/llvm/test/Transforms/EarlyCSE/math-2.ll
index 0b39725470bd9..fb6d979ae6850 100644
--- a/llvm/test/Transforms/EarlyCSE/math-2.ll
+++ b/llvm/test/Transforms/EarlyCSE/math-2.ll
@@ -4,7 +4,6 @@
 declare double @atan2(double, double) #0
 define double @f_atan2() {
 ; CHECK-LABEL: @f_atan2(
-; CHECK-NEXT:    [[RES:%.*]] = tail call fast double @atan2(double 1.000000e+00, double 2.000000e+00)
 ; CHECK-NEXT:    ret double 0x3FDDAC6{{.+}}
 ;
   %res = tail call fast double @atan2(double 1.0, double 2.0)


        


More information about the llvm-commits mailing list