diff --git a/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp b/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp index 2ad7fab8142..0a0b993778c 100644 --- a/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp +++ b/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp @@ -1928,7 +1928,7 @@ bool AMDGPUDAGToDAGISel::SelectScratchSAddr(SDNode *N, 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/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp b/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp index 22c32400ecb..1fd6c2cca6d 100644 --- a/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp +++ b/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp @@ -3646,22 +3646,20 @@ bool AMDGPUAsmParser::validateFlatOffset(const MCInst &Inst, 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/lib/Target/AMDGPU/SIInstrInfo.cpp b/lib/Target/AMDGPU/SIInstrInfo.cpp index 01721595d55..889908bce90 100644 --- a/lib/Target/AMDGPU/SIInstrInfo.cpp +++ b/lib/Target/AMDGPU/SIInstrInfo.cpp @@ -7053,13 +7053,6 @@ bool SIInstrInfo::isBufferSMRD(const MachineInstr &MI) const { 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 @@ bool SIInstrInfo::isLegalFLATOffset(int64_t Offset, unsigned AddrSpace, 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 @@ std::pair SIInstrInfo::splitFlatOffset(int64_t COffsetVal, 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/lib/Target/AMDGPU/SIInstrInfo.h b/lib/Target/AMDGPU/SIInstrInfo.h index 39b512a967e..4625cefa1e3 100644 --- a/lib/Target/AMDGPU/SIInstrInfo.h +++ b/lib/Target/AMDGPU/SIInstrInfo.h @@ -1042,8 +1042,6 @@ public: 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/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp b/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp index b5a0d43645d..c0c5c683c1f 100644 --- a/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp +++ b/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp @@ -1526,6 +1526,14 @@ Optional getSMRDEncodedLiteralOffset32(const MCSubtargetInfo &ST, 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/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h b/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h index 297ed3e2200..c65acfc558e 100644 --- a/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h +++ b/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h @@ -742,6 +742,13 @@ Optional getSMRDEncodedOffset(const MCSubtargetInfo &ST, 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/test/MC/AMDGPU/flat-gfx10.s b/test/MC/AMDGPU/flat-gfx10.s index b8975cdaf3c..97ab93d5a98 100644 --- a/test/MC/AMDGPU/flat-gfx10.s +++ b/test/MC/AMDGPU/flat-gfx10.s @@ -5,13 +5,13 @@ flat_load_dword v1, v[3:4] // 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/test/MC/AMDGPU/gfx10_err_pos.s b/test/MC/AMDGPU/gfx10_err_pos.s index 1d4e52d6c64..013dba64100 100644 --- a/test/MC/AMDGPU/gfx10_err_pos.s +++ b/test/MC/AMDGPU/gfx10_err_pos.s @@ -387,7 +387,7 @@ ds_swizzle_b32 v8, v2 offset:SWZ(QUAD_PERM, 0, 1, 2, 3) // 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:{{^}} ^