From: Matt Arsenault Date: Thu, 12 Nov 2020 15:59:15 +0000 (-0500) Subject: AMDGPU: Factor out large flat offset splitting X-Git-Tag: llvmorg-13-init~6151 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e722943e05a16901eb336fc4a3e954b541211383;p=platform%2Fupstream%2Fllvm.git AMDGPU: Factor out large flat offset splitting --- diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp index 0f2aa56..33c5430 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp @@ -1742,22 +1742,10 @@ bool AMDGPUDAGToDAGISel::SelectFlatOffset(SDNode *N, // into two pieces that are both >= 0 or both <= 0. SDLoc DL(N); - uint64_t RemainderOffset = COffsetVal; - 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(COffsetVal) / D) * D; - ImmField = COffsetVal - RemainderOffset; - } else if (static_cast(COffsetVal) >= 0) { - ImmField = COffsetVal & maskTrailingOnes(NumBits); - RemainderOffset = COffsetVal - ImmField; - } - assert(TII->isLegalFLATOffset(ImmField, AS, IsSigned)); - assert(RemainderOffset + ImmField == COffsetVal); + uint64_t RemainderOffset; - OffsetVal = ImmField; + std::tie(OffsetVal, RemainderOffset) + = TII->splitFlatOffset(COffsetVal, AS, IsSigned); SDValue AddOffsetLo = getMaterializedScalarImm32(Lo_32(RemainderOffset), DL); diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp index 20c6c47..f2b54e6 100644 --- a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp +++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp @@ -6959,6 +6959,26 @@ bool SIInstrInfo::isLegalFLATOffset(int64_t Offset, unsigned AddrSpace, return Signed ? isInt<13>(Offset) :isUInt<12>(Offset); } +std::pair 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(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 enum SIEncodingFamily { diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.h b/llvm/lib/Target/AMDGPU/SIInstrInfo.h index 82e7e81..0ff8a13 100644 --- a/llvm/lib/Target/AMDGPU/SIInstrInfo.h +++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.h @@ -1039,6 +1039,12 @@ public: bool isLegalFLATOffset(int64_t Offset, unsigned AddrSpace, bool Signed) const; + /// Split \p COffsetVal into {immediate offset field, remainder offset} + /// values. + std::pair splitFlatOffset(int64_t COffsetVal, + unsigned AddrSpace, + bool IsSigned) const; + /// \brief Return a target-specific opcode if Opcode is a pseudo instruction. /// Return -1 if the target-specific opcode for the pseudo instruction does /// not exist. If Opcode is not a pseudo instruction, this is identity.