[PATCH] D86726: [InstCombine]: Transform 1.0/sqrt(X) * X to X/sqrt(X) and X * 1.0/sqrt(X) to X/sqrt(X)
Venkataramanan Kumar via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 27 10:34:14 PDT 2020
venkataramanan.kumar.llvm created this revision.
venkataramanan.kumar.llvm added a reviewer: spatel.
Herald added subscribers: llvm-commits, steven.zhang, hiraditya.
Herald added a project: LLVM.
venkataramanan.kumar.llvm requested review of this revision.
The patch does the following transforms in InstCombine.
1.0/sqrt(X) * X => X/sqrt(X)
X * 1.0/sqrt(X) => X/sqrt(X)
DagCombiner <https://reviews.llvm.org/rG62e91bf563337fff93be0059ecb1f4dae32d8980> can then optimizes the X/sqrt(x) to sqrt(X).
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D86726
Files:
llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
llvm/test/Transforms/InstCombine/fmul-sqrt.ll
Index: llvm/test/Transforms/InstCombine/fmul-sqrt.ll
===================================================================
--- llvm/test/Transforms/InstCombine/fmul-sqrt.ll
+++ llvm/test/Transforms/InstCombine/fmul-sqrt.ll
@@ -99,6 +99,45 @@
ret double %squared
}
+define double @rsqrt_a_reassociate(double %x) {
+; CHECK-LABEL: @rsqrt_a_reassociate(
+; CHECK-NEXT: [[SQRT:%.*]] = call fast double @llvm.sqrt.f64(double [[X:%.*]])
+; CHECK-NEXT: [[MULT:%.*]] = fdiv reassoc double [[X:%.*]], [[SQRT]]
+; CHECK-NEXT: ret double [[MULT]]
+;
+ %sqrt = call fast double @llvm.sqrt.f64(double %x)
+ %rsqrt = fdiv fast double 1.0, %sqrt
+ %mult = fmul reassoc double %rsqrt, %x
+ ret double %mult
+}
+
+define double @a_rsqrt_reassociate(double %x) {
+; CHECK-LABEL: @a_rsqrt_reassociate(
+; CHECK-NEXT: [[SQRT:%.*]] = call fast double @llvm.sqrt.f64(double [[X:%.*]])
+; CHECK-NEXT: [[DIV:%.*]] = fdiv reassoc double [[X:%.*]], [[SQRT]]
+; CHECK-NEXT: ret double [[DIV]]
+;
+ %sqrt = call fast double @llvm.sqrt.f64(double %x)
+ %rsqrt = fdiv fast double 1.0, %sqrt
+ %mult = fmul reassoc double %x, %rsqrt
+ ret double %mult
+}
+
+define double @rsqrt_a_reassociate_extra_use(double %x, double * %p) {
+; CHECK-LABEL: @rsqrt_a_reassociate_extra_use(
+; CHECK-NEXT: [[SQRT:%.*]] = call fast double @llvm.sqrt.f64(double [[X:%.*]])
+; CHECK-NEXT: [[RSQRT:%.*]] = fdiv fast double 1.000000e+00, [[SQRT]]
+; CHECK-NEXT: [[DIV:%.*]] = fdiv reassoc double [[X:%.*]], [[SQRT]]
+; CHECK-NEXT: store double [[RSQRT]], double* %p
+; CHECK-NEXT: ret double [[DIV]]
+;
+ %sqrt = call fast double @llvm.sqrt.f64(double %x)
+ %rsqrt = fdiv fast double 1.0, %sqrt
+ %res = fmul reassoc double %rsqrt, %x
+ store double %rsqrt, double* %p
+ ret double %res
+}
+
define double @sqrt_divisor_squared(double %x, double %y) {
; CHECK-LABEL: @sqrt_divisor_squared(
; CHECK-NEXT: [[TMP1:%.*]] = fmul reassoc nnan nsz double [[Y:%.*]], [[Y]]
Index: llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -544,6 +544,16 @@
return replaceInstUsesWith(I, Sqrt);
}
+ // 1.0/sqrt(X) * X = X/sqrt(X).
+ if (match(Op0, (m_FDiv(m_SpecificFP(1.0), m_Value(Y)))) &&
+ match(Y, m_Intrinsic<Intrinsic::sqrt>(m_Value(X))) && Op1 == X)
+ return BinaryOperator::CreateFDivFMF(X, Y, &I);
+
+ // X * 1.0/sqrt(X) = X/sqrt(X).
+ if (match(Op1, (m_FDiv(m_SpecificFP(1.0), m_Value(Y)))) &&
+ match(Y, m_Intrinsic<Intrinsic::sqrt>(m_Value(X))) && Op0 == X)
+ return BinaryOperator::CreateFDivFMF(X, Y, &I);
+
// Like the similar transform in instsimplify, this requires 'nsz' because
// sqrt(-0.0) = -0.0, and -0.0 * -0.0 does not simplify to -0.0.
if (I.hasNoNaNs() && I.hasNoSignedZeros() && Op0 == Op1 &&
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D86726.288384.patch
Type: text/x-patch
Size: 2975 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200827/928fccbc/attachment.bin>
More information about the llvm-commits
mailing list