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

[AMDGPU] Improve FLAT scratch detection

We were useing too broad check for isFLATScratch() which also
includes FLAT global.

Differential Revision: https://reviews.llvm.org/D90505
This commit is contained in:
Stanislav Mekhanoshin 2020-11-02 10:56:12 -08:00
parent 157bbdf8a4
commit d05e59d827
6 changed files with 34 additions and 15 deletions

View File

@ -3565,7 +3565,7 @@ bool AMDGPUAsmParser::validateFlatOffset(const MCInst &Inst,
// For FLAT segment the offset must be positive;
// MSB is ignored and forced to zero.
unsigned OffsetSize = isGFX9() ? 13 : 12;
if (TSFlags & SIInstrFlags::IsNonFlatSeg) {
if (TSFlags & (SIInstrFlags::IsFlatGlobal | SIInstrFlags::IsFlatScratch)) {
if (!isIntN(OffsetSize, Op.getImm())) {
Error(getFlatOffsetLoc(Operands),
isGFX9() ? "expected a 13-bit signed offset" :

View File

@ -67,7 +67,9 @@ class FLAT_Pseudo<string opName, dag outs, dag ins,
let VM_CNT = 1;
let LGKM_CNT = !not(!or(is_flat_global, is_flat_scratch));
let IsNonFlatSeg = !or(is_flat_global, is_flat_scratch);
let IsFlatGlobal = is_flat_global;
let IsFlatScratch = is_flat_scratch;
}
class FLAT_Real <bits<7> op, FLAT_Pseudo ps> :

View File

@ -149,7 +149,8 @@ void AMDGPUInstPrinter::printFlatOffset(const MCInst *MI, unsigned OpNo,
O << " offset:";
const MCInstrDesc &Desc = MII.get(MI->getOpcode());
bool IsFlatSeg = !(Desc.TSFlags & SIInstrFlags::IsNonFlatSeg);
bool IsFlatSeg = !(Desc.TSFlags &
(SIInstrFlags::IsFlatGlobal | SIInstrFlags::IsFlatScratch));
if (IsFlatSeg) { // Unsigned offset
printU16ImmDecOperand(MI, OpNo, O);

View File

@ -89,8 +89,8 @@ enum : uint64_t {
// Is a D16 buffer instruction.
D16Buf = UINT64_C(1) << 50,
// FLAT instruction accesses FLAT_GLBL or FLAT_SCRATCH segment.
IsNonFlatSeg = UINT64_C(1) << 51,
// FLAT instruction accesses FLAT_GLBL segment.
IsFlatGlobal = UINT64_C(1) << 51,
// Uses floating point double precision rounding mode
FPDPRounding = UINT64_C(1) << 52,
@ -102,7 +102,10 @@ enum : uint64_t {
IsMAI = UINT64_C(1) << 54,
// Is a DOT instruction.
IsDOT = UINT64_C(1) << 55
IsDOT = UINT64_C(1) << 55,
// FLAT instruction accesses FLAT_SCRATCH segment.
IsFlatScratch = UINT64_C(1) << 56
};
// v_cmp_class_* etc. use a 10-bit mask for what operation is checked.

View File

@ -110,9 +110,9 @@ class InstSI <dag outs, dag ins, string asm = "",
// This bit indicates that this is a D16 buffer instruction.
field bit D16Buf = 0;
// This field indicates that FLAT instruction accesses FLAT_GLBL or
// FLAT_SCRATCH segment. Must be 0 for non-FLAT instructions.
field bit IsNonFlatSeg = 0;
// This field indicates that FLAT instruction accesses FLAT_GLBL segment.
// Must be 0 for non-FLAT instructions.
field bit IsFlatGlobal = 0;
// Reads the mode register, usually for FP environment.
field bit ReadsModeReg = 0;
@ -130,6 +130,10 @@ class InstSI <dag outs, dag ins, string asm = "",
// This bit indicates that this is one of DOT instructions.
field bit IsDOT = 0;
// This field indicates that FLAT instruction accesses FLAT_SCRATCH segment.
// Must be 0 for non-FLAT instructions.
field bit IsFlatScratch = 0;
// These need to be kept in sync with the enum in SIInstrFlags.
let TSFlags{0} = SALU;
let TSFlags{1} = VALU;
@ -187,7 +191,7 @@ class InstSI <dag outs, dag ins, string asm = "",
let TSFlags{50} = D16Buf;
let TSFlags{51} = IsNonFlatSeg;
let TSFlags{51} = IsFlatGlobal;
let TSFlags{52} = FPDPRounding;
@ -197,6 +201,8 @@ class InstSI <dag outs, dag ins, string asm = "",
let TSFlags{55} = IsDOT;
let TSFlags{56} = IsFlatScratch;
let SchedRW = [Write32Bit];
field bits<1> DisableSIDecoder = 0;

View File

@ -504,21 +504,28 @@ public:
// i.e. global_* or scratch_*.
static bool isSegmentSpecificFLAT(const MachineInstr &MI) {
auto Flags = MI.getDesc().TSFlags;
return (Flags & SIInstrFlags::FLAT) && !(Flags & SIInstrFlags::LGKM_CNT);
return Flags & (SIInstrFlags::IsFlatGlobal | SIInstrFlags::IsFlatScratch);
}
bool isSegmentSpecificFLAT(uint16_t Opcode) const {
auto Flags = get(Opcode).TSFlags;
return (Flags & SIInstrFlags::FLAT) && !(Flags & SIInstrFlags::LGKM_CNT);
return Flags & (SIInstrFlags::IsFlatGlobal | SIInstrFlags::IsFlatScratch);
}
static bool isFLATGlobal(const MachineInstr &MI) {
return MI.getDesc().TSFlags & SIInstrFlags::IsFlatGlobal;
}
bool isFLATGlobal(uint16_t Opcode) const {
return get(Opcode).TSFlags & SIInstrFlags::IsFlatGlobal;
}
// FIXME: Make this more precise
static bool isFLATScratch(const MachineInstr &MI) {
return isSegmentSpecificFLAT(MI);
return MI.getDesc().TSFlags & SIInstrFlags::IsFlatScratch;
}
bool isFLATScratch(uint16_t Opcode) const {
return isSegmentSpecificFLAT(Opcode);
return get(Opcode).TSFlags & SIInstrFlags::IsFlatScratch;
}
// Any FLAT encoded instruction, including global_* and scratch_*.