diff options
author | Sanjay Patel <spatel@rotateright.com> | 2019-08-15 12:43:15 +0000 |
---|---|---|
committer | Sanjay Patel <spatel@rotateright.com> | 2019-08-15 12:43:15 +0000 |
commit | 57d459309dbbf252dfee7d235f9b17936abca3ad (patch) | |
tree | da0abd02f3011bfd198d6fe0ae4b4157504458d7 /llvm/lib/CodeGen | |
parent | 7aa0dbb664ea05e233c503c009052f8682fc0f62 (diff) | |
download | llvm-57d459309dbbf252dfee7d235f9b17936abca3ad.zip llvm-57d459309dbbf252dfee7d235f9b17936abca3ad.tar.gz llvm-57d459309dbbf252dfee7d235f9b17936abca3ad.tar.bz2 |
[SDAG][x86] check for relaxed math when matching an FP reduction
If the last step in an FP add reduction allows reassociation and doesn't care
about -0.0, then we are free to recognize that computation as a reduction
that may reorder the intermediate steps.
This is requested directly by PR42705:
https://bugs.llvm.org/show_bug.cgi?id=42705
and solves PR42947 (if horizontal math instructions are actually faster than
the alternative):
https://bugs.llvm.org/show_bug.cgi?id=42947
Differential Revision: https://reviews.llvm.org/D66236
llvm-svn: 368995
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index be41e12..d8711f8 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -9002,14 +9002,27 @@ SelectionDAG::matchBinOpReduction(SDNode *Extract, ISD::NodeType &BinOp, !isNullConstant(Extract->getOperand(1))) return SDValue(); - SDValue Op = Extract->getOperand(0); - // Match against one of the candidate binary ops. + SDValue Op = Extract->getOperand(0); if (llvm::none_of(CandidateBinOps, [Op](ISD::NodeType BinOp) { return Op.getOpcode() == unsigned(BinOp); })) return SDValue(); + + // Floating-point reductions may require relaxed constraints on the final step + // of the reduction because they may reorder intermediate operations. unsigned CandidateBinOp = Op.getOpcode(); + if (Op.getValueType().isFloatingPoint()) { + SDNodeFlags Flags = Op->getFlags(); + switch (CandidateBinOp) { + case ISD::FADD: + if (!Flags.hasNoSignedZeros() || !Flags.hasAllowReassociation()) + return SDValue(); + break; + default: + llvm_unreachable("Unhandled FP opcode for binop reduction"); + } + } // Matching failed - attempt to see if we did enough stages that a partial // reduction from a subvector is possible. |