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

From d054c47f005e0812673e95aac9eeaf16cd2fe52c Mon Sep 17 00:00:00 2001
From: Gergely Balint <[email protected]>
Date: Thu, 28 Aug 2025 12:32:37 +0000
Subject: [PATCH] [BOLT][BTI] Add MCPlusBuilder::isBTILandingPad

- takes both implicit and explicit BTIs into account
- fix related comment in AArch64BranchTargets.cpp
---
 bolt/include/bolt/Core/MCPlusBuilder.h         | 14 ++++++++++++++
 .../Target/AArch64/AArch64MCPlusBuilder.cpp    | 18 ++++++++++++++++++
 bolt/unittests/Core/MCPlusBuilder.cpp          | 17 +++++++++++++++++
 .../Target/AArch64/AArch64BranchTargets.cpp    |  6 ++++--
 4 files changed, 53 insertions(+), 2 deletions(-)

diff --git a/bolt/include/bolt/Core/MCPlusBuilder.h 
b/bolt/include/bolt/Core/MCPlusBuilder.h
index 940eb161eb4f1..c702ebacf4163 100644
--- a/bolt/include/bolt/Core/MCPlusBuilder.h
+++ b/bolt/include/bolt/Core/MCPlusBuilder.h
@@ -1863,6 +1863,20 @@ class MCPlusBuilder {
     llvm_unreachable("not implemented");
   }
 
+  /// Check if an Instruction is a BTI landing pad with the required 
properties.
+  /// Takes both explicit and implicit BTIs into account.
+  virtual bool isBTILandingPad(MCInst &Inst, bool CallTarget,
+                               bool JumpTarget) const {
+    llvm_unreachable("not implemented");
+    return false;
+  }
+
+  /// Check if an Instruction is an implicit BTI c landing pad.
+  virtual bool isImplicitBTIC(MCInst &Inst) const {
+    llvm_unreachable("not implemented");
+    return false;
+  }
+
   /// Create a BTI landing pad instruction.
   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 851a8a18337d4..863c99555b127 100644
--- a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
+++ b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
@@ -2748,6 +2748,24 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
     return Insts;
   }
 
+  bool isBTILandingPad(MCInst &Inst, bool CallTarget,
+                       bool JumpTarget) const override {
+    unsigned HintNum = getBTIHintNum(CallTarget, JumpTarget);
+    bool IsExplicitBTI =
+        Inst.getOpcode() == AArch64::HINT && Inst.getNumOperands() == 1 &&
+        Inst.getOperand(0).isImm() && Inst.getOperand(0).getImm() == HintNum;
+
+    bool IsImplicitBTI = HintNum == 34 && isImplicitBTIC(Inst);
+    return IsExplicitBTI || IsImplicitBTI;
+  }
+
+  bool isImplicitBTIC(MCInst &Inst) const override {
+    // PACI[AB]SP are always implicitly BTI C, independently of
+    // SCTLR_EL1.BT[01].
+    return Inst.getOpcode() == AArch64::PACIASP ||
+           Inst.getOpcode() == AArch64::PACIBSP;
+  }
+
   void createBTI(MCInst &Inst, bool CallTarget, bool JumpTarget) const 
override {
     Inst.setOpcode(AArch64::HINT);
     unsigned HintNum = getBTIHintNum(CallTarget, JumpTarget);
diff --git a/bolt/unittests/Core/MCPlusBuilder.cpp 
b/bolt/unittests/Core/MCPlusBuilder.cpp
index 33389bca8b21e..439d72a343ce8 100644
--- a/bolt/unittests/Core/MCPlusBuilder.cpp
+++ b/bolt/unittests/Core/MCPlusBuilder.cpp
@@ -155,22 +155,39 @@ TEST_P(MCPlusBuilderTester, AArch64_BTI) {
   auto II = BB->begin();
   ASSERT_EQ(II->getOpcode(), AArch64::HINT);
   ASSERT_EQ(II->getOperand(0).getImm(), 38);
+  ASSERT_TRUE(BC->MIB->isBTILandingPad(*II, true, true));
 
   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);
+  ASSERT_TRUE(BC->MIB->isBTILandingPad(*II, false, true));
 
   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);
+  ASSERT_TRUE(BC->MIB->isBTILandingPad(*II, true, false));
 
   MCInst BTIinvalid;
   ASSERT_DEATH(BC->MIB->createBTI(BTIinvalid, false, false),
                "No target kinds!");
+
+  MCInst Paciasp = MCInstBuilder(AArch64::PACIASP);
+  II = BB->addInstruction(Paciasp);
+  ASSERT_TRUE(BC->MIB->isBTILandingPad(*II, true, false));
+  ASSERT_FALSE(BC->MIB->isBTILandingPad(*II, true, true));
+  ASSERT_FALSE(BC->MIB->isBTILandingPad(*II, false, true));
+  ASSERT_TRUE(BC->MIB->isImplicitBTIC(*II));
+
+  MCInst Pacibsp = MCInstBuilder(AArch64::PACIBSP);
+  II = BB->addInstruction(Pacibsp);
+  ASSERT_TRUE(BC->MIB->isBTILandingPad(*II, true, false));
+  ASSERT_FALSE(BC->MIB->isBTILandingPad(*II, true, true));
+  ASSERT_FALSE(BC->MIB->isBTILandingPad(*II, false, true));
+  ASSERT_TRUE(BC->MIB->isImplicitBTIC(*II));
 }
 
 TEST_P(MCPlusBuilderTester, AArch64_CmpJNE) {
diff --git a/llvm/lib/Target/AArch64/AArch64BranchTargets.cpp 
b/llvm/lib/Target/AArch64/AArch64BranchTargets.cpp
index b6f3e56c3a18f..ea7de840faf92 100644
--- a/llvm/lib/Target/AArch64/AArch64BranchTargets.cpp
+++ b/llvm/lib/Target/AArch64/AArch64BranchTargets.cpp
@@ -150,8 +150,10 @@ void AArch64BranchTargets::addBTI(MachineBasicBlock &MBB, 
bool CouldCall,
        ++MBBI)
     ;
 
-  // SCTLR_EL1.BT[01] is set to 0 by default which means
-  // PACI[AB]SP are implicitly BTI C so no BTI C instruction is needed there.
+  // PACI[AB]SP are compatible with BTI c, independently of SCTLR_EL1.BT[01].
+  // If SCTLR_EL1.BT[01] is set to 1, they are compatible with BTI jc, but we
+  // cannot rely on that it compile time. Therefore, we can only skip adding a
+  // BTI c for these.
   if (MBBI != MBB.end() && ((HintNum & BTIMask) == BTIC) &&
       (MBBI->getOpcode() == AArch64::PACIASP ||
        MBBI->getOpcode() == AArch64::PACIBSP))

_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to