[PATCH] D41283: [InstCombine] Missed optimization in math expression: tan(a) * cos(a) == sin(a)
Dmitry Venikov via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Fri Dec 15 04:55:16 PST 2017
Quolyk created this revision.
Quolyk added reviewers: hfinkel, spatel.
Motivation: https://bugs.llvm.org/show_bug.cgi?id=35602
https://reviews.llvm.org/D41283
Files:
lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
test/Transforms/InstCombine/fmul.ll
Index: test/Transforms/InstCombine/fmul.ll
===================================================================
--- test/Transforms/InstCombine/fmul.ll
+++ test/Transforms/InstCombine/fmul.ll
@@ -181,3 +181,17 @@
%mul = fmul float %x.fabs, %y.fabs
ret float %mul
}
+
+; CHECK-LABEL @tan_x_cos(
+; CHECK: call fast double @llvm.sin.f64(double %a)
+define double @tan_x_cos(double %a) {
+entry:
+ %call = call fast double @tan(double %a)
+ %0 = call fast double @llvm.cos.f64(double %a)
+ %mul = fmul fast double %0, %call
+ ret double %mul
+}
+
+declare double @tan(double) nounwind readnone
+declare double @llvm.cos.f64(double) nounwind readnone speculatable
+declare double @llvm.sin.f64(double) nounwind readnone speculatable
Index: lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
===================================================================
--- lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -508,6 +508,22 @@
Y = I->getOperand(0);
}
+/// Detect if one operand is IntrincisInst and other is CallInst
+static void detectIntrincisInstWithCallInst(Value *Op0, Value *Op1,
+ IntrinsicInst *&Intr, CallInst *&Call) {
+ if ((Call = dyn_cast<CallInst>(Op0))) {
+ if ((Intr = dyn_cast<IntrinsicInst>(Op1))) {
+ return;
+ }
+ }
+
+ if ((Intr = dyn_cast<IntrinsicInst>(Op0))) {
+ if ((Call = dyn_cast<CallInst>(Op1))) {
+ return;
+ }
+ }
+}
+
static bool isFiniteNonZeroFp(Constant *C) {
if (C->getType()->isVectorTy()) {
for (unsigned I = 0, E = C->getType()->getVectorNumElements(); I != E;
@@ -701,6 +717,24 @@
}
}
+ // tan(a) * cos(a) -> sin(a)
+ if (AllowReassociate) {
+ CallInst *Tan = nullptr;
+ IntrinsicInst *Cos = nullptr;
+ detectIntrincisInstWithCallInst(Op0, Op1, Cos, Tan);
+ if (Cos && Tan) {
+ Function *TanCallee = Tan->getCalledFunction();
+ StringRef TanName = TanCallee->getName();
+ if (Cos->getIntrinsicID() == Intrinsic::cos && TanName == "tan" &&
+ Cos->getArgOperand(0) == Tan->getArgOperand(0)) {
+ Value *Sin = Intrinsic::getDeclaration(I.getModule(), Intrinsic::sin, I.getType());
+ Builder.setFastMathFlags(I.getFastMathFlags());
+ Value *SinCall = Builder.CreateCall(Sin, Cos->getArgOperand(0), "sin");
+ return replaceInstUsesWith(I, SinCall);
+ }
+ }
+ }
+
// Under unsafe algebra do:
// X * log2(0.5*Y) = X*log2(Y) - X
if (AllowReassociate) {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D41283.127106.patch
Type: text/x-patch
Size: 2536 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20171215/a17d284e/attachment.bin>
More information about the llvm-commits
mailing list