[llvm] [BOLT][AArch64] Eliminate e843419 veneers (PR #187955)
Elvina Yakubova via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 27 07:43:34 PDT 2026
https://github.com/ElvinaYakubova updated https://github.com/llvm/llvm-project/pull/187955
>From 7cea275a858b87404a2e5daddd81e25f39fc50e2 Mon Sep 17 00:00:00 2001
From: Elvina Yakubova <eyakubova at nvidia.com>
Date: Sun, 8 Mar 2026 17:33:34 -0700
Subject: [PATCH 1/2] [BOLT][AArch64] Eliminate e843419 veneers
Detect and eliminate A53 843419 errata veneers
---
bolt/include/bolt/Core/MCPlusBuilder.h | 8 +
bolt/lib/Core/BinaryFunction.cpp | 4 +-
bolt/lib/Passes/VeneerElimination.cpp | 76 +++++++
.../Target/AArch64/AArch64MCPlusBuilder.cpp | 20 ++
bolt/test/AArch64/veneer-erratum-843419.s | 198 ++++++++++++++++++
5 files changed, 305 insertions(+), 1 deletion(-)
create mode 100644 bolt/test/AArch64/veneer-erratum-843419.s
diff --git a/bolt/include/bolt/Core/MCPlusBuilder.h b/bolt/include/bolt/Core/MCPlusBuilder.h
index f9acaa4ee55a3..d5d66c8bb157b 100644
--- a/bolt/include/bolt/Core/MCPlusBuilder.h
+++ b/bolt/include/bolt/Core/MCPlusBuilder.h
@@ -1890,6 +1890,14 @@ class MCPlusBuilder {
llvm_unreachable("not implemented");
}
+ /// Match Cortex-A53 erratum 843419 workaround veneer. Such veneers have
+ /// exactly one BB with two instructions: a load/store and an unconditional
+ /// branch back to the call site. Returns true if BF matches this pattern
+ /// (name e843419* or __CortexA53843419_*, 2-instruction body).
+ virtual bool matchE843419Veneer(const BinaryFunction &BF) const {
+ return false;
+ }
+
virtual bool matchAdrpAddPair(const MCInst &Adrp, const MCInst &Add) const {
llvm_unreachable("not implemented");
return false;
diff --git a/bolt/lib/Core/BinaryFunction.cpp b/bolt/lib/Core/BinaryFunction.cpp
index c5aefe685de34..2ebaae1c77a5e 100644
--- a/bolt/lib/Core/BinaryFunction.cpp
+++ b/bolt/lib/Core/BinaryFunction.cpp
@@ -4845,7 +4845,9 @@ bool BinaryFunction::isAArch64Veneer() const {
bool BinaryFunction::isPossibleVeneer() const {
return BC.isAArch64() &&
- (isAArch64Veneer() || getOneName().starts_with("__AArch64"));
+ (isAArch64Veneer() || getOneName().starts_with("__AArch64") ||
+ getOneName().starts_with("e843419") ||
+ getOneName().starts_with("__CortexA53843419_"));
}
void BinaryFunction::addRelocation(uint64_t Address, MCSymbol *Symbol,
diff --git a/bolt/lib/Passes/VeneerElimination.cpp b/bolt/lib/Passes/VeneerElimination.cpp
index c0a6bcfbdd756..e0808738f3eac 100644
--- a/bolt/lib/Passes/VeneerElimination.cpp
+++ b/bolt/lib/Passes/VeneerElimination.cpp
@@ -35,6 +35,8 @@ Error VeneerElimination::runOnFunctions(BinaryContext &BC) {
std::unordered_map<const MCSymbol *, const MCSymbol *> VeneerDestinations;
uint64_t NumEliminatedVeneers = 0;
+ uint64_t NumE843419Inlined = 0;
+
for (BinaryFunction &BF : llvm::make_second_range(BC.getBinaryFunctions())) {
if (!BF.isPossibleVeneer())
continue;
@@ -42,6 +44,77 @@ Error VeneerElimination::runOnFunctions(BinaryContext &BC) {
if (BF.isIgnored())
continue;
+ // Cortex-A53 erratum 843419 veneers: inline the veneer body at each
+ // branch site instead of redirecting, so LongJmp do not introduce
+ // code that clobbers registers (e.g. x16) used by the caller.
+ if (BC.MIB->matchE843419Veneer(BF)) {
+ const MCInst &VeneerFirstInstr = BF.front().getInstructionAtIndex(0);
+ const MCSymbol *ReturnTargetSym =
+ BC.MIB->getTargetSymbol(BF.front().getInstructionAtIndex(1));
+
+ // Check if this branch targets our e843419 veneer.
+ auto BranchTargetsVeneer = [&BF, &BC](const MCSymbol *Target) {
+ if (!Target)
+ return false;
+ if (BC.getFunctionForSymbol(Target) == &BF)
+ return true;
+ if (ErrorOr<uint64_t> Addr = BC.getSymbolValue(*Target))
+ return BC.getBinaryFunctionContainingAddress(*Addr) == &BF;
+ return false;
+ };
+
+ uint64_t CallSites = 0;
+
+ // Find caller from veneer's branch-back target so we can limit the scan.
+ BinaryFunction *CallerBF = nullptr;
+ if (ReturnTargetSym) {
+ if (ErrorOr<uint64_t> Addr = BC.getSymbolValue(*ReturnTargetSym))
+ CallerBF = BC.getBinaryFunctionContainingAddress(*Addr);
+ }
+
+ auto ScanForBranchesToVeneer = [&](BinaryFunction &F) {
+ for (BinaryBasicBlock &BB : F) {
+ for (auto II = BB.begin(); II != BB.end();) {
+ MCInst &Instr = *II;
+ if (!BC.MIB->isBranch(Instr)) {
+ ++II;
+ continue;
+ }
+ const MCSymbol *Target = BC.MIB->getTargetSymbol(Instr);
+ if (!BranchTargetsVeneer(Target)) {
+ ++II;
+ continue;
+ }
+ InstructionListType Repl;
+ Repl.emplace_back(VeneerFirstInstr);
+ II = BB.replaceInstruction(II, Repl);
+ ++CallSites;
+ ++NumE843419Inlined;
+ }
+ }
+ };
+
+ if (CallerBF && !CallerBF->isIgnored())
+ ScanForBranchesToVeneer(*CallerBF);
+ else
+ LLVM_DEBUG(dbgs() << "BOLT: skipping e843419 veneer inline for "
+ << BF.getOneName()
+ << " (caller not resolved or ignored)\n");
+
+ // Only mark pseudo when we actually inlined at least one branch site.
+ if (CallSites > 0) {
+ ++NumEliminatedVeneers;
+ BF.setPseudo(true);
+ LLVM_DEBUG(dbgs() << "BOLT-INFO: inlined e843419 veneer "
+ << BF.getOneName() << " at " << CallSites
+ << " branch sites\n");
+ } else {
+ LLVM_DEBUG(dbgs() << "BOLT: e843419 veneer " << BF.getOneName()
+ << " left unchanged (no branch sites inlined)\n");
+ }
+ continue;
+ }
+
MCInst &FirstInstruction = *(BF.begin()->begin());
const MCSymbol *VeneerTargetSymbol = 0;
uint64_t TargetAddress;
@@ -67,6 +140,9 @@ Error VeneerElimination::runOnFunctions(BinaryContext &BC) {
BC.outs() << "BOLT-INFO: number of removed linker-inserted veneers: "
<< NumEliminatedVeneers << '\n';
+ if (NumE843419Inlined)
+ BC.outs() << "BOLT-INFO: e843419 veneer call sites inlined: "
+ << NumE843419Inlined << '\n';
// Handle veneers to veneers in case they occur
for (auto &Entry : VeneerDestinations) {
diff --git a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
index b091378682731..ce359551275ec 100644
--- a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
+++ b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
@@ -2854,6 +2854,26 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
return true;
}
+ /// Match Cortex-A53 erratum 843419 workaround veneer: one BB, two
+ /// instructions (load/store then branch back).
+ bool matchE843419Veneer(const BinaryFunction &BF) const override {
+ StringRef Name = BF.getOneName();
+ if (!Name.starts_with("e843419") && !Name.starts_with("__CortexA53843419_"))
+ return false;
+ if (BF.size() != 1)
+ return false;
+ const BinaryBasicBlock &BB = BF.front();
+ if (BB.size() != 2)
+ return false;
+ const MCInst &First = BB.getInstructionAtIndex(0);
+ const MCInst &Second = BB.getInstructionAtIndex(1);
+ if (!(mayLoad(First) || mayStore(First)))
+ return false;
+ if (!isTailCall(Second))
+ return false;
+ return true;
+ }
+
bool matchAdrpAddPair(const MCInst &Adrp, const MCInst &Add) const override {
if (!isADRP(Adrp) || !isAddXri(Add))
return false;
diff --git a/bolt/test/AArch64/veneer-erratum-843419.s b/bolt/test/AArch64/veneer-erratum-843419.s
new file mode 100644
index 0000000000000..6a9c83268c4fa
--- /dev/null
+++ b/bolt/test/AArch64/veneer-erratum-843419.s
@@ -0,0 +1,198 @@
+## Test case for ARM Cortex-A53 erratum 843419 workaround veneers
+## These veneers have a specific pattern:
+## 1. ADRP instruction to load page address
+## 2. Optional instructions
+## 3. Branch to veneer (e843419 at ...)
+## 4. Veneer contains: LDR/STR using same register, branch back to +1 instruction
+
+# RUN: llvm-mc -filetype=obj -triple aarch64-unknown-unknown %s -o %t.o
+# RUN: %clang %cflags -fPIC -pie %t.o -o %t.exe -nostdlib \
+# RUN: -fuse-ld=lld -Wl,-q
+# RUN: llvm-bolt %t.exe -o %t.bolt
+# RUN: llvm-objdump -d %t.bolt | FileCheck %s
+
+.text
+.balign 4
+.global target_function
+.type target_function, %function
+target_function:
+ ret
+.size target_function, .-target_function
+
+## Pattern 1: ADRP + multiple instructions + branch to veneer
+.global test_pattern_1
+.type test_pattern_1, %function
+test_pattern_1:
+# CHECK-LABEL: <test_pattern_1>:
+ adrp x7, target_function
+# CHECK: adrp
+ stp w9, w8, [sp, #0xc4]
+ b e843419_veneer_1
+.Lreturn_1:
+ stur d0, [sp, #0xbc]
+ blr x7
+# CHECK-NOT: b {{.*}} <e843419_veneer_1>
+# CHECK: blr
+ ret
+.size test_pattern_1, .-test_pattern_1
+
+## Veneer for pattern 1
+.global e843419_veneer_1
+.type e843419_veneer_1, %function
+e843419_veneer_1:
+# CHECK-NOT: <e843419_veneer_1>:
+ ldr x7, [x7, #0x1a8]
+ b .Lreturn_1
+.size e843419_veneer_1, .-e843419_veneer_1
+
+## Pattern 2: ADRP + load + mov + branch to veneer
+.global test_pattern_2
+.type test_pattern_2, %function
+test_pattern_2:
+# CHECK-LABEL: <test_pattern_2>:
+ adrp x13, target_function
+# CHECK: adrp
+ ldr w14, [x10]
+ mov w10, #0x1
+ b e843419_veneer_2
+.Lreturn_2:
+ mov x13, #0x220
+# CHECK-NOT: b {{.*}} <e843419_veneer_2>
+# CHECK: mov
+ cmp w14, #0x2ed
+ ret
+.size test_pattern_2, .-test_pattern_2
+
+## Veneer for pattern 2
+.global e843419_veneer_2
+.type e843419_veneer_2, %function
+e843419_veneer_2:
+# CHECK-NOT: <e843419_veneer_2>:
+ ldr d0, [x13, #0x888]
+ b .Lreturn_2
+.size e843419_veneer_2, .-e843419_veneer_2
+
+## Pattern 3: Minimal case with just ADRP and branch
+.global test_pattern_3
+.type test_pattern_3, %function
+test_pattern_3:
+# CHECK-LABEL: <test_pattern_3>:
+ adrp x15, target_function
+# CHECK: adrp
+ b e843419_veneer_3
+.Lreturn_3:
+ add x15, x15, #0x100
+# CHECK-NOT: b {{.*}} <e843419_veneer_3>
+# CHECK: add
+ ret
+.size test_pattern_3, .-test_pattern_3
+
+## Veneer for pattern 3
+.global e843419_veneer_3
+.type e843419_veneer_3, %function
+e843419_veneer_3:
+# CHECK-NOT: <e843419_veneer_3>:
+ ldr x15, [x15, #0x200]
+ b .Lreturn_3
+.size e843419_veneer_3, .-e843419_veneer_3
+
+## Pattern 4: Using different registers (x8)
+.global test_pattern_4
+.type test_pattern_4, %function
+test_pattern_4:
+# CHECK-LABEL: <test_pattern_4>:
+ adrp x8, target_function
+# CHECK: adrp
+ str x9, [sp, #0x10]
+ b e843419_veneer_4
+.Lreturn_4:
+ ldr x9, [x8, #0x50]
+# CHECK-NOT: b {{.*}} <e843419_veneer_4>
+# CHECK: ldr
+ ret
+.size test_pattern_4, .-test_pattern_4
+
+## Veneer for pattern 4
+.global e843419_veneer_4
+.type e843419_veneer_4, %function
+e843419_veneer_4:
+# CHECK-NOT: <e843419_veneer_4>:
+ ldr x8, [x8, #0x400]
+ b .Lreturn_4
+.size e843419_veneer_4, .-e843419_veneer_4
+
+## Pattern 5: Complex pattern with conditional code
+.global test_pattern_5
+.type test_pattern_5, %function
+test_pattern_5:
+# CHECK-LABEL: <test_pattern_5>:
+ adrp x20, target_function
+# CHECK: adrp
+ cbz x1, .Lskip
+ ldr x2, [sp, #0x20]
+.Lskip:
+ b e843419_veneer_5
+.Lreturn_5:
+ ldrb w3, [x20, #0x10]
+# CHECK-NOT: b {{.*}} <e843419_veneer_5>
+# CHECK: ldrb
+ ret
+.size test_pattern_5, .-test_pattern_5
+
+## Veneer for pattern 5
+.global e843419_veneer_5
+.type e843419_veneer_5, %function
+e843419_veneer_5:
+# CHECK-NOT: <e843419_veneer_5>:
+ ldr x20, [x20, #0x600]
+ b .Lreturn_5
+.size e843419_veneer_5, .-e843419_veneer_5
+
+## Pattern 6 (x16): mov x16 + branch to veneer; inlining preserves x16 for later use.
+## Without inlining, LongJmp could turn the veneer into adrp/add/br x16 and clobber it.
+.global test_pattern_x16
+.type test_pattern_x16, %function
+test_pattern_x16:
+# CHECK-LABEL: <test_pattern_x16>:
+ adrp x1, target_function
+ ldr q2, [x0, #3744]
+ mov x16, #0x2600
+ b e843419_x16_veneer
+.Lreturn_x16:
+ adrp x1, target_function
+ ldr q3, [x3, #0xee0]
+# CHECK-NOT: b {{.*}} <e843419_x16_veneer>
+# CHECK: ldr q7, [x1, #0xff0]
+# CHECK: adrp
+ ret
+.size test_pattern_x16, .-test_pattern_x16
+
+.global e843419_x16_veneer
+.type e843419_x16_veneer, %function
+e843419_x16_veneer:
+# CHECK-NOT: <e843419_x16_veneer>:
+ ldr q7, [x1, #0xff0]
+ b .Lreturn_x16
+.size e843419_x16_veneer, .-e843419_x16_veneer
+
+## Do NOT inline when target is not the 2-instr e843419 pattern.
+.global test_pattern_anti
+.type test_pattern_anti, %function
+test_pattern_anti:
+# CHECK-LABEL: <test_pattern_anti>:
+ adrp x8, target_function
+ b e843419_veneer_anti
+# CHECK: b {{.*}} <e843419_veneer_anti>
+.Lreturn_anti:
+ blr x8
+ ret
+.size test_pattern_anti, .-test_pattern_anti
+
+.global e843419_veneer_anti
+.type e843419_veneer_anti, %function
+e843419_veneer_anti:
+# CHECK: <e843419_veneer_anti>:
+ ldr x8, [x8, #0x100]
+ add x8, x8, #0
+ b .Lreturn_anti
+.size e843419_veneer_anti, .-e843419_veneer_anti
>From dacc777d1f2307075fdd869c3f851b63480626af Mon Sep 17 00:00:00 2001
From: Elvina Yakubova <eyakubova at nvidia.com>
Date: Fri, 17 Apr 2026 05:31:28 -0700
Subject: [PATCH 2/2] Updated test to generate veneers with lld
---
bolt/test/AArch64/veneer-erratum-843419.s | 192 +++++++++-------------
1 file changed, 80 insertions(+), 112 deletions(-)
diff --git a/bolt/test/AArch64/veneer-erratum-843419.s b/bolt/test/AArch64/veneer-erratum-843419.s
index 6a9c83268c4fa..22fe419bb60ff 100644
--- a/bolt/test/AArch64/veneer-erratum-843419.s
+++ b/bolt/test/AArch64/veneer-erratum-843419.s
@@ -1,17 +1,23 @@
-## Test case for ARM Cortex-A53 erratum 843419 workaround veneers
-## These veneers have a specific pattern:
-## 1. ADRP instruction to load page address
-## 2. Optional instructions
-## 3. Branch to veneer (e843419 at ...)
-## 4. Veneer contains: LDR/STR using same register, branch back to +1 instruction
-
-# RUN: llvm-mc -filetype=obj -triple aarch64-unknown-unknown %s -o %t.o
+## Test case for ARM Cortex-A53 erratum 843419 workaround veneers.
+## LLD emits veneers when linking with --fix-cortex-a53-843419: the erratum
+## sequence is ADRP at 0xff8/0xffc, a qualifying load/store, an optional
+## non-branch, then a load/store (unsigned immediate) using the ADRP register;
+## LLD replaces that final instruction with B to __CortexA53843419_*.
+## BOLT recognizes those veneers (same shape as e843419* stubs) and inlines.
+##
+## Layout follows lld/test/ELF/aarch64-cortex-a53-843419-address.s test cases.
+
+# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux-gnu %s -o %t.o
+# RUN: echo "SECTIONS { \
+# RUN: . = SIZEOF_HEADERS; \
+# RUN: .text : { *(.text.main) *(.text.pats) } \
+# RUN: .data : { *(.data.main) } }" > %t.script
# RUN: %clang %cflags -fPIC -pie %t.o -o %t.exe -nostdlib \
-# RUN: -fuse-ld=lld -Wl,-q
+# RUN: -fuse-ld=lld -Wl,-q -Wl,-T,%t.script -Wl,--fix-cortex-a53-843419
# RUN: llvm-bolt %t.exe -o %t.bolt
# RUN: llvm-objdump -d %t.bolt | FileCheck %s
-.text
+.section .text.main, "ax", %progbits
.balign 4
.global target_function
.type target_function, %function
@@ -19,180 +25,142 @@ target_function:
ret
.size target_function, .-target_function
-## Pattern 1: ADRP + multiple instructions + branch to veneer
+## Anti-pattern: manual 3-instruction "veneer" (not LLD's 2-instruction patch).
+## BOLT must not inline this.
+.global test_pattern_anti
+.type test_pattern_anti, %function
+test_pattern_anti:
+# CHECK-LABEL: <test_pattern_anti>:
+ adrp x8, target_function
+ b e843419_veneer_anti
+# CHECK: b {{.*}} <e843419_veneer_anti>
+.Lreturn_anti:
+ blr x8
+ ret
+.size test_pattern_anti, .-test_pattern_anti
+
+.global e843419_veneer_anti
+.type e843419_veneer_anti, %function
+e843419_veneer_anti:
+# CHECK: <e843419_veneer_anti>:
+ ldr x8, [x8, #0x100]
+ add x8, x8, #0
+ b .Lreturn_anti
+.size e843419_veneer_anti, .-e843419_veneer_anti
+
+.section .text.pats, "ax", %progbits
+
+.balign 4096
+.space 4096 - 8
.global test_pattern_1
.type test_pattern_1, %function
test_pattern_1:
# CHECK-LABEL: <test_pattern_1>:
- adrp x7, target_function
+ adrp x7, dat
# CHECK: adrp
stp w9, w8, [sp, #0xc4]
- b e843419_veneer_1
+ ldr x7, [x7, :got_lo12:dat]
+# CHECK-NOT: b {{.*}} <__CortexA53843419_
.Lreturn_1:
stur d0, [sp, #0xbc]
blr x7
-# CHECK-NOT: b {{.*}} <e843419_veneer_1>
# CHECK: blr
ret
.size test_pattern_1, .-test_pattern_1
-## Veneer for pattern 1
-.global e843419_veneer_1
-.type e843419_veneer_1, %function
-e843419_veneer_1:
-# CHECK-NOT: <e843419_veneer_1>:
- ldr x7, [x7, #0x1a8]
- b .Lreturn_1
-.size e843419_veneer_1, .-e843419_veneer_1
-
-## Pattern 2: ADRP + load + mov + branch to veneer
+.balign 4096
+.space 4096 - 8
.global test_pattern_2
.type test_pattern_2, %function
test_pattern_2:
# CHECK-LABEL: <test_pattern_2>:
- adrp x13, target_function
+ adrp x13, dat
# CHECK: adrp
ldr w14, [x10]
mov w10, #0x1
- b e843419_veneer_2
+ ldr d0, [x13, :got_lo12:dat]
+# CHECK-NOT: b {{.*}} <__CortexA53843419_
.Lreturn_2:
mov x13, #0x220
-# CHECK-NOT: b {{.*}} <e843419_veneer_2>
# CHECK: mov
cmp w14, #0x2ed
ret
.size test_pattern_2, .-test_pattern_2
-## Veneer for pattern 2
-.global e843419_veneer_2
-.type e843419_veneer_2, %function
-e843419_veneer_2:
-# CHECK-NOT: <e843419_veneer_2>:
- ldr d0, [x13, #0x888]
- b .Lreturn_2
-.size e843419_veneer_2, .-e843419_veneer_2
-
-## Pattern 3: Minimal case with just ADRP and branch
+.balign 4096
+.space 4096 - 8
.global test_pattern_3
.type test_pattern_3, %function
test_pattern_3:
# CHECK-LABEL: <test_pattern_3>:
- adrp x15, target_function
+ adrp x15, dat
# CHECK: adrp
- b e843419_veneer_3
+ ldr w0, [sp, #0x20]
+ ldr x15, [x15, :got_lo12:dat]
+# CHECK-NOT: b {{.*}} <__CortexA53843419_
.Lreturn_3:
add x15, x15, #0x100
-# CHECK-NOT: b {{.*}} <e843419_veneer_3>
# CHECK: add
ret
.size test_pattern_3, .-test_pattern_3
-## Veneer for pattern 3
-.global e843419_veneer_3
-.type e843419_veneer_3, %function
-e843419_veneer_3:
-# CHECK-NOT: <e843419_veneer_3>:
- ldr x15, [x15, #0x200]
- b .Lreturn_3
-.size e843419_veneer_3, .-e843419_veneer_3
-
-## Pattern 4: Using different registers (x8)
+.balign 4096
+.space 4096 - 8
.global test_pattern_4
.type test_pattern_4, %function
test_pattern_4:
# CHECK-LABEL: <test_pattern_4>:
- adrp x8, target_function
+ adrp x8, dat
# CHECK: adrp
str x9, [sp, #0x10]
- b e843419_veneer_4
+ ldr x8, [x8, :got_lo12:dat]
+# CHECK-NOT: b {{.*}} <__CortexA53843419_
.Lreturn_4:
ldr x9, [x8, #0x50]
-# CHECK-NOT: b {{.*}} <e843419_veneer_4>
# CHECK: ldr
ret
.size test_pattern_4, .-test_pattern_4
-## Veneer for pattern 4
-.global e843419_veneer_4
-.type e843419_veneer_4, %function
-e843419_veneer_4:
-# CHECK-NOT: <e843419_veneer_4>:
- ldr x8, [x8, #0x400]
- b .Lreturn_4
-.size e843419_veneer_4, .-e843419_veneer_4
-
-## Pattern 5: Complex pattern with conditional code
+.balign 4096
+.space 4096 - 8
.global test_pattern_5
.type test_pattern_5, %function
test_pattern_5:
# CHECK-LABEL: <test_pattern_5>:
- adrp x20, target_function
+ adrp x20, dat
# CHECK: adrp
- cbz x1, .Lskip
ldr x2, [sp, #0x20]
-.Lskip:
- b e843419_veneer_5
+ orr x0, x0, x0
+ ldr x20, [x20, :got_lo12:dat]
+# CHECK-NOT: b {{.*}} <__CortexA53843419_
.Lreturn_5:
ldrb w3, [x20, #0x10]
-# CHECK-NOT: b {{.*}} <e843419_veneer_5>
# CHECK: ldrb
ret
.size test_pattern_5, .-test_pattern_5
-## Veneer for pattern 5
-.global e843419_veneer_5
-.type e843419_veneer_5, %function
-e843419_veneer_5:
-# CHECK-NOT: <e843419_veneer_5>:
- ldr x20, [x20, #0x600]
- b .Lreturn_5
-.size e843419_veneer_5, .-e843419_veneer_5
-
-## Pattern 6 (x16): mov x16 + branch to veneer; inlining preserves x16 for later use.
-## Without inlining, LongJmp could turn the veneer into adrp/add/br x16 and clobber it.
+## Pattern 6 (x16): mov x16 + final load; inlining must preserve x16.
+.balign 4096
+.space 4096 - 8
.global test_pattern_x16
.type test_pattern_x16, %function
test_pattern_x16:
# CHECK-LABEL: <test_pattern_x16>:
- adrp x1, target_function
+ adrp x1, dat
ldr q2, [x0, #3744]
mov x16, #0x2600
- b e843419_x16_veneer
+ ldr d7, [x1, :got_lo12:dat]
+# CHECK-NOT: b {{.*}} <__CortexA53843419_
.Lreturn_x16:
adrp x1, target_function
ldr q3, [x3, #0xee0]
-# CHECK-NOT: b {{.*}} <e843419_x16_veneer>
-# CHECK: ldr q7, [x1, #0xff0]
+# CHECK: ldr{{.*}}d7
# CHECK: adrp
ret
.size test_pattern_x16, .-test_pattern_x16
-.global e843419_x16_veneer
-.type e843419_x16_veneer, %function
-e843419_x16_veneer:
-# CHECK-NOT: <e843419_x16_veneer>:
- ldr q7, [x1, #0xff0]
- b .Lreturn_x16
-.size e843419_x16_veneer, .-e843419_x16_veneer
-
-## Do NOT inline when target is not the 2-instr e843419 pattern.
-.global test_pattern_anti
-.type test_pattern_anti, %function
-test_pattern_anti:
-# CHECK-LABEL: <test_pattern_anti>:
- adrp x8, target_function
- b e843419_veneer_anti
-# CHECK: b {{.*}} <e843419_veneer_anti>
-.Lreturn_anti:
- blr x8
- ret
-.size test_pattern_anti, .-test_pattern_anti
-
-.global e843419_veneer_anti
-.type e843419_veneer_anti, %function
-e843419_veneer_anti:
-# CHECK: <e843419_veneer_anti>:
- ldr x8, [x8, #0x100]
- add x8, x8, #0
- b .Lreturn_anti
-.size e843419_veneer_anti, .-e843419_veneer_anti
+.section .data.main, "aw", %progbits
+.balign 8
+.global dat
+dat:
+ .quad 0
More information about the llvm-commits
mailing list