diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2019-05-06 16:17:17 +0000 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2019-05-06 16:17:17 +0000 |
commit | cfe786a19567424b04206bea5b5f1817fe9041b4 (patch) | |
tree | 7b1db578324a53136e46d6e920b69c8c7faaffbb /llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | |
parent | c3167696bc3758efc9c1e98c63ef653951567a2a (diff) | |
download | bcm5719-llvm-cfe786a19567424b04206bea5b5f1817fe9041b4.tar.gz bcm5719-llvm-cfe786a19567424b04206bea5b5f1817fe9041b4.zip |
[SDAG][AArch64] Boolean and/or reduce to umax/min reduce (PR41635)
This addresses one half of https://bugs.llvm.org/show_bug.cgi?id=41635
by combining a VECREDUCE_AND/OR into VECREDUCE_UMIN/UMAX (if latter is
legal but former is not) for zero-or-all-ones boolean reductions (which
are detected based on sign bits).
Differential Revision: https://reviews.llvm.org/D61398
llvm-svn: 360054
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp')
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index a2d608318fc..9a32ca51db4 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -18670,6 +18670,7 @@ SDValue DAGCombiner::visitFP16_TO_FP(SDNode *N) { SDValue DAGCombiner::visitVECREDUCE(SDNode *N) { SDValue N0 = N->getOperand(0); EVT VT = N0.getValueType(); + unsigned Opcode = N->getOpcode(); // VECREDUCE over 1-element vector is just an extract. if (VT.getVectorNumElements() == 1) { @@ -18682,6 +18683,17 @@ SDValue DAGCombiner::visitVECREDUCE(SDNode *N) { return Res; } + // On an boolean vector an and/or reduction is the same as a umin/umax + // reduction. Convert them if the latter is legal while the former isn't. + if (Opcode == ISD::VECREDUCE_AND || Opcode == ISD::VECREDUCE_OR) { + unsigned NewOpcode = Opcode == ISD::VECREDUCE_AND + ? ISD::VECREDUCE_UMIN : ISD::VECREDUCE_UMAX; + if (!TLI.isOperationLegalOrCustom(Opcode, VT) && + TLI.isOperationLegalOrCustom(NewOpcode, VT) && + DAG.ComputeNumSignBits(N0) == VT.getScalarSizeInBits()) + return DAG.getNode(NewOpcode, SDLoc(N), N->getValueType(0), N0); + } + return SDValue(); } |