@@ -5521,11 +5521,18 @@ AMDGPUInstructionSelector::selectFlatOffsetImpl(MachineOperand &Root,
5521
5521
5522
5522
Register PtrBase;
5523
5523
int64_t ConstOffset;
5524
- std::tie (PtrBase, ConstOffset) =
5524
+ bool IsInBounds;
5525
+ std::tie (PtrBase, ConstOffset, IsInBounds) =
5525
5526
getPtrBaseWithConstantOffset (Root.getReg (), *MRI);
5526
5527
5527
- if (ConstOffset == 0 || (FlatVariant == SIInstrFlags::FlatScratch &&
5528
- !isFlatScratchBaseLegal (Root.getReg ())))
5528
+ // Adding the offset to the base address with an immediate in a FLAT
5529
+ // instruction must not change the memory aperture in which the address falls.
5530
+ // Therefore we can only fold offsets from inbounds GEPs into FLAT
5531
+ // instructions.
5532
+ if (ConstOffset == 0 ||
5533
+ (FlatVariant == SIInstrFlags::FlatScratch &&
5534
+ !isFlatScratchBaseLegal (Root.getReg ())) ||
5535
+ (FlatVariant == SIInstrFlags::FLAT && !IsInBounds))
5529
5536
return Default;
5530
5537
5531
5538
unsigned AddrSpace = (*MI->memoperands_begin ())->getAddrSpace ();
@@ -5577,7 +5584,8 @@ AMDGPUInstructionSelector::selectGlobalSAddr(MachineOperand &Root,
5577
5584
5578
5585
// Match the immediate offset first, which canonically is moved as low as
5579
5586
// possible.
5580
- std::tie (PtrBase, ConstOffset) = getPtrBaseWithConstantOffset (Addr, *MRI);
5587
+ std::tie (PtrBase, ConstOffset, std::ignore) =
5588
+ getPtrBaseWithConstantOffset (Addr, *MRI);
5581
5589
5582
5590
if (ConstOffset != 0 ) {
5583
5591
if (NeedIOffset &&
@@ -5760,7 +5768,8 @@ AMDGPUInstructionSelector::selectScratchSAddr(MachineOperand &Root) const {
5760
5768
5761
5769
// Match the immediate offset first, which canonically is moved as low as
5762
5770
// possible.
5763
- std::tie (PtrBase, ConstOffset) = getPtrBaseWithConstantOffset (Addr, *MRI);
5771
+ std::tie (PtrBase, ConstOffset, std::ignore) =
5772
+ getPtrBaseWithConstantOffset (Addr, *MRI);
5764
5773
5765
5774
if (ConstOffset != 0 && isFlatScratchBaseLegal (Addr) &&
5766
5775
TII.isLegalFLATOffset (ConstOffset, AMDGPUAS::PRIVATE_ADDRESS,
@@ -5836,7 +5845,8 @@ AMDGPUInstructionSelector::selectScratchSVAddr(MachineOperand &Root) const {
5836
5845
5837
5846
// Match the immediate offset first, which canonically is moved as low as
5838
5847
// possible.
5839
- std::tie (PtrBase, ConstOffset) = getPtrBaseWithConstantOffset (Addr, *MRI);
5848
+ std::tie (PtrBase, ConstOffset, std::ignore) =
5849
+ getPtrBaseWithConstantOffset (Addr, *MRI);
5840
5850
5841
5851
Register OrigAddr = Addr;
5842
5852
if (ConstOffset != 0 &&
@@ -5942,7 +5952,8 @@ AMDGPUInstructionSelector::selectMUBUFScratchOffen(MachineOperand &Root) const {
5942
5952
const MachineInstr *RootDef = MRI->getVRegDef (Root.getReg ());
5943
5953
Register PtrBase;
5944
5954
int64_t ConstOffset;
5945
- std::tie (PtrBase, ConstOffset) = getPtrBaseWithConstantOffset (VAddr, *MRI);
5955
+ std::tie (PtrBase, ConstOffset, std::ignore) =
5956
+ getPtrBaseWithConstantOffset (VAddr, *MRI);
5946
5957
if (ConstOffset != 0 ) {
5947
5958
if (TII.isLegalMUBUFImmOffset (ConstOffset) &&
5948
5959
(!STI.privateMemoryResourceIsRangeChecked () ||
@@ -6181,8 +6192,8 @@ AMDGPUInstructionSelector::selectDS1Addr1OffsetImpl(MachineOperand &Root) const
6181
6192
6182
6193
Register PtrBase;
6183
6194
int64_t Offset;
6184
- std::tie (PtrBase, Offset) =
6185
- getPtrBaseWithConstantOffset (Root.getReg (), *MRI);
6195
+ std::tie (PtrBase, Offset, std::ignore ) =
6196
+ getPtrBaseWithConstantOffset (Root.getReg (), *MRI);
6186
6197
6187
6198
if (Offset) {
6188
6199
if (isDSOffsetLegal (PtrBase, Offset)) {
@@ -6243,8 +6254,8 @@ AMDGPUInstructionSelector::selectDSReadWrite2Impl(MachineOperand &Root,
6243
6254
6244
6255
Register PtrBase;
6245
6256
int64_t Offset;
6246
- std::tie (PtrBase, Offset) =
6247
- getPtrBaseWithConstantOffset (Root.getReg (), *MRI);
6257
+ std::tie (PtrBase, Offset, std::ignore ) =
6258
+ getPtrBaseWithConstantOffset (Root.getReg (), *MRI);
6248
6259
6249
6260
if (Offset) {
6250
6261
int64_t OffsetValue0 = Offset;
@@ -6265,22 +6276,25 @@ AMDGPUInstructionSelector::selectDSReadWrite2Impl(MachineOperand &Root,
6265
6276
}
6266
6277
6267
6278
// / If \p Root is a G_PTR_ADD with a G_CONSTANT on the right hand side, return
6268
- // / the base value with the constant offset. There may be intervening copies
6269
- // / between \p Root and the identified constant. Returns \p Root, 0 if this does
6270
- // / not match the pattern.
6271
- std::pair<Register, int64_t >
6279
+ // / the base value with the constant offset, and if the offset computation is
6280
+ // / known to be inbounds. There may be intervening copies between \p Root and
6281
+ // / the identified constant. Returns \p Root, 0, false if this does not match
6282
+ // / the pattern.
6283
+ std::tuple<Register, int64_t , bool >
6272
6284
AMDGPUInstructionSelector::getPtrBaseWithConstantOffset (
6273
- Register Root, const MachineRegisterInfo &MRI) const {
6285
+ Register Root, const MachineRegisterInfo &MRI) const {
6274
6286
MachineInstr *RootI = getDefIgnoringCopies (Root, MRI);
6275
6287
if (RootI->getOpcode () != TargetOpcode::G_PTR_ADD)
6276
- return {Root, 0 };
6288
+ return {Root, 0 , false };
6277
6289
6278
6290
MachineOperand &RHS = RootI->getOperand (2 );
6279
6291
std::optional<ValueAndVReg> MaybeOffset =
6280
6292
getIConstantVRegValWithLookThrough (RHS.getReg (), MRI);
6281
6293
if (!MaybeOffset)
6282
- return {Root, 0 };
6283
- return {RootI->getOperand (1 ).getReg (), MaybeOffset->Value .getSExtValue ()};
6294
+ return {Root, 0 , false };
6295
+ bool IsInBounds = RootI->getFlag (MachineInstr::MIFlag::InBounds);
6296
+ return {RootI->getOperand (1 ).getReg (), MaybeOffset->Value .getSExtValue (),
6297
+ IsInBounds};
6284
6298
}
6285
6299
6286
6300
static void addZeroImm (MachineInstrBuilder &MIB) {
@@ -6358,7 +6372,8 @@ AMDGPUInstructionSelector::parseMUBUFAddress(Register Src) const {
6358
6372
Register PtrBase;
6359
6373
int64_t Offset;
6360
6374
6361
- std::tie (PtrBase, Offset) = getPtrBaseWithConstantOffset (Src, *MRI);
6375
+ std::tie (PtrBase, Offset, std::ignore) =
6376
+ getPtrBaseWithConstantOffset (Src, *MRI);
6362
6377
if (isUInt<32 >(Offset)) {
6363
6378
Data.N0 = PtrBase;
6364
6379
Data.Offset = Offset;
0 commit comments