[llvm] [Transforms] Add cos(fabs(x)) -> cos(x) to SimplifyLibCalls (PR #79699)

via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 31 12:24:06 PST 2024


https://github.com/AtariDreams updated https://github.com/llvm/llvm-project/pull/79699

>From 41a6b735b635dab19adfead20d4dc42a20b0495a Mon Sep 17 00:00:00 2001
From: Rose <83477269+AtariDreams at users.noreply.github.com>
Date: Mon, 29 Jan 2024 18:56:58 -0500
Subject: [PATCH 1/2] [Transforms] Add pre-commit tests (NFC)

---
 llvm/test/Transforms/InstCombine/cos-1.ll | 79 +++++++++++++++++++++++
 1 file changed, 79 insertions(+)

diff --git a/llvm/test/Transforms/InstCombine/cos-1.ll b/llvm/test/Transforms/InstCombine/cos-1.ll
index 7cdb1d2f2b678..06775b71246d1 100644
--- a/llvm/test/Transforms/InstCombine/cos-1.ll
+++ b/llvm/test/Transforms/InstCombine/cos-1.ll
@@ -17,6 +17,14 @@ declare float @llvm.sin.f32(float)
 declare double @tan(double)
 declare fp128 @tanl(fp128)
 
+declare double @fabs(double)
+declare double @llvm.fabs.f64(double)
+declare float @fabsf(float)
+declare float @llvm.fabs.f32(float)
+
+declare double @llvm.copysign(double, double)
+declare float @llvm.copysign.f32(float, float)
+
 ; cos(-x) -> cos(x);
 
 define double @cos_negated_arg(double %x) {
@@ -100,6 +108,77 @@ define float @cosf_unary_negated_arg_FMF(float %x) {
   ret float %r
 }
 
+; cos(fabs(x)) -> cos(x)
+
+define double @cos_unary_fabs_arg(double %x) {
+; ANY-LABEL: @cos_unary_fabs_arg(
+; ANY-NEXT:    [[FABS:%.*]] = tail call double @llvm.fabs.f64(double [[X:%.*]])
+; ANY-NEXT:    [[R:%.*]] = call double @cos(double [[FABS]])
+; ANY-NEXT:    ret double [[R]]
+;
+  %fabs = tail call double @llvm.fabs.f64(double %x)
+  %r = call double @cos(double %fabs)
+  ret double %r
+}
+
+define float @cosf_unary_fabs_arg(float %x) {
+; ANY-LABEL: @cosf_unary_fabs_arg(
+; ANY-NEXT:    [[FABS:%.*]] = tail call float @llvm.fabs.f32(float [[X:%.*]])
+; ANY-NEXT:    [[R:%.*]] = call float @cosf(float [[FABS]])
+; ANY-NEXT:    ret float [[R]]
+;
+  %fabs = tail call float @llvm.fabs.f32(float %x)
+  %r = call float @cosf(float %fabs)
+  ret float %r
+}
+
+define float @cosf_unary_fabs_arg_FMF(float %x) {
+; ANY-LABEL: @cosf_unary_fabs_arg_FMF(
+; ANY-NEXT:    [[FABS:%.*]] = tail call float @llvm.fabs.f32(float [[X:%.*]])
+; ANY-NEXT:    [[R:%.*]] = call reassoc nnan float @cosf(float [[FABS]])
+; ANY-NEXT:    ret float [[R]]
+;
+  %fabs = tail call float @llvm.fabs.f32(float %x)
+  %r = call nnan reassoc float @cosf(float %fabs)
+  ret float %r
+}
+
+; cos(copysign(x, y)) -> cos(x)
+
+define double @cos_copysign_arg(double %x, double %y) {
+; ANY-LABEL: @cos_copysign_arg(
+; ANY-NEXT:    [[COPYSIGN:%.*]] = tail call double @llvm.copysign.f64(double [[X:%.*]], double [[Y:%.*]])
+; ANY-NEXT:    [[R:%.*]] = call double @cos(double [[COPYSIGN]])
+; ANY-NEXT:    ret double [[R]]
+;
+  %copysign = tail call double @llvm.copysign(double %x, double %y)
+  %r = call double @cos(double %copysign)
+  ret double %r
+}
+
+
+define float @cosf_unary_copysign_arg(float %x) {
+; ANY-LABEL: @cosf_unary_copysign_arg(
+; ANY-NEXT:    [[COPYSIGN:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
+; ANY-NEXT:    [[R:%.*]] = call float @cosf(float [[COPYSIGN]])
+; ANY-NEXT:    ret float [[R]]
+;
+  %copysign = tail call float @llvm.copysign.f32(float %x, float 1.0)
+  %r = call float @cosf(float %copysign)
+  ret float %r
+}
+
+define float @cosf_copysign_arg_FMF(float %x, float %y) {
+; ANY-LABEL: @cosf_copysign_arg_FMF(
+; ANY-NEXT:    [[COPYSIGN:%.*]] = tail call float @llvm.copysign.f32(float [[X:%.*]], float [[Y:%.*]])
+; ANY-NEXT:    [[R:%.*]] = call reassoc nnan float @cosf(float [[COPYSIGN]])
+; ANY-NEXT:    ret float [[R]]
+;
+  %copysign = tail call float @llvm.copysign.f32(float %x, float %y)
+  %r = call nnan reassoc float @cosf(float %copysign)
+  ret float %r
+}
+
 ; sin(-x) -> -sin(x);
 
 define double @sin_negated_arg(double %x) {

>From dd0987811289f59a79fbed8cd74d1b2389fe6aac Mon Sep 17 00:00:00 2001
From: Rose <83477269+AtariDreams at users.noreply.github.com>
Date: Sat, 27 Jan 2024 12:38:19 -0500
Subject: [PATCH 2/2] [Transforms] Add more cos combinations to
 SimplifyLibCalls and InstCombineCalls

Add cos(fabs(x)) -> cos(x) and cos(copysign(x, y)) -> cos(x).
---
 .../InstCombine/InstCombineCalls.cpp          | 10 ++++---
 .../lib/Transforms/Utils/SimplifyLibCalls.cpp | 12 ++++++--
 llvm/test/Transforms/InstCombine/cos-1.ll     | 30 ++++++++-----------
 3 files changed, 27 insertions(+), 25 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index b7e73856f4060..475ed54791994 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -2488,11 +2488,13 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
   }
   case Intrinsic::cos:
   case Intrinsic::amdgcn_cos: {
-    Value *X;
+    Value *X, *Sign;
     Value *Src = II->getArgOperand(0);
-    if (match(Src, m_FNeg(m_Value(X))) || match(Src, m_FAbs(m_Value(X)))) {
-      // cos(-x) -> cos(x)
-      // cos(fabs(x)) -> cos(x)
+    if (match(Src, m_FNeg(m_Value(X))) || match(Src, m_FAbs(m_Value(X))) ||
+        match(Src, m_CopySign(m_Value(X), m_Value(Sign)))) {
+      // cos(-x) --> cos(x)
+      // cos(fabs(x)) --> cos(x)
+      // cos(copysign(x, y)) --> cos(x)
       return replaceOperand(*II, 0, X);
     }
     break;
diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
index 52eef9ab58a4d..5155b0ce99b44 100644
--- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
@@ -1933,12 +1933,18 @@ static Value *optimizeTrigReflections(CallInst *Call, LibFunc Func,
     break;
   case LibFunc_cos:
   case LibFunc_cosf:
-  case LibFunc_cosl:
-    // cos(-X) --> cos(X)
-    if (match(Call->getArgOperand(0), m_FNeg(m_Value(X))))
+  case LibFunc_cosl: {
+    // cos(-x) --> cos(x)
+    // cos(fabs(x)) --> cos(x)
+    // cos(copysign(x, y)) --> cos(x)
+    Value *Sign;
+    if (match(Call->getArgOperand(0), m_FNeg(m_Value(X))) ||
+        match(Call->getArgOperand(0), m_FAbs(m_Value(X))) ||
+        match(Call->getArgOperand(0), m_CopySign(m_Value(X), m_Value(Sign))))
       return copyFlags(*Call,
                        B.CreateCall(Call->getCalledFunction(), X, "cos"));
     break;
+  }
   default:
     break;
   }
diff --git a/llvm/test/Transforms/InstCombine/cos-1.ll b/llvm/test/Transforms/InstCombine/cos-1.ll
index 06775b71246d1..168d88fb3a942 100644
--- a/llvm/test/Transforms/InstCombine/cos-1.ll
+++ b/llvm/test/Transforms/InstCombine/cos-1.ll
@@ -112,9 +112,8 @@ define float @cosf_unary_negated_arg_FMF(float %x) {
 
 define double @cos_unary_fabs_arg(double %x) {
 ; ANY-LABEL: @cos_unary_fabs_arg(
-; ANY-NEXT:    [[FABS:%.*]] = tail call double @llvm.fabs.f64(double [[X:%.*]])
-; ANY-NEXT:    [[R:%.*]] = call double @cos(double [[FABS]])
-; ANY-NEXT:    ret double [[R]]
+; ANY-NEXT:    [[COS:%.*]] = call double @cos(double [[X:%.*]])
+; ANY-NEXT:    ret double [[COS]]
 ;
   %fabs = tail call double @llvm.fabs.f64(double %x)
   %r = call double @cos(double %fabs)
@@ -123,9 +122,8 @@ define double @cos_unary_fabs_arg(double %x) {
 
 define float @cosf_unary_fabs_arg(float %x) {
 ; ANY-LABEL: @cosf_unary_fabs_arg(
-; ANY-NEXT:    [[FABS:%.*]] = tail call float @llvm.fabs.f32(float [[X:%.*]])
-; ANY-NEXT:    [[R:%.*]] = call float @cosf(float [[FABS]])
-; ANY-NEXT:    ret float [[R]]
+; ANY-NEXT:    [[COS:%.*]] = call float @cosf(float [[X:%.*]])
+; ANY-NEXT:    ret float [[COS]]
 ;
   %fabs = tail call float @llvm.fabs.f32(float %x)
   %r = call float @cosf(float %fabs)
@@ -134,9 +132,8 @@ define float @cosf_unary_fabs_arg(float %x) {
 
 define float @cosf_unary_fabs_arg_FMF(float %x) {
 ; ANY-LABEL: @cosf_unary_fabs_arg_FMF(
-; ANY-NEXT:    [[FABS:%.*]] = tail call float @llvm.fabs.f32(float [[X:%.*]])
-; ANY-NEXT:    [[R:%.*]] = call reassoc nnan float @cosf(float [[FABS]])
-; ANY-NEXT:    ret float [[R]]
+; ANY-NEXT:    [[COS:%.*]] = call reassoc nnan float @cosf(float [[X:%.*]])
+; ANY-NEXT:    ret float [[COS]]
 ;
   %fabs = tail call float @llvm.fabs.f32(float %x)
   %r = call nnan reassoc float @cosf(float %fabs)
@@ -147,9 +144,8 @@ define float @cosf_unary_fabs_arg_FMF(float %x) {
 
 define double @cos_copysign_arg(double %x, double %y) {
 ; ANY-LABEL: @cos_copysign_arg(
-; ANY-NEXT:    [[COPYSIGN:%.*]] = tail call double @llvm.copysign.f64(double [[X:%.*]], double [[Y:%.*]])
-; ANY-NEXT:    [[R:%.*]] = call double @cos(double [[COPYSIGN]])
-; ANY-NEXT:    ret double [[R]]
+; ANY-NEXT:    [[COS:%.*]] = call double @cos(double [[X:%.*]])
+; ANY-NEXT:    ret double [[COS]]
 ;
   %copysign = tail call double @llvm.copysign(double %x, double %y)
   %r = call double @cos(double %copysign)
@@ -159,9 +155,8 @@ define double @cos_copysign_arg(double %x, double %y) {
 
 define float @cosf_unary_copysign_arg(float %x) {
 ; ANY-LABEL: @cosf_unary_copysign_arg(
-; ANY-NEXT:    [[COPYSIGN:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
-; ANY-NEXT:    [[R:%.*]] = call float @cosf(float [[COPYSIGN]])
-; ANY-NEXT:    ret float [[R]]
+; ANY-NEXT:    [[COS:%.*]] = call float @cosf(float [[X:%.*]])
+; ANY-NEXT:    ret float [[COS]]
 ;
   %copysign = tail call float @llvm.copysign.f32(float %x, float 1.0)
   %r = call float @cosf(float %copysign)
@@ -170,9 +165,8 @@ define float @cosf_unary_copysign_arg(float %x) {
 
 define float @cosf_copysign_arg_FMF(float %x, float %y) {
 ; ANY-LABEL: @cosf_copysign_arg_FMF(
-; ANY-NEXT:    [[COPYSIGN:%.*]] = tail call float @llvm.copysign.f32(float [[X:%.*]], float [[Y:%.*]])
-; ANY-NEXT:    [[R:%.*]] = call reassoc nnan float @cosf(float [[COPYSIGN]])
-; ANY-NEXT:    ret float [[R]]
+; ANY-NEXT:    [[COS:%.*]] = call reassoc nnan float @cosf(float [[X:%.*]])
+; ANY-NEXT:    ret float [[COS]]
 ;
   %copysign = tail call float @llvm.copysign.f32(float %x, float %y)
   %r = call nnan reassoc float @cosf(float %copysign)



More information about the llvm-commits mailing list