aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAtariDreams <83477269+AtariDreams@users.noreply.github.com>2024-02-05 14:00:18 -0500
committerGitHub <noreply@github.com>2024-02-06 00:30:18 +0530
commit37462944513731af2743d95e5dd40bdbeefd6460 (patch)
tree6ebcf0f8b7c61316d180624966afd66b53673020
parent9805c051f7d3a09a629c51461b49f8070c01de62 (diff)
downloadllvm-37462944513731af2743d95e5dd40bdbeefd6460.zip
llvm-37462944513731af2743d95e5dd40bdbeefd6460.tar.gz
llvm-37462944513731af2743d95e5dd40bdbeefd6460.tar.bz2
[Transforms] Add more cos combinations to SimplifyLibCalls and InstCombine (#79699)
Add cos(fabs(x)) -> cos(x) and cos(copysign(x, y)) -> cos(x).
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp10
-rw-r--r--llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp12
-rw-r--r--llvm/test/Transforms/InstCombine/cos-1.ll73
3 files changed, 88 insertions, 7 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index df24c9b..ed5d447 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 3d1ce11..9e9d097 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;
+ Value *Src = Call->getArgOperand(0);
+ 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))))
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 7cdb1d2..168d88f 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,71 @@ 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: [[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)
+ ret double %r
+}
+
+define float @cosf_unary_fabs_arg(float %x) {
+; ANY-LABEL: @cosf_unary_fabs_arg(
+; 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)
+ ret float %r
+}
+
+define float @cosf_unary_fabs_arg_FMF(float %x) {
+; ANY-LABEL: @cosf_unary_fabs_arg_FMF(
+; 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)
+ 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: [[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)
+ ret double %r
+}
+
+
+define float @cosf_unary_copysign_arg(float %x) {
+; ANY-LABEL: @cosf_unary_copysign_arg(
+; 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)
+ ret float %r
+}
+
+define float @cosf_copysign_arg_FMF(float %x, float %y) {
+; ANY-LABEL: @cosf_copysign_arg_FMF(
+; 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)
+ ret float %r
+}
+
; sin(-x) -> -sin(x);
define double @sin_negated_arg(double %x) {