diff options
author | Simon Pilgrim <llvm-dev@redking.me.uk> | 2019-04-28 10:46:17 +0000 |
---|---|---|
committer | Simon Pilgrim <llvm-dev@redking.me.uk> | 2019-04-28 10:46:17 +0000 |
commit | 93ad48210cb7c61906875ad5be1ca8d894063380 (patch) | |
tree | e9dc544fad4b64eb822d82a17a5a55069c0dce1e /llvm/lib | |
parent | fed302ae37ec56badc8283e39070561e47ae740e (diff) | |
download | bcm5719-llvm-93ad48210cb7c61906875ad5be1ca8d894063380.tar.gz bcm5719-llvm-93ad48210cb7c61906875ad5be1ca8d894063380.zip |
[X86][SSE] Optimize llvm.experimental.vector.reduce.xor.vXi1 parity reduction (PR38840)
An xor reduction of a bool vector can be optimized to a parity check of the MOVMSK/BITCAST'd integer - if the population count is odd return 1, else return 0.
Differential Revision: https://reviews.llvm.org/D61230
llvm-svn: 359396
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 420397f1621..535a7b27b62 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -34386,7 +34386,7 @@ static SDValue combineHorizontalMinMaxResult(SDNode *Extract, SelectionDAG &DAG, DAG.getIntPtrConstant(0, DL)); } -// Attempt to replace an all_of/any_of style horizontal reduction with a MOVMSK. +// Attempt to replace an all_of/any_of/parity style horizontal reduction with a MOVMSK. static SDValue combineHorizontalPredicateResult(SDNode *Extract, SelectionDAG &DAG, const X86Subtarget &Subtarget) { @@ -34400,9 +34400,11 @@ static SDValue combineHorizontalPredicateResult(SDNode *Extract, ExtractVT != MVT::i8 && ExtractVT != MVT::i1) return SDValue(); - // Check for OR(any_of) and AND(all_of) horizontal reduction patterns. + // Check for OR(any_of)/AND(all_of)/XOR(parity) horizontal reduction patterns. ISD::NodeType BinOp; SDValue Match = DAG.matchBinOpReduction(Extract, BinOp, {ISD::OR, ISD::AND}); + if (!Match && ExtractVT == MVT::i1) + Match = DAG.matchBinOpReduction(Extract, BinOp, {ISD::XOR}); if (!Match) return SDValue(); @@ -34480,6 +34482,14 @@ static SDValue combineHorizontalPredicateResult(SDNode *Extract, } assert(NumElts <= 32 && "Not expecting more than 32 elements"); + if (BinOp == ISD::XOR) { + // parity -> (AND (CTPOP(MOVMSK X)), 1) + SDValue Mask = DAG.getConstant(1, DL, MVT::i32); + SDValue Result = DAG.getNode(ISD::CTPOP, DL, MVT::i32, Movmsk); + Result = DAG.getNode(ISD::AND, DL, MVT::i32, Result, Mask); + return DAG.getZExtOrTrunc(Result, DL, ExtractVT); + } + SDValue CmpC; ISD::CondCode CondCode; if (BinOp == ISD::OR) { |