1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 11:13:28 +01:00

AMDGPU: Factor out large flat offset splitting

This commit is contained in:
Matt Arsenault 2020-11-12 10:59:15 -05:00
parent 79a7d81750
commit b3aa28b9d4
3 changed files with 29 additions and 15 deletions

View File

@ -1742,22 +1742,10 @@ bool AMDGPUDAGToDAGISel::SelectFlatOffset(SDNode *N,
// into two pieces that are both >= 0 or both <= 0. // into two pieces that are both >= 0 or both <= 0.
SDLoc DL(N); SDLoc DL(N);
uint64_t RemainderOffset = COffsetVal; uint64_t RemainderOffset;
uint64_t ImmField = 0;
const unsigned NumBits = TII->getNumFlatOffsetBits(IsSigned);
if (IsSigned) {
// Use signed division by a power of two to truncate towards 0.
int64_t D = 1LL << (NumBits - 1);
RemainderOffset = (static_cast<int64_t>(COffsetVal) / D) * D;
ImmField = COffsetVal - RemainderOffset;
} else if (static_cast<int64_t>(COffsetVal) >= 0) {
ImmField = COffsetVal & maskTrailingOnes<uint64_t>(NumBits);
RemainderOffset = COffsetVal - ImmField;
}
assert(TII->isLegalFLATOffset(ImmField, AS, IsSigned));
assert(RemainderOffset + ImmField == COffsetVal);
OffsetVal = ImmField; std::tie(OffsetVal, RemainderOffset)
= TII->splitFlatOffset(COffsetVal, AS, IsSigned);
SDValue AddOffsetLo = SDValue AddOffsetLo =
getMaterializedScalarImm32(Lo_32(RemainderOffset), DL); getMaterializedScalarImm32(Lo_32(RemainderOffset), DL);

View File

@ -6959,6 +6959,26 @@ bool SIInstrInfo::isLegalFLATOffset(int64_t Offset, unsigned AddrSpace,
return Signed ? isInt<13>(Offset) :isUInt<12>(Offset); return Signed ? isInt<13>(Offset) :isUInt<12>(Offset);
} }
std::pair<int64_t, int64_t> SIInstrInfo::splitFlatOffset(int64_t COffsetVal,
unsigned AddrSpace,
bool IsSigned) const {
int64_t RemainderOffset = COffsetVal;
int64_t ImmField = 0;
const unsigned NumBits = getNumFlatOffsetBits(IsSigned);
if (IsSigned) {
// Use signed division by a power of two to truncate towards 0.
int64_t D = 1LL << (NumBits - 1);
RemainderOffset = (COffsetVal / D) * D;
ImmField = COffsetVal - RemainderOffset;
} else if (COffsetVal >= 0) {
ImmField = COffsetVal & maskTrailingOnes<uint64_t>(NumBits);
RemainderOffset = COffsetVal - ImmField;
}
assert(isLegalFLATOffset(ImmField, AddrSpace, IsSigned));
assert(RemainderOffset + ImmField == COffsetVal);
return {ImmField, RemainderOffset};
}
// This must be kept in sync with the SIEncodingFamily class in SIInstrInfo.td // This must be kept in sync with the SIEncodingFamily class in SIInstrInfo.td
enum SIEncodingFamily { enum SIEncodingFamily {

View File

@ -1039,6 +1039,12 @@ public:
bool isLegalFLATOffset(int64_t Offset, unsigned AddrSpace, bool isLegalFLATOffset(int64_t Offset, unsigned AddrSpace,
bool Signed) const; bool Signed) const;
/// Split \p COffsetVal into {immediate offset field, remainder offset}
/// values.
std::pair<int64_t, int64_t> splitFlatOffset(int64_t COffsetVal,
unsigned AddrSpace,
bool IsSigned) 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
/// not exist. If Opcode is not a pseudo instruction, this is identity. /// not exist. If Opcode is not a pseudo instruction, this is identity.