summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp19
-rw-r--r--llvm/test/Transforms/InstCombine/cos-sin-intrinsic.ll12
2 files changed, 20 insertions, 11 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 2993f0095a6..4755e8509b3 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -2124,16 +2124,25 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
}
case Intrinsic::cos:
case Intrinsic::amdgcn_cos: {
- Value *SrcSrc;
+ Value *X;
Value *Src = II->getArgOperand(0);
- if (match(Src, m_FNeg(m_Value(SrcSrc))) ||
- match(Src, m_FAbs(m_Value(SrcSrc)))) {
+ if (match(Src, m_FNeg(m_Value(X))) || match(Src, m_FAbs(m_Value(X)))) {
// cos(-x) -> cos(x)
// cos(fabs(x)) -> cos(x)
- II->setArgOperand(0, SrcSrc);
+ II->setArgOperand(0, X);
return II;
}
-
+ break;
+ }
+ case Intrinsic::sin: {
+ Value *X;
+ if (match(II->getArgOperand(0), m_OneUse(m_FNeg(m_Value(X))))) {
+ // sin(-x) --> -sin(x)
+ Value *NewSin = Builder.CreateIntrinsic(Intrinsic::sin, { X }, II);
+ Instruction *FNeg = BinaryOperator::CreateFNeg(NewSin);
+ FNeg->copyFastMathFlags(II);
+ return FNeg;
+ }
break;
}
case Intrinsic::ppc_altivec_lvx:
diff --git a/llvm/test/Transforms/InstCombine/cos-sin-intrinsic.ll b/llvm/test/Transforms/InstCombine/cos-sin-intrinsic.ll
index 98c2434bb14..ef5513d086e 100644
--- a/llvm/test/Transforms/InstCombine/cos-sin-intrinsic.ll
+++ b/llvm/test/Transforms/InstCombine/cos-sin-intrinsic.ll
@@ -92,14 +92,14 @@ define <2 x float> @fabs_fneg_v2f32(<2 x float> %x) {
ret <2 x float> %cos
}
-; TODO: Negate is canonicalized after sin.
+; Negate is canonicalized after sin.
declare <2 x float> @llvm.sin.v2f32(<2 x float>)
define <2 x float> @fneg_sin(<2 x float> %x){
; CHECK-LABEL: @fneg_sin(
-; CHECK-NEXT: [[NEGX:%.*]] = fsub <2 x float> <float -0.000000e+00, float -0.000000e+00>, [[X:%.*]]
-; CHECK-NEXT: [[R:%.*]] = call <2 x float> @llvm.sin.v2f32(<2 x float> [[NEGX]])
+; CHECK-NEXT: [[TMP1:%.*]] = call <2 x float> @llvm.sin.v2f32(<2 x float> [[X:%.*]])
+; CHECK-NEXT: [[R:%.*]] = fsub <2 x float> <float -0.000000e+00, float -0.000000e+00>, [[TMP1]]
; CHECK-NEXT: ret <2 x float> [[R]]
;
%negx = fsub <2 x float> <float -0.0, float -0.0>, %x
@@ -107,12 +107,12 @@ define <2 x float> @fneg_sin(<2 x float> %x){
ret <2 x float> %r
}
-; TODO: FMF are not required, but they should propagate.
+; FMF are not required, but they should propagate.
define <2 x float> @fneg_sin_fmf(<2 x float> %x){
; CHECK-LABEL: @fneg_sin_fmf(
-; CHECK-NEXT: [[NEGX:%.*]] = fsub fast <2 x float> <float -0.000000e+00, float -0.000000e+00>, [[X:%.*]]
-; CHECK-NEXT: [[R:%.*]] = call nnan arcp afn <2 x float> @llvm.sin.v2f32(<2 x float> [[NEGX]])
+; CHECK-NEXT: [[TMP1:%.*]] = call nnan arcp afn <2 x float> @llvm.sin.v2f32(<2 x float> [[X:%.*]])
+; CHECK-NEXT: [[R:%.*]] = fsub nnan arcp afn <2 x float> <float -0.000000e+00, float -0.000000e+00>, [[TMP1]]
; CHECK-NEXT: ret <2 x float> [[R]]
;
%negx = fsub fast <2 x float> <float -0.0, float -0.0>, %x
OpenPOWER on IntegriCloud