summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2018-03-02 20:32:46 +0000
committerSanjay Patel <spatel@rotateright.com>2018-03-02 20:32:46 +0000
commit2fd0acf05aa5909b3c7b38d9dcae6d27ff682cec (patch)
tree8e8c25dc400bb2550eadbc18545c253b538e2d9a /llvm/lib
parent8b93a591e75c147ab01d13490610bec11b8ef342 (diff)
downloadbcm5719-llvm-2fd0acf05aa5909b3c7b38d9dcae6d27ff682cec.tar.gz
bcm5719-llvm-2fd0acf05aa5909b3c7b38d9dcae6d27ff682cec.zip
[InstCombine] partly fix FMF for fmul+log2 fold
The code was checking that all of the instructions in the sequence are 'fast', but that's not necessary. The final multiply is all that we need to check (tests adjusted). The fmul doesn't need to be fully 'fast' either, but that can be another patch. llvm-svn: 326608
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp69
1 files changed, 17 insertions, 52 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
index 1529911c5a9..799493c6550 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -447,35 +447,6 @@ Instruction *InstCombiner::visitMul(BinaryOperator &I) {
return Changed ? &I : nullptr;
}
-/// Detect pattern log2(Y * 0.5) with corresponding fast math flags.
-static void detectLog2OfHalf(Value *&Op, Value *&Y, IntrinsicInst *&Log2) {
- if (!Op->hasOneUse())
- return;
-
- IntrinsicInst *II = dyn_cast<IntrinsicInst>(Op);
- if (!II)
- return;
- if (II->getIntrinsicID() != Intrinsic::log2 || !II->isFast())
- return;
- Log2 = II;
-
- Value *OpLog2Of = II->getArgOperand(0);
- if (!OpLog2Of->hasOneUse())
- return;
-
- Instruction *I = dyn_cast<Instruction>(OpLog2Of);
- if (!I)
- return;
-
- if (I->getOpcode() != Instruction::FMul || !I->isFast())
- return;
-
- if (match(I->getOperand(0), m_SpecificFP(0.5)))
- Y = I->getOperand(1);
- else if (match(I->getOperand(1), m_SpecificFP(0.5)))
- Y = I->getOperand(0);
-}
-
/// Helper function of InstCombiner::visitFMul(). Return true iff the given
/// value is FMul or FDiv with one and only one operand being a finite-non-zero
/// constant (i.e. not Zero/NaN/Infinity).
@@ -617,30 +588,24 @@ Instruction *InstCombiner::visitFMul(BinaryOperator &I) {
if (Op0 == Op1 && match(Op0, m_Intrinsic<Intrinsic::fabs>(m_Value(X))))
return BinaryOperator::CreateFMulFMF(X, X, &I);
- // Under unsafe algebra do:
- // X * log2(0.5*Y) = X*log2(Y) - X
- if (AllowReassociate) {
- Value *OpX = nullptr;
- Value *OpY = nullptr;
- IntrinsicInst *Log2;
- detectLog2OfHalf(Op0, OpY, Log2);
- if (OpY) {
- OpX = Op1;
- } else {
- detectLog2OfHalf(Op1, OpY, Log2);
- if (OpY) {
- OpX = Op0;
- }
+ // log2(X * 0.5) * Y = log2(X) * Y - Y
+ if (I.isFast()) {
+ IntrinsicInst *Log2 = nullptr;
+ if (match(Op0, m_OneUse(m_Intrinsic<Intrinsic::log2>(
+ m_OneUse(m_FMul(m_Value(X), m_SpecificFP(0.5))))))) {
+ Log2 = cast<IntrinsicInst>(Op0);
+ Y = Op1;
+ }
+ if (match(Op1, m_OneUse(m_Intrinsic<Intrinsic::log2>(
+ m_OneUse(m_FMul(m_Value(X), m_SpecificFP(0.5))))))) {
+ Log2 = cast<IntrinsicInst>(Op1);
+ Y = Op0;
}
- // if pattern detected emit alternate sequence
- if (OpX && OpY) {
- BuilderTy::FastMathFlagGuard Guard(Builder);
- Builder.setFastMathFlags(Log2->getFastMathFlags());
- Log2->setArgOperand(0, OpY);
- Value *FMulVal = Builder.CreateFMul(OpX, Log2);
- Value *FSub = Builder.CreateFSub(FMulVal, OpX);
- FSub->takeName(&I);
- return replaceInstUsesWith(I, FSub);
+ if (Log2) {
+ Log2->setArgOperand(0, X);
+ Log2->copyFastMathFlags(&I);
+ Value *LogXTimesY = Builder.CreateFMulFMF(Log2, Y, &I);
+ return BinaryOperator::CreateFSubFMF(LogXTimesY, Y, &I);
}
}
OpenPOWER on IntegriCloud