diff options
author | David Bolvansky <david.bolvansky@gmail.com> | 2018-08-23 15:22:15 +0000 |
---|---|---|
committer | David Bolvansky <david.bolvansky@gmail.com> | 2018-08-23 15:22:15 +0000 |
commit | 43b0e2584706c5c0efc86ea099ba8b54bb64743f (patch) | |
tree | 65f01c77cd68ca4fff904f626ee1fb22c94e08fe /llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp | |
parent | 3ecabd709f7d7031df9368d27d0b300460d51cf1 (diff) | |
download | bcm5719-llvm-43b0e2584706c5c0efc86ea099ba8b54bb64743f.tar.gz bcm5719-llvm-43b0e2584706c5c0efc86ea099ba8b54bb64743f.zip |
[InstCombine] Fold Select with binary op - FP opcodes
Summary:
Follow up for https://reviews.llvm.org/rL339520 and https://reviews.llvm.org/rL338300
Alive:
```
%A = fcmp oeq float %x, 0.0
%B = fadd nsz float %x, %z
%C = select i1 %A, float %B, float %y
=>
%C = select i1 %A, float %z, float %y
----------
%A = fcmp oeq float %x, 0.0
%B = fadd nsz float %x, %z
%C = select %A, float %B, float %y
=>
%C = select %A, float %z, float %y
Done: 1
Optimization is correct
%A = fcmp une float %x, -0.0
%B = fadd nsz float %x, %z
%C = select i1 %A, float %y, float %B
=>
%C = select i1 %A, float %y, float %z
----------
%A = fcmp une float %x, -0.0
%B = fadd nsz float %x, %z
%C = select %A, float %y, float %B
=>
%C = select %A, float %y, float %z
Done: 1
Optimization is correct
```
Reviewers: spatel, lebedev.ri
Reviewed By: spatel
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D50714
llvm-svn: 340538
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp index f09a67d96f3..07a25c45118 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -56,19 +56,26 @@ static Value *createMinMax(InstCombiner::BuilderTy &Builder, /// Replace a select operand based on an equality comparison with the identity /// constant of a binop. -static Instruction *foldSelectBinOpIdentity(SelectInst &Sel) { +static Instruction *foldSelectBinOpIdentity(SelectInst &Sel, const TargetLibraryInfo &TLI) { // The select condition must be an equality compare with a constant operand. - // TODO: Support FP compares. Value *X; Constant *C; CmpInst::Predicate Pred; - if (!match(Sel.getCondition(), m_ICmp(Pred, m_Value(X), m_Constant(C))) || - !ICmpInst::isEquality(Pred)) + if (!match(Sel.getCondition(), m_Cmp(Pred, m_Value(X), m_Constant(C)))) + return nullptr; + + bool IsEq; + if (ICmpInst::isEquality(Pred)) + IsEq = Pred == ICmpInst::ICMP_EQ; + else if (Pred == FCmpInst::FCMP_OEQ) + IsEq = true; + else if (Pred == FCmpInst::FCMP_UNE) + IsEq = false; + else return nullptr; // A select operand must be a binop, and the compare constant must be the // identity constant for that binop. - bool IsEq = Pred == ICmpInst::ICMP_EQ; BinaryOperator *BO; if (!match(Sel.getOperand(IsEq ? 1 : 2), m_BinOp(BO)) || ConstantExpr::getBinOpIdentity(BO->getOpcode(), BO->getType(), true) != C) @@ -81,6 +88,12 @@ static Instruction *foldSelectBinOpIdentity(SelectInst &Sel) { if (!match(BO, m_c_BinOp(m_Value(Y), m_Specific(X)))) return nullptr; + // +0.0 compares equal to -0.0, and so it does not behave as required for this + // transform. Bail out if we can not exclude that possibility. + if (isa<FPMathOperator>(BO)) + if (!BO->hasNoSignedZeros() && !CannotBeNegativeZero(Y, &TLI)) + return nullptr; + // BO = binop Y, X // S = { select (cmp eq X, C), BO, ? } or { select (cmp ne X, C), ?, BO } // => @@ -2000,7 +2013,7 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) { if (Instruction *Select = foldSelectCmpXchg(SI)) return Select; - if (Instruction *Select = foldSelectBinOpIdentity(SI)) + if (Instruction *Select = foldSelectBinOpIdentity(SI, TLI)) return Select; return nullptr; |