https://github.com/bgergely0 created https://github.com/llvm/llvm-project/pull/167306
- takes both implicit and explicit BTIs into account - fix related comment in AArch64BranchTargets.cpp From 57061b65e6c36e8e6f18a1a0f0db2f0266730b0e 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 9cbff02619bd2..6760586876d94 100644 --- a/bolt/include/bolt/Core/MCPlusBuilder.h +++ b/bolt/include/bolt/Core/MCPlusBuilder.h @@ -1865,6 +1865,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 CouldCall, + bool CouldJump) 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 CouldCall, bool CouldJump) const { llvm_unreachable("not implemented"); diff --git a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp index b6dfa16355ad9..3988847396182 100644 --- a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp +++ b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp @@ -2705,6 +2705,24 @@ class AArch64MCPlusBuilder : public MCPlusBuilder { return Insts; } + bool isBTILandingPad(MCInst &Inst, bool CouldCall, + bool CouldJump) const override { + unsigned HintNum = getBTIHintNum(CouldCall, CouldJump); + 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 CouldCall, bool CouldJump) const override { Inst.setOpcode(AArch64::HINT); unsigned HintNum = getBTIHintNum(CouldCall, CouldJump); 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
