diff --git a/llvm/include/llvm/CodeGen/MachineBasicBlock.h b/llvm/include/llvm/CodeGen/MachineBasicBlock.h index 9e3d9196cc184..94139b64a3e30 100644 --- a/llvm/include/llvm/CodeGen/MachineBasicBlock.h +++ b/llvm/include/llvm/CodeGen/MachineBasicBlock.h @@ -553,8 +553,8 @@ class MachineBasicBlock LiveRegI = (*BlockI)->livein_begin(); if (!advanceToValidPosition()) return; - if (LiveRegI->PhysReg == ExceptionPointer || - LiveRegI->PhysReg == ExceptionSelector) + if ((*BlockI)->isEHPad() && (LiveRegI->PhysReg == ExceptionPointer || + LiveRegI->PhysReg == ExceptionSelector)) ++(*this); } } diff --git a/llvm/lib/CodeGen/LiveRegUnits.cpp b/llvm/lib/CodeGen/LiveRegUnits.cpp index 34de09dd2944b..d9c56b87a6bf4 100644 --- a/llvm/lib/CodeGen/LiveRegUnits.cpp +++ b/llvm/lib/CodeGen/LiveRegUnits.cpp @@ -91,6 +91,13 @@ static void addBlockLiveIns(LiveRegUnits &LiveUnits, LiveUnits.addRegMasked(LI.PhysReg, LI.LaneMask); } +/// Add live-out registers of basic block \p MBB to \p LiveUnits. +static void addBlockLiveOuts(LiveRegUnits &LiveUnits, + const MachineBasicBlock &MBB) { + for (const auto &LI : MBB.liveouts()) + LiveUnits.addRegMasked(LI.PhysReg, LI.LaneMask); +} + /// Adds all callee saved registers to \p LiveUnits. static void addCalleeSavedRegs(LiveRegUnits &LiveUnits, const MachineFunction &MF) { @@ -137,12 +144,8 @@ void LiveRegUnits::addPristines(const MachineFunction &MF) { void LiveRegUnits::addLiveOuts(const MachineBasicBlock &MBB) { const MachineFunction &MF = *MBB.getParent(); - addPristines(MF); - - // To get the live-outs we simply merge the live-ins of all successors. - for (const MachineBasicBlock *Succ : MBB.successors()) - addBlockLiveIns(*this, *Succ); + addBlockLiveOuts(*this, MBB); // For the return block: Add all callee saved registers. if (MBB.isReturnBlock()) { diff --git a/llvm/lib/CodeGen/MachineBasicBlock.cpp b/llvm/lib/CodeGen/MachineBasicBlock.cpp index c3c5a0f5102d7..08a51b9b0242a 100644 --- a/llvm/lib/CodeGen/MachineBasicBlock.cpp +++ b/llvm/lib/CodeGen/MachineBasicBlock.cpp @@ -1781,9 +1781,6 @@ MachineBasicBlock::livein_iterator MachineBasicBlock::livein_begin() const { MachineBasicBlock::liveout_iterator MachineBasicBlock::liveout_begin() const { const MachineFunction &MF = *getParent(); - assert(MF.getProperties().hasTracksLiveness() && - "Liveness information is accurate"); - const TargetLowering &TLI = *MF.getSubtarget().getTargetLowering(); MCRegister ExceptionPointer, ExceptionSelector; if (MF.getFunction().hasPersonalityFn()) { diff --git a/llvm/test/CodeGen/AArch64/sme-abi-eh-liveins.mir b/llvm/test/CodeGen/AArch64/sme-abi-eh-liveins.mir new file mode 100644 index 0000000000000..711745e528bbf --- /dev/null +++ b/llvm/test/CodeGen/AArch64/sme-abi-eh-liveins.mir @@ -0,0 +1,82 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5 +# RUN: llc -mtriple=aarch64 -mattr=+sve -mattr=+sme -run-pass=aarch64-machine-sme-abi -verify-machineinstrs %s -o - | FileCheck %s + +# This test verifies that runtime defined live-ins are not included in the live +# outs of predecessors in the MachineSMEABIPass, as including them would result +# in copies of undefined registers. + +--- | + define void @sme_abi_eh_liveins() "aarch64_inout_za" personality ptr @__gxx_personality_v0 { entry: unreachable } + + declare i32 @__gxx_personality_v0(...) +... +--- +name: sme_abi_eh_liveins +tracksRegLiveness: true +isSSA: true +noVRegs: false + +body: | + ; CHECK-LABEL: name: sme_abi_eh_liveins + ; CHECK: bb.0: + ; CHECK-NEXT: successors: %bb.2(0x00000000), %bb.1(0x80000000) + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[RDSVLI_XI:%[0-9]+]]:gpr64 = RDSVLI_XI 1, implicit $vg + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $sp + ; CHECK-NEXT: [[MSUBXrrr:%[0-9]+]]:gpr64 = MSUBXrrr [[RDSVLI_XI]], [[RDSVLI_XI]], [[COPY]] + ; CHECK-NEXT: $sp = COPY [[MSUBXrrr]] + ; CHECK-NEXT: STPXi [[MSUBXrrr]], [[RDSVLI_XI]], %stack.0, 0 + ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp + ; CHECK-NEXT: InOutZAUsePseudo + ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp + ; CHECK-NEXT: [[ADDXri:%[0-9]+]]:gpr64sp = ADDXri %stack.0, 0, 0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64 = COPY [[ADDXri]] + ; CHECK-NEXT: MSR 56965, [[COPY1]] + ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp + ; CHECK-NEXT: RequiresZASavePseudo + ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp + ; CHECK-NEXT: MSRpstatesvcrImm1 2, 1, implicit-def $nzcv + ; CHECK-NEXT: [[MRS:%[0-9]+]]:gpr64 = MRS 56965, implicit-def $nzcv + ; CHECK-NEXT: $x0 = ADDXri %stack.0, 0, 0 + ; CHECK-NEXT: RestoreZAPseudo [[MRS]], $x0, &__arm_tpidr2_restore, csr_aarch64_sme_abi_support_routines_preservemost_from_x0 + ; CHECK-NEXT: MSR 56965, $xzr + ; CHECK-NEXT: B %bb.2 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: bb.1 (landing-pad): + ; CHECK-NEXT: successors: %bb.2(0x80000000) + ; CHECK-NEXT: liveins: $x0, $x1 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: MSRpstatesvcrImm1 2, 1, implicit-def $nzcv + ; CHECK-NEXT: [[MRS1:%[0-9]+]]:gpr64 = MRS 56965, implicit-def $nzcv + ; CHECK-NEXT: $x0 = ADDXri %stack.0, 0, 0 + ; CHECK-NEXT: RestoreZAPseudo [[MRS1]], $x0, &__arm_tpidr2_restore, csr_aarch64_sme_abi_support_routines_preservemost_from_x0 + ; CHECK-NEXT: MSR 56965, $xzr + ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp + ; CHECK-NEXT: InOutZAUsePseudo + ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: bb.2: + bb.0: + successors: %bb.2(0x00000000), %bb.1(0x80000000) + + ; Simulate shared ZA call + ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp + InOutZAUsePseudo + ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp + + ; Simulate private ZA call at the end of the block + ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp + RequiresZASavePseudo + ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp + + B %bb.2 + + bb.1 (landing-pad): + liveins: $x0, $x1 + + ; Simulate shared ZA call + ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp + InOutZAUsePseudo + ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp + + bb.2: diff --git a/llvm/test/CodeGen/AArch64/sme-za-exceptions.ll b/llvm/test/CodeGen/AArch64/sme-za-exceptions.ll index 7a3e246b530b0..bb88142efa592 100644 --- a/llvm/test/CodeGen/AArch64/sme-za-exceptions.ll +++ b/llvm/test/CodeGen/AArch64/sme-za-exceptions.ll @@ -1,9 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 ; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sme -aarch64-new-sme-abi -verify-machineinstrs < %s | FileCheck %s -; FIXME: XFAILs until https://github.com/llvm/llvm-project/pull/154325 -; XFAIL: * - ; A simple EH test case that corresponds to the following C++ source: ; ; struct ZAResource { @@ -65,16 +62,14 @@ define void @za_with_raii(i1 %fail) "aarch64_inout_za" personality ptr @__gxx_pe ; CHECK-NEXT: ldr x1, [x1, :got_lo12:typeinfo_for_char_const_ptr] ; CHECK-NEXT: bl __cxa_throw ; CHECK-NEXT: .Ltmp1: -; CHECK-NEXT: mov x8, x0 ; CHECK-NEXT: smstart za -; CHECK-NEXT: mrs x9, TPIDR2_EL0 +; CHECK-NEXT: mrs x8, TPIDR2_EL0 ; CHECK-NEXT: sub x0, x29, #16 -; CHECK-NEXT: cbnz x9, .LBB0_4 +; CHECK-NEXT: cbnz x8, .LBB0_4 ; CHECK-NEXT: // %bb.3: // %throw_exception ; CHECK-NEXT: bl __arm_tpidr2_restore ; CHECK-NEXT: .LBB0_4: // %throw_exception ; CHECK-NEXT: msr TPIDR2_EL0, xzr -; CHECK-NEXT: // kill: def $x0 killed $x8 ; CHECK-NEXT: // %bb.5: // %throw_fail ; CHECK-NEXT: .LBB0_6: // %unwind_dtors ; CHECK-NEXT: .Ltmp2: