[PATCH] D102574: [InstCombine] Missed optimization for pow(x, y) * pow(x, z) with fast-math
Daniil Seredkin via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Sun May 16 04:36:52 PDT 2021
vdsered updated this revision to Diff 345698.
vdsered added a comment.
Calling CreateBinaryIntrinsic instead of CreateIntrinsic for better readability
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D102574/new/
https://reviews.llvm.org/D102574
Files:
llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
llvm/test/Transforms/InstCombine/fmul-pow.ll
Index: llvm/test/Transforms/InstCombine/fmul-pow.ll
===================================================================
--- llvm/test/Transforms/InstCombine/fmul-pow.ll
+++ llvm/test/Transforms/InstCombine/fmul-pow.ll
@@ -78,13 +78,23 @@
define double @pow_ab_x_pow_ac_reassoc(double %a, double %b, double %c) {
; CHECK-LABEL: @pow_ab_x_pow_ac_reassoc(
-; CHECK-NEXT: [[TMP1:%.*]] = call double @llvm.pow.f64(double [[A:%.*]], double [[B:%.*]])
-; CHECK-NEXT: [[TMP2:%.*]] = call double @llvm.pow.f64(double [[A]], double [[C:%.*]])
-; CHECK-NEXT: [[MUL:%.*]] = fmul reassoc double [[TMP2]], [[TMP1]]
-; CHECK-NEXT: ret double [[MUL]]
+; CHECK-NEXT: [[TMP1:%.*]] = fadd double [[C:%.*]], [[B:%.*]]
+; CHECK-NEXT: [[TMP2:%.*]] = call double @llvm.pow.f64(double [[A:%.*]], double [[TMP1]])
+; CHECK-NEXT: ret double [[TMP2]]
;
%1 = call double @llvm.pow.f64(double %a, double %b)
%2 = call double @llvm.pow.f64(double %a, double %c)
%mul = fmul reassoc double %2, %1
ret double %mul
}
+
+define double @pow_ab_reassoc(double %a, double %b) {
+; CHECK-LABEL: @pow_ab_reassoc(
+; CHECK-NEXT: [[TMP1:%.*]] = fadd double [[B:%.*]], [[B]]
+; CHECK-NEXT: [[TMP2:%.*]] = call double @llvm.pow.f64(double [[A:%.*]], double [[TMP1]])
+; CHECK-NEXT: ret double [[TMP2]]
+;
+ %1 = call double @llvm.pow.f64(double %a, double %b)
+ %mul = fmul reassoc double %1, %1
+ ret double %mul
+}
Index: llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -462,6 +462,27 @@
return replaceInstUsesWith(I, V);
if (I.hasAllowReassoc()) {
+ // pow(x, y) * pow(x, z) -> pow(x, y + z)
+ // If operands of fmul are equal and they have exactly two uses, then
+ // they have one user. It is useful for a case like the one below
+ //
+ // %2 = pow %0, %1
+ // %3 = fmul %2, %2
+ // -->
+ // %2 = fadd %1, %1
+ // %3 = pow %0, %2
+ if (Op0->hasOneUse() || Op1->hasOneUse() ||
+ (Op1 == Op0 && Op1->hasNUses(2))) {
+ Value *X, *Y, *Z;
+ if (match(Op0, m_Intrinsic<Intrinsic::pow>(m_Value(X), m_Value(Y))))
+ if (match(Op1,
+ m_Intrinsic<Intrinsic::pow>(m_Specific(X), m_Value(Z)))) {
+ auto *Expo = Builder.CreateFAdd(Y, Z);
+ auto *NewPow = Builder.CreateBinaryIntrinsic(Intrinsic::pow, X, Expo);
+ return replaceInstUsesWith(I, NewPow);
+ }
+ }
+
// Reassociate constant RHS with another constant to form constant
// expression.
if (match(Op1, m_Constant(C)) && C->isFiniteNonZeroFP()) {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D102574.345698.patch
Type: text/x-patch
Size: 2737 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210516/dfa5e557/attachment.bin>
More information about the llvm-commits
mailing list