From 9cec2b246e719533723562950e56c292fe5dd5ad Mon Sep 17 00:00:00 2001 From: Nick Desaulniers Date: Wed, 1 Mar 2023 15:20:55 -0800 Subject: [PATCH] [RegAllocFast] insert additional spills along indirect edges of INLINEASM_BR When generating spills (stores) for values produced by INLINEASM_BR instructions, make sure to insert one spill per indirect target. Otherwise the reload generated may load from a stack slot that has not yet been stored to (resulting in a load of an uninitialized stack slot). Link: https://github.com/llvm/llvm-project/issues/53562 Fixes: https://github.com/llvm/llvm-project/issues/60855 Reviewed By: MatzeB Differential Revision: https://reviews.llvm.org/D144907 --- llvm/lib/CodeGen/RegAllocFast.cpp | 17 +++++++++++++++++ .../CodeGen/X86/callbr-asm-outputs-regallocfast.mir | 3 ++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/llvm/lib/CodeGen/RegAllocFast.cpp b/llvm/lib/CodeGen/RegAllocFast.cpp index 775e66e..613e146 100644 --- a/llvm/lib/CodeGen/RegAllocFast.cpp +++ b/llvm/lib/CodeGen/RegAllocFast.cpp @@ -948,6 +948,23 @@ void RegAllocFast::defineVirtReg(MachineInstr &MI, unsigned OpNum, << 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 index db7b249..6417538 100644 --- a/llvm/test/CodeGen/X86/callbr-asm-outputs-regallocfast.mir +++ b/llvm/test/CodeGen/X86/callbr-asm-outputs-regallocfast.mir @@ -135,8 +135,9 @@ body: | ; 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 -- 2.7.4