-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[AArch64] Add -mlr-for-calls-only to replace the now removed -ffixed-x30 flag. #98073
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
|
||
aemerson marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// RUN: %clang --target=aarch64-none-gnu -mlr-for-calls-only -### %s 2> %t | ||
// RUN: FileCheck --check-prefix=CHECK < %t %s | ||
// CHECK: "-target-feature" "+reserve-lr-for-ra" |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3267,10 +3267,13 @@ bool AArch64FrameLowering::spillCalleeSavedRegisters( | |
InsertSEH(MIB, TII, MachineInstr::FrameSetup); | ||
} else { // The code when the pair of ZReg is not present | ||
MachineInstrBuilder MIB = BuildMI(MBB, MI, DL, TII.get(StrOpc)); | ||
if (!MRI.isReserved(Reg1)) | ||
const AArch64RegisterInfo *RegInfo = | ||
static_cast<const AArch64RegisterInfo *>( | ||
MF.getSubtarget().getRegisterInfo()); | ||
if (!RegInfo->isStrictlyReservedReg(MF, Reg1)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not confident this does what you want: even if you get the liveness right inside FrameLowering, target-independent code like LivePhysRegs will ignore registers marked isReserved(). So I'm not sure any liveness computations based on a reserved LR can be trusted. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe not, but I'm not sure what other options we have. It's worked for so far except for this case with the outliner. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could unreserve LR after register allocation, I guess? That would have roughly the right semantics. Or we could make the outliner use some other method to try to figure out the "liveness" of LR if it's a reserved register. I mean, if LR is reserved, the only way it can be live is if the prologue doesn't save/restore it (in which case it's live across the whole function). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Having With shrink-wrapping the prolog can be in successor blocks, so LR can be live on some CFG paths and not others. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I think this can happen anyway? For example, with the frame/base pointer.
Oh, right. Other possibilities:
Maybe worth bringing up on Discourse to see if there are other opinions. (I'm not trying to make things complicated here, but I really don't want to take shortcuts when it comes to core MIR datastructures.) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Indeed :(
Yeah, I thought about something along these lines. Perhaps if we could dynamically alter regclasses. I think I'll give the changing reservedness approach a go here since there's already some precedent for it. |
||
MBB.addLiveIn(Reg1); | ||
if (RPI.isPaired()) { | ||
if (!MRI.isReserved(Reg2)) | ||
if (!RegInfo->isStrictlyReservedReg(MF, Reg2)) | ||
MBB.addLiveIn(Reg2); | ||
MIB.addReg(Reg2, getPrologueDeath(MF, Reg2)); | ||
MIB.addMemOperand(MF.getMachineMemOperand( | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5 | ||
# RUN: llc -run-pass=prologepilog -o - %s | FileCheck %s | ||
--- | | ||
target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128-Fn32" | ||
target triple = "arm64e-apple-ios18.4.0" | ||
|
||
declare void @spam() | ||
|
||
define i32 @check_lr_live(ptr %arg) #0 { | ||
bb: | ||
%icmp = icmp eq ptr %arg, null | ||
%or = or i1 %icmp, false | ||
br i1 %or, label %bb2, label %bb1 | ||
|
||
bb1: ; preds = %bb | ||
call void @spam() | ||
br label %bb2 | ||
|
||
bb2: ; preds = %bb1, %bb | ||
%phi = phi i32 [ -536870206, %bb ], [ 0, %bb1 ] | ||
ret i32 %phi | ||
} | ||
|
||
attributes #0 = { nounwind "target-features"="+fp-armv8,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+reserve-lr-for-ra" } | ||
|
||
... | ||
# This test checks that the live-in flags for LR are correctly set when LR is reserved, but live for a call. | ||
--- | ||
name: check_lr_live | ||
alignment: 4 | ||
tracksRegLiveness: true | ||
tracksDebugUserValues: true | ||
liveins: | ||
- { reg: '$x0' } | ||
frameInfo: | ||
maxAlignment: 1 | ||
adjustsStack: true | ||
hasCalls: true | ||
maxCallFrameSize: 0 | ||
savePoint: '%bb.2' | ||
restorePoint: '%bb.2' | ||
machineFunctionInfo: {} | ||
body: | | ||
; CHECK-LABEL: name: check_lr_live | ||
; CHECK: bb.0.bb: | ||
; CHECK-NEXT: successors: %bb.1(0x20000000), %bb.2(0x60000000) | ||
; CHECK-NEXT: liveins: $x0 | ||
; CHECK-NEXT: {{ $}} | ||
; CHECK-NEXT: renamable $x8 = COPY $x0 | ||
; CHECK-NEXT: renamable $w0 = MOVi32imm -536870206 | ||
; CHECK-NEXT: CBNZX killed renamable $x8, %bb.2 | ||
; CHECK-NEXT: {{ $}} | ||
; CHECK-NEXT: bb.1: | ||
; CHECK-NEXT: successors: %bb.4(0x80000000) | ||
; CHECK-NEXT: liveins: $w0 | ||
; CHECK-NEXT: {{ $}} | ||
; CHECK-NEXT: B %bb.4 | ||
; CHECK-NEXT: {{ $}} | ||
; CHECK-NEXT: bb.2.bb: | ||
; CHECK-NEXT: successors: %bb.4(0x2aaaaaab), %bb.3(0x55555555) | ||
; CHECK-NEXT: liveins: $w0 | ||
; CHECK-NEXT: {{ $}} | ||
; CHECK-NEXT: CBNZW $wzr, %bb.4 | ||
; CHECK-NEXT: B %bb.3 | ||
; CHECK-NEXT: {{ $}} | ||
; CHECK-NEXT: bb.3.bb1: | ||
; CHECK-NEXT: successors: %bb.4(0x80000000) | ||
; CHECK-NEXT: liveins: $lr | ||
; CHECK-NEXT: {{ $}} | ||
; CHECK-NEXT: early-clobber $sp = frame-setup STPXpre killed $fp, killed $lr, $sp, -2 :: (store (s64) into %stack.1), (store (s64) into %stack.0) | ||
; CHECK-NEXT: BL @spam, csr_darwin_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp | ||
; CHECK-NEXT: renamable $w0 = COPY $wzr | ||
; CHECK-NEXT: early-clobber $sp, $fp, $lr = frame-destroy LDPXpost $sp, 2 :: (load (s64) from %stack.1), (load (s64) from %stack.0) | ||
; CHECK-NEXT: {{ $}} | ||
; CHECK-NEXT: bb.4.bb2: | ||
; CHECK-NEXT: liveins: $w0 | ||
; CHECK-NEXT: {{ $}} | ||
; CHECK-NEXT: RET_ReallyLR implicit $w0 | ||
bb.0.bb: | ||
successors: %bb.4(0x20000000), %bb.1(0x60000000) | ||
liveins: $x0 | ||
|
||
renamable $x8 = COPY $x0 | ||
renamable $w0 = MOVi32imm -536870206 | ||
CBNZX killed renamable $x8, %bb.1 | ||
|
||
bb.4: | ||
liveins: $w0 | ||
|
||
B %bb.3 | ||
|
||
bb.1.bb: | ||
successors: %bb.3(0x2aaaaaab), %bb.2(0x55555555) | ||
liveins: $w0 | ||
|
||
CBNZW $wzr, %bb.3 | ||
B %bb.2 | ||
|
||
bb.2.bb1: | ||
ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp | ||
BL @spam, csr_darwin_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp | ||
ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp | ||
renamable $w0 = COPY $wzr | ||
|
||
bb.3.bb2: | ||
liveins: $w0 | ||
|
||
RET_ReallyLR implicit $w0 | ||
|
||
... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Name seems okay.