From bc6d07ca46d7e77f3602281a0d0b89ac818ef40d Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Thu, 14 Mar 2019 22:54:43 +0000 Subject: [PATCH] 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 --- .../llvm}/CodeGen/MIRParser/MIParser.h | 4 +- llvm/include/llvm/CodeGen/MIRYamlMapping.h | 17 +++ llvm/include/llvm/CodeGen/MachineModuleInfo.h | 2 + llvm/include/llvm/Target/TargetMachine.h | 28 ++++ llvm/lib/CodeGen/MIRParser/MIParser.cpp | 2 +- llvm/lib/CodeGen/MIRParser/MIRParser.cpp | 21 ++- llvm/lib/CodeGen/MIRPrinter.cpp | 5 + llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp | 73 ++++++++++ llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.h | 8 ++ llvm/lib/Target/AMDGPU/LLVMBuild.txt | 2 +- llvm/lib/Target/AMDGPU/SIISelLowering.cpp | 19 ++- llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp | 39 ++++++ llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h | 54 +++++++- .../CodeGen/AMDGPU/scalar-store-cache-flush.mir | 14 ++ .../CodeGen/AMDGPU/sgpr-spill-wrong-stack-id.mir | 5 + llvm/test/CodeGen/AMDGPU/spill-before-exec.mir | 4 + .../CodeGen/AMDGPU/spill-empty-live-interval.mir | 10 ++ .../AMDGPU/stack-slot-color-sgpr-vgpr-spills.mir | 7 +- .../CodeGen/AMDGPU/subreg-split-live-in-error.mir | 5 + .../MIR/AMDGPU/machine-function-info-no-ir.mir | 151 +++++++++++++++++++++ ...machine-function-info-register-parse-error1.mir | 12 ++ ...machine-function-info-register-parse-error2.mir | 12 ++ .../CodeGen/MIR/AMDGPU/machine-function-info.ll | 83 +++++++++++ .../MIR/AMDGPU/mfi-frame-offset-reg-class.mir | 13 ++ .../AMDGPU/mfi-parse-error-frame-offset-reg.mir | 12 ++ .../AMDGPU/mfi-parse-error-scratch-rsrc-reg.mir | 12 ++ .../mfi-parse-error-scratch-wave-offset-reg.mir | 12 ++ .../mfi-parse-error-stack-ptr-offset-reg.mir | 12 ++ .../MIR/AMDGPU/mfi-scratch-rsrc-reg-reg-class.mir | 13 ++ .../AMDGPU/mfi-scratch-wave-offset-reg-class.mir | 13 ++ .../MIR/AMDGPU/mfi-stack-ptr-offset-reg-class.mir | 13 ++ 31 files changed, 665 insertions(+), 12 deletions(-) rename llvm/{lib => include/llvm}/CodeGen/MIRParser/MIParser.h (98%) create mode 100644 llvm/test/CodeGen/MIR/AMDGPU/machine-function-info-no-ir.mir create mode 100644 llvm/test/CodeGen/MIR/AMDGPU/machine-function-info-register-parse-error1.mir create mode 100644 llvm/test/CodeGen/MIR/AMDGPU/machine-function-info-register-parse-error2.mir create mode 100644 llvm/test/CodeGen/MIR/AMDGPU/machine-function-info.ll create mode 100644 llvm/test/CodeGen/MIR/AMDGPU/mfi-frame-offset-reg-class.mir create mode 100644 llvm/test/CodeGen/MIR/AMDGPU/mfi-parse-error-frame-offset-reg.mir create mode 100644 llvm/test/CodeGen/MIR/AMDGPU/mfi-parse-error-scratch-rsrc-reg.mir create mode 100644 llvm/test/CodeGen/MIR/AMDGPU/mfi-parse-error-scratch-wave-offset-reg.mir create mode 100644 llvm/test/CodeGen/MIR/AMDGPU/mfi-parse-error-stack-ptr-offset-reg.mir create mode 100644 llvm/test/CodeGen/MIR/AMDGPU/mfi-scratch-rsrc-reg-reg-class.mir create mode 100644 llvm/test/CodeGen/MIR/AMDGPU/mfi-scratch-wave-offset-reg-class.mir create mode 100644 llvm/test/CodeGen/MIR/AMDGPU/mfi-stack-ptr-offset-reg-class.mir diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.h b/llvm/include/llvm/CodeGen/MIRParser/MIParser.h similarity index 98% rename from llvm/lib/CodeGen/MIRParser/MIParser.h rename to llvm/include/llvm/CodeGen/MIRParser/MIParser.h index dc858a9..4e32a04 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 MBBSlots; - DenseMap VRegInfos; - StringMap VRegInfosNamed; + DenseMap VRegInfos; + StringMap VRegInfosNamed; DenseMap FixedStackObjectSlots; DenseMap StackObjectSlots; DenseMap ConstantPoolSlots; diff --git a/llvm/include/llvm/CodeGen/MIRYamlMapping.h b/llvm/include/llvm/CodeGen/MIRYamlMapping.h index a0f2b16..13f572f 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 { } }; +/// 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> { + static void mapping(IO &YamlIO, std::unique_ptr &MFI) { + if (MFI) + MFI->mappingImpl(YamlIO); + } +}; + struct MachineFunction { StringRef Name; unsigned Alignment = 0; @@ -503,6 +518,7 @@ struct MachineFunction { std::vector FixedStackObjects; std::vector StackObjects; std::vector Constants; /// Constant pool. + std::unique_ptr MachineFuncInfo; MachineJumpTable JumpTableInfo; BlockStringValue Body; }; @@ -531,6 +547,7 @@ template <> struct MappingTraits { std::vector()); YamlIO.mapOptional("constants", MF.Constants, std::vector()); + 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 9b81dc6..4ff5c7f 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 7dd9b99..f289c65 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 593ec57..971944b 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 7a4eb45f..3598cbe 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 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( + 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 5977ba4..86e3f53 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(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 dd76390..23ba6ce 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(); + 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(MFI_); + MachineFunction &MF = PFS.MF; + SIMachineFunctionInfo *MFI = MF.getInfo(); + + 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 b8805f0..70fa396 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 2f661af..e18085d 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 9205c20..f625331 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 78e88ab..834f651 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::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 de84fbb..ce103dc 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 { + 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 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 23974fe..1fea21d 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 9481e98..5943279 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 0726a25..7f0576b7 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 384042f..c0e63ef 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 559c0d4..9d21d70 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 68f6ec7..3bb2737 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 0000000..81c4f8f --- /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 0000000..cfa5323 --- /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 0000000..f3da77e --- /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 0000000..d04df7d --- /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 0000000..c66f6b6 --- /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 0000000..723f542 --- /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 0000000..ee047b9 --- /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 0000000..bbf5808 --- /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 0000000..e8164da --- /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 0000000..ac02af9 --- /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 0000000..8e765ba --- /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 0000000..c15b0c6 --- /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 +... -- 2.7.4