[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