Skip to content

Commit 977f649

Browse files
committed
[BOLT][AArch64] Fixes assertion errors occurred when perf2bolt was executed
BOLT only checks for the most common indirect branch pattern during the branch analyzation. Needs to extend the current logic with other cases which slightly differs from the expected one. This instruction sequences comes from libc, it occurs when the binary is static. As a workaround mark it as UNKNOWN branch and add support for them in a follow up PR later. Fixes: #83114
1 parent 720b958 commit 977f649

File tree

2 files changed

+60
-2
lines changed

2 files changed

+60
-2
lines changed

bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -702,8 +702,20 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
702702
unsigned ShiftVal = AArch64_AM::getArithShiftValue(OperandExtension);
703703
AArch64_AM::ShiftExtendType ExtendType =
704704
AArch64_AM::getArithExtendType(OperandExtension);
705-
if (ShiftVal != 2)
706-
llvm_unreachable("Failed to match indirect branch! (fragment 2)");
705+
if (ShiftVal != 2) {
706+
// TODO: handle that case where ShiftVal != 2.
707+
// The following code sequence below has no shift amount,
708+
// the range could be 0 to 4.
709+
// The pattern comes from libc, it occurs when the binary is static.
710+
// adr x6, 0x219fb0 <sigall_set+0x88>
711+
// add x6, x6, x14, lsl #2
712+
// ldr w7, [x6]
713+
// add x6, x6, w7, sxtw => no shift amount
714+
// br x6
715+
errs() << "BOLT-WARNING: "
716+
"Failed to match indirect branch: ShiftVAL != 2 \n";
717+
return false;
718+
}
707719

708720
if (ExtendType == AArch64_AM::SXTB)
709721
ScaleValue = 1LL;
@@ -748,6 +760,19 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
748760
return true;
749761
}
750762

763+
if (DefJTBaseAdd->getOpcode() == AArch64::ADR) {
764+
// TODO: handle that case when we do not have adrp/add pair.
765+
// It also occurs when the binary is static.
766+
// adr x13, 0x215a18 <_nl_value_type_LC_COLLATE+0x50>
767+
// ldrh w13, [x13, w12, uxtw #1]
768+
// adr x12, 0x247b30 <__gettextparse+0x5b0>
769+
// add x13, x12, w13, sxth #2
770+
// br x13
771+
errs() << "BOLT-WARNING: Failed to match indirect branch: "
772+
"nop/adr instead of adrp/add \n";
773+
return false;
774+
}
775+
751776
assert(DefJTBaseAdd->getOpcode() == AArch64::ADDXri &&
752777
"Failed to match jump table base address pattern! (1)");
753778

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Test how BOLT handles indirect branch sequence of instructions in
2+
// AArch64MCPlus builder.
3+
// This test checks that case when we have no shift amount after add
4+
// instruction. This pattern comes from libc, so needs to build '-static'
5+
// binary to reproduce the issue easily.
6+
//
7+
// adr x6, 0x219fb0 <sigall_set+0x88>
8+
// add x6, x6, x14, lsl #2
9+
// ldr w7, [x6]
10+
// add x6, x6, w7, sxtw => no shift amount
11+
// br x6
12+
// It also tests another case when we use '-fuse-ld=lld' along with '-static'
13+
// which produces the following sequence of intsructions:
14+
//
15+
// nop => nop/adr instead of adrp/add
16+
// adr x13, 0x215a18 <_nl_value_type_LC_COLLATE+0x50>
17+
// ldrh w13, [x13, w12, uxtw #1]
18+
// adr x12, 0x247b30 <__gettextparse+0x5b0>
19+
// add x13, x12, w13, sxth #2
20+
// br x13
21+
22+
// clang-format off
23+
24+
// REQUIRES: system-linux
25+
// RUN: %clang %s -o %t.exe -Wl,-q -static -fuse-ld=lld \
26+
// RUN: --target=aarch64-unknown-linux-gnu
27+
// RUN: llvm-bolt %t.exe -o %t.bolt --print-cfg \
28+
// RUN: -v=1 2>&1 | FileCheck --match-full-lines %s
29+
30+
// CHECK: BOLT-WARNING: Failed to match indirect branch: nop/adr instead of adrp/add
31+
// CHECK: BOLT-WARNING: Failed to match indirect branch: ShiftVAL != 2
32+
33+
int main() { return 42; }

0 commit comments

Comments
 (0)