diff options
author | Sanjay Patel <spatel@rotateright.com> | 2019-05-06 20:34:05 +0000 |
---|---|---|
committer | Sanjay Patel <spatel@rotateright.com> | 2019-05-06 20:34:05 +0000 |
commit | a6019d51649973c88dc5953d98a46a964768deb2 (patch) | |
tree | 65f0732d13f403fa07850245519b622dbd7fc0c7 /llvm/lib | |
parent | 2d2277f5e7ce8b2836e4a5a393a2c4da26c2e439 (diff) | |
download | bcm5719-llvm-a6019d51649973c88dc5953d98a46a964768deb2.tar.gz bcm5719-llvm-a6019d51649973c88dc5953d98a46a964768deb2.zip |
[InstCombine] sink FP negation of operands through select
We don't always get this:
Cond ? -X : -Y --> -(Cond ? X : Y)
...even with the legacy IR form of fneg in the case with extra uses,
and we miss matching with the newer 'fneg' instruction because we
are expecting binops through the rest of the path.
Differential Revision: https://reviews.llvm.org/D61604
llvm-svn: 360075
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp index d0292b640fe..5a14726bee2 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -333,6 +333,18 @@ Instruction *InstCombiner::foldSelectOpOp(SelectInst &SI, Instruction *TI, TI->getType()); } + // Cond ? -X : -Y --> -(Cond ? X : Y) + Value *X, *Y; + if (match(TI, m_FNeg(m_Value(X))) && match(FI, m_FNeg(m_Value(Y))) && + (TI->hasOneUse() || FI->hasOneUse())) { + Value *NewSel = Builder.CreateSelect(Cond, X, Y, SI.getName() + ".v", &SI); + // TODO: Remove the hack for the binop form when the unary op is optimized + // properly with all IR passes. + if (TI->getOpcode() != Instruction::FNeg) + return BinaryOperator::CreateFNegFMF(NewSel, cast<BinaryOperator>(TI)); + return UnaryOperator::CreateFNeg(NewSel); + } + // Only handle binary operators (including two-operand getelementptr) with // one-use here. As with the cast case above, it may be possible to relax the // one-use constraint, but that needs be examined carefully since it may not |