[llvm] r326098 - [InstCombine] allow fdiv folds with less than fully 'fast' ops
Sanjay Patel via llvm-commits
llvm-commits at lists.llvm.org
Mon Feb 26 08:02:45 PST 2018
Author: spatel
Date: Mon Feb 26 08:02:45 2018
New Revision: 326098
URL: http://llvm.org/viewvc/llvm-project?rev=326098&view=rev
Log:
[InstCombine] allow fdiv folds with less than fully 'fast' ops
Note: gcc appears to allow this fold with -freciprocal-math alone,
but clang/llvm require more than that with this patch. The wording
in the definitions seems fuzzy enough that it could go either way,
but we'll err on the conservative side of FMF interpretation.
This patch also changes the newly created fmul to have FMF propagated
by the last fdiv rather than intersecting the FMF of the fdivs. This
matches the behavior of other folds near here. The new fmul is only
used to produce an intermediate op for the final fdiv result, so it
shouldn't be any stricter than that result. The previous behavior
could result in dropping FMF via other folds in instcombine or CSE.
Differential Revision: https://reviews.llvm.org/D43398
Modified:
llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
llvm/trunk/test/Transforms/InstCombine/fdiv.ll
Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp?rev=326098&r1=326097&r2=326098&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp Mon Feb 26 08:02:45 2018
@@ -1347,28 +1347,18 @@ Instruction *InstCombiner::visitFDiv(Bin
if (Instruction *R = FoldOpIntoSelect(I, SI))
return R;
- if (I.isFast()) {
+ if (I.hasAllowReassoc() && I.hasAllowReciprocal()) {
Value *X, *Y;
if (match(Op0, m_OneUse(m_FDiv(m_Value(X), m_Value(Y)))) &&
(!isa<Constant>(Y) || !isa<Constant>(Op1))) {
// (X / Y) / Z => X / (Y * Z)
- Value *YZ = Builder.CreateFMul(Y, Op1);
- if (auto *YZInst = dyn_cast<Instruction>(YZ)) {
- FastMathFlags FMFIntersect = I.getFastMathFlags();
- FMFIntersect &= cast<Instruction>(Op0)->getFastMathFlags();
- YZInst->setFastMathFlags(FMFIntersect);
- }
+ Value *YZ = Builder.CreateFMulFMF(Y, Op1, &I);
return BinaryOperator::CreateFDivFMF(X, YZ, &I);
}
if (match(Op1, m_OneUse(m_FDiv(m_Value(X), m_Value(Y)))) &&
(!isa<Constant>(Y) || !isa<Constant>(Op0))) {
// Z / (X / Y) => (Y * Z) / X
- Value *YZ = Builder.CreateFMul(Y, Op0);
- if (auto *YZInst = dyn_cast<Instruction>(YZ)) {
- FastMathFlags FMFIntersect = I.getFastMathFlags();
- FMFIntersect &= cast<Instruction>(Op1)->getFastMathFlags();
- YZInst->setFastMathFlags(FMFIntersect);
- }
+ Value *YZ = Builder.CreateFMulFMF(Y, Op0, &I);
return BinaryOperator::CreateFDivFMF(YZ, X, &I);
}
}
Modified: llvm/trunk/test/Transforms/InstCombine/fdiv.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/fdiv.ll?rev=326098&r1=326097&r2=326098&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/fdiv.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/fdiv.ll Mon Feb 26 08:02:45 2018
@@ -126,12 +126,12 @@ define <2 x float> @not_exact_inverse_ve
define float @div_with_div_numerator(float %x, float %y, float %z) {
; CHECK-LABEL: @div_with_div_numerator(
-; CHECK-NEXT: [[TMP1:%.*]] = fmul ninf float [[Y:%.*]], [[Z:%.*]]
-; CHECK-NEXT: [[DIV2:%.*]] = fdiv fast float [[X:%.*]], [[TMP1]]
+; CHECK-NEXT: [[TMP1:%.*]] = fmul reassoc arcp float [[Y:%.*]], [[Z:%.*]]
+; CHECK-NEXT: [[DIV2:%.*]] = fdiv reassoc arcp float [[X:%.*]], [[TMP1]]
; CHECK-NEXT: ret float [[DIV2]]
;
%div1 = fdiv ninf float %x, %y
- %div2 = fdiv fast float %div1, %z
+ %div2 = fdiv arcp reassoc float %div1, %z
ret float %div2
}
@@ -139,12 +139,12 @@ define float @div_with_div_numerator(flo
define <2 x float> @div_with_div_denominator(<2 x float> %x, <2 x float> %y, <2 x float> %z) {
; CHECK-LABEL: @div_with_div_denominator(
-; CHECK-NEXT: [[TMP1:%.*]] = fmul nnan <2 x float> [[Y:%.*]], [[Z:%.*]]
-; CHECK-NEXT: [[DIV2:%.*]] = fdiv fast <2 x float> [[TMP1]], [[X:%.*]]
+; CHECK-NEXT: [[TMP1:%.*]] = fmul reassoc arcp <2 x float> [[Y:%.*]], [[Z:%.*]]
+; CHECK-NEXT: [[DIV2:%.*]] = fdiv reassoc arcp <2 x float> [[TMP1]], [[X:%.*]]
; CHECK-NEXT: ret <2 x float> [[DIV2]]
;
%div1 = fdiv nnan <2 x float> %x, %y
- %div2 = fdiv fast <2 x float> %z, %div1
+ %div2 = fdiv arcp reassoc <2 x float> %z, %div1
ret <2 x float> %div2
}
@@ -342,8 +342,8 @@ define <2 x float> @div_constant_dividen
define <2 x float> @div_constant_dividend3(<2 x float> %x) {
; CHECK-LABEL: @div_constant_dividend3(
-; CHECK-NEXT: [[T1:%.*]] = fdiv <2 x float> <float 3.000000e+00, float 7.000000e+00>, [[X:%.*]]
-; CHECK-NEXT: [[T2:%.*]] = fdiv reassoc arcp <2 x float> <float 1.500000e+01, float -7.000000e+00>, [[T1]]
+; CHECK-NEXT: [[TMP1:%.*]] = fmul reassoc arcp <2 x float> [[X:%.*]], <float 1.500000e+01, float -7.000000e+00>
+; CHECK-NEXT: [[T2:%.*]] = fmul reassoc arcp <2 x float> [[TMP1]], <float 0x3FD5555560000000, float 0x3FC24924A0000000>
; CHECK-NEXT: ret <2 x float> [[T2]]
;
%t1 = fdiv <2 x float> <float 3.0e0, float 7.0e0>, %x
More information about the llvm-commits
mailing list