diff --git a/llvm/lib/CodeGen/RegAllocFast.cpp b/llvm/lib/CodeGen/RegAllocFast.cpp --- a/llvm/lib/CodeGen/RegAllocFast.cpp +++ b/llvm/lib/CodeGen/RegAllocFast.cpp @@ -948,6 +948,23 @@ << LRI->Reloaded << '\n'); bool Kill = LRI->LastUse == nullptr; spill(SpillBefore, VirtReg, PhysReg, Kill, LRI->LiveOut); + + // We need to place additional spills for each indirect destination of an + // INLINEASM_BR. + if (MI.getOpcode() == TargetOpcode::INLINEASM_BR) { + int FI = StackSlotForVirtReg[VirtReg]; + const TargetRegisterClass &RC = *MRI->getRegClass(VirtReg); + for (MachineOperand &MO : MI.operands()) { + if (MO.isMBB()) { + MachineBasicBlock *Succ = MO.getMBB(); + TII->storeRegToStackSlot(*Succ, Succ->begin(), PhysReg, Kill, + FI, &RC, TRI, VirtReg); + ++NumStores; + Succ->addLiveIn(PhysReg); + } + } + } + LRI->LastUse = nullptr; } LRI->LiveOut = false; diff --git a/llvm/test/CodeGen/X86/callbr-asm-outputs-regallocfast.mir b/llvm/test/CodeGen/X86/callbr-asm-outputs-regallocfast.mir --- a/llvm/test/CodeGen/X86/callbr-asm-outputs-regallocfast.mir +++ b/llvm/test/CodeGen/X86/callbr-asm-outputs-regallocfast.mir @@ -135,8 +135,9 @@ ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.3.label.split (machine-block-address-taken, inlineasm-br-indirect-target): ; CHECK-NEXT: successors: %bb.2(0x80000000) + ; CHECK-NEXT: liveins: $eax ; CHECK-NEXT: {{ $}} - ; FIXME: this is a load from a stack slot that hasn't been stored to yet! + ; CHECK-NEXT: MOV32mr %stack.3, 1, $noreg, 0, $noreg, $eax :: (store (s32) into %stack.3) ; CHECK-NEXT: $eax = MOV32rm %stack.3, 1, $noreg, 0, $noreg :: (load (s32) from %stack.3) ; CHECK-NEXT: MOV32mr %stack.1.x, 1, $noreg, 0, $noreg, killed renamable $eax :: (store (s32) into %ir.x) ; CHECK-NEXT: JMP_1 %bb.2