diff options
author | Sanjay Patel <spatel@rotateright.com> | 2019-06-30 13:40:31 +0000 |
---|---|---|
committer | Sanjay Patel <spatel@rotateright.com> | 2019-06-30 13:40:31 +0000 |
commit | 706b48251f6a30cf03185c34d93e907ba1e05de2 (patch) | |
tree | c238cbd413571229b2239c3c373f15a2b5e979e1 /llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp | |
parent | 78ee2fbf984b84db814bf7b3a68e2317e32b1a24 (diff) | |
download | bcm5719-llvm-706b48251f6a30cf03185c34d93e907ba1e05de2.tar.gz bcm5719-llvm-706b48251f6a30cf03185c34d93e907ba1e05de2.zip |
[InstCombine] canonicalize fcmp+select to minnum/maxnum intrinsics
This is the opposite direction of D62158 (we have to choose 1 form or the other).
Now that we have FMF on the select, this becomes more palatable. And the benefits
of having a single IR instruction for this operation (less chances of missing folds
based on extra uses, etc) overcome my previous comments about the potential advantage
of larger pattern matching/analysis.
Differential Revision: https://reviews.llvm.org/D62414
llvm-svn: 364721
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp index c6d2acac155..7a3c2b96658 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -2030,6 +2030,19 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) { } } + // Canonicalize select of FP values where NaN and -0.0 are not valid as + // minnum/maxnum intrinsics. + if (isa<FPMathOperator>(SI) && SI.hasNoNaNs() && SI.hasNoSignedZeros()) { + Value *X, *Y; + if (match(&SI, m_OrdFMax(m_Value(X), m_Value(Y)))) + return replaceInstUsesWith( + SI, Builder.CreateBinaryIntrinsic(Intrinsic::maxnum, X, Y, &SI)); + + if (match(&SI, m_OrdFMin(m_Value(X), m_Value(Y)))) + return replaceInstUsesWith( + SI, Builder.CreateBinaryIntrinsic(Intrinsic::minnum, X, Y, &SI)); + } + // See if we can fold the select into a phi node if the condition is a select. if (auto *PN = dyn_cast<PHINode>(SI.getCondition())) // The true/false values have to be live in the PHI predecessor's blocks. |