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