Skip to content

Commit 557cd75

Browse files
committed
[AArch64][PAC] Don't emit auth/resign checks when targeting FPAC.
When the FPAC feature is present, we can rely on its faulting behavior to avoid emitting the expensive authentication failure check sequence ourvelves. In which case we emit the same sequence as a plain unchecked auth/resign.
1 parent e97643f commit 557cd75

File tree

2 files changed

+379
-0
lines changed

2 files changed

+379
-0
lines changed

llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1693,6 +1693,11 @@ void AArch64AsmPrinter::emitPtrauthAuthResign(const MachineInstr *MI) {
16931693
// In the checked sequence, we only trap if explicitly requested.
16941694
bool ShouldTrap = MF->getFunction().hasFnAttribute("ptrauth-auth-traps");
16951695

1696+
// On an FPAC CPU, you get traps whether you want them or not: there's
1697+
// no point in emitting checks or traps.
1698+
if (STI->hasFPAC())
1699+
ShouldCheck = ShouldTrap = false;
1700+
16961701
// However, command-line flags can override this, for experimentation.
16971702
switch (PtrauthAuthChecks) {
16981703
case PtrauthCheckMode::Default:
Lines changed: 374 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,374 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc < %s -mtriple arm64e-apple-darwin -verify-machineinstrs | FileCheck %s --check-prefixes=ALL,NOFPAC
3+
; RUN: llc < %s -mtriple arm64e-apple-darwin -mattr=+fpac -verify-machineinstrs | FileCheck %s --check-prefixes=ALL,FPAC
4+
5+
target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
6+
7+
define i64 @test_auth_ia(i64 %arg, i64 %arg1) {
8+
; ALL-LABEL: test_auth_ia:
9+
; ALL: ; %bb.0:
10+
; ALL-NEXT: mov x16, x0
11+
; ALL-NEXT: autia x16, x1
12+
; ALL-NEXT: mov x0, x16
13+
; ALL-NEXT: ret
14+
%tmp = call i64 @llvm.ptrauth.auth(i64 %arg, i32 0, i64 %arg1)
15+
ret i64 %tmp
16+
}
17+
18+
define i64 @test_auth_ia_zero(i64 %arg) {
19+
; ALL-LABEL: test_auth_ia_zero:
20+
; ALL: ; %bb.0:
21+
; ALL-NEXT: mov x16, x0
22+
; ALL-NEXT: autiza x16
23+
; ALL-NEXT: mov x0, x16
24+
; ALL-NEXT: ret
25+
%tmp = call i64 @llvm.ptrauth.auth(i64 %arg, i32 0, i64 0)
26+
ret i64 %tmp
27+
}
28+
29+
define i64 @test_auth_ib(i64 %arg, i64 %arg1) {
30+
; ALL-LABEL: test_auth_ib:
31+
; ALL: ; %bb.0:
32+
; ALL-NEXT: mov x16, x0
33+
; ALL-NEXT: autib x16, x1
34+
; ALL-NEXT: mov x0, x16
35+
; ALL-NEXT: ret
36+
%tmp = call i64 @llvm.ptrauth.auth(i64 %arg, i32 1, i64 %arg1)
37+
ret i64 %tmp
38+
}
39+
40+
define i64 @test_auth_ib_zero(i64 %arg) {
41+
; ALL-LABEL: test_auth_ib_zero:
42+
; ALL: ; %bb.0:
43+
; ALL-NEXT: mov x16, x0
44+
; ALL-NEXT: autizb x16
45+
; ALL-NEXT: mov x0, x16
46+
; ALL-NEXT: ret
47+
%tmp = call i64 @llvm.ptrauth.auth(i64 %arg, i32 1, i64 0)
48+
ret i64 %tmp
49+
}
50+
51+
define i64 @test_auth_da(i64 %arg, i64 %arg1) {
52+
; ALL-LABEL: test_auth_da:
53+
; ALL: ; %bb.0:
54+
; ALL-NEXT: mov x16, x0
55+
; ALL-NEXT: autda x16, x1
56+
; ALL-NEXT: mov x0, x16
57+
; ALL-NEXT: ret
58+
%tmp = call i64 @llvm.ptrauth.auth(i64 %arg, i32 2, i64 %arg1)
59+
ret i64 %tmp
60+
}
61+
62+
define i64 @test_auth_da_zero(i64 %arg) {
63+
; ALL-LABEL: test_auth_da_zero:
64+
; ALL: ; %bb.0:
65+
; ALL-NEXT: mov x16, x0
66+
; ALL-NEXT: autdza x16
67+
; ALL-NEXT: mov x0, x16
68+
; ALL-NEXT: ret
69+
%tmp = call i64 @llvm.ptrauth.auth(i64 %arg, i32 2, i64 0)
70+
ret i64 %tmp
71+
}
72+
73+
define i64 @test_auth_db(i64 %arg, i64 %arg1) {
74+
; ALL-LABEL: test_auth_db:
75+
; ALL: ; %bb.0:
76+
; ALL-NEXT: mov x16, x0
77+
; ALL-NEXT: autdb x16, x1
78+
; ALL-NEXT: mov x0, x16
79+
; ALL-NEXT: ret
80+
%tmp = call i64 @llvm.ptrauth.auth(i64 %arg, i32 3, i64 %arg1)
81+
ret i64 %tmp
82+
}
83+
84+
define i64 @test_auth_db_zero(i64 %arg) {
85+
; ALL-LABEL: test_auth_db_zero:
86+
; ALL: ; %bb.0:
87+
; ALL-NEXT: mov x16, x0
88+
; ALL-NEXT: autdzb x16
89+
; ALL-NEXT: mov x0, x16
90+
; ALL-NEXT: ret
91+
%tmp = call i64 @llvm.ptrauth.auth(i64 %arg, i32 3, i64 0)
92+
ret i64 %tmp
93+
}
94+
95+
; Note that this might seem like a no-op but is actually a valid way to enforce
96+
; the validity of a signature.
97+
define i64 @test_resign_ia_ia(i64 %arg, i64 %arg1, i64 %arg2) {
98+
; NOFPAC-LABEL: test_resign_ia_ia:
99+
; NOFPAC: ; %bb.0:
100+
; NOFPAC-NEXT: mov x16, x0
101+
; NOFPAC-NEXT: autia x16, x1
102+
; NOFPAC-NEXT: mov x17, x16
103+
; NOFPAC-NEXT: xpaci x17
104+
; NOFPAC-NEXT: cmp x16, x17
105+
; NOFPAC-NEXT: b.eq Lauth_success_0
106+
; NOFPAC-NEXT: mov x16, x17
107+
; NOFPAC-NEXT: b Lresign_end_0
108+
; NOFPAC-NEXT: Lauth_success_0:
109+
; NOFPAC-NEXT: pacia x16, x2
110+
; NOFPAC-NEXT: Lresign_end_0:
111+
; NOFPAC-NEXT: mov x0, x16
112+
; NOFPAC-NEXT: ret
113+
;
114+
; FPAC-LABEL: test_resign_ia_ia:
115+
; FPAC: ; %bb.0:
116+
; FPAC-NEXT: mov x16, x0
117+
; FPAC-NEXT: autia x16, x1
118+
; FPAC-NEXT: pacia x16, x2
119+
; FPAC-NEXT: mov x0, x16
120+
; FPAC-NEXT: ret
121+
%tmp = call i64 @llvm.ptrauth.resign(i64 %arg, i32 0, i64 %arg1, i32 0, i64 %arg2)
122+
ret i64 %tmp
123+
}
124+
125+
define i64 @test_resign_ib_ia(i64 %arg, i64 %arg1, i64 %arg2) {
126+
; NOFPAC-LABEL: test_resign_ib_ia:
127+
; NOFPAC: ; %bb.0:
128+
; NOFPAC-NEXT: mov x16, x0
129+
; NOFPAC-NEXT: autib x16, x1
130+
; NOFPAC-NEXT: mov x17, x16
131+
; NOFPAC-NEXT: xpaci x17
132+
; NOFPAC-NEXT: cmp x16, x17
133+
; NOFPAC-NEXT: b.eq Lauth_success_1
134+
; NOFPAC-NEXT: mov x16, x17
135+
; NOFPAC-NEXT: b Lresign_end_1
136+
; NOFPAC-NEXT: Lauth_success_1:
137+
; NOFPAC-NEXT: pacia x16, x2
138+
; NOFPAC-NEXT: Lresign_end_1:
139+
; NOFPAC-NEXT: mov x0, x16
140+
; NOFPAC-NEXT: ret
141+
;
142+
; FPAC-LABEL: test_resign_ib_ia:
143+
; FPAC: ; %bb.0:
144+
; FPAC-NEXT: mov x16, x0
145+
; FPAC-NEXT: autib x16, x1
146+
; FPAC-NEXT: pacia x16, x2
147+
; FPAC-NEXT: mov x0, x16
148+
; FPAC-NEXT: ret
149+
%tmp = call i64 @llvm.ptrauth.resign(i64 %arg, i32 1, i64 %arg1, i32 0, i64 %arg2)
150+
ret i64 %tmp
151+
}
152+
153+
define i64 @test_resign_da_ia(i64 %arg, i64 %arg1, i64 %arg2) {
154+
; NOFPAC-LABEL: test_resign_da_ia:
155+
; NOFPAC: ; %bb.0:
156+
; NOFPAC-NEXT: mov x16, x0
157+
; NOFPAC-NEXT: autda x16, x1
158+
; NOFPAC-NEXT: mov x17, x16
159+
; NOFPAC-NEXT: xpacd x17
160+
; NOFPAC-NEXT: cmp x16, x17
161+
; NOFPAC-NEXT: b.eq Lauth_success_2
162+
; NOFPAC-NEXT: mov x16, x17
163+
; NOFPAC-NEXT: b Lresign_end_2
164+
; NOFPAC-NEXT: Lauth_success_2:
165+
; NOFPAC-NEXT: pacia x16, x2
166+
; NOFPAC-NEXT: Lresign_end_2:
167+
; NOFPAC-NEXT: mov x0, x16
168+
; NOFPAC-NEXT: ret
169+
;
170+
; FPAC-LABEL: test_resign_da_ia:
171+
; FPAC: ; %bb.0:
172+
; FPAC-NEXT: mov x16, x0
173+
; FPAC-NEXT: autda x16, x1
174+
; FPAC-NEXT: pacia x16, x2
175+
; FPAC-NEXT: mov x0, x16
176+
; FPAC-NEXT: ret
177+
%tmp = call i64 @llvm.ptrauth.resign(i64 %arg, i32 2, i64 %arg1, i32 0, i64 %arg2)
178+
ret i64 %tmp
179+
}
180+
181+
define i64 @test_resign_db_ia(i64 %arg, i64 %arg1, i64 %arg2) {
182+
; NOFPAC-LABEL: test_resign_db_ia:
183+
; NOFPAC: ; %bb.0:
184+
; NOFPAC-NEXT: mov x16, x0
185+
; NOFPAC-NEXT: autdb x16, x1
186+
; NOFPAC-NEXT: mov x17, x16
187+
; NOFPAC-NEXT: xpacd x17
188+
; NOFPAC-NEXT: cmp x16, x17
189+
; NOFPAC-NEXT: b.eq Lauth_success_3
190+
; NOFPAC-NEXT: mov x16, x17
191+
; NOFPAC-NEXT: b Lresign_end_3
192+
; NOFPAC-NEXT: Lauth_success_3:
193+
; NOFPAC-NEXT: pacia x16, x2
194+
; NOFPAC-NEXT: Lresign_end_3:
195+
; NOFPAC-NEXT: mov x0, x16
196+
; NOFPAC-NEXT: ret
197+
;
198+
; FPAC-LABEL: test_resign_db_ia:
199+
; FPAC: ; %bb.0:
200+
; FPAC-NEXT: mov x16, x0
201+
; FPAC-NEXT: autdb x16, x1
202+
; FPAC-NEXT: pacia x16, x2
203+
; FPAC-NEXT: mov x0, x16
204+
; FPAC-NEXT: ret
205+
%tmp = call i64 @llvm.ptrauth.resign(i64 %arg, i32 3, i64 %arg1, i32 0, i64 %arg2)
206+
ret i64 %tmp
207+
}
208+
209+
define i64 @test_resign_db_ib(i64 %arg, i64 %arg1, i64 %arg2) {
210+
; NOFPAC-LABEL: test_resign_db_ib:
211+
; NOFPAC: ; %bb.0:
212+
; NOFPAC-NEXT: mov x16, x0
213+
; NOFPAC-NEXT: autdb x16, x1
214+
; NOFPAC-NEXT: mov x17, x16
215+
; NOFPAC-NEXT: xpacd x17
216+
; NOFPAC-NEXT: cmp x16, x17
217+
; NOFPAC-NEXT: b.eq Lauth_success_4
218+
; NOFPAC-NEXT: mov x16, x17
219+
; NOFPAC-NEXT: b Lresign_end_4
220+
; NOFPAC-NEXT: Lauth_success_4:
221+
; NOFPAC-NEXT: pacib x16, x2
222+
; NOFPAC-NEXT: Lresign_end_4:
223+
; NOFPAC-NEXT: mov x0, x16
224+
; NOFPAC-NEXT: ret
225+
;
226+
; FPAC-LABEL: test_resign_db_ib:
227+
; FPAC: ; %bb.0:
228+
; FPAC-NEXT: mov x16, x0
229+
; FPAC-NEXT: autdb x16, x1
230+
; FPAC-NEXT: pacib x16, x2
231+
; FPAC-NEXT: mov x0, x16
232+
; FPAC-NEXT: ret
233+
%tmp = call i64 @llvm.ptrauth.resign(i64 %arg, i32 3, i64 %arg1, i32 1, i64 %arg2)
234+
ret i64 %tmp
235+
}
236+
237+
define i64 @test_resign_db_da(i64 %arg, i64 %arg1, i64 %arg2) {
238+
; NOFPAC-LABEL: test_resign_db_da:
239+
; NOFPAC: ; %bb.0:
240+
; NOFPAC-NEXT: mov x16, x0
241+
; NOFPAC-NEXT: autdb x16, x1
242+
; NOFPAC-NEXT: mov x17, x16
243+
; NOFPAC-NEXT: xpacd x17
244+
; NOFPAC-NEXT: cmp x16, x17
245+
; NOFPAC-NEXT: b.eq Lauth_success_5
246+
; NOFPAC-NEXT: mov x16, x17
247+
; NOFPAC-NEXT: b Lresign_end_5
248+
; NOFPAC-NEXT: Lauth_success_5:
249+
; NOFPAC-NEXT: pacda x16, x2
250+
; NOFPAC-NEXT: Lresign_end_5:
251+
; NOFPAC-NEXT: mov x0, x16
252+
; NOFPAC-NEXT: ret
253+
;
254+
; FPAC-LABEL: test_resign_db_da:
255+
; FPAC: ; %bb.0:
256+
; FPAC-NEXT: mov x16, x0
257+
; FPAC-NEXT: autdb x16, x1
258+
; FPAC-NEXT: pacda x16, x2
259+
; FPAC-NEXT: mov x0, x16
260+
; FPAC-NEXT: ret
261+
%tmp = call i64 @llvm.ptrauth.resign(i64 %arg, i32 3, i64 %arg1, i32 2, i64 %arg2)
262+
ret i64 %tmp
263+
}
264+
265+
define i64 @test_resign_db_db(i64 %arg, i64 %arg1, i64 %arg2) {
266+
; NOFPAC-LABEL: test_resign_db_db:
267+
; NOFPAC: ; %bb.0:
268+
; NOFPAC-NEXT: mov x16, x0
269+
; NOFPAC-NEXT: autdb x16, x1
270+
; NOFPAC-NEXT: mov x17, x16
271+
; NOFPAC-NEXT: xpacd x17
272+
; NOFPAC-NEXT: cmp x16, x17
273+
; NOFPAC-NEXT: b.eq Lauth_success_6
274+
; NOFPAC-NEXT: mov x16, x17
275+
; NOFPAC-NEXT: b Lresign_end_6
276+
; NOFPAC-NEXT: Lauth_success_6:
277+
; NOFPAC-NEXT: pacdb x16, x2
278+
; NOFPAC-NEXT: Lresign_end_6:
279+
; NOFPAC-NEXT: mov x0, x16
280+
; NOFPAC-NEXT: ret
281+
;
282+
; FPAC-LABEL: test_resign_db_db:
283+
; FPAC: ; %bb.0:
284+
; FPAC-NEXT: mov x16, x0
285+
; FPAC-NEXT: autdb x16, x1
286+
; FPAC-NEXT: pacdb x16, x2
287+
; FPAC-NEXT: mov x0, x16
288+
; FPAC-NEXT: ret
289+
%tmp = call i64 @llvm.ptrauth.resign(i64 %arg, i32 3, i64 %arg1, i32 3, i64 %arg2)
290+
ret i64 %tmp
291+
}
292+
293+
define i64 @test_resign_iza_db(i64 %arg, i64 %arg1, i64 %arg2) {
294+
; NOFPAC-LABEL: test_resign_iza_db:
295+
; NOFPAC: ; %bb.0:
296+
; NOFPAC-NEXT: mov x16, x0
297+
; NOFPAC-NEXT: autiza x16
298+
; NOFPAC-NEXT: mov x17, x16
299+
; NOFPAC-NEXT: xpaci x17
300+
; NOFPAC-NEXT: cmp x16, x17
301+
; NOFPAC-NEXT: b.eq Lauth_success_7
302+
; NOFPAC-NEXT: mov x16, x17
303+
; NOFPAC-NEXT: b Lresign_end_7
304+
; NOFPAC-NEXT: Lauth_success_7:
305+
; NOFPAC-NEXT: pacdb x16, x2
306+
; NOFPAC-NEXT: Lresign_end_7:
307+
; NOFPAC-NEXT: mov x0, x16
308+
; NOFPAC-NEXT: ret
309+
;
310+
; FPAC-LABEL: test_resign_iza_db:
311+
; FPAC: ; %bb.0:
312+
; FPAC-NEXT: mov x16, x0
313+
; FPAC-NEXT: autiza x16
314+
; FPAC-NEXT: pacdb x16, x2
315+
; FPAC-NEXT: mov x0, x16
316+
; FPAC-NEXT: ret
317+
%tmp = call i64 @llvm.ptrauth.resign(i64 %arg, i32 0, i64 0, i32 3, i64 %arg2)
318+
ret i64 %tmp
319+
}
320+
321+
define i64 @test_resign_da_dzb(i64 %arg, i64 %arg1, i64 %arg2) {
322+
; NOFPAC-LABEL: test_resign_da_dzb:
323+
; NOFPAC: ; %bb.0:
324+
; NOFPAC-NEXT: mov x16, x0
325+
; NOFPAC-NEXT: autda x16, x1
326+
; NOFPAC-NEXT: mov x17, x16
327+
; NOFPAC-NEXT: xpacd x17
328+
; NOFPAC-NEXT: cmp x16, x17
329+
; NOFPAC-NEXT: b.eq Lauth_success_8
330+
; NOFPAC-NEXT: mov x16, x17
331+
; NOFPAC-NEXT: b Lresign_end_8
332+
; NOFPAC-NEXT: Lauth_success_8:
333+
; NOFPAC-NEXT: pacdzb x16
334+
; NOFPAC-NEXT: Lresign_end_8:
335+
; NOFPAC-NEXT: mov x0, x16
336+
; NOFPAC-NEXT: ret
337+
;
338+
; FPAC-LABEL: test_resign_da_dzb:
339+
; FPAC: ; %bb.0:
340+
; FPAC-NEXT: mov x16, x0
341+
; FPAC-NEXT: autda x16, x1
342+
; FPAC-NEXT: pacdzb x16
343+
; FPAC-NEXT: mov x0, x16
344+
; FPAC-NEXT: ret
345+
%tmp = call i64 @llvm.ptrauth.resign(i64 %arg, i32 2, i64 %arg1, i32 3, i64 0)
346+
ret i64 %tmp
347+
}
348+
349+
define i64 @test_auth_trap_attribute(i64 %arg, i64 %arg1) "ptrauth-auth-traps" {
350+
; NOFPAC-LABEL: test_auth_trap_attribute:
351+
; NOFPAC: ; %bb.0:
352+
; NOFPAC-NEXT: mov x16, x0
353+
; NOFPAC-NEXT: autia x16, x1
354+
; NOFPAC-NEXT: mov x17, x16
355+
; NOFPAC-NEXT: xpaci x17
356+
; NOFPAC-NEXT: cmp x16, x17
357+
; NOFPAC-NEXT: b.eq Lauth_success_9
358+
; NOFPAC-NEXT: brk #0xc470
359+
; NOFPAC-NEXT: Lauth_success_9:
360+
; NOFPAC-NEXT: mov x0, x16
361+
; NOFPAC-NEXT: ret
362+
;
363+
; FPAC-LABEL: test_auth_trap_attribute:
364+
; FPAC: ; %bb.0:
365+
; FPAC-NEXT: mov x16, x0
366+
; FPAC-NEXT: autia x16, x1
367+
; FPAC-NEXT: mov x0, x16
368+
; FPAC-NEXT: ret
369+
%tmp = call i64 @llvm.ptrauth.auth(i64 %arg, i32 0, i64 %arg1)
370+
ret i64 %tmp
371+
}
372+
373+
declare i64 @llvm.ptrauth.auth(i64, i32, i64)
374+
declare i64 @llvm.ptrauth.resign(i64, i32, i64, i32, i64)

0 commit comments

Comments
 (0)