summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp36
1 files changed, 19 insertions, 17 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 36c5d185f0d..4a52368a3b4 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -19448,33 +19448,35 @@ SDValue DAGCombiner::SimplifyVBinOp(SDNode *N) {
}
}
- // Make sure all but the first op are undef.
- auto ConcatWithUndef = [](SDValue Concat) {
+ // Make sure all but the first op are undef or constant.
+ auto ConcatWithConstantOrUndef = [](SDValue Concat) {
return Concat.getOpcode() == ISD::CONCAT_VECTORS &&
std::all_of(std::next(Concat->op_begin()), Concat->op_end(),
- [](const SDValue &Op) {
- return Op.isUndef();
- });
+ [](const SDValue &Op) {
+ return Op.isUndef() ||
+ ISD::isBuildVectorOfConstantSDNodes(Op.getNode());
+ });
};
// The following pattern is likely to emerge with vector reduction ops. Moving
// the binary operation ahead of the concat may allow using a narrower vector
// instruction that has better performance than the wide version of the op:
- // VBinOp (concat X, undef), (concat Y, undef) --> concat (VBinOp X, Y), VecC
- if (ConcatWithUndef(LHS) && ConcatWithUndef(RHS) &&
+ // VBinOp (concat X, undef/constant), (concat Y, undef/constant) -->
+ // concat (VBinOp X, Y), VecC
+ if (ConcatWithConstantOrUndef(LHS) && ConcatWithConstantOrUndef(RHS) &&
(LHS.hasOneUse() || RHS.hasOneUse())) {
- SDValue X = LHS.getOperand(0);
- SDValue Y = RHS.getOperand(0);
- EVT NarrowVT = X.getValueType();
- if (NarrowVT == Y.getValueType() &&
+ EVT NarrowVT = LHS.getOperand(0).getValueType();
+ if (NarrowVT == RHS.getOperand(0).getValueType() &&
TLI.isOperationLegalOrCustomOrPromote(Opcode, NarrowVT)) {
- // (binop undef, undef) may not return undef, so compute that result.
SDLoc DL(N);
- SDValue VecC =
- DAG.getNode(Opcode, DL, NarrowVT, DAG.getUNDEF(NarrowVT),
- DAG.getUNDEF(NarrowVT));
- SmallVector<SDValue, 4> Ops(LHS.getNumOperands(), VecC);
- Ops[0] = DAG.getNode(Opcode, DL, NarrowVT, X, Y);
+ unsigned NumOperands = LHS.getNumOperands();
+ SmallVector<SDValue, 4> Ops;
+ for (unsigned i = 0; i != NumOperands; ++i) {
+ // This constant fold for operands 1 and up.
+ Ops.push_back(DAG.getNode(Opcode, DL, NarrowVT, LHS.getOperand(i),
+ RHS.getOperand(i)));
+ }
+
return DAG.getNode(ISD::CONCAT_VECTORS, DL, VT, Ops);
}
}
OpenPOWER on IntegriCloud