[PATCH] D42385: [InstSimplify] (X * Y) / Y --> X for relaxed floating-point ops
Sanjay Patel via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Jan 22 10:53:09 PST 2018
spatel created this revision.
spatel added reviewers: efriedma, hfinkel, RKSimon.
Herald added a subscriber: mcrosier.
This is the FP counterpart that was mentioned in PR35709:
https://bugs.llvm.org/show_bug.cgi?id=35709
I suspect we're missing other similar basic folds for FP reassociations.
https://reviews.llvm.org/D42385
Files:
include/llvm/IR/PatternMatch.h
lib/Analysis/InstructionSimplify.cpp
test/Transforms/InstSimplify/fdiv.ll
Index: test/Transforms/InstSimplify/fdiv.ll
===================================================================
--- test/Transforms/InstSimplify/fdiv.ll
+++ test/Transforms/InstSimplify/fdiv.ll
@@ -34,3 +34,37 @@
%r = fdiv double %X, undef
ret double %r
}
+
+define double @fmul_fdiv_common_operand(double %x, double %y) {
+; CHECK-LABEL: @fmul_fdiv_common_operand(
+; CHECK-NEXT: ret double %x
+;
+ %m = fmul double %x, %y
+ %d = fdiv reassoc nnan double %m, %y
+ ret double %d
+}
+
+; Negative test - the fdiv must be reassociative and not allow NaNs.
+
+define double @fmul_fdiv_common_operand_too_strict(double %x, double %y) {
+; CHECK-LABEL: @fmul_fdiv_common_operand_too_strict(
+; CHECK-NEXT: [[M:%.*]] = fmul fast double %x, %y
+; CHECK-NEXT: [[D:%.*]] = fdiv reassoc double [[M]], %y
+; CHECK-NEXT: ret double [[D]]
+;
+ %m = fmul fast double %x, %y
+ %d = fdiv reassoc double %m, %y
+ ret double %d
+}
+
+; Commute the fmul operands. Use a vector type to verify that works too.
+
+define <2 x float> @fmul_fdiv_common_operand_commute_vec(<2 x float> %x, <2 x float> %y) {
+; CHECK-LABEL: @fmul_fdiv_common_operand_commute_vec(
+; CHECK-NEXT: ret <2 x float> %x
+;
+ %m = fmul <2 x float> %y, %x
+ %d = fdiv fast <2 x float> %m, %y
+ ret <2 x float> %d
+}
+
Index: lib/Analysis/InstructionSimplify.cpp
===================================================================
--- lib/Analysis/InstructionSimplify.cpp
+++ lib/Analysis/InstructionSimplify.cpp
@@ -4290,9 +4290,15 @@
if (FMF.noNaNs()) {
// X / X -> 1.0 is legal when NaNs are ignored.
+ // We can ignore infinities because INF/INF is NaN.
if (Op0 == Op1)
return ConstantFP::get(Op0->getType(), 1.0);
+ // (X * Y) / Y --> X if we can reassociate to the above form.
+ Value *X;
+ if (FMF.allowReassoc() && match(Op0, m_c_FMul(m_Value(X), m_Specific(Op1))))
+ return X;
+
// -X / X -> -1.0 and
// X / -X -> -1.0 are legal when NaNs are ignored.
// We can ignore signed zeros because +-0.0/+-0.0 is NaN and ignored.
Index: include/llvm/IR/PatternMatch.h
===================================================================
--- include/llvm/IR/PatternMatch.h
+++ include/llvm/IR/PatternMatch.h
@@ -1555,6 +1555,20 @@
return MaxMin_match<ICmpInst, LHS, RHS, umax_pred_ty, true>(L, R);
}
+/// Matches FAdd with LHS and RHS in either order.
+template <typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::FAdd, true>
+m_c_FAdd(const LHS &L, const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::FAdd, true>(L, R);
+}
+
+/// Matches FMul with LHS and RHS in either order.
+template <typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::FMul, true>
+m_c_FMul(const LHS &L, const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::FMul, true>(L, R);
+}
+
} // end namespace PatternMatch
} // end namespace llvm
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D42385.130924.patch
Type: text/x-patch
Size: 2925 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180122/b4ffb2fb/attachment.bin>
More information about the llvm-commits
mailing list