[llvm] [bolt][x86] Fixed process indirect branch instruction (PR #179663)
Alexey Moksyakov via llvm-commits
llvm-commits at lists.llvm.org
Wed Feb 4 06:07:56 PST 2026
https://github.com/yavtuk updated https://github.com/llvm/llvm-project/pull/179663
>From 6453639d464e3cb977a2306f1b1456b1aeeda39e Mon Sep 17 00:00:00 2001
From: yavtuk <yavtuk at ya.ru>
Date: Wed, 4 Feb 2026 16:23:58 +0300
Subject: [PATCH] [bolt][x86] Fixed process indirect branch instruction
This patch adds checking that JT is already exist for pattern
with fixed indirect branch instruction. if JT is not exist or
deleted need to create new one based on snippet type update Imm
value to label for fixed entry load instruction.
---
bolt/lib/Core/BinaryFunction.cpp | 39 ++++++++++++-------
.../X86/Inputs/jump-table-fixed-ref-pic.s | 2 +-
bolt/test/X86/jump-table-fixed-ref-pic.test | 19 +++++++--
3 files changed, 41 insertions(+), 19 deletions(-)
diff --git a/bolt/lib/Core/BinaryFunction.cpp b/bolt/lib/Core/BinaryFunction.cpp
index 255f3d734bdb4..89d5c2c21a549 100644
--- a/bolt/lib/Core/BinaryFunction.cpp
+++ b/bolt/lib/Core/BinaryFunction.cpp
@@ -938,20 +938,12 @@ BinaryFunction::processIndirectBranch(MCInst &Instruction, unsigned Size,
<< " the destination value is 0x"
<< Twine::utohexstr(ArrayStart + *Value) << '\n';
- TargetAddress = ArrayStart + *Value;
-
- // Remove spurious JumpTable at EntryAddress caused by PIC reference from
- // the load instruction.
- BC.deleteJumpTable(EntryAddress);
-
- // Replace FixedEntryDispExpr used in target address calculation with outer
- // jump table reference.
- JumpTable *JT = BC.getJumpTableContainingAddress(ArrayStart);
- assert(JT && "Must have a containing jump table for PIC fixed branch");
- BC.MIB->replaceMemOperandDisp(*FixedEntryLoadInstr, JT->getFirstLabel(),
- EntryAddress - ArrayStart, &*BC.Ctx);
-
- return BranchType;
+ JumpTable *JT = BC.getJumpTableContainingAddress(EntryAddress);
+ if (JT) {
+ // Remove spurious JumpTable at EntryAddress caused by PIC reference from
+ // the load instruction.
+ BC.deleteJumpTable(JT->getAddress());
+ }
}
LLVM_DEBUG(dbgs() << "BOLT-DEBUG: addressed memory is 0x"
@@ -1009,7 +1001,8 @@ BinaryFunction::processIndirectBranch(MCInst &Instruction, unsigned Size,
// Check that jump table type in instruction pattern matches memory contents.
JumpTable::JumpTableType JTType;
- if (BranchType == IndirectBranchType::POSSIBLE_PIC_JUMP_TABLE) {
+ if (BranchType == IndirectBranchType::POSSIBLE_PIC_JUMP_TABLE ||
+ BranchType == IndirectBranchType::POSSIBLE_PIC_FIXED_BRANCH) {
if (MemType != MemoryContentsType::POSSIBLE_PIC_JUMP_TABLE)
return IndirectBranchType::UNKNOWN;
JTType = JumpTable::JTT_PIC;
@@ -1031,6 +1024,22 @@ BinaryFunction::processIndirectBranch(MCInst &Instruction, unsigned Size,
JTSites.emplace_back(Offset, ArrayStart);
+ if (FixedEntryLoadInstr) {
+ assert(BranchType == IndirectBranchType::POSSIBLE_PIC_FIXED_BRANCH &&
+ "Invalid IndirectBranch type");
+ JumpTable *JT = BC.getJumpTableContainingAddress(ArrayStart);
+ if (!JT)
+ return BranchType;
+ MCInst::iterator FixedEntryDispOperand =
+ BC.MIB->getMemOperandDisp(*FixedEntryLoadInstr);
+ assert(FixedEntryDispOperand != FixedEntryLoadInstr->end() &&
+ "Invalid memory instruction");
+ const MCExpr *FixedEntryDispExpr = FixedEntryDispOperand->getExpr();
+ const uint64_t EntryAddress = getExprValue(FixedEntryDispExpr);
+ BC.MIB->replaceMemOperandDisp(*FixedEntryLoadInstr, JT->getFirstLabel(),
+ EntryAddress - ArrayStart, &*BC.Ctx);
+ }
+
return BranchType;
}
diff --git a/bolt/test/X86/Inputs/jump-table-fixed-ref-pic.s b/bolt/test/X86/Inputs/jump-table-fixed-ref-pic.s
index 6407964593e2d..887281e582867 100644
--- a/bolt/test/X86/Inputs/jump-table-fixed-ref-pic.s
+++ b/bolt/test/X86/Inputs/jump-table-fixed-ref-pic.s
@@ -6,7 +6,7 @@ main:
jae .L4
cmpq $0x1, %rdi
jne .L4
- movslq .Ljt_pic+8(%rip), %rax
+ movslq .Ljt_pic+JT_ENTRY_OFFSET(%rip), %rax
lea .Ljt_pic(%rip), %rdx
add %rdx, %rax
jmpq *%rax
diff --git a/bolt/test/X86/jump-table-fixed-ref-pic.test b/bolt/test/X86/jump-table-fixed-ref-pic.test
index d215c565b31e5..1be994761f615 100644
--- a/bolt/test/X86/jump-table-fixed-ref-pic.test
+++ b/bolt/test/X86/jump-table-fixed-ref-pic.test
@@ -1,13 +1,26 @@
## Verify that BOLT detects fixed destination of indirect jump for PIC
## case.
-RUN: %clang %cflags -no-pie %S/Inputs/jump-table-fixed-ref-pic.s -Wl,-q -o %t
+RUN: %clang %cflags -no-pie %S/Inputs/jump-table-fixed-ref-pic.s -Wl,-q -o %t \
+RUN: -Wa,--defsym,JT_ENTRY_OFFSET=8
RUN: llvm-bolt %t --relocs -o %t.null -print-cfg 2>&1 | FileCheck %s
CHECK: BOLT-INFO: fixed PIC indirect branch detected in main {{.*}} the destination value is 0x[[#TGT:]]
CHECK: Binary Function "main" after building cfg
-CHECK: movslq ".rodata/1"+8(%rip), %rax
+CHECK: movslq ".rodata/1"+[[#OFFSET:8]](%rip), %rax
CHECK-NEXT: leaq ".rodata/1"(%rip), %rdx
CHECK-NEXT: addq %rdx, %rax
-CHECK-NEXT: jmpq *%rax # UNKNOWN CONTROL FLOW
+CHECK-NEXT: jmpq *%rax # JUMPTABLE
+
+RUN: %clang %cflags -no-pie %S/Inputs/jump-table-fixed-ref-pic.s -Wl,-q -o %t \
+RUN: -Wa,--defsym,JT_ENTRY_OFFSET=0
+RUN: llvm-bolt %t --relocs -o %t.null -print-cfg 2>&1 | FileCheck %s
+
+CHECK-LABEL: BOLT-INFO: fixed PIC indirect branch detected in main {{.*}} the destination value is 0x[[#TGT:]]
+CHECK: Binary Function "main" after building cfg
+
+CHECK: movslq ".rodata/1"(%rip), %rax
+CHECK-NEXT: leaq ".rodata/1"(%rip), %rdx
+CHECK-NEXT: addq %rdx, %rax
+CHECK-NEXT: jmpq *%rax # JUMPTABLE
More information about the llvm-commits
mailing list