xref: /llvm-project/llvm/test/CodeGen/AArch64/ptrauth-constant-in-code.ll (revision 5f1bb62c6bb83b9a46e3c6a45999d4468edb11e0)
1; RUN: rm -rf %t && split-file %s %t && cd %t
2
3;--- err1.ll
4
5; RUN: not --crash llc < err1.ll -mtriple aarch64-elf -mattr=+pauth \
6; RUN:   -global-isel=0 -verify-machineinstrs 2>&1 | FileCheck --check-prefix=ERR1 %s
7; RUN: not --crash llc < err1.ll -mtriple arm64-apple-ios -mattr=+pauth \
8; RUN:   -global-isel=0 -verify-machineinstrs 2>&1 | FileCheck --check-prefix=ERR1 %s
9
10@g = external global i32
11
12define ptr @foo() {
13; ERR1: LLVM ERROR: key in ptrauth global out of range [0, 3]
14  ret ptr ptrauth (ptr @g, i32 4)
15}
16
17;--- err2.ll
18
19; RUN: not --crash llc < err2.ll -mtriple aarch64-elf -mattr=+pauth \
20; RUN:   -global-isel=0 -verify-machineinstrs 2>&1 | FileCheck --check-prefix=ERR2 %s
21; RUN: not --crash llc < err2.ll -mtriple arm64-apple-ios -mattr=+pauth \
22; RUN:   -global-isel=0 -verify-machineinstrs 2>&1 | FileCheck --check-prefix=ERR2 %s
23
24@g = external global i32
25
26define ptr @foo() {
27; ERR2: LLVM ERROR: constant discriminator in ptrauth global out of range [0, 0xffff]
28  ret ptr ptrauth (ptr @g, i32 2, i64 65536)
29}
30
31;--- err3.ll
32
33; RUN: not --crash llc < err3.ll -mtriple aarch64-elf -mattr=+pauth \
34; RUN:   -global-isel=0 -verify-machineinstrs 2>&1 | FileCheck --check-prefix=ERR3 %s
35; RUN: not --crash llc < err3.ll -mtriple arm64-apple-ios -mattr=+pauth \
36; RUN:   -global-isel=0 -verify-machineinstrs 2>&1 | FileCheck --check-prefix=ERR3 %s
37
38@g_weak = extern_weak global i32
39
40define ptr @foo() {
41; ERR3: LLVM ERROR: unsupported non-zero offset in weak ptrauth global reference
42  ret ptr ptrauth (ptr getelementptr (i8, ptr @g_weak, i64 16), i32 2, i64 42)
43}
44
45;--- err4.ll
46
47; RUN: not --crash llc < err4.ll -mtriple aarch64-elf -mattr=+pauth \
48; RUN:   -global-isel=0 -verify-machineinstrs 2>&1 | FileCheck --check-prefix=ERR4 %s
49; RUN: not --crash llc < err4.ll -mtriple arm64-apple-ios -mattr=+pauth \
50; RUN:   -global-isel=0 -verify-machineinstrs 2>&1 | FileCheck --check-prefix=ERR4 %s
51
52@g_weak = extern_weak global i32
53@g_weak.ref.da.42.addr = dso_local constant ptr ptrauth (ptr @g_weak, i32 2, i64 42, ptr @g_weak.ref.da.42.addr)
54
55define ptr @foo() {
56; ERR4: LLVM ERROR: unsupported weak addr-div ptrauth global
57  ret ptr ptrauth (ptr @g_weak, i32 0, i64 42, ptr @g_weak.ref.da.42.addr)
58}
59
60;--- err5.ll
61
62; RUN: not --crash llc < err5.ll -mtriple aarch64-windows -mattr=+pauth \
63; RUN:   -global-isel=0 -verify-machineinstrs 2>&1 | FileCheck --check-prefix=ERR5 %s
64
65@g = external global i32
66
67define ptr @foo() {
68; ERR5: LLVM ERROR: ptrauth global lowering only supported on MachO/ELF
69  ret ptr ptrauth (ptr @g, i32 0)
70}
71
72;--- ok.ll
73
74; RUN: llc < ok.ll -mtriple aarch64-elf -mattr=+pauth -global-isel=0 \
75; RUN:   -verify-machineinstrs | FileCheck %s --check-prefix=ELF
76; RUN: llc < ok.ll -mtriple aarch64-elf -mattr=+pauth -global-isel=0 \
77; RUN:   -verify-machineinstrs -filetype=obj
78
79; RUN: llc < ok.ll -mtriple arm64-apple-ios -mattr=+pauth -global-isel=0 \
80; RUN:   -verify-machineinstrs | FileCheck %s --check-prefix=MACHO
81; RUN: llc < ok.ll -mtriple arm64-apple-ios -mattr=+pauth -global-isel=0 \
82; RUN:   -verify-machineinstrs -filetype=obj
83
84@g = external global i32
85@g_weak = extern_weak global i32
86@g_strong_def = dso_local constant i32 42
87
88define ptr @test_global_zero_disc() {
89; ELF-LABEL:   test_global_zero_disc:
90; ELF:         // %bb.0:
91; ELF-NEXT:      adrp    x16, :got:g
92; ELF-NEXT:      ldr     x16, [x16, :got_lo12:g]
93; ELF-NEXT:      paciza  x16
94; ELF-NEXT:      mov     x0, x16
95; ELF-NEXT:      ret
96
97; MACHO-LABEL: _test_global_zero_disc:
98; MACHO:       ; %bb.0:
99; MACHO-NEXT:    adrp    x16, _g@GOTPAGE
100; MACHO-NEXT:    ldr     x16, [x16, _g@GOTPAGEOFF]
101; MACHO-NEXT:    paciza  x16
102; MACHO-NEXT:    mov     x0, x16
103; MACHO-NEXT:    ret
104
105  ret ptr ptrauth (ptr @g, i32 0)
106}
107
108define ptr @test_global_offset_zero_disc() {
109; ELF-LABEL: test_global_offset_zero_disc:
110; ELF:       // %bb.0:
111; ELF-NEXT:    adrp    x16, :got:g
112; ELF-NEXT:    ldr     x16, [x16, :got_lo12:g]
113; ELF-NEXT:    add     x16, x16, #16
114; ELF-NEXT:    pacdza  x16
115; ELF-NEXT:    mov     x0, x16
116; ELF-NEXT:    ret
117
118; MACHO-LABEL: _test_global_offset_zero_disc:
119; MACHO:       ; %bb.0:
120; MACHO-NEXT:    adrp    x16, _g@GOTPAGE
121; MACHO-NEXT:    ldr     x16, [x16, _g@GOTPAGEOFF]
122; MACHO-NEXT:    add     x16, x16, #16
123; MACHO-NEXT:    pacdza  x16
124; MACHO-NEXT:    mov     x0, x16
125; MACHO-NEXT:    ret
126
127  ret ptr ptrauth (ptr getelementptr (i8, ptr @g, i64 16), i32 2)
128}
129
130define ptr @test_global_neg_offset_zero_disc() {
131; ELF-LABEL: test_global_neg_offset_zero_disc:
132; ELF:       // %bb.0:
133; ELF-NEXT:    adrp    x16, :got:g
134; ELF-NEXT:    ldr     x16, [x16, :got_lo12:g]
135; ELF-NEXT:    sub     x16, x16, #576
136; ELF-NEXT:    sub     x16, x16, #30, lsl #12
137; ELF-NEXT:    pacdza  x16
138; ELF-NEXT:    mov     x0, x16
139; ELF-NEXT:    ret
140
141; MACHO-LABEL: _test_global_neg_offset_zero_disc:
142; MACHO:       ; %bb.0:
143; MACHO-NEXT:    adrp    x16, _g@GOTPAGE
144; MACHO-NEXT:    ldr     x16, [x16, _g@GOTPAGEOFF]
145; MACHO-NEXT:    sub     x16, x16, #576
146; MACHO-NEXT:    sub     x16, x16, #30, lsl #12
147; MACHO-NEXT:    pacdza  x16
148; MACHO-NEXT:    mov     x0, x16
149; MACHO-NEXT:    ret
150
151  ret ptr ptrauth (ptr getelementptr (i8, ptr @g, i64 -123456), i32 2)
152}
153
154define ptr @test_global_big_offset_zero_disc() {
155; ELF-LABEL: test_global_big_offset_zero_disc:
156; ELF:       // %bb.0:
157; ELF-NEXT:    adrp    x16, :got:g
158; ELF-NEXT:    ldr     x16, [x16, :got_lo12:g]
159; ELF-NEXT:    mov     x17, #1
160; ELF-NEXT:    movk    x17, #32769, lsl #16
161; ELF-NEXT:    add     x16, x16, x17
162; ELF-NEXT:    pacdza  x16
163; ELF-NEXT:    mov     x0, x16
164; ELF-NEXT:    ret
165
166; MACHO-LABEL: _test_global_big_offset_zero_disc:
167; MACHO:       ; %bb.0:
168; MACHO-NEXT:    adrp    x16, _g@GOTPAGE
169; MACHO-NEXT:    ldr     x16, [x16, _g@GOTPAGEOFF]
170; MACHO-NEXT:    mov     x17, #1
171; MACHO-NEXT:    movk    x17, #32769, lsl #16
172; MACHO-NEXT:    add     x16, x16, x17
173; MACHO-NEXT:    pacdza  x16
174; MACHO-NEXT:    mov     x0, x16
175; MACHO-NEXT:    ret
176
177  ret ptr ptrauth (ptr getelementptr (i8, ptr @g, i64 add (i64 2147483648, i64 65537)), i32 2)
178}
179
180define ptr @test_global_big_neg_offset_zero_disc() {
181; ELF-LABEL: test_global_big_neg_offset_zero_disc:
182; ELF:       // %bb.0:
183; ELF-NEXT:    adrp    x16, :got:g
184; ELF-NEXT:    ldr     x16, [x16, :got_lo12:g]
185; ELF-NEXT:    mov     x17, #-52501
186; ELF-NEXT:    movk    x17, #63652, lsl #16
187; ELF-NEXT:    add     x16, x16, x17
188; ELF-NEXT:    pacdza  x16
189; ELF-NEXT:    mov     x0, x16
190; ELF-NEXT:    ret
191
192; MACHO-LABEL: _test_global_big_neg_offset_zero_disc:
193; MACHO:       ; %bb.0:
194; MACHO-NEXT:    adrp    x16, _g@GOTPAGE
195; MACHO-NEXT:    ldr     x16, [x16, _g@GOTPAGEOFF]
196; MACHO-NEXT:    mov     x17, #-52501
197; MACHO-NEXT:    movk    x17, #63652, lsl #16
198; MACHO-NEXT:    add     x16, x16, x17
199; MACHO-NEXT:    pacdza  x16
200; MACHO-NEXT:    mov     x0, x16
201; MACHO-NEXT:    ret
202
203  ret ptr ptrauth (ptr getelementptr (i8, ptr @g, i64 -123456789), i32 2)
204}
205
206define ptr @test_global_huge_neg_offset_zero_disc() {
207; ELF-LABEL: test_global_huge_neg_offset_zero_disc:
208; ELF:       // %bb.0:
209; ELF-NEXT:    adrp    x16, :got:g
210; ELF-NEXT:    ldr     x16, [x16, :got_lo12:g]
211; ELF-NEXT:    mov     x17, #-65536
212; ELF-NEXT:    movk    x17, #0, lsl #16
213; ELF-NEXT:    movk    x17, #0, lsl #32
214; ELF-NEXT:    movk    x17, #32768, lsl #48
215; ELF-NEXT:    add     x16, x16, x17
216; ELF-NEXT:    pacdza  x16
217; ELF-NEXT:    mov     x0, x16
218; ELF-NEXT:    ret
219
220; MACHO-LABEL: _test_global_huge_neg_offset_zero_disc:
221; MACHO:       ; %bb.0:
222; MACHO-NEXT:    adrp    x16, _g@GOTPAGE
223; MACHO-NEXT:    ldr     x16, [x16, _g@GOTPAGEOFF]
224; MACHO-NEXT:    mov     x17, #-65536
225; MACHO-NEXT:    movk    x17, #0, lsl #16
226; MACHO-NEXT:    movk    x17, #0, lsl #32
227; MACHO-NEXT:    movk    x17, #32768, lsl #48
228; MACHO-NEXT:    add     x16, x16, x17
229; MACHO-NEXT:    pacdza  x16
230; MACHO-NEXT:    mov     x0, x16
231; MACHO-NEXT:    ret
232
233  ret ptr ptrauth (ptr getelementptr (i8, ptr @g, i64 -9223372036854775808), i32 2)
234}
235
236define ptr @test_global_disc() {
237; ELF-LABEL: test_global_disc:
238; ELF:       // %bb.0:
239; ELF-NEXT:    adrp    x16, :got:g
240; ELF-NEXT:    ldr     x16, [x16, :got_lo12:g]
241; ELF-NEXT:    mov     x17, #42 // =0x2a
242; ELF-NEXT:    pacia   x16, x17
243; ELF-NEXT:    mov     x0, x16
244; ELF-NEXT:    ret
245
246; MACHO-LABEL: _test_global_disc:
247; MACHO:       ; %bb.0:
248; MACHO-NEXT:    adrp    x16, _g@GOTPAGE
249; MACHO-NEXT:    ldr     x16, [x16, _g@GOTPAGEOFF]
250; MACHO-NEXT:    mov     x17, #42 ; =0x2a
251; MACHO-NEXT:    pacia   x16, x17
252; MACHO-NEXT:    mov     x0, x16
253; MACHO-NEXT:    ret
254
255  ret ptr ptrauth (ptr @g, i32 0, i64 42)
256}
257
258@g.ref.da.42.addr = dso_local constant ptr ptrauth (ptr @g, i32 2, i64 42, ptr @g.ref.da.42.addr)
259
260define ptr @test_global_addr_disc() {
261; ELF-LABEL: test_global_addr_disc:
262; ELF:       // %bb.0:
263; ELF-NEXT:    adrp x8, g.ref.da.42.addr
264; ELF-NEXT:    add x8, x8, :lo12:g.ref.da.42.addr
265; ELF-NEXT:    adrp x16, :got:g
266; ELF-NEXT:    ldr x16, [x16, :got_lo12:g]
267; ELF-NEXT:    mov x17, x8
268; ELF-NEXT:    movk x17, #42, lsl #48
269; ELF-NEXT:    pacda x16, x17
270; ELF-NEXT:    mov x0, x16
271; ELF-NEXT:    ret
272
273; MACHO-LABEL: _test_global_addr_disc:
274; MACHO:       ; %bb.0:
275; MACHO-NEXT:   Lloh{{.*}}:
276; MACHO-NEXT:    adrp x8, _g.ref.da.42.addr@PAGE
277; MACHO-NEXT:   Lloh{{.*}}:
278; MACHO-NEXT:    add x8, x8, _g.ref.da.42.addr@PAGEOFF
279; MACHO-NEXT:    adrp x16, _g@GOTPAGE
280; MACHO-NEXT:    ldr x16, [x16, _g@GOTPAGEOFF]
281; MACHO-NEXT:    mov x17, x8
282; MACHO-NEXT:    movk x17, #42, lsl #48
283; MACHO-NEXT:    pacda x16, x17
284; MACHO-NEXT:    mov x0, x16
285; MACHO-NEXT:    ret
286
287  ret ptr ptrauth (ptr @g, i32 2, i64 42, ptr @g.ref.da.42.addr)
288}
289
290define ptr @test_global_process_specific() {
291; ELF-LABEL: test_global_process_specific:
292; ELF:       // %bb.0:
293; ELF-NEXT:    adrp    x16, :got:g
294; ELF-NEXT:    ldr     x16, [x16, :got_lo12:g]
295; ELF-NEXT:    pacizb  x16
296; ELF-NEXT:    mov     x0, x16
297; ELF-NEXT:    ret
298
299; MACHO-LABEL: _test_global_process_specific:
300; MACHO:       ; %bb.0:
301; MACHO-NEXT:    adrp    x16, _g@GOTPAGE
302; MACHO-NEXT:    ldr     x16, [x16, _g@GOTPAGEOFF]
303; MACHO-NEXT:    pacizb  x16
304; MACHO-NEXT:    mov     x0, x16
305; MACHO-NEXT:    ret
306
307  ret ptr ptrauth (ptr @g, i32 1)
308}
309
310; Non-external symbols don't need to be accessed through the GOT.
311
312define ptr @test_global_strong_def() {
313; ELF-LABEL: test_global_strong_def:
314; ELF:       // %bb.0:
315; ELF-NEXT:    adrp    x16, g_strong_def
316; ELF-NEXT:    add     x16, x16, :lo12:g_strong_def
317; ELF-NEXT:    pacdza  x16
318; ELF-NEXT:    mov     x0, x16
319; ELF-NEXT:    ret
320
321; MACHO-LABEL: _test_global_strong_def:
322; MACHO:       ; %bb.0:
323; MACHO-NEXT:    adrp    x16, _g_strong_def@PAGE
324; MACHO-NEXT:    add     x16, x16, _g_strong_def@PAGEOFF
325; MACHO-NEXT:    pacdza  x16
326; MACHO-NEXT:    mov     x0, x16
327; MACHO-NEXT:    ret
328
329  ret ptr ptrauth (ptr @g_strong_def, i32 2)
330}
331
332; weak symbols can't be assumed to be non-nil. Use $auth_ptr$ stub slot always.
333; The alternative is to emit a null-check here, but that'd be redundant with
334; whatever null-check follows in user code.
335
336define ptr @test_global_weak() {
337; ELF-LABEL: test_global_weak:
338; ELF:       // %bb.0:
339; ELF-NEXT:    adrp    x0, g_weak$auth_ptr$ia$42
340; ELF-NEXT:    ldr     x0, [x0, :lo12:g_weak$auth_ptr$ia$42]
341; ELF-NEXT:    ret
342
343; MACHO-LABEL: _test_global_weak:
344; MACHO:       ; %bb.0:
345; MACHO-NEXT:    adrp    x0, l_g_weak$auth_ptr$ia$42@PAGE
346; MACHO-NEXT:    ldr     x0, [x0, l_g_weak$auth_ptr$ia$42@PAGEOFF]
347; MACHO-NEXT:    ret
348
349  ret ptr ptrauth (ptr @g_weak, i32 0, i64 42)
350}
351
352; Test another weak symbol to check that stubs are emitted in a stable order.
353
354@g_weak_2 = extern_weak global i32
355
356define ptr @test_global_weak_2() {
357; ELF-LABEL: test_global_weak_2:
358; ELF:       // %bb.0:
359; ELF-NEXT:    adrp    x0, g_weak_2$auth_ptr$ia$42
360; ELF-NEXT:    ldr     x0, [x0, :lo12:g_weak_2$auth_ptr$ia$42]
361; ELF-NEXT:    ret
362
363; MACHO-LABEL: _test_global_weak_2:
364; MACHO:       ; %bb.0:
365; MACHO-NEXT:    adrp    x0, l_g_weak_2$auth_ptr$ia$42@PAGE
366; MACHO-NEXT:    ldr     x0, [x0, l_g_weak_2$auth_ptr$ia$42@PAGEOFF]
367; MACHO-NEXT:    ret
368
369  ret ptr ptrauth (ptr @g_weak_2, i32 0, i64 42)
370}
371
372; ELF-LABEL: g_weak$auth_ptr$ia$42:
373; ELF-NEXT:    .xword  g_weak@AUTH(ia,42)
374; ELF-LABEL: g_weak_2$auth_ptr$ia$42:
375; ELF-NEXT:    .xword  g_weak_2@AUTH(ia,42)
376
377; MACHO-LABEL: l_g_weak$auth_ptr$ia$42:
378; MACHO-NEXT:    .quad  _g_weak@AUTH(ia,42)
379; MACHO-LABEL: l_g_weak_2$auth_ptr$ia$42:
380; MACHO-NEXT:    .quad  _g_weak_2@AUTH(ia,42)
381