Index: lib/CodeGen/InlineSpiller.cpp =================================================================== --- lib/CodeGen/InlineSpiller.cpp +++ lib/CodeGen/InlineSpiller.cpp @@ -984,6 +984,14 @@ if (!OpPair.first->isRegTiedToDefOperand(OpPair.second)) MO.setIsKill(); } else { + // For bundled instructions: Only examine defs in the BUNDLE + // instruction itself if it exists. + MachineInstr *DefMI = OpPair.first; + if (DefMI->isBundled() && + getBundleStart(DefMI->getIterator())->isBundle() && + !DefMI->isBundle()) + continue; + if (!MO.isDead()) hasLiveDef = true; } Index: test/CodeGen/MIR/AArch64/spill-dead-bundle.mir =================================================================== --- /dev/null +++ test/CodeGen/MIR/AArch64/spill-dead-bundle.mir @@ -0,0 +1,36 @@ +# RUN: llc -mtriple=aarch64-none-linux-gnu -run-pass=greedy -verify-regalloc -o - %s | FileCheck %s +--- +name: test +tracksRegLiveness: true +registers: + - { id: 0, class: gpr64 } + - { id: 1, class: gpr64 } +liveins: + - { reg: '%x0' } +body: | + bb.0: + liveins: %x0 + + %0 = COPY %x0 + + INLINEASM $nop, 1, 12, implicit-def dead %x0, 12, implicit-def dead %x1, 12, implicit-def dead %x2, 12, implicit-def dead %x3, 12, implicit-def dead %x4, 12, implicit-def dead %x5, 12, implicit-def dead %x6, 12, implicit-def dead %x7, 12, implicit-def dead %x8, 12, implicit-def dead %x9, 12, implicit-def dead %x10, 12, implicit-def dead %x11, 12, implicit-def dead %x12, 12, implicit-def dead %x13, 12, implicit-def dead %x14, 12, implicit-def dead %x15, 12, implicit-def dead %x16, 12, implicit-def dead %x17, 12, implicit-def dead %x18, 12, implicit-def dead %x19, 12, implicit-def dead %x20, 12, implicit-def dead %x21, 12, implicit-def dead %x22, 12, implicit-def dead %x23, 12, implicit-def dead %x24, 12, implicit-def dead %x25, 12, implicit-def dead %x26, 12, implicit-def dead %x27, 12, implicit-def dead %x28, 12, implicit-def dead %fp, 12, implicit-def dead %lr, 12, implicit-def %sp + + BUNDLE implicit-def dead %0, implicit-def %1, implicit %0 { + %0.sub_32 = COPY undef %wzr + %1 = COPY %0 + } +... + +# Force spill of %0 by destroying all registers with the nop. + +# The def of %0.sub_32 has no use outside of the BUNDLE and the implicit def of +# %0 is marked dead, so there should be no spill of %0 after the BUNDLE. + +# CHECK: STRXui %x0, %stack.0 +# CHECK-NEXT: INLINEASM $nop +# CHECK-NEXT: %2 = LDRXui %stack.0 +# CHECK-NEXT: BUNDLE implicit-def dead %2, implicit-def dead %1, implicit %2 { +# CHECK-NEXT: %2.sub_32 = COPY undef %wzr +# CHECK-NEXT: %1 = COPY %2 +# CHECK-NEXT: } +# CHECK-NOT: STRXui