Index: lib/Target/AArch64/AArch64ISelLowering.cpp =================================================================== --- lib/Target/AArch64/AArch64ISelLowering.cpp +++ lib/Target/AArch64/AArch64ISelLowering.cpp @@ -10592,13 +10592,7 @@ MachineRegisterInfo *MRI = &Entry->getParent()->getRegInfo(); MachineBasicBlock::iterator MBBI = Entry->begin(); for (const MCPhysReg *I = IStart; *I; ++I) { - const TargetRegisterClass *RC = nullptr; - if (AArch64::GPR64RegClass.contains(*I)) - RC = &AArch64::GPR64RegClass; - else if (AArch64::FPR64RegClass.contains(*I)) - RC = &AArch64::FPR64RegClass; - else - llvm_unreachable("Unexpected register class in CSRsViaCopy!"); + const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(*I); unsigned NewVR = MRI->createVirtualRegister(RC); // Create copy from CSR to a virtual register. Index: lib/Target/ARM/ARMBaseRegisterInfo.cpp =================================================================== --- lib/Target/ARM/ARMBaseRegisterInfo.cpp +++ lib/Target/ARM/ARMBaseRegisterInfo.cpp @@ -749,6 +749,10 @@ Done = rewriteARMFrameIndex(MI, FIOperandNum, FrameReg, Offset, TII); else { assert(AFI->isThumb2Function()); + MI.dump(); + dbgs() << FIOperandNum << "\n"; + dbgs() << FrameReg << "\n"; + dbgs() << Offset << "\n"; Done = rewriteT2FrameIndex(MI, FIOperandNum, FrameReg, Offset, TII); } if (Done) Index: lib/Target/ARM/ARMISelLowering.cpp =================================================================== --- lib/Target/ARM/ARMISelLowering.cpp +++ lib/Target/ARM/ARMISelLowering.cpp @@ -13364,13 +13364,8 @@ MachineRegisterInfo *MRI = &Entry->getParent()->getRegInfo(); MachineBasicBlock::iterator MBBI = Entry->begin(); for (const MCPhysReg *I = IStart; *I; ++I) { - const TargetRegisterClass *RC = nullptr; - if (ARM::GPRRegClass.contains(*I)) - RC = &ARM::GPRRegClass; - else if (ARM::DPRRegClass.contains(*I)) - RC = &ARM::DPRRegClass; - else - llvm_unreachable("Unexpected register class in CSRsViaCopy!"); + const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(*I); + assert(RC); unsigned NewVR = MRI->createVirtualRegister(RC); // Create copy from CSR to a virtual register. @@ -13383,7 +13378,7 @@ "Function should be nounwind in insertCopiesSplitCSR!"); Entry->addLiveIn(*I); BuildMI(*Entry, MBBI, DebugLoc(), TII->get(TargetOpcode::COPY), NewVR) - .addReg(*I); + .addReg(*I)->dump(); // Insert the copy-back instructions right before the terminator. for (auto *Exit : Exits) Index: lib/Target/ARM/Thumb2InstrInfo.cpp =================================================================== --- lib/Target/ARM/Thumb2InstrInfo.cpp +++ lib/Target/ARM/Thumb2InstrInfo.cpp @@ -586,7 +586,7 @@ Scale = 1; assert((Offset & 3) == 0 && "Can't encode this offset!"); } else { - llvm_unreachable("Unsupported addressing mode!"); + return false; } if (NewOpc != Opcode) Index: lib/Target/PowerPC/PPCISelLowering.cpp =================================================================== --- lib/Target/PowerPC/PPCISelLowering.cpp +++ lib/Target/PowerPC/PPCISelLowering.cpp @@ -12701,17 +12701,7 @@ MachineRegisterInfo *MRI = &Entry->getParent()->getRegInfo(); MachineBasicBlock::iterator MBBI = Entry->begin(); for (const MCPhysReg *I = IStart; *I; ++I) { - const TargetRegisterClass *RC = nullptr; - if (PPC::G8RCRegClass.contains(*I)) - RC = &PPC::G8RCRegClass; - else if (PPC::F8RCRegClass.contains(*I)) - RC = &PPC::F8RCRegClass; - else if (PPC::CRRCRegClass.contains(*I)) - RC = &PPC::CRRCRegClass; - else if (PPC::VRRCRegClass.contains(*I)) - RC = &PPC::VRRCRegClass; - else - llvm_unreachable("Unexpected register class in CSRsViaCopy!"); + const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(*I); unsigned NewVR = MRI->createVirtualRegister(RC); // Create copy from CSR to a virtual register. Index: lib/Target/X86/X86ISelLowering.h =================================================================== --- lib/Target/X86/X86ISelLowering.h +++ lib/Target/X86/X86ISelLowering.h @@ -1169,10 +1169,7 @@ const SmallVectorImpl &OutVals, const SDLoc &dl, SelectionDAG &DAG) const override; - bool supportSplitCSR(MachineFunction *MF) const override { - return MF->getFunction()->getCallingConv() == CallingConv::CXX_FAST_TLS && - MF->getFunction()->hasFnAttribute(Attribute::NoUnwind); - } + bool supportSplitCSR(MachineFunction *MF) const override; void initializeSplitCSR(MachineBasicBlock *Entry) const override; void insertCopiesSplitCSR( MachineBasicBlock *Entry, Index: lib/Target/X86/X86ISelLowering.cpp =================================================================== --- lib/Target/X86/X86ISelLowering.cpp +++ lib/Target/X86/X86ISelLowering.cpp @@ -33762,10 +33762,25 @@ return OptSize && !VT.isVector(); } -void X86TargetLowering::initializeSplitCSR(MachineBasicBlock *Entry) const { +bool X86TargetLowering::supportSplitCSR(MachineFunction *MF) const { + // Why is this requirement here? if (!Subtarget.is64Bit()) - return; + return false; + + // TODO: SplitCSR does not support CFI at this time. + if (MF->getTarget().getMCAsmInfo()->usesWindowsCFI() || + !MF->getFunction()->hasFnAttribute(Attribute::NoUnwind) || + MF->getMMI().hasDebugInfo()) + return false; + // This check is probably no longer needed; it was left to avoid mixing + // semantic and non-semantic changes. TODO: consider removing this + return MF->getFunction()->getCallingConv() == CallingConv::CXX_FAST_TLS; +} + +void X86TargetLowering::initializeSplitCSR(MachineBasicBlock *Entry) const { + assert(supportSplitCSR(Entry->getParent())); + // Update IsSplitCSR in X86MachineFunctionInfo. X86MachineFunctionInfo *AFI = Entry->getParent()->getInfo(); @@ -33775,8 +33790,11 @@ void X86TargetLowering::insertCopiesSplitCSR( MachineBasicBlock *Entry, const SmallVectorImpl &Exits) const { + MachineFunction *MF = Entry->getParent(); + assert(supportSplitCSR(MF)); + const X86RegisterInfo *TRI = Subtarget.getRegisterInfo(); - const MCPhysReg *IStart = TRI->getCalleeSavedRegsViaCopy(Entry->getParent()); + const MCPhysReg *IStart = TRI->getCalleeSavedRegsViaCopy(MF); if (!IStart) return; @@ -33784,20 +33802,16 @@ MachineRegisterInfo *MRI = &Entry->getParent()->getRegInfo(); MachineBasicBlock::iterator MBBI = Entry->begin(); for (const MCPhysReg *I = IStart; *I; ++I) { - const TargetRegisterClass *RC = nullptr; - if (X86::GR64RegClass.contains(*I)) - RC = &X86::GR64RegClass; - else - llvm_unreachable("Unexpected register class in CSRsViaCopy!"); - - unsigned NewVR = MRI->createVirtualRegister(RC); + const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(*I); + const unsigned NewVR = MRI->createVirtualRegister(RC); // Create copy from CSR to a virtual register. // FIXME: this currently does not emit CFI pseudo-instructions, it works // fine for CXX_FAST_TLS since the C++-style TLS access functions should be // nounwind. If we want to generalize this later, we may need to emit // CFI pseudo-instructions. - assert(Entry->getParent()->getFunction()->hasFnAttribute( - Attribute::NoUnwind) && + // TODO: factor this out into a more precise check: see the logic in + // X86FrameLowering.cpp around windows, dwarf, etc.. + assert(MF->getFunction()->hasFnAttribute(Attribute::NoUnwind) && "Function should be nounwind in insertCopiesSplitCSR!"); Entry->addLiveIn(*I); BuildMI(*Entry, MBBI, DebugLoc(), TII->get(TargetOpcode::COPY), NewVR)