Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion llvm/lib/Target/AArch64/AArch64InstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -1773,7 +1773,12 @@ def : InstAlias<"xpaclri", (XPACLRI), 0>;

let Uses = [LR, SP], Defs = [LR] in {
// Insertion point of LR signing code.
def PAUTH_PROLOGUE : Pseudo<(outs), (ins), []>, Sched<[]>;
def PAUTH_PROLOGUE : Pseudo<(outs), (ins), []>, Sched<[]> {
// When using PAuthLR, the address of one of the instructions this expands
// into is used as an input to the signature calculation, so this must not be
// duplicated.
let isNotDuplicable = 1;
}
// Insertion point of LR authentication code.
// The RET terminator of the containing machine basic block may be replaced
// with a combined RETA(A|B) instruction when rewriting this Pseudo.
Expand Down
88 changes: 88 additions & 0 deletions llvm/test/CodeGen/AArch64/pauthlr-prologue-duplication.mir
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
# RUN: llc -mtriple aarch64-none-elf -run-pass=block-placement -O3 -o - %s | FileCheck %s

## Check that block-placement does not perform tail duplication on the
## PAUTH_EPILOGUE instruction. If that happened, the two prologues would use
## different addresses while calculating the return address signature, so the
## epilogue could only be correct for (at most) one of them.

--- |
define void @test() "frame-pointer"="non-leaf" {
entry:
ret void
}

declare void @f()
...
---
name: test
body: |
; CHECK-LABEL: name: test
; CHECK: bb.0.entry:
; CHECK-NEXT: successors: %bb.1(0x30000000), %bb.2(0x50000000)
; CHECK-NEXT: liveins: $w0, $w1, $lr
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: CBZW renamable $w0, %bb.1
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.2:
; CHECK-NEXT: successors: %bb.3(0x80000000)
; CHECK-NEXT: liveins: $w0, $w1, $lr
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: B %bb.3
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.1:
; CHECK-NEXT: successors: %bb.3(0x80000000)
; CHECK-NEXT: liveins: $w1, $lr
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: renamable $w8 = MOVZWi 1, 0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.3:
; CHECK-NEXT: successors: %bb.5(0x30000000), %bb.4(0x50000000)
; CHECK-NEXT: liveins: $w1, $w8, $lr
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: frame-setup PAUTH_PROLOGUE implicit-def $lr, implicit killed $lr, implicit $sp
; CHECK-NEXT: CBZW killed renamable $w1, %bb.5
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.4:
; CHECK-NEXT: successors: %bb.5(0x80000000)
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: BL @f, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.5:
; CHECK-NEXT: BL @f, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp
; CHECK-NEXT: frame-destroy PAUTH_EPILOGUE implicit-def $lr, implicit killed $lr, implicit $sp
; CHECK-NEXT: TCRETURNdi @f, 0, csr_aarch64_aapcs, implicit $sp
bb.0.entry:
successors: %bb.1(0x30000000), %bb.2(0x50000000)
liveins: $w0, $w1, $lr

CBNZW renamable $w0, %bb.2

bb.1:
successors: %bb.3(0x80000000)
liveins: $w1, $lr

renamable $w8 = MOVZWi 1, 0
B %bb.3

bb.2:
successors: %bb.3(0x80000000)
liveins: $w0, $w1, $lr

bb.3:
successors: %bb.5(0x30000000), %bb.4(0x50000000)
liveins: $w1, $w8, $lr

frame-setup PAUTH_PROLOGUE implicit-def $lr, implicit killed $lr, implicit $sp
CBZW killed renamable $w1, %bb.5

bb.4:
successors: %bb.5(0x80000000)

BL @f, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp

bb.5:
BL @f, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp
frame-destroy PAUTH_EPILOGUE implicit-def $lr, implicit killed $lr, implicit $sp
TCRETURNdi @f, 0, csr_aarch64_aapcs, implicit $sp
...