Loading llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp +3 −15 Original line number Diff line number Diff line Loading @@ -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<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); uint64_t RemainderOffset; OffsetVal = ImmField; std::tie(OffsetVal, RemainderOffset) = TII->splitFlatOffset(COffsetVal, AS, IsSigned); SDValue AddOffsetLo = getMaterializedScalarImm32(Lo_32(RemainderOffset), DL); Loading llvm/lib/Target/AMDGPU/SIInstrInfo.cpp +20 −0 Original line number Diff line number Diff line Loading @@ -6959,6 +6959,26 @@ bool SIInstrInfo::isLegalFLATOffset(int64_t Offset, unsigned AddrSpace, 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 enum SIEncodingFamily { Loading llvm/lib/Target/AMDGPU/SIInstrInfo.h +6 −0 Original line number Diff line number Diff line Loading @@ -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<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. /// Return -1 if the target-specific opcode for the pseudo instruction does /// not exist. If Opcode is not a pseudo instruction, this is identity. Loading Loading
llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp +3 −15 Original line number Diff line number Diff line Loading @@ -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<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); uint64_t RemainderOffset; OffsetVal = ImmField; std::tie(OffsetVal, RemainderOffset) = TII->splitFlatOffset(COffsetVal, AS, IsSigned); SDValue AddOffsetLo = getMaterializedScalarImm32(Lo_32(RemainderOffset), DL); Loading
llvm/lib/Target/AMDGPU/SIInstrInfo.cpp +20 −0 Original line number Diff line number Diff line Loading @@ -6959,6 +6959,26 @@ bool SIInstrInfo::isLegalFLATOffset(int64_t Offset, unsigned AddrSpace, 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 enum SIEncodingFamily { Loading
llvm/lib/Target/AMDGPU/SIInstrInfo.h +6 −0 Original line number Diff line number Diff line Loading @@ -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<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. /// Return -1 if the target-specific opcode for the pseudo instruction does /// not exist. If Opcode is not a pseudo instruction, this is identity. Loading