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