summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2019-05-13 14:31:14 +0000
committerSanjay Patel <spatel@rotateright.com>2019-05-13 14:31:14 +0000
commit05dafb1c97de8f3dbb8a883f96c6ae452dcc6ef4 (patch)
tree11d96f2d764bd16e635ec0c3825d351471d96952 /llvm/lib/CodeGen
parentf9e00db8185ddcf6491b62c700d23283b3559a08 (diff)
downloadbcm5719-llvm-05dafb1c97de8f3dbb8a883f96c6ae452dcc6ef4.tar.gz
bcm5719-llvm-05dafb1c97de8f3dbb8a883f96c6ae452dcc6ef4.zip
[DAGCombiner] narrow vector binop with inserts/extract
We catch most of these patterns (on x86 at least) by matching a concat vectors opcode early in combining, but the pattern may emerge later using insert subvector instead. The AVX1 diffs for add/sub overflow show another missed narrowing pattern. That one may be falling though the cracks because of combine ordering and multiple uses. llvm-svn: 360585
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp34
1 files changed, 33 insertions, 1 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 12490e6c6ef..fcbb9fcd990 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -17409,12 +17409,45 @@ SDValue DAGCombiner::visitCONCAT_VECTORS(SDNode *N) {
return SDValue();
}
+static SDValue narrowInsertExtractVectorBinOp(SDNode *Extract,
+ SelectionDAG &DAG) {
+ SDValue BinOp = Extract->getOperand(0);
+ if (!ISD::isBinaryOp(BinOp.getNode()))
+ return SDValue();
+
+ SDValue Bop0 = BinOp.getOperand(0), Bop1 = BinOp.getOperand(1);
+ SDValue Index = Extract->getOperand(1);
+ EVT VT = Extract->getValueType(0);
+ bool IsInsert0 = Bop0.getOpcode() == ISD::INSERT_SUBVECTOR &&
+ Bop0.getOperand(1).getValueType() == VT &&
+ Bop0.getOperand(2) == Index;
+ bool IsInsert1 = Bop1.getOpcode() == ISD::INSERT_SUBVECTOR &&
+ Bop1.getOperand(1).getValueType() == VT &&
+ Bop1.getOperand(2) == Index;
+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
+ // TODO: We could handle the case where only 1 operand is being inserted by
+ // creating an extract of the other operand, but that requires checking
+ // number of uses and/or costs.
+ if (!IsInsert0 || !IsInsert1 ||
+ !TLI.isOperationLegalOrCustom(BinOp.getOpcode(), VT))
+ return SDValue();
+
+ // We are inserting both operands of the wide binop only to extract back
+ // to the narrow vector size. Eliminate all of the insert/extract:
+ // ext (binop (ins ?, X, Index), (ins ?, Y, Index)), Index --> binop X, Y
+ return DAG.getNode(BinOp.getOpcode(), SDLoc(Extract), VT, Bop0.getOperand(1),
+ Bop1.getOperand(1), BinOp->getFlags());
+}
+
/// If we are extracting a subvector produced by a wide binary operator try
/// to use a narrow binary operator and/or avoid concatenation and extraction.
static SDValue narrowExtractedVectorBinOp(SDNode *Extract, SelectionDAG &DAG) {
// TODO: Refactor with the caller (visitEXTRACT_SUBVECTOR), so we can share
// some of these bailouts with other transforms.
+ if (SDValue V = narrowInsertExtractVectorBinOp(Extract, DAG))
+ return V;
+
// The extract index must be a constant, so we can map it to a concat operand.
auto *ExtractIndexC = dyn_cast<ConstantSDNode>(Extract->getOperand(1));
if (!ExtractIndexC)
@@ -17493,7 +17526,6 @@ static SDValue narrowExtractedVectorBinOp(SDNode *Extract, SelectionDAG &DAG) {
// We need at least one concatenation operation of a binop operand to make
// this transform worthwhile. The concat must double the input vector sizes.
- // TODO: Should we also handle INSERT_SUBVECTOR patterns?
SDValue LHS = peekThroughBitcasts(BinOp.getOperand(0));
SDValue RHS = peekThroughBitcasts(BinOp.getOperand(1));
bool ConcatL =
OpenPOWER on IntegriCloud