Skip to content

Commit e809e3b

Browse files
committed
[AArch64][SME] Exclude runtime defined liveins when computing liveouts
These liveins are not defined by predecessors, so attempting to preserve them results in generating invalid MIR (as the registers may not be defined). This takes a similar approach to: c1dc267
1 parent 46e77eb commit e809e3b

File tree

5 files changed

+113
-14
lines changed

5 files changed

+113
-14
lines changed

llvm/include/llvm/CodeGen/LiveRegUnits.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ namespace llvm {
2626

2727
class MachineInstr;
2828
class MachineBasicBlock;
29+
class TargetLowering;
2930

3031
/// A set of register units used to track register liveness.
3132
class LiveRegUnits {
@@ -135,8 +136,11 @@ class LiveRegUnits {
135136
/// Adds registers living out of block \p MBB.
136137
/// Live out registers are the union of the live-in registers of the successor
137138
/// blocks and pristine registers. Live out registers of the end block are the
138-
/// callee saved registers.
139-
LLVM_ABI void addLiveOuts(const MachineBasicBlock &MBB);
139+
/// callee saved registers. If the target lowering information \p TLI is
140+
/// provided, runtime-defined live ins of successors will be excluded from the
141+
/// live outs.
142+
LLVM_ABI void addLiveOuts(const MachineBasicBlock &MBB,
143+
const TargetLowering *TLI = nullptr);
140144

141145
/// Adds registers living into block \p MBB.
142146
LLVM_ABI void addLiveIns(const MachineBasicBlock &MBB);

llvm/lib/CodeGen/LiveRegUnits.cpp

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "llvm/CodeGen/MachineFunction.h"
1717
#include "llvm/CodeGen/MachineOperand.h"
1818
#include "llvm/CodeGen/MachineRegisterInfo.h"
19+
#include "llvm/CodeGen/TargetLowering.h"
1920

2021
using namespace llvm;
2122

@@ -86,9 +87,15 @@ void LiveRegUnits::accumulate(const MachineInstr &MI) {
8687

8788
/// Add live-in registers of basic block \p MBB to \p LiveUnits.
8889
static void addBlockLiveIns(LiveRegUnits &LiveUnits,
89-
const MachineBasicBlock &MBB) {
90-
for (const auto &LI : MBB.liveins())
90+
const MachineBasicBlock &MBB,
91+
MCPhysReg ExceptionPointer = {},
92+
MCPhysReg ExceptionSelector = {}) {
93+
for (const auto &LI : MBB.liveins()) {
94+
if (MBB.isEHPad() &&
95+
(LI.PhysReg == ExceptionPointer || LI.PhysReg == ExceptionSelector))
96+
continue;
9197
LiveUnits.addRegMasked(LI.PhysReg, LI.LaneMask);
98+
}
9299
}
93100

94101
/// Adds all callee saved registers to \p LiveUnits.
@@ -135,14 +142,25 @@ void LiveRegUnits::addPristines(const MachineFunction &MF) {
135142
addUnits(Pristine.getBitVector());
136143
}
137144

138-
void LiveRegUnits::addLiveOuts(const MachineBasicBlock &MBB) {
145+
void LiveRegUnits::addLiveOuts(const MachineBasicBlock &MBB,
146+
const TargetLowering *TLI) {
139147
const MachineFunction &MF = *MBB.getParent();
140148

141149
addPristines(MF);
142150

151+
MCPhysReg ExceptionPointer;
152+
MCPhysReg ExceptionSelector;
153+
154+
// Remove live-ins from successors that are defined by the runtime.
155+
if (TLI && MF.getFunction().hasPersonalityFn()) {
156+
auto PersonalityFn = MF.getFunction().getPersonalityFn();
157+
ExceptionPointer = TLI->getExceptionPointerRegister(PersonalityFn);
158+
ExceptionSelector = TLI->getExceptionSelectorRegister(PersonalityFn);
159+
}
160+
143161
// To get the live-outs we simply merge the live-ins of all successors.
144162
for (const MachineBasicBlock *Succ : MBB.successors())
145-
addBlockLiveIns(*this, *Succ);
163+
addBlockLiveIns(*this, *Succ, ExceptionPointer, ExceptionSelector);
146164

147165
// For the return block: Add all callee saved registers.
148166
if (MBB.isReturnBlock()) {

llvm/lib/Target/AArch64/MachineSMEABIPass.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ void MachineSMEABI::collectNeededZAStates(SMEAttrs SMEFnAttrs) {
277277
}
278278

279279
LiveRegUnits LiveUnits(*TRI);
280-
LiveUnits.addLiveOuts(MBB);
280+
LiveUnits.addLiveOuts(MBB, Subtarget->getTargetLowering());
281281

282282
auto GetPhysLiveRegs = [&] {
283283
LiveRegs PhysLiveRegs = LiveRegs::None;
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
2+
# RUN: llc -mtriple=aarch64 -mattr=+sve -mattr=+sme -run-pass=aarch64-machine-sme-abi -verify-machineinstrs %s -o - | FileCheck %s
3+
4+
# This test verifies that runtime defined live-ins are not included in the live
5+
# outs of predecessors in the MachineSMEABIPass, as including them would result
6+
# in copies of undefined registers.
7+
8+
--- |
9+
define void @sme_abi_eh_liveins() "aarch64_inout_za" personality ptr @__gxx_personality_v0 { entry: unreachable }
10+
11+
declare i32 @__gxx_personality_v0(...)
12+
...
13+
---
14+
name: sme_abi_eh_liveins
15+
tracksRegLiveness: true
16+
isSSA: true
17+
noVRegs: false
18+
19+
body: |
20+
; CHECK-LABEL: name: sme_abi_eh_liveins
21+
; CHECK: bb.0:
22+
; CHECK-NEXT: successors: %bb.2(0x00000000), %bb.1(0x80000000)
23+
; CHECK-NEXT: {{ $}}
24+
; CHECK-NEXT: [[RDSVLI_XI:%[0-9]+]]:gpr64 = RDSVLI_XI 1, implicit $vg
25+
; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $sp
26+
; CHECK-NEXT: [[MSUBXrrr:%[0-9]+]]:gpr64 = MSUBXrrr [[RDSVLI_XI]], [[RDSVLI_XI]], [[COPY]]
27+
; CHECK-NEXT: $sp = COPY [[MSUBXrrr]]
28+
; CHECK-NEXT: STPXi [[MSUBXrrr]], [[RDSVLI_XI]], %stack.0, 0
29+
; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp
30+
; CHECK-NEXT: InOutZAUsePseudo
31+
; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp
32+
; CHECK-NEXT: [[ADDXri:%[0-9]+]]:gpr64sp = ADDXri %stack.0, 0, 0
33+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64 = COPY [[ADDXri]]
34+
; CHECK-NEXT: MSR 56965, [[COPY1]]
35+
; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp
36+
; CHECK-NEXT: RequiresZASavePseudo
37+
; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp
38+
; CHECK-NEXT: MSRpstatesvcrImm1 2, 1, implicit-def $nzcv
39+
; CHECK-NEXT: [[MRS:%[0-9]+]]:gpr64 = MRS 56965, implicit-def $nzcv
40+
; CHECK-NEXT: $x0 = ADDXri %stack.0, 0, 0
41+
; CHECK-NEXT: RestoreZAPseudo [[MRS]], $x0, &__arm_tpidr2_restore, csr_aarch64_sme_abi_support_routines_preservemost_from_x0
42+
; CHECK-NEXT: MSR 56965, $xzr
43+
; CHECK-NEXT: B %bb.2
44+
; CHECK-NEXT: {{ $}}
45+
; CHECK-NEXT: bb.1 (landing-pad):
46+
; CHECK-NEXT: successors: %bb.2(0x80000000)
47+
; CHECK-NEXT: liveins: $x0, $x1
48+
; CHECK-NEXT: {{ $}}
49+
; CHECK-NEXT: MSRpstatesvcrImm1 2, 1, implicit-def $nzcv
50+
; CHECK-NEXT: [[MRS1:%[0-9]+]]:gpr64 = MRS 56965, implicit-def $nzcv
51+
; CHECK-NEXT: $x0 = ADDXri %stack.0, 0, 0
52+
; CHECK-NEXT: RestoreZAPseudo [[MRS1]], $x0, &__arm_tpidr2_restore, csr_aarch64_sme_abi_support_routines_preservemost_from_x0
53+
; CHECK-NEXT: MSR 56965, $xzr
54+
; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp
55+
; CHECK-NEXT: InOutZAUsePseudo
56+
; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp
57+
; CHECK-NEXT: {{ $}}
58+
; CHECK-NEXT: bb.2:
59+
bb.0:
60+
successors: %bb.2(0x00000000), %bb.1(0x80000000)
61+
62+
; Simulate shared ZA call
63+
ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp
64+
InOutZAUsePseudo
65+
ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp
66+
67+
; Simulate private ZA call at the end of the block
68+
ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp
69+
RequiresZASavePseudo
70+
ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp
71+
72+
B %bb.2
73+
74+
bb.1 (landing-pad):
75+
liveins: $x0, $x1
76+
77+
; Simulate shared ZA call
78+
ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp
79+
InOutZAUsePseudo
80+
ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp
81+
82+
bb.2:

llvm/test/CodeGen/AArch64/sme-za-exceptions.ll

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
22
; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sme -aarch64-new-sme-abi -verify-machineinstrs < %s | FileCheck %s
33

4-
; FIXME: XFAILs until https://github.com/llvm/llvm-project/pull/154325
5-
; XFAIL: *
6-
74
; A simple EH test case that corresponds to the following C++ source:
85
;
96
; struct ZAResource {
@@ -65,16 +62,14 @@ define void @za_with_raii(i1 %fail) "aarch64_inout_za" personality ptr @__gxx_pe
6562
; CHECK-NEXT: ldr x1, [x1, :got_lo12:typeinfo_for_char_const_ptr]
6663
; CHECK-NEXT: bl __cxa_throw
6764
; CHECK-NEXT: .Ltmp1:
68-
; CHECK-NEXT: mov x8, x0
6965
; CHECK-NEXT: smstart za
70-
; CHECK-NEXT: mrs x9, TPIDR2_EL0
66+
; CHECK-NEXT: mrs x8, TPIDR2_EL0
7167
; CHECK-NEXT: sub x0, x29, #16
72-
; CHECK-NEXT: cbnz x9, .LBB0_4
68+
; CHECK-NEXT: cbnz x8, .LBB0_4
7369
; CHECK-NEXT: // %bb.3: // %throw_exception
7470
; CHECK-NEXT: bl __arm_tpidr2_restore
7571
; CHECK-NEXT: .LBB0_4: // %throw_exception
7672
; CHECK-NEXT: msr TPIDR2_EL0, xzr
77-
; CHECK-NEXT: // kill: def $x0 killed $x8
7873
; CHECK-NEXT: // %bb.5: // %throw_fail
7974
; CHECK-NEXT: .LBB0_6: // %unwind_dtors
8075
; CHECK-NEXT: .Ltmp2:

0 commit comments

Comments
 (0)