
On most operating systems, the x16 and x17 registers are not special, so there is no benefit, and only a code size cost, to constraining AUT to only using them. Therefore, adjust the backend to only use the AUT pseudo (renamed AUTx16x17 for clarity) on Darwin platforms. All other platforms use an unconstrained variant of the pseudo, AUTxMxN, for selection. Reviewers: ahmedbougacha, kovdan01, atrosinenko Reviewed By: atrosinenko Pull Request: https://github.com/llvm/llvm-project/pull/132857
398 lines
12 KiB
LLVM
398 lines
12 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
|
; RUN: llc < %s -mtriple arm64e-apple-darwin -verify-machineinstrs | FileCheck %s -DL="L" --check-prefixes=ALL,DARWIN,NOFPAC,DARWIN-NOFPAC
|
|
; RUN: llc < %s -mtriple arm64e-apple-darwin -mattr=+fpac -verify-machineinstrs | FileCheck %s -DL="L" --check-prefixes=ALL,DARWIN,FPAC,DARWIN-FPAC
|
|
; RUN: llc < %s -mtriple aarch64-linux-gnu -mattr=+pauth -verify-machineinstrs | FileCheck %s -DL=".L" --check-prefixes=ALL,ELF,NOFPAC,ELF-NOFPAC
|
|
; RUN: llc < %s -mtriple aarch64-linux-gnu -mattr=+pauth -mattr=+fpac -verify-machineinstrs | FileCheck %s -DL=".L" --check-prefixes=ALL,ELF,FPAC,ELF-FPAC
|
|
|
|
target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
|
|
|
|
define i64 @test_auth_ia(i64 %arg, i64 %arg1) {
|
|
; ALL-LABEL: test_auth_ia:
|
|
; ALL: %bb.0:
|
|
; DARWIN-NEXT: mov x16, x0
|
|
; DARWIN-NEXT: autia x16, x1
|
|
; DARWIN-NEXT: mov x0, x16
|
|
; ELF-NEXT: autia x0, x1
|
|
; ALL-NEXT: ret
|
|
%tmp = call i64 @llvm.ptrauth.auth(i64 %arg, i32 0, i64 %arg1)
|
|
ret i64 %tmp
|
|
}
|
|
|
|
define i64 @test_auth_ia_zero(i64 %arg) {
|
|
; ALL-LABEL: test_auth_ia_zero:
|
|
; ALL: %bb.0:
|
|
; DARWIN-NEXT: mov x16, x0
|
|
; DARWIN-NEXT: autiza x16
|
|
; DARWIN-NEXT: mov x0, x16
|
|
; ELF-NEXT: autiza x0
|
|
; ALL-NEXT: ret
|
|
%tmp = call i64 @llvm.ptrauth.auth(i64 %arg, i32 0, i64 0)
|
|
ret i64 %tmp
|
|
}
|
|
|
|
define i64 @test_auth_ib(i64 %arg, i64 %arg1) {
|
|
; ALL-LABEL: test_auth_ib:
|
|
; ALL: %bb.0:
|
|
; DARWIN-NEXT: mov x16, x0
|
|
; DARWIN-NEXT: autib x16, x1
|
|
; DARWIN-NEXT: mov x0, x16
|
|
; ELF-NEXT: autib x0, x1
|
|
; ALL-NEXT: ret
|
|
%tmp = call i64 @llvm.ptrauth.auth(i64 %arg, i32 1, i64 %arg1)
|
|
ret i64 %tmp
|
|
}
|
|
|
|
define i64 @test_auth_ib_zero(i64 %arg) {
|
|
; ALL-LABEL: test_auth_ib_zero:
|
|
; ALL: %bb.0:
|
|
; DARWIN-NEXT: mov x16, x0
|
|
; DARWIN-NEXT: autizb x16
|
|
; DARWIN-NEXT: mov x0, x16
|
|
; ELF-NEXT: autizb x0
|
|
; ALL-NEXT: ret
|
|
%tmp = call i64 @llvm.ptrauth.auth(i64 %arg, i32 1, i64 0)
|
|
ret i64 %tmp
|
|
}
|
|
|
|
define i64 @test_auth_da(i64 %arg, i64 %arg1) {
|
|
; ALL-LABEL: test_auth_da:
|
|
; ALL: %bb.0:
|
|
; DARWIN-NEXT: mov x16, x0
|
|
; DARWIN-NEXT: autda x16, x1
|
|
; DARWIN-NEXT: mov x0, x16
|
|
; ELF-NEXT: autda x0, x1
|
|
; ALL-NEXT: ret
|
|
%tmp = call i64 @llvm.ptrauth.auth(i64 %arg, i32 2, i64 %arg1)
|
|
ret i64 %tmp
|
|
}
|
|
|
|
define i64 @test_auth_da_zero(i64 %arg) {
|
|
; ALL-LABEL: test_auth_da_zero:
|
|
; ALL: %bb.0:
|
|
; DARWIN-NEXT: mov x16, x0
|
|
; DARWIN-NEXT: autdza x16
|
|
; DARWIN-NEXT: mov x0, x16
|
|
; ELF-NEXT: autdza x0
|
|
; ALL-NEXT: ret
|
|
%tmp = call i64 @llvm.ptrauth.auth(i64 %arg, i32 2, i64 0)
|
|
ret i64 %tmp
|
|
}
|
|
|
|
define i64 @test_auth_db(i64 %arg, i64 %arg1) {
|
|
; ALL-LABEL: test_auth_db:
|
|
; ALL: %bb.0:
|
|
; DARWIN-NEXT: mov x16, x0
|
|
; DARWIN-NEXT: autdb x16, x1
|
|
; DARWIN-NEXT: mov x0, x16
|
|
; ELF-NEXT: autdb x0, x1
|
|
; ALL-NEXT: ret
|
|
%tmp = call i64 @llvm.ptrauth.auth(i64 %arg, i32 3, i64 %arg1)
|
|
ret i64 %tmp
|
|
}
|
|
|
|
define i64 @test_auth_db_zero(i64 %arg) {
|
|
; ALL-LABEL: test_auth_db_zero:
|
|
; ALL: %bb.0:
|
|
; DARWIN-NEXT: mov x16, x0
|
|
; DARWIN-NEXT: autdzb x16
|
|
; DARWIN-NEXT: mov x0, x16
|
|
; ELF-NEXT: autdzb x0
|
|
; ALL-NEXT: ret
|
|
%tmp = call i64 @llvm.ptrauth.auth(i64 %arg, i32 3, i64 0)
|
|
ret i64 %tmp
|
|
}
|
|
|
|
; Note that this might seem like a no-op but is actually a valid way to enforce
|
|
; the validity of a signature.
|
|
define i64 @test_resign_ia_ia(i64 %arg, i64 %arg1, i64 %arg2) {
|
|
; NOFPAC-LABEL: test_resign_ia_ia:
|
|
; NOFPAC: %bb.0:
|
|
; NOFPAC-NEXT: mov x16, x0
|
|
; NOFPAC-NEXT: autia x16, x1
|
|
; NOFPAC-NEXT: mov x17, x16
|
|
; NOFPAC-NEXT: xpaci x17
|
|
; NOFPAC-NEXT: cmp x16, x17
|
|
; NOFPAC-NEXT: b.eq [[L]]auth_success_0
|
|
; NOFPAC-NEXT: mov x16, x17
|
|
; NOFPAC-NEXT: b [[L]]resign_end_0
|
|
; NOFPAC-NEXT: Lauth_success_0:
|
|
; NOFPAC-NEXT: pacia x16, x2
|
|
; NOFPAC-NEXT: Lresign_end_0:
|
|
; NOFPAC-NEXT: mov x0, x16
|
|
; NOFPAC-NEXT: ret
|
|
;
|
|
; FPAC-LABEL: test_resign_ia_ia:
|
|
; FPAC: %bb.0:
|
|
; FPAC-NEXT: mov x16, x0
|
|
; FPAC-NEXT: autia x16, x1
|
|
; FPAC-NEXT: pacia x16, x2
|
|
; FPAC-NEXT: mov x0, x16
|
|
; FPAC-NEXT: ret
|
|
%tmp = call i64 @llvm.ptrauth.resign(i64 %arg, i32 0, i64 %arg1, i32 0, i64 %arg2)
|
|
ret i64 %tmp
|
|
}
|
|
|
|
define i64 @test_resign_ib_ia(i64 %arg, i64 %arg1, i64 %arg2) {
|
|
; NOFPAC-LABEL: test_resign_ib_ia:
|
|
; NOFPAC: %bb.0:
|
|
; NOFPAC-NEXT: mov x16, x0
|
|
; NOFPAC-NEXT: autib x16, x1
|
|
; NOFPAC-NEXT: mov x17, x16
|
|
; NOFPAC-NEXT: xpaci x17
|
|
; NOFPAC-NEXT: cmp x16, x17
|
|
; NOFPAC-NEXT: b.eq [[L]]auth_success_1
|
|
; NOFPAC-NEXT: mov x16, x17
|
|
; NOFPAC-NEXT: b [[L]]resign_end_1
|
|
; NOFPAC-NEXT: Lauth_success_1:
|
|
; NOFPAC-NEXT: pacia x16, x2
|
|
; NOFPAC-NEXT: Lresign_end_1:
|
|
; NOFPAC-NEXT: mov x0, x16
|
|
; NOFPAC-NEXT: ret
|
|
;
|
|
; FPAC-LABEL: test_resign_ib_ia:
|
|
; FPAC: %bb.0:
|
|
; FPAC-NEXT: mov x16, x0
|
|
; FPAC-NEXT: autib x16, x1
|
|
; FPAC-NEXT: pacia x16, x2
|
|
; FPAC-NEXT: mov x0, x16
|
|
; FPAC-NEXT: ret
|
|
%tmp = call i64 @llvm.ptrauth.resign(i64 %arg, i32 1, i64 %arg1, i32 0, i64 %arg2)
|
|
ret i64 %tmp
|
|
}
|
|
|
|
define i64 @test_resign_da_ia(i64 %arg, i64 %arg1, i64 %arg2) {
|
|
; NOFPAC-LABEL: test_resign_da_ia:
|
|
; NOFPAC: %bb.0:
|
|
; NOFPAC-NEXT: mov x16, x0
|
|
; NOFPAC-NEXT: autda x16, x1
|
|
; NOFPAC-NEXT: mov x17, x16
|
|
; NOFPAC-NEXT: xpacd x17
|
|
; NOFPAC-NEXT: cmp x16, x17
|
|
; NOFPAC-NEXT: b.eq [[L]]auth_success_2
|
|
; NOFPAC-NEXT: mov x16, x17
|
|
; NOFPAC-NEXT: b [[L]]resign_end_2
|
|
; NOFPAC-NEXT: Lauth_success_2:
|
|
; NOFPAC-NEXT: pacia x16, x2
|
|
; NOFPAC-NEXT: Lresign_end_2:
|
|
; NOFPAC-NEXT: mov x0, x16
|
|
; NOFPAC-NEXT: ret
|
|
;
|
|
; FPAC-LABEL: test_resign_da_ia:
|
|
; FPAC: %bb.0:
|
|
; FPAC-NEXT: mov x16, x0
|
|
; FPAC-NEXT: autda x16, x1
|
|
; FPAC-NEXT: pacia x16, x2
|
|
; FPAC-NEXT: mov x0, x16
|
|
; FPAC-NEXT: ret
|
|
%tmp = call i64 @llvm.ptrauth.resign(i64 %arg, i32 2, i64 %arg1, i32 0, i64 %arg2)
|
|
ret i64 %tmp
|
|
}
|
|
|
|
define i64 @test_resign_db_ia(i64 %arg, i64 %arg1, i64 %arg2) {
|
|
; NOFPAC-LABEL: test_resign_db_ia:
|
|
; NOFPAC: %bb.0:
|
|
; NOFPAC-NEXT: mov x16, x0
|
|
; NOFPAC-NEXT: autdb x16, x1
|
|
; NOFPAC-NEXT: mov x17, x16
|
|
; NOFPAC-NEXT: xpacd x17
|
|
; NOFPAC-NEXT: cmp x16, x17
|
|
; NOFPAC-NEXT: b.eq [[L]]auth_success_3
|
|
; NOFPAC-NEXT: mov x16, x17
|
|
; NOFPAC-NEXT: b [[L]]resign_end_3
|
|
; NOFPAC-NEXT: Lauth_success_3:
|
|
; NOFPAC-NEXT: pacia x16, x2
|
|
; NOFPAC-NEXT: Lresign_end_3:
|
|
; NOFPAC-NEXT: mov x0, x16
|
|
; NOFPAC-NEXT: ret
|
|
;
|
|
; FPAC-LABEL: test_resign_db_ia:
|
|
; FPAC: %bb.0:
|
|
; FPAC-NEXT: mov x16, x0
|
|
; FPAC-NEXT: autdb x16, x1
|
|
; FPAC-NEXT: pacia x16, x2
|
|
; FPAC-NEXT: mov x0, x16
|
|
; FPAC-NEXT: ret
|
|
%tmp = call i64 @llvm.ptrauth.resign(i64 %arg, i32 3, i64 %arg1, i32 0, i64 %arg2)
|
|
ret i64 %tmp
|
|
}
|
|
|
|
define i64 @test_resign_db_ib(i64 %arg, i64 %arg1, i64 %arg2) {
|
|
; NOFPAC-LABEL: test_resign_db_ib:
|
|
; NOFPAC: %bb.0:
|
|
; NOFPAC-NEXT: mov x16, x0
|
|
; NOFPAC-NEXT: autdb x16, x1
|
|
; NOFPAC-NEXT: mov x17, x16
|
|
; NOFPAC-NEXT: xpacd x17
|
|
; NOFPAC-NEXT: cmp x16, x17
|
|
; NOFPAC-NEXT: b.eq [[L]]auth_success_4
|
|
; NOFPAC-NEXT: mov x16, x17
|
|
; NOFPAC-NEXT: b [[L]]resign_end_4
|
|
; NOFPAC-NEXT: Lauth_success_4:
|
|
; NOFPAC-NEXT: pacib x16, x2
|
|
; NOFPAC-NEXT: Lresign_end_4:
|
|
; NOFPAC-NEXT: mov x0, x16
|
|
; NOFPAC-NEXT: ret
|
|
;
|
|
; FPAC-LABEL: test_resign_db_ib:
|
|
; FPAC: %bb.0:
|
|
; FPAC-NEXT: mov x16, x0
|
|
; FPAC-NEXT: autdb x16, x1
|
|
; FPAC-NEXT: pacib x16, x2
|
|
; FPAC-NEXT: mov x0, x16
|
|
; FPAC-NEXT: ret
|
|
%tmp = call i64 @llvm.ptrauth.resign(i64 %arg, i32 3, i64 %arg1, i32 1, i64 %arg2)
|
|
ret i64 %tmp
|
|
}
|
|
|
|
define i64 @test_resign_db_da(i64 %arg, i64 %arg1, i64 %arg2) {
|
|
; NOFPAC-LABEL: test_resign_db_da:
|
|
; NOFPAC: %bb.0:
|
|
; NOFPAC-NEXT: mov x16, x0
|
|
; NOFPAC-NEXT: autdb x16, x1
|
|
; NOFPAC-NEXT: mov x17, x16
|
|
; NOFPAC-NEXT: xpacd x17
|
|
; NOFPAC-NEXT: cmp x16, x17
|
|
; NOFPAC-NEXT: b.eq [[L]]auth_success_5
|
|
; NOFPAC-NEXT: mov x16, x17
|
|
; NOFPAC-NEXT: b [[L]]resign_end_5
|
|
; NOFPAC-NEXT: Lauth_success_5:
|
|
; NOFPAC-NEXT: pacda x16, x2
|
|
; NOFPAC-NEXT: Lresign_end_5:
|
|
; NOFPAC-NEXT: mov x0, x16
|
|
; NOFPAC-NEXT: ret
|
|
;
|
|
; FPAC-LABEL: test_resign_db_da:
|
|
; FPAC: %bb.0:
|
|
; FPAC-NEXT: mov x16, x0
|
|
; FPAC-NEXT: autdb x16, x1
|
|
; FPAC-NEXT: pacda x16, x2
|
|
; FPAC-NEXT: mov x0, x16
|
|
; FPAC-NEXT: ret
|
|
%tmp = call i64 @llvm.ptrauth.resign(i64 %arg, i32 3, i64 %arg1, i32 2, i64 %arg2)
|
|
ret i64 %tmp
|
|
}
|
|
|
|
define i64 @test_resign_db_db(i64 %arg, i64 %arg1, i64 %arg2) {
|
|
; NOFPAC-LABEL: test_resign_db_db:
|
|
; NOFPAC: %bb.0:
|
|
; NOFPAC-NEXT: mov x16, x0
|
|
; NOFPAC-NEXT: autdb x16, x1
|
|
; NOFPAC-NEXT: mov x17, x16
|
|
; NOFPAC-NEXT: xpacd x17
|
|
; NOFPAC-NEXT: cmp x16, x17
|
|
; NOFPAC-NEXT: b.eq [[L]]auth_success_6
|
|
; NOFPAC-NEXT: mov x16, x17
|
|
; NOFPAC-NEXT: b [[L]]resign_end_6
|
|
; NOFPAC-NEXT: Lauth_success_6:
|
|
; NOFPAC-NEXT: pacdb x16, x2
|
|
; NOFPAC-NEXT: Lresign_end_6:
|
|
; NOFPAC-NEXT: mov x0, x16
|
|
; NOFPAC-NEXT: ret
|
|
;
|
|
; FPAC-LABEL: test_resign_db_db:
|
|
; FPAC: %bb.0:
|
|
; FPAC-NEXT: mov x16, x0
|
|
; FPAC-NEXT: autdb x16, x1
|
|
; FPAC-NEXT: pacdb x16, x2
|
|
; FPAC-NEXT: mov x0, x16
|
|
; FPAC-NEXT: ret
|
|
%tmp = call i64 @llvm.ptrauth.resign(i64 %arg, i32 3, i64 %arg1, i32 3, i64 %arg2)
|
|
ret i64 %tmp
|
|
}
|
|
|
|
define i64 @test_resign_iza_db(i64 %arg, i64 %arg1, i64 %arg2) {
|
|
; NOFPAC-LABEL: test_resign_iza_db:
|
|
; NOFPAC: %bb.0:
|
|
; NOFPAC-NEXT: mov x16, x0
|
|
; NOFPAC-NEXT: autiza x16
|
|
; NOFPAC-NEXT: mov x17, x16
|
|
; NOFPAC-NEXT: xpaci x17
|
|
; NOFPAC-NEXT: cmp x16, x17
|
|
; NOFPAC-NEXT: b.eq [[L]]auth_success_7
|
|
; NOFPAC-NEXT: mov x16, x17
|
|
; NOFPAC-NEXT: b [[L]]resign_end_7
|
|
; NOFPAC-NEXT: Lauth_success_7:
|
|
; NOFPAC-NEXT: pacdb x16, x2
|
|
; NOFPAC-NEXT: Lresign_end_7:
|
|
; NOFPAC-NEXT: mov x0, x16
|
|
; NOFPAC-NEXT: ret
|
|
;
|
|
; FPAC-LABEL: test_resign_iza_db:
|
|
; FPAC: %bb.0:
|
|
; FPAC-NEXT: mov x16, x0
|
|
; FPAC-NEXT: autiza x16
|
|
; FPAC-NEXT: pacdb x16, x2
|
|
; FPAC-NEXT: mov x0, x16
|
|
; FPAC-NEXT: ret
|
|
%tmp = call i64 @llvm.ptrauth.resign(i64 %arg, i32 0, i64 0, i32 3, i64 %arg2)
|
|
ret i64 %tmp
|
|
}
|
|
|
|
define i64 @test_resign_da_dzb(i64 %arg, i64 %arg1, i64 %arg2) {
|
|
; NOFPAC-LABEL: test_resign_da_dzb:
|
|
; NOFPAC: %bb.0:
|
|
; NOFPAC-NEXT: mov x16, x0
|
|
; NOFPAC-NEXT: autda x16, x1
|
|
; NOFPAC-NEXT: mov x17, x16
|
|
; NOFPAC-NEXT: xpacd x17
|
|
; NOFPAC-NEXT: cmp x16, x17
|
|
; NOFPAC-NEXT: b.eq [[L]]auth_success_8
|
|
; NOFPAC-NEXT: mov x16, x17
|
|
; NOFPAC-NEXT: b [[L]]resign_end_8
|
|
; NOFPAC-NEXT: Lauth_success_8:
|
|
; NOFPAC-NEXT: pacdzb x16
|
|
; NOFPAC-NEXT: Lresign_end_8:
|
|
; NOFPAC-NEXT: mov x0, x16
|
|
; NOFPAC-NEXT: ret
|
|
;
|
|
; FPAC-LABEL: test_resign_da_dzb:
|
|
; FPAC: %bb.0:
|
|
; FPAC-NEXT: mov x16, x0
|
|
; FPAC-NEXT: autda x16, x1
|
|
; FPAC-NEXT: pacdzb x16
|
|
; FPAC-NEXT: mov x0, x16
|
|
; FPAC-NEXT: ret
|
|
%tmp = call i64 @llvm.ptrauth.resign(i64 %arg, i32 2, i64 %arg1, i32 3, i64 0)
|
|
ret i64 %tmp
|
|
}
|
|
|
|
define i64 @test_auth_trap_attribute(i64 %arg, i64 %arg1) "ptrauth-auth-traps" {
|
|
; ALL-LABEL: test_auth_trap_attribute:
|
|
; DARWIN-NOFPAC: %bb.0:
|
|
; DARWIN-NOFPAC-NEXT: mov x16, x0
|
|
; DARWIN-NOFPAC-NEXT: autia x16, x1
|
|
; DARWIN-NOFPAC-NEXT: mov x17, x16
|
|
; DARWIN-NOFPAC-NEXT: xpaci x17
|
|
; DARWIN-NOFPAC-NEXT: cmp x16, x17
|
|
; DARWIN-NOFPAC-NEXT: b.eq [[L]]auth_success_9
|
|
; DARWIN-NOFPAC-NEXT: brk #0xc470
|
|
; DARWIN-NOFPAC-NEXT: Lauth_success_9:
|
|
; DARWIN-NOFPAC-NEXT: mov x0, x16
|
|
; DARWIN-NOFPAC-NEXT: ret
|
|
;
|
|
; ELF-NOFPAC: %bb.0:
|
|
; ELF-NOFPAC-NEXT: autia x0, x1
|
|
; ELF-NOFPAC-NEXT: mov x8, x0
|
|
; ELF-NOFPAC-NEXT: xpaci x8
|
|
; ELF-NOFPAC-NEXT: cmp x0, x8
|
|
; ELF-NOFPAC-NEXT: b.eq [[L]]auth_success_9
|
|
; ELF-NOFPAC-NEXT: brk #0xc470
|
|
; ELF-NOFPAC-NEXT: Lauth_success_9:
|
|
; ELF-NOFPAC-NEXT: ret
|
|
;
|
|
; DARWIN-FPAC: %bb.0:
|
|
; DARWIN-FPAC-NEXT: mov x16, x0
|
|
; DARWIN-FPAC-NEXT: autia x16, x1
|
|
; DARWIN-FPAC-NEXT: mov x0, x16
|
|
; DARWIN-FPAC-NEXT: ret
|
|
;
|
|
; ELF-FPAC: %bb.0:
|
|
; ELF-FPAC-NEXT: autia x0, x1
|
|
; ELF-FPAC-NEXT: ret
|
|
%tmp = call i64 @llvm.ptrauth.auth(i64 %arg, i32 0, i64 %arg1)
|
|
ret i64 %tmp
|
|
}
|
|
|
|
declare i64 @llvm.ptrauth.auth(i64, i32, i64)
|
|
declare i64 @llvm.ptrauth.resign(i64, i32, i64, i32, i64)
|