From 3b391fe80e65f144d9e2e31a09e24f00ac7bb230 Mon Sep 17 00:00:00 2001 From: Geoff Berry Date: Tue, 12 Dec 2017 17:53:59 +0000 Subject: [PATCH] [MachineOperand][MIR] Add isRenamable to MachineOperand. Summary: Add isRenamable() predicate to MachineOperand. This predicate can be used by machine passes after register allocation to determine whether it is safe to rename a given register operand. Register operands that aren't marked as renamable may be required to be assigned their current register to satisfy constraints that are not captured by the machine IR (e.g. ABI or ISA constraints). Reviewers: qcolombet, MatzeB, hfinkel Subscribers: nemanjai, mcrosier, javed.absar, llvm-commits Differential Revision: https://reviews.llvm.org/D39400 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@320503 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/MIRLangRef.rst | 3 ++ include/llvm/CodeGen/MachineInstrBuilder.h | 13 +++++- include/llvm/CodeGen/MachineOperand.h | 49 ++++++++++++++-------- lib/CodeGen/MIRParser/MILexer.cpp | 1 + lib/CodeGen/MIRParser/MILexer.h | 4 +- lib/CodeGen/MIRParser/MIParser.cpp | 7 +++- lib/CodeGen/MachineOperand.cpp | 37 +++++++++++++++- lib/CodeGen/MachineVerifier.cpp | 8 ++++ lib/CodeGen/RegAllocFast.cpp | 2 + lib/CodeGen/VirtRegMap.cpp | 1 + lib/Target/ARM/ARMBaseInstrInfo.cpp | 17 ++++++-- lib/Target/ARM/ARMExpandPseudoInsts.cpp | 11 +++-- lib/Target/ARM/ARMISelLowering.cpp | 5 ++- test/CodeGen/AArch64/arm64-misched-multimmo.ll | 4 +- test/CodeGen/AMDGPU/shrink-carry.mir | 8 ++-- test/CodeGen/AMDGPU/splitkit.mir | 16 +++---- .../AMDGPU/stack-slot-color-sgpr-vgpr-spills.mir | 4 +- test/CodeGen/AMDGPU/subreg_interference.mir | 12 +++--- test/CodeGen/AMDGPU/syncscopes.ll | 6 +-- test/CodeGen/Hexagon/regalloc-bad-undef.mir | 2 +- test/CodeGen/MIR/X86/renamable-register-flag.mir | 16 +++++++ test/CodeGen/PowerPC/byval-agg-info.ll | 2 +- .../SystemZ/regalloc-fast-invalid-kill-flag.mir | 4 +- test/CodeGen/X86/tail-merge-debugloc.ll | 2 +- test/DebugInfo/X86/pr34545.ll | 4 +- test/DebugInfo/X86/sdag-salvage-add.ll | 2 +- 26 files changed, 176 insertions(+), 64 deletions(-) create mode 100644 test/CodeGen/MIR/X86/renamable-register-flag.mir diff --git a/docs/MIRLangRef.rst b/docs/MIRLangRef.rst index 562b11a6d18..7615a28112d 100644 --- a/docs/MIRLangRef.rst +++ b/docs/MIRLangRef.rst @@ -529,6 +529,9 @@ corresponding internal ``llvm::RegState`` representation: * - ``debug-use`` - ``RegState::Debug`` + * - ``renamable`` + - ``RegState::Renamable`` + .. _subregister-indices: Subregister Indices diff --git a/include/llvm/CodeGen/MachineInstrBuilder.h b/include/llvm/CodeGen/MachineInstrBuilder.h index 9e0f19a5aea..e4f3976ec95 100644 --- a/include/llvm/CodeGen/MachineInstrBuilder.h +++ b/include/llvm/CodeGen/MachineInstrBuilder.h @@ -25,6 +25,7 @@ #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineInstrBundle.h" #include "llvm/CodeGen/MachineOperand.h" +#include "llvm/CodeGen/TargetRegisterInfo.h" #include "llvm/IR/InstrTypes.h" #include "llvm/IR/Intrinsics.h" #include "llvm/Support/ErrorHandling.h" @@ -48,6 +49,7 @@ namespace RegState { EarlyClobber = 0x40, Debug = 0x80, InternalRead = 0x100, + Renamable = 0x200, DefineNoRead = Define | Undef, ImplicitDefine = Implicit | Define, ImplicitKill = Implicit | Kill @@ -91,7 +93,8 @@ public: flags & RegState::EarlyClobber, SubReg, flags & RegState::Debug, - flags & RegState::InternalRead)); + flags & RegState::InternalRead, + flags & RegState::Renamable)); return *this; } @@ -443,6 +446,9 @@ inline unsigned getInternalReadRegState(bool B) { inline unsigned getDebugRegState(bool B) { return B ? RegState::Debug : 0; } +inline unsigned getRenamableRegState(bool B) { + return B ? RegState::Renamable : 0; +} /// Get all register state flags from machine operand \p RegOp. inline unsigned getRegState(const MachineOperand &RegOp) { @@ -453,7 +459,10 @@ inline unsigned getRegState(const MachineOperand &RegOp) { getDeadRegState(RegOp.isDead()) | getUndefRegState(RegOp.isUndef()) | getInternalReadRegState(RegOp.isInternalRead()) | - getDebugRegState(RegOp.isDebug()); + getDebugRegState(RegOp.isDebug()) | + getRenamableRegState( + TargetRegisterInfo::isPhysicalRegister(RegOp.getReg()) && + RegOp.isRenamable()); } /// Helper class for constructing bundles of MachineInstrs. diff --git a/include/llvm/CodeGen/MachineOperand.h b/include/llvm/CodeGen/MachineOperand.h index a7043ea90e3..c235649c009 100644 --- a/include/llvm/CodeGen/MachineOperand.h +++ b/include/llvm/CodeGen/MachineOperand.h @@ -86,24 +86,30 @@ private: /// before MachineInstr::tieOperands(). unsigned char TiedTo : 4; - /// IsDef/IsImp/IsKill/IsDead flags - These are only valid for MO_Register - /// operands. - /// IsDef - True if this is a def, false if this is a use of the register. + /// This is only valid on register operands. /// bool IsDef : 1; /// IsImp - True if this is an implicit def or use, false if it is explicit. + /// This is only valid on register opderands. /// bool IsImp : 1; - /// IsKill - True if this instruction is the last use of the register on this - /// path through the function. This is only valid on uses of registers. - bool IsKill : 1; - - /// IsDead - True if this register is never used by a subsequent instruction. - /// This is only valid on definitions of registers. - bool IsDead : 1; + /// IsDeadOrKill + /// For uses: IsKill - True if this instruction is the last use of the + /// register on this path through the function. + /// For defs: IsDead - True if this register is never used by a subsequent + /// instruction. + /// This is only valid on register operands. + bool IsDeadOrKill : 1; + + /// IsRenamable - True if this register may be renamed, i.e. it does not + /// generate a value that is somehow read in a way that is not represented by + /// the Machine IR (e.g. to meet an ABI or ISA requirement). This is only + /// valid on physical register operands. Virtual registers are assumed to + /// always be renamable regardless of the value of this field. + bool IsRenamable : 1; /// IsUndef - True if this register operand reads an "undef" value, i.e. the /// read value doesn't matter. This flag can be set on both use and def @@ -333,12 +339,12 @@ public: bool isDead() const { assert(isReg() && "Wrong MachineOperand accessor"); - return IsDead; + return IsDeadOrKill & IsDef; } bool isKill() const { assert(isReg() && "Wrong MachineOperand accessor"); - return IsKill; + return IsDeadOrKill & !IsDef; } bool isUndef() const { @@ -346,6 +352,8 @@ public: return IsUndef; } + bool isRenamable() const; + bool isInternalRead() const { assert(isReg() && "Wrong MachineOperand accessor"); return IsInternalRead; @@ -418,12 +426,12 @@ public: void setIsKill(bool Val = true) { assert(isReg() && !IsDef && "Wrong MachineOperand mutator"); assert((!Val || !isDebug()) && "Marking a debug operation as kill"); - IsKill = Val; + IsDeadOrKill = Val; } void setIsDead(bool Val = true) { assert(isReg() && IsDef && "Wrong MachineOperand mutator"); - IsDead = Val; + IsDeadOrKill = Val; } void setIsUndef(bool Val = true) { @@ -431,6 +439,12 @@ public: IsUndef = Val; } + void setIsRenamable(bool Val = true); + + /// Set IsRenamable to true if there are no extra register allocation + /// requirements placed on this operand by the parent instruction's opcode. + void setIsRenamableIfNoExtraRegAllocReq(); + void setIsInternalRead(bool Val = true) { assert(isReg() && "Wrong MachineOperand mutator"); IsInternalRead = Val; @@ -675,14 +689,15 @@ public: bool isUndef = false, bool isEarlyClobber = false, unsigned SubReg = 0, bool isDebug = false, - bool isInternalRead = false) { + bool isInternalRead = false, + bool isRenamable = false) { assert(!(isDead && !isDef) && "Dead flag on non-def"); assert(!(isKill && isDef) && "Kill flag on def"); MachineOperand Op(MachineOperand::MO_Register); Op.IsDef = isDef; Op.IsImp = isImp; - Op.IsKill = isKill; - Op.IsDead = isDead; + Op.IsDeadOrKill = isKill | isDead; + Op.IsRenamable = isRenamable; Op.IsUndef = isUndef; Op.IsInternalRead = isInternalRead; Op.IsEarlyClobber = isEarlyClobber; diff --git a/lib/CodeGen/MIRParser/MILexer.cpp b/lib/CodeGen/MIRParser/MILexer.cpp index ac696923794..fe6d075726e 100644 --- a/lib/CodeGen/MIRParser/MILexer.cpp +++ b/lib/CodeGen/MIRParser/MILexer.cpp @@ -208,6 +208,7 @@ static MIToken::TokenKind getIdentifierKind(StringRef Identifier) { .Case("internal", MIToken::kw_internal) .Case("early-clobber", MIToken::kw_early_clobber) .Case("debug-use", MIToken::kw_debug_use) + .Case("renamable", MIToken::kw_renamable) .Case("tied-def", MIToken::kw_tied_def) .Case("frame-setup", MIToken::kw_frame_setup) .Case("debug-location", MIToken::kw_debug_location) diff --git a/lib/CodeGen/MIRParser/MILexer.h b/lib/CodeGen/MIRParser/MILexer.h index 6894fe8b0ac..f7027bea181 100644 --- a/lib/CodeGen/MIRParser/MILexer.h +++ b/lib/CodeGen/MIRParser/MILexer.h @@ -60,6 +60,7 @@ struct MIToken { kw_internal, kw_early_clobber, kw_debug_use, + kw_renamable, kw_tied_def, kw_frame_setup, kw_debug_location, @@ -166,7 +167,8 @@ public: return Kind == kw_implicit || Kind == kw_implicit_define || Kind == kw_def || Kind == kw_dead || Kind == kw_killed || Kind == kw_undef || Kind == kw_internal || - Kind == kw_early_clobber || Kind == kw_debug_use; + Kind == kw_early_clobber || Kind == kw_debug_use || + Kind == kw_renamable; } bool isMemoryOperandFlag() const { diff --git a/lib/CodeGen/MIRParser/MIParser.cpp b/lib/CodeGen/MIRParser/MIParser.cpp index de951e42c8f..6ec3fc864c6 100644 --- a/lib/CodeGen/MIRParser/MIParser.cpp +++ b/lib/CodeGen/MIRParser/MIParser.cpp @@ -1060,6 +1060,9 @@ bool MIParser::parseRegisterFlag(unsigned &Flags) { case MIToken::kw_debug_use: Flags |= RegState::Debug; break; + case MIToken::kw_renamable: + Flags |= RegState::Renamable; + break; default: llvm_unreachable("The current token should be a register flag"); } @@ -1212,7 +1215,8 @@ bool MIParser::parseRegisterOperand(MachineOperand &Dest, Reg, Flags & RegState::Define, Flags & RegState::Implicit, Flags & RegState::Kill, Flags & RegState::Dead, Flags & RegState::Undef, Flags & RegState::EarlyClobber, SubReg, Flags & RegState::Debug, - Flags & RegState::InternalRead); + Flags & RegState::InternalRead, Flags & RegState::Renamable); + return false; } @@ -1880,6 +1884,7 @@ bool MIParser::parseMachineOperand(MachineOperand &Dest, case MIToken::kw_internal: case MIToken::kw_early_clobber: case MIToken::kw_debug_use: + case MIToken::kw_renamable: case MIToken::underscore: case MIToken::NamedRegister: case MIToken::VirtualRegister: diff --git a/lib/CodeGen/MachineOperand.cpp b/lib/CodeGen/MachineOperand.cpp index 8bd6a7a965b..b618e605dca 100644 --- a/lib/CodeGen/MachineOperand.cpp +++ b/lib/CodeGen/MachineOperand.cpp @@ -90,6 +90,7 @@ void MachineOperand::setIsDef(bool Val) { assert((!Val || !isDebug()) && "Marking a debug operation as def"); if (IsDef == Val) return; + assert(!IsDeadOrKill && "Changing def/use with dead/kill set not supported"); // MRI may keep uses and defs in different list positions. if (MachineFunction *MF = getMFIfAvailable(*this)) { MachineRegisterInfo &MRI = MF->getRegInfo(); @@ -101,6 +102,34 @@ void MachineOperand::setIsDef(bool Val) { IsDef = Val; } +bool MachineOperand::isRenamable() const { + assert(isReg() && "Wrong MachineOperand accessor"); + assert(TargetRegisterInfo::isPhysicalRegister(getReg()) && + "isRenamable should only be checked on physical registers"); + return IsRenamable; +} + +void MachineOperand::setIsRenamable(bool Val) { + assert(isReg() && "Wrong MachineOperand accessor"); + assert(TargetRegisterInfo::isPhysicalRegister(getReg()) && + "setIsRenamable should only be called on physical registers"); + if (const MachineInstr *MI = getParent()) + if ((isDef() && MI->hasExtraDefRegAllocReq()) || + (isUse() && MI->hasExtraSrcRegAllocReq())) + assert(!Val && "isRenamable should be false for " + "hasExtraDefRegAllocReq/hasExtraSrcRegAllocReq opcodes"); + IsRenamable = Val; +} + +void MachineOperand::setIsRenamableIfNoExtraRegAllocReq() { + if (const MachineInstr *MI = getParent()) + if ((isDef() && MI->hasExtraDefRegAllocReq()) || + (isUse() && MI->hasExtraSrcRegAllocReq())) + return; + + setIsRenamable(true); +} + // If this operand is currently a register operand, and if this is in a // function, deregister the operand from the register's use/def list. void MachineOperand::removeRegFromUses() { @@ -194,13 +223,15 @@ void MachineOperand::ChangeToRegister(unsigned Reg, bool isDef, bool isImp, RegInfo->removeRegOperandFromUseList(this); // Change this to a register and set the reg#. + assert(!(isDead && !isDef) && "Dead flag on non-def"); + assert(!(isKill && isDef) && "Kill flag on def"); OpKind = MO_Register; SmallContents.RegNo = Reg; SubReg_TargetFlags = 0; IsDef = isDef; IsImp = isImp; - IsKill = isKill; - IsDead = isDead; + IsDeadOrKill = isKill | isDead; + IsRenamable = false; IsUndef = isUndef; IsInternalRead = false; IsEarlyClobber = false; @@ -389,6 +420,8 @@ void MachineOperand::print(raw_ostream &OS, ModuleSlotTracker &MST, OS << "early-clobber "; if (isDebug()) OS << "debug-use "; + if (TargetRegisterInfo::isPhysicalRegister(getReg()) && isRenamable()) + OS << "renamable "; OS << printReg(Reg, TRI); // Print the sub register. if (unsigned SubReg = getSubReg()) { diff --git a/lib/CodeGen/MachineVerifier.cpp b/lib/CodeGen/MachineVerifier.cpp index d5658db161a..6ed6f0aced9 100644 --- a/lib/CodeGen/MachineVerifier.cpp +++ b/lib/CodeGen/MachineVerifier.cpp @@ -1101,6 +1101,14 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) { } } } + if (MO->isRenamable() && + ((MO->isDef() && MI->hasExtraDefRegAllocReq()) || + (MO->isUse() && MI->hasExtraSrcRegAllocReq()))) { + report("Illegal isRenamable setting for opcode with extra regalloc " + "requirements", + MO, MONum); + return; + } } else { // Virtual register. const TargetRegisterClass *RC = MRI->getRegClassOrNull(Reg); diff --git a/lib/CodeGen/RegAllocFast.cpp b/lib/CodeGen/RegAllocFast.cpp index 97011d55d89..f6adb2509bf 100644 --- a/lib/CodeGen/RegAllocFast.cpp +++ b/lib/CodeGen/RegAllocFast.cpp @@ -699,11 +699,13 @@ bool RegAllocFast::setPhysReg(MachineInstr &MI, unsigned OpNum, bool Dead = MO.isDead(); if (!MO.getSubReg()) { MO.setReg(PhysReg); + MO.setIsRenamableIfNoExtraRegAllocReq(); return MO.isKill() || Dead; } // Handle subregister index. MO.setReg(PhysReg ? TRI->getSubReg(PhysReg, MO.getSubReg()) : 0); + MO.setIsRenamableIfNoExtraRegAllocReq(); MO.setSubReg(0); // A kill flag implies killing the full register. Add corresponding super diff --git a/lib/CodeGen/VirtRegMap.cpp b/lib/CodeGen/VirtRegMap.cpp index 6e5674bb8bc..00a4eb7808f 100644 --- a/lib/CodeGen/VirtRegMap.cpp +++ b/lib/CodeGen/VirtRegMap.cpp @@ -530,6 +530,7 @@ void VirtRegRewriter::rewrite() { // Rewrite. Note we could have used MachineOperand::substPhysReg(), but // we need the inlining here. MO.setReg(PhysReg); + MO.setIsRenamableIfNoExtraRegAllocReq(); } // Add any missing super-register kills after rewriting the whole diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp index b2f4a529efa..02bf7739e15 100644 --- a/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -1357,25 +1357,34 @@ void ARMBaseInstrInfo::expandMEMCPY(MachineBasicBlock::iterator MI) const { MachineInstrBuilder LDM, STM; if (isThumb1 || !MI->getOperand(1).isDead()) { + MachineOperand LDWb(MI->getOperand(1)); + LDWb.setIsRenamable(false); LDM = BuildMI(*BB, MI, dl, TII->get(isThumb2 ? ARM::t2LDMIA_UPD : isThumb1 ? ARM::tLDMIA_UPD : ARM::LDMIA_UPD)) - .add(MI->getOperand(1)); + .add(LDWb); } else { LDM = BuildMI(*BB, MI, dl, TII->get(isThumb2 ? ARM::t2LDMIA : ARM::LDMIA)); } if (isThumb1 || !MI->getOperand(0).isDead()) { + MachineOperand STWb(MI->getOperand(0)); + STWb.setIsRenamable(false); STM = BuildMI(*BB, MI, dl, TII->get(isThumb2 ? ARM::t2STMIA_UPD : isThumb1 ? ARM::tSTMIA_UPD : ARM::STMIA_UPD)) - .add(MI->getOperand(0)); + .add(STWb); } else { STM = BuildMI(*BB, MI, dl, TII->get(isThumb2 ? ARM::t2STMIA : ARM::STMIA)); } - LDM.add(MI->getOperand(3)).add(predOps(ARMCC::AL)); - STM.add(MI->getOperand(2)).add(predOps(ARMCC::AL)); + MachineOperand LDBase(MI->getOperand(3)); + LDBase.setIsRenamable(false); + LDM.add(LDBase).add(predOps(ARMCC::AL)); + + MachineOperand STBase(MI->getOperand(2)); + STBase.setIsRenamable(false); + STM.add(STBase).add(predOps(ARMCC::AL)); // Sort the scratch registers into ascending order. const TargetRegisterInfo &TRI = getRegisterInfo(); diff --git a/lib/Target/ARM/ARMExpandPseudoInsts.cpp b/lib/Target/ARM/ARMExpandPseudoInsts.cpp index eab84ae59e2..1c64e3d1a1c 100644 --- a/lib/Target/ARM/ARMExpandPseudoInsts.cpp +++ b/lib/Target/ARM/ARMExpandPseudoInsts.cpp @@ -606,8 +606,11 @@ void ARMExpandPseudo::ExpandVTBL(MachineBasicBlock::iterator &MBBI, // Transfer the destination register operand. MIB.add(MI.getOperand(OpIdx++)); - if (IsExt) - MIB.add(MI.getOperand(OpIdx++)); + if (IsExt) { + MachineOperand VdSrc(MI.getOperand(OpIdx++)); + VdSrc.setIsRenamable(false); + MIB.add(VdSrc); + } bool SrcIsKill = MI.getOperand(OpIdx).isKill(); unsigned SrcReg = MI.getOperand(OpIdx++).getReg(); @@ -616,7 +619,9 @@ void ARMExpandPseudo::ExpandVTBL(MachineBasicBlock::iterator &MBBI, MIB.addReg(D0); // Copy the other source register operand. - MIB.add(MI.getOperand(OpIdx++)); + MachineOperand VmSrc(MI.getOperand(OpIdx++)); + VmSrc.setIsRenamable(false); + MIB.add(VmSrc); // Copy the predicate operands. MIB.add(MI.getOperand(OpIdx++)); diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index 0a0869afb86..e4296a77c0d 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -8974,8 +8974,11 @@ ARMTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI, // Thumb1 post-indexed loads are really just single-register LDMs. case ARM::tLDR_postidx: { + MachineOperand Def(MI.getOperand(1)); + if (TargetRegisterInfo::isPhysicalRegister(Def.getReg())) + Def.setIsRenamable(false); BuildMI(*BB, MI, dl, TII->get(ARM::tLDMIA_UPD)) - .add(MI.getOperand(1)) // Rn_wb + .add(Def) // Rn_wb .add(MI.getOperand(2)) // Rn .add(MI.getOperand(3)) // PredImm .add(MI.getOperand(4)) // PredReg diff --git a/test/CodeGen/AArch64/arm64-misched-multimmo.ll b/test/CodeGen/AArch64/arm64-misched-multimmo.ll index bdd4f49d174..47f2ec790c7 100644 --- a/test/CodeGen/AArch64/arm64-misched-multimmo.ll +++ b/test/CodeGen/AArch64/arm64-misched-multimmo.ll @@ -8,11 +8,11 @@ ; Check that no scheduling dependencies are created between the paired loads and the store during post-RA MI scheduling. ; ; CHECK-LABEL: # Machine code for function foo: -; CHECK: SU(2): %w{{[0-9]+}}, %w{{[0-9]+}} = LDPWi +; CHECK: SU(2): renamable %w{{[0-9]+}}, renamable %w{{[0-9]+}} = LDPWi ; CHECK: Successors: ; CHECK-NOT: ch SU(4) ; CHECK: SU(3) -; CHECK: SU(4): STRWui %wzr, %x{{[0-9]+}} +; CHECK: SU(4): STRWui %wzr, renamable %x{{[0-9]+}} define i32 @foo() { entry: %0 = load i32, i32* getelementptr inbounds ([100 x i32], [100 x i32]* @G2, i64 0, i64 0), align 4 diff --git a/test/CodeGen/AMDGPU/shrink-carry.mir b/test/CodeGen/AMDGPU/shrink-carry.mir index cf000ffa774..d499b2192e9 100644 --- a/test/CodeGen/AMDGPU/shrink-carry.mir +++ b/test/CodeGen/AMDGPU/shrink-carry.mir @@ -1,7 +1,7 @@ # RUN: llc -march=amdgcn -verify-machineinstrs -start-before si-shrink-instructions -stop-before si-insert-skips -o - %s | FileCheck -check-prefix=GCN %s # GCN-LABEL: name: subbrev{{$}} -# GCN: V_SUBBREV_U32_e64 0, undef %vgpr0, killed %vcc, implicit %exec +# GCN: V_SUBBREV_U32_e64 0, undef %vgpr0, killed renamable %vcc, implicit %exec --- name: subbrev @@ -25,7 +25,7 @@ body: | ... # GCN-LABEL: name: subb{{$}} -# GCN: V_SUBB_U32_e64 undef %vgpr0, 0, killed %vcc, implicit %exec +# GCN: V_SUBB_U32_e64 undef %vgpr0, 0, killed renamable %vcc, implicit %exec --- name: subb @@ -49,7 +49,7 @@ body: | ... # GCN-LABEL: name: addc{{$}} -# GCN: V_ADDC_U32_e32 0, undef %vgpr0, implicit-def %vcc, implicit killed %vcc, implicit %exec +# GCN: V_ADDC_U32_e32 0, undef renamable %vgpr0, implicit-def %vcc, implicit killed %vcc, implicit %exec --- name: addc @@ -73,7 +73,7 @@ body: | ... # GCN-LABEL: name: addc2{{$}} -# GCN: V_ADDC_U32_e32 0, undef %vgpr0, implicit-def %vcc, implicit killed %vcc, implicit %exec +# GCN: V_ADDC_U32_e32 0, undef renamable %vgpr0, implicit-def %vcc, implicit killed %vcc, implicit %exec --- name: addc2 diff --git a/test/CodeGen/AMDGPU/splitkit.mir b/test/CodeGen/AMDGPU/splitkit.mir index 41782af40e3..45a9c41c381 100644 --- a/test/CodeGen/AMDGPU/splitkit.mir +++ b/test/CodeGen/AMDGPU/splitkit.mir @@ -37,13 +37,13 @@ body: | # CHECK: [[REG0:%sgpr[0-9]+]] = COPY %sgpr0 # CHECK: [[REG1:%sgpr[0-9]+]] = COPY %sgpr2 # CHECK: S_NOP 0 -# CHECK: S_NOP 0, implicit [[REG0]] -# CHECK: S_NOP 0, implicit [[REG1]] -# CHECK: %sgpr0 = COPY [[REG0]] -# CHECK: %sgpr2 = COPY [[REG1]] +# CHECK: S_NOP 0, implicit renamable [[REG0]] +# CHECK: S_NOP 0, implicit renamable [[REG1]] +# CHECK: %sgpr0 = COPY renamable [[REG0]] +# CHECK: %sgpr2 = COPY renamable [[REG1]] # CHECK: S_NOP -# CHECK: S_NOP 0, implicit %sgpr0 -# CHECK: S_NOP 0, implicit %sgpr2 +# CHECK: S_NOP 0, implicit renamable %sgpr0 +# CHECK: S_NOP 0, implicit renamable %sgpr2 name: func1 tracksRegLiveness: true body: | @@ -67,8 +67,8 @@ body: | # Check that copy hoisting out of loops works. This mainly should not crash the # compiler when it hoists a subreg copy sequence. # CHECK-LABEL: name: splitHoist -# CHECK: S_NOP 0, implicit-def %sgpr0 -# CHECK: S_NOP 0, implicit-def %sgpr3 +# CHECK: S_NOP 0, implicit-def renamable %sgpr0 +# CHECK: S_NOP 0, implicit-def renamable %sgpr3 # CHECK-NEXT: SI_SPILL_S128_SAVE name: splitHoist tracksRegLiveness: true diff --git a/test/CodeGen/AMDGPU/stack-slot-color-sgpr-vgpr-spills.mir b/test/CodeGen/AMDGPU/stack-slot-color-sgpr-vgpr-spills.mir index b41e6ac6fd5..d5bf6a1eb8c 100644 --- a/test/CodeGen/AMDGPU/stack-slot-color-sgpr-vgpr-spills.mir +++ b/test/CodeGen/AMDGPU/stack-slot-color-sgpr-vgpr-spills.mir @@ -9,10 +9,10 @@ # CHECK: - { id: 1, name: '', type: spill-slot, offset: 0, size: 4, alignment: 4, # CHECK-NEXT: stack-id: 1, -# CHECK: SI_SPILL_V32_SAVE killed %vgpr0, %stack.0, %sgpr0_sgpr1_sgpr2_sgpr3, %sgpr5, 0, implicit %exec :: (store 4 into %stack.0) +# CHECK: SI_SPILL_V32_SAVE killed renamable %vgpr0, %stack.0, %sgpr0_sgpr1_sgpr2_sgpr3, %sgpr5, 0, implicit %exec :: (store 4 into %stack.0) # CHECK: %vgpr0 = SI_SPILL_V32_RESTORE %stack.0, %sgpr0_sgpr1_sgpr2_sgpr3, %sgpr5, 0, implicit %exec :: (load 4 from %stack.0) -# CHECK: SI_SPILL_S32_SAVE killed %sgpr6, %stack.1, implicit %exec, implicit %sgpr0_sgpr1_sgpr2_sgpr3, implicit %sgpr5, implicit-def dead %m0 :: (store 4 into %stack.1) +# CHECK: SI_SPILL_S32_SAVE killed renamable %sgpr6, %stack.1, implicit %exec, implicit %sgpr0_sgpr1_sgpr2_sgpr3, implicit %sgpr5, implicit-def dead %m0 :: (store 4 into %stack.1) # CHECK: %sgpr6 = SI_SPILL_S32_RESTORE %stack.1, implicit %exec, implicit %sgpr0_sgpr1_sgpr2_sgpr3, implicit %sgpr5, implicit-def dead %m0 :: (load 4 from %stack.1) name: no_merge_sgpr_vgpr_spill_slot diff --git a/test/CodeGen/AMDGPU/subreg_interference.mir b/test/CodeGen/AMDGPU/subreg_interference.mir index 6fc22c8d189..3575e41c2b7 100644 --- a/test/CodeGen/AMDGPU/subreg_interference.mir +++ b/test/CodeGen/AMDGPU/subreg_interference.mir @@ -12,12 +12,12 @@ # sgpr0-sgpr3. # # CHECK-LABEL: func0 -# CHECK: S_NOP 0, implicit-def %sgpr0 -# CHECK: S_NOP 0, implicit-def %sgpr3 -# CHECK: S_NOP 0, implicit-def %sgpr1 -# CHECK: S_NOP 0, implicit-def %sgpr2 -# CHECK: S_NOP 0, implicit %sgpr0, implicit %sgpr3 -# CHECK: S_NOP 0, implicit %sgpr1, implicit %sgpr2 +# CHECK: S_NOP 0, implicit-def renamable %sgpr0 +# CHECK: S_NOP 0, implicit-def renamable %sgpr3 +# CHECK: S_NOP 0, implicit-def renamable %sgpr1 +# CHECK: S_NOP 0, implicit-def renamable %sgpr2 +# CHECK: S_NOP 0, implicit renamable %sgpr0, implicit renamable %sgpr3 +# CHECK: S_NOP 0, implicit renamable %sgpr1, implicit renamable %sgpr2 name: func0 body: | bb.0: diff --git a/test/CodeGen/AMDGPU/syncscopes.ll b/test/CodeGen/AMDGPU/syncscopes.ll index 6e356f69e05..5cea1588d4b 100644 --- a/test/CodeGen/AMDGPU/syncscopes.ll +++ b/test/CodeGen/AMDGPU/syncscopes.ll @@ -1,9 +1,9 @@ ; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx803 -stop-before=si-debugger-insert-nops < %s | FileCheck --check-prefix=GCN %s ; GCN-LABEL: name: syncscopes -; GCN: FLAT_STORE_DWORD killed %vgpr1_vgpr2, killed %vgpr0, 0, 0, 0, implicit %exec, implicit %flat_scr :: (volatile store syncscope("agent") seq_cst 4 into %ir.agent_out) -; GCN: FLAT_STORE_DWORD killed %vgpr4_vgpr5, killed %vgpr3, 0, 0, 0, implicit %exec, implicit %flat_scr :: (volatile store syncscope("workgroup") seq_cst 4 into %ir.workgroup_out) -; GCN: FLAT_STORE_DWORD killed %vgpr7_vgpr8, killed %vgpr6, 0, 0, 0, implicit %exec, implicit %flat_scr :: (volatile store syncscope("wavefront") seq_cst 4 into %ir.wavefront_out) +; GCN: FLAT_STORE_DWORD killed renamable %vgpr1_vgpr2, killed renamable %vgpr0, 0, 0, 0, implicit %exec, implicit %flat_scr :: (volatile store syncscope("agent") seq_cst 4 into %ir.agent_out) +; GCN: FLAT_STORE_DWORD killed renamable %vgpr4_vgpr5, killed renamable %vgpr3, 0, 0, 0, implicit %exec, implicit %flat_scr :: (volatile store syncscope("workgroup") seq_cst 4 into %ir.workgroup_out) +; GCN: FLAT_STORE_DWORD killed renamable %vgpr7_vgpr8, killed renamable %vgpr6, 0, 0, 0, implicit %exec, implicit %flat_scr :: (volatile store syncscope("wavefront") seq_cst 4 into %ir.wavefront_out) define void @syncscopes( i32 %agent, i32 addrspace(4)* %agent_out, diff --git a/test/CodeGen/Hexagon/regalloc-bad-undef.mir b/test/CodeGen/Hexagon/regalloc-bad-undef.mir index 7e18011a523..720f504098d 100644 --- a/test/CodeGen/Hexagon/regalloc-bad-undef.mir +++ b/test/CodeGen/Hexagon/regalloc-bad-undef.mir @@ -153,7 +153,7 @@ body: | %13 = S2_asl_r_p_acc %13, %47, %8.isub_lo %51 = A2_tfrpi 0 - ; CHECK: %d2 = S2_extractup undef %d0, 6, 25 + ; CHECK: %d2 = S2_extractup undef renamable %d0, 6, 25 ; CHECK: %d0 = A2_tfrpi 2 ; CHECK: %d13 = A2_tfrpi -1 ; CHECK-NOT: undef %r4 diff --git a/test/CodeGen/MIR/X86/renamable-register-flag.mir b/test/CodeGen/MIR/X86/renamable-register-flag.mir new file mode 100644 index 00000000000..3854a2877c0 --- /dev/null +++ b/test/CodeGen/MIR/X86/renamable-register-flag.mir @@ -0,0 +1,16 @@ +# RUN: llc -march=x86-64 -run-pass none -o - %s | FileCheck %s +# This test ensures that the MIR parser parses the 'renamable' register flags +# correctly. + +--- | + define void @foo() { ret void } +... +--- +name: foo +body: | + ; CHECK: bb.0: + bb.0: + ; CHECK: renamable %eax = IMUL32rri8 %edi, 11, implicit-def dead %eflags + renamable %eax = IMUL32rri8 %edi, 11, implicit-def dead %eflags + RETQ %eax +... diff --git a/test/CodeGen/PowerPC/byval-agg-info.ll b/test/CodeGen/PowerPC/byval-agg-info.ll index 141edb57967..6e0b167757f 100644 --- a/test/CodeGen/PowerPC/byval-agg-info.ll +++ b/test/CodeGen/PowerPC/byval-agg-info.ll @@ -13,5 +13,5 @@ entry: ; Make sure that the MMO on the store has no offset from the byval ; variable itself (we used to have mem:ST8[%v+64]). -; CHECK: STD killed %x5, 176, %x1; mem:ST8[%v](align=16) +; CHECK: STD killed renamable %x5, 176, %x1; mem:ST8[%v](align=16) diff --git a/test/CodeGen/SystemZ/regalloc-fast-invalid-kill-flag.mir b/test/CodeGen/SystemZ/regalloc-fast-invalid-kill-flag.mir index 8bf2b5575e8..29173d1274c 100644 --- a/test/CodeGen/SystemZ/regalloc-fast-invalid-kill-flag.mir +++ b/test/CodeGen/SystemZ/regalloc-fast-invalid-kill-flag.mir @@ -18,11 +18,11 @@ registers: - { id: 1, class: gr64bit } - { id: 2, class: addr64bit } # CHECK: %r0q = L128 -# CHECK-NEXT: %r0l = COPY %r1l +# CHECK-NEXT: %r0l = COPY renamable %r1l # Although R0L partially redefines R0Q, it must not mark R0Q as kill # because R1D is still live through that instruction. # CHECK-NOT: implicit killed %r0q -# CHECK-NEXT: %r2d = COPY %r1d +# CHECK-NEXT: %r2d = COPY renamable %r1d # CHECK-NEXT: LARL body: | bb.0: diff --git a/test/CodeGen/X86/tail-merge-debugloc.ll b/test/CodeGen/X86/tail-merge-debugloc.ll index 197b0b80325..85ba0ab6261 100644 --- a/test/CodeGen/X86/tail-merge-debugloc.ll +++ b/test/CodeGen/X86/tail-merge-debugloc.ll @@ -6,7 +6,7 @@ ; location info. ; ; CHECK: [[DLOC:![0-9]+]] = !DILocation(line: 2, column: 2, scope: !{{[0-9]+}}) -; CHECK: TEST64rr{{.*}}%rsi, %rsi, implicit-def %eflags +; CHECK: TEST64rr{{.*}}%rsi, renamable %rsi, implicit-def %eflags ; CHECK-NEXT: JNE_1{{.*}}, debug-location [[DLOC]] target triple = "x86_64-unknown-linux-gnu" diff --git a/test/DebugInfo/X86/pr34545.ll b/test/DebugInfo/X86/pr34545.ll index 0a97f210107..07e80f48c3d 100644 --- a/test/DebugInfo/X86/pr34545.ll +++ b/test/DebugInfo/X86/pr34545.ll @@ -2,11 +2,11 @@ ; CHECK: %eax = MOV32rm ; CHECK: DBG_VALUE %eax -; CHECK: %eax = SHL32rCL killed %eax +; CHECK: %eax = SHL32rCL killed renamable %eax ; CHECK: DBG_VALUE %eax ; CHECK: DBG_VALUE %rsp, 0, !{{[0-9]+}}, !DIExpression(DW_OP_constu, 4, DW_OP_minus) ; CHECK: DBG_VALUE %eax -; CHECK: %eax = SHL32rCL killed %eax +; CHECK: %eax = SHL32rCL killed renamable %eax ; CHECK: DBG_VALUE %eax ; CHECK: RETQ %eax diff --git a/test/DebugInfo/X86/sdag-salvage-add.ll b/test/DebugInfo/X86/sdag-salvage-add.ll index 8a2a63420b4..1b1f86f1cd7 100644 --- a/test/DebugInfo/X86/sdag-salvage-add.ll +++ b/test/DebugInfo/X86/sdag-salvage-add.ll @@ -28,7 +28,7 @@ ; CHECK-SAME: !DIExpression(DW_OP_plus_uconst, 4096, DW_OP_stack_value) ; CHECK-NEXT: DBG_VALUE debug-use %rax, debug-use %noreg, ![[S4]], ; CHECK-SAME: !DIExpression(DW_OP_plus_uconst, 4096, DW_OP_stack_value) -; CHECK-NEXT: %rdi = MOV64rm killed %rax, 1, %noreg, 4096, %noreg, +; CHECK-NEXT: %rdi = MOV64rm killed renamable %rax, 1, %noreg, 4096, %noreg, source_filename = "test.c" target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" -- 2.11.0