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 @@ -3565,7 +3565,7 @@ // 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" : diff --git a/llvm/lib/Target/AMDGPU/FLATInstructions.td b/llvm/lib/Target/AMDGPU/FLATInstructions.td --- a/llvm/lib/Target/AMDGPU/FLATInstructions.td +++ b/llvm/lib/Target/AMDGPU/FLATInstructions.td @@ -67,7 +67,9 @@ 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 op, FLAT_Pseudo ps> : diff --git a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp --- a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp +++ b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp @@ -149,7 +149,8 @@ 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); diff --git a/llvm/lib/Target/AMDGPU/SIDefines.h b/llvm/lib/Target/AMDGPU/SIDefines.h --- a/llvm/lib/Target/AMDGPU/SIDefines.h +++ b/llvm/lib/Target/AMDGPU/SIDefines.h @@ -89,8 +89,8 @@ // 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 @@ 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. diff --git a/llvm/lib/Target/AMDGPU/SIInstrFormats.td b/llvm/lib/Target/AMDGPU/SIInstrFormats.td --- a/llvm/lib/Target/AMDGPU/SIInstrFormats.td +++ b/llvm/lib/Target/AMDGPU/SIInstrFormats.td @@ -110,9 +110,9 @@ // 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 @@ // 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 @@ let TSFlags{50} = D16Buf; - let TSFlags{51} = IsNonFlatSeg; + let TSFlags{51} = IsFlatGlobal; let TSFlags{52} = FPDPRounding; @@ -197,6 +201,8 @@ let TSFlags{55} = IsDOT; + let TSFlags{56} = IsFlatScratch; + let SchedRW = [Write32Bit]; field bits<1> DisableSIDecoder = 0; 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 @@ -504,21 +504,28 @@ // 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_*.