Skip to content

Commit f1cc15e

Browse files
committed
[BOLT][BTI] Add MCPlusBuilder::isBTILandingPad
- takes both implicit and explicit BTIs into account - fix related comment in AArch64BranchTargets.cpp
1 parent 5cbe1e3 commit f1cc15e

File tree

4 files changed

+53
-2
lines changed

4 files changed

+53
-2
lines changed

bolt/include/bolt/Core/MCPlusBuilder.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1865,6 +1865,20 @@ class MCPlusBuilder {
18651865
llvm_unreachable("not implemented");
18661866
}
18671867

1868+
/// Check if an Instruction is a BTI landing pad with the required properties.
1869+
/// Takes both explicit and implicit BTIs into account.
1870+
virtual bool isBTILandingPad(MCInst &Inst, bool CouldCall,
1871+
bool CouldJump) const {
1872+
llvm_unreachable("not implemented");
1873+
return false;
1874+
}
1875+
1876+
/// Check if an Instruction is an implicit BTI c landing pad.
1877+
virtual bool isImplicitBTIC(MCInst &Inst) const {
1878+
llvm_unreachable("not implemented");
1879+
return false;
1880+
}
1881+
18681882
/// Create a BTI landing pad instruction.
18691883
virtual void createBTI(MCInst &Inst, bool CouldCall, bool CouldJump) const {
18701884
llvm_unreachable("not implemented");

bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2706,6 +2706,24 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
27062706
return Insts;
27072707
}
27082708

2709+
bool isBTILandingPad(MCInst &Inst, bool CouldCall,
2710+
bool CouldJump) const override {
2711+
unsigned HintNum = getBTIHintNum(CouldCall, CouldJump);
2712+
bool IsExplicitBTI =
2713+
Inst.getOpcode() == AArch64::HINT && Inst.getNumOperands() == 1 &&
2714+
Inst.getOperand(0).isImm() && Inst.getOperand(0).getImm() == HintNum;
2715+
2716+
bool IsImplicitBTI = HintNum == 34 && isImplicitBTIC(Inst);
2717+
return IsExplicitBTI || IsImplicitBTI;
2718+
}
2719+
2720+
bool isImplicitBTIC(MCInst &Inst) const override {
2721+
// PACI[AB]SP are always implicitly BTI C, independently of
2722+
// SCTLR_EL1.BT[01].
2723+
return Inst.getOpcode() == AArch64::PACIASP ||
2724+
Inst.getOpcode() == AArch64::PACIBSP;
2725+
}
2726+
27092727
void createBTI(MCInst &Inst, bool CouldCall, bool CouldJump) const override {
27102728
Inst.setOpcode(AArch64::HINT);
27112729
unsigned HintNum = getBTIHintNum(CouldCall, CouldJump);

bolt/unittests/Core/MCPlusBuilder.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,22 +155,39 @@ TEST_P(MCPlusBuilderTester, AArch64_BTI) {
155155
auto II = BB->begin();
156156
ASSERT_EQ(II->getOpcode(), AArch64::HINT);
157157
ASSERT_EQ(II->getOperand(0).getImm(), 38);
158+
ASSERT_TRUE(BC->MIB->isBTILandingPad(*II, true, true));
158159

159160
MCInst BTIj;
160161
BC->MIB->createBTI(BTIj, false, true);
161162
II = BB->addInstruction(BTIj);
162163
ASSERT_EQ(II->getOpcode(), AArch64::HINT);
163164
ASSERT_EQ(II->getOperand(0).getImm(), 36);
165+
ASSERT_TRUE(BC->MIB->isBTILandingPad(*II, false, true));
164166

165167
MCInst BTIc;
166168
BC->MIB->createBTI(BTIc, true, false);
167169
II = BB->addInstruction(BTIc);
168170
ASSERT_EQ(II->getOpcode(), AArch64::HINT);
169171
ASSERT_EQ(II->getOperand(0).getImm(), 34);
172+
ASSERT_TRUE(BC->MIB->isBTILandingPad(*II, true, false));
170173

171174
MCInst BTIinvalid;
172175
ASSERT_DEATH(BC->MIB->createBTI(BTIinvalid, false, false),
173176
"No target kinds!");
177+
178+
MCInst Paciasp = MCInstBuilder(AArch64::PACIASP);
179+
II = BB->addInstruction(Paciasp);
180+
ASSERT_TRUE(BC->MIB->isBTILandingPad(*II, true, false));
181+
ASSERT_FALSE(BC->MIB->isBTILandingPad(*II, true, true));
182+
ASSERT_FALSE(BC->MIB->isBTILandingPad(*II, false, true));
183+
ASSERT_TRUE(BC->MIB->isImplicitBTIC(*II));
184+
185+
MCInst Pacibsp = MCInstBuilder(AArch64::PACIBSP);
186+
II = BB->addInstruction(Pacibsp);
187+
ASSERT_TRUE(BC->MIB->isBTILandingPad(*II, true, false));
188+
ASSERT_FALSE(BC->MIB->isBTILandingPad(*II, true, true));
189+
ASSERT_FALSE(BC->MIB->isBTILandingPad(*II, false, true));
190+
ASSERT_TRUE(BC->MIB->isImplicitBTIC(*II));
174191
}
175192

176193
TEST_P(MCPlusBuilderTester, AArch64_CmpJNE) {

llvm/lib/Target/AArch64/AArch64BranchTargets.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,10 @@ void AArch64BranchTargets::addBTI(MachineBasicBlock &MBB, bool CouldCall,
150150
++MBBI)
151151
;
152152

153-
// SCTLR_EL1.BT[01] is set to 0 by default which means
154-
// PACI[AB]SP are implicitly BTI C so no BTI C instruction is needed there.
153+
// PACI[AB]SP are compatible with BTI c, independently of SCTLR_EL1.BT[01].
154+
// If SCTLR_EL1.BT[01] is set to 1, they are compatible with BTI jc, but we
155+
// cannot rely on that it compile time. Therefore, we can only skip adding a
156+
// BTI c for these.
155157
if (MBBI != MBB.end() && ((HintNum & BTIMask) == BTIC) &&
156158
(MBBI->getOpcode() == AArch64::PACIASP ||
157159
MBBI->getOpcode() == AArch64::PACIBSP))

0 commit comments

Comments
 (0)