Skip to content
This repository was archived by the owner on Apr 23, 2020. It is now read-only.

Commit a2d22f7

Browse files
committed
[SelectionDAG] Make binop reduction matcher available to all targets
There is nothing x86-specific about this code, so it'd be nice to make this available for other targets to use in the future (and get it out of X86ISelLowering!). Differential Revision: https://reviews.llvm.org/D50083 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@338586 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent dc21a6f commit a2d22f7

File tree

3 files changed

+73
-65
lines changed

3 files changed

+73
-65
lines changed

include/llvm/CodeGen/SelectionDAG.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1503,6 +1503,15 @@ class SelectionDAG {
15031503
/// allow an 'add' to be transformed into an 'or'.
15041504
bool haveNoCommonBitsSet(SDValue A, SDValue B) const;
15051505

1506+
/// Match a binop + shuffle pyramid that represents a horizontal reduction
1507+
/// over the elements of a vector starting from the EXTRACT_VECTOR_ELT node /p
1508+
/// Extract. The reduction must use one of the opcodes listed in /p
1509+
/// CandidateBinOps and on success /p BinOp will contain the matching opcode.
1510+
/// Returns the vector that is being reduced on, or SDValue() if a reduction
1511+
/// was not matched.
1512+
SDValue matchBinOpReduction(SDNode *Extract, ISD::NodeType &BinOp,
1513+
ArrayRef<ISD::NodeType> CandidateBinOps);
1514+
15061515
/// Utility function used by legalize and lowering to
15071516
/// "unroll" a vector operation by splitting out the scalars and operating
15081517
/// on each element individually. If the ResNE is 0, fully unroll the vector

lib/CodeGen/SelectionDAG/SelectionDAG.cpp

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8318,6 +8318,64 @@ void SDNode::intersectFlagsWith(const SDNodeFlags Flags) {
83188318
this->Flags.intersectWith(Flags);
83198319
}
83208320

8321+
SDValue
8322+
SelectionDAG::matchBinOpReduction(SDNode *Extract, ISD::NodeType &BinOp,
8323+
ArrayRef<ISD::NodeType> CandidateBinOps) {
8324+
// The pattern must end in an extract from index 0.
8325+
if (Extract->getOpcode() != ISD::EXTRACT_VECTOR_ELT ||
8326+
!isNullConstant(Extract->getOperand(1)))
8327+
return SDValue();
8328+
8329+
SDValue Op = Extract->getOperand(0);
8330+
unsigned Stages = Log2_32(Op.getValueType().getVectorNumElements());
8331+
8332+
// Match against one of the candidate binary ops.
8333+
if (llvm::none_of(CandidateBinOps, [Op](ISD::NodeType BinOp) {
8334+
return Op.getOpcode() == unsigned(BinOp);
8335+
}))
8336+
return SDValue();
8337+
8338+
// At each stage, we're looking for something that looks like:
8339+
// %s = shufflevector <8 x i32> %op, <8 x i32> undef,
8340+
// <8 x i32> <i32 2, i32 3, i32 undef, i32 undef,
8341+
// i32 undef, i32 undef, i32 undef, i32 undef>
8342+
// %a = binop <8 x i32> %op, %s
8343+
// Where the mask changes according to the stage. E.g. for a 3-stage pyramid,
8344+
// we expect something like:
8345+
// <4,5,6,7,u,u,u,u>
8346+
// <2,3,u,u,u,u,u,u>
8347+
// <1,u,u,u,u,u,u,u>
8348+
unsigned CandidateBinOp = Op.getOpcode();
8349+
for (unsigned i = 0; i < Stages; ++i) {
8350+
if (Op.getOpcode() != CandidateBinOp)
8351+
return SDValue();
8352+
8353+
SDValue Op0 = Op.getOperand(0);
8354+
SDValue Op1 = Op.getOperand(1);
8355+
8356+
ShuffleVectorSDNode *Shuffle = dyn_cast<ShuffleVectorSDNode>(Op0);
8357+
if (Shuffle) {
8358+
Op = Op1;
8359+
} else {
8360+
Shuffle = dyn_cast<ShuffleVectorSDNode>(Op1);
8361+
Op = Op0;
8362+
}
8363+
8364+
// The first operand of the shuffle should be the same as the other operand
8365+
// of the binop.
8366+
if (!Shuffle || Shuffle->getOperand(0) != Op)
8367+
return SDValue();
8368+
8369+
// Verify the shuffle has the expected (at this stage of the pyramid) mask.
8370+
for (int Index = 0, MaskEnd = 1 << i; Index < MaskEnd; ++Index)
8371+
if (Shuffle->getMaskElt(Index) != MaskEnd + Index)
8372+
return SDValue();
8373+
}
8374+
8375+
BinOp = (ISD::NodeType)CandidateBinOp;
8376+
return Op;
8377+
}
8378+
83218379
SDValue SelectionDAG::UnrollVectorOp(SDNode *N, unsigned ResNE) {
83228380
assert(N->getNumValues() == 1 &&
83238381
"Can't unroll a vector with multiple results!");

lib/Target/X86/X86ISelLowering.cpp

Lines changed: 6 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -31807,65 +31807,6 @@ static SDValue combineBitcast(SDNode *N, SelectionDAG &DAG,
3180731807
return SDValue();
3180831808
}
3180931809

31810-
// Match a binop + shuffle pyramid that represents a horizontal reduction over
31811-
// the elements of a vector.
31812-
// Returns the vector that is being reduced on, or SDValue() if a reduction
31813-
// was not matched.
31814-
static SDValue matchBinOpReduction(SDNode *Extract, unsigned &BinOp,
31815-
ArrayRef<ISD::NodeType> CandidateBinOps) {
31816-
// The pattern must end in an extract from index 0.
31817-
if ((Extract->getOpcode() != ISD::EXTRACT_VECTOR_ELT) ||
31818-
!isNullConstant(Extract->getOperand(1)))
31819-
return SDValue();
31820-
31821-
SDValue Op = Extract->getOperand(0);
31822-
unsigned Stages = Log2_32(Op.getValueType().getVectorNumElements());
31823-
31824-
// Match against one of the candidate binary ops.
31825-
if (llvm::none_of(CandidateBinOps, [Op](ISD::NodeType BinOp) {
31826-
return Op.getOpcode() == unsigned(BinOp);
31827-
}))
31828-
return SDValue();
31829-
31830-
// At each stage, we're looking for something that looks like:
31831-
// %s = shufflevector <8 x i32> %op, <8 x i32> undef,
31832-
// <8 x i32> <i32 2, i32 3, i32 undef, i32 undef,
31833-
// i32 undef, i32 undef, i32 undef, i32 undef>
31834-
// %a = binop <8 x i32> %op, %s
31835-
// Where the mask changes according to the stage. E.g. for a 3-stage pyramid,
31836-
// we expect something like:
31837-
// <4,5,6,7,u,u,u,u>
31838-
// <2,3,u,u,u,u,u,u>
31839-
// <1,u,u,u,u,u,u,u>
31840-
unsigned CandidateBinOp = Op.getOpcode();
31841-
for (unsigned i = 0; i < Stages; ++i) {
31842-
if (Op.getOpcode() != CandidateBinOp)
31843-
return SDValue();
31844-
31845-
ShuffleVectorSDNode *Shuffle =
31846-
dyn_cast<ShuffleVectorSDNode>(Op.getOperand(0).getNode());
31847-
if (Shuffle) {
31848-
Op = Op.getOperand(1);
31849-
} else {
31850-
Shuffle = dyn_cast<ShuffleVectorSDNode>(Op.getOperand(1).getNode());
31851-
Op = Op.getOperand(0);
31852-
}
31853-
31854-
// The first operand of the shuffle should be the same as the other operand
31855-
// of the binop.
31856-
if (!Shuffle || Shuffle->getOperand(0) != Op)
31857-
return SDValue();
31858-
31859-
// Verify the shuffle has the expected (at this stage of the pyramid) mask.
31860-
for (int Index = 0, MaskEnd = 1 << i; Index < MaskEnd; ++Index)
31861-
if (Shuffle->getMaskElt(Index) != MaskEnd + Index)
31862-
return SDValue();
31863-
}
31864-
31865-
BinOp = CandidateBinOp;
31866-
return Op;
31867-
}
31868-
3186931810
// Given a select, detect the following pattern:
3187031811
// 1: %2 = zext <N x i8> %0 to <N x i32>
3187131812
// 2: %3 = zext <N x i8> %1 to <N x i32>
@@ -31980,8 +31921,8 @@ static SDValue combineHorizontalMinMaxResult(SDNode *Extract, SelectionDAG &DAG,
3198031921
return SDValue();
3198131922

3198231923
// Check for SMAX/SMIN/UMAX/UMIN horizontal reduction patterns.
31983-
unsigned BinOp;
31984-
SDValue Src = matchBinOpReduction(
31924+
ISD::NodeType BinOp;
31925+
SDValue Src = DAG.matchBinOpReduction(
3198531926
Extract, BinOp, {ISD::SMAX, ISD::SMIN, ISD::UMAX, ISD::UMIN});
3198631927
if (!Src)
3198731928
return SDValue();
@@ -32060,8 +32001,8 @@ static SDValue combineHorizontalPredicateResult(SDNode *Extract,
3206032001
return SDValue();
3206132002

3206232003
// Check for OR(any_of) and AND(all_of) horizontal reduction patterns.
32063-
unsigned BinOp = 0;
32064-
SDValue Match = matchBinOpReduction(Extract, BinOp, {ISD::OR, ISD::AND});
32004+
ISD::NodeType BinOp;
32005+
SDValue Match = DAG.matchBinOpReduction(Extract, BinOp, {ISD::OR, ISD::AND});
3206532006
if (!Match)
3206632007
return SDValue();
3206732008

@@ -32143,8 +32084,8 @@ static SDValue combineBasicSADPattern(SDNode *Extract, SelectionDAG &DAG,
3214332084
return SDValue();
3214432085

3214532086
// Match shuffle + add pyramid.
32146-
unsigned BinOp = 0;
32147-
SDValue Root = matchBinOpReduction(Extract, BinOp, {ISD::ADD});
32087+
ISD::NodeType BinOp;
32088+
SDValue Root = DAG.matchBinOpReduction(Extract, BinOp, {ISD::ADD});
3214832089

3214932090
// The operand is expected to be zero extended from i8
3215032091
// (verified in detectZextAbsDiff).

0 commit comments

Comments
 (0)