forked from OSchip/llvm-project
[AMDGPU] Use SIInstrFlags for flat variants. NFC
Use SIInstrFlags to differentiate between the different variants of flat instructions (flat, global and scratch). This should make it easier to bundle the immediate offset logic in a single place and implement restrictions and bug workarounds. Fixed version of D99587, which does not rely on the address space. Differential Revision: https://reviews.llvm.org/D99743
This commit is contained in:
parent
c1a88e007b
commit
cc7add5298
|
@ -229,7 +229,7 @@ def FeatureNSAtoVMEMBug : SubtargetFeature<"nsa-to-vmem-bug",
|
||||||
def FeatureFlatSegmentOffsetBug : SubtargetFeature<"flat-segment-offset-bug",
|
def FeatureFlatSegmentOffsetBug : SubtargetFeature<"flat-segment-offset-bug",
|
||||||
"HasFlatSegmentOffsetBug",
|
"HasFlatSegmentOffsetBug",
|
||||||
"true",
|
"true",
|
||||||
"GFX10 bug, inst_offset ignored in flat segment"
|
"GFX10 bug where inst_offset is ignored when flat instructions access global memory"
|
||||||
>;
|
>;
|
||||||
|
|
||||||
def FeatureOffset3fBug : SubtargetFeature<"offset-3f-bug",
|
def FeatureOffset3fBug : SubtargetFeature<"offset-3f-bug",
|
||||||
|
|
|
@ -70,10 +70,10 @@ def gi_smrd_sgpr :
|
||||||
|
|
||||||
def gi_flat_offset :
|
def gi_flat_offset :
|
||||||
GIComplexOperandMatcher<s64, "selectFlatOffset">,
|
GIComplexOperandMatcher<s64, "selectFlatOffset">,
|
||||||
GIComplexPatternEquiv<FLATOffset>;
|
GIComplexPatternEquiv<FlatOffset>;
|
||||||
def gi_flat_offset_signed :
|
def gi_global_offset :
|
||||||
GIComplexOperandMatcher<s64, "selectFlatOffsetSigned">,
|
GIComplexOperandMatcher<s64, "selectGlobalOffset">,
|
||||||
GIComplexPatternEquiv<FLATOffsetSigned>;
|
GIComplexPatternEquiv<GlobalOffset>;
|
||||||
def gi_global_saddr :
|
def gi_global_saddr :
|
||||||
GIComplexOperandMatcher<s64, "selectGlobalSAddr">,
|
GIComplexOperandMatcher<s64, "selectGlobalSAddr">,
|
||||||
GIComplexPatternEquiv<GlobalSAddr>;
|
GIComplexPatternEquiv<GlobalSAddr>;
|
||||||
|
@ -86,7 +86,7 @@ def gi_mubuf_scratch_offen :
|
||||||
GIComplexPatternEquiv<MUBUFScratchOffen>;
|
GIComplexPatternEquiv<MUBUFScratchOffen>;
|
||||||
|
|
||||||
def gi_flat_scratch_offset :
|
def gi_flat_scratch_offset :
|
||||||
GIComplexOperandMatcher<s32, "selectFlatOffsetSigned">,
|
GIComplexOperandMatcher<s32, "selectScratchOffset">,
|
||||||
GIComplexPatternEquiv<ScratchOffset>;
|
GIComplexPatternEquiv<ScratchOffset>;
|
||||||
|
|
||||||
def gi_flat_scratch_saddr :
|
def gi_flat_scratch_saddr :
|
||||||
|
|
|
@ -201,9 +201,14 @@ private:
|
||||||
bool SelectMUBUFOffset(SDValue Addr, SDValue &SRsrc, SDValue &Soffset,
|
bool SelectMUBUFOffset(SDValue Addr, SDValue &SRsrc, SDValue &Soffset,
|
||||||
SDValue &Offset) const;
|
SDValue &Offset) const;
|
||||||
|
|
||||||
template <bool IsSigned>
|
bool SelectFlatOffsetImpl(SDNode *N, SDValue Addr, SDValue &VAddr,
|
||||||
|
SDValue &Offset, uint64_t FlatVariant) const;
|
||||||
bool SelectFlatOffset(SDNode *N, SDValue Addr, SDValue &VAddr,
|
bool SelectFlatOffset(SDNode *N, SDValue Addr, SDValue &VAddr,
|
||||||
SDValue &Offset) const;
|
SDValue &Offset) const;
|
||||||
|
bool SelectGlobalOffset(SDNode *N, SDValue Addr, SDValue &VAddr,
|
||||||
|
SDValue &Offset) const;
|
||||||
|
bool SelectScratchOffset(SDNode *N, SDValue Addr, SDValue &VAddr,
|
||||||
|
SDValue &Offset) const;
|
||||||
bool SelectGlobalSAddr(SDNode *N, SDValue Addr, SDValue &SAddr,
|
bool SelectGlobalSAddr(SDNode *N, SDValue Addr, SDValue &SAddr,
|
||||||
SDValue &VOffset, SDValue &Offset) const;
|
SDValue &VOffset, SDValue &Offset) const;
|
||||||
bool SelectScratchSAddr(SDNode *N, SDValue Addr, SDValue &SAddr,
|
bool SelectScratchSAddr(SDNode *N, SDValue Addr, SDValue &SAddr,
|
||||||
|
@ -1649,24 +1654,25 @@ static MemSDNode* findMemSDNode(SDNode *N) {
|
||||||
llvm_unreachable("cannot find MemSDNode in the pattern!");
|
llvm_unreachable("cannot find MemSDNode in the pattern!");
|
||||||
}
|
}
|
||||||
|
|
||||||
template <bool IsSigned>
|
bool AMDGPUDAGToDAGISel::SelectFlatOffsetImpl(SDNode *N, SDValue Addr,
|
||||||
bool AMDGPUDAGToDAGISel::SelectFlatOffset(SDNode *N,
|
SDValue &VAddr, SDValue &Offset,
|
||||||
SDValue Addr,
|
uint64_t FlatVariant) const {
|
||||||
SDValue &VAddr,
|
|
||||||
SDValue &Offset) const {
|
|
||||||
int64_t OffsetVal = 0;
|
int64_t OffsetVal = 0;
|
||||||
|
|
||||||
unsigned AS = findMemSDNode(N)->getAddressSpace();
|
unsigned AS = findMemSDNode(N)->getAddressSpace();
|
||||||
|
|
||||||
if (Subtarget->hasFlatInstOffsets() &&
|
bool CanHaveFlatSegmentOffsetBug =
|
||||||
(!Subtarget->hasFlatSegmentOffsetBug() ||
|
Subtarget->hasFlatSegmentOffsetBug() &&
|
||||||
AS != AMDGPUAS::FLAT_ADDRESS)) {
|
FlatVariant == SIInstrFlags::FLAT &&
|
||||||
|
(AS == AMDGPUAS::FLAT_ADDRESS || AS == AMDGPUAS::GLOBAL_ADDRESS);
|
||||||
|
|
||||||
|
if (Subtarget->hasFlatInstOffsets() && !CanHaveFlatSegmentOffsetBug) {
|
||||||
SDValue N0, N1;
|
SDValue N0, N1;
|
||||||
if (isBaseWithConstantOffset64(Addr, N0, N1)) {
|
if (isBaseWithConstantOffset64(Addr, N0, N1)) {
|
||||||
uint64_t COffsetVal = cast<ConstantSDNode>(N1)->getSExtValue();
|
uint64_t COffsetVal = cast<ConstantSDNode>(N1)->getSExtValue();
|
||||||
|
|
||||||
const SIInstrInfo *TII = Subtarget->getInstrInfo();
|
const SIInstrInfo *TII = Subtarget->getInstrInfo();
|
||||||
if (TII->isLegalFLATOffset(COffsetVal, AS, IsSigned)) {
|
if (TII->isLegalFLATOffset(COffsetVal, AS, FlatVariant)) {
|
||||||
Addr = N0;
|
Addr = N0;
|
||||||
OffsetVal = COffsetVal;
|
OffsetVal = COffsetVal;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1683,8 +1689,8 @@ bool AMDGPUDAGToDAGISel::SelectFlatOffset(SDNode *N,
|
||||||
SDLoc DL(N);
|
SDLoc DL(N);
|
||||||
uint64_t RemainderOffset;
|
uint64_t RemainderOffset;
|
||||||
|
|
||||||
std::tie(OffsetVal, RemainderOffset)
|
std::tie(OffsetVal, RemainderOffset) =
|
||||||
= TII->splitFlatOffset(COffsetVal, AS, IsSigned);
|
TII->splitFlatOffset(COffsetVal, AS, FlatVariant);
|
||||||
|
|
||||||
SDValue AddOffsetLo =
|
SDValue AddOffsetLo =
|
||||||
getMaterializedScalarImm32(Lo_32(RemainderOffset), DL);
|
getMaterializedScalarImm32(Lo_32(RemainderOffset), DL);
|
||||||
|
@ -1741,6 +1747,25 @@ bool AMDGPUDAGToDAGISel::SelectFlatOffset(SDNode *N,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AMDGPUDAGToDAGISel::SelectFlatOffset(SDNode *N, SDValue Addr,
|
||||||
|
SDValue &VAddr,
|
||||||
|
SDValue &Offset) const {
|
||||||
|
return SelectFlatOffsetImpl(N, Addr, VAddr, Offset, SIInstrFlags::FLAT);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AMDGPUDAGToDAGISel::SelectGlobalOffset(SDNode *N, SDValue Addr,
|
||||||
|
SDValue &VAddr,
|
||||||
|
SDValue &Offset) const {
|
||||||
|
return SelectFlatOffsetImpl(N, Addr, VAddr, Offset, SIInstrFlags::FlatGlobal);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AMDGPUDAGToDAGISel::SelectScratchOffset(SDNode *N, SDValue Addr,
|
||||||
|
SDValue &VAddr,
|
||||||
|
SDValue &Offset) const {
|
||||||
|
return SelectFlatOffsetImpl(N, Addr, VAddr, Offset,
|
||||||
|
SIInstrFlags::FlatScratch);
|
||||||
|
}
|
||||||
|
|
||||||
// If this matches zero_extend i32:x, return x
|
// If this matches zero_extend i32:x, return x
|
||||||
static SDValue matchZExtFromI32(SDValue Op) {
|
static SDValue matchZExtFromI32(SDValue Op) {
|
||||||
if (Op.getOpcode() != ISD::ZERO_EXTEND)
|
if (Op.getOpcode() != ISD::ZERO_EXTEND)
|
||||||
|
@ -1766,7 +1791,8 @@ bool AMDGPUDAGToDAGISel::SelectGlobalSAddr(SDNode *N,
|
||||||
int64_t COffsetVal = cast<ConstantSDNode>(RHS)->getSExtValue();
|
int64_t COffsetVal = cast<ConstantSDNode>(RHS)->getSExtValue();
|
||||||
const SIInstrInfo *TII = Subtarget->getInstrInfo();
|
const SIInstrInfo *TII = Subtarget->getInstrInfo();
|
||||||
|
|
||||||
if (TII->isLegalFLATOffset(COffsetVal, AMDGPUAS::GLOBAL_ADDRESS, true)) {
|
if (TII->isLegalFLATOffset(COffsetVal, AMDGPUAS::GLOBAL_ADDRESS,
|
||||||
|
SIInstrFlags::FlatGlobal)) {
|
||||||
Addr = LHS;
|
Addr = LHS;
|
||||||
ImmOffset = COffsetVal;
|
ImmOffset = COffsetVal;
|
||||||
} else if (!LHS->isDivergent() && COffsetVal > 0) {
|
} else if (!LHS->isDivergent() && COffsetVal > 0) {
|
||||||
|
@ -1774,8 +1800,8 @@ bool AMDGPUDAGToDAGISel::SelectGlobalSAddr(SDNode *N,
|
||||||
// saddr + large_offset -> saddr + (voffset = large_offset & ~MaxOffset) +
|
// saddr + large_offset -> saddr + (voffset = large_offset & ~MaxOffset) +
|
||||||
// (large_offset & MaxOffset);
|
// (large_offset & MaxOffset);
|
||||||
int64_t SplitImmOffset, RemainderOffset;
|
int64_t SplitImmOffset, RemainderOffset;
|
||||||
std::tie(SplitImmOffset, RemainderOffset)
|
std::tie(SplitImmOffset, RemainderOffset) = TII->splitFlatOffset(
|
||||||
= TII->splitFlatOffset(COffsetVal, AMDGPUAS::GLOBAL_ADDRESS, true);
|
COffsetVal, AMDGPUAS::GLOBAL_ADDRESS, SIInstrFlags::FlatGlobal);
|
||||||
|
|
||||||
if (isUInt<32>(RemainderOffset)) {
|
if (isUInt<32>(RemainderOffset)) {
|
||||||
SDNode *VMov = CurDAG->getMachineNode(
|
SDNode *VMov = CurDAG->getMachineNode(
|
||||||
|
@ -1864,14 +1890,16 @@ bool AMDGPUDAGToDAGISel::SelectScratchSAddr(SDNode *N,
|
||||||
|
|
||||||
const SIInstrInfo *TII = Subtarget->getInstrInfo();
|
const SIInstrInfo *TII = Subtarget->getInstrInfo();
|
||||||
|
|
||||||
if (!TII->isLegalFLATOffset(COffsetVal, AMDGPUAS::PRIVATE_ADDRESS, true)) {
|
if (!TII->isLegalFLATOffset(COffsetVal, AMDGPUAS::PRIVATE_ADDRESS,
|
||||||
|
SIInstrFlags::FlatScratch)) {
|
||||||
const unsigned NumBits = AMDGPU::getNumFlatOffsetBits(*Subtarget, true);
|
const unsigned NumBits = AMDGPU::getNumFlatOffsetBits(*Subtarget, true);
|
||||||
// Use signed division by a power of two to truncate towards 0.
|
// Use signed division by a power of two to truncate towards 0.
|
||||||
int64_t D = 1LL << (NumBits - 1);
|
int64_t D = 1LL << (NumBits - 1);
|
||||||
int64_t RemainderOffset = (COffsetVal / D) * D;
|
int64_t RemainderOffset = (COffsetVal / D) * D;
|
||||||
int64_t ImmField = COffsetVal - RemainderOffset;
|
int64_t ImmField = COffsetVal - RemainderOffset;
|
||||||
|
|
||||||
assert(TII->isLegalFLATOffset(ImmField, AMDGPUAS::PRIVATE_ADDRESS, true));
|
assert(TII->isLegalFLATOffset(ImmField, AMDGPUAS::PRIVATE_ADDRESS,
|
||||||
|
SIInstrFlags::FlatScratch));
|
||||||
assert(RemainderOffset + ImmField == COffsetVal);
|
assert(RemainderOffset + ImmField == COffsetVal);
|
||||||
|
|
||||||
COffsetVal = ImmField;
|
COffsetVal = ImmField;
|
||||||
|
|
|
@ -3023,7 +3023,7 @@ bool AMDGPUInstructionSelector::selectGlobalAtomicFadd(
|
||||||
// FIXME: This is only needed because tablegen requires number of dst operands
|
// FIXME: This is only needed because tablegen requires number of dst operands
|
||||||
// in match and replace pattern to be the same. Otherwise patterns can be
|
// in match and replace pattern to be the same. Otherwise patterns can be
|
||||||
// exported from SDag path.
|
// exported from SDag path.
|
||||||
auto Addr = selectFlatOffsetImpl<true>(AddrOp);
|
auto Addr = selectFlatOffsetImpl(AddrOp, SIInstrFlags::FlatGlobal);
|
||||||
|
|
||||||
Register Data = DataOp.getReg();
|
Register Data = DataOp.getReg();
|
||||||
const unsigned Opc = MRI->getType(Data).isVector() ?
|
const unsigned Opc = MRI->getType(Data).isVector() ?
|
||||||
|
@ -3437,9 +3437,9 @@ AMDGPUInstructionSelector::selectSmrdSgpr(MachineOperand &Root) const {
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <bool Signed>
|
|
||||||
std::pair<Register, int>
|
std::pair<Register, int>
|
||||||
AMDGPUInstructionSelector::selectFlatOffsetImpl(MachineOperand &Root) const {
|
AMDGPUInstructionSelector::selectFlatOffsetImpl(MachineOperand &Root,
|
||||||
|
uint64_t FlatVariant) const {
|
||||||
MachineInstr *MI = Root.getParent();
|
MachineInstr *MI = Root.getParent();
|
||||||
|
|
||||||
auto Default = std::make_pair(Root.getReg(), 0);
|
auto Default = std::make_pair(Root.getReg(), 0);
|
||||||
|
@ -3455,7 +3455,7 @@ AMDGPUInstructionSelector::selectFlatOffsetImpl(MachineOperand &Root) const {
|
||||||
return Default;
|
return Default;
|
||||||
|
|
||||||
unsigned AddrSpace = (*MI->memoperands_begin())->getAddrSpace();
|
unsigned AddrSpace = (*MI->memoperands_begin())->getAddrSpace();
|
||||||
if (!TII.isLegalFLATOffset(ConstOffset, AddrSpace, Signed))
|
if (!TII.isLegalFLATOffset(ConstOffset, AddrSpace, FlatVariant))
|
||||||
return Default;
|
return Default;
|
||||||
|
|
||||||
return std::make_pair(PtrBase, ConstOffset);
|
return std::make_pair(PtrBase, ConstOffset);
|
||||||
|
@ -3463,7 +3463,7 @@ AMDGPUInstructionSelector::selectFlatOffsetImpl(MachineOperand &Root) const {
|
||||||
|
|
||||||
InstructionSelector::ComplexRendererFns
|
InstructionSelector::ComplexRendererFns
|
||||||
AMDGPUInstructionSelector::selectFlatOffset(MachineOperand &Root) const {
|
AMDGPUInstructionSelector::selectFlatOffset(MachineOperand &Root) const {
|
||||||
auto PtrWithOffset = selectFlatOffsetImpl<false>(Root);
|
auto PtrWithOffset = selectFlatOffsetImpl(Root, SIInstrFlags::FLAT);
|
||||||
|
|
||||||
return {{
|
return {{
|
||||||
[=](MachineInstrBuilder &MIB) { MIB.addReg(PtrWithOffset.first); },
|
[=](MachineInstrBuilder &MIB) { MIB.addReg(PtrWithOffset.first); },
|
||||||
|
@ -3472,8 +3472,18 @@ AMDGPUInstructionSelector::selectFlatOffset(MachineOperand &Root) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
InstructionSelector::ComplexRendererFns
|
InstructionSelector::ComplexRendererFns
|
||||||
AMDGPUInstructionSelector::selectFlatOffsetSigned(MachineOperand &Root) const {
|
AMDGPUInstructionSelector::selectGlobalOffset(MachineOperand &Root) const {
|
||||||
auto PtrWithOffset = selectFlatOffsetImpl<true>(Root);
|
auto PtrWithOffset = selectFlatOffsetImpl(Root, SIInstrFlags::FlatGlobal);
|
||||||
|
|
||||||
|
return {{
|
||||||
|
[=](MachineInstrBuilder &MIB) { MIB.addReg(PtrWithOffset.first); },
|
||||||
|
[=](MachineInstrBuilder &MIB) { MIB.addImm(PtrWithOffset.second); },
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
InstructionSelector::ComplexRendererFns
|
||||||
|
AMDGPUInstructionSelector::selectScratchOffset(MachineOperand &Root) const {
|
||||||
|
auto PtrWithOffset = selectFlatOffsetImpl(Root, SIInstrFlags::FlatScratch);
|
||||||
|
|
||||||
return {{
|
return {{
|
||||||
[=](MachineInstrBuilder &MIB) { MIB.addReg(PtrWithOffset.first); },
|
[=](MachineInstrBuilder &MIB) { MIB.addReg(PtrWithOffset.first); },
|
||||||
|
@ -3512,7 +3522,8 @@ AMDGPUInstructionSelector::selectGlobalSAddr(MachineOperand &Root) const {
|
||||||
std::tie(PtrBase, ConstOffset) = getPtrBaseWithConstantOffset(Addr, *MRI);
|
std::tie(PtrBase, ConstOffset) = getPtrBaseWithConstantOffset(Addr, *MRI);
|
||||||
|
|
||||||
if (ConstOffset != 0) {
|
if (ConstOffset != 0) {
|
||||||
if (TII.isLegalFLATOffset(ConstOffset, AMDGPUAS::GLOBAL_ADDRESS, true)) {
|
if (TII.isLegalFLATOffset(ConstOffset, AMDGPUAS::GLOBAL_ADDRESS,
|
||||||
|
SIInstrFlags::FlatGlobal)) {
|
||||||
Addr = PtrBase;
|
Addr = PtrBase;
|
||||||
ImmOffset = ConstOffset;
|
ImmOffset = ConstOffset;
|
||||||
} else if (ConstOffset > 0) {
|
} else if (ConstOffset > 0) {
|
||||||
|
@ -3526,8 +3537,8 @@ AMDGPUInstructionSelector::selectGlobalSAddr(MachineOperand &Root) const {
|
||||||
// saddr + large_offset -> saddr + (voffset = large_offset & ~MaxOffset)
|
// saddr + large_offset -> saddr + (voffset = large_offset & ~MaxOffset)
|
||||||
// + (large_offset & MaxOffset);
|
// + (large_offset & MaxOffset);
|
||||||
int64_t SplitImmOffset, RemainderOffset;
|
int64_t SplitImmOffset, RemainderOffset;
|
||||||
std::tie(SplitImmOffset, RemainderOffset)
|
std::tie(SplitImmOffset, RemainderOffset) = TII.splitFlatOffset(
|
||||||
= TII.splitFlatOffset(ConstOffset, AMDGPUAS::GLOBAL_ADDRESS, true);
|
ConstOffset, AMDGPUAS::GLOBAL_ADDRESS, SIInstrFlags::FlatGlobal);
|
||||||
|
|
||||||
if (isUInt<32>(RemainderOffset)) {
|
if (isUInt<32>(RemainderOffset)) {
|
||||||
MachineInstr *MI = Root.getParent();
|
MachineInstr *MI = Root.getParent();
|
||||||
|
@ -3619,7 +3630,8 @@ AMDGPUInstructionSelector::selectScratchSAddr(MachineOperand &Root) const {
|
||||||
std::tie(PtrBase, ConstOffset) = getPtrBaseWithConstantOffset(Addr, *MRI);
|
std::tie(PtrBase, ConstOffset) = getPtrBaseWithConstantOffset(Addr, *MRI);
|
||||||
|
|
||||||
if (ConstOffset != 0 &&
|
if (ConstOffset != 0 &&
|
||||||
TII.isLegalFLATOffset(ConstOffset, AMDGPUAS::PRIVATE_ADDRESS, true)) {
|
TII.isLegalFLATOffset(ConstOffset, AMDGPUAS::PRIVATE_ADDRESS,
|
||||||
|
SIInstrFlags::FlatScratch)) {
|
||||||
Addr = PtrBase;
|
Addr = PtrBase;
|
||||||
ImmOffset = ConstOffset;
|
ImmOffset = ConstOffset;
|
||||||
}
|
}
|
||||||
|
|
|
@ -192,14 +192,15 @@ private:
|
||||||
InstructionSelector::ComplexRendererFns
|
InstructionSelector::ComplexRendererFns
|
||||||
selectSmrdSgpr(MachineOperand &Root) const;
|
selectSmrdSgpr(MachineOperand &Root) const;
|
||||||
|
|
||||||
template <bool Signed>
|
std::pair<Register, int> selectFlatOffsetImpl(MachineOperand &Root,
|
||||||
std::pair<Register, int>
|
uint64_t FlatVariant) const;
|
||||||
selectFlatOffsetImpl(MachineOperand &Root) const;
|
|
||||||
|
|
||||||
InstructionSelector::ComplexRendererFns
|
InstructionSelector::ComplexRendererFns
|
||||||
selectFlatOffset(MachineOperand &Root) const;
|
selectFlatOffset(MachineOperand &Root) const;
|
||||||
InstructionSelector::ComplexRendererFns
|
InstructionSelector::ComplexRendererFns
|
||||||
selectFlatOffsetSigned(MachineOperand &Root) const;
|
selectGlobalOffset(MachineOperand &Root) const;
|
||||||
|
InstructionSelector::ComplexRendererFns
|
||||||
|
selectScratchOffset(MachineOperand &Root) const;
|
||||||
|
|
||||||
InstructionSelector::ComplexRendererFns
|
InstructionSelector::ComplexRendererFns
|
||||||
selectGlobalSAddr(MachineOperand &Root) const;
|
selectGlobalSAddr(MachineOperand &Root) const;
|
||||||
|
|
|
@ -6,9 +6,9 @@
|
||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
def FLATOffset : ComplexPattern<i64, 2, "SelectFlatOffset<false>", [], [SDNPWantRoot], -10>;
|
def FlatOffset : ComplexPattern<i64, 2, "SelectFlatOffset", [], [SDNPWantRoot], -10>;
|
||||||
def FLATOffsetSigned : ComplexPattern<i64, 2, "SelectFlatOffset<true>", [], [SDNPWantRoot], -10>;
|
def GlobalOffset : ComplexPattern<i64, 2, "SelectGlobalOffset", [], [SDNPWantRoot], -10>;
|
||||||
def ScratchOffset : ComplexPattern<i32, 2, "SelectFlatOffset<true>", [], [SDNPWantRoot], -10>;
|
def ScratchOffset : ComplexPattern<i32, 2, "SelectScratchOffset", [], [SDNPWantRoot], -10>;
|
||||||
|
|
||||||
def GlobalSAddr : ComplexPattern<i64, 3, "SelectGlobalSAddr", [], [SDNPWantRoot], -10>;
|
def GlobalSAddr : ComplexPattern<i64, 3, "SelectGlobalSAddr", [], [SDNPWantRoot], -10>;
|
||||||
def ScratchSAddr : ComplexPattern<i32, 2, "SelectScratchSAddr", [], [SDNPWantRoot], -10>;
|
def ScratchSAddr : ComplexPattern<i32, 2, "SelectScratchSAddr", [], [SDNPWantRoot], -10>;
|
||||||
|
@ -392,7 +392,7 @@ multiclass FLAT_Atomic_Pseudo<
|
||||||
(ins VReg_64:$vaddr, data_op:$vdata, flat_offset:$offset, CPol_GLC1:$cpol),
|
(ins VReg_64:$vaddr, data_op:$vdata, flat_offset:$offset, CPol_GLC1:$cpol),
|
||||||
" $vdst, $vaddr, $vdata$offset$cpol",
|
" $vdst, $vaddr, $vdata$offset$cpol",
|
||||||
[(set vt:$vdst,
|
[(set vt:$vdst,
|
||||||
(atomic (FLATOffset i64:$vaddr, i16:$offset), data_vt:$vdata))]>,
|
(atomic (FlatOffset i64:$vaddr, i16:$offset), data_vt:$vdata))]>,
|
||||||
GlobalSaddrTable<0, opName#"_rtn">,
|
GlobalSaddrTable<0, opName#"_rtn">,
|
||||||
AtomicNoRet <opName, 1>{
|
AtomicNoRet <opName, 1>{
|
||||||
let FPAtomic = isFP;
|
let FPAtomic = isFP;
|
||||||
|
@ -450,7 +450,7 @@ multiclass FLAT_Global_Atomic_Pseudo_RTN<
|
||||||
(ins VReg_64:$vaddr, data_op:$vdata, flat_offset:$offset, CPol_GLC1:$cpol),
|
(ins VReg_64:$vaddr, data_op:$vdata, flat_offset:$offset, CPol_GLC1:$cpol),
|
||||||
" $vdst, $vaddr, $vdata, off$offset$cpol",
|
" $vdst, $vaddr, $vdata, off$offset$cpol",
|
||||||
[(set vt:$vdst,
|
[(set vt:$vdst,
|
||||||
(atomic (FLATOffsetSigned i64:$vaddr, i16:$offset), data_vt:$vdata))]>,
|
(atomic (GlobalOffset i64:$vaddr, i16:$offset), data_vt:$vdata))]>,
|
||||||
GlobalSaddrTable<0, opName#"_rtn">,
|
GlobalSaddrTable<0, opName#"_rtn">,
|
||||||
AtomicNoRet <opName, 1> {
|
AtomicNoRet <opName, 1> {
|
||||||
let has_saddr = 1;
|
let has_saddr = 1;
|
||||||
|
@ -817,17 +817,17 @@ let OtherPredicates = [isGFX90APlus] in {
|
||||||
|
|
||||||
// Patterns for global loads with no offset.
|
// Patterns for global loads with no offset.
|
||||||
class FlatLoadPat <FLAT_Pseudo inst, SDPatternOperator node, ValueType vt> : GCNPat <
|
class FlatLoadPat <FLAT_Pseudo inst, SDPatternOperator node, ValueType vt> : GCNPat <
|
||||||
(vt (node (FLATOffset i64:$vaddr, i16:$offset))),
|
(vt (node (FlatOffset i64:$vaddr, i16:$offset))),
|
||||||
(inst $vaddr, $offset)
|
(inst $vaddr, $offset)
|
||||||
>;
|
>;
|
||||||
|
|
||||||
class FlatLoadPat_D16 <FLAT_Pseudo inst, SDPatternOperator node, ValueType vt> : GCNPat <
|
class FlatLoadPat_D16 <FLAT_Pseudo inst, SDPatternOperator node, ValueType vt> : GCNPat <
|
||||||
(node (FLATOffset (i64 VReg_64:$vaddr), i16:$offset), vt:$in),
|
(node (FlatOffset (i64 VReg_64:$vaddr), i16:$offset), vt:$in),
|
||||||
(inst $vaddr, $offset, 0, $in)
|
(inst $vaddr, $offset, 0, $in)
|
||||||
>;
|
>;
|
||||||
|
|
||||||
class FlatSignedLoadPat_D16 <FLAT_Pseudo inst, SDPatternOperator node, ValueType vt> : GCNPat <
|
class FlatSignedLoadPat_D16 <FLAT_Pseudo inst, SDPatternOperator node, ValueType vt> : GCNPat <
|
||||||
(node (FLATOffsetSigned (i64 VReg_64:$vaddr), i16:$offset), vt:$in),
|
(node (GlobalOffset (i64 VReg_64:$vaddr), i16:$offset), vt:$in),
|
||||||
(inst $vaddr, $offset, 0, $in)
|
(inst $vaddr, $offset, 0, $in)
|
||||||
>;
|
>;
|
||||||
|
|
||||||
|
@ -837,7 +837,7 @@ class GlobalLoadSaddrPat_D16 <FLAT_Pseudo inst, SDPatternOperator node, ValueTyp
|
||||||
>;
|
>;
|
||||||
|
|
||||||
class FlatLoadSignedPat <FLAT_Pseudo inst, SDPatternOperator node, ValueType vt> : GCNPat <
|
class FlatLoadSignedPat <FLAT_Pseudo inst, SDPatternOperator node, ValueType vt> : GCNPat <
|
||||||
(vt (node (FLATOffsetSigned (i64 VReg_64:$vaddr), i16:$offset))),
|
(vt (node (GlobalOffset (i64 VReg_64:$vaddr), i16:$offset))),
|
||||||
(inst $vaddr, $offset)
|
(inst $vaddr, $offset)
|
||||||
>;
|
>;
|
||||||
|
|
||||||
|
@ -871,19 +871,19 @@ class GlobalAtomicNoRtnSaddrPat <FLAT_Pseudo inst, SDPatternOperator node,
|
||||||
>;
|
>;
|
||||||
|
|
||||||
class FlatStorePat <FLAT_Pseudo inst, SDPatternOperator node, ValueType vt> : GCNPat <
|
class FlatStorePat <FLAT_Pseudo inst, SDPatternOperator node, ValueType vt> : GCNPat <
|
||||||
(node vt:$data, (FLATOffset i64:$vaddr, i16:$offset)),
|
(node vt:$data, (FlatOffset i64:$vaddr, i16:$offset)),
|
||||||
(inst $vaddr, getVregSrcForVT<vt>.ret:$data, $offset)
|
(inst $vaddr, getVregSrcForVT<vt>.ret:$data, $offset)
|
||||||
>;
|
>;
|
||||||
|
|
||||||
class FlatStoreSignedPat <FLAT_Pseudo inst, SDPatternOperator node, ValueType vt> : GCNPat <
|
class FlatStoreSignedPat <FLAT_Pseudo inst, SDPatternOperator node, ValueType vt> : GCNPat <
|
||||||
(node vt:$data, (FLATOffsetSigned i64:$vaddr, i16:$offset)),
|
(node vt:$data, (GlobalOffset i64:$vaddr, i16:$offset)),
|
||||||
(inst $vaddr, getVregSrcForVT<vt>.ret:$data, $offset)
|
(inst $vaddr, getVregSrcForVT<vt>.ret:$data, $offset)
|
||||||
>;
|
>;
|
||||||
|
|
||||||
class FlatStoreAtomicPat <FLAT_Pseudo inst, SDPatternOperator node, ValueType vt> : GCNPat <
|
class FlatStoreAtomicPat <FLAT_Pseudo inst, SDPatternOperator node, ValueType vt> : GCNPat <
|
||||||
// atomic store follows atomic binop convention so the address comes
|
// atomic store follows atomic binop convention so the address comes
|
||||||
// first.
|
// first.
|
||||||
(node (FLATOffset i64:$vaddr, i16:$offset), vt:$data),
|
(node (FlatOffset i64:$vaddr, i16:$offset), vt:$data),
|
||||||
(inst $vaddr, getVregSrcForVT<vt>.ret:$data, $offset)
|
(inst $vaddr, getVregSrcForVT<vt>.ret:$data, $offset)
|
||||||
>;
|
>;
|
||||||
|
|
||||||
|
@ -891,29 +891,29 @@ class FlatStoreSignedAtomicPat <FLAT_Pseudo inst, SDPatternOperator node,
|
||||||
ValueType vt, ValueType data_vt = vt> : GCNPat <
|
ValueType vt, ValueType data_vt = vt> : GCNPat <
|
||||||
// atomic store follows atomic binop convention so the address comes
|
// atomic store follows atomic binop convention so the address comes
|
||||||
// first.
|
// first.
|
||||||
(node (FLATOffset i64:$vaddr, i16:$offset), data_vt:$data),
|
(node (GlobalOffset i64:$vaddr, i16:$offset), data_vt:$data),
|
||||||
(inst $vaddr, getVregSrcForVT<data_vt>.ret:$data, $offset)
|
(inst $vaddr, getVregSrcForVT<data_vt>.ret:$data, $offset)
|
||||||
>;
|
>;
|
||||||
|
|
||||||
class FlatAtomicPat <FLAT_Pseudo inst, SDPatternOperator node, ValueType vt,
|
class FlatAtomicPat <FLAT_Pseudo inst, SDPatternOperator node, ValueType vt,
|
||||||
ValueType data_vt = vt> : GCNPat <
|
ValueType data_vt = vt> : GCNPat <
|
||||||
(vt (node (FLATOffset i64:$vaddr, i16:$offset), data_vt:$data)),
|
(vt (node (FlatOffset i64:$vaddr, i16:$offset), data_vt:$data)),
|
||||||
(inst $vaddr, $data, $offset)
|
(inst $vaddr, $data, $offset)
|
||||||
>;
|
>;
|
||||||
|
|
||||||
class FlatAtomicPatNoRtn <FLAT_Pseudo inst, SDPatternOperator node, ValueType vt> : GCNPat <
|
class FlatAtomicPatNoRtn <FLAT_Pseudo inst, SDPatternOperator node, ValueType vt> : GCNPat <
|
||||||
(node (FLATOffset i64:$vaddr, i16:$offset), vt:$data),
|
(node (FlatOffset i64:$vaddr, i16:$offset), vt:$data),
|
||||||
(inst VReg_64:$vaddr, getVregSrcForVT<vt>.ret:$data, $offset)
|
(inst VReg_64:$vaddr, getVregSrcForVT<vt>.ret:$data, $offset)
|
||||||
>;
|
>;
|
||||||
|
|
||||||
class FlatSignedAtomicPatNoRtn <FLAT_Pseudo inst, SDPatternOperator node, ValueType vt> : GCNPat <
|
class FlatSignedAtomicPatNoRtn <FLAT_Pseudo inst, SDPatternOperator node, ValueType vt> : GCNPat <
|
||||||
(node (FLATOffsetSigned i64:$vaddr, i16:$offset), vt:$data),
|
(node (GlobalOffset i64:$vaddr, i16:$offset), vt:$data),
|
||||||
(inst VReg_64:$vaddr, getVregSrcForVT<vt>.ret:$data, $offset)
|
(inst VReg_64:$vaddr, getVregSrcForVT<vt>.ret:$data, $offset)
|
||||||
>;
|
>;
|
||||||
|
|
||||||
class FlatSignedAtomicPat <FLAT_Pseudo inst, SDPatternOperator node, ValueType vt,
|
class FlatSignedAtomicPat <FLAT_Pseudo inst, SDPatternOperator node, ValueType vt,
|
||||||
ValueType data_vt = vt> : GCNPat <
|
ValueType data_vt = vt> : GCNPat <
|
||||||
(vt (node (FLATOffsetSigned i64:$vaddr, i16:$offset), data_vt:$data)),
|
(vt (node (GlobalOffset i64:$vaddr, i16:$offset), data_vt:$data)),
|
||||||
(inst $vaddr, $data, $offset)
|
(inst $vaddr, $data, $offset)
|
||||||
>;
|
>;
|
||||||
|
|
||||||
|
|
|
@ -130,7 +130,8 @@ static void buildPrologSpill(const GCNSubtarget &ST, LivePhysRegs &LiveRegs,
|
||||||
MFI.getObjectAlign(FI));
|
MFI.getObjectAlign(FI));
|
||||||
|
|
||||||
if (ST.enableFlatScratch()) {
|
if (ST.enableFlatScratch()) {
|
||||||
if (TII->isLegalFLATOffset(Offset, AMDGPUAS::PRIVATE_ADDRESS, true)) {
|
if (TII->isLegalFLATOffset(Offset, AMDGPUAS::PRIVATE_ADDRESS,
|
||||||
|
SIInstrFlags::FlatScratch)) {
|
||||||
BuildMI(MBB, I, DebugLoc(), TII->get(AMDGPU::SCRATCH_STORE_DWORD_SADDR))
|
BuildMI(MBB, I, DebugLoc(), TII->get(AMDGPU::SCRATCH_STORE_DWORD_SADDR))
|
||||||
.addReg(SpillReg, RegState::Kill)
|
.addReg(SpillReg, RegState::Kill)
|
||||||
.addReg(SPReg)
|
.addReg(SPReg)
|
||||||
|
@ -239,7 +240,8 @@ static void buildEpilogReload(const GCNSubtarget &ST, LivePhysRegs &LiveRegs,
|
||||||
MFI.getObjectAlign(FI));
|
MFI.getObjectAlign(FI));
|
||||||
|
|
||||||
if (ST.enableFlatScratch()) {
|
if (ST.enableFlatScratch()) {
|
||||||
if (TII->isLegalFLATOffset(Offset, AMDGPUAS::PRIVATE_ADDRESS, true)) {
|
if (TII->isLegalFLATOffset(Offset, AMDGPUAS::PRIVATE_ADDRESS,
|
||||||
|
SIInstrFlags::FlatScratch)) {
|
||||||
BuildMI(MBB, I, DebugLoc(),
|
BuildMI(MBB, I, DebugLoc(),
|
||||||
TII->get(AMDGPU::SCRATCH_LOAD_DWORD_SADDR), SpillReg)
|
TII->get(AMDGPU::SCRATCH_LOAD_DWORD_SADDR), SpillReg)
|
||||||
.addReg(SPReg)
|
.addReg(SPReg)
|
||||||
|
|
|
@ -1237,9 +1237,9 @@ bool SITargetLowering::isLegalFlatAddressingMode(const AddrMode &AM) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
return AM.Scale == 0 &&
|
return AM.Scale == 0 &&
|
||||||
(AM.BaseOffs == 0 || Subtarget->getInstrInfo()->isLegalFLATOffset(
|
(AM.BaseOffs == 0 ||
|
||||||
AM.BaseOffs, AMDGPUAS::FLAT_ADDRESS,
|
Subtarget->getInstrInfo()->isLegalFLATOffset(
|
||||||
/*Signed=*/false));
|
AM.BaseOffs, AMDGPUAS::FLAT_ADDRESS, SIInstrFlags::FLAT));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SITargetLowering::isLegalGlobalAddressingMode(const AddrMode &AM) const {
|
bool SITargetLowering::isLegalGlobalAddressingMode(const AddrMode &AM) const {
|
||||||
|
@ -1247,7 +1247,7 @@ bool SITargetLowering::isLegalGlobalAddressingMode(const AddrMode &AM) const {
|
||||||
return AM.Scale == 0 &&
|
return AM.Scale == 0 &&
|
||||||
(AM.BaseOffs == 0 || Subtarget->getInstrInfo()->isLegalFLATOffset(
|
(AM.BaseOffs == 0 || Subtarget->getInstrInfo()->isLegalFLATOffset(
|
||||||
AM.BaseOffs, AMDGPUAS::GLOBAL_ADDRESS,
|
AM.BaseOffs, AMDGPUAS::GLOBAL_ADDRESS,
|
||||||
/*Signed=*/true));
|
SIInstrFlags::FlatGlobal));
|
||||||
|
|
||||||
if (!Subtarget->hasAddr64() || Subtarget->useFlatForGlobal()) {
|
if (!Subtarget->hasAddr64() || Subtarget->useFlatForGlobal()) {
|
||||||
// Assume the we will use FLAT for all global memory accesses
|
// Assume the we will use FLAT for all global memory accesses
|
||||||
|
|
|
@ -7300,25 +7300,29 @@ bool SIInstrInfo::isBufferSMRD(const MachineInstr &MI) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SIInstrInfo::isLegalFLATOffset(int64_t Offset, unsigned AddrSpace,
|
bool SIInstrInfo::isLegalFLATOffset(int64_t Offset, unsigned AddrSpace,
|
||||||
bool Signed) const {
|
uint64_t FlatVariant) const {
|
||||||
// TODO: Should 0 be special cased?
|
// TODO: Should 0 be special cased?
|
||||||
if (!ST.hasFlatInstOffsets())
|
if (!ST.hasFlatInstOffsets())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (ST.hasFlatSegmentOffsetBug() && AddrSpace == AMDGPUAS::FLAT_ADDRESS)
|
if (ST.hasFlatSegmentOffsetBug() && FlatVariant == SIInstrFlags::FLAT &&
|
||||||
|
(AddrSpace == AMDGPUAS::FLAT_ADDRESS ||
|
||||||
|
AddrSpace == AMDGPUAS::GLOBAL_ADDRESS))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
bool Signed = FlatVariant != SIInstrFlags::FLAT;
|
||||||
unsigned N = AMDGPU::getNumFlatOffsetBits(ST, Signed);
|
unsigned N = AMDGPU::getNumFlatOffsetBits(ST, Signed);
|
||||||
return Signed ? isIntN(N, Offset) : isUIntN(N, Offset);
|
return Signed ? isIntN(N, Offset) : isUIntN(N, Offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<int64_t, int64_t> SIInstrInfo::splitFlatOffset(int64_t COffsetVal,
|
std::pair<int64_t, int64_t>
|
||||||
unsigned AddrSpace,
|
SIInstrInfo::splitFlatOffset(int64_t COffsetVal, unsigned AddrSpace,
|
||||||
bool IsSigned) const {
|
uint64_t FlatVariant) const {
|
||||||
int64_t RemainderOffset = COffsetVal;
|
int64_t RemainderOffset = COffsetVal;
|
||||||
int64_t ImmField = 0;
|
int64_t ImmField = 0;
|
||||||
const unsigned NumBits = AMDGPU::getNumFlatOffsetBits(ST, IsSigned);
|
bool Signed = FlatVariant != SIInstrFlags::FLAT;
|
||||||
if (IsSigned) {
|
const unsigned NumBits = AMDGPU::getNumFlatOffsetBits(ST, Signed);
|
||||||
|
if (Signed) {
|
||||||
// Use signed division by a power of two to truncate towards 0.
|
// Use signed division by a power of two to truncate towards 0.
|
||||||
int64_t D = 1LL << (NumBits - 1);
|
int64_t D = 1LL << (NumBits - 1);
|
||||||
RemainderOffset = (COffsetVal / D) * D;
|
RemainderOffset = (COffsetVal / D) * D;
|
||||||
|
@ -7328,7 +7332,7 @@ std::pair<int64_t, int64_t> SIInstrInfo::splitFlatOffset(int64_t COffsetVal,
|
||||||
RemainderOffset = COffsetVal - ImmField;
|
RemainderOffset = COffsetVal - ImmField;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(isLegalFLATOffset(ImmField, AddrSpace, IsSigned));
|
assert(isLegalFLATOffset(ImmField, AddrSpace, FlatVariant));
|
||||||
assert(RemainderOffset + ImmField == COffsetVal);
|
assert(RemainderOffset + ImmField == COffsetVal);
|
||||||
return {ImmField, RemainderOffset};
|
return {ImmField, RemainderOffset};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1070,13 +1070,13 @@ public:
|
||||||
/// encoded instruction. If \p Signed, this is for an instruction that
|
/// encoded instruction. If \p Signed, this is for an instruction that
|
||||||
/// interprets the offset as signed.
|
/// interprets the offset as signed.
|
||||||
bool isLegalFLATOffset(int64_t Offset, unsigned AddrSpace,
|
bool isLegalFLATOffset(int64_t Offset, unsigned AddrSpace,
|
||||||
bool Signed) const;
|
uint64_t FlatVariant) const;
|
||||||
|
|
||||||
/// Split \p COffsetVal into {immediate offset field, remainder offset}
|
/// Split \p COffsetVal into {immediate offset field, remainder offset}
|
||||||
/// values.
|
/// values.
|
||||||
std::pair<int64_t, int64_t> splitFlatOffset(int64_t COffsetVal,
|
std::pair<int64_t, int64_t> splitFlatOffset(int64_t COffsetVal,
|
||||||
unsigned AddrSpace,
|
unsigned AddrSpace,
|
||||||
bool IsSigned) const;
|
uint64_t FlatVariant) const;
|
||||||
|
|
||||||
/// \brief Return a target-specific opcode if Opcode is a pseudo instruction.
|
/// \brief Return a target-specific opcode if Opcode is a pseudo instruction.
|
||||||
/// Return -1 if the target-specific opcode for the pseudo instruction does
|
/// Return -1 if the target-specific opcode for the pseudo instruction does
|
||||||
|
|
|
@ -435,7 +435,8 @@ bool SIRegisterInfo::needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const {
|
||||||
return !SIInstrInfo::isLegalMUBUFImmOffset(FullOffset);
|
return !SIInstrInfo::isLegalMUBUFImmOffset(FullOffset);
|
||||||
|
|
||||||
const SIInstrInfo *TII = ST.getInstrInfo();
|
const SIInstrInfo *TII = ST.getInstrInfo();
|
||||||
return !TII->isLegalFLATOffset(FullOffset, AMDGPUAS::PRIVATE_ADDRESS, true);
|
return !TII->isLegalFLATOffset(FullOffset, AMDGPUAS::PRIVATE_ADDRESS,
|
||||||
|
SIInstrFlags::FlatScratch);
|
||||||
}
|
}
|
||||||
|
|
||||||
Register SIRegisterInfo::materializeFrameBaseRegister(MachineBasicBlock *MBB,
|
Register SIRegisterInfo::materializeFrameBaseRegister(MachineBasicBlock *MBB,
|
||||||
|
@ -518,7 +519,8 @@ void SIRegisterInfo::resolveFrameIndex(MachineInstr &MI, Register BaseReg,
|
||||||
assert(TII->isMUBUF(MI) || TII->isFLATScratch(MI));
|
assert(TII->isMUBUF(MI) || TII->isFLATScratch(MI));
|
||||||
|
|
||||||
if (IsFlat) {
|
if (IsFlat) {
|
||||||
assert(TII->isLegalFLATOffset(NewOffset, AMDGPUAS::PRIVATE_ADDRESS, true) &&
|
assert(TII->isLegalFLATOffset(NewOffset, AMDGPUAS::PRIVATE_ADDRESS,
|
||||||
|
SIInstrFlags::FlatScratch) &&
|
||||||
"offset should be legal");
|
"offset should be legal");
|
||||||
FIOp->ChangeToRegister(BaseReg, false);
|
FIOp->ChangeToRegister(BaseReg, false);
|
||||||
OffsetOp->setImm(NewOffset);
|
OffsetOp->setImm(NewOffset);
|
||||||
|
@ -549,7 +551,8 @@ bool SIRegisterInfo::isFrameOffsetLegal(const MachineInstr *MI,
|
||||||
return SIInstrInfo::isLegalMUBUFImmOffset(NewOffset);
|
return SIInstrInfo::isLegalMUBUFImmOffset(NewOffset);
|
||||||
|
|
||||||
const SIInstrInfo *TII = ST.getInstrInfo();
|
const SIInstrInfo *TII = ST.getInstrInfo();
|
||||||
return TII->isLegalFLATOffset(NewOffset, AMDGPUAS::PRIVATE_ADDRESS, true);
|
return TII->isLegalFLATOffset(NewOffset, AMDGPUAS::PRIVATE_ADDRESS,
|
||||||
|
SIInstrFlags::FlatScratch);
|
||||||
}
|
}
|
||||||
|
|
||||||
const TargetRegisterClass *SIRegisterInfo::getPointerRegClass(
|
const TargetRegisterClass *SIRegisterInfo::getPointerRegClass(
|
||||||
|
@ -840,9 +843,10 @@ void SIRegisterInfo::buildSpillLoadStore(MachineBasicBlock::iterator MI,
|
||||||
assert((IsFlat || ((Offset % EltSize) == 0)) &&
|
assert((IsFlat || ((Offset % EltSize) == 0)) &&
|
||||||
"unexpected VGPR spill offset");
|
"unexpected VGPR spill offset");
|
||||||
|
|
||||||
bool IsOffsetLegal = IsFlat
|
bool IsOffsetLegal =
|
||||||
? TII->isLegalFLATOffset(MaxOffset, AMDGPUAS::PRIVATE_ADDRESS, true)
|
IsFlat ? TII->isLegalFLATOffset(MaxOffset, AMDGPUAS::PRIVATE_ADDRESS,
|
||||||
: SIInstrInfo::isLegalMUBUFImmOffset(MaxOffset);
|
SIInstrFlags::FlatScratch)
|
||||||
|
: SIInstrInfo::isLegalMUBUFImmOffset(MaxOffset);
|
||||||
if (!IsOffsetLegal || (IsFlat && !SOffset && !ST.hasFlatScratchSTMode())) {
|
if (!IsOffsetLegal || (IsFlat && !SOffset && !ST.hasFlatScratchSTMode())) {
|
||||||
SOffset = MCRegister();
|
SOffset = MCRegister();
|
||||||
|
|
||||||
|
@ -1522,7 +1526,7 @@ void SIRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator MI,
|
||||||
TII->getNamedOperand(*MI, AMDGPU::OpName::offset);
|
TII->getNamedOperand(*MI, AMDGPU::OpName::offset);
|
||||||
int64_t NewOffset = Offset + OffsetOp->getImm();
|
int64_t NewOffset = Offset + OffsetOp->getImm();
|
||||||
if (TII->isLegalFLATOffset(NewOffset, AMDGPUAS::PRIVATE_ADDRESS,
|
if (TII->isLegalFLATOffset(NewOffset, AMDGPUAS::PRIVATE_ADDRESS,
|
||||||
true)) {
|
SIInstrFlags::FlatScratch)) {
|
||||||
OffsetOp->setImm(NewOffset);
|
OffsetOp->setImm(NewOffset);
|
||||||
if (FrameReg)
|
if (FrameReg)
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Reference in New Issue