mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-26 12:43:36 +01:00
[RISCV] Add support for -ffixed-xX flags
This adds support for reserving GPRs such that the compiler will not choose a register for register allocation. The implementation follows the same design as for AArch64; each reserved register becomes a target feature and used for getting the reserved registers for a given MachineFunction. The backend checks that it does not need to write to any reserved register; if it does a relevant error is generated. Differential Revision: https://reviews.llvm.org/D67185
This commit is contained in:
parent
43ea8ce9c7
commit
2fb7212d27
@ -69,6 +69,11 @@ def FeatureRelax
|
||||
: SubtargetFeature<"relax", "EnableLinkerRelax", "true",
|
||||
"Enable Linker relaxation.">;
|
||||
|
||||
foreach i = {1-31} in
|
||||
def FeatureReserveX#i :
|
||||
SubtargetFeature<"reserve-x"#i, "UserReservedRegister[RISCV::X"#i#"]",
|
||||
"true", "Reserve X"#i>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Named operands for CSR instructions.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/CodeGen/RegisterScavenging.h"
|
||||
#include "llvm/IR/DiagnosticInfo.h"
|
||||
#include "llvm/MC/MCDwarf.h"
|
||||
|
||||
using namespace llvm;
|
||||
@ -131,6 +132,12 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
|
||||
if (StackSize == 0 && !MFI.adjustsStack())
|
||||
return;
|
||||
|
||||
// If the stack pointer has been marked as reserved, then produce an error if
|
||||
// the frame requires stack allocation
|
||||
if (STI.isRegisterReservedByUser(SPReg))
|
||||
MF.getFunction().getContext().diagnose(DiagnosticInfoUnsupported{
|
||||
MF.getFunction(), "Stack pointer required, but has been reserved."});
|
||||
|
||||
uint64_t FirstSPAdjustAmount = getFirstSPAdjustAmount(MF);
|
||||
// Split the SP adjustment to reduce the offsets of callee saved spill.
|
||||
if (FirstSPAdjustAmount)
|
||||
@ -167,6 +174,10 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
|
||||
|
||||
// Generate new FP.
|
||||
if (hasFP(MF)) {
|
||||
if (STI.isRegisterReservedByUser(FPReg))
|
||||
MF.getFunction().getContext().diagnose(DiagnosticInfoUnsupported{
|
||||
MF.getFunction(), "Frame pointer required, but has been reserved."});
|
||||
|
||||
adjustReg(MBB, MBBI, DL, FPReg, SPReg,
|
||||
StackSize - RVFI->getVarArgsSaveSize(), MachineInstr::FrameSetup);
|
||||
|
||||
|
@ -2247,6 +2247,16 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI,
|
||||
Glue = Chain.getValue(1);
|
||||
}
|
||||
|
||||
// Validate that none of the argument registers have been marked as
|
||||
// reserved, if so report an error. Do the same for the return address if this
|
||||
// is not a tailcall.
|
||||
validateCCReservedRegs(RegsToPass, MF);
|
||||
if (!IsTailCall &&
|
||||
MF.getSubtarget<RISCVSubtarget>().isRegisterReservedByUser(RISCV::X1))
|
||||
MF.getFunction().getContext().diagnose(DiagnosticInfoUnsupported{
|
||||
MF.getFunction(),
|
||||
"Return address register required, but has been reserved."});
|
||||
|
||||
// If the callee is a GlobalAddress/ExternalSymbol node, turn it into a
|
||||
// TargetGlobalAddress/TargetExternalSymbol node so that legalize won't
|
||||
// split it and then direct call can be matched by PseudoCALL.
|
||||
@ -2362,6 +2372,9 @@ RISCVTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
|
||||
const SmallVectorImpl<ISD::OutputArg> &Outs,
|
||||
const SmallVectorImpl<SDValue> &OutVals,
|
||||
const SDLoc &DL, SelectionDAG &DAG) const {
|
||||
const MachineFunction &MF = DAG.getMachineFunction();
|
||||
const RISCVSubtarget &STI = MF.getSubtarget<RISCVSubtarget>();
|
||||
|
||||
// Stores the assignment of the return value to a location.
|
||||
SmallVector<CCValAssign, 16> RVLocs;
|
||||
|
||||
@ -2391,6 +2404,13 @@ RISCVTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
|
||||
Register RegLo = VA.getLocReg();
|
||||
assert(RegLo < RISCV::X31 && "Invalid register pair");
|
||||
Register RegHi = RegLo + 1;
|
||||
|
||||
if (STI.isRegisterReservedByUser(RegLo) ||
|
||||
STI.isRegisterReservedByUser(RegHi))
|
||||
MF.getFunction().getContext().diagnose(DiagnosticInfoUnsupported{
|
||||
MF.getFunction(),
|
||||
"Return value register required, but has been reserved."});
|
||||
|
||||
Chain = DAG.getCopyToReg(Chain, DL, RegLo, Lo, Glue);
|
||||
Glue = Chain.getValue(1);
|
||||
RetOps.push_back(DAG.getRegister(RegLo, MVT::i32));
|
||||
@ -2402,6 +2422,11 @@ RISCVTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
|
||||
Val = convertValVTToLocVT(DAG, Val, VA, DL);
|
||||
Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), Val, Glue);
|
||||
|
||||
if (STI.isRegisterReservedByUser(VA.getLocReg()))
|
||||
MF.getFunction().getContext().diagnose(DiagnosticInfoUnsupported{
|
||||
MF.getFunction(),
|
||||
"Return value register required, but has been reserved."});
|
||||
|
||||
// Guarantee that all emitted copies are stuck together.
|
||||
Glue = Chain.getValue(1);
|
||||
RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
|
||||
@ -2440,6 +2465,19 @@ RISCVTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
|
||||
return DAG.getNode(RISCVISD::RET_FLAG, DL, MVT::Other, RetOps);
|
||||
}
|
||||
|
||||
void RISCVTargetLowering::validateCCReservedRegs(
|
||||
const SmallVectorImpl<std::pair<llvm::Register, llvm::SDValue>> &Regs,
|
||||
MachineFunction &MF) const {
|
||||
const Function &F = MF.getFunction();
|
||||
const RISCVSubtarget &STI = MF.getSubtarget<RISCVSubtarget>();
|
||||
|
||||
if (std::any_of(std::begin(Regs), std::end(Regs), [&STI](auto Reg) {
|
||||
return STI.isRegisterReservedByUser(Reg.first);
|
||||
}))
|
||||
F.getContext().diagnose(DiagnosticInfoUnsupported{
|
||||
F, "Argument register required, but has been reserved."});
|
||||
}
|
||||
|
||||
const char *RISCVTargetLowering::getTargetNodeName(unsigned Opcode) const {
|
||||
switch ((RISCVISD::NodeType)Opcode) {
|
||||
case RISCVISD::FIRST_NUMBER:
|
||||
|
@ -210,6 +210,12 @@ private:
|
||||
Value *AlignedAddr, Value *CmpVal,
|
||||
Value *NewVal, Value *Mask,
|
||||
AtomicOrdering Ord) const override;
|
||||
|
||||
/// Generate error diagnostics if any register used by CC has been marked
|
||||
/// reserved.
|
||||
void validateCCReservedRegs(
|
||||
const SmallVectorImpl<std::pair<llvm::Register, llvm::SDValue>> &Regs,
|
||||
MachineFunction &MF) const;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -69,6 +69,12 @@ BitVector RISCVRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
|
||||
const TargetFrameLowering *TFI = getFrameLowering(MF);
|
||||
BitVector Reserved(getNumRegs());
|
||||
|
||||
// Mark any registers requested to be reserved as such
|
||||
for (size_t Reg = 0; Reg < getNumRegs(); Reg++) {
|
||||
if (MF.getSubtarget<RISCVSubtarget>().isRegisterReservedByUser(Reg))
|
||||
markSuperRegs(Reserved, Reg);
|
||||
}
|
||||
|
||||
// Use markSuperRegs to ensure any register aliases are also reserved
|
||||
markSuperRegs(Reserved, RISCV::X0); // zero
|
||||
markSuperRegs(Reserved, RISCV::X1); // ra
|
||||
@ -81,6 +87,11 @@ BitVector RISCVRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
|
||||
return Reserved;
|
||||
}
|
||||
|
||||
bool RISCVRegisterInfo::isAsmClobberable(const MachineFunction &MF,
|
||||
unsigned PhysReg) const {
|
||||
return !MF.getSubtarget<RISCVSubtarget>().isRegisterReservedByUser(PhysReg);
|
||||
}
|
||||
|
||||
bool RISCVRegisterInfo::isConstantPhysReg(unsigned PhysReg) const {
|
||||
return PhysReg == RISCV::X0;
|
||||
}
|
||||
|
@ -30,6 +30,8 @@ struct RISCVRegisterInfo : public RISCVGenRegisterInfo {
|
||||
const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const override;
|
||||
|
||||
BitVector getReservedRegs(const MachineFunction &MF) const override;
|
||||
bool isAsmClobberable(const MachineFunction &MF,
|
||||
unsigned PhysReg) const override;
|
||||
|
||||
bool isConstantPhysReg(unsigned PhysReg) const override;
|
||||
|
||||
|
@ -50,6 +50,7 @@ RISCVSubtarget &RISCVSubtarget::initializeSubtargetDependencies(
|
||||
RISCVSubtarget::RISCVSubtarget(const Triple &TT, StringRef CPU, StringRef FS,
|
||||
StringRef ABIName, const TargetMachine &TM)
|
||||
: RISCVGenSubtargetInfo(TT, CPU, FS),
|
||||
UserReservedRegister(RISCV::NUM_TARGET_REGS),
|
||||
FrameLowering(initializeSubtargetDependencies(TT, CPU, FS, ABIName)),
|
||||
InstrInfo(*this), RegInfo(getHwMode()), TLInfo(TM, *this) {
|
||||
CallLoweringInfo.reset(new RISCVCallLowering(*getTargetLowering()));
|
||||
|
@ -46,6 +46,7 @@ class RISCVSubtarget : public RISCVGenSubtargetInfo {
|
||||
unsigned XLen = 32;
|
||||
MVT XLenVT = MVT::i32;
|
||||
RISCVABI::ABI TargetABI = RISCVABI::ABI_Unknown;
|
||||
BitVector UserReservedRegister;
|
||||
RISCVFrameLowering FrameLowering;
|
||||
RISCVInstrInfo InstrInfo;
|
||||
RISCVRegisterInfo RegInfo;
|
||||
@ -93,6 +94,10 @@ public:
|
||||
MVT getXLenVT() const { return XLenVT; }
|
||||
unsigned getXLen() const { return XLen; }
|
||||
RISCVABI::ABI getTargetABI() const { return TargetABI; }
|
||||
bool isRegisterReservedByUser(Register i) const {
|
||||
assert(i < RISCV::NUM_TARGET_REGS && "Register out of range");
|
||||
return UserReservedRegister[i];
|
||||
}
|
||||
|
||||
protected:
|
||||
// GlobalISel related APIs.
|
||||
|
36
test/CodeGen/RISCV/reserved-reg-errors.ll
Normal file
36
test/CodeGen/RISCV/reserved-reg-errors.ll
Normal file
@ -0,0 +1,36 @@
|
||||
; RUN: not llc -mtriple=riscv32 -mattr=+reserve-x1 < %s 2>&1 | FileCheck %s -check-prefix=X1
|
||||
; RUN: not llc -mtriple=riscv64 -mattr=+reserve-x1 < %s 2>&1 | FileCheck %s -check-prefix=X1
|
||||
; RUN: not llc -mtriple=riscv32 -mattr=+reserve-x2 < %s 2>&1 | FileCheck %s -check-prefix=X2
|
||||
; RUN: not llc -mtriple=riscv64 -mattr=+reserve-x2 < %s 2>&1 | FileCheck %s -check-prefix=X2
|
||||
; RUN: not llc -mtriple=riscv32 -mattr=+reserve-x8 < %s 2>&1 | FileCheck %s -check-prefix=X8
|
||||
; RUN: not llc -mtriple=riscv64 -mattr=+reserve-x8 < %s 2>&1 | FileCheck %s -check-prefix=X8
|
||||
; RUN: not llc -mtriple=riscv32 -mattr=+reserve-x10 < %s 2>&1 | FileCheck %s -check-prefix=X10
|
||||
; RUN: not llc -mtriple=riscv64 -mattr=+reserve-x10 < %s 2>&1 | FileCheck %s -check-prefix=X10
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+reserve-x11 < %s 2>&1 | FileCheck %s -check-prefix=X11
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+reserve-x11 < %s 2>&1 | FileCheck %s -check-prefix=X11
|
||||
; RUN: llc -mtriple=riscv32 <%s
|
||||
; RUN: llc -mtriple=riscv64 <%s
|
||||
|
||||
; This tests combinations when we would expect an error to be produced because
|
||||
; a reserved register is required by the default ABI. The final test checks no
|
||||
; errors are produced when no registers are reserved.
|
||||
|
||||
define i32 @caller(i32 %a) #0 {
|
||||
; X1: in function caller {{.*}} Return address register required, but has been reserved.
|
||||
; X2: in function caller {{.*}} Stack pointer required, but has been reserved.
|
||||
; X8: in function caller {{.*}} Frame pointer required, but has been reserved.
|
||||
; X10: in function caller {{.*}} Argument register required, but has been reserved.
|
||||
; X10: in function caller {{.*}} Return value register required, but has been reserved.
|
||||
%call = call i32 @callee(i32 0)
|
||||
ret i32 %call
|
||||
}
|
||||
|
||||
declare i32 @callee(i32 %a)
|
||||
|
||||
define void @clobber() {
|
||||
; X11: warning: inline asm clobber list contains reserved registers: X11
|
||||
call void asm sideeffect "nop", "~{x11}"()
|
||||
ret void
|
||||
}
|
||||
|
||||
attributes #0 = { "frame-pointer"="all" }
|
130
test/CodeGen/RISCV/reserved-regs.ll
Normal file
130
test/CodeGen/RISCV/reserved-regs.ll
Normal file
@ -0,0 +1,130 @@
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+reserve-x3 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X3
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+reserve-x3 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X3
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+reserve-x4 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X4
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+reserve-x4 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X4
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+reserve-x5 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X5
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+reserve-x5 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X5
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+reserve-x6 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X6
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+reserve-x6 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X6
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+reserve-x7 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X7
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+reserve-x7 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X7
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+reserve-x8 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X8
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+reserve-x8 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X8
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+reserve-x9 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X9
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+reserve-x9 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X9
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+reserve-x10 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X10
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+reserve-x10 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X10
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+reserve-x11 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X11
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+reserve-x11 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X11
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+reserve-x12 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X12
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+reserve-x12 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X12
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+reserve-x13 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X13
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+reserve-x13 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X13
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+reserve-x14 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X14
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+reserve-x14 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X14
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+reserve-x15 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X15
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+reserve-x15 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X15
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+reserve-x16 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X16
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+reserve-x16 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X16
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+reserve-x17 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X17
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+reserve-x17 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X17
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+reserve-x18 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X18
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+reserve-x18 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X18
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+reserve-x19 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X19
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+reserve-x19 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X19
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+reserve-x20 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X20
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+reserve-x20 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X20
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+reserve-x21 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X21
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+reserve-x21 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X21
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+reserve-x22 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X22
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+reserve-x22 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X22
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+reserve-x23 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X23
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+reserve-x23 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X23
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+reserve-x24 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X24
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+reserve-x24 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X24
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+reserve-x25 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X25
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+reserve-x25 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X25
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+reserve-x26 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X26
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+reserve-x26 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X26
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+reserve-x27 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X27
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+reserve-x27 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X27
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+reserve-x28 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X28
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+reserve-x28 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X28
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+reserve-x29 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X29
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+reserve-x29 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X29
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+reserve-x30 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X30
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+reserve-x30 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X30
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+reserve-x31 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X31
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+reserve-x31 -verify-machineinstrs < %s | FileCheck %s -check-prefix=X31
|
||||
|
||||
; This program is free to use all registers, but needs a stack pointer for
|
||||
; spill values, so do not test for reserving the stack pointer.
|
||||
|
||||
; Used to exhaust all registers
|
||||
@var = global [32 x i64] zeroinitializer
|
||||
|
||||
define void @foo() {
|
||||
%1 = load volatile [32 x i64], [32 x i64]* @var
|
||||
store volatile [32 x i64] %1, [32 x i64]* @var
|
||||
|
||||
; X3-NOT: lw gp,
|
||||
; X3-NOT: ld gp,
|
||||
; X4-NOT: lw tp,
|
||||
; X4-NOT: ld tp,
|
||||
; X5-NOT: lw t0,
|
||||
; X5-NOT: ld t0,
|
||||
; X6-NOT: lw t1,
|
||||
; X6-NOT: ld t1,
|
||||
; X7-NOT: lw t2,
|
||||
; X7-NOT: ld t2,
|
||||
; X8-NOT: lw s0,
|
||||
; X8-NOT: ld s0,
|
||||
; X9-NOT: lw s1,
|
||||
; X9-NOT: ld s1,
|
||||
; X10-NOT: lw a0,
|
||||
; X10-NOT: ld a0,
|
||||
; X11-NOT: lw a1,
|
||||
; X11-NOT: ld a1,
|
||||
; X12-NOT: lw a2,
|
||||
; X12-NOT: ld a2,
|
||||
; X13-NOT: lw a3,
|
||||
; X13-NOT: ld a3,
|
||||
; X14-NOT: lw a4,
|
||||
; X14-NOT: ld a4,
|
||||
; X15-NOT: lw a5,
|
||||
; X15-NOT: ld a5,
|
||||
; X16-NOT: lw a6,
|
||||
; X16-NOT: ld a6,
|
||||
; X17-NOT: lw a7,
|
||||
; X17-NOT: ld a7,
|
||||
; X18-NOT: lw s2,
|
||||
; X18-NOT: ld s2,
|
||||
; X19-NOT: lw s3,
|
||||
; X19-NOT: ld s3,
|
||||
; X20-NOT: lw s4,
|
||||
; X20-NOT: ld s4,
|
||||
; X21-NOT: lw s5,
|
||||
; X21-NOT: ld s5,
|
||||
; X22-NOT: lw s6,
|
||||
; X22-NOT: ld s6,
|
||||
; X23-NOT: lw s7,
|
||||
; X23-NOT: ld s7,
|
||||
; X24-NOT: lw s8,
|
||||
; X24-NOT: ld s8,
|
||||
; X25-NOT: lw s9,
|
||||
; X25-NOT: ld s9,
|
||||
; X26-NOT: lw s10,
|
||||
; X26-NOT: ld s10,
|
||||
; X27-NOT: lw s11,
|
||||
; X27-NOT: ld s11,
|
||||
; X28-NOT: lw t3,
|
||||
; X28-NOT: ld t3,
|
||||
; X29-NOT: lw t4,
|
||||
; X29-NOT: ld t4,
|
||||
; X30-NOT: lw t5,
|
||||
; X30-NOT: ld t5,
|
||||
; X31-NOT: lw t6,
|
||||
; X31-NOT: ld t6,
|
||||
|
||||
ret void
|
||||
}
|
Loading…
Reference in New Issue
Block a user