1 ; RUN: rm -rf %t && split-file %s %t && cd %t
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
10 @g = external global i32
13 ; ERR1: LLVM ERROR: key in ptrauth global out of range [0, 3]
14 ret ptr ptrauth (ptr @g, i32 4)
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
24 @g = external global i32
27 ; ERR2: LLVM ERROR: constant discriminator in ptrauth global out of range [0, 0xffff]
28 ret ptr ptrauth (ptr @g, i32 2, i64 65536)
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
38 @g_weak = extern_weak global i32
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)
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
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)
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)
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
65 @g = external global i32
68 ; ERR5: LLVM ERROR: ptrauth global lowering only supported on MachO/ELF
69 ret ptr ptrauth (ptr @g, i32 0)
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
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
84 @g = external global i32
85 @g_weak = extern_weak global i32
86 @g_strong_def = dso_local constant i32 42
88 define ptr @test_global_zero_disc() {
89 ; ELF-LABEL: test_global_zero_disc:
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
97 ; MACHO-LABEL: _test_global_zero_disc:
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
105 ret ptr ptrauth (ptr @g, i32 0)
108 define ptr @test_global_offset_zero_disc() {
109 ; ELF-LABEL: test_global_offset_zero_disc:
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
118 ; MACHO-LABEL: _test_global_offset_zero_disc:
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
127 ret ptr ptrauth (ptr getelementptr (i8, ptr @g, i64 16), i32 2)
130 define ptr @test_global_neg_offset_zero_disc() {
131 ; ELF-LABEL: test_global_neg_offset_zero_disc:
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
141 ; MACHO-LABEL: _test_global_neg_offset_zero_disc:
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
151 ret ptr ptrauth (ptr getelementptr (i8, ptr @g, i64 -123456), i32 2)
154 define ptr @test_global_big_offset_zero_disc() {
155 ; ELF-LABEL: test_global_big_offset_zero_disc:
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
166 ; MACHO-LABEL: _test_global_big_offset_zero_disc:
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
177 ret ptr ptrauth (ptr getelementptr (i8, ptr @g, i64 add (i64 2147483648, i64 65537)), i32 2)
180 define ptr @test_global_big_neg_offset_zero_disc() {
181 ; ELF-LABEL: test_global_big_neg_offset_zero_disc:
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
192 ; MACHO-LABEL: _test_global_big_neg_offset_zero_disc:
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
203 ret ptr ptrauth (ptr getelementptr (i8, ptr @g, i64 -123456789), i32 2)
206 define ptr @test_global_huge_neg_offset_zero_disc() {
207 ; ELF-LABEL: test_global_huge_neg_offset_zero_disc:
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
220 ; MACHO-LABEL: _test_global_huge_neg_offset_zero_disc:
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
233 ret ptr ptrauth (ptr getelementptr (i8, ptr @g, i64 -9223372036854775808), i32 2)
236 define ptr @test_global_disc() {
237 ; ELF-LABEL: test_global_disc:
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
246 ; MACHO-LABEL: _test_global_disc:
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
255 ret ptr ptrauth (ptr @g, i32 0, i64 42)
258 @g.ref.da.42.addr = dso_local constant ptr ptrauth (ptr @g, i32 2, i64 42, ptr @g.ref.da.42.addr)
260 define ptr @test_global_addr_disc() {
261 ; ELF-LABEL: test_global_addr_disc:
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
273 ; MACHO-LABEL: _test_global_addr_disc:
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
287 ret ptr ptrauth (ptr @g, i32 2, i64 42, ptr @g.ref.da.42.addr)
290 define ptr @test_global_process_specific() {
291 ; ELF-LABEL: test_global_process_specific:
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
299 ; MACHO-LABEL: _test_global_process_specific:
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
307 ret ptr ptrauth (ptr @g, i32 1)
310 ; Non-external symbols don't need to be accessed through the GOT.
312 define ptr @test_global_strong_def() {
313 ; ELF-LABEL: test_global_strong_def:
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
321 ; MACHO-LABEL: _test_global_strong_def:
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
329 ret ptr ptrauth (ptr @g_strong_def, i32 2)
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.
336 define ptr @test_global_weak() {
337 ; ELF-LABEL: test_global_weak:
339 ; ELF-NEXT: adrp x0, g_weak$auth_ptr$ia$42
340 ; ELF-NEXT: ldr x0, [x0, :lo12:g_weak$auth_ptr$ia$42]
343 ; MACHO-LABEL: _test_global_weak:
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]
349 ret ptr ptrauth (ptr @g_weak, i32 0, i64 42)
352 ; Test another weak symbol to check that stubs are emitted in a stable order.
354 @g_weak_2 = extern_weak global i32
356 define ptr @test_global_weak_2() {
357 ; ELF-LABEL: test_global_weak_2:
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]
363 ; MACHO-LABEL: _test_global_weak_2:
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]
369 ret ptr ptrauth (ptr @g_weak_2, i32 0, i64 42)
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)
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)