summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Arsenault <Matthew.Arsenault@amd.com>2019-03-14 22:54:43 +0000
committerMatt Arsenault <Matthew.Arsenault@amd.com>2019-03-14 22:54:43 +0000
commitbc6d07ca46d7e77f3602281a0d0b89ac818ef40d (patch)
tree4d4c5d1cf6686a738b24c4811b24d598c0a3b96b
parent7d6784f5225b19867eb7702e4ff9b3c3b06dfb7b (diff)
downloadbcm5719-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
-rw-r--r--llvm/include/llvm/CodeGen/MIRParser/MIParser.h (renamed from llvm/lib/CodeGen/MIRParser/MIParser.h)4
-rw-r--r--llvm/include/llvm/CodeGen/MIRYamlMapping.h17
-rw-r--r--llvm/include/llvm/CodeGen/MachineModuleInfo.h2
-rw-r--r--llvm/include/llvm/Target/TargetMachine.h28
-rw-r--r--llvm/lib/CodeGen/MIRParser/MIParser.cpp2
-rw-r--r--llvm/lib/CodeGen/MIRParser/MIRParser.cpp21
-rw-r--r--llvm/lib/CodeGen/MIRPrinter.cpp5
-rw-r--r--llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp73
-rw-r--r--llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.h8
-rw-r--r--llvm/lib/Target/AMDGPU/LLVMBuild.txt2
-rw-r--r--llvm/lib/Target/AMDGPU/SIISelLowering.cpp19
-rw-r--r--llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp39
-rw-r--r--llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h54
-rw-r--r--llvm/test/CodeGen/AMDGPU/scalar-store-cache-flush.mir14
-rw-r--r--llvm/test/CodeGen/AMDGPU/sgpr-spill-wrong-stack-id.mir5
-rw-r--r--llvm/test/CodeGen/AMDGPU/spill-before-exec.mir4
-rw-r--r--llvm/test/CodeGen/AMDGPU/spill-empty-live-interval.mir10
-rw-r--r--llvm/test/CodeGen/AMDGPU/stack-slot-color-sgpr-vgpr-spills.mir7
-rw-r--r--llvm/test/CodeGen/AMDGPU/subreg-split-live-in-error.mir5
-rw-r--r--llvm/test/CodeGen/MIR/AMDGPU/machine-function-info-no-ir.mir151
-rw-r--r--llvm/test/CodeGen/MIR/AMDGPU/machine-function-info-register-parse-error1.mir12
-rw-r--r--llvm/test/CodeGen/MIR/AMDGPU/machine-function-info-register-parse-error2.mir12
-rw-r--r--llvm/test/CodeGen/MIR/AMDGPU/machine-function-info.ll83
-rw-r--r--llvm/test/CodeGen/MIR/AMDGPU/mfi-frame-offset-reg-class.mir13
-rw-r--r--llvm/test/CodeGen/MIR/AMDGPU/mfi-parse-error-frame-offset-reg.mir12
-rw-r--r--llvm/test/CodeGen/MIR/AMDGPU/mfi-parse-error-scratch-rsrc-reg.mir12
-rw-r--r--llvm/test/CodeGen/MIR/AMDGPU/mfi-parse-error-scratch-wave-offset-reg.mir12
-rw-r--r--llvm/test/CodeGen/MIR/AMDGPU/mfi-parse-error-stack-ptr-offset-reg.mir12
-rw-r--r--llvm/test/CodeGen/MIR/AMDGPU/mfi-scratch-rsrc-reg-reg-class.mir13
-rw-r--r--llvm/test/CodeGen/MIR/AMDGPU/mfi-scratch-wave-offset-reg-class.mir13
-rw-r--r--llvm/test/CodeGen/MIR/AMDGPU/mfi-stack-ptr-offset-reg-class.mir13
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
+...
OpenPOWER on IntegriCloud