@@ -56517,6 +56517,7 @@ static SDValue combineGatherScatter(SDNode *N, SelectionDAG &DAG,
5651756517 SDValue Base = GorS->getBasePtr();
5651856518 SDValue Scale = GorS->getScale();
5651956519 EVT IndexVT = Index.getValueType();
56520+ EVT IndexSVT = IndexVT.getVectorElementType();
5652056521 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
5652156522
5652256523 if (DCI.isBeforeLegalize()) {
@@ -56553,41 +56554,51 @@ static SDValue combineGatherScatter(SDNode *N, SelectionDAG &DAG,
5655356554 }
5655456555
5655556556 EVT PtrVT = TLI.getPointerTy(DAG.getDataLayout());
56556- // Try to move splat constant adders from the index operand to the base
56557+
56558+ // Try to move splat adders from the index operand to the base
5655756559 // pointer operand. Taking care to multiply by the scale. We can only do
5655856560 // this when index element type is the same as the pointer type.
5655956561 // Otherwise we need to be sure the math doesn't wrap before the scale.
56560- if (Index.getOpcode() == ISD::ADD &&
56561- IndexVT.getVectorElementType() == PtrVT && isa<ConstantSDNode>(Scale)) {
56562+ if (Index.getOpcode() == ISD::ADD && IndexSVT == PtrVT &&
56563+ isa<ConstantSDNode>(Scale)) {
5656256564 uint64_t ScaleAmt = Scale->getAsZExtVal();
56563- if (auto *BV = dyn_cast<BuildVectorSDNode>(Index.getOperand(1))) {
56564- BitVector UndefElts;
56565- if (ConstantSDNode *C = BV->getConstantSplatNode(&UndefElts)) {
56566- // FIXME: Allow non-constant?
56567- if (UndefElts.none()) {
56568- // Apply the scale.
56569- APInt Adder = C->getAPIntValue() * ScaleAmt;
56570- // Add it to the existing base.
56571- Base = DAG.getNode(ISD::ADD, DL, PtrVT, Base,
56572- DAG.getConstant(Adder, DL, PtrVT));
56573- Index = Index.getOperand(0);
56574- return rebuildGatherScatter(GorS, Index, Base, Scale, DAG);
56575- }
56576- }
5657756565
56578- // It's also possible base is just a constant. In that case, just
56579- // replace it with 0 and move the displacement into the index.
56580- if (BV->isConstant() && isa<ConstantSDNode>(Base) &&
56581- isOneConstant(Scale)) {
56582- SDValue Splat = DAG.getSplatBuildVector(IndexVT, DL, Base);
56583- // Combine the constant build_vector and the constant base.
56584- Splat = DAG.getNode(ISD::ADD, DL, IndexVT, Index.getOperand(1), Splat);
56585- // Add to the LHS of the original Index add.
56586- Index = DAG.getNode(ISD::ADD, DL, IndexVT, Index.getOperand(0), Splat);
56587- Base = DAG.getConstant(0, DL, Base.getValueType());
56588- return rebuildGatherScatter(GorS, Index, Base, Scale, DAG);
56566+ for (unsigned I = 0; I != 2; ++I)
56567+ if (auto *BV = dyn_cast<BuildVectorSDNode>(Index.getOperand(I))) {
56568+ BitVector UndefElts;
56569+ if (SDValue Splat = BV->getSplatValue(&UndefElts)) {
56570+ if (UndefElts.none()) {
56571+ // If the splat value is constant we can add the scaled splat value
56572+ // to the existing base.
56573+ if (auto *C = dyn_cast<ConstantSDNode>(Splat)) {
56574+ APInt Adder = C->getAPIntValue() * ScaleAmt;
56575+ SDValue NewBase = DAG.getNode(ISD::ADD, DL, PtrVT, Base,
56576+ DAG.getConstant(Adder, DL, PtrVT));
56577+ SDValue NewIndex = Index.getOperand(1 - I);
56578+ return rebuildGatherScatter(GorS, NewIndex, NewBase, Scale, DAG);
56579+ }
56580+ // For non-constant cases, limit this to non-scaled cases.
56581+ if (ScaleAmt == 1) {
56582+ SDValue NewBase = DAG.getNode(ISD::ADD, DL, PtrVT, Base, Splat);
56583+ SDValue NewIndex = Index.getOperand(1 - I);
56584+ return rebuildGatherScatter(GorS, NewIndex, NewBase, Scale, DAG);
56585+ }
56586+ }
56587+ }
56588+ // It's also possible base is just a constant. In that case, just
56589+ // replace it with 0 and move the displacement into the index.
56590+ if (ScaleAmt == 1 && BV->isConstant() && isa<ConstantSDNode>(Base)) {
56591+ SDValue Splat = DAG.getSplatBuildVector(IndexVT, DL, Base);
56592+ // Combine the constant build_vector and the constant base.
56593+ Splat =
56594+ DAG.getNode(ISD::ADD, DL, IndexVT, Index.getOperand(I), Splat);
56595+ // Add to the other half of the original Index add.
56596+ SDValue NewIndex = DAG.getNode(ISD::ADD, DL, IndexVT,
56597+ Index.getOperand(1 - I), Splat);
56598+ SDValue NewBase = DAG.getConstant(0, DL, PtrVT);
56599+ return rebuildGatherScatter(GorS, NewIndex, NewBase, Scale, DAG);
56600+ }
5658956601 }
56590- }
5659156602 }
5659256603
5659356604 if (DCI.isBeforeLegalizeOps()) {
0 commit comments