; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc < %s -mtriple arm64e-apple-darwin -global-isel=0 -verify-machineinstrs \ ; RUN: -aarch64-ptrauth-auth-checks=none | FileCheck %s -DL="L" --check-prefixes=UNCHECKED,UNCHECKED-DARWIN ; RUN: llc < %s -mtriple arm64e-apple-darwin -global-isel -global-isel-abort=1 -verify-machineinstrs \ ; RUN: -aarch64-ptrauth-auth-checks=none | FileCheck %s -DL="L" --check-prefixes=UNCHECKED,UNCHECKED-DARWIN ; RUN: llc < %s -mtriple arm64e-apple-darwin -global-isel=0 -verify-machineinstrs \ ; RUN: | FileCheck %s -DL="L" --check-prefixes=CHECKED,CHECKED-DARWIN ; RUN: llc < %s -mtriple arm64e-apple-darwin -global-isel -global-isel-abort=1 -verify-machineinstrs \ ; RUN: | FileCheck %s -DL="L" --check-prefixes=CHECKED,CHECKED-DARWIN ; RUN: llc < %s -mtriple arm64e-apple-darwin -global-isel=0 -verify-machineinstrs \ ; RUN: -aarch64-ptrauth-auth-checks=trap | FileCheck %s -DL="L" --check-prefixes=TRAP,TRAP-DARWIN ; RUN: llc < %s -mtriple arm64e-apple-darwin -global-isel -global-isel-abort=1 -verify-machineinstrs \ ; RUN: -aarch64-ptrauth-auth-checks=trap | FileCheck %s -DL="L" --check-prefixes=TRAP,TRAP-DARWIN ; RUN: llc < %s -mtriple aarch64-linux-gnu -mattr=+pauth -global-isel=0 -verify-machineinstrs \ ; RUN: -aarch64-ptrauth-auth-checks=none | FileCheck %s -DL=".L" --check-prefixes=UNCHECKED,UNCHECKED-ELF ; RUN: llc < %s -mtriple aarch64-linux-gnu -mattr=+pauth -global-isel -global-isel-abort=1 -verify-machineinstrs \ ; RUN: -aarch64-ptrauth-auth-checks=none | FileCheck %s -DL=".L" --check-prefixes=UNCHECKED,UNCHECKED-ELF ; RUN: llc < %s -mtriple aarch64-linux-gnu -mattr=+pauth -global-isel=0 -verify-machineinstrs \ ; RUN: | FileCheck %s -DL=".L" --check-prefixes=CHECKED,CHECKED-ELF ; RUN: llc < %s -mtriple aarch64-linux-gnu -mattr=+pauth -global-isel -global-isel-abort=1 -verify-machineinstrs \ ; RUN: | FileCheck %s -DL=".L" --check-prefixes=CHECKED,CHECKED-ELF ; RUN: llc < %s -mtriple aarch64-linux-gnu -mattr=+pauth -global-isel=0 -verify-machineinstrs \ ; RUN: -aarch64-ptrauth-auth-checks=trap | FileCheck %s -DL=".L" --check-prefixes=TRAP,TRAP-ELF ; RUN: llc < %s -mtriple aarch64-linux-gnu -mattr=+pauth -global-isel -global-isel-abort=1 -verify-machineinstrs \ ; RUN: -aarch64-ptrauth-auth-checks=trap | FileCheck %s -DL=".L" --check-prefixes=TRAP,TRAP-ELF target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" define i64 @test_auth_ia(i64 %arg, i64 %arg1) { ; UNCHECKED-LABEL: test_auth_ia: ; UNCHECKED: %bb.0: ; UNCHECKED-DARWIN-NEXT: mov x16, x0 ; UNCHECKED-DARWIN-NEXT: autia x16, x1 ; UNCHECKED-DARWIN-NEXT: mov x0, x16 ; UNCHECKED-ELF-NEXT: autia x0, x1 ; UNCHECKED-NEXT: ret ; ; CHECKED-LABEL: test_auth_ia: ; CHECKED: %bb.0: ; CHECKED-DARWIN-NEXT: mov x16, x0 ; CHECKED-DARWIN-NEXT: autia x16, x1 ; CHECKED-DARWIN-NEXT: mov x0, x16 ; CHECKED-ELF-NEXT: autia x0, x1 ; CHECKED-NEXT: ret ; ; TRAP-LABEL: test_auth_ia: ; TRAP: %bb.0: ; TRAP-DARWIN-NEXT: mov x16, x0 ; TRAP-DARWIN-NEXT: autia x16, x1 ; TRAP-DARWIN-NEXT: mov x17, x16 ; TRAP-DARWIN-NEXT: xpaci x17 ; TRAP-DARWIN-NEXT: cmp x16, x17 ; TRAP-ELF-NEXT: autia x0, x1 ; TRAP-ELF-NEXT: mov x8, x0 ; TRAP-ELF-NEXT: xpaci x8 ; TRAP-ELF-NEXT: cmp x0, x8 ; TRAP-NEXT: b.eq [[L]]auth_success_0 ; TRAP-NEXT: brk #0xc470 ; TRAP-NEXT: Lauth_success_0: ; TRAP-DARWIN-NEXT: mov x0, x16 ; TRAP-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) { ; UNCHECKED-LABEL: test_auth_ia_zero: ; UNCHECKED: %bb.0: ; UNCHECKED-DARWIN-NEXT: mov x16, x0 ; UNCHECKED-DARWIN-NEXT: autiza x16 ; UNCHECKED-DARWIN-NEXT: mov x0, x16 ; UNCHECKED-ELF-NEXT: autiza x0 ; UNCHECKED-NEXT: ret ; ; CHECKED-LABEL: test_auth_ia_zero: ; CHECKED: %bb.0: ; CHECKED-DARWIN-NEXT: mov x16, x0 ; CHECKED-DARWIN-NEXT: autiza x16 ; CHECKED-DARWIN-NEXT: mov x0, x16 ; CHECKED-ELF-NEXT: autiza x0 ; CHECKED-NEXT: ret ; ; TRAP-LABEL: test_auth_ia_zero: ; TRAP: %bb.0: ; TRAP-DARWIN-NEXT: mov x16, x0 ; TRAP-DARWIN-NEXT: autiza x16 ; TRAP-DARWIN-NEXT: mov x17, x16 ; TRAP-DARWIN-NEXT: xpaci x17 ; TRAP-DARWIN-NEXT: cmp x16, x17 ; TRAP-ELF-NEXT: autiza x0 ; TRAP-ELF-NEXT: mov x8, x0 ; TRAP-ELF-NEXT: xpaci x8 ; TRAP-ELF-NEXT: cmp x0, x8 ; TRAP-NEXT: b.eq [[L]]auth_success_1 ; TRAP-NEXT: brk #0xc470 ; TRAP-NEXT: Lauth_success_1: ; TRAP-DARWIN-NEXT: mov x0, x16 ; TRAP-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) { ; UNCHECKED-LABEL: test_auth_ib: ; UNCHECKED: %bb.0: ; UNCHECKED-DARWIN-NEXT: mov x16, x0 ; UNCHECKED-DARWIN-NEXT: autib x16, x1 ; UNCHECKED-DARWIN-NEXT: mov x0, x16 ; UNCHECKED-ELF-NEXT: autib x0, x1 ; UNCHECKED-NEXT: ret ; ; CHECKED-LABEL: test_auth_ib: ; CHECKED: %bb.0: ; CHECKED-DARWIN-NEXT: mov x16, x0 ; CHECKED-DARWIN-NEXT: autib x16, x1 ; CHECKED-DARWIN-NEXT: mov x0, x16 ; CHECKED-ELF-NEXT: autib x0, x1 ; CHECKED-NEXT: ret ; ; TRAP-LABEL: test_auth_ib: ; TRAP: %bb.0: ; TRAP-DARWIN-NEXT: mov x16, x0 ; TRAP-DARWIN-NEXT: autib x16, x1 ; TRAP-DARWIN-NEXT: mov x17, x16 ; TRAP-DARWIN-NEXT: xpaci x17 ; TRAP-DARWIN-NEXT: cmp x16, x17 ; TRAP-ELF-NEXT: autib x0, x1 ; TRAP-ELF-NEXT: mov x8, x0 ; TRAP-ELF-NEXT: xpaci x8 ; TRAP-ELF-NEXT: cmp x0, x8 ; TRAP-NEXT: b.eq [[L]]auth_success_2 ; TRAP-NEXT: brk #0xc471 ; TRAP-NEXT: Lauth_success_2: ; TRAP-DARWIN-NEXT: mov x0, x16 ; TRAP-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) { ; UNCHECKED-LABEL: test_auth_ib_zero: ; UNCHECKED: %bb.0: ; UNCHECKED-DARWIN-NEXT: mov x16, x0 ; UNCHECKED-DARWIN-NEXT: autizb x16 ; UNCHECKED-DARWIN-NEXT: mov x0, x16 ; UNCHECKED-ELF-NEXT: autizb x0 ; UNCHECKED-NEXT: ret ; ; CHECKED-LABEL: test_auth_ib_zero: ; CHECKED: %bb.0: ; CHECKED-DARWIN-NEXT: mov x16, x0 ; CHECKED-DARWIN-NEXT: autizb x16 ; CHECKED-DARWIN-NEXT: mov x0, x16 ; CHECKED-ELF-NEXT: autizb x0 ; CHECKED-NEXT: ret ; ; TRAP-LABEL: test_auth_ib_zero: ; TRAP: %bb.0: ; TRAP-DARWIN-NEXT: mov x16, x0 ; TRAP-DARWIN-NEXT: autizb x16 ; TRAP-DARWIN-NEXT: mov x17, x16 ; TRAP-DARWIN-NEXT: xpaci x17 ; TRAP-DARWIN-NEXT: cmp x16, x17 ; TRAP-ELF-NEXT: autizb x0 ; TRAP-ELF-NEXT: mov x8, x0 ; TRAP-ELF-NEXT: xpaci x8 ; TRAP-ELF-NEXT: cmp x0, x8 ; TRAP-NEXT: b.eq [[L]]auth_success_3 ; TRAP-NEXT: brk #0xc471 ; TRAP-NEXT: Lauth_success_3: ; TRAP-DARWIN-NEXT: mov x0, x16 ; TRAP-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) { ; UNCHECKED-LABEL: test_auth_da: ; UNCHECKED: %bb.0: ; UNCHECKED-DARWIN-NEXT: mov x16, x0 ; UNCHECKED-DARWIN-NEXT: autda x16, x1 ; UNCHECKED-DARWIN-NEXT: mov x0, x16 ; UNCHECKED-ELF-NEXT: autda x0, x1 ; UNCHECKED-NEXT: ret ; ; CHECKED-LABEL: test_auth_da: ; CHECKED: %bb.0: ; CHECKED-DARWIN-NEXT: mov x16, x0 ; CHECKED-DARWIN-NEXT: autda x16, x1 ; CHECKED-DARWIN-NEXT: mov x0, x16 ; CHECKED-ELF-NEXT: autda x0, x1 ; CHECKED-NEXT: ret ; ; TRAP-LABEL: test_auth_da: ; TRAP: %bb.0: ; TRAP-DARWIN-NEXT: mov x16, x0 ; TRAP-DARWIN-NEXT: autda x16, x1 ; TRAP-DARWIN-NEXT: mov x17, x16 ; TRAP-DARWIN-NEXT: xpacd x17 ; TRAP-DARWIN-NEXT: cmp x16, x17 ; TRAP-ELF-NEXT: autda x0, x1 ; TRAP-ELF-NEXT: mov x8, x0 ; TRAP-ELF-NEXT: xpacd x8 ; TRAP-ELF-NEXT: cmp x0, x8 ; TRAP-NEXT: b.eq [[L]]auth_success_4 ; TRAP-NEXT: brk #0xc472 ; TRAP-NEXT: Lauth_success_4: ; TRAP-DARWIN-NEXT: mov x0, x16 ; TRAP-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) { ; UNCHECKED-LABEL: test_auth_da_zero: ; UNCHECKED: %bb.0: ; UNCHECKED-DARWIN-NEXT: mov x16, x0 ; UNCHECKED-DARWIN-NEXT: autdza x16 ; UNCHECKED-DARWIN-NEXT: mov x0, x16 ; UNCHECKED-ELF-NEXT: autdza x0 ; UNCHECKED-NEXT: ret ; ; CHECKED-LABEL: test_auth_da_zero: ; CHECKED: %bb.0: ; CHECKED-DARWIN-NEXT: mov x16, x0 ; CHECKED-DARWIN-NEXT: autdza x16 ; CHECKED-DARWIN-NEXT: mov x0, x16 ; CHECKED-ELF-NEXT: autdza x0 ; CHECKED-NEXT: ret ; ; TRAP-LABEL: test_auth_da_zero: ; TRAP: %bb.0: ; TRAP-DARWIN-NEXT: mov x16, x0 ; TRAP-DARWIN-NEXT: autdza x16 ; TRAP-DARWIN-NEXT: mov x17, x16 ; TRAP-DARWIN-NEXT: xpacd x17 ; TRAP-DARWIN-NEXT: cmp x16, x17 ; TRAP-ELF-NEXT: autdza x0 ; TRAP-ELF-NEXT: mov x8, x0 ; TRAP-ELF-NEXT: xpacd x8 ; TRAP-ELF-NEXT: cmp x0, x8 ; TRAP-NEXT: b.eq [[L]]auth_success_5 ; TRAP-NEXT: brk #0xc472 ; TRAP-NEXT: Lauth_success_5: ; TRAP-DARWIN-NEXT: mov x0, x16 ; TRAP-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) { ; UNCHECKED-LABEL: test_auth_db: ; UNCHECKED: %bb.0: ; UNCHECKED-DARWIN-NEXT: mov x16, x0 ; UNCHECKED-DARWIN-NEXT: autdb x16, x1 ; UNCHECKED-DARWIN-NEXT: mov x0, x16 ; UNCHECKED-ELF-NEXT: autdb x0, x1 ; UNCHECKED-NEXT: ret ; ; CHECKED-LABEL: test_auth_db: ; CHECKED: %bb.0: ; CHECKED-DARWIN-NEXT: mov x16, x0 ; CHECKED-DARWIN-NEXT: autdb x16, x1 ; CHECKED-DARWIN-NEXT: mov x0, x16 ; CHECKED-ELF-NEXT: autdb x0, x1 ; CHECKED-NEXT: ret ; ; TRAP-LABEL: test_auth_db: ; TRAP: %bb.0: ; TRAP-DARWIN-NEXT: mov x16, x0 ; TRAP-DARWIN-NEXT: autdb x16, x1 ; TRAP-DARWIN-NEXT: mov x17, x16 ; TRAP-DARWIN-NEXT: xpacd x17 ; TRAP-DARWIN-NEXT: cmp x16, x17 ; TRAP-ELF-NEXT: autdb x0, x1 ; TRAP-ELF-NEXT: mov x8, x0 ; TRAP-ELF-NEXT: xpacd x8 ; TRAP-ELF-NEXT: cmp x0, x8 ; TRAP-NEXT: b.eq [[L]]auth_success_6 ; TRAP-NEXT: brk #0xc473 ; TRAP-NEXT: Lauth_success_6: ; TRAP-DARWIN-NEXT: mov x0, x16 ; TRAP-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) { ; UNCHECKED-LABEL: test_auth_db_zero: ; UNCHECKED: %bb.0: ; UNCHECKED-DARWIN-NEXT: mov x16, x0 ; UNCHECKED-DARWIN-NEXT: autdzb x16 ; UNCHECKED-DARWIN-NEXT: mov x0, x16 ; UNCHECKED-ELF-NEXT: autdzb x0 ; UNCHECKED-NEXT: ret ; ; CHECKED-LABEL: test_auth_db_zero: ; CHECKED: %bb.0: ; CHECKED-DARWIN-NEXT: mov x16, x0 ; CHECKED-DARWIN-NEXT: autdzb x16 ; CHECKED-DARWIN-NEXT: mov x0, x16 ; CHECKED-ELF-NEXT: autdzb x0 ; CHECKED-NEXT: ret ; ; TRAP-LABEL: test_auth_db_zero: ; TRAP: %bb.0: ; TRAP-DARWIN-NEXT: mov x16, x0 ; TRAP-DARWIN-NEXT: autdzb x16 ; TRAP-DARWIN-NEXT: mov x17, x16 ; TRAP-DARWIN-NEXT: xpacd x17 ; TRAP-DARWIN-NEXT: cmp x16, x17 ; TRAP-ELF-NEXT: autdzb x0 ; TRAP-ELF-NEXT: mov x8, x0 ; TRAP-ELF-NEXT: xpacd x8 ; TRAP-ELF-NEXT: cmp x0, x8 ; TRAP-NEXT: b.eq [[L]]auth_success_7 ; TRAP-NEXT: brk #0xc473 ; TRAP-NEXT: Lauth_success_7: ; TRAP-DARWIN-NEXT: mov x0, x16 ; TRAP-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) { ; UNCHECKED-LABEL: test_resign_ia_ia: ; UNCHECKED: %bb.0: ; UNCHECKED-NEXT: mov x16, x0 ; UNCHECKED-NEXT: autia x16, x1 ; UNCHECKED-NEXT: pacia x16, x2 ; UNCHECKED-NEXT: mov x0, x16 ; UNCHECKED-NEXT: ret ; ; CHECKED-LABEL: test_resign_ia_ia: ; CHECKED: %bb.0: ; CHECKED-NEXT: mov x16, x0 ; CHECKED-NEXT: autia x16, x1 ; CHECKED-NEXT: mov x17, x16 ; CHECKED-NEXT: xpaci x17 ; CHECKED-NEXT: cmp x16, x17 ; CHECKED-NEXT: b.eq [[L]]auth_success_0 ; CHECKED-NEXT: mov x16, x17 ; CHECKED-NEXT: b [[L]]resign_end_0 ; CHECKED-NEXT: Lauth_success_0: ; CHECKED-NEXT: pacia x16, x2 ; CHECKED-NEXT: Lresign_end_0: ; CHECKED-NEXT: mov x0, x16 ; CHECKED-NEXT: ret ; ; TRAP-LABEL: test_resign_ia_ia: ; TRAP: %bb.0: ; TRAP-NEXT: mov x16, x0 ; TRAP-NEXT: autia x16, x1 ; TRAP-NEXT: mov x17, x16 ; TRAP-NEXT: xpaci x17 ; TRAP-NEXT: cmp x16, x17 ; TRAP-NEXT: b.eq [[L]]auth_success_8 ; TRAP-NEXT: brk #0xc470 ; TRAP-NEXT: Lauth_success_8: ; TRAP-NEXT: pacia x16, x2 ; TRAP-NEXT: mov x0, x16 ; TRAP-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) { ; UNCHECKED-LABEL: test_resign_ib_ia: ; UNCHECKED: %bb.0: ; UNCHECKED-NEXT: mov x16, x0 ; UNCHECKED-NEXT: autib x16, x1 ; UNCHECKED-NEXT: pacia x16, x2 ; UNCHECKED-NEXT: mov x0, x16 ; UNCHECKED-NEXT: ret ; ; CHECKED-LABEL: test_resign_ib_ia: ; CHECKED: %bb.0: ; CHECKED-NEXT: mov x16, x0 ; CHECKED-NEXT: autib x16, x1 ; CHECKED-NEXT: mov x17, x16 ; CHECKED-NEXT: xpaci x17 ; CHECKED-NEXT: cmp x16, x17 ; CHECKED-NEXT: b.eq [[L]]auth_success_1 ; CHECKED-NEXT: mov x16, x17 ; CHECKED-NEXT: b [[L]]resign_end_1 ; CHECKED-NEXT: Lauth_success_1: ; CHECKED-NEXT: pacia x16, x2 ; CHECKED-NEXT: Lresign_end_1: ; CHECKED-NEXT: mov x0, x16 ; CHECKED-NEXT: ret ; ; TRAP-LABEL: test_resign_ib_ia: ; TRAP: %bb.0: ; TRAP-NEXT: mov x16, x0 ; TRAP-NEXT: autib x16, x1 ; TRAP-NEXT: mov x17, x16 ; TRAP-NEXT: xpaci x17 ; TRAP-NEXT: cmp x16, x17 ; TRAP-NEXT: b.eq [[L]]auth_success_9 ; TRAP-NEXT: brk #0xc471 ; TRAP-NEXT: Lauth_success_9: ; TRAP-NEXT: pacia x16, x2 ; TRAP-NEXT: mov x0, x16 ; TRAP-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) { ; UNCHECKED-LABEL: test_resign_da_ia: ; UNCHECKED: %bb.0: ; UNCHECKED-NEXT: mov x16, x0 ; UNCHECKED-NEXT: autda x16, x1 ; UNCHECKED-NEXT: pacia x16, x2 ; UNCHECKED-NEXT: mov x0, x16 ; UNCHECKED-NEXT: ret ; ; CHECKED-LABEL: test_resign_da_ia: ; CHECKED: %bb.0: ; CHECKED-NEXT: mov x16, x0 ; CHECKED-NEXT: autda x16, x1 ; CHECKED-NEXT: mov x17, x16 ; CHECKED-NEXT: xpacd x17 ; CHECKED-NEXT: cmp x16, x17 ; CHECKED-NEXT: b.eq [[L]]auth_success_2 ; CHECKED-NEXT: mov x16, x17 ; CHECKED-NEXT: b [[L]]resign_end_2 ; CHECKED-NEXT: Lauth_success_2: ; CHECKED-NEXT: pacia x16, x2 ; CHECKED-NEXT: Lresign_end_2: ; CHECKED-NEXT: mov x0, x16 ; CHECKED-NEXT: ret ; ; TRAP-LABEL: test_resign_da_ia: ; TRAP: %bb.0: ; TRAP-NEXT: mov x16, x0 ; TRAP-NEXT: autda x16, x1 ; TRAP-NEXT: mov x17, x16 ; TRAP-NEXT: xpacd x17 ; TRAP-NEXT: cmp x16, x17 ; TRAP-NEXT: b.eq [[L]]auth_success_10 ; TRAP-NEXT: brk #0xc472 ; TRAP-NEXT: Lauth_success_10: ; TRAP-NEXT: pacia x16, x2 ; TRAP-NEXT: mov x0, x16 ; TRAP-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_da(i64 %arg, i64 %arg1, i64 %arg2) { ; UNCHECKED-LABEL: test_resign_db_da: ; UNCHECKED: %bb.0: ; UNCHECKED-NEXT: mov x16, x0 ; UNCHECKED-NEXT: autdb x16, x1 ; UNCHECKED-NEXT: pacda x16, x2 ; UNCHECKED-NEXT: mov x0, x16 ; UNCHECKED-NEXT: ret ; ; CHECKED-LABEL: test_resign_db_da: ; CHECKED: %bb.0: ; CHECKED-NEXT: mov x16, x0 ; CHECKED-NEXT: autdb x16, x1 ; CHECKED-NEXT: mov x17, x16 ; CHECKED-NEXT: xpacd x17 ; CHECKED-NEXT: cmp x16, x17 ; CHECKED-NEXT: b.eq [[L]]auth_success_3 ; CHECKED-NEXT: mov x16, x17 ; CHECKED-NEXT: b [[L]]resign_end_3 ; CHECKED-NEXT: Lauth_success_3: ; CHECKED-NEXT: pacda x16, x2 ; CHECKED-NEXT: Lresign_end_3: ; CHECKED-NEXT: mov x0, x16 ; CHECKED-NEXT: ret ; ; TRAP-LABEL: test_resign_db_da: ; TRAP: %bb.0: ; TRAP-NEXT: mov x16, x0 ; TRAP-NEXT: autdb x16, x1 ; TRAP-NEXT: mov x17, x16 ; TRAP-NEXT: xpacd x17 ; TRAP-NEXT: cmp x16, x17 ; TRAP-NEXT: b.eq [[L]]auth_success_11 ; TRAP-NEXT: brk #0xc473 ; TRAP-NEXT: Lauth_success_11: ; TRAP-NEXT: pacda x16, x2 ; TRAP-NEXT: mov x0, x16 ; TRAP-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_iza_db(i64 %arg, i64 %arg1, i64 %arg2) { ; UNCHECKED-LABEL: test_resign_iza_db: ; UNCHECKED: %bb.0: ; UNCHECKED-NEXT: mov x16, x0 ; UNCHECKED-NEXT: autiza x16 ; UNCHECKED-NEXT: pacdb x16, x2 ; UNCHECKED-NEXT: mov x0, x16 ; UNCHECKED-NEXT: ret ; ; CHECKED-LABEL: test_resign_iza_db: ; CHECKED: %bb.0: ; CHECKED-NEXT: mov x16, x0 ; CHECKED-NEXT: autiza x16 ; CHECKED-NEXT: mov x17, x16 ; CHECKED-NEXT: xpaci x17 ; CHECKED-NEXT: cmp x16, x17 ; CHECKED-NEXT: b.eq [[L]]auth_success_4 ; CHECKED-NEXT: mov x16, x17 ; CHECKED-NEXT: b [[L]]resign_end_4 ; CHECKED-NEXT: Lauth_success_4: ; CHECKED-NEXT: pacdb x16, x2 ; CHECKED-NEXT: Lresign_end_4: ; CHECKED-NEXT: mov x0, x16 ; CHECKED-NEXT: ret ; ; TRAP-LABEL: test_resign_iza_db: ; TRAP: %bb.0: ; TRAP-NEXT: mov x16, x0 ; TRAP-NEXT: autiza x16 ; TRAP-NEXT: mov x17, x16 ; TRAP-NEXT: xpaci x17 ; TRAP-NEXT: cmp x16, x17 ; TRAP-NEXT: b.eq [[L]]auth_success_12 ; TRAP-NEXT: brk #0xc470 ; TRAP-NEXT: Lauth_success_12: ; TRAP-NEXT: pacdb x16, x2 ; TRAP-NEXT: mov x0, x16 ; TRAP-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) { ; UNCHECKED-LABEL: test_resign_da_dzb: ; UNCHECKED: %bb.0: ; UNCHECKED-NEXT: mov x16, x0 ; UNCHECKED-NEXT: autda x16, x1 ; UNCHECKED-NEXT: pacdzb x16 ; UNCHECKED-NEXT: mov x0, x16 ; UNCHECKED-NEXT: ret ; ; CHECKED-LABEL: test_resign_da_dzb: ; CHECKED: %bb.0: ; CHECKED-NEXT: mov x16, x0 ; CHECKED-NEXT: autda x16, x1 ; CHECKED-NEXT: mov x17, x16 ; CHECKED-NEXT: xpacd x17 ; CHECKED-NEXT: cmp x16, x17 ; CHECKED-NEXT: b.eq [[L]]auth_success_5 ; CHECKED-NEXT: mov x16, x17 ; CHECKED-NEXT: b [[L]]resign_end_5 ; CHECKED-NEXT: Lauth_success_5: ; CHECKED-NEXT: pacdzb x16 ; CHECKED-NEXT: Lresign_end_5: ; CHECKED-NEXT: mov x0, x16 ; CHECKED-NEXT: ret ; ; TRAP-LABEL: test_resign_da_dzb: ; TRAP: %bb.0: ; TRAP-NEXT: mov x16, x0 ; TRAP-NEXT: autda x16, x1 ; TRAP-NEXT: mov x17, x16 ; TRAP-NEXT: xpacd x17 ; TRAP-NEXT: cmp x16, x17 ; TRAP-NEXT: b.eq [[L]]auth_success_13 ; TRAP-NEXT: brk #0xc472 ; TRAP-NEXT: Lauth_success_13: ; TRAP-NEXT: pacdzb x16 ; TRAP-NEXT: mov x0, x16 ; TRAP-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" { ; UNCHECKED-LABEL: test_auth_trap_attribute: ; UNCHECKED: %bb.0: ; UNCHECKED-DARWIN-NEXT: mov x16, x0 ; UNCHECKED-DARWIN-NEXT: autia x16, x1 ; UNCHECKED-DARWIN-NEXT: mov x0, x16 ; UNCHECKED-ELF-NEXT: autia x0, x1 ; UNCHECKED-NEXT: ret ; ; CHECKED-LABEL: test_auth_trap_attribute: ; CHECKED: %bb.0: ; CHECKED-DARWIN-NEXT: mov x16, x0 ; CHECKED-DARWIN-NEXT: autia x16, x1 ; CHECKED-DARWIN-NEXT: mov x17, x16 ; CHECKED-DARWIN-NEXT: xpaci x17 ; CHECKED-DARWIN-NEXT: cmp x16, x17 ; CHECKED-ELF-NEXT: autia x0, x1 ; CHECKED-ELF-NEXT: mov x8, x0 ; CHECKED-ELF-NEXT: xpaci x8 ; CHECKED-ELF-NEXT: cmp x0, x8 ; CHECKED-NEXT: b.eq [[L]]auth_success_6 ; CHECKED-NEXT: brk #0xc470 ; CHECKED-NEXT: Lauth_success_6: ; CHECKED-DARWIN-NEXT: mov x0, x16 ; CHECKED-NEXT: ret ; ; TRAP-LABEL: test_auth_trap_attribute: ; TRAP: %bb.0: ; TRAP-DARWIN-NEXT: mov x16, x0 ; TRAP-DARWIN-NEXT: autia x16, x1 ; TRAP-DARWIN-NEXT: mov x17, x16 ; TRAP-DARWIN-NEXT: xpaci x17 ; TRAP-DARWIN-NEXT: cmp x16, x17 ; TRAP-ELF-NEXT: autia x0, x1 ; TRAP-ELF-NEXT: mov x8, x0 ; TRAP-ELF-NEXT: xpaci x8 ; TRAP-ELF-NEXT: cmp x0, x8 ; TRAP-NEXT: b.eq [[L]]auth_success_14 ; TRAP-NEXT: brk #0xc470 ; TRAP-NEXT: Lauth_success_14: ; TRAP-DARWIN-NEXT: mov x0, x16 ; TRAP-NEXT: ret %tmp = call i64 @llvm.ptrauth.auth(i64 %arg, i32 0, i64 %arg1) ret i64 %tmp } define i64 @test_auth_ia_constdisc(i64 %arg) { ; UNCHECKED-LABEL: test_auth_ia_constdisc: ; UNCHECKED: %bb.0: ; UNCHECKED-DARWIN-NEXT: mov x16, x0 ; UNCHECKED-DARWIN-NEXT: mov x17, #256 ; UNCHECKED-DARWIN-NEXT: autia x16, x17 ; UNCHECKED-DARWIN-NEXT: mov x0, x16 ; UNCHECKED-ELF-NEXT: mov x8, #256 ; UNCHECKED-ELF-NEXT: autia x0, x8 ; UNCHECKED-NEXT: ret ; ; CHECKED-LABEL: test_auth_ia_constdisc: ; CHECKED: %bb.0: ; CHECKED-DARWIN-NEXT: mov x16, x0 ; CHECKED-DARWIN-NEXT: mov x17, #256 ; CHECKED-DARWIN-NEXT: autia x16, x17 ; CHECKED-DARWIN-NEXT: mov x0, x16 ; CHECKED-ELF-NEXT: mov x8, #256 ; CHECKED-ELF-NEXT: autia x0, x8 ; CHECKED-NEXT: ret ; ; TRAP-LABEL: test_auth_ia_constdisc: ; TRAP: %bb.0: ; TRAP-DARWIN-NEXT: mov x16, x0 ; TRAP-DARWIN-NEXT: mov x17, #256 ; TRAP-DARWIN-NEXT: autia x16, x17 ; TRAP-DARWIN-NEXT: mov x17, x16 ; TRAP-DARWIN-NEXT: xpaci x17 ; TRAP-DARWIN-NEXT: cmp x16, x17 ; TRAP-ELF-NEXT: mov x8, #256 ; TRAP-ELF-NEXT: autia x0, x8 ; TRAP-ELF-NEXT: mov x8, x0 ; TRAP-ELF-NEXT: xpaci x8 ; TRAP-ELF-NEXT: cmp x0, x8 ; TRAP-NEXT: b.eq [[L]]auth_success_15 ; TRAP-NEXT: brk #0xc470 ; TRAP-NEXT: Lauth_success_15: ; TRAP-DARWIN-NEXT: mov x0, x16 ; TRAP-NEXT: ret %tmp = call i64 @llvm.ptrauth.auth(i64 %arg, i32 0, i64 256) ret i64 %tmp } define i64 @test_resign_da_constdisc(i64 %arg, i64 %arg1) { ; UNCHECKED-LABEL: test_resign_da_constdisc: ; UNCHECKED: %bb.0: ; UNCHECKED-NEXT: mov x16, x0 ; UNCHECKED-NEXT: autda x16, x1 ; UNCHECKED-NEXT: mov x17, #256 ; UNCHECKED-NEXT: pacda x16, x17 ; UNCHECKED-NEXT: mov x0, x16 ; UNCHECKED-NEXT: ret ; ; CHECKED-LABEL: test_resign_da_constdisc: ; CHECKED: %bb.0: ; CHECKED-NEXT: mov x16, x0 ; CHECKED-NEXT: autda x16, x1 ; CHECKED-NEXT: mov x17, x16 ; CHECKED-NEXT: xpacd x17 ; CHECKED-NEXT: cmp x16, x17 ; CHECKED-NEXT: b.eq [[L]]auth_success_7 ; CHECKED-NEXT: mov x16, x17 ; CHECKED-NEXT: b [[L]]resign_end_6 ; CHECKED-NEXT: Lauth_success_7: ; CHECKED-NEXT: mov x17, #256 ; CHECKED-NEXT: pacda x16, x17 ; CHECKED-NEXT: Lresign_end_6: ; CHECKED-NEXT: mov x0, x16 ; CHECKED-NEXT: ret ; ; TRAP-LABEL: test_resign_da_constdisc: ; TRAP: %bb.0: ; TRAP-NEXT: mov x16, x0 ; TRAP-NEXT: autda x16, x1 ; TRAP-NEXT: mov x17, x16 ; TRAP-NEXT: xpacd x17 ; TRAP-NEXT: cmp x16, x17 ; TRAP-NEXT: b.eq [[L]]auth_success_16 ; TRAP-NEXT: brk #0xc472 ; TRAP-NEXT: Lauth_success_16: ; TRAP-NEXT: mov x17, #256 ; TRAP-NEXT: pacda x16, x17 ; TRAP-NEXT: mov x0, x16 ; TRAP-NEXT: ret %tmp = call i64 @llvm.ptrauth.resign(i64 %arg, i32 2, i64 %arg1, i32 2, i64 256) ret i64 %tmp } define i64 @test_auth_ia_swapped(i64 %arg, i64 %arg1) { ; UNCHECKED-LABEL: test_auth_ia_swapped: ; UNCHECKED: %bb.0: ; UNCHECKED-DARWIN-NEXT: mov x16, x1 ; UNCHECKED-DARWIN-NEXT: autia x16, x0 ; UNCHECKED-DARWIN-NEXT: mov x0, x16 ; UNCHECKED-ELF-NEXT: autia x1, x0 ; UNCHECKED-ELF-NEXT: mov x0, x1 ; UNCHECKED-NEXT: ret ; ; CHECKED-LABEL: test_auth_ia_swapped: ; CHECKED: %bb.0: ; CHECKED-DARWIN-NEXT: mov x16, x1 ; CHECKED-DARWIN-NEXT: autia x16, x0 ; CHECKED-DARWIN-NEXT: mov x0, x16 ; CHECKED-ELF-NEXT: autia x1, x0 ; CHECKED-ELF-NEXT: mov x0, x1 ; CHECKED-NEXT: ret ; ; TRAP-LABEL: test_auth_ia_swapped: ; TRAP: %bb.0: ; TRAP-DARWIN-NEXT: mov x16, x1 ; TRAP-DARWIN-NEXT: autia x16, x0 ; TRAP-DARWIN-NEXT: mov x17, x16 ; TRAP-DARWIN-NEXT: xpaci x17 ; TRAP-DARWIN-NEXT: cmp x16, x17 ; TRAP-ELF-NEXT: autia x1, x0 ; TRAP-ELF-NEXT: mov x8, x1 ; TRAP-ELF-NEXT: xpaci x8 ; TRAP-ELF-NEXT: cmp x1, x8 ; TRAP-NEXT: b.eq [[L]]auth_success_17 ; TRAP-NEXT: brk #0xc470 ; TRAP-NEXT: Lauth_success_17: ; TRAP-DARWIN-NEXT: mov x0, x16 ; TRAP-ELF-NEXT: mov x0, x1 ; TRAP-NEXT: ret %tmp = call i64 @llvm.ptrauth.auth(i64 %arg1, i32 0, i64 %arg) ret i64 %tmp } ; Authentications should not be speculated, as they crash on failure and it is ; perfectly correct to dynamically choose the signing schema or whether to ; perform authentication at all. define ptr @auth_speculation(i64 %signed, i1 %cond) { ; UNCHECKED-LABEL: auth_speculation: ; UNCHECKED: %bb.0: ; UNCHECKED-DARWIN-NEXT: mov x16, x0 ; UNCHECKED-DARWIN-NEXT: tbz w1, #0, [[BB_ELSE:[A-Za-z0-9_.]+]] ; UNCHECKED-DARWIN-NEXT: %bb.1: ; UNCHECKED-DARWIN-NEXT: autdza x16 ; UNCHECKED-DARWIN-NEXT: b [[BB_RETURN:[A-Za-z0-9_.]+]] ; UNCHECKED-DARWIN-NEXT: [[BB_ELSE]]: ; UNCHECKED-DARWIN-NEXT: autdzb x16 ; UNCHECKED-DARWIN-NEXT: [[BB_RETURN]]: ; UNCHECKED-DARWIN-NEXT: ldr x8, [x16] ; UNCHECKED-ELF-NEXT: tbz w1, #0, [[BB_ELSE:[A-Za-z0-9_.]+]] ; UNCHECKED-ELF-NEXT: %bb.1: ; UNCHECKED-ELF-NEXT: autdza x0 ; UNCHECKED-ELF-NEXT: b [[BB_RETURN:[A-Za-z0-9_.]+]] ; UNCHECKED-ELF-NEXT: [[BB_ELSE]]: ; UNCHECKED-ELF-NEXT: autdzb x0 ; UNCHECKED-ELF-NEXT: [[BB_RETURN]]: ; UNCHECKED-ELF-NEXT: ldr x8, [x0] ; UNCHECKED-NEXT: ldr x8, [x8] ; UNCHECKED-NEXT: ldr x8, [x8] ; UNCHECKED-NEXT: ldr x0, [x8] ; UNCHECKED-NEXT: ret ; ; CHECKED-LABEL: auth_speculation: ; CHECKED: %bb.0: ; CHECKED-DARWIN-NEXT: mov x16, x0 ; CHECKED-DARWIN-NEXT: tbz w1, #0, [[BB_ELSE:[A-Za-z0-9_.]+]] ; CHECKED-DARWIN-NEXT: %bb.1: ; CHECKED-DARWIN-NEXT: autdza x16 ; CHECKED-DARWIN-NEXT: b [[BB_RETURN:[A-Za-z0-9_.]+]] ; CHECKED-DARWIN-NEXT: [[BB_ELSE]]: ; CHECKED-DARWIN-NEXT: autdzb x16 ; CHECKED-DARWIN-NEXT: [[BB_RETURN]]: ; CHECKED-DARWIN-NEXT: ldr x8, [x16] ; CHECKED-ELF-NEXT: tbz w1, #0, [[BB_ELSE:[A-Za-z0-9_.]+]] ; CHECKED-ELF-NEXT: %bb.1: ; CHECKED-ELF-NEXT: autdza x0 ; CHECKED-ELF-NEXT: b [[BB_RETURN:[A-Za-z0-9_.]+]] ; CHECKED-ELF-NEXT: [[BB_ELSE]]: ; CHECKED-ELF-NEXT: autdzb x0 ; CHECKED-ELF-NEXT: [[BB_RETURN]]: ; CHECKED-ELF-NEXT: ldr x8, [x0] ; CHECKED-NEXT: ldr x8, [x8] ; CHECKED-NEXT: ldr x8, [x8] ; CHECKED-NEXT: ldr x0, [x8] ; CHECKED-NEXT: ret ; ; TRAP-LABEL: auth_speculation: ; TRAP: %bb.0: ; TRAP-DARWIN-NEXT: mov x16, x0 ; TRAP-DARWIN-NEXT: tbz w1, #0, [[BB_ELSE:[A-Za-z0-9_.]+]] ; TRAP-DARWIN-NEXT: %bb.1: ; TRAP-DARWIN-NEXT: autdza x16 ; TRAP-DARWIN-NEXT: mov x17, x16 ; TRAP-DARWIN-NEXT: xpacd x17 ; TRAP-DARWIN-NEXT: cmp x16, x17 ; TRAP-DARWIN-NEXT: b.eq [[L]]auth_success_18 ; TRAP-DARWIN-NEXT: brk #0xc472 ; TRAP-DARWIN-NEXT: [[L]]auth_success_18: ; TRAP-DARWIN-NEXT: b [[BB_RETURN:[A-Za-z0-9_.]+]] ; TRAP-DARWIN-NEXT: [[BB_ELSE]]: ; TRAP-DARWIN-NEXT: autdzb x16 ; TRAP-DARWIN-NEXT: mov x17, x16 ; TRAP-DARWIN-NEXT: xpacd x17 ; TRAP-DARWIN-NEXT: cmp x16, x17 ; TRAP-DARWIN-NEXT: b.eq [[L]]auth_success_19 ; TRAP-DARWIN-NEXT: brk #0xc473 ; TRAP-DARWIN-NEXT: [[L]]auth_success_19: ; TRAP-DARWIN-NEXT: [[BB_RETURN]]: ; TRAP-DARWIN-NEXT: ldr x8, [x16] ; TRAP-ELF-NEXT: tbz w1, #0, [[BB_ELSE:[A-Za-z0-9_.]+]] ; TRAP-ELF-NEXT: %bb.1: ; TRAP-ELF-NEXT: autdza x0 ; TRAP-ELF-NEXT: mov x8, x0 ; TRAP-ELF-NEXT: xpacd x8 ; TRAP-ELF-NEXT: cmp x0, x8 ; TRAP-ELF-NEXT: b.eq [[L]]auth_success_18 ; TRAP-ELF-NEXT: brk #0xc472 ; TRAP-ELF-NEXT: [[L]]auth_success_18: ; TRAP-ELF-NEXT: b [[BB_RETURN:[A-Za-z0-9_.]+]] ; TRAP-ELF-NEXT: [[BB_ELSE]]: ; TRAP-ELF-NEXT: autdzb x0 ; TRAP-ELF-NEXT: mov x8, x0 ; TRAP-ELF-NEXT: xpacd x8 ; TRAP-ELF-NEXT: cmp x0, x8 ; TRAP-ELF-NEXT: b.eq [[L]]auth_success_19 ; TRAP-ELF-NEXT: brk #0xc473 ; TRAP-ELF-NEXT: [[L]]auth_success_19: ; TRAP-ELF-NEXT: [[BB_RETURN]]: ; TRAP-ELF-NEXT: ldr x8, [x0] ; TRAP-NEXT: ldr x8, [x8] ; TRAP-NEXT: ldr x8, [x8] ; TRAP-NEXT: ldr x0, [x8] ; TRAP-NEXT: ret entry: br i1 %cond, label %if.then, label %if.else if.then: %auted.then = tail call i64 @llvm.ptrauth.auth(i64 %signed, i32 2, i64 0) br label %return if.else: %auted.else = tail call i64 @llvm.ptrauth.auth(i64 %signed, i32 3, i64 0) br label %return return: %auted = phi i64 [ %auted.then, %if.then ], [ %auted.else, %if.else ] ; A sequence of instructions that is common to both "then" and "else" ; branches and is expensive to duplicate. %ptr.0 = inttoptr i64 %auted to ptr %ptr.1 = load ptr, ptr %ptr.0 %ptr.2 = load ptr, ptr %ptr.1 %ptr.3 = load ptr, ptr %ptr.2 %ptr.4 = load ptr, ptr %ptr.3 ret ptr %ptr.4 } declare i64 @llvm.ptrauth.auth(i64, i32, i64) declare i64 @llvm.ptrauth.resign(i64, i32, i64, i32, i64)