[llvm] [PAC][CodeGen][ELF][AArch64] Support signed GOT with tiny code model (PR #114525)
Daniil Kovalev via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 1 02:30:21 PDT 2024
https://github.com/kovdan01 created https://github.com/llvm/llvm-project/pull/114525
Support the following relocations and assembly operators:
- `R_AARCH64_AUTH_GOT_ADR_PREL_LO21` (`:got_auth:` for `adr`)
- `R_AARCH64_AUTH_GOT_LD_PREL19` (`:got_auth:` for `ldr`)
`LOADgotAUTH` pseudo-instruction is expanded to actual instruction sequence like the following.
```
adr x16, :got_auth:sym
ldr x0, [x16]
autia x0, x16
```
Both SelectionDAG and GlobalISel are suppported. For FastISel, we fall back to SelectionDAG.
Tests starting with 'ptrauth-' have corresponding variants w/o this prefix.
>From 2bde6a50a2c168bed56874c2406115ea75102875 Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Sun, 27 Oct 2024 17:23:17 +0300
Subject: [PATCH] [PAC][CodeGen][ELF][AArch64] Support signed GOT with tiny
code model
Support the following relocations and assembly operators:
- `R_AARCH64_AUTH_GOT_ADR_PREL_LO21` (`:got_auth:` for `adr`)
- `R_AARCH64_AUTH_GOT_LD_PREL19` (`:got_auth:` for `ldr`)
`LOADgotAUTH` pseudo-instruction is expanded to actual instruction
sequence like the following.
```
adr x16, :got_auth:sym
ldr x0, [x16]
autia x0, x16
```
Both SelectionDAG and GlobalISel are suppported. For FastISel, we fall
back to SelectionDAG.
Tests starting with 'ptrauth-' have corresponding variants w/o this prefix.
---
llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp | 47 +++--
.../AArch64/AsmParser/AArch64AsmParser.cpp | 8 +-
.../MCTargetDesc/AArch64ELFObjectWriter.cpp | 18 ++
.../CodeGen/AArch64/ptrauth-extern-weak.ll | 42 ++++
.../CodeGen/AArch64/ptrauth-tiny-model-pic.ll | 182 ++++++++++++++++++
.../AArch64/ptrauth-tiny-model-static.ll | 157 +++++++++++++++
llvm/test/MC/AArch64/arm64-elf-relocs.s | 13 ++
llvm/test/MC/AArch64/ilp32-diagnostics.s | 6 +
8 files changed, 454 insertions(+), 19 deletions(-)
create mode 100644 llvm/test/CodeGen/AArch64/ptrauth-tiny-model-pic.ll
create mode 100644 llvm/test/CodeGen/AArch64/ptrauth-tiny-model-static.ll
diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
index e79457f925db66..2a3161a5c6b704 100644
--- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
+++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
@@ -2277,28 +2277,39 @@ void AArch64AsmPrinter::LowerLOADgotAUTH(const MachineInstr &MI) {
const MachineOperand &GAMO = MI.getOperand(1);
assert(GAMO.getOffset() == 0);
- MachineOperand GAHiOp(GAMO);
- MachineOperand GALoOp(GAMO);
- GAHiOp.addTargetFlag(AArch64II::MO_PAGE);
- GALoOp.addTargetFlag(AArch64II::MO_PAGEOFF | AArch64II::MO_NC);
+ if (MI.getMF()->getTarget().getCodeModel() == CodeModel::Tiny) {
+ MCOperand GAMC;
+ MCInstLowering.lowerOperand(GAMO, GAMC);
+ EmitToStreamer(
+ MCInstBuilder(AArch64::ADR).addReg(AArch64::X17).addOperand(GAMC));
+ EmitToStreamer(MCInstBuilder(AArch64::LDRXui)
+ .addReg(AuthResultReg)
+ .addReg(AArch64::X17)
+ .addImm(0));
+ } else {
+ MachineOperand GAHiOp(GAMO);
+ MachineOperand GALoOp(GAMO);
+ GAHiOp.addTargetFlag(AArch64II::MO_PAGE);
+ GALoOp.addTargetFlag(AArch64II::MO_PAGEOFF | AArch64II::MO_NC);
- MCOperand GAMCHi, GAMCLo;
- MCInstLowering.lowerOperand(GAHiOp, GAMCHi);
- MCInstLowering.lowerOperand(GALoOp, GAMCLo);
+ MCOperand GAMCHi, GAMCLo;
+ MCInstLowering.lowerOperand(GAHiOp, GAMCHi);
+ MCInstLowering.lowerOperand(GALoOp, GAMCLo);
- EmitToStreamer(
- MCInstBuilder(AArch64::ADRP).addReg(AArch64::X17).addOperand(GAMCHi));
+ EmitToStreamer(
+ MCInstBuilder(AArch64::ADRP).addReg(AArch64::X17).addOperand(GAMCHi));
- EmitToStreamer(MCInstBuilder(AArch64::ADDXri)
- .addReg(AArch64::X17)
- .addReg(AArch64::X17)
- .addOperand(GAMCLo)
- .addImm(0));
+ EmitToStreamer(MCInstBuilder(AArch64::ADDXri)
+ .addReg(AArch64::X17)
+ .addReg(AArch64::X17)
+ .addOperand(GAMCLo)
+ .addImm(0));
- EmitToStreamer(MCInstBuilder(AArch64::LDRXui)
- .addReg(AuthResultReg)
- .addReg(AArch64::X17)
- .addImm(0));
+ EmitToStreamer(MCInstBuilder(AArch64::LDRXui)
+ .addReg(AuthResultReg)
+ .addReg(AArch64::X17)
+ .addImm(0));
+ }
assert(GAMO.isGlobal());
MCSymbol *UndefWeakSym;
diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
index 712f6de52941c9..4a792f7bddb220 100644
--- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
+++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
@@ -3354,7 +3354,13 @@ ParseStatus AArch64AsmParser::tryParseAdrLabel(OperandVector &Operands) {
// No modifier was specified at all; this is the syntax for an ELF basic
// ADR relocation (unfortunately).
Expr = AArch64MCExpr::create(Expr, AArch64MCExpr::VK_ABS, getContext());
- } else {
+ } else if (ELFRefKind != AArch64MCExpr::VK_GOT_AUTH_PAGE) {
+ // For tiny code model, we use :got_auth: operator to fill 21-bit imm of
+ // adr. It's not actually GOT entry page address but the GOT address
+ // itself - we just share the same variant kind with :got_auth: operator
+ // applied for adrp.
+ // TODO: can we somehow get current TargetMachine object to call
+ // getCodeModel() on it to ensure we are using tiny code model?
return Error(S, "unexpected adr label");
}
}
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
index b5f5a58d96288e..04f90e21bb3b1f 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
@@ -147,6 +147,15 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
}
return ELF::R_AARCH64_PREL64;
case AArch64::fixup_aarch64_pcrel_adr_imm21:
+ if (SymLoc == AArch64MCExpr::VK_GOT_AUTH) {
+ if (IsILP32) {
+ Ctx.reportError(Fixup.getLoc(),
+ "ILP32 ADR AUTH relocation not supported "
+ "(LP64 eqv: AUTH_GOT_ADR_PREL_LO21)");
+ return ELF::R_AARCH64_NONE;
+ }
+ return ELF::R_AARCH64_AUTH_GOT_ADR_PREL_LO21;
+ }
if (SymLoc != AArch64MCExpr::VK_ABS)
Ctx.reportError(Fixup.getLoc(),
"invalid symbol kind for ADR relocation");
@@ -190,6 +199,15 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
return R_CLS(TLSIE_LD_GOTTPREL_PREL19);
if (SymLoc == AArch64MCExpr::VK_GOT)
return R_CLS(GOT_LD_PREL19);
+ if (SymLoc == AArch64MCExpr::VK_GOT_AUTH) {
+ if (IsILP32) {
+ Ctx.reportError(Fixup.getLoc(),
+ "ILP32 LDR AUTH relocation not supported "
+ "(LP64 eqv: AUTH_GOT_LD_PREL19)");
+ return ELF::R_AARCH64_NONE;
+ }
+ return ELF::R_AARCH64_AUTH_GOT_LD_PREL19;
+ }
return R_CLS(LD_PREL_LO19);
case AArch64::fixup_aarch64_pcrel_branch14:
return R_CLS(TSTBR14);
diff --git a/llvm/test/CodeGen/AArch64/ptrauth-extern-weak.ll b/llvm/test/CodeGen/AArch64/ptrauth-extern-weak.ll
index 5d0a3f556c4c2e..141af917fa3e2c 100644
--- a/llvm/test/CodeGen/AArch64/ptrauth-extern-weak.ll
+++ b/llvm/test/CodeGen/AArch64/ptrauth-extern-weak.ll
@@ -13,6 +13,11 @@
; RUN: llc -mtriple=aarch64-none-linux-gnu -global-isel=1 -global-isel-abort=1 -relocation-model=pic \
; RUN: -mattr=+pauth -o - %s | FileCheck --check-prefixes=CHECK,TRAP %s
+; RUN: llc -mtriple=aarch64-none-linux-gnu -code-model=tiny -mattr=+pauth -mattr=+fpac -o - %s | \
+; RUN: FileCheck --check-prefixes=CHECK-TINY,NOTRAP-TINY %s
+; RUN: llc -mtriple=aarch64-none-linux-gnu -code-model=tiny -mattr=+pauth -o - %s | \
+; RUN: FileCheck --check-prefixes=CHECK-TINY,TRAP-TINY %s
+
;; Note: for FastISel, we fall back to SelectionDAG
declare extern_weak dso_local i32 @var()
@@ -41,6 +46,24 @@ define ptr @foo() {
; TRAP-NEXT: .Lauth_success_0:
; TRAP-NEXT: mov x0, x16
; CHECK-NEXT: ret
+
+; CHECK-TINY-LABEL: foo:
+; CHECK-TINY: adr x17, :got_auth:var
+; NOTRAP-TINY-NEXT: ldr x0, [x17]
+; NOTRAP-TINY-NEXT: cbz x0, .Lundef_weak0
+; NOTRAP-TINY-NEXT: autia x0, x17
+; TRAP-TINY-NEXT: ldr x16, [x17]
+; TRAP-TINY-NEXT: cbz x16, .Lundef_weak0
+; TRAP-TINY-NEXT: autia x16, x17
+; CHECK-TINY-NEXT: .Lundef_weak0:
+; TRAP-TINY-NEXT: mov x17, x16
+; TRAP-TINY-NEXT: xpaci x17
+; TRAP-TINY-NEXT: cmp x16, x17
+; TRAP-TINY-NEXT: b.eq .Lauth_success_0
+; TRAP-TINY-NEXT: brk #0xc470
+; TRAP-TINY-NEXT: .Lauth_success_0:
+; TRAP-TINY-NEXT: mov x0, x16
+; CHECK-TINY-NEXT: ret
}
@arr_var = extern_weak global [10 x i32]
@@ -68,6 +91,25 @@ define ptr @bar() {
; TRAP-NEXT: mov x8, x16
; CHECK-NEXT: add x0, x8, #20
; CHECK-NEXT: ret
+
+; CHECK-TINY-LABEL: bar:
+; CHECK-TINY: adr x17, :got_auth:arr_var
+; NOTRAP-TINY-NEXT: ldr x8, [x17]
+; NOTRAP-TINY-NEXT: cbz x8, .Lundef_weak1
+; NOTRAP-TINY-NEXT: autda x8, x17
+; TRAP-TINY-NEXT: ldr x16, [x17]
+; TRAP-TINY-NEXT: cbz x16, .Lundef_weak1
+; TRAP-TINY-NEXT: autda x16, x17
+; CHECK-TINY-NEXT: .Lundef_weak1:
+; TRAP-TINY-NEXT: mov x17, x16
+; TRAP-TINY-NEXT: xpacd x17
+; TRAP-TINY-NEXT: cmp x16, x17
+; TRAP-TINY-NEXT: b.eq .Lauth_success_1
+; TRAP-TINY-NEXT: brk #0xc472
+; TRAP-TINY-NEXT: .Lauth_success_1:
+; TRAP-TINY-NEXT: mov x8, x16
+; CHECK-TINY-NEXT: add x0, x8, #20
+; CHECK-TINY-NEXT: ret
}
!llvm.module.flags = !{!0}
diff --git a/llvm/test/CodeGen/AArch64/ptrauth-tiny-model-pic.ll b/llvm/test/CodeGen/AArch64/ptrauth-tiny-model-pic.ll
new file mode 100644
index 00000000000000..93b21c93418a64
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/ptrauth-tiny-model-pic.ll
@@ -0,0 +1,182 @@
+; RUN: llc -verify-machineinstrs -mtriple=aarch64 -mattr=+pauth -mattr=+fpac -code-model=tiny \
+; RUN: -relocation-model=pic < %s | FileCheck --check-prefixes=CHECK,NOTRAP %s
+; RUN: llc -verify-machineinstrs -mtriple=aarch64 -mattr=+pauth -code-model=tiny \
+; RUN: -relocation-model=pic < %s | FileCheck --check-prefixes=CHECK,TRAP %s
+
+; RUN: llc -verify-machineinstrs -mtriple=aarch64 -mattr=+pauth -mattr=+fpac -code-model=tiny \
+; RUN: -relocation-model=pic -fast-isel < %s | FileCheck --check-prefixes=CHECK,NOTRAP %s
+; RUN: llc -verify-machineinstrs -mtriple=aarch64 -mattr=+pauth -code-model=tiny \
+; RUN: -relocation-model=pic -fast-isel < %s | FileCheck --check-prefixes=CHECK,TRAP %s
+
+; RUN: llc -verify-machineinstrs -mtriple=aarch64 -mattr=+pauth -mattr=+fpac -code-model=tiny \
+; RUN: -relocation-model=pic -global-isel -global-isel-abort=1 < %s | FileCheck --check-prefixes=CHECK,NOTRAP %s
+; RUN: llc -verify-machineinstrs -mtriple=aarch64 -mattr=+pauth -code-model=tiny \
+; RUN: -relocation-model=pic -global-isel -global-isel-abort=1 < %s | FileCheck --check-prefixes=CHECK,TRAP %s
+
+; Note: fast-isel tests here will fall back to isel
+
+ at src = external local_unnamed_addr global [65536 x i8], align 1
+ at dst = external global [65536 x i8], align 1
+ at ptr = external local_unnamed_addr global ptr, align 8
+
+define dso_preemptable void @foo1() {
+; CHECK-LABEL: foo1:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: adr x17, :got_auth:src
+; NOTRAP-NEXT: ldr x8, [x17]
+; NOTRAP-NEXT: autda x8, x17
+; TRAP-NEXT: ldr x16, [x17]
+; TRAP-NEXT: autda x16, x17
+; TRAP-NEXT: mov x17, x16
+; TRAP-NEXT: xpacd x17
+; TRAP-NEXT: cmp x16, x17
+; TRAP-NEXT: b.eq .Lauth_success_0
+; TRAP-NEXT: brk #0xc472
+; TRAP-NEXT: .Lauth_success_0:
+; TRAP-NEXT: mov x8, x16
+; CHECK-NEXT: ldrb w8, [x8]
+; CHECK-NEXT: adr x17, :got_auth:dst
+; NOTRAP-NEXT: ldr x9, [x17]
+; NOTRAP-NEXT: autda x9, x17
+; TRAP-NEXT: ldr x16, [x17]
+; TRAP-NEXT: autda x16, x17
+; TRAP-NEXT: mov x17, x16
+; TRAP-NEXT: xpacd x17
+; TRAP-NEXT: cmp x16, x17
+; TRAP-NEXT: b.eq .Lauth_success_1
+; TRAP-NEXT: brk #0xc472
+; TRAP-NEXT: .Lauth_success_1:
+; TRAP-NEXT: mov x9, x16
+; CHECK-NEXT: strb w8, [x9]
+; CHECK-NEXT: ret
+
+entry:
+ %0 = load i8, ptr @src, align 1
+ store i8 %0, ptr @dst, align 1
+ ret void
+}
+
+define dso_preemptable void @foo2() {
+; CHECK-LABEL: foo2:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: adr x17, :got_auth:ptr
+; NOTRAP-NEXT: ldr x8, [x17]
+; NOTRAP-NEXT: autda x8, x17
+; TRAP-NEXT: ldr x16, [x17]
+; TRAP-NEXT: autda x16, x17
+; TRAP-NEXT: mov x17, x16
+; TRAP-NEXT: xpacd x17
+; TRAP-NEXT: cmp x16, x17
+; TRAP-NEXT: b.eq .Lauth_success_2
+; TRAP-NEXT: brk #0xc472
+; TRAP-NEXT: .Lauth_success_2:
+; TRAP-NEXT: mov x8, x16
+; CHECK-NEXT: adr x17, :got_auth:dst
+; NOTRAP-NEXT: ldr x9, [x17]
+; NOTRAP-NEXT: autda x9, x17
+; TRAP-NEXT: ldr x16, [x17]
+; TRAP-NEXT: autda x16, x17
+; TRAP-NEXT: mov x17, x16
+; TRAP-NEXT: xpacd x17
+; TRAP-NEXT: cmp x16, x17
+; TRAP-NEXT: b.eq .Lauth_success_3
+; TRAP-NEXT: brk #0xc472
+; TRAP-NEXT: .Lauth_success_3:
+; TRAP-NEXT: mov x9, x16
+; CHECK-NEXT: str x9, [x8]
+; CHECK-NEXT: ret
+
+entry:
+ store ptr @dst, ptr @ptr, align 8
+ ret void
+}
+
+define dso_preemptable void @foo3() {
+; CHECK-LABEL: foo3:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: adr x17, :got_auth:src
+; NOTRAP-NEXT: ldr x8, [x17]
+; NOTRAP-NEXT: autda x8, x17
+; TRAP-NEXT: ldr x16, [x17]
+; TRAP-NEXT: autda x16, x17
+; TRAP-NEXT: mov x17, x16
+; TRAP-NEXT: xpacd x17
+; TRAP-NEXT: cmp x16, x17
+; TRAP-NEXT: b.eq .Lauth_success_4
+; TRAP-NEXT: brk #0xc472
+; TRAP-NEXT: .Lauth_success_4:
+; TRAP-NEXT: mov x8, x16
+; CHECK-NEXT: ldrb w8, [x8]
+; CHECK-NEXT: adr x17, :got_auth:ptr
+; NOTRAP-NEXT: ldr x9, [x17]
+; NOTRAP-NEXT: autda x9, x17
+; TRAP-NEXT: ldr x16, [x17]
+; TRAP-NEXT: autda x16, x17
+; TRAP-NEXT: mov x17, x16
+; TRAP-NEXT: xpacd x17
+; TRAP-NEXT: cmp x16, x17
+; TRAP-NEXT: b.eq .Lauth_success_5
+; TRAP-NEXT: brk #0xc472
+; TRAP-NEXT: .Lauth_success_5:
+; TRAP-NEXT: mov x9, x16
+; CHECK-NEXT: ldr x9, [x9]
+; CHECK-NEXT: strb w8, [x9]
+; CHECK-NEXT: ret
+
+entry:
+ %0 = load i8, ptr @src, align 1
+ %1 = load ptr, ptr @ptr, align 8
+ store i8 %0, ptr %1, align 1
+ ret void
+}
+
+ at lsrc = internal global i8 0, align 4
+ at ldst = internal global i8 0, align 4
+ at lptr = internal global ptr null, align 8
+
+declare void @func(...)
+
+define dso_preemptable ptr @externfuncaddr() {
+; CHECK-LABEL: externfuncaddr:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: adr x17, :got_auth:func
+; NOTRAP-NEXT: ldr x0, [x17]
+; NOTRAP-NEXT: autia x0, x17
+; TRAP-NEXT: ldr x16, [x17]
+; TRAP-NEXT: autia x16, x17
+; TRAP-NEXT: mov x17, x16
+; TRAP-NEXT: xpaci x17
+; TRAP-NEXT: cmp x16, x17
+; TRAP-NEXT: b.eq .Lauth_success_6
+; TRAP-NEXT: brk #0xc470
+; TRAP-NEXT: .Lauth_success_6:
+; TRAP-NEXT: mov x0, x16
+; CHECK-NEXT: ret
+
+entry:
+ ret ptr @func
+}
+
+define dso_preemptable ptr @localfuncaddr() {
+; CHECK-LABEL: localfuncaddr:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: adr x17, :got_auth:externfuncaddr
+; NOTRAP-NEXT: ldr x0, [x17]
+; NOTRAP-NEXT: autia x0, x17
+; TRAP-NEXT: ldr x16, [x17]
+; TRAP-NEXT: autia x16, x17
+; TRAP-NEXT: mov x17, x16
+; TRAP-NEXT: xpaci x17
+; TRAP-NEXT: cmp x16, x17
+; TRAP-NEXT: b.eq .Lauth_success_7
+; TRAP-NEXT: brk #0xc470
+; TRAP-NEXT: .Lauth_success_7:
+; TRAP-NEXT: mov x0, x16
+; CHECK-NEXT: ret
+
+entry:
+ ret ptr @externfuncaddr
+}
+
+!llvm.module.flags = !{!0}
+!0 = !{i32 8, !"ptrauth-elf-got", i32 1}
diff --git a/llvm/test/CodeGen/AArch64/ptrauth-tiny-model-static.ll b/llvm/test/CodeGen/AArch64/ptrauth-tiny-model-static.ll
new file mode 100644
index 00000000000000..2d098b70accccc
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/ptrauth-tiny-model-static.ll
@@ -0,0 +1,157 @@
+; RUN: llc -verify-machineinstrs -o - -mtriple=aarch64-none-linux-gnu -mattr=+pauth -mattr=+fpac \
+; RUN: -code-model=tiny < %s | FileCheck --check-prefixes=CHECK,NOTRAP %s
+; RUN: llc -verify-machineinstrs -o - -mtriple=aarch64-none-linux-gnu -mattr=+pauth \
+; RUN: -code-model=tiny < %s | FileCheck --check-prefixes=CHECK,TRAP %s
+
+; RUN: llc -verify-machineinstrs -o - -mtriple=aarch64-none-linux-gnu -mattr=+pauth -mattr=+fpac \
+; RUN: -code-model=tiny -fast-isel < %s | FileCheck --check-prefixes=CHECK,NOTRAP %s
+; RUN: llc -verify-machineinstrs -o - -mtriple=aarch64-none-linux-gnu -mattr=+pauth \
+; RUN: -code-model=tiny -fast-isel < %s | FileCheck --check-prefixes=CHECK,TRAP %s
+
+; RUN: llc -verify-machineinstrs -o - -mtriple=aarch64-none-linux-gnu -mattr=+pauth -mattr=+fpac \
+; RUN: -code-model=tiny -global-isel -global-isel-abort=1 < %s | FileCheck --check-prefixes=CHECK,NOTRAP %s
+; RUN: llc -verify-machineinstrs -o - -mtriple=aarch64-none-linux-gnu -mattr=+pauth \
+; RUN: -code-model=tiny -global-isel -global-isel-abort=1 < %s | FileCheck --check-prefixes=CHECK,TRAP %s
+
+; Note fast-isel tests here will fall back to isel
+
+ at src = external local_unnamed_addr global [65536 x i8], align 1
+ at dst = external global [65536 x i8], align 1
+ at ptr = external local_unnamed_addr global ptr, align 8
+
+define dso_local void @foo1() {
+; CHECK-LABEL: foo1:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: adr x17, :got_auth:src
+; NOTRAP-NEXT: ldr x8, [x17]
+; NOTRAP-NEXT: autda x8, x17
+; TRAP-NEXT: ldr x16, [x17]
+; TRAP-NEXT: autda x16, x17
+; TRAP-NEXT: mov x17, x16
+; TRAP-NEXT: xpacd x17
+; TRAP-NEXT: cmp x16, x17
+; TRAP-NEXT: b.eq .Lauth_success_0
+; TRAP-NEXT: brk #0xc472
+; TRAP-NEXT: .Lauth_success_0:
+; TRAP-NEXT: mov x8, x16
+; CHECK-NEXT: ldrb w8, [x8]
+; CHECK-NEXT: adr x17, :got_auth:dst
+; NOTRAP-NEXT: ldr x9, [x17]
+; NOTRAP-NEXT: autda x9, x17
+; TRAP-NEXT: ldr x16, [x17]
+; TRAP-NEXT: autda x16, x17
+; TRAP-NEXT: mov x17, x16
+; TRAP-NEXT: xpacd x17
+; TRAP-NEXT: cmp x16, x17
+; TRAP-NEXT: b.eq .Lauth_success_1
+; TRAP-NEXT: brk #0xc472
+; TRAP-NEXT: .Lauth_success_1:
+; TRAP-NEXT: mov x9, x16
+; CHECK-NEXT: strb w8, [x9]
+; CHECK-NEXT: ret
+
+entry:
+ %0 = load i8, ptr @src, align 1
+ store i8 %0, ptr @dst, align 1
+ ret void
+}
+
+define dso_local void @foo2() {
+; CHECK-LABEL: foo2:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: adr x17, :got_auth:ptr
+; NOTRAP-NEXT: ldr x8, [x17]
+; NOTRAP-NEXT: autda x8, x17
+; TRAP-NEXT: ldr x16, [x17]
+; TRAP-NEXT: autda x16, x17
+; TRAP-NEXT: mov x17, x16
+; TRAP-NEXT: xpacd x17
+; TRAP-NEXT: cmp x16, x17
+; TRAP-NEXT: b.eq .Lauth_success_2
+; TRAP-NEXT: brk #0xc472
+; TRAP-NEXT: .Lauth_success_2:
+; TRAP-NEXT: mov x8, x16
+; CHECK-NEXT: adr x17, :got_auth:dst
+; NOTRAP-NEXT: ldr x9, [x17]
+; NOTRAP-NEXT: autda x9, x17
+; TRAP-NEXT: ldr x16, [x17]
+; TRAP-NEXT: autda x16, x17
+; TRAP-NEXT: mov x17, x16
+; TRAP-NEXT: xpacd x17
+; TRAP-NEXT: cmp x16, x17
+; TRAP-NEXT: b.eq .Lauth_success_3
+; TRAP-NEXT: brk #0xc472
+; TRAP-NEXT: .Lauth_success_3:
+; TRAP-NEXT: mov x9, x16
+; CHECK-NEXT: str x9, [x8]
+; CHECK-NEXT: ret
+
+entry:
+ store ptr @dst, ptr @ptr, align 8
+ ret void
+}
+
+define dso_local void @foo3() {
+; CHECK-LABEL: foo3:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: adr x17, :got_auth:src
+; NOTRAP-NEXT: ldr x8, [x17]
+; NOTRAP-NEXT: autda x8, x17
+; TRAP-NEXT: ldr x16, [x17]
+; TRAP-NEXT: autda x16, x17
+; TRAP-NEXT: mov x17, x16
+; TRAP-NEXT: xpacd x17
+; TRAP-NEXT: cmp x16, x17
+; TRAP-NEXT: b.eq .Lauth_success_4
+; TRAP-NEXT: brk #0xc472
+; TRAP-NEXT: .Lauth_success_4:
+; TRAP-NEXT: mov x8, x16
+; CHECK-NEXT: ldrb w8, [x8]
+; CHECK-NEXT: adr x17, :got_auth:ptr
+; NOTRAP-NEXT: ldr x9, [x17]
+; NOTRAP-NEXT: autda x9, x17
+; TRAP-NEXT: ldr x16, [x17]
+; TRAP-NEXT: autda x16, x17
+; TRAP-NEXT: mov x17, x16
+; TRAP-NEXT: xpacd x17
+; TRAP-NEXT: cmp x16, x17
+; TRAP-NEXT: b.eq .Lauth_success_5
+; TRAP-NEXT: brk #0xc472
+; TRAP-NEXT: .Lauth_success_5:
+; TRAP-NEXT: mov x9, x16
+; CHECK-NEXT: ldr x9, [x9]
+; CHECK-NEXT: strb w8, [x9]
+; CHECK-NEXT: ret
+
+entry:
+ %0 = load i8, ptr @src, align 1
+ %1 = load ptr, ptr @ptr, align 8
+ store i8 %0, ptr %1, align 1
+ ret void
+}
+
+declare void @func(...)
+
+define dso_local ptr @externfuncaddr() {
+; CHECK-LABEL: externfuncaddr:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: adr x17, :got_auth:func
+; NOTRAP-NEXT: ldr x0, [x17]
+; NOTRAP-NEXT: autia x0, x17
+; TRAP-NEXT: ldr x16, [x17]
+; TRAP-NEXT: autia x16, x17
+; TRAP-NEXT: mov x17, x16
+; TRAP-NEXT: xpaci x17
+; TRAP-NEXT: cmp x16, x17
+; TRAP-NEXT: b.eq .Lauth_success_6
+; TRAP-NEXT: brk #0xc470
+; TRAP-NEXT: .Lauth_success_6:
+; TRAP-NEXT: mov x0, x16
+; CHECK-NEXT: ret
+
+entry:
+ ret ptr @func
+}
+
+!llvm.module.flags = !{!0}
+!0 = !{i32 8, !"ptrauth-elf-got", i32 1}
diff --git a/llvm/test/MC/AArch64/arm64-elf-relocs.s b/llvm/test/MC/AArch64/arm64-elf-relocs.s
index f679bb4c82827b..5c04e899a7b22e 100644
--- a/llvm/test/MC/AArch64/arm64-elf-relocs.s
+++ b/llvm/test/MC/AArch64/arm64-elf-relocs.s
@@ -331,6 +331,19 @@ trickQuestion:
// CHECK-OBJ-LP64: R_AARCH64_GOT_LD_PREL19 sym
// CHECK-OBJ-LP64: R_AARCH64_GOT_LD_PREL19 sym
+ adr x24, #:got_auth:sym
+ adr x24, :got_auth:sym
+ ldr x24, #:got_auth:sym
+ ldr x24, :got_auth:sym
+// CHECK: adr x24, :got_auth:sym
+// CHECK: adr x24, :got_auth:sym
+// CHECK: ldr x24, :got_auth:sym
+// CHECK: ldr x24, :got_auth:sym
+// CHECK-OBJ-LP64: R_AARCH64_AUTH_GOT_ADR_PREL_LO21 sym
+// CHECK-OBJ-LP64: R_AARCH64_AUTH_GOT_ADR_PREL_LO21 sym
+// CHECK-OBJ-LP64: R_AARCH64_AUTH_GOT_LD_PREL19 sym
+// CHECK-OBJ-LP64: R_AARCH64_AUTH_GOT_LD_PREL19 sym
+
// GOT relocations referencing local symbols are not converted to reference
// STT_SECTION symbols. https://github.com/llvm/llvm-project/issues/63418
ldr x0, [x0, :got_lo12:local0]
diff --git a/llvm/test/MC/AArch64/ilp32-diagnostics.s b/llvm/test/MC/AArch64/ilp32-diagnostics.s
index 5d9c6e5626b2b3..cf50188ec8ae60 100644
--- a/llvm/test/MC/AArch64/ilp32-diagnostics.s
+++ b/llvm/test/MC/AArch64/ilp32-diagnostics.s
@@ -87,3 +87,9 @@ ldr x24, [x23, #:got_lo12:sym]
ldr x24, [x23, :gottprel_lo12:sym]
// ERROR: [[#@LINE-1]]:1: error: ILP32 64-bit load/store relocation not supported (LP64 eqv: TLSIE_LD64_GOTTPREL_LO12_NC)
+
+ldr x24, :got_auth:sym
+// ERROR: error: ILP32 LDR AUTH relocation not supported (LP64 eqv: AUTH_GOT_LD_PREL19)
+
+adr x24, :got_auth:sym
+// ERROR: error: ILP32 ADR AUTH relocation not supported (LP64 eqv: AUTH_GOT_ADR_PREL_LO21)
More information about the llvm-commits
mailing list