diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp --- a/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp @@ -1928,7 +1928,7 @@ if (!TII->isLegalFLATOffset(COffsetVal, AMDGPUAS::PRIVATE_ADDRESS, true)) { int64_t RemainderOffset = COffsetVal; int64_t ImmField = 0; - const unsigned NumBits = TII->getNumFlatOffsetBits(true); + const unsigned NumBits = AMDGPU::getNumFlatOffsetBits(*Subtarget, true); // Use signed division by a power of two to truncate towards 0. int64_t D = 1LL << (NumBits - 1); RemainderOffset = (COffsetVal / D) * D; diff --git a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp --- a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp +++ b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp @@ -3646,22 +3646,20 @@ return false; } - // Address offset is 12-bit signed for GFX10, 13-bit for GFX9. // For FLAT segment the offset must be positive; // MSB is ignored and forced to zero. - unsigned OffsetSize = isGFX9() ? 13 : 12; if (TSFlags & (SIInstrFlags::IsFlatGlobal | SIInstrFlags::IsFlatScratch)) { + unsigned OffsetSize = AMDGPU::getNumFlatOffsetBits(getSTI(), true); if (!isIntN(OffsetSize, Op.getImm())) { Error(getFlatOffsetLoc(Operands), - isGFX9() ? "expected a 13-bit signed offset" : - "expected a 12-bit signed offset"); + Twine("expected a ") + Twine(OffsetSize) + "-bit signed offset"); return false; } } else { - if (!isUIntN(OffsetSize - 1, Op.getImm())) { + unsigned OffsetSize = AMDGPU::getNumFlatOffsetBits(getSTI(), false); + if (!isUIntN(OffsetSize, Op.getImm())) { Error(getFlatOffsetLoc(Operands), - isGFX9() ? "expected a 12-bit unsigned offset" : - "expected an 11-bit unsigned offset"); + Twine("expected a ") + Twine(OffsetSize) + "-bit unsigned offset"); return false; } } diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.h b/llvm/lib/Target/AMDGPU/SIInstrInfo.h --- a/llvm/lib/Target/AMDGPU/SIInstrInfo.h +++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.h @@ -1042,8 +1042,6 @@ return isUInt<12>(Imm); } - unsigned getNumFlatOffsetBits(bool Signed) const; - /// Returns if \p Offset is legal for the subtarget as the offset to a FLAT /// encoded instruction. If \p Signed, this is for an instruction that /// interprets the offset as signed. diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp --- a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp +++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp @@ -7053,13 +7053,6 @@ return RI.getRegClass(RCID)->hasSubClassEq(&AMDGPU::SGPR_128RegClass); } -unsigned SIInstrInfo::getNumFlatOffsetBits(bool Signed) const { - if (ST.getGeneration() >= AMDGPUSubtarget::GFX10) - return Signed ? 12 : 11; - - return Signed ? 13 : 12; -} - bool SIInstrInfo::isLegalFLATOffset(int64_t Offset, unsigned AddrSpace, bool Signed) const { // TODO: Should 0 be special cased? @@ -7069,10 +7062,8 @@ if (ST.hasFlatSegmentOffsetBug() && AddrSpace == AMDGPUAS::FLAT_ADDRESS) return false; - if (ST.getGeneration() >= AMDGPUSubtarget::GFX10) - return Signed ? isInt<12>(Offset) : isUInt<11>(Offset); - - return Signed ? isInt<13>(Offset) :isUInt<12>(Offset); + unsigned N = AMDGPU::getNumFlatOffsetBits(ST, Signed); + return Signed ? isIntN(N, Offset) : isUIntN(N, Offset); } std::pair SIInstrInfo::splitFlatOffset(int64_t COffsetVal, @@ -7080,7 +7071,7 @@ bool IsSigned) const { int64_t RemainderOffset = COffsetVal; int64_t ImmField = 0; - const unsigned NumBits = getNumFlatOffsetBits(IsSigned); + const unsigned NumBits = AMDGPU::getNumFlatOffsetBits(ST, IsSigned); if (IsSigned) { // Use signed division by a power of two to truncate towards 0. int64_t D = 1LL << (NumBits - 1); diff --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h --- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h +++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h @@ -742,6 +742,13 @@ Optional getSMRDEncodedLiteralOffset32(const MCSubtargetInfo &ST, int64_t ByteOffset); +/// For FLAT segment the offset must be positive; +/// MSB is ignored and forced to zero. +/// +/// \return The number of bits available for the offset field in flat +/// instructions. +unsigned getNumFlatOffsetBits(const MCSubtargetInfo &ST, bool Signed); + /// \returns true if this offset is small enough to fit in the SMRD /// offset field. \p ByteOffset should be the offset in bytes and /// not the encoded offset. diff --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp --- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp +++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp @@ -1526,6 +1526,14 @@ return isUInt<32>(EncodedOffset) ? Optional(EncodedOffset) : None; } +unsigned getNumFlatOffsetBits(const MCSubtargetInfo &ST, bool Signed) { + // Address offset is 12-bit signed for GFX10, 13-bit for GFX9. + if (AMDGPU::isGFX10(ST)) + return Signed ? 12 : 11; + + return Signed ? 13 : 12; +} + // Given Imm, split it into the values to put into the SOffset and ImmOffset // fields in an MUBUF instruction. Return false if it is not possible (due to a // hardware bug needing a workaround). diff --git a/llvm/test/MC/AMDGPU/flat-gfx10.s b/llvm/test/MC/AMDGPU/flat-gfx10.s --- a/llvm/test/MC/AMDGPU/flat-gfx10.s +++ b/llvm/test/MC/AMDGPU/flat-gfx10.s @@ -5,13 +5,13 @@ // GFX10: encoding: [0x00,0x00,0x30,0xdc,0x03,0x00,0x7d,0x01] flat_load_dword v1, v[3:4] offset:-1 -// GFX10-ERR: :28: error: expected an 11-bit unsigned offset +// GFX10-ERR: :28: error: expected a 11-bit unsigned offset flat_load_dword v1, v[3:4] offset:2047 // GFX10: encoding: [0xff,0x07,0x30,0xdc,0x03,0x00,0x7d,0x01] flat_load_dword v1, v[3:4] offset:2048 -// GFX10-ERR: error: expected an 11-bit unsigned offset +// GFX10-ERR: error: expected a 11-bit unsigned offset flat_load_dword v1, v[3:4] offset:4 glc // GFX10: encoding: [0x04,0x00,0x31,0xdc,0x03,0x00,0x7d,0x01] diff --git a/llvm/test/MC/AMDGPU/gfx10_err_pos.s b/llvm/test/MC/AMDGPU/gfx10_err_pos.s --- a/llvm/test/MC/AMDGPU/gfx10_err_pos.s +++ b/llvm/test/MC/AMDGPU/gfx10_err_pos.s @@ -387,7 +387,7 @@ // expected an 11-bit unsigned offset flat_atomic_cmpswap v0, v[1:2], v[3:4] offset:4095 glc -// CHECK: error: expected an 11-bit unsigned offset +// CHECK: error: expected a 11-bit unsigned offset // CHECK-NEXT:{{^}}flat_atomic_cmpswap v0, v[1:2], v[3:4] offset:4095 glc // CHECK-NEXT:{{^}} ^