[llvm] [InstCombine] Optimize `sinh` and `cosh` divivsions (PR #81433)

Felix Kellenbenz via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 13 13:04:00 PST 2024


https://github.com/felixkellenbenz updated https://github.com/llvm/llvm-project/pull/81433

>From f49bb401addab67825567d0bda94067832fbe2eb Mon Sep 17 00:00:00 2001
From: Felix Kellenbenz <fe.kellenbenz.computer at outlook.de>
Date: Sat, 10 Feb 2024 17:41:04 +0100
Subject: [PATCH 1/6] [InstCombine] Optimize sinh and cosh divivsion

[InstCombine] Optimize sinh and cosh divivsion

Add regression tests

Add regression tests
---
 .../InstCombine/InstCombineMulDivRem.cpp      | 124 +++++++++++++-----
 .../Transforms/InstCombine/fdiv-cosh-sinh.ll  |  87 ++++++++++++
 .../Transforms/InstCombine/fdiv-sinh-cosh.ll  |  84 ++++++++++++
 3 files changed, 259 insertions(+), 36 deletions(-)
 create mode 100644 llvm/test/Transforms/InstCombine/fdiv-cosh-sinh.ll
 create mode 100644 llvm/test/Transforms/InstCombine/fdiv-sinh-cosh.ll

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
index 0bd4b6d1a835af..62917691a6eafe 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -48,7 +48,8 @@ static Value *simplifyValueKnownNonZero(Value *V, InstCombinerImpl &IC,
   // If V has multiple uses, then we would have to do more analysis to determine
   // if this is safe.  For example, the use could be in dynamically unreached
   // code.
-  if (!V->hasOneUse()) return nullptr;
+  if (!V->hasOneUse())
+    return nullptr;
 
   bool MadeChange = false;
 
@@ -223,8 +224,8 @@ Instruction *InstCombinerImpl::visitMul(BinaryOperator &I) {
     Value *NewOp;
     Constant *C1, *C2;
     const APInt *IVal;
-    if (match(&I, m_Mul(m_Shl(m_Value(NewOp), m_Constant(C2)),
-                        m_Constant(C1))) &&
+    if (match(&I,
+              m_Mul(m_Shl(m_Value(NewOp), m_Constant(C2)), m_Constant(C1))) &&
         match(C1, m_APInt(IVal))) {
       // ((X << C2)*C1) == (X * (C1 << C2))
       Constant *Shl = ConstantExpr::getShl(C1, C2);
@@ -410,9 +411,8 @@ Instruction *InstCombinerImpl::visitMul(BinaryOperator &I) {
   //   2) X * Y --> X & Y, iff X, Y can be only {0,1}.
   // Note: We could use known bits to generalize this and related patterns with
   // shifts/truncs
-  if (Ty->isIntOrIntVectorTy(1) ||
-      (match(Op0, m_And(m_Value(), m_One())) &&
-       match(Op1, m_And(m_Value(), m_One()))))
+  if (Ty->isIntOrIntVectorTy(1) || (match(Op0, m_And(m_Value(), m_One())) &&
+                                    match(Op1, m_And(m_Value(), m_One()))))
     return BinaryOperator::CreateAnd(Op0, Op1);
 
   if (Value *R = foldMulShl1(I, /* CommuteOperands */ false, Builder))
@@ -746,9 +746,9 @@ Instruction *InstCombinerImpl::foldFMulReassoc(BinaryOperator &I) {
 }
 
 Instruction *InstCombinerImpl::visitFMul(BinaryOperator &I) {
-  if (Value *V = simplifyFMulInst(I.getOperand(0), I.getOperand(1),
-                                  I.getFastMathFlags(),
-                                  SQ.getWithInstruction(&I)))
+  if (Value *V =
+          simplifyFMulInst(I.getOperand(0), I.getOperand(1),
+                           I.getFastMathFlags(), SQ.getWithInstruction(&I)))
     return replaceInstUsesWith(I, V);
 
   if (SimplifyAssociativeOrCommutative(I))
@@ -800,12 +800,12 @@ Instruction *InstCombinerImpl::visitFMul(BinaryOperator &I) {
   if (I.isFast()) {
     IntrinsicInst *Log2 = nullptr;
     if (match(Op0, m_OneUse(m_Intrinsic<Intrinsic::log2>(
-            m_OneUse(m_FMul(m_Value(X), m_SpecificFP(0.5))))))) {
+                       m_OneUse(m_FMul(m_Value(X), m_SpecificFP(0.5))))))) {
       Log2 = cast<IntrinsicInst>(Op0);
       Y = Op1;
     }
     if (match(Op1, m_OneUse(m_Intrinsic<Intrinsic::log2>(
-            m_OneUse(m_FMul(m_Value(X), m_SpecificFP(0.5))))))) {
+                       m_OneUse(m_FMul(m_Value(X), m_SpecificFP(0.5))))))) {
       Log2 = cast<IntrinsicInst>(Op1);
       Y = Op0;
     }
@@ -906,7 +906,6 @@ bool InstCombinerImpl::simplifyDivRemOfSelectWithZeroOp(BinaryOperator &I) {
     // If we ran out of things to eliminate, break out of the loop.
     if (!SelectCond && !SI)
       break;
-
   }
   return true;
 }
@@ -1301,8 +1300,8 @@ static Value *takeLog2(IRBuilderBase &Builder, Value *Op, unsigned Depth,
   // log2(Cond ? X : Y) -> Cond ? log2(X) : log2(Y)
   // FIXME: Require one use?
   if (SelectInst *SI = dyn_cast<SelectInst>(Op))
-    if (Value *LogX = takeLog2(Builder, SI->getOperand(1), Depth,
-                               AssumeNonZero, DoFold))
+    if (Value *LogX =
+            takeLog2(Builder, SI->getOperand(1), Depth, AssumeNonZero, DoFold))
       if (Value *LogY = takeLog2(Builder, SI->getOperand(2), Depth,
                                  AssumeNonZero, DoFold))
         return IfFold([&]() {
@@ -1330,8 +1329,7 @@ static Value *takeLog2(IRBuilderBase &Builder, Value *Op, unsigned Depth,
 
 /// If we have zero-extended operands of an unsigned div or rem, we may be able
 /// to narrow the operation (sink the zext below the math).
-static Instruction *narrowUDivURem(BinaryOperator &I,
-                                   InstCombinerImpl &IC) {
+static Instruction *narrowUDivURem(BinaryOperator &I, InstCombinerImpl &IC) {
   Instruction::BinaryOps Opcode = I.getOpcode();
   Value *N = I.getOperand(0);
   Value *D = I.getOperand(1);
@@ -1709,9 +1707,9 @@ static Instruction *foldFDivPowDivisor(BinaryOperator &I,
 Instruction *InstCombinerImpl::visitFDiv(BinaryOperator &I) {
   Module *M = I.getModule();
 
-  if (Value *V = simplifyFDivInst(I.getOperand(0), I.getOperand(1),
-                                  I.getFastMathFlags(),
-                                  SQ.getWithInstruction(&I)))
+  if (Value *V =
+          simplifyFDivInst(I.getOperand(0), I.getOperand(1),
+                           I.getFastMathFlags(), SQ.getWithInstruction(&I)))
     return replaceInstUsesWith(I, V);
 
   if (Instruction *X = foldVectorBinop(I))
@@ -1767,26 +1765,81 @@ Instruction *InstCombinerImpl::visitFDiv(BinaryOperator &I) {
   if (I.hasAllowReassoc() && Op0->hasOneUse() && Op1->hasOneUse()) {
     // sin(X) / cos(X) -> tan(X)
     // cos(X) / sin(X) -> 1/tan(X) (cotangent)
-    Value *X;
+    // sinh(X) / cosh(X) -> tanh(X)
+    // cosh(X) / sinh(X) -> 1/tanh(X)
+    Value *X, *Y;
+
     bool IsTan = match(Op0, m_Intrinsic<Intrinsic::sin>(m_Value(X))) &&
                  match(Op1, m_Intrinsic<Intrinsic::cos>(m_Specific(X)));
-    bool IsCot =
-        !IsTan && match(Op0, m_Intrinsic<Intrinsic::cos>(m_Value(X))) &&
-                  match(Op1, m_Intrinsic<Intrinsic::sin>(m_Specific(X)));
+    bool IsCot = !IsTan &&
+                 match(Op0, m_Intrinsic<Intrinsic::cos>(m_Value(X))) &&
+                 match(Op1, m_Intrinsic<Intrinsic::sin>(m_Specific(X)));
 
-    if ((IsTan || IsCot) && hasFloatFn(M, &TLI, I.getType(), LibFunc_tan,
-                                       LibFunc_tanf, LibFunc_tanl)) {
+    auto GetReplacement = [&](Value *Arg, bool IsInv, LibFunc DoubleFunc,
+                              LibFunc FloatFunc,
+                              LibFunc LongDoubleFunc) -> Value * {
       IRBuilder<> B(&I);
       IRBuilder<>::FastMathFlagGuard FMFGuard(B);
       B.setFastMathFlags(I.getFastMathFlags());
       AttributeList Attrs =
           cast<CallBase>(Op0)->getCalledFunction()->getAttributes();
-      Value *Res = emitUnaryFloatFnCall(X, &TLI, LibFunc_tan, LibFunc_tanf,
-                                        LibFunc_tanl, B, Attrs);
-      if (IsCot)
+      Value *Res = emitUnaryFloatFnCall(Arg, &TLI, DoubleFunc, FloatFunc,
+                                        LongDoubleFunc, B, Attrs);
+
+      if (IsInv)
         Res = B.CreateFDiv(ConstantFP::get(I.getType(), 1.0), Res);
+
+      return Res;
+    };
+
+    if ((IsTan || IsCot) && hasFloatFn(M, &TLI, I.getType(), LibFunc_tan,
+                                       LibFunc_tanf, LibFunc_tanl)) {
+
+      Value *Res =
+          GetReplacement(X, IsCot, LibFunc_tan, LibFunc_tanf, LibFunc_tanl);
+
       return replaceInstUsesWith(I, Res);
     }
+
+    if (isa<CallBase>(Op0) && isa<CallBase>(Op1)) {
+
+      CallBase *Op0AsCallBase = cast<CallBase>(Op0);
+      CallBase *Op1AsCallBase = cast<CallBase>(Op1);
+
+      bool ArgsMatch = match(Op0AsCallBase->getArgOperand(0), m_Value(Y)) &&
+                       match(Op1AsCallBase->getArgOperand(0), m_Specific(Y));
+
+      bool IsTanH = Op0AsCallBase->getCalledFunction()->getName() == "sinh" &&
+                    Op1AsCallBase->getCalledFunction()->getName() == "cosh" &&
+                    ArgsMatch;
+
+      bool IsCotH = !IsTanH && ArgsMatch &&
+                    Op0AsCallBase->getCalledFunction()->getName() == "cosh" &&
+                    Op1AsCallBase->getCalledFunction()->getName() == "sinh";
+
+      if ((IsTanH || IsCotH) && hasFloatFn(M, &TLI, I.getType(), LibFunc_tanh,
+                                           LibFunc_tanhf, LibFunc_tanhl)) {
+
+        Value *Res =
+            GetReplacement(Y, false, LibFunc_tanh, LibFunc_tanf, LibFunc_tanl);
+
+        Instruction *Result = replaceInstUsesWith(I, Res);
+
+        // Call instructions of sinh and cosh need to be erased seperatly
+        if (!Op0AsCallBase->use_empty())
+          Op0AsCallBase->replaceAllUsesWith(
+              UndefValue::get(Op0AsCallBase->getType()));
+
+        if (!Op1AsCallBase->use_empty())
+          Op1AsCallBase->replaceAllUsesWith(
+              UndefValue::get(Op1AsCallBase->getType()));
+
+        Op0AsCallBase->eraseFromParent();
+        Op1AsCallBase->eraseFromParent();
+
+        return Result;
+      }
+    }
   }
 
   // X / (X * Y) --> 1.0 / Y
@@ -1814,9 +1867,8 @@ Instruction *InstCombinerImpl::visitFDiv(BinaryOperator &I) {
     return Mul;
 
   // pow(X, Y) / X --> pow(X, Y-1)
-  if (I.hasAllowReassoc() &&
-      match(Op0, m_OneUse(m_Intrinsic<Intrinsic::pow>(m_Specific(Op1),
-                                                      m_Value(Y))))) {
+  if (I.hasAllowReassoc() && match(Op0, m_OneUse(m_Intrinsic<Intrinsic::pow>(
+                                            m_Specific(Op1), m_Value(Y))))) {
     Value *Y1 =
         Builder.CreateFAddFMF(Y, ConstantFP::get(I.getType(), -1.0), &I);
     Value *Pow = Builder.CreateBinaryIntrinsic(Intrinsic::pow, Op1, Y1, &I);
@@ -2126,7 +2178,7 @@ Instruction *InstCombinerImpl::visitSRem(BinaryOperator &I) {
     if (hasNegative && !hasMissing) {
       SmallVector<Constant *, 16> Elts(VWidth);
       for (unsigned i = 0; i != VWidth; ++i) {
-        Elts[i] = C->getAggregateElement(i);  // Handle undef, etc.
+        Elts[i] = C->getAggregateElement(i); // Handle undef, etc.
         if (ConstantInt *RHS = dyn_cast<ConstantInt>(Elts[i])) {
           if (RHS->isNegative())
             Elts[i] = cast<ConstantInt>(ConstantExpr::getNeg(RHS));
@@ -2134,7 +2186,7 @@ Instruction *InstCombinerImpl::visitSRem(BinaryOperator &I) {
       }
 
       Constant *NewRHSV = ConstantVector::get(Elts);
-      if (NewRHSV != C)  // Don't loop on -MININT
+      if (NewRHSV != C) // Don't loop on -MININT
         return replaceOperand(I, 1, NewRHSV);
     }
   }
@@ -2143,9 +2195,9 @@ Instruction *InstCombinerImpl::visitSRem(BinaryOperator &I) {
 }
 
 Instruction *InstCombinerImpl::visitFRem(BinaryOperator &I) {
-  if (Value *V = simplifyFRemInst(I.getOperand(0), I.getOperand(1),
-                                  I.getFastMathFlags(),
-                                  SQ.getWithInstruction(&I)))
+  if (Value *V =
+          simplifyFRemInst(I.getOperand(0), I.getOperand(1),
+                           I.getFastMathFlags(), SQ.getWithInstruction(&I)))
     return replaceInstUsesWith(I, V);
 
   if (Instruction *X = foldVectorBinop(I))
diff --git a/llvm/test/Transforms/InstCombine/fdiv-cosh-sinh.ll b/llvm/test/Transforms/InstCombine/fdiv-cosh-sinh.ll
new file mode 100644
index 00000000000000..3c7d64d6ba5472
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/fdiv-cosh-sinh.ll
@@ -0,0 +1,87 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -S -passes=instcombine < %s | FileCheck %s
+
+define double @fdiv_cosh_sinh(double %a) {
+; CHECK-LABEL: @fdiv_cosh_sinh(
+; CHECK-NEXT:    [[TMP1:%.*]] = call double @cosh(double [[A:%.*]])
+; CHECK-NEXT:    [[TMP2:%.*]] = call double @sinh(double [[A]])
+; CHECK-NEXT:    [[DIV:%.*]] = fdiv double [[TMP1]], [[TMP2]]
+; CHECK-NEXT:    ret double [[DIV]]
+;
+  %1 = call double @cosh(double %a)
+  %2 = call double @sinh(double %a)
+  %div = fdiv double %1, %2
+  ret double %div
+}
+
+define double @fdiv_strict_cosh_strict_sinh_reassoc(double %a) {
+; CHECK-LABEL: @fdiv_strict_cosh_strict_sinh_reassoc(
+; CHECK-NEXT:    [[TMP1:%.*]] = call double @cosh(double [[A:%.*]])
+; CHECK-NEXT:    [[TMP2:%.*]] = call reassoc double @sinh(double [[A]])
+; CHECK-NEXT:    [[DIV:%.*]] = fdiv double [[TMP1]], [[TMP2]]
+; CHECK-NEXT:    ret double [[DIV]]
+;
+  %1 = call double @cosh(double %a)
+  %2 = call reassoc double @sinh(double %a)
+  %div = fdiv double %1, %2
+  ret double %div
+}
+
+define double @fdiv_reassoc_cosh_strict_sinh_strict(double %a, ptr dereferenceable(2) %dummy) {
+; CHECK-LABEL: @fdiv_reassoc_cosh_strict_sinh_strict(
+; CHECK-NEXT:    [[TAN:%.*]] = call reassoc double @tanh(double [[A:%.*]])
+; CHECK-NEXT:    [[DIV:%.*]] = fdiv reassoc double 1.000000e+00, [[TAN]]
+; CHECK-NEXT:    ret double [[DIV]]
+;
+  %1 = call double @cosh(double %a)
+  %2 = call double @sinh(double %a)
+  %div = fdiv reassoc double %1, %2
+  ret double %div
+}
+
+define double @fdiv_reassoc_cosh_reassoc_sinh_strict(double %a) {
+; CHECK-LABEL: @fdiv_reassoc_cosh_reassoc_sinh_strict(
+; CHECK-NEXT:    [[TAN:%.*]] = call reassoc double @tanh(double [[A:%.*]])
+; CHECK-NEXT:    [[DIV:%.*]] = fdiv reassoc double 1.000000e+00, [[TAN]]
+; CHECK-NEXT:    ret double [[DIV]]
+;
+  %1 = call reassoc double @cosh(double %a)
+  %2 = call double @sinh(double %a)
+  %div = fdiv reassoc double %1, %2
+  ret double %div
+}
+
+define double @fdiv_cosh_sinh_reassoc_multiple_uses(double %a) {
+; CHECK-LABEL: @fdiv_cosh_sinh_reassoc_multiple_uses(
+; CHECK-NEXT:    [[TMP1:%.*]] = call reassoc double @cosh(double [[A:%.*]])
+; CHECK-NEXT:    [[TMP2:%.*]] = call reassoc double @sinh(double [[A]])
+; CHECK-NEXT:    [[DIV:%.*]] = fdiv reassoc double [[TMP1]], [[TMP2]]
+; CHECK-NEXT:    call void @use(double [[TMP2]])
+; CHECK-NEXT:    ret double [[DIV]]
+;
+  %1 = call reassoc double @cosh(double %a)
+  %2 = call reassoc double @sinh(double %a)
+  %div = fdiv reassoc double %1, %2
+  call void @use(double %2)
+  ret double %div
+}
+
+define double @fdiv_cosh_sinh_reassoc(double %a){
+; CHECK-LABEL: @fdiv_cosh_sinh_reassoc(
+; CHECK-NEXT:    [[TAN:%.*]] = call reassoc double @tanh(double [[A:%.*]])
+; CHECK-NEXT:    [[DIV:%.*]] = fdiv reassoc double 1.000000e+00, [[TAN]]
+; CHECK-NEXT:    ret double [[DIV]]
+;
+  %1 = call reassoc double @cosh(double %a)
+  %2 = call reassoc double @sinh(double %a)
+  %div = fdiv reassoc double %1, %2
+  ret double %div
+}
+
+
+declare double @cosh(double)
+declare double @sinh(double)
+
+declare double @tanh(double)
+
+declare void @use(double)
diff --git a/llvm/test/Transforms/InstCombine/fdiv-sinh-cosh.ll b/llvm/test/Transforms/InstCombine/fdiv-sinh-cosh.ll
new file mode 100644
index 00000000000000..3ece1686263e24
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/fdiv-sinh-cosh.ll
@@ -0,0 +1,84 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -S -passes=instcombine < %s | FileCheck %s
+
+define double @fdiv_sinh_cosh(double %a) {
+; CHECK-LABEL: @fdiv_sinh_cosh(
+; CHECK-NEXT:    [[TMP1:%.*]] = call double @sinh(double [[A:%.*]])
+; CHECK-NEXT:    [[TMP2:%.*]] = call double @cosh(double [[A]])
+; CHECK-NEXT:    [[DIV:%.*]] = fdiv double [[TMP1]], [[TMP2]]
+; CHECK-NEXT:    ret double [[DIV]]
+;
+  %1 = call double @sinh(double %a)
+  %2 = call double @cosh(double %a)
+  %div = fdiv double %1, %2
+  ret double %div
+}
+
+define double @fdiv_reassoc_sinh_strict_cosh_strict(double %a, ptr dereferenceable(2) %dummy) {
+; CHECK-LABEL: @fdiv_reassoc_sinh_strict_cosh_strict(
+; CHECK-NEXT:    [[TANH:%.*]] = call reassoc double @tanh(double [[A:%.*]])
+; CHECK-NEXT:    ret double [[TANH]]
+;
+  %1 = call double @sinh(double %a)
+  %2 = call double @cosh(double %a)
+  %div = fdiv reassoc double %1, %2
+  ret double %div
+}
+
+define double @fdiv_reassoc_sinh_reassoc_cosh_strict(double %a) {
+; CHECK-LABEL: @fdiv_reassoc_sinh_reassoc_cosh_strict(
+; CHECK-NEXT:    [[TANH:%.*]] = call reassoc double @tanh(double [[A:%.*]])
+; CHECK-NEXT:    ret double [[TANH]]
+;
+  %1 = call reassoc double @sinh(double %a)
+  %2 = call double @cosh(double %a)
+  %div = fdiv reassoc double %1, %2
+  ret double %div
+}
+
+define double @fdiv_sin_cos_reassoc_multiple_uses_sinh(double %a) {
+; CHECK-LABEL: @fdiv_sin_cos_reassoc_multiple_uses_sinh(
+; CHECK-NEXT:    [[TMP1:%.*]] = call reassoc double @sinh(double [[A:%.*]])
+; CHECK-NEXT:    [[TMP2:%.*]] = call reassoc double @cosh(double [[A]])
+; CHECK-NEXT:    [[DIV:%.*]] = fdiv reassoc double [[TMP1]], [[TMP2]]
+; CHECK-NEXT:    call void @use(double [[TMP1]])
+; CHECK-NEXT:    ret double [[DIV]]
+;
+  %1 = call reassoc double @sinh(double %a)
+  %2 = call reassoc double @cosh(double %a)
+  %div = fdiv reassoc double %1, %2
+  call void @use(double %1)
+  ret double %div
+}
+
+define double @fdiv_sin_cos_reassoc_multiple_uses_cosh(double %a) {
+; CHECK-LABEL: @fdiv_sin_cos_reassoc_multiple_uses_cosh(
+; CHECK-NEXT:    [[TMP1:%.*]] = call reassoc double @sinh(double [[A:%.*]])
+; CHECK-NEXT:    [[TMP2:%.*]] = call reassoc double @cosh(double [[A]])
+; CHECK-NEXT:    [[DIV:%.*]] = fdiv reassoc double [[TMP1]], [[TMP2]]
+; CHECK-NEXT:    call void @use(double [[TMP2]])
+; CHECK-NEXT:    ret double [[DIV]]
+;
+  %1 = call reassoc double @sinh(double %a)
+  %2 = call reassoc double @cosh(double %a)
+  %div = fdiv reassoc double %1, %2
+  call void @use(double %2)
+  ret double %div
+}
+
+
+define double @fdiv_sinh_cosh_reassoc(double %a) {
+; CHECK-LABEL: @fdiv_sinh_cosh_reassoc(
+; CHECK-NEXT:    [[TANH:%.*]] = call reassoc double @tanh(double [[A:%.*]])
+; CHECK-NEXT:    ret double [[TANH]]
+;
+  %1 = call reassoc double @sinh(double %a)
+  %2 = call reassoc double @cosh(double %a)
+  %div = fdiv reassoc double %1, %2
+  ret double %div
+}
+
+declare double @cosh(double)
+declare double @sinh(double)
+
+declare void @use(double)

>From 3f2206be8b9b8b66556c7aa03b9694af04b042d1 Mon Sep 17 00:00:00 2001
From: Felix Kellenbenz <fe.kellenbenz.computer at outlook.de>
Date: Mon, 12 Feb 2024 14:17:55 +0100
Subject: [PATCH 2/6] Match with getLibFunc undo clang format changes

---
 .../InstCombine/InstCombineMulDivRem.cpp      | 67 +++++++++++--------
 .../Transforms/InstCombine/fdiv-cosh-sinh.ll  | 18 +++--
 .../Transforms/InstCombine/fdiv-sinh-cosh.ll  | 12 +++-
 3 files changed, 60 insertions(+), 37 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
index 62917691a6eafe..700c2883084759 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -15,6 +15,7 @@
 #include "llvm/ADT/APInt.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Analysis/InstructionSimplify.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
 #include "llvm/Analysis/ValueTracking.h"
 #include "llvm/IR/BasicBlock.h"
 #include "llvm/IR/Constant.h"
@@ -48,8 +49,7 @@ static Value *simplifyValueKnownNonZero(Value *V, InstCombinerImpl &IC,
   // If V has multiple uses, then we would have to do more analysis to determine
   // if this is safe.  For example, the use could be in dynamically unreached
   // code.
-  if (!V->hasOneUse())
-    return nullptr;
+  if (!V->hasOneUse()) return nullptr;
 
   bool MadeChange = false;
 
@@ -224,8 +224,7 @@ Instruction *InstCombinerImpl::visitMul(BinaryOperator &I) {
     Value *NewOp;
     Constant *C1, *C2;
     const APInt *IVal;
-    if (match(&I,
-              m_Mul(m_Shl(m_Value(NewOp), m_Constant(C2)), m_Constant(C1))) &&
+    if (match(&I, m_Mul(m_Shl(m_Value(NewOp), m_Constant(C2)), m_Constant(C1))) &&
         match(C1, m_APInt(IVal))) {
       // ((X << C2)*C1) == (X * (C1 << C2))
       Constant *Shl = ConstantExpr::getShl(C1, C2);
@@ -411,8 +410,9 @@ Instruction *InstCombinerImpl::visitMul(BinaryOperator &I) {
   //   2) X * Y --> X & Y, iff X, Y can be only {0,1}.
   // Note: We could use known bits to generalize this and related patterns with
   // shifts/truncs
-  if (Ty->isIntOrIntVectorTy(1) || (match(Op0, m_And(m_Value(), m_One())) &&
-                                    match(Op1, m_And(m_Value(), m_One()))))
+  if (Ty->isIntOrIntVectorTy(1) || 
+      (match(Op0, m_And(m_Value(), m_One())) &&
+       match(Op1, m_And(m_Value(), m_One()))))
     return BinaryOperator::CreateAnd(Op0, Op1);
 
   if (Value *R = foldMulShl1(I, /* CommuteOperands */ false, Builder))
@@ -748,7 +748,8 @@ Instruction *InstCombinerImpl::foldFMulReassoc(BinaryOperator &I) {
 Instruction *InstCombinerImpl::visitFMul(BinaryOperator &I) {
   if (Value *V =
           simplifyFMulInst(I.getOperand(0), I.getOperand(1),
-                           I.getFastMathFlags(), SQ.getWithInstruction(&I)))
+                           I.getFastMathFlags(),
+                           SQ.getWithInstruction(&I)))
     return replaceInstUsesWith(I, V);
 
   if (SimplifyAssociativeOrCommutative(I))
@@ -800,12 +801,12 @@ Instruction *InstCombinerImpl::visitFMul(BinaryOperator &I) {
   if (I.isFast()) {
     IntrinsicInst *Log2 = nullptr;
     if (match(Op0, m_OneUse(m_Intrinsic<Intrinsic::log2>(
-                       m_OneUse(m_FMul(m_Value(X), m_SpecificFP(0.5))))))) {
+            m_OneUse(m_FMul(m_Value(X), m_SpecificFP(0.5))))))) {
       Log2 = cast<IntrinsicInst>(Op0);
       Y = Op1;
     }
     if (match(Op1, m_OneUse(m_Intrinsic<Intrinsic::log2>(
-                       m_OneUse(m_FMul(m_Value(X), m_SpecificFP(0.5))))))) {
+            m_OneUse(m_FMul(m_Value(X), m_SpecificFP(0.5))))))) {
       Log2 = cast<IntrinsicInst>(Op1);
       Y = Op0;
     }
@@ -906,6 +907,7 @@ bool InstCombinerImpl::simplifyDivRemOfSelectWithZeroOp(BinaryOperator &I) {
     // If we ran out of things to eliminate, break out of the loop.
     if (!SelectCond && !SI)
       break;
+
   }
   return true;
 }
@@ -1300,8 +1302,8 @@ static Value *takeLog2(IRBuilderBase &Builder, Value *Op, unsigned Depth,
   // log2(Cond ? X : Y) -> Cond ? log2(X) : log2(Y)
   // FIXME: Require one use?
   if (SelectInst *SI = dyn_cast<SelectInst>(Op))
-    if (Value *LogX =
-            takeLog2(Builder, SI->getOperand(1), Depth, AssumeNonZero, DoFold))
+    if (Value *LogX = takeLog2(Builder, SI->getOperand(1), Depth, 
+                               AssumeNonZero, DoFold))
       if (Value *LogY = takeLog2(Builder, SI->getOperand(2), Depth,
                                  AssumeNonZero, DoFold))
         return IfFold([&]() {
@@ -1329,7 +1331,8 @@ static Value *takeLog2(IRBuilderBase &Builder, Value *Op, unsigned Depth,
 
 /// If we have zero-extended operands of an unsigned div or rem, we may be able
 /// to narrow the operation (sink the zext below the math).
-static Instruction *narrowUDivURem(BinaryOperator &I, InstCombinerImpl &IC) {
+static Instruction *narrowUDivURem(BinaryOperator &I,
+                                   InstCombinerImpl &IC) {
   Instruction::BinaryOps Opcode = I.getOpcode();
   Value *N = I.getOperand(0);
   Value *D = I.getOperand(1);
@@ -1707,9 +1710,9 @@ static Instruction *foldFDivPowDivisor(BinaryOperator &I,
 Instruction *InstCombinerImpl::visitFDiv(BinaryOperator &I) {
   Module *M = I.getModule();
 
-  if (Value *V =
-          simplifyFDivInst(I.getOperand(0), I.getOperand(1),
-                           I.getFastMathFlags(), SQ.getWithInstruction(&I)))
+  if (Value *V = simplifyFDivInst(I.getOperand(0), I.getOperand(1),
+                                  I.getFastMathFlags(), 
+                                  SQ.getWithInstruction(&I)))
     return replaceInstUsesWith(I, V);
 
   if (Instruction *X = foldVectorBinop(I))
@@ -1805,25 +1808,31 @@ Instruction *InstCombinerImpl::visitFDiv(BinaryOperator &I) {
 
       CallBase *Op0AsCallBase = cast<CallBase>(Op0);
       CallBase *Op1AsCallBase = cast<CallBase>(Op1);
+      LibFunc Op0LibFunc, Op1LibFunc;
+
+      TLI.getLibFunc(*Op1AsCallBase, Op1LibFunc);
+      TLI.getLibFunc(*Op0AsCallBase, Op0LibFunc);
 
       bool ArgsMatch = match(Op0AsCallBase->getArgOperand(0), m_Value(Y)) &&
                        match(Op1AsCallBase->getArgOperand(0), m_Specific(Y));
 
-      bool IsTanH = Op0AsCallBase->getCalledFunction()->getName() == "sinh" &&
-                    Op1AsCallBase->getCalledFunction()->getName() == "cosh" &&
-                    ArgsMatch;
+      bool IsTanH = ArgsMatch &&
+                    ((Op0LibFunc == LibFunc_sinh && Op1LibFunc == LibFunc_cosh) ||
+                    (Op0LibFunc == LibFunc_sinhf && Op1LibFunc == LibFunc_coshf) ||
+                    (Op0LibFunc == LibFunc_sinhl && Op1LibFunc == LibFunc_coshl));
 
       bool IsCotH = !IsTanH && ArgsMatch &&
-                    Op0AsCallBase->getCalledFunction()->getName() == "cosh" &&
-                    Op1AsCallBase->getCalledFunction()->getName() == "sinh";
+                    ((Op1LibFunc == LibFunc_sinh && Op0LibFunc == LibFunc_cosh) ||
+                    (Op1LibFunc == LibFunc_sinhf && Op0LibFunc == LibFunc_coshf) ||
+                    (Op1LibFunc == LibFunc_sinhl && Op0LibFunc == LibFunc_coshl)); 
 
       if ((IsTanH || IsCotH) && hasFloatFn(M, &TLI, I.getType(), LibFunc_tanh,
                                            LibFunc_tanhf, LibFunc_tanhl)) {
 
         Value *Res =
-            GetReplacement(Y, false, LibFunc_tanh, LibFunc_tanf, LibFunc_tanl);
+            GetReplacement(Y, IsCotH, LibFunc_tanh, LibFunc_tanf, LibFunc_tanl);
 
-        Instruction *Result = replaceInstUsesWith(I, Res);
+        Instruction *Replacement = replaceInstUsesWith(I,Res);
 
         // Call instructions of sinh and cosh need to be erased seperatly
         if (!Op0AsCallBase->use_empty())
@@ -1837,7 +1846,7 @@ Instruction *InstCombinerImpl::visitFDiv(BinaryOperator &I) {
         Op0AsCallBase->eraseFromParent();
         Op1AsCallBase->eraseFromParent();
 
-        return Result;
+        return Replacement;
       }
     }
   }
@@ -1867,8 +1876,9 @@ Instruction *InstCombinerImpl::visitFDiv(BinaryOperator &I) {
     return Mul;
 
   // pow(X, Y) / X --> pow(X, Y-1)
-  if (I.hasAllowReassoc() && match(Op0, m_OneUse(m_Intrinsic<Intrinsic::pow>(
-                                            m_Specific(Op1), m_Value(Y))))) {
+  if (I.hasAllowReassoc() && 
+      match(Op0, m_OneUse(m_Intrinsic<Intrinsic::pow>(
+                          m_Specific(Op1), m_Value(Y))))) {
     Value *Y1 =
         Builder.CreateFAddFMF(Y, ConstantFP::get(I.getType(), -1.0), &I);
     Value *Pow = Builder.CreateBinaryIntrinsic(Intrinsic::pow, Op1, Y1, &I);
@@ -2178,7 +2188,7 @@ Instruction *InstCombinerImpl::visitSRem(BinaryOperator &I) {
     if (hasNegative && !hasMissing) {
       SmallVector<Constant *, 16> Elts(VWidth);
       for (unsigned i = 0; i != VWidth; ++i) {
-        Elts[i] = C->getAggregateElement(i); // Handle undef, etc.
+        Elts[i] = C->getAggregateElement(i);  // Handle undef, etc.
         if (ConstantInt *RHS = dyn_cast<ConstantInt>(Elts[i])) {
           if (RHS->isNegative())
             Elts[i] = cast<ConstantInt>(ConstantExpr::getNeg(RHS));
@@ -2186,7 +2196,7 @@ Instruction *InstCombinerImpl::visitSRem(BinaryOperator &I) {
       }
 
       Constant *NewRHSV = ConstantVector::get(Elts);
-      if (NewRHSV != C) // Don't loop on -MININT
+      if (NewRHSV != C)  // Don't loop on -MININT
         return replaceOperand(I, 1, NewRHSV);
     }
   }
@@ -2197,7 +2207,8 @@ Instruction *InstCombinerImpl::visitSRem(BinaryOperator &I) {
 Instruction *InstCombinerImpl::visitFRem(BinaryOperator &I) {
   if (Value *V =
           simplifyFRemInst(I.getOperand(0), I.getOperand(1),
-                           I.getFastMathFlags(), SQ.getWithInstruction(&I)))
+                           I.getFastMathFlags(),
+                           SQ.getWithInstruction(&I)))
     return replaceInstUsesWith(I, V);
 
   if (Instruction *X = foldVectorBinop(I))
diff --git a/llvm/test/Transforms/InstCombine/fdiv-cosh-sinh.ll b/llvm/test/Transforms/InstCombine/fdiv-cosh-sinh.ll
index 3c7d64d6ba5472..1427794a9aca49 100644
--- a/llvm/test/Transforms/InstCombine/fdiv-cosh-sinh.ll
+++ b/llvm/test/Transforms/InstCombine/fdiv-cosh-sinh.ll
@@ -29,8 +29,10 @@ define double @fdiv_strict_cosh_strict_sinh_reassoc(double %a) {
 
 define double @fdiv_reassoc_cosh_strict_sinh_strict(double %a, ptr dereferenceable(2) %dummy) {
 ; CHECK-LABEL: @fdiv_reassoc_cosh_strict_sinh_strict(
-; CHECK-NEXT:    [[TAN:%.*]] = call reassoc double @tanh(double [[A:%.*]])
-; CHECK-NEXT:    [[DIV:%.*]] = fdiv reassoc double 1.000000e+00, [[TAN]]
+; CHECK-NEXT:    [[TMP1:%.*]] = call double @cosh(double [[A:%.*]])
+; CHECK-NEXT:    [[TMP2:%.*]] = call double @sinh(double [[A]])
+; CHECK-NEXT:    [[TANH:%.*]] = call reassoc double @tanh(double [[A]])
+; CHECK-NEXT:    [[DIV:%.*]] = fdiv reassoc double 1.000000e+00, [[TANH]]
 ; CHECK-NEXT:    ret double [[DIV]]
 ;
   %1 = call double @cosh(double %a)
@@ -41,8 +43,10 @@ define double @fdiv_reassoc_cosh_strict_sinh_strict(double %a, ptr dereferenceab
 
 define double @fdiv_reassoc_cosh_reassoc_sinh_strict(double %a) {
 ; CHECK-LABEL: @fdiv_reassoc_cosh_reassoc_sinh_strict(
-; CHECK-NEXT:    [[TAN:%.*]] = call reassoc double @tanh(double [[A:%.*]])
-; CHECK-NEXT:    [[DIV:%.*]] = fdiv reassoc double 1.000000e+00, [[TAN]]
+; CHECK-NEXT:    [[TMP1:%.*]] = call reassoc double @cosh(double [[A:%.*]])
+; CHECK-NEXT:    [[TMP2:%.*]] = call double @sinh(double [[A]])
+; CHECK-NEXT:    [[TANH:%.*]] = call reassoc double @tanh(double [[A]])
+; CHECK-NEXT:    [[DIV:%.*]] = fdiv reassoc double 1.000000e+00, [[TANH]]
 ; CHECK-NEXT:    ret double [[DIV]]
 ;
   %1 = call reassoc double @cosh(double %a)
@@ -68,8 +72,10 @@ define double @fdiv_cosh_sinh_reassoc_multiple_uses(double %a) {
 
 define double @fdiv_cosh_sinh_reassoc(double %a){
 ; CHECK-LABEL: @fdiv_cosh_sinh_reassoc(
-; CHECK-NEXT:    [[TAN:%.*]] = call reassoc double @tanh(double [[A:%.*]])
-; CHECK-NEXT:    [[DIV:%.*]] = fdiv reassoc double 1.000000e+00, [[TAN]]
+; CHECK-NEXT:    [[TMP1:%.*]] = call reassoc double @cosh(double [[A:%.*]])
+; CHECK-NEXT:    [[TMP2:%.*]] = call reassoc double @sinh(double [[A]])
+; CHECK-NEXT:    [[TANH:%.*]] = call reassoc double @tanh(double [[A]])
+; CHECK-NEXT:    [[DIV:%.*]] = fdiv reassoc double 1.000000e+00, [[TANH]]
 ; CHECK-NEXT:    ret double [[DIV]]
 ;
   %1 = call reassoc double @cosh(double %a)
diff --git a/llvm/test/Transforms/InstCombine/fdiv-sinh-cosh.ll b/llvm/test/Transforms/InstCombine/fdiv-sinh-cosh.ll
index 3ece1686263e24..bd254f19794ba8 100644
--- a/llvm/test/Transforms/InstCombine/fdiv-sinh-cosh.ll
+++ b/llvm/test/Transforms/InstCombine/fdiv-sinh-cosh.ll
@@ -16,7 +16,9 @@ define double @fdiv_sinh_cosh(double %a) {
 
 define double @fdiv_reassoc_sinh_strict_cosh_strict(double %a, ptr dereferenceable(2) %dummy) {
 ; CHECK-LABEL: @fdiv_reassoc_sinh_strict_cosh_strict(
-; CHECK-NEXT:    [[TANH:%.*]] = call reassoc double @tanh(double [[A:%.*]])
+; CHECK-NEXT:    [[TMP1:%.*]] = call double @sinh(double [[A:%.*]])
+; CHECK-NEXT:    [[TMP2:%.*]] = call double @cosh(double [[A]])
+; CHECK-NEXT:    [[TANH:%.*]] = call reassoc double @tanh(double [[A]])
 ; CHECK-NEXT:    ret double [[TANH]]
 ;
   %1 = call double @sinh(double %a)
@@ -27,7 +29,9 @@ define double @fdiv_reassoc_sinh_strict_cosh_strict(double %a, ptr dereferenceab
 
 define double @fdiv_reassoc_sinh_reassoc_cosh_strict(double %a) {
 ; CHECK-LABEL: @fdiv_reassoc_sinh_reassoc_cosh_strict(
-; CHECK-NEXT:    [[TANH:%.*]] = call reassoc double @tanh(double [[A:%.*]])
+; CHECK-NEXT:    [[TMP1:%.*]] = call reassoc double @sinh(double [[A:%.*]])
+; CHECK-NEXT:    [[TMP2:%.*]] = call double @cosh(double [[A]])
+; CHECK-NEXT:    [[TANH:%.*]] = call reassoc double @tanh(double [[A]])
 ; CHECK-NEXT:    ret double [[TANH]]
 ;
   %1 = call reassoc double @sinh(double %a)
@@ -69,7 +73,9 @@ define double @fdiv_sin_cos_reassoc_multiple_uses_cosh(double %a) {
 
 define double @fdiv_sinh_cosh_reassoc(double %a) {
 ; CHECK-LABEL: @fdiv_sinh_cosh_reassoc(
-; CHECK-NEXT:    [[TANH:%.*]] = call reassoc double @tanh(double [[A:%.*]])
+; CHECK-NEXT:    [[TMP1:%.*]] = call reassoc double @sinh(double [[A:%.*]])
+; CHECK-NEXT:    [[TMP2:%.*]] = call reassoc double @cosh(double [[A]])
+; CHECK-NEXT:    [[TANH:%.*]] = call reassoc double @tanh(double [[A]])
 ; CHECK-NEXT:    ret double [[TANH]]
 ;
   %1 = call reassoc double @sinh(double %a)

>From 2a0d8cbe8cfe8696dcd129b063f54a9c8be84cbb Mon Sep 17 00:00:00 2001
From: Felix Kellenbenz <fe.kellenbenz.computer at outlook.de>
Date: Mon, 12 Feb 2024 14:59:01 +0100
Subject: [PATCH 3/6] Update tests and undo unrelated clang format changes

---
 .../InstCombine/InstCombineMulDivRem.cpp      | 28 +++++++++----------
 .../Transforms/InstCombine/fdiv-cosh-sinh.ll  |  6 ----
 .../Transforms/InstCombine/fdiv-sinh-cosh.ll  |  6 ----
 3 files changed, 13 insertions(+), 27 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
index 700c2883084759..12dd3972e0a7cd 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -15,7 +15,6 @@
 #include "llvm/ADT/APInt.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Analysis/InstructionSimplify.h"
-#include "llvm/Analysis/TargetLibraryInfo.h"
 #include "llvm/Analysis/ValueTracking.h"
 #include "llvm/IR/BasicBlock.h"
 #include "llvm/IR/Constant.h"
@@ -224,7 +223,8 @@ Instruction *InstCombinerImpl::visitMul(BinaryOperator &I) {
     Value *NewOp;
     Constant *C1, *C2;
     const APInt *IVal;
-    if (match(&I, m_Mul(m_Shl(m_Value(NewOp), m_Constant(C2)), m_Constant(C1))) &&
+    if (match(&I, m_Mul(m_Shl(m_Value(NewOp),
+                        m_Constant(C2)), m_Constant(C1))) &&
         match(C1, m_APInt(IVal))) {
       // ((X << C2)*C1) == (X * (C1 << C2))
       Constant *Shl = ConstantExpr::getShl(C1, C2);
@@ -410,7 +410,7 @@ Instruction *InstCombinerImpl::visitMul(BinaryOperator &I) {
   //   2) X * Y --> X & Y, iff X, Y can be only {0,1}.
   // Note: We could use known bits to generalize this and related patterns with
   // shifts/truncs
-  if (Ty->isIntOrIntVectorTy(1) || 
+  if (Ty->isIntOrIntVectorTy(1) ||
       (match(Op0, m_And(m_Value(), m_One())) &&
        match(Op1, m_And(m_Value(), m_One()))))
     return BinaryOperator::CreateAnd(Op0, Op1);
@@ -746,10 +746,9 @@ Instruction *InstCombinerImpl::foldFMulReassoc(BinaryOperator &I) {
 }
 
 Instruction *InstCombinerImpl::visitFMul(BinaryOperator &I) {
-  if (Value *V =
-          simplifyFMulInst(I.getOperand(0), I.getOperand(1),
-                           I.getFastMathFlags(),
-                           SQ.getWithInstruction(&I)))
+  if (Value *V = simplifyFMulInst(I.getOperand(0), I.getOperand(1),
+                                  I.getFastMathFlags(),
+                                  SQ.getWithInstruction(&I)))
     return replaceInstUsesWith(I, V);
 
   if (SimplifyAssociativeOrCommutative(I))
@@ -1302,7 +1301,7 @@ static Value *takeLog2(IRBuilderBase &Builder, Value *Op, unsigned Depth,
   // log2(Cond ? X : Y) -> Cond ? log2(X) : log2(Y)
   // FIXME: Require one use?
   if (SelectInst *SI = dyn_cast<SelectInst>(Op))
-    if (Value *LogX = takeLog2(Builder, SI->getOperand(1), Depth, 
+    if (Value *LogX = takeLog2(Builder, SI->getOperand(1), Depth,
                                AssumeNonZero, DoFold))
       if (Value *LogY = takeLog2(Builder, SI->getOperand(2), Depth,
                                  AssumeNonZero, DoFold))
@@ -1711,7 +1710,7 @@ Instruction *InstCombinerImpl::visitFDiv(BinaryOperator &I) {
   Module *M = I.getModule();
 
   if (Value *V = simplifyFDivInst(I.getOperand(0), I.getOperand(1),
-                                  I.getFastMathFlags(), 
+                                  I.getFastMathFlags(),
                                   SQ.getWithInstruction(&I)))
     return replaceInstUsesWith(I, V);
 
@@ -1877,8 +1876,8 @@ Instruction *InstCombinerImpl::visitFDiv(BinaryOperator &I) {
 
   // pow(X, Y) / X --> pow(X, Y-1)
   if (I.hasAllowReassoc() && 
-      match(Op0, m_OneUse(m_Intrinsic<Intrinsic::pow>(
-                          m_Specific(Op1), m_Value(Y))))) {
+      match(Op0, m_OneUse(m_Intrinsic<Intrinsic::pow>(m_Specific(Op1),
+                                                      m_Value(Y))))) {
     Value *Y1 =
         Builder.CreateFAddFMF(Y, ConstantFP::get(I.getType(), -1.0), &I);
     Value *Pow = Builder.CreateBinaryIntrinsic(Intrinsic::pow, Op1, Y1, &I);
@@ -2205,10 +2204,9 @@ Instruction *InstCombinerImpl::visitSRem(BinaryOperator &I) {
 }
 
 Instruction *InstCombinerImpl::visitFRem(BinaryOperator &I) {
-  if (Value *V =
-          simplifyFRemInst(I.getOperand(0), I.getOperand(1),
-                           I.getFastMathFlags(),
-                           SQ.getWithInstruction(&I)))
+  if (Value *V = simplifyFRemInst(I.getOperand(0), I.getOperand(1),
+                                  I.getFastMathFlags(),
+                                  SQ.getWithInstruction(&I)))
     return replaceInstUsesWith(I, V);
 
   if (Instruction *X = foldVectorBinop(I))
diff --git a/llvm/test/Transforms/InstCombine/fdiv-cosh-sinh.ll b/llvm/test/Transforms/InstCombine/fdiv-cosh-sinh.ll
index 1427794a9aca49..df6943b0af0084 100644
--- a/llvm/test/Transforms/InstCombine/fdiv-cosh-sinh.ll
+++ b/llvm/test/Transforms/InstCombine/fdiv-cosh-sinh.ll
@@ -29,8 +29,6 @@ define double @fdiv_strict_cosh_strict_sinh_reassoc(double %a) {
 
 define double @fdiv_reassoc_cosh_strict_sinh_strict(double %a, ptr dereferenceable(2) %dummy) {
 ; CHECK-LABEL: @fdiv_reassoc_cosh_strict_sinh_strict(
-; CHECK-NEXT:    [[TMP1:%.*]] = call double @cosh(double [[A:%.*]])
-; CHECK-NEXT:    [[TMP2:%.*]] = call double @sinh(double [[A]])
 ; CHECK-NEXT:    [[TANH:%.*]] = call reassoc double @tanh(double [[A]])
 ; CHECK-NEXT:    [[DIV:%.*]] = fdiv reassoc double 1.000000e+00, [[TANH]]
 ; CHECK-NEXT:    ret double [[DIV]]
@@ -43,8 +41,6 @@ define double @fdiv_reassoc_cosh_strict_sinh_strict(double %a, ptr dereferenceab
 
 define double @fdiv_reassoc_cosh_reassoc_sinh_strict(double %a) {
 ; CHECK-LABEL: @fdiv_reassoc_cosh_reassoc_sinh_strict(
-; CHECK-NEXT:    [[TMP1:%.*]] = call reassoc double @cosh(double [[A:%.*]])
-; CHECK-NEXT:    [[TMP2:%.*]] = call double @sinh(double [[A]])
 ; CHECK-NEXT:    [[TANH:%.*]] = call reassoc double @tanh(double [[A]])
 ; CHECK-NEXT:    [[DIV:%.*]] = fdiv reassoc double 1.000000e+00, [[TANH]]
 ; CHECK-NEXT:    ret double [[DIV]]
@@ -72,8 +68,6 @@ define double @fdiv_cosh_sinh_reassoc_multiple_uses(double %a) {
 
 define double @fdiv_cosh_sinh_reassoc(double %a){
 ; CHECK-LABEL: @fdiv_cosh_sinh_reassoc(
-; CHECK-NEXT:    [[TMP1:%.*]] = call reassoc double @cosh(double [[A:%.*]])
-; CHECK-NEXT:    [[TMP2:%.*]] = call reassoc double @sinh(double [[A]])
 ; CHECK-NEXT:    [[TANH:%.*]] = call reassoc double @tanh(double [[A]])
 ; CHECK-NEXT:    [[DIV:%.*]] = fdiv reassoc double 1.000000e+00, [[TANH]]
 ; CHECK-NEXT:    ret double [[DIV]]
diff --git a/llvm/test/Transforms/InstCombine/fdiv-sinh-cosh.ll b/llvm/test/Transforms/InstCombine/fdiv-sinh-cosh.ll
index bd254f19794ba8..8a6b576bf0ecbc 100644
--- a/llvm/test/Transforms/InstCombine/fdiv-sinh-cosh.ll
+++ b/llvm/test/Transforms/InstCombine/fdiv-sinh-cosh.ll
@@ -16,8 +16,6 @@ define double @fdiv_sinh_cosh(double %a) {
 
 define double @fdiv_reassoc_sinh_strict_cosh_strict(double %a, ptr dereferenceable(2) %dummy) {
 ; CHECK-LABEL: @fdiv_reassoc_sinh_strict_cosh_strict(
-; CHECK-NEXT:    [[TMP1:%.*]] = call double @sinh(double [[A:%.*]])
-; CHECK-NEXT:    [[TMP2:%.*]] = call double @cosh(double [[A]])
 ; CHECK-NEXT:    [[TANH:%.*]] = call reassoc double @tanh(double [[A]])
 ; CHECK-NEXT:    ret double [[TANH]]
 ;
@@ -29,8 +27,6 @@ define double @fdiv_reassoc_sinh_strict_cosh_strict(double %a, ptr dereferenceab
 
 define double @fdiv_reassoc_sinh_reassoc_cosh_strict(double %a) {
 ; CHECK-LABEL: @fdiv_reassoc_sinh_reassoc_cosh_strict(
-; CHECK-NEXT:    [[TMP1:%.*]] = call reassoc double @sinh(double [[A:%.*]])
-; CHECK-NEXT:    [[TMP2:%.*]] = call double @cosh(double [[A]])
 ; CHECK-NEXT:    [[TANH:%.*]] = call reassoc double @tanh(double [[A]])
 ; CHECK-NEXT:    ret double [[TANH]]
 ;
@@ -73,8 +69,6 @@ define double @fdiv_sin_cos_reassoc_multiple_uses_cosh(double %a) {
 
 define double @fdiv_sinh_cosh_reassoc(double %a) {
 ; CHECK-LABEL: @fdiv_sinh_cosh_reassoc(
-; CHECK-NEXT:    [[TMP1:%.*]] = call reassoc double @sinh(double [[A:%.*]])
-; CHECK-NEXT:    [[TMP2:%.*]] = call reassoc double @cosh(double [[A]])
 ; CHECK-NEXT:    [[TANH:%.*]] = call reassoc double @tanh(double [[A]])
 ; CHECK-NEXT:    ret double [[TANH]]
 ;

>From 29bd3174d79f0685ae5b23e17ed451f0c41beb4f Mon Sep 17 00:00:00 2001
From: Felix Kellenbenz <fe.kellenbenz.computer at outlook.de>
Date: Mon, 12 Feb 2024 18:26:22 +0100
Subject: [PATCH 4/6] Remove more unwanted format changes

---
 .../InstCombine/InstCombineMulDivRem.cpp      | 26 ++++++++++---------
 1 file changed, 14 insertions(+), 12 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
index 12dd3972e0a7cd..3fc90d796eb3b8 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -223,8 +223,8 @@ Instruction *InstCombinerImpl::visitMul(BinaryOperator &I) {
     Value *NewOp;
     Constant *C1, *C2;
     const APInt *IVal;
-    if (match(&I, m_Mul(m_Shl(m_Value(NewOp),
-                        m_Constant(C2)), m_Constant(C1))) &&
+    if (match(&I, m_Mul(m_Shl(m_Value(NewOp), m_Constant(C2)),
+                        m_Constant(C1))) &&
         match(C1, m_APInt(IVal))) {
       // ((X << C2)*C1) == (X * (C1 << C2))
       Constant *Shl = ConstantExpr::getShl(C1, C2);
@@ -1815,15 +1815,17 @@ Instruction *InstCombinerImpl::visitFDiv(BinaryOperator &I) {
       bool ArgsMatch = match(Op0AsCallBase->getArgOperand(0), m_Value(Y)) &&
                        match(Op1AsCallBase->getArgOperand(0), m_Specific(Y));
 
-      bool IsTanH = ArgsMatch &&
-                    ((Op0LibFunc == LibFunc_sinh && Op1LibFunc == LibFunc_cosh) ||
-                    (Op0LibFunc == LibFunc_sinhf && Op1LibFunc == LibFunc_coshf) ||
-                    (Op0LibFunc == LibFunc_sinhl && Op1LibFunc == LibFunc_coshl));
+      bool IsTanH = 
+        ArgsMatch &&
+        ((Op0LibFunc == LibFunc_sinh && Op1LibFunc == LibFunc_cosh) ||
+         (Op0LibFunc == LibFunc_sinhf && Op1LibFunc == LibFunc_coshf) |
+         (Op0LibFunc == LibFunc_sinhl && Op1LibFunc == LibFunc_coshl));
 
-      bool IsCotH = !IsTanH && ArgsMatch &&
-                    ((Op1LibFunc == LibFunc_sinh && Op0LibFunc == LibFunc_cosh) ||
-                    (Op1LibFunc == LibFunc_sinhf && Op0LibFunc == LibFunc_coshf) ||
-                    (Op1LibFunc == LibFunc_sinhl && Op0LibFunc == LibFunc_coshl)); 
+      bool IsCotH = 
+        !IsTanH && ArgsMatch &&
+        ((Op1LibFunc == LibFunc_sinh && Op0LibFunc == LibFunc_cosh) |
+         (Op1LibFunc == LibFunc_sinhf && Op0LibFunc == LibFunc_coshf) ||
+         (Op1LibFunc == LibFunc_sinhl && Op0LibFunc == LibFunc_coshl)); 
 
       if ((IsTanH || IsCotH) && hasFloatFn(M, &TLI, I.getType(), LibFunc_tanh,
                                            LibFunc_tanhf, LibFunc_tanhl)) {
@@ -1831,7 +1833,7 @@ Instruction *InstCombinerImpl::visitFDiv(BinaryOperator &I) {
         Value *Res =
             GetReplacement(Y, IsCotH, LibFunc_tanh, LibFunc_tanf, LibFunc_tanl);
 
-        Instruction *Replacement = replaceInstUsesWith(I,Res);
+        Instruction *Replacement = replaceInstUsesWith(I, Res);
 
         // Call instructions of sinh and cosh need to be erased seperatly
         if (!Op0AsCallBase->use_empty())
@@ -1875,7 +1877,7 @@ Instruction *InstCombinerImpl::visitFDiv(BinaryOperator &I) {
     return Mul;
 
   // pow(X, Y) / X --> pow(X, Y-1)
-  if (I.hasAllowReassoc() && 
+  if (I.hasAllowReassoc() &&
       match(Op0, m_OneUse(m_Intrinsic<Intrinsic::pow>(m_Specific(Op1),
                                                       m_Value(Y))))) {
     Value *Y1 =

>From aa1faaf5c43cf0527dec83cc5e10a753f8163ddf Mon Sep 17 00:00:00 2001
From: Felix Kellenbenz <fe.kellenbenz.computer at outlook.de>
Date: Tue, 13 Feb 2024 21:12:46 +0100
Subject: [PATCH 5/6] Add new regression tests for float and long double

---
 .../InstCombine/InstCombineMulDivRem.cpp      |  2 +-
 .../Transforms/InstCombine/fdiv-cosh-sinh.ll  | 31 +++++++++++++++++--
 .../Transforms/InstCombine/fdiv-sinh-cosh.ll  | 27 ++++++++++++++++
 3 files changed, 57 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
index 3fc90d796eb3b8..5bea9f709847be 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -1831,7 +1831,7 @@ Instruction *InstCombinerImpl::visitFDiv(BinaryOperator &I) {
                                            LibFunc_tanhf, LibFunc_tanhl)) {
 
         Value *Res =
-            GetReplacement(Y, IsCotH, LibFunc_tanh, LibFunc_tanf, LibFunc_tanl);
+            GetReplacement(Y, IsCotH, LibFunc_tanh, LibFunc_tanhf, LibFunc_tanhl);
 
         Instruction *Replacement = replaceInstUsesWith(I, Res);
 
diff --git a/llvm/test/Transforms/InstCombine/fdiv-cosh-sinh.ll b/llvm/test/Transforms/InstCombine/fdiv-cosh-sinh.ll
index df6943b0af0084..12565626a87c51 100644
--- a/llvm/test/Transforms/InstCombine/fdiv-cosh-sinh.ll
+++ b/llvm/test/Transforms/InstCombine/fdiv-cosh-sinh.ll
@@ -78,10 +78,37 @@ define double @fdiv_cosh_sinh_reassoc(double %a){
   ret double %div
 }
 
+define fp128 @fdiv_coshl_sinhl_reassoc(fp128 %a){
+; CHECK-LABEL: @fdiv_coshl_sinhl_reassoc(
+; CHECK-NEXT:    [[TANH:%.*]] = call reassoc fp128 @tanhl(fp128 [[A]])
+; CHECK-NEXT:    [[DIV:%.*]] = fdiv reassoc fp128 0xL00000000000000003FFF000000000000, [[TANH]]
+; CHECK-NEXT:    ret fp128 [[DIV]]
+;
+  %1 = call reassoc fp128 @coshl(fp128 %a)
+  %2 = call reassoc fp128 @sinhl(fp128 %a)
+  %div = fdiv reassoc fp128 %1, %2
+  ret fp128 %div
+}
+
+
+define float @fdiv_coshf_sinhf_reassoc(float %a){
+; CHECK-LABEL: @fdiv_coshf_sinhf_reassoc(
+; CHECK-NEXT:    [[TANH:%.*]] = call reassoc float @tanhf(float [[A]])
+; CHECK-NEXT:    [[DIV:%.*]] = fdiv reassoc float 1.000000e+00, [[TANH]]
+; CHECK-NEXT:    ret float [[DIV]]
+;
+  %1 = call reassoc float @coshf(float %a)
+  %2 = call reassoc float @sinhf(float %a)
+  %div = fdiv reassoc float %1, %2
+  ret float %div
+}
 
 declare double @cosh(double)
-declare double @sinh(double)
+declare float @coshf(float)
+declare fp128 @coshl(fp128)
 
-declare double @tanh(double)
+declare double @sinh(double)
+declare float @sinhf(float)
+declare fp128 @sinhl(fp128)
 
 declare void @use(double)
diff --git a/llvm/test/Transforms/InstCombine/fdiv-sinh-cosh.ll b/llvm/test/Transforms/InstCombine/fdiv-sinh-cosh.ll
index 8a6b576bf0ecbc..e81b07ae6428e0 100644
--- a/llvm/test/Transforms/InstCombine/fdiv-sinh-cosh.ll
+++ b/llvm/test/Transforms/InstCombine/fdiv-sinh-cosh.ll
@@ -78,7 +78,34 @@ define double @fdiv_sinh_cosh_reassoc(double %a) {
   ret double %div
 }
 
+define float @fdiv_sinhf_coshf_reassoc(float %a) {
+; CHECK-LABEL: @fdiv_sinhf_coshf_reassoc(
+; CHECK-NEXT:    [[TANH:%.*]] = call reassoc float @tanhf(float [[A]])
+; CHECK-NEXT:    ret float [[TANH]]
+;
+  %1 = call reassoc float @sinhf(float %a)
+  %2 = call reassoc float @coshf(float %a)
+  %div = fdiv reassoc float %1, %2
+  ret float %div
+}
+
+define fp128 @fdiv_sinhl_coshl_reassoc(fp128 %a) {
+; CHECK-LABEL: @fdiv_sinhl_coshl_reassoc(
+; CHECK-NEXT:    [[TANH:%.*]] = call reassoc fp128 @tanhl(fp128 [[A]])
+; CHECK-NEXT:    ret fp128 [[TANH]]
+;
+  %1 = call reassoc fp128 @sinhl(fp128 %a)
+  %2 = call reassoc fp128 @coshl(fp128 %a)
+  %div = fdiv reassoc fp128 %1, %2
+  ret fp128 %div
+}
+
 declare double @cosh(double)
+declare float @coshf(float)
+declare fp128 @coshl(fp128)
+
 declare double @sinh(double)
+declare float @sinhf(float)
+declare fp128 @sinhl(fp128)
 
 declare void @use(double)

>From 5b82857ef03d99b4a0f32656d06c26bcce8b52b0 Mon Sep 17 00:00:00 2001
From: Felix Kellenbenz <fe.kellenbenz.computer at outlook.de>
Date: Tue, 13 Feb 2024 21:22:02 +0100
Subject: [PATCH 6/6] Format my changes and change logical or

---
 .../InstCombine/InstCombineMulDivRem.cpp      | 26 +++++++++----------
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
index 5bea9f709847be..a88e7be5604bd6 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -1815,23 +1815,23 @@ Instruction *InstCombinerImpl::visitFDiv(BinaryOperator &I) {
       bool ArgsMatch = match(Op0AsCallBase->getArgOperand(0), m_Value(Y)) &&
                        match(Op1AsCallBase->getArgOperand(0), m_Specific(Y));
 
-      bool IsTanH = 
-        ArgsMatch &&
-        ((Op0LibFunc == LibFunc_sinh && Op1LibFunc == LibFunc_cosh) ||
-         (Op0LibFunc == LibFunc_sinhf && Op1LibFunc == LibFunc_coshf) |
-         (Op0LibFunc == LibFunc_sinhl && Op1LibFunc == LibFunc_coshl));
-
-      bool IsCotH = 
-        !IsTanH && ArgsMatch &&
-        ((Op1LibFunc == LibFunc_sinh && Op0LibFunc == LibFunc_cosh) |
-         (Op1LibFunc == LibFunc_sinhf && Op0LibFunc == LibFunc_coshf) ||
-         (Op1LibFunc == LibFunc_sinhl && Op0LibFunc == LibFunc_coshl)); 
+      bool IsTanH =
+          ArgsMatch &&
+          ((Op0LibFunc == LibFunc_sinh && Op1LibFunc == LibFunc_cosh) ||
+           (Op0LibFunc == LibFunc_sinhf && Op1LibFunc == LibFunc_coshf) ||
+           (Op0LibFunc == LibFunc_sinhl && Op1LibFunc == LibFunc_coshl));
+
+      bool IsCotH =
+          !IsTanH && ArgsMatch &&
+          ((Op1LibFunc == LibFunc_sinh && Op0LibFunc == LibFunc_cosh) ||
+           (Op1LibFunc == LibFunc_sinhf && Op0LibFunc == LibFunc_coshf) ||
+           (Op1LibFunc == LibFunc_sinhl && Op0LibFunc == LibFunc_coshl));
 
       if ((IsTanH || IsCotH) && hasFloatFn(M, &TLI, I.getType(), LibFunc_tanh,
                                            LibFunc_tanhf, LibFunc_tanhl)) {
 
-        Value *Res =
-            GetReplacement(Y, IsCotH, LibFunc_tanh, LibFunc_tanhf, LibFunc_tanhl);
+        Value *Res = GetReplacement(Y, IsCotH, LibFunc_tanh, LibFunc_tanhf,
+                                    LibFunc_tanhl);
 
         Instruction *Replacement = replaceInstUsesWith(I, Res);
 



More information about the llvm-commits mailing list