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

Joshua Cranmer via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 27 13:54:42 PDT 2024


================
@@ -0,0 +1,114 @@
+; 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:    [[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)
+  %2 = call double @sinh(double %a)
+  %div = fdiv reassoc double %1, %2
----------------
jcranmer-intel wrote:

The historical use of our flags has been `reassoc` for these transformations, which feels wrong from a user perspective, but it's been the going rate.

I still haven't gotten to posting my RFC on fixing fast-math flags, but it's not clear to me that users appreciate that applying associativity laws means you get transformations on math library functions--I think most users would expect it to apply only associative and distributive laws to addition and multiplication.

I think these transformations are crying out for some sort of "algebraic identity flag", which I'd tentatively give semantics as "allow any transformation to another expression which would produce the same value if floats were computed as having infinite precision". Although such a definition still wouldn't suffice here: `sinh(inf)/cosh(inf)` is `inf/inf`, aka NaN, while `tanh(inf)` is inf.

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


More information about the llvm-commits mailing list