@@ -1438,11 +1438,15 @@ bool SITargetLowering::isLegalAddressingMode(const DataLayout &DL,
1438
1438
// On VI, these use the SMEM format and the offset is 20-bit in bytes.
1439
1439
if (!isUInt<20>(AM.BaseOffs))
1440
1440
return false;
1441
- } else {
1441
+ } else if (Subtarget->getGeneration() < AMDGPUSubtarget::GFX12) {
1442
1442
// On GFX9 the offset is signed 21-bit in bytes (but must not be negative
1443
1443
// for S_BUFFER_* instructions).
1444
1444
if (!isInt<21>(AM.BaseOffs))
1445
1445
return false;
1446
+ } else {
1447
+ // On GFX12, all offsets are signed 24-bit in bytes.
1448
+ if (!isInt<24>(AM.BaseOffs))
1449
+ return false;
1446
1450
}
1447
1451
1448
1452
if (AM.Scale == 0) // r + i or just i, depending on HasBaseReg.
@@ -7497,7 +7501,8 @@ SDValue SITargetLowering::lowerSBuffer(EVT VT, SDLoc DL, SDValue Rsrc,
7497
7501
};
7498
7502
7499
7503
// Widen vec3 load to vec4.
7500
- if (VT.isVector() && VT.getVectorNumElements() == 3) {
7504
+ if (VT.isVector() && VT.getVectorNumElements() == 3 &&
7505
+ !Subtarget->hasScalarDwordx3Loads()) {
7501
7506
EVT WidenedVT =
7502
7507
EVT::getVectorVT(*DAG.getContext(), VT.getVectorElementType(), 4);
7503
7508
auto WidenedOp = DAG.getMemIntrinsicNode(
@@ -7913,6 +7918,19 @@ SDValue SITargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
7913
7918
}
7914
7919
}
7915
7920
7921
+ // On targets not supporting constant in soffset field, turn zero to
7922
+ // SGPR_NULL to avoid generating an extra s_mov with zero.
7923
+ static SDValue selectSOffset(SDValue SOffset, SelectionDAG &DAG,
7924
+ const GCNSubtarget *Subtarget) {
7925
+ if (Subtarget->hasRestrictedSOffset())
7926
+ if (auto SOffsetConst = dyn_cast<ConstantSDNode>(SOffset)) {
7927
+ if (SOffsetConst->isZero()) {
7928
+ return DAG.getRegister(AMDGPU::SGPR_NULL, MVT::i32);
7929
+ }
7930
+ }
7931
+ return SOffset;
7932
+ }
7933
+
7916
7934
SDValue SITargetLowering::lowerRawBufferAtomicIntrin(SDValue Op,
7917
7935
SelectionDAG &DAG,
7918
7936
unsigned NewOpcode) const {
@@ -7921,13 +7939,14 @@ SDValue SITargetLowering::lowerRawBufferAtomicIntrin(SDValue Op,
7921
7939
SDValue VData = Op.getOperand(2);
7922
7940
SDValue Rsrc = bufferRsrcPtrToVector(Op.getOperand(3), DAG);
7923
7941
auto Offsets = splitBufferOffsets(Op.getOperand(4), DAG);
7942
+ auto SOffset = selectSOffset(Op.getOperand(5), DAG, Subtarget);
7924
7943
SDValue Ops[] = {
7925
7944
Op.getOperand(0), // Chain
7926
7945
VData, // vdata
7927
7946
Rsrc, // rsrc
7928
7947
DAG.getConstant(0, DL, MVT::i32), // vindex
7929
7948
Offsets.first, // voffset
7930
- Op.getOperand(5), // soffset
7949
+ SOffset, // soffset
7931
7950
Offsets.second, // offset
7932
7951
Op.getOperand(6), // cachepolicy
7933
7952
DAG.getTargetConstant(0, DL, MVT::i1), // idxen
@@ -7954,13 +7973,14 @@ SITargetLowering::lowerStructBufferAtomicIntrin(SDValue Op, SelectionDAG &DAG,
7954
7973
SDValue VData = Op.getOperand(2);
7955
7974
SDValue Rsrc = bufferRsrcPtrToVector(Op.getOperand(3), DAG);
7956
7975
auto Offsets = splitBufferOffsets(Op.getOperand(5), DAG);
7976
+ auto SOffset = selectSOffset(Op.getOperand(6), DAG, Subtarget);
7957
7977
SDValue Ops[] = {
7958
7978
Op.getOperand(0), // Chain
7959
7979
VData, // vdata
7960
7980
Rsrc, // rsrc
7961
7981
Op.getOperand(4), // vindex
7962
7982
Offsets.first, // voffset
7963
- Op.getOperand(6), // soffset
7983
+ SOffset, // soffset
7964
7984
Offsets.second, // offset
7965
7985
Op.getOperand(7), // cachepolicy
7966
7986
DAG.getTargetConstant(1, DL, MVT::i1), // idxen
@@ -8116,12 +8136,13 @@ SDValue SITargetLowering::LowerINTRINSIC_W_CHAIN(SDValue Op,
8116
8136
8117
8137
SDValue Rsrc = bufferRsrcPtrToVector(Op.getOperand(2), DAG);
8118
8138
auto Offsets = splitBufferOffsets(Op.getOperand(3), DAG);
8139
+ auto SOffset = selectSOffset(Op.getOperand(4), DAG, Subtarget);
8119
8140
SDValue Ops[] = {
8120
8141
Op.getOperand(0), // Chain
8121
8142
Rsrc, // rsrc
8122
8143
DAG.getConstant(0, DL, MVT::i32), // vindex
8123
8144
Offsets.first, // voffset
8124
- Op.getOperand(4), // soffset
8145
+ SOffset, // soffset
8125
8146
Offsets.second, // offset
8126
8147
Op.getOperand(5), // cachepolicy, swizzled buffer
8127
8148
DAG.getTargetConstant(0, DL, MVT::i1), // idxen
@@ -8140,12 +8161,13 @@ SDValue SITargetLowering::LowerINTRINSIC_W_CHAIN(SDValue Op,
8140
8161
8141
8162
SDValue Rsrc = bufferRsrcPtrToVector(Op.getOperand(2), DAG);
8142
8163
auto Offsets = splitBufferOffsets(Op.getOperand(4), DAG);
8164
+ auto SOffset = selectSOffset(Op.getOperand(5), DAG, Subtarget);
8143
8165
SDValue Ops[] = {
8144
8166
Op.getOperand(0), // Chain
8145
8167
Rsrc, // rsrc
8146
8168
Op.getOperand(3), // vindex
8147
8169
Offsets.first, // voffset
8148
- Op.getOperand(5), // soffset
8170
+ SOffset, // soffset
8149
8171
Offsets.second, // offset
8150
8172
Op.getOperand(6), // cachepolicy, swizzled buffer
8151
8173
DAG.getTargetConstant(1, DL, MVT::i1), // idxen
@@ -8157,21 +8179,22 @@ SDValue SITargetLowering::LowerINTRINSIC_W_CHAIN(SDValue Op,
8157
8179
MemSDNode *M = cast<MemSDNode>(Op);
8158
8180
EVT LoadVT = Op.getValueType();
8159
8181
8182
+ auto SOffset = selectSOffset(Op.getOperand(5), DAG, Subtarget);
8160
8183
unsigned Dfmt = cast<ConstantSDNode>(Op.getOperand(7))->getZExtValue();
8161
8184
unsigned Nfmt = cast<ConstantSDNode>(Op.getOperand(8))->getZExtValue();
8162
8185
unsigned Glc = cast<ConstantSDNode>(Op.getOperand(9))->getZExtValue();
8163
8186
unsigned Slc = cast<ConstantSDNode>(Op.getOperand(10))->getZExtValue();
8164
8187
unsigned IdxEn = getIdxEn(Op.getOperand(3));
8165
8188
SDValue Ops[] = {
8166
- Op.getOperand(0), // Chain
8167
- Op.getOperand(2), // rsrc
8168
- Op.getOperand(3), // vindex
8169
- Op.getOperand(4), // voffset
8170
- Op.getOperand(5), // soffset
8171
- Op.getOperand(6), // offset
8172
- DAG.getTargetConstant(Dfmt | (Nfmt << 4), DL, MVT::i32), // format
8173
- DAG.getTargetConstant(Glc | (Slc << 1), DL, MVT::i32), // cachepolicy
8174
- DAG.getTargetConstant(IdxEn, DL, MVT::i1) // idxen
8189
+ Op.getOperand(0), // Chain
8190
+ Op.getOperand(2), // rsrc
8191
+ Op.getOperand(3), // vindex
8192
+ Op.getOperand(4), // voffset
8193
+ SOffset, // soffset
8194
+ Op.getOperand(6), // offset
8195
+ DAG.getTargetConstant(Dfmt | (Nfmt << 4), DL, MVT::i32), // format
8196
+ DAG.getTargetConstant(Glc | (Slc << 1), DL, MVT::i32), // cachepolicy
8197
+ DAG.getTargetConstant(IdxEn, DL, MVT::i1) // idxen
8175
8198
};
8176
8199
8177
8200
if (LoadVT.getScalarType() == MVT::f16)
@@ -8187,13 +8210,14 @@ SDValue SITargetLowering::LowerINTRINSIC_W_CHAIN(SDValue Op,
8187
8210
EVT LoadVT = Op.getValueType();
8188
8211
SDValue Rsrc = bufferRsrcPtrToVector(Op.getOperand(2), DAG);
8189
8212
auto Offsets = splitBufferOffsets(Op.getOperand(3), DAG);
8213
+ auto SOffset = selectSOffset(Op.getOperand(4), DAG, Subtarget);
8190
8214
8191
8215
SDValue Ops[] = {
8192
8216
Op.getOperand(0), // Chain
8193
8217
Rsrc, // rsrc
8194
8218
DAG.getConstant(0, DL, MVT::i32), // vindex
8195
8219
Offsets.first, // voffset
8196
- Op.getOperand(4), // soffset
8220
+ SOffset, // soffset
8197
8221
Offsets.second, // offset
8198
8222
Op.getOperand(5), // format
8199
8223
Op.getOperand(6), // cachepolicy, swizzled buffer
@@ -8213,13 +8237,14 @@ SDValue SITargetLowering::LowerINTRINSIC_W_CHAIN(SDValue Op,
8213
8237
EVT LoadVT = Op.getValueType();
8214
8238
SDValue Rsrc = bufferRsrcPtrToVector(Op.getOperand(2), DAG);
8215
8239
auto Offsets = splitBufferOffsets(Op.getOperand(4), DAG);
8240
+ auto SOffset = selectSOffset(Op.getOperand(5), DAG, Subtarget);
8216
8241
8217
8242
SDValue Ops[] = {
8218
8243
Op.getOperand(0), // Chain
8219
8244
Rsrc, // rsrc
8220
8245
Op.getOperand(3), // vindex
8221
8246
Offsets.first, // voffset
8222
- Op.getOperand(5), // soffset
8247
+ SOffset, // soffset
8223
8248
Offsets.second, // offset
8224
8249
Op.getOperand(6), // format
8225
8250
Op.getOperand(7), // cachepolicy, swizzled buffer
@@ -8432,14 +8457,15 @@ SDValue SITargetLowering::LowerINTRINSIC_W_CHAIN(SDValue Op,
8432
8457
case Intrinsic::amdgcn_raw_ptr_buffer_atomic_cmpswap: {
8433
8458
SDValue Rsrc = bufferRsrcPtrToVector(Op.getOperand(4), DAG);
8434
8459
auto Offsets = splitBufferOffsets(Op.getOperand(5), DAG);
8460
+ auto SOffset = selectSOffset(Op.getOperand(6), DAG, Subtarget);
8435
8461
SDValue Ops[] = {
8436
8462
Op.getOperand(0), // Chain
8437
8463
Op.getOperand(2), // src
8438
8464
Op.getOperand(3), // cmp
8439
8465
Rsrc, // rsrc
8440
8466
DAG.getConstant(0, DL, MVT::i32), // vindex
8441
8467
Offsets.first, // voffset
8442
- Op.getOperand(6), // soffset
8468
+ SOffset, // soffset
8443
8469
Offsets.second, // offset
8444
8470
Op.getOperand(7), // cachepolicy
8445
8471
DAG.getTargetConstant(0, DL, MVT::i1), // idxen
@@ -8454,14 +8480,15 @@ SDValue SITargetLowering::LowerINTRINSIC_W_CHAIN(SDValue Op,
8454
8480
case Intrinsic::amdgcn_struct_ptr_buffer_atomic_cmpswap: {
8455
8481
SDValue Rsrc = bufferRsrcPtrToVector(Op->getOperand(4), DAG);
8456
8482
auto Offsets = splitBufferOffsets(Op.getOperand(6), DAG);
8483
+ auto SOffset = selectSOffset(Op.getOperand(7), DAG, Subtarget);
8457
8484
SDValue Ops[] = {
8458
8485
Op.getOperand(0), // Chain
8459
8486
Op.getOperand(2), // src
8460
8487
Op.getOperand(3), // cmp
8461
8488
Rsrc, // rsrc
8462
8489
Op.getOperand(5), // vindex
8463
8490
Offsets.first, // voffset
8464
- Op.getOperand(7), // soffset
8491
+ SOffset, // soffset
8465
8492
Offsets.second, // offset
8466
8493
Op.getOperand(8), // cachepolicy
8467
8494
DAG.getTargetConstant(1, DL, MVT::i1), // idxen
@@ -8893,13 +8920,14 @@ SDValue SITargetLowering::LowerINTRINSIC_VOID(SDValue Op,
8893
8920
VData = handleD16VData(VData, DAG);
8894
8921
SDValue Rsrc = bufferRsrcPtrToVector(Op.getOperand(3), DAG);
8895
8922
auto Offsets = splitBufferOffsets(Op.getOperand(5), DAG);
8923
+ auto SOffset = selectSOffset(Op.getOperand(6), DAG, Subtarget);
8896
8924
SDValue Ops[] = {
8897
8925
Chain,
8898
8926
VData, // vdata
8899
8927
Rsrc, // rsrc
8900
8928
Op.getOperand(4), // vindex
8901
8929
Offsets.first, // voffset
8902
- Op.getOperand(6), // soffset
8930
+ SOffset, // soffset
8903
8931
Offsets.second, // offset
8904
8932
Op.getOperand(7), // format
8905
8933
Op.getOperand(8), // cachepolicy, swizzled buffer
@@ -8920,13 +8948,14 @@ SDValue SITargetLowering::LowerINTRINSIC_VOID(SDValue Op,
8920
8948
VData = handleD16VData(VData, DAG);
8921
8949
SDValue Rsrc = bufferRsrcPtrToVector(Op.getOperand(3), DAG);
8922
8950
auto Offsets = splitBufferOffsets(Op.getOperand(4), DAG);
8951
+ auto SOffset = selectSOffset(Op.getOperand(5), DAG, Subtarget);
8923
8952
SDValue Ops[] = {
8924
8953
Chain,
8925
8954
VData, // vdata
8926
8955
Rsrc, // rsrc
8927
8956
DAG.getConstant(0, DL, MVT::i32), // vindex
8928
8957
Offsets.first, // voffset
8929
- Op.getOperand(5), // soffset
8958
+ SOffset, // soffset
8930
8959
Offsets.second, // offset
8931
8960
Op.getOperand(6), // format
8932
8961
Op.getOperand(7), // cachepolicy, swizzled buffer
@@ -9000,13 +9029,14 @@ SDValue SITargetLowering::LowerINTRINSIC_VOID(SDValue Op,
9000
9029
9001
9030
SDValue Rsrc = bufferRsrcPtrToVector(Op.getOperand(3), DAG);
9002
9031
auto Offsets = splitBufferOffsets(Op.getOperand(4), DAG);
9032
+ auto SOffset = selectSOffset(Op.getOperand(5), DAG, Subtarget);
9003
9033
SDValue Ops[] = {
9004
9034
Chain,
9005
9035
VData,
9006
9036
Rsrc,
9007
9037
DAG.getConstant(0, DL, MVT::i32), // vindex
9008
9038
Offsets.first, // voffset
9009
- Op.getOperand(5), // soffset
9039
+ SOffset, // soffset
9010
9040
Offsets.second, // offset
9011
9041
Op.getOperand(6), // cachepolicy, swizzled buffer
9012
9042
DAG.getTargetConstant(0, DL, MVT::i1), // idxen
@@ -9050,13 +9080,14 @@ SDValue SITargetLowering::LowerINTRINSIC_VOID(SDValue Op,
9050
9080
9051
9081
auto Rsrc = bufferRsrcPtrToVector(Op.getOperand(3), DAG);
9052
9082
auto Offsets = splitBufferOffsets(Op.getOperand(5), DAG);
9083
+ auto SOffset = selectSOffset(Op.getOperand(6), DAG, Subtarget);
9053
9084
SDValue Ops[] = {
9054
9085
Chain,
9055
9086
VData,
9056
9087
Rsrc,
9057
9088
Op.getOperand(4), // vindex
9058
9089
Offsets.first, // voffset
9059
- Op.getOperand(6), // soffset
9090
+ SOffset, // soffset
9060
9091
Offsets.second, // offset
9061
9092
Op.getOperand(7), // cachepolicy, swizzled buffer
9062
9093
DAG.getTargetConstant(1, DL, MVT::i1), // idxen
@@ -9404,8 +9435,13 @@ void SITargetLowering::setBufferOffsets(SDValue CombinedOffset,
9404
9435
return;
9405
9436
}
9406
9437
}
9438
+
9439
+ SDValue SOffsetZero = Subtarget->hasRestrictedSOffset()
9440
+ ? DAG.getRegister(AMDGPU::SGPR_NULL, MVT::i32)
9441
+ : DAG.getConstant(0, DL, MVT::i32);
9442
+
9407
9443
Offsets[0] = CombinedOffset;
9408
- Offsets[1] = DAG.getConstant(0, DL, MVT::i32) ;
9444
+ Offsets[1] = SOffsetZero ;
9409
9445
Offsets[2] = DAG.getTargetConstant(0, DL, MVT::i32);
9410
9446
}
9411
9447
@@ -9663,7 +9699,8 @@ SDValue SITargetLowering::LowerLOAD(SDValue Op, SelectionDAG &DAG) const {
9663
9699
if (AS == AMDGPUAS::CONSTANT_ADDRESS ||
9664
9700
AS == AMDGPUAS::CONSTANT_ADDRESS_32BIT) {
9665
9701
if (!Op->isDivergent() && Alignment >= Align(4) && NumElements < 32) {
9666
- if (MemVT.isPow2VectorType())
9702
+ if (MemVT.isPow2VectorType() ||
9703
+ (Subtarget->hasScalarDwordx3Loads() && NumElements == 3))
9667
9704
return SDValue();
9668
9705
return WidenOrSplitVectorLoad(Op, DAG);
9669
9706
}
@@ -9679,7 +9716,8 @@ SDValue SITargetLowering::LowerLOAD(SDValue Op, SelectionDAG &DAG) const {
9679
9716
if (Subtarget->getScalarizeGlobalBehavior() && !Op->isDivergent() &&
9680
9717
Load->isSimple() && isMemOpHasNoClobberedMemOperand(Load) &&
9681
9718
Alignment >= Align(4) && NumElements < 32) {
9682
- if (MemVT.isPow2VectorType())
9719
+ if (MemVT.isPow2VectorType() ||
9720
+ (Subtarget->hasScalarDwordx3Loads() && NumElements == 3))
9683
9721
return SDValue();
9684
9722
return WidenOrSplitVectorLoad(Op, DAG);
9685
9723
}
0 commit comments