diff options
| author | Matt Arsenault <Matthew.Arsenault@amd.com> | 2019-03-14 22:54:43 +0000 |
|---|---|---|
| committer | Matt Arsenault <Matthew.Arsenault@amd.com> | 2019-03-14 22:54:43 +0000 |
| commit | bc6d07ca46d7e77f3602281a0d0b89ac818ef40d (patch) | |
| tree | 4d4c5d1cf6686a738b24c4811b24d598c0a3b96b | |
| parent | 7d6784f5225b19867eb7702e4ff9b3c3b06dfb7b (diff) | |
| download | bcm5719-llvm-bc6d07ca46d7e77f3602281a0d0b89ac818ef40d.tar.gz bcm5719-llvm-bc6d07ca46d7e77f3602281a0d0b89ac818ef40d.zip | |
MIR: Allow targets to serialize MachineFunctionInfo
This has been a very painful missing feature that has made producing
reduced testcases difficult. In particular the various registers
determined for stack access during function lowering were necessary to
avoid undefined register errors in a large percentage of
cases. Implement a subset of the important fields that need to be
preserved for AMDGPU.
Most of the changes are to support targets parsing register fields and
properly reporting errors. The biggest sort-of bug remaining is for
fields that can be initialized from the IR section will be overwritten
by a default initialized machineFunctionInfo section. Another
remaining bug is the machineFunctionInfo section is still printed even
if empty.
llvm-svn: 356215
31 files changed, 665 insertions, 12 deletions
diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.h b/llvm/include/llvm/CodeGen/MIRParser/MIParser.h index dc858a95681..4e32a04551c 100644 --- a/llvm/lib/CodeGen/MIRParser/MIParser.h +++ b/llvm/include/llvm/CodeGen/MIRParser/MIParser.h @@ -164,8 +164,8 @@ struct PerFunctionMIParsingState { PerTargetMIParsingState &Target; DenseMap<unsigned, MachineBasicBlock *> MBBSlots; - DenseMap<unsigned, VRegInfo*> VRegInfos; - StringMap<VRegInfo*> VRegInfosNamed; + DenseMap<unsigned, VRegInfo *> VRegInfos; + StringMap<VRegInfo *> VRegInfosNamed; DenseMap<unsigned, int> FixedStackObjectSlots; DenseMap<unsigned, int> StackObjectSlots; DenseMap<unsigned, unsigned> ConstantPoolSlots; diff --git a/llvm/include/llvm/CodeGen/MIRYamlMapping.h b/llvm/include/llvm/CodeGen/MIRYamlMapping.h index a0f2b16745f..13f572f9bb5 100644 --- a/llvm/include/llvm/CodeGen/MIRYamlMapping.h +++ b/llvm/include/llvm/CodeGen/MIRYamlMapping.h @@ -36,6 +36,7 @@ struct StringValue { StringValue() = default; StringValue(std::string Value) : Value(std::move(Value)) {} + StringValue(const char Val[]) : Value(Val) {} bool operator==(const StringValue &Other) const { return Value == Other.Value; @@ -482,6 +483,20 @@ template <> struct MappingTraits<MachineFrameInfo> { } }; +/// Targets should override this in a way that mirrors the implementation of +/// llvm::MachineFunctionInfo. +struct MachineFunctionInfo { + virtual ~MachineFunctionInfo() {} + virtual void mappingImpl(IO &YamlIO) {} +}; + +template <> struct MappingTraits<std::unique_ptr<MachineFunctionInfo>> { + static void mapping(IO &YamlIO, std::unique_ptr<MachineFunctionInfo> &MFI) { + if (MFI) + MFI->mappingImpl(YamlIO); + } +}; + struct MachineFunction { StringRef Name; unsigned Alignment = 0; @@ -503,6 +518,7 @@ struct MachineFunction { std::vector<FixedMachineStackObject> FixedStackObjects; std::vector<MachineStackObject> StackObjects; std::vector<MachineConstantPoolValue> Constants; /// Constant pool. + std::unique_ptr<MachineFunctionInfo> MachineFuncInfo; MachineJumpTable JumpTableInfo; BlockStringValue Body; }; @@ -531,6 +547,7 @@ template <> struct MappingTraits<MachineFunction> { std::vector<MachineStackObject>()); YamlIO.mapOptional("constants", MF.Constants, std::vector<MachineConstantPoolValue>()); + YamlIO.mapOptional("machineFunctionInfo", MF.MachineFuncInfo); if (!YamlIO.outputting() || !MF.JumpTableInfo.Entries.empty()) YamlIO.mapOptional("jumpTable", MF.JumpTableInfo, MachineJumpTable()); YamlIO.mapOptional("body", MF.Body, BlockStringValue()); diff --git a/llvm/include/llvm/CodeGen/MachineModuleInfo.h b/llvm/include/llvm/CodeGen/MachineModuleInfo.h index 9b81dc6a45e..4ff5c7fd013 100644 --- a/llvm/include/llvm/CodeGen/MachineModuleInfo.h +++ b/llvm/include/llvm/CodeGen/MachineModuleInfo.h @@ -150,6 +150,8 @@ public: bool doInitialization(Module &) override; bool doFinalization(Module &) override; + const LLVMTargetMachine &getTarget() const { return TM; } + const MCContext &getContext() const { return Context; } MCContext &getContext() { return Context; } diff --git a/llvm/include/llvm/Target/TargetMachine.h b/llvm/include/llvm/Target/TargetMachine.h index 7dd9b99b682..f289c653e54 100644 --- a/llvm/include/llvm/Target/TargetMachine.h +++ b/llvm/include/llvm/Target/TargetMachine.h @@ -35,6 +35,9 @@ class MCSubtargetInfo; class MCSymbol; class raw_pwrite_stream; class PassManagerBuilder; +struct PerFunctionMIParsingState; +class SMDiagnostic; +class SMRange; class Target; class TargetIntrinsicInfo; class TargetIRAnalysis; @@ -49,6 +52,10 @@ class PassManagerBase; } using legacy::PassManagerBase; +namespace yaml { +struct MachineFunctionInfo; +} + //===----------------------------------------------------------------------===// /// /// Primary interface to the complete machine description for the target @@ -114,6 +121,27 @@ public: return nullptr; } + /// Allocate and return a default initialized instance of the YAML + /// representation for the MachineFunctionInfo. + virtual yaml::MachineFunctionInfo *createDefaultFuncInfoYAML() const { + return nullptr; + } + + /// Allocate and initialize an instance of the YAML representation of the + /// MachineFunctionInfo. + virtual yaml::MachineFunctionInfo * + convertFuncInfoToYAML(const MachineFunction &MF) const { + return nullptr; + } + + /// Parse out the target's MachineFunctionInfo from the YAML reprsentation. + virtual bool parseMachineFunctionInfo(const yaml::MachineFunctionInfo &, + PerFunctionMIParsingState &PFS, + SMDiagnostic &Error, + SMRange &SourceRange) const { + return false; + } + /// This method returns a pointer to the specified type of /// TargetSubtargetInfo. In debug builds, it verifies that the object being /// returned is of the correct type. diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.cpp b/llvm/lib/CodeGen/MIRParser/MIParser.cpp index 593ec57e7ee..971944be2f9 100644 --- a/llvm/lib/CodeGen/MIRParser/MIParser.cpp +++ b/llvm/lib/CodeGen/MIRParser/MIParser.cpp @@ -10,7 +10,7 @@ // //===----------------------------------------------------------------------===// -#include "MIParser.h" +#include "llvm/CodeGen/MIRParser/MIParser.h" #include "MILexer.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/APSInt.h" diff --git a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp index 7a4eb45fb1e..3598cbe22ce 100644 --- a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp +++ b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp @@ -12,7 +12,6 @@ //===----------------------------------------------------------------------===// #include "llvm/CodeGen/MIRParser/MIRParser.h" -#include "MIParser.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringMap.h" @@ -21,6 +20,7 @@ #include "llvm/AsmParser/SlotMapping.h" #include "llvm/CodeGen/GlobalISel/RegisterBank.h" #include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h" +#include "llvm/CodeGen/MIRParser/MIParser.h" #include "llvm/CodeGen/MIRYamlMapping.h" #include "llvm/CodeGen/MachineConstantPool.h" #include "llvm/CodeGen/MachineFrameInfo.h" @@ -39,6 +39,7 @@ #include "llvm/Support/SMLoc.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/YAMLTraits.h" +#include "llvm/Target/TargetMachine.h" #include <memory> using namespace llvm; @@ -266,6 +267,11 @@ bool MIRParserImpl::parseMachineFunction(Module &M, MachineModuleInfo &MMI) { // Parse the yaml. yaml::MachineFunction YamlMF; yaml::EmptyContext Ctx; + + const LLVMTargetMachine &TM = MMI.getTarget(); + YamlMF.MachineFuncInfo = std::unique_ptr<yaml::MachineFunctionInfo>( + TM.createDefaultFuncInfoYAML()); + yaml::yamlize(In, YamlMF, false, Ctx); if (In.error()) return true; @@ -407,6 +413,19 @@ MIRParserImpl::initializeMachineFunction(const yaml::MachineFunction &YamlMF, if (setupRegisterInfo(PFS, YamlMF)) return true; + if (YamlMF.MachineFuncInfo) { + const LLVMTargetMachine &TM = MF.getTarget(); + // Note this is called after the initial constructor of the + // MachineFunctionInfo based on the MachineFunction, which may depend on the + // IR. + + SMRange SrcRange; + if (TM.parseMachineFunctionInfo(*YamlMF.MachineFuncInfo, PFS, Error, + SrcRange)) { + return error(Error, SrcRange); + } + } + computeFunctionProperties(MF); MF.getSubtarget().mirFileLoaded(MF); diff --git a/llvm/lib/CodeGen/MIRPrinter.cpp b/llvm/lib/CodeGen/MIRPrinter.cpp index 5977ba467ac..86e3f53608c 100644 --- a/llvm/lib/CodeGen/MIRPrinter.cpp +++ b/llvm/lib/CodeGen/MIRPrinter.cpp @@ -215,6 +215,11 @@ void MIRPrinter::print(const MachineFunction &MF) { convert(YamlMF, *ConstantPool); if (const auto *JumpTableInfo = MF.getJumpTableInfo()) convert(MST, YamlMF.JumpTableInfo, *JumpTableInfo); + + const TargetMachine &TM = MF.getTarget(); + YamlMF.MachineFuncInfo = + std::unique_ptr<yaml::MachineFunctionInfo>(TM.convertFuncInfoToYAML(MF)); + raw_string_ostream StrOS(YamlMF.Body.Value.Value); bool IsNewlineNeeded = false; for (const auto &MBB : MF) { diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp index dd763903397..23ba6ce9334 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp @@ -24,11 +24,13 @@ #include "GCNIterativeScheduler.h" #include "GCNSchedStrategy.h" #include "R600MachineScheduler.h" +#include "SIMachineFunctionInfo.h" #include "SIMachineScheduler.h" #include "llvm/CodeGen/GlobalISel/IRTranslator.h" #include "llvm/CodeGen/GlobalISel/InstructionSelect.h" #include "llvm/CodeGen/GlobalISel/Legalizer.h" #include "llvm/CodeGen/GlobalISel/RegBankSelect.h" +#include "llvm/CodeGen/MIRParser/MIParser.h" #include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/TargetPassConfig.h" #include "llvm/IR/Attributes.h" @@ -930,3 +932,74 @@ void GCNPassConfig::addPreEmitPass() { TargetPassConfig *GCNTargetMachine::createPassConfig(PassManagerBase &PM) { return new GCNPassConfig(*this, PM); } + +yaml::MachineFunctionInfo *GCNTargetMachine::createDefaultFuncInfoYAML() const { + return new yaml::SIMachineFunctionInfo(); +} + +yaml::MachineFunctionInfo * +GCNTargetMachine::convertFuncInfoToYAML(const MachineFunction &MF) const { + const SIMachineFunctionInfo *MFI = MF.getInfo<SIMachineFunctionInfo>(); + return new yaml::SIMachineFunctionInfo(*MFI, + *MF.getSubtarget().getRegisterInfo()); +} + +bool GCNTargetMachine::parseMachineFunctionInfo( + const yaml::MachineFunctionInfo &MFI_, PerFunctionMIParsingState &PFS, + SMDiagnostic &Error, SMRange &SourceRange) const { + const yaml::SIMachineFunctionInfo &YamlMFI = + reinterpret_cast<const yaml::SIMachineFunctionInfo &>(MFI_); + MachineFunction &MF = PFS.MF; + SIMachineFunctionInfo *MFI = MF.getInfo<SIMachineFunctionInfo>(); + + MFI->initializeBaseYamlFields(YamlMFI); + + auto parseRegister = [&](const yaml::StringValue &RegName, unsigned &RegVal) { + if (parseNamedRegisterReference(PFS, RegVal, RegName.Value, Error)) { + SourceRange = RegName.SourceRange; + return true; + } + + return false; + }; + + auto diagnoseRegisterClass = [&](const yaml::StringValue &RegName) { + // Create a diagnostic for a the register string literal. + const MemoryBuffer &Buffer = + *PFS.SM->getMemoryBuffer(PFS.SM->getMainFileID()); + Error = SMDiagnostic(*PFS.SM, SMLoc(), Buffer.getBufferIdentifier(), 1, + RegName.Value.size(), SourceMgr::DK_Error, + "incorrect register class for field", RegName.Value, + None, None); + SourceRange = RegName.SourceRange; + return true; + }; + + if (parseRegister(YamlMFI.ScratchRSrcReg, MFI->ScratchRSrcReg) || + parseRegister(YamlMFI.ScratchWaveOffsetReg, MFI->ScratchWaveOffsetReg) || + parseRegister(YamlMFI.FrameOffsetReg, MFI->FrameOffsetReg) || + parseRegister(YamlMFI.StackPtrOffsetReg, MFI->StackPtrOffsetReg)) + return true; + + if (MFI->ScratchRSrcReg != AMDGPU::PRIVATE_RSRC_REG && + !AMDGPU::SReg_128RegClass.contains(MFI->ScratchRSrcReg)) { + return diagnoseRegisterClass(YamlMFI.ScratchRSrcReg); + } + + if (MFI->ScratchWaveOffsetReg != AMDGPU::SCRATCH_WAVE_OFFSET_REG && + !AMDGPU::SGPR_32RegClass.contains(MFI->ScratchWaveOffsetReg)) { + return diagnoseRegisterClass(YamlMFI.ScratchWaveOffsetReg); + } + + if (MFI->FrameOffsetReg != AMDGPU::FP_REG && + !AMDGPU::SGPR_32RegClass.contains(MFI->FrameOffsetReg)) { + return diagnoseRegisterClass(YamlMFI.FrameOffsetReg); + } + + if (MFI->StackPtrOffsetReg != AMDGPU::SP_REG && + !AMDGPU::SGPR_32RegClass.contains(MFI->StackPtrOffsetReg)) { + return diagnoseRegisterClass(YamlMFI.StackPtrOffsetReg); + } + + return false; +} diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.h b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.h index b8805f08bc0..70fa3961236 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.h +++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.h @@ -110,6 +110,14 @@ public: bool useIPRA() const override { return true; } + + yaml::MachineFunctionInfo *createDefaultFuncInfoYAML() const override; + yaml::MachineFunctionInfo * + convertFuncInfoToYAML(const MachineFunction &MF) const override; + bool parseMachineFunctionInfo(const yaml::MachineFunctionInfo &, + PerFunctionMIParsingState &PFS, + SMDiagnostic &Error, + SMRange &SourceRange) const override; }; } // end namespace llvm diff --git a/llvm/lib/Target/AMDGPU/LLVMBuild.txt b/llvm/lib/Target/AMDGPU/LLVMBuild.txt index 2f661af14f9..e18085d0ae5 100644 --- a/llvm/lib/Target/AMDGPU/LLVMBuild.txt +++ b/llvm/lib/Target/AMDGPU/LLVMBuild.txt @@ -29,5 +29,5 @@ has_disassembler = 1 type = Library name = AMDGPUCodeGen parent = AMDGPU -required_libraries = Analysis AsmPrinter CodeGen Core IPO MC AMDGPUAsmPrinter AMDGPUDesc AMDGPUInfo AMDGPUUtils Scalar SelectionDAG Support Target TransformUtils Vectorize GlobalISel BinaryFormat +required_libraries = Analysis AsmPrinter CodeGen Core IPO MC AMDGPUAsmPrinter AMDGPUDesc AMDGPUInfo AMDGPUUtils Scalar SelectionDAG Support Target TransformUtils Vectorize GlobalISel BinaryFormat MIRParser add_to_library_groups = AMDGPU diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp index 9205c20cefc..f6253317073 100644 --- a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp +++ b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp @@ -9607,13 +9607,22 @@ void SITargetLowering::finalizeLowering(MachineFunction &MF) const { assert(Info->getStackPtrOffsetReg() != Info->getFrameOffsetReg()); assert(!TRI->isSubRegister(Info->getScratchRSrcReg(), Info->getStackPtrOffsetReg())); - MRI.replaceRegWith(AMDGPU::SP_REG, Info->getStackPtrOffsetReg()); + if (Info->getStackPtrOffsetReg() != AMDGPU::SP_REG) + MRI.replaceRegWith(AMDGPU::SP_REG, Info->getStackPtrOffsetReg()); } - MRI.replaceRegWith(AMDGPU::PRIVATE_RSRC_REG, Info->getScratchRSrcReg()); - MRI.replaceRegWith(AMDGPU::FP_REG, Info->getFrameOffsetReg()); - MRI.replaceRegWith(AMDGPU::SCRATCH_WAVE_OFFSET_REG, - Info->getScratchWaveOffsetReg()); + // We need to worry about replacing the default register with itself in case + // of MIR testcases missing the MFI. + if (Info->getScratchRSrcReg() != AMDGPU::PRIVATE_RSRC_REG) + MRI.replaceRegWith(AMDGPU::PRIVATE_RSRC_REG, Info->getScratchRSrcReg()); + + if (Info->getFrameOffsetReg() != AMDGPU::FP_REG) + MRI.replaceRegWith(AMDGPU::FP_REG, Info->getFrameOffsetReg()); + + if (Info->getScratchWaveOffsetReg() != AMDGPU::SCRATCH_WAVE_OFFSET_REG) { + MRI.replaceRegWith(AMDGPU::SCRATCH_WAVE_OFFSET_REG, + Info->getScratchWaveOffsetReg()); + } Info->limitOccupancy(MF); diff --git a/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp b/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp index 78e88abda68..834f651c42d 100644 --- a/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp +++ b/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp @@ -319,3 +319,42 @@ MCPhysReg SIMachineFunctionInfo::getNextUserSGPR() const { MCPhysReg SIMachineFunctionInfo::getNextSystemSGPR() const { return AMDGPU::SGPR0 + NumUserSGPRs + NumSystemSGPRs; } + +static yaml::StringValue regToString(unsigned Reg, + const TargetRegisterInfo &TRI) { + yaml::StringValue Dest; + raw_string_ostream OS(Dest.Value); + OS << printReg(Reg, &TRI); + return Dest; +} + +yaml::SIMachineFunctionInfo::SIMachineFunctionInfo( + const llvm::SIMachineFunctionInfo& MFI, + const TargetRegisterInfo &TRI) + : ExplicitKernArgSize(MFI.getExplicitKernArgSize()), + MaxKernArgAlign(MFI.getMaxKernArgAlign()), + LDSSize(MFI.getLDSSize()), + IsEntryFunction(MFI.isEntryFunction()), + NoSignedZerosFPMath(MFI.hasNoSignedZerosFPMath()), + MemoryBound(MFI.isMemoryBound()), + WaveLimiter(MFI.needsWaveLimiter()), + ScratchRSrcReg(regToString(MFI.getScratchRSrcReg(), TRI)), + ScratchWaveOffsetReg(regToString(MFI.getScratchWaveOffsetReg(), TRI)), + FrameOffsetReg(regToString(MFI.getFrameOffsetReg(), TRI)), + StackPtrOffsetReg(regToString(MFI.getStackPtrOffsetReg(), TRI)) {} + +void yaml::SIMachineFunctionInfo::mappingImpl(yaml::IO &YamlIO) { + MappingTraits<SIMachineFunctionInfo>::mapping(YamlIO, *this); +} + +bool SIMachineFunctionInfo::initializeBaseYamlFields( + const yaml::SIMachineFunctionInfo &YamlMFI) { + ExplicitKernArgSize = YamlMFI.ExplicitKernArgSize; + MaxKernArgAlign = YamlMFI.MaxKernArgAlign; + LDSSize = YamlMFI.LDSSize; + IsEntryFunction = YamlMFI.IsEntryFunction; + NoSignedZerosFPMath = YamlMFI.NoSignedZerosFPMath; + MemoryBound = YamlMFI.MemoryBound; + WaveLimiter = YamlMFI.WaveLimiter; + return false; +} diff --git a/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h b/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h index de84fbbd776..ce103dcc31b 100644 --- a/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h +++ b/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h @@ -15,13 +15,14 @@ #include "AMDGPUArgumentUsageInfo.h" #include "AMDGPUMachineFunction.h" +#include "MCTargetDesc/AMDGPUMCTargetDesc.h" #include "SIInstrInfo.h" #include "SIRegisterInfo.h" -#include "MCTargetDesc/AMDGPUMCTargetDesc.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/CodeGen/MIRYamlMapping.h" #include "llvm/CodeGen/PseudoSourceValue.h" #include "llvm/CodeGen/TargetInstrInfo.h" #include "llvm/MC/MCRegisterInfo.h" @@ -78,9 +79,58 @@ public: } }; +namespace yaml { + +struct SIMachineFunctionInfo final : public yaml::MachineFunctionInfo { + uint64_t ExplicitKernArgSize = 0; + unsigned MaxKernArgAlign = 0; + unsigned LDSSize = 0; + bool IsEntryFunction = false; + bool NoSignedZerosFPMath = false; + bool MemoryBound = false; + bool WaveLimiter = false; + + StringValue ScratchRSrcReg = "$private_rsrc_reg"; + StringValue ScratchWaveOffsetReg = "$scratch_wave_offset_reg"; + StringValue FrameOffsetReg = "$fp_reg"; + StringValue StackPtrOffsetReg = "$sp_reg"; + + SIMachineFunctionInfo() = default; + SIMachineFunctionInfo(const llvm::SIMachineFunctionInfo &, + const TargetRegisterInfo &TRI); + + void mappingImpl(yaml::IO &YamlIO) override; + ~SIMachineFunctionInfo() = default; +}; + +template <> struct MappingTraits<SIMachineFunctionInfo> { + static void mapping(IO &YamlIO, SIMachineFunctionInfo &MFI) { + YamlIO.mapOptional("explicitKernArgSize", MFI.ExplicitKernArgSize, + UINT64_C(0)); + YamlIO.mapOptional("maxKernArgAlign", MFI.MaxKernArgAlign, 0u); + YamlIO.mapOptional("ldsSize", MFI.LDSSize, 0u); + YamlIO.mapOptional("isEntryFunction", MFI.IsEntryFunction, false); + YamlIO.mapOptional("noSignedZerosFPMath", MFI.NoSignedZerosFPMath, false); + YamlIO.mapOptional("memoryBound", MFI.MemoryBound, false); + YamlIO.mapOptional("waveLimiter", MFI.WaveLimiter, false); + YamlIO.mapOptional("scratchRSrcReg", MFI.ScratchRSrcReg, + StringValue("$private_rsrc_reg")); + YamlIO.mapOptional("scratchWaveOffsetReg", MFI.ScratchWaveOffsetReg, + StringValue("$scratch_wave_offset_reg")); + YamlIO.mapOptional("frameOffsetReg", MFI.FrameOffsetReg, + StringValue("$fp_reg")); + YamlIO.mapOptional("stackPtrOffsetReg", MFI.StackPtrOffsetReg, + StringValue("$sp_reg")); + } +}; + +} // end namespace yaml + /// This class keeps track of the SPI_SP_INPUT_ADDR config register, which /// tells the hardware which interpolation parameters to load. class SIMachineFunctionInfo final : public AMDGPUMachineFunction { + friend class GCNTargetMachine; + unsigned TIDReg = AMDGPU::NoRegister; // Registers that may be reserved for spilling purposes. These may be the same @@ -219,6 +269,8 @@ private: public: SIMachineFunctionInfo(const MachineFunction &MF); + bool initializeBaseYamlFields(const yaml::SIMachineFunctionInfo &YamlMFI); + ArrayRef<SpilledReg> getSGPRToVGPRSpills(int FrameIndex) const { auto I = SGPRToVGPRSpills.find(FrameIndex); return (I == SGPRToVGPRSpills.end()) ? diff --git a/llvm/test/CodeGen/AMDGPU/scalar-store-cache-flush.mir b/llvm/test/CodeGen/AMDGPU/scalar-store-cache-flush.mir index 23974fe0849..1fea21ddd77 100644 --- a/llvm/test/CodeGen/AMDGPU/scalar-store-cache-flush.mir +++ b/llvm/test/CodeGen/AMDGPU/scalar-store-cache-flush.mir @@ -53,6 +53,8 @@ name: basic_insert_dcache_wb tracksRegLiveness: false +machineFunctionInfo: + isEntryFunction: true body: | bb.0: @@ -69,6 +71,8 @@ body: | name: explicit_flush_after tracksRegLiveness: false +machineFunctionInfo: + isEntryFunction: true body: | bb.0: @@ -87,6 +91,8 @@ body: | name: explicit_flush_before tracksRegLiveness: false +machineFunctionInfo: + isEntryFunction: true body: | bb.0: @@ -100,6 +106,8 @@ body: | # CHECK-NEXT: S_ENDPGM 0 name: no_scalar_store tracksRegLiveness: false +machineFunctionInfo: + isEntryFunction: true body: | bb.0: @@ -119,6 +127,8 @@ body: | name: multi_block_store tracksRegLiveness: false +machineFunctionInfo: + isEntryFunction: true body: | bb.0: @@ -146,6 +156,8 @@ body: | name: one_block_store tracksRegLiveness: false +machineFunctionInfo: + isEntryFunction: true body: | bb.0: @@ -165,6 +177,8 @@ body: | name: si_return tracksRegLiveness: false +machineFunctionInfo: + isEntryFunction: true body: | bb.0: diff --git a/llvm/test/CodeGen/AMDGPU/sgpr-spill-wrong-stack-id.mir b/llvm/test/CodeGen/AMDGPU/sgpr-spill-wrong-stack-id.mir index 9481e98502d..59432798c97 100644 --- a/llvm/test/CodeGen/AMDGPU/sgpr-spill-wrong-stack-id.mir +++ b/llvm/test/CodeGen/AMDGPU/sgpr-spill-wrong-stack-id.mir @@ -76,6 +76,11 @@ name: sgpr_spill_wrong_stack_id tracksRegLiveness: true frameInfo: hasCalls: true +machineFunctionInfo: + scratchRSrcReg: $sgpr0_sgpr1_sgpr2_sgpr3 + scratchWaveOffsetReg: $sgpr4 + frameOffsetReg: $sgpr5 + stackPtrOffsetReg: $sgpr32 body: | bb.0: %0:sreg_32_xm0 = COPY $sgpr5 diff --git a/llvm/test/CodeGen/AMDGPU/spill-before-exec.mir b/llvm/test/CodeGen/AMDGPU/spill-before-exec.mir index 0726a2500d6..7f0576b7580 100644 --- a/llvm/test/CodeGen/AMDGPU/spill-before-exec.mir +++ b/llvm/test/CodeGen/AMDGPU/spill-before-exec.mir @@ -8,6 +8,10 @@ name: foo tracksRegLiveness: true +machineFunctionInfo: + scratchRSrcReg: $sgpr0_sgpr1_sgpr2_sgpr3 + scratchWaveOffsetReg: $sgpr4 + stackPtrOffsetReg: $sgpr32 registers: - { id: 0, class: sreg_64 } - { id: 1100, class: sreg_128 } diff --git a/llvm/test/CodeGen/AMDGPU/spill-empty-live-interval.mir b/llvm/test/CodeGen/AMDGPU/spill-empty-live-interval.mir index 384042f5a63..c0e63effb24 100644 --- a/llvm/test/CodeGen/AMDGPU/spill-empty-live-interval.mir +++ b/llvm/test/CodeGen/AMDGPU/spill-empty-live-interval.mir @@ -19,6 +19,11 @@ name: expecting_non_empty_interval tracksRegLiveness: true +machineFunctionInfo: + scratchRSrcReg: $sgpr0_sgpr1_sgpr2_sgpr3 + scratchWaveOffsetReg: $sgpr4 + frameOffsetReg: $sgpr5 + stackPtrOffsetReg: $sgpr32 body: | bb.0: successors: %bb.1 @@ -49,6 +54,11 @@ body: | # CHECK-NEXT: S_NOP 0, implicit %2.sub2 name: rematerialize_empty_interval_has_reference tracksRegLiveness: true +machineFunctionInfo: + scratchRSrcReg: $sgpr0_sgpr1_sgpr2_sgpr3 + scratchWaveOffsetReg: $sgpr4 + frameOffsetReg: $sgpr5 + stackPtrOffsetReg: $sgpr32 body: | bb.0: successors: %bb.1 diff --git a/llvm/test/CodeGen/AMDGPU/stack-slot-color-sgpr-vgpr-spills.mir b/llvm/test/CodeGen/AMDGPU/stack-slot-color-sgpr-vgpr-spills.mir index 559c0d438ef..9d21d70d0b8 100644 --- a/llvm/test/CodeGen/AMDGPU/stack-slot-color-sgpr-vgpr-spills.mir +++ b/llvm/test/CodeGen/AMDGPU/stack-slot-color-sgpr-vgpr-spills.mir @@ -17,9 +17,14 @@ name: no_merge_sgpr_vgpr_spill_slot tracksRegLiveness: true +machineFunctionInfo: + scratchRSrcReg: $sgpr0_sgpr1_sgpr2_sgpr3 + scratchWaveOffsetReg: $sgpr4 + frameOffsetReg: $sgpr5 + stackPtrOffsetReg: $sgpr32 body: | bb.0: - %0:vgpr_32 = FLAT_LOAD_DWORD undef $vgpr0_vgpr1, 0, 0, 0, implicit $flat_scr, implicit $exec + %0:vgpr_32 = FLAT_LOAD_DWORD undef $vgpr0_vgpr1, 0, 0, 0, implicit $flat_scr, implicit $exec %2:vgpr_32 = FLAT_LOAD_DWORD undef $vgpr0_vgpr1, 0, 0, 0, implicit $flat_scr, implicit $exec S_NOP 0, implicit %0 %1:sreg_32_xm0_xexec = S_LOAD_DWORD_IMM undef $sgpr0_sgpr1, 0, 0 diff --git a/llvm/test/CodeGen/AMDGPU/subreg-split-live-in-error.mir b/llvm/test/CodeGen/AMDGPU/subreg-split-live-in-error.mir index 68f6ec79a39..3bb2737b896 100644 --- a/llvm/test/CodeGen/AMDGPU/subreg-split-live-in-error.mir +++ b/llvm/test/CodeGen/AMDGPU/subreg-split-live-in-error.mir @@ -39,6 +39,11 @@ --- name: _amdgpu_ps_main tracksRegLiveness: true +machineFunctionInfo: + scratchRSrcReg: $sgpr0_sgpr1_sgpr2_sgpr3 + scratchWaveOffsetReg: $sgpr4 + frameOffsetReg: $sgpr5 + stackPtrOffsetReg: $sgpr32 liveins: - { reg: '$vgpr2', virtual-reg: '%0' } - { reg: '$vgpr3', virtual-reg: '%1' } diff --git a/llvm/test/CodeGen/MIR/AMDGPU/machine-function-info-no-ir.mir b/llvm/test/CodeGen/MIR/AMDGPU/machine-function-info-no-ir.mir new file mode 100644 index 00000000000..81c4f8f12be --- /dev/null +++ b/llvm/test/CodeGen/MIR/AMDGPU/machine-function-info-no-ir.mir @@ -0,0 +1,151 @@ +# RUN: llc -mtriple=amdgcn-amd-amdhsa -run-pass=none -verify-machineinstrs %s -o - | FileCheck -check-prefixes=FULL,ALL %s +# RUN: llc -mtriple=amdgcn-amd-amdhsa -run-pass=none -simplify-mir -verify-machineinstrs %s -o - | FileCheck -check-prefixes=SIMPLE,ALL %s + + +--- +# ALL-LABEL: name: kernel0 +# FULL: machineFunctionInfo: +# FULL-NEXT: explicitKernArgSize: 128 +# FULL-NEXT: maxKernArgAlign: 64 +# FULL-NEXT: ldsSize: 2048 +# FULL-NEXT: isEntryFunction: true +# FULL-NEXT: noSignedZerosFPMath: false +# FULL-NEXT: memoryBound: true +# FULL-NEXT: waveLimiter: true +# FULL-NEXT: scratchRSrcReg: '$sgpr8_sgpr9_sgpr10_sgpr11' +# FULL-NEXT: scratchWaveOffsetReg: '$sgpr12' +# FULL-NEXT: frameOffsetReg: '$sgpr12' +# FULL-NEXT: stackPtrOffsetReg: '$sgpr13' +# FULL-NEXT: body: + +# SIMPLE: machineFunctionInfo: +# SIMPLE-NEXT: explicitKernArgSize: 128 +# SIMPLE-NEXT: maxKernArgAlign: 64 +# SIMPLE-NEXT: ldsSize: 2048 +# SIMPLE-NEXT: isEntryFunction: true +# SIMPLE-NEXT: memoryBound: true +# SIMPLE-NEXT: waveLimiter: true +# SIMPLE-NEXT: scratchRSrcReg: '$sgpr8_sgpr9_sgpr10_sgpr11' +# SIMPLE-NEXT: scratchWaveOffsetReg: '$sgpr12' +# SIMPLE-NEXT: frameOffsetReg: '$sgpr12' +# SIMPLE-NEXT: stackPtrOffsetReg: '$sgpr13' +# SIMPLE-NEXT: body: +name: kernel0 +machineFunctionInfo: + explicitKernArgSize: 128 + maxKernArgAlign: 64 + ldsSize: 2048 + isEntryFunction: true + noSignedZerosFPMath: false + memoryBound: true + waveLimiter: true + scratchRSrcReg: '$sgpr8_sgpr9_sgpr10_sgpr11' + scratchWaveOffsetReg: '$sgpr12' + frameOffsetReg: '$sgpr12' + stackPtrOffsetReg: '$sgpr13' +body: | + bb.0: + S_ENDPGM 0 + +... + +# FIXME: Should be able to not print section for simple +--- +# ALL-LABEL: name: no_mfi +# FULL: machineFunctionInfo: +# FULL-NEXT: explicitKernArgSize: 0 +# FULL-NEXT: maxKernArgAlign: 0 +# FULL-NEXT: ldsSize: 0 +# FULL-NEXT: isEntryFunction: false +# FULL-NEXT: noSignedZerosFPMath: false +# FULL-NEXT: memoryBound: false +# FULL-NEXT: waveLimiter: false +# FULL-NEXT: scratchRSrcReg: '$private_rsrc_reg' +# FULL-NEXT: scratchWaveOffsetReg: '$scratch_wave_offset_reg' +# FULL-NEXT: frameOffsetReg: '$fp_reg' +# FULL-NEXT: stackPtrOffsetReg: '$sp_reg' + +# SIMPLE: machineFunctionInfo: +# SIMPLE-NEXT: body: + +name: no_mfi +body: | + bb.0: + S_ENDPGM 0 + +... + +--- +# ALL-LABEL: name: empty_mfi +# FULL: machineFunctionInfo: +# FULL-NEXT: explicitKernArgSize: 0 +# FULL-NEXT: maxKernArgAlign: 0 +# FULL-NEXT: ldsSize: 0 +# FULL-NEXT: isEntryFunction: false +# FULL-NEXT: noSignedZerosFPMath: false +# FULL-NEXT: memoryBound: false +# FULL-NEXT: waveLimiter: false +# FULL-NEXT: scratchRSrcReg: '$private_rsrc_reg' +# FULL-NEXT: scratchWaveOffsetReg: '$scratch_wave_offset_reg' +# FULL-NEXT: frameOffsetReg: '$fp_reg' +# FULL-NEXT: stackPtrOffsetReg: '$sp_reg' + +# SIMPLE: machineFunctionInfo: +# SIMPLE-NEXT: body: + +name: empty_mfi +machineFunctionInfo: +body: | + bb.0: + S_ENDPGM 0 + +... + +--- +# ALL-LABEL: name: empty_mfi_entry_func +# FULL: machineFunctionInfo: +# FULL-NEXT: explicitKernArgSize: 0 +# FULL-NEXT: maxKernArgAlign: 0 +# FULL-NEXT: ldsSize: 0 +# FULL-NEXT: isEntryFunction: true +# FULL-NEXT: noSignedZerosFPMath: false +# FULL-NEXT: memoryBound: false +# FULL-NEXT: waveLimiter: false +# FULL-NEXT: scratchRSrcReg: '$private_rsrc_reg' +# FULL-NEXT: scratchWaveOffsetReg: '$scratch_wave_offset_reg' +# FULL-NEXT: frameOffsetReg: '$fp_reg' +# FULL-NEXT: stackPtrOffsetReg: '$sp_reg' + +# SIMPLE: machineFunctionInfo: +# SIMPLE-NEXT: isEntryFunction: true +# SIMPLE-NEXT: body: + +name: empty_mfi_entry_func +machineFunctionInfo: + isEntryFunction: true +body: | + bb.0: + S_ENDPGM 0 + +... + +--- +# ALL-LABEL: name: default_regs_mfi + +# FULL: scratchRSrcReg: '$private_rsrc_reg' +# FULL-NEXT: scratchWaveOffsetReg: '$scratch_wave_offset_reg' +# FULL-NEXT: frameOffsetReg: '$fp_reg' +# FULL-NEXT: stackPtrOffsetReg: '$sp_reg' + +# SIMPLE-NOT: scratchRSrcReg +# SIMPLE-NOT: scratchWaveOffsetReg +# SIMPLE-NOT:: stackPtrOffsetReg +name: default_regs_mfi +machineFunctionInfo: + scratchRSrcReg: '$private_rsrc_reg' + +body: | + bb.0: + S_ENDPGM 0 + +... diff --git a/llvm/test/CodeGen/MIR/AMDGPU/machine-function-info-register-parse-error1.mir b/llvm/test/CodeGen/MIR/AMDGPU/machine-function-info-register-parse-error1.mir new file mode 100644 index 00000000000..cfa5323497e --- /dev/null +++ b/llvm/test/CodeGen/MIR/AMDGPU/machine-function-info-register-parse-error1.mir @@ -0,0 +1,12 @@ +# RUN: not llc -march=amdgcn -run-pass none -o /dev/null %s 2>&1 | FileCheck %s +# CHECK: :7:27: incorrect register class for field +# CHECK: scratchRSrcReg: '$noreg' +--- +name: noreg_rsrc_reg +machineFunctionInfo: + scratchRSrcReg: '$noreg' +body: | + bb.0: + + S_ENDPGM +... diff --git a/llvm/test/CodeGen/MIR/AMDGPU/machine-function-info-register-parse-error2.mir b/llvm/test/CodeGen/MIR/AMDGPU/machine-function-info-register-parse-error2.mir new file mode 100644 index 00000000000..f3da77e2dec --- /dev/null +++ b/llvm/test/CodeGen/MIR/AMDGPU/machine-function-info-register-parse-error2.mir @@ -0,0 +1,12 @@ +# RUN: not llc -march=amdgcn -run-pass none -o /dev/null %s 2>&1 | FileCheck %s +# CHECK: :7:21: unknown register name 'not_a_register_name' +# CHECK: scratchRSrcReg: '$not_a_register_name' +--- +name: invalid_rsrc_reg +machineFunctionInfo: + scratchRSrcReg: '$not_a_register_name' +body: | + bb.0: + + S_ENDPGM +... diff --git a/llvm/test/CodeGen/MIR/AMDGPU/machine-function-info.ll b/llvm/test/CodeGen/MIR/AMDGPU/machine-function-info.ll new file mode 100644 index 00000000000..d04df7d52fe --- /dev/null +++ b/llvm/test/CodeGen/MIR/AMDGPU/machine-function-info.ll @@ -0,0 +1,83 @@ +; RUN: llc -mtriple=amdgcn-mesa-mesa3d -stop-after expand-isel-pseudos -o %t.mir %s +; RUN: llc -run-pass=none -verify-machineinstrs %t.mir -o - | FileCheck %s + +; Test that SIMachineFunctionInfo can be round trip serialized through +; MIR. + +@lds = addrspace(3) global [512 x float] undef, align 4 + +; CHECK-LABEL: {{^}}name: kernel +; CHECK: machineFunctionInfo: +; CHECK-NEXT: explicitKernArgSize: 128 +; CHECK-NEXT: maxKernArgAlign: 64 +; CHECK-NEXT: ldsSize: 2048 +; CHECK-NEXT: isEntryFunction: true +; CHECK-NEXT: noSignedZerosFPMath: false +; CHECK-NEXT: memoryBound: false +; CHECK-NEXT: waveLimiter: false +; CHECK-NEXT: scratchRSrcReg: '$sgpr96_sgpr97_sgpr98_sgpr99' +; CHECK-NEXT: scratchWaveOffsetReg: '$sgpr101' +; CHECK-NEXT: frameOffsetReg: '$sgpr101' +; CHECK-NEXT: stackPtrOffsetReg: '$sp_reg' +; CHECK-NEXT: body: +define amdgpu_kernel void @kernel(i32 %arg0, i64 %arg1, <16 x i32> %arg2) { + %gep = getelementptr inbounds [512 x float], [512 x float] addrspace(3)* @lds, i32 0, i32 %arg0 + store float 0.0, float addrspace(3)* %gep, align 4 + ret void +} + +; CHECK-LABEL: {{^}}name: ps_shader +; CHECK: machineFunctionInfo: +; CHECK-NEXT: explicitKernArgSize: 0 +; CHECK-NEXT: maxKernArgAlign: 0 +; CHECK-NEXT: ldsSize: 0 +; CHECK-NEXT: isEntryFunction: true +; CHECK-NEXT: noSignedZerosFPMath: false +; CHECK-NEXT: memoryBound: false +; CHECK-NEXT: waveLimiter: false +; CHECK-NEXT: scratchRSrcReg: '$sgpr96_sgpr97_sgpr98_sgpr99' +; CHECK-NEXT: scratchWaveOffsetReg: '$sgpr101' +; CHECK-NEXT: frameOffsetReg: '$sgpr101' +; CHECK-NEXT: stackPtrOffsetReg: '$sp_reg' +; CHECK-NEXT: body: +define amdgpu_ps void @ps_shader(i32 %arg0, i32 inreg %arg1) { + ret void +} + +; CHECK-LABEL: {{^}}name: function +; CHECK: machineFunctionInfo: +; CHECK-NEXT: explicitKernArgSize: 0 +; CHECK-NEXT: maxKernArgAlign: 0 +; CHECK-NEXT: ldsSize: 0 +; CHECK-NEXT: isEntryFunction: false +; CHECK-NEXT: noSignedZerosFPMath: false +; CHECK-NEXT: memoryBound: false +; CHECK-NEXT: waveLimiter: false +; CHECK-NEXT: scratchRSrcReg: '$sgpr0_sgpr1_sgpr2_sgpr3' +; CHECK-NEXT: scratchWaveOffsetReg: '$sgpr4' +; CHECK-NEXT: frameOffsetReg: '$sgpr5' +; CHECK-NEXT: stackPtrOffsetReg: '$sgpr32' +; CHECK-NEXT: body: +define void @function() { + ret void +} + +; CHECK-LABEL: {{^}}name: function_nsz +; CHECK: machineFunctionInfo: +; CHECK-NEXT: explicitKernArgSize: 0 +; CHECK-NEXT: maxKernArgAlign: 0 +; CHECK-NEXT: ldsSize: 0 +; CHECK-NEXT: isEntryFunction: false +; CHECK-NEXT: noSignedZerosFPMath: true +; CHECK-NEXT: memoryBound: false +; CHECK-NEXT: waveLimiter: false +; CHECK-NEXT: scratchRSrcReg: '$sgpr0_sgpr1_sgpr2_sgpr3' +; CHECK-NEXT: scratchWaveOffsetReg: '$sgpr4' +; CHECK-NEXT: frameOffsetReg: '$sgpr5' +; CHECK-NEXT: stackPtrOffsetReg: '$sgpr32' +; CHECK-NEXT: body: +define void @function_nsz() #0 { + ret void +} + +attributes #0 = { "no-signed-zeros-fp-math" = "true" } diff --git a/llvm/test/CodeGen/MIR/AMDGPU/mfi-frame-offset-reg-class.mir b/llvm/test/CodeGen/MIR/AMDGPU/mfi-frame-offset-reg-class.mir new file mode 100644 index 00000000000..c66f6b62fa0 --- /dev/null +++ b/llvm/test/CodeGen/MIR/AMDGPU/mfi-frame-offset-reg-class.mir @@ -0,0 +1,13 @@ +# RUN: not llc -march=amdgcn -run-pass none -o /dev/null %s 2>&1 | FileCheck %s +# CHECK: :8:27: incorrect register class for field +# CHECK: frameOffsetReg: '$vgpr0' + +--- +name: wrong_reg_class_frame_offset_reg +machineFunctionInfo: + frameOffsetReg: '$vgpr0' +body: | + bb.0: + + S_ENDPGM +... diff --git a/llvm/test/CodeGen/MIR/AMDGPU/mfi-parse-error-frame-offset-reg.mir b/llvm/test/CodeGen/MIR/AMDGPU/mfi-parse-error-frame-offset-reg.mir new file mode 100644 index 00000000000..723f542f336 --- /dev/null +++ b/llvm/test/CodeGen/MIR/AMDGPU/mfi-parse-error-frame-offset-reg.mir @@ -0,0 +1,12 @@ +# RUN: not llc -march=amdgcn -run-pass none -o /dev/null %s 2>&1 | FileCheck %s +# CHECK: :7:21: expected a named register +# CHECK: frameOffsetReg: '' +--- +name: empty_frame_offset_reg +machineFunctionInfo: + frameOffsetReg: '' +body: | + bb.0: + + S_ENDPGM +... diff --git a/llvm/test/CodeGen/MIR/AMDGPU/mfi-parse-error-scratch-rsrc-reg.mir b/llvm/test/CodeGen/MIR/AMDGPU/mfi-parse-error-scratch-rsrc-reg.mir new file mode 100644 index 00000000000..ee047b91aa4 --- /dev/null +++ b/llvm/test/CodeGen/MIR/AMDGPU/mfi-parse-error-scratch-rsrc-reg.mir @@ -0,0 +1,12 @@ +# RUN: not llc -march=amdgcn -run-pass none -o /dev/null %s 2>&1 | FileCheck %s +# CHECK: :7:21: expected a named register +# CHECK: scratchRSrcReg: '' +--- +name: empty_scratch_rsrc_reg +machineFunctionInfo: + scratchRSrcReg: '' +body: | + bb.0: + + S_ENDPGM +... diff --git a/llvm/test/CodeGen/MIR/AMDGPU/mfi-parse-error-scratch-wave-offset-reg.mir b/llvm/test/CodeGen/MIR/AMDGPU/mfi-parse-error-scratch-wave-offset-reg.mir new file mode 100644 index 00000000000..bbf58085cfa --- /dev/null +++ b/llvm/test/CodeGen/MIR/AMDGPU/mfi-parse-error-scratch-wave-offset-reg.mir @@ -0,0 +1,12 @@ +# RUN: not llc -march=amdgcn -run-pass none -o /dev/null %s 2>&1 | FileCheck %s +# CHECK: :7:27: expected a named register +# CHECK: scratchWaveOffsetReg: '' +--- +name: empty_scratch_wave_offset_reg +machineFunctionInfo: + scratchWaveOffsetReg: '' +body: | + bb.0: + + S_ENDPGM +... diff --git a/llvm/test/CodeGen/MIR/AMDGPU/mfi-parse-error-stack-ptr-offset-reg.mir b/llvm/test/CodeGen/MIR/AMDGPU/mfi-parse-error-stack-ptr-offset-reg.mir new file mode 100644 index 00000000000..e8164dabdd3 --- /dev/null +++ b/llvm/test/CodeGen/MIR/AMDGPU/mfi-parse-error-stack-ptr-offset-reg.mir @@ -0,0 +1,12 @@ +# RUN: not llc -march=amdgcn -run-pass none -o /dev/null %s 2>&1 | FileCheck %s +# CHECK: :7:24: expected a named register +# CHECK: stackPtrOffsetReg: '' +--- +name: empty_stack_ptr_offset_reg +machineFunctionInfo: + stackPtrOffsetReg: '' +body: | + bb.0: + + S_ENDPGM +... diff --git a/llvm/test/CodeGen/MIR/AMDGPU/mfi-scratch-rsrc-reg-reg-class.mir b/llvm/test/CodeGen/MIR/AMDGPU/mfi-scratch-rsrc-reg-reg-class.mir new file mode 100644 index 00000000000..ac02af91a2d --- /dev/null +++ b/llvm/test/CodeGen/MIR/AMDGPU/mfi-scratch-rsrc-reg-reg-class.mir @@ -0,0 +1,13 @@ +# RUN: not llc -march=amdgcn -run-pass none -o /dev/null %s 2>&1 | FileCheck %s +# CHECK: :8:45: incorrect register class for field +# CHECK: scratchRSrcReg: '$vgpr0_vgpr1_vgpr2_vgpr3' + +--- +name: wrong_reg_class_scratch_rsrc_reg +machineFunctionInfo: + scratchRSrcReg: '$vgpr0_vgpr1_vgpr2_vgpr3' +body: | + bb.0: + + S_ENDPGM +... diff --git a/llvm/test/CodeGen/MIR/AMDGPU/mfi-scratch-wave-offset-reg-class.mir b/llvm/test/CodeGen/MIR/AMDGPU/mfi-scratch-wave-offset-reg-class.mir new file mode 100644 index 00000000000..8e765ba01e3 --- /dev/null +++ b/llvm/test/CodeGen/MIR/AMDGPU/mfi-scratch-wave-offset-reg-class.mir @@ -0,0 +1,13 @@ +# RUN: not llc -march=amdgcn -run-pass none -o /dev/null %s 2>&1 | FileCheck %s +# CHECK: :8:33: incorrect register class for field +# CHECK: scratchWaveOffsetReg: '$vgpr0' + +--- +name: wrong_reg_class_scratch_wave_offset_reg +machineFunctionInfo: + scratchWaveOffsetReg: '$vgpr0' +body: | + bb.0: + + S_ENDPGM +... diff --git a/llvm/test/CodeGen/MIR/AMDGPU/mfi-stack-ptr-offset-reg-class.mir b/llvm/test/CodeGen/MIR/AMDGPU/mfi-stack-ptr-offset-reg-class.mir new file mode 100644 index 00000000000..c15b0c6bc98 --- /dev/null +++ b/llvm/test/CodeGen/MIR/AMDGPU/mfi-stack-ptr-offset-reg-class.mir @@ -0,0 +1,13 @@ +# RUN: not llc -march=amdgcn -run-pass none -o /dev/null %s 2>&1 | FileCheck %s +# CHECK: :8:30: incorrect register class for field +# CHECK: stackPtrOffsetReg: '$vgpr0' + +--- +name: wrong_reg_class_stack_ptr_offset_reg +machineFunctionInfo: + stackPtrOffsetReg: '$vgpr0' +body: | + bb.0: + + S_ENDPGM +... |

