[llvm] [BOLT][BTI] Add MCPlusBuilder::createBTI (PR #167305)

Gergely Bálint via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 20 04:18:10 PST 2025


https://github.com/bgergely0 updated https://github.com/llvm/llvm-project/pull/167305

>From f26be06c77b522f1196d974c9c8d6d6f951b2e9c Mon Sep 17 00:00:00 2001
From: Gergely Balint <gergely.balint at arm.com>
Date: Thu, 28 Aug 2025 14:56:14 +0000
Subject: [PATCH 1/2] [BOLT][BTI] Add MCPlusBuilder::createBTI

- creates a bti j|c landing pad MCInst.
- create getBTIHintNum utility in AArch64/Utils, to make sure BOLT
  generates BTI immediates the same way as LLVM.
- add MCPlusBuilder unittests to cover new function.
---
 bolt/include/bolt/Core/MCPlusBuilder.h        |  5 ++++
 .../Target/AArch64/AArch64MCPlusBuilder.cpp   |  6 ++++
 bolt/unittests/Core/MCPlusBuilder.cpp         | 30 +++++++++++++++++++
 .../Target/AArch64/AArch64BranchTargets.cpp   |  9 ++----
 .../Target/AArch64/Utils/AArch64BaseInfo.h    | 10 +++++++
 5 files changed, 53 insertions(+), 7 deletions(-)

diff --git a/bolt/include/bolt/Core/MCPlusBuilder.h b/bolt/include/bolt/Core/MCPlusBuilder.h
index 69ae4fb8ddcc9..be66b663dde44 100644
--- a/bolt/include/bolt/Core/MCPlusBuilder.h
+++ b/bolt/include/bolt/Core/MCPlusBuilder.h
@@ -1863,6 +1863,11 @@ class MCPlusBuilder {
     llvm_unreachable("not implemented");
   }
 
+  /// Create a BTI landing pad instruction.
+  virtual void createBTI(MCInst &Inst, bool CouldCall, bool CouldJump) const {
+    llvm_unreachable("not implemented");
+  }
+
   /// Store \p Target absolute address to \p RegName
   virtual InstructionListType materializeAddress(const MCSymbol *Target,
                                                  MCContext *Ctx,
diff --git a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
index db3989d6b0b5f..19a08fb855e25 100644
--- a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
+++ b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
@@ -2748,6 +2748,12 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
     return Insts;
   }
 
+  void createBTI(MCInst &Inst, bool CouldCall, bool CouldJump) const override {
+    Inst.setOpcode(AArch64::HINT);
+    unsigned HintNum = getBTIHintNum(CouldCall, CouldJump);
+    Inst.addOperand(MCOperand::createImm(HintNum));
+  }
+
   InstructionListType materializeAddress(const MCSymbol *Target, MCContext *Ctx,
                                          MCPhysReg RegName,
                                          int64_t Addend = 0) const override {
diff --git a/bolt/unittests/Core/MCPlusBuilder.cpp b/bolt/unittests/Core/MCPlusBuilder.cpp
index bc37cedb435ae..33389bca8b21e 100644
--- a/bolt/unittests/Core/MCPlusBuilder.cpp
+++ b/bolt/unittests/Core/MCPlusBuilder.cpp
@@ -143,6 +143,36 @@ TEST_P(MCPlusBuilderTester, AArch64_CmpJE) {
   ASSERT_EQ(Label, BB->getLabel());
 }
 
+TEST_P(MCPlusBuilderTester, AArch64_BTI) {
+  if (GetParam() != Triple::aarch64)
+    GTEST_SKIP();
+  BinaryFunction *BF = BC->createInjectedBinaryFunction("BF", true);
+  std::unique_ptr<BinaryBasicBlock> BB = BF->createBasicBlock();
+
+  MCInst BTIjc;
+  BC->MIB->createBTI(BTIjc, true, true);
+  BB->addInstruction(BTIjc);
+  auto II = BB->begin();
+  ASSERT_EQ(II->getOpcode(), AArch64::HINT);
+  ASSERT_EQ(II->getOperand(0).getImm(), 38);
+
+  MCInst BTIj;
+  BC->MIB->createBTI(BTIj, false, true);
+  II = BB->addInstruction(BTIj);
+  ASSERT_EQ(II->getOpcode(), AArch64::HINT);
+  ASSERT_EQ(II->getOperand(0).getImm(), 36);
+
+  MCInst BTIc;
+  BC->MIB->createBTI(BTIc, true, false);
+  II = BB->addInstruction(BTIc);
+  ASSERT_EQ(II->getOpcode(), AArch64::HINT);
+  ASSERT_EQ(II->getOperand(0).getImm(), 34);
+
+  MCInst BTIinvalid;
+  ASSERT_DEATH(BC->MIB->createBTI(BTIinvalid, false, false),
+               "No target kinds!");
+}
+
 TEST_P(MCPlusBuilderTester, AArch64_CmpJNE) {
   if (GetParam() != Triple::aarch64)
     GTEST_SKIP();
diff --git a/llvm/lib/Target/AArch64/AArch64BranchTargets.cpp b/llvm/lib/Target/AArch64/AArch64BranchTargets.cpp
index f13554f72ce53..b6f3e56c3a18f 100644
--- a/llvm/lib/Target/AArch64/AArch64BranchTargets.cpp
+++ b/llvm/lib/Target/AArch64/AArch64BranchTargets.cpp
@@ -18,6 +18,7 @@
 
 #include "AArch64MachineFunctionInfo.h"
 #include "AArch64Subtarget.h"
+#include "Utils/AArch64BaseInfo.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
 #include "llvm/CodeGen/MachineJumpTableInfo.h"
@@ -135,13 +136,7 @@ void AArch64BranchTargets::addBTI(MachineBasicBlock &MBB, bool CouldCall,
                     << (CouldCall ? "c" : "") << " to " << MBB.getName()
                     << "\n");
 
-  unsigned HintNum = 32;
-  if (CouldCall)
-    HintNum |= 2;
-  if (CouldJump)
-    HintNum |= 4;
-  assert(HintNum != 32 && "No target kinds!");
-
+  unsigned HintNum = getBTIHintNum(CouldCall, CouldJump);
   auto MBBI = MBB.begin();
 
   // If the block starts with EH_LABEL(s), skip them first.
diff --git a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
index 27812e94a3516..78532346d1fe4 100644
--- a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
+++ b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
@@ -987,6 +987,16 @@ AArch64StringToPACKeyID(StringRef Name) {
   return std::nullopt;
 }
 
+inline static unsigned getBTIHintNum(bool CouldCall, bool CouldJump) {
+  unsigned HintNum = 32;
+  if (CouldCall)
+    HintNum |= 2;
+  if (CouldJump)
+    HintNum |= 4;
+  assert(HintNum != 32 && "No target kinds!");
+  return HintNum;
+}
+
 namespace AArch64 {
 // The number of bits in a SVE register is architecturally defined
 // to be a multiple of this value.  If <M x t> has this number of bits,

>From c508aacef6f4f5176b38c6bcbbdea3b2a9208601 Mon Sep 17 00:00:00 2001
From: Gergely Balint <gergely.balint at arm.com>
Date: Thu, 20 Nov 2025 12:02:48 +0000
Subject: [PATCH 2/2] [BOLT] Fix naming

- CouldCall -> CallTarget
- CouldJump -> JumpTarget
---
 bolt/include/bolt/Core/MCPlusBuilder.h           | 2 +-
 bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp | 4 ++--
 llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h  | 6 +++---
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/bolt/include/bolt/Core/MCPlusBuilder.h b/bolt/include/bolt/Core/MCPlusBuilder.h
index be66b663dde44..940eb161eb4f1 100644
--- a/bolt/include/bolt/Core/MCPlusBuilder.h
+++ b/bolt/include/bolt/Core/MCPlusBuilder.h
@@ -1864,7 +1864,7 @@ class MCPlusBuilder {
   }
 
   /// Create a BTI landing pad instruction.
-  virtual void createBTI(MCInst &Inst, bool CouldCall, bool CouldJump) const {
+  virtual void createBTI(MCInst &Inst, bool CallTarget, bool JumpTarget) const {
     llvm_unreachable("not implemented");
   }
 
diff --git a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
index 19a08fb855e25..851a8a18337d4 100644
--- a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
+++ b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
@@ -2748,9 +2748,9 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
     return Insts;
   }
 
-  void createBTI(MCInst &Inst, bool CouldCall, bool CouldJump) const override {
+  void createBTI(MCInst &Inst, bool CallTarget, bool JumpTarget) const override {
     Inst.setOpcode(AArch64::HINT);
-    unsigned HintNum = getBTIHintNum(CouldCall, CouldJump);
+    unsigned HintNum = getBTIHintNum(CallTarget, JumpTarget);
     Inst.addOperand(MCOperand::createImm(HintNum));
   }
 
diff --git a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
index 78532346d1fe4..98bc5d43f719f 100644
--- a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
+++ b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
@@ -987,11 +987,11 @@ AArch64StringToPACKeyID(StringRef Name) {
   return std::nullopt;
 }
 
-inline static unsigned getBTIHintNum(bool CouldCall, bool CouldJump) {
+inline static unsigned getBTIHintNum(bool CallTarget, bool JumpTarget) {
   unsigned HintNum = 32;
-  if (CouldCall)
+  if (CallTarget)
     HintNum |= 2;
-  if (CouldJump)
+  if (JumpTarget)
     HintNum |= 4;
   assert(HintNum != 32 && "No target kinds!");
   return HintNum;



More information about the llvm-commits mailing list