diff options
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp | 19 | ||||
-rw-r--r-- | llvm/test/Transforms/InstCombine/cos-sin-intrinsic.ll | 12 |
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 |