Skip to content

Commit 3c4f4f3

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 c63a622 commit 3c4f4f3

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
@@ -706,8 +706,20 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
706706
unsigned ShiftVal = AArch64_AM::getArithShiftValue(OperandExtension);
707707
AArch64_AM::ShiftExtendType ExtendType =
708708
AArch64_AM::getArithExtendType(OperandExtension);
709-
if (ShiftVal != 2)
710-
llvm_unreachable("Failed to match indirect branch! (fragment 2)");
709+
if (ShiftVal != 2) {
710+
// TODO: handle that case where ShiftVal != 2.
711+
// The following code sequence below has no shift amount,
712+
// the range could be 0 to 4.
713+
// The pattern comes from libc, it occurs when the binary is static.
714+
// adr x6, 0x219fb0 <sigall_set+0x88>
715+
// add x6, x6, x14, lsl #2
716+
// ldr w7, [x6]
717+
// add x6, x6, w7, sxtw => no shift amount
718+
// br x6
719+
errs() << "BOLT-WARNING: "
720+
"Failed to match indirect branch: ShiftVAL != 2 \n";
721+
return false;
722+
}
711723

712724
if (ExtendType == AArch64_AM::SXTB)
713725
ScaleValue = 1LL;
@@ -752,6 +764,19 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
752764
return true;
753765
}
754766

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

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)