Skip to content

Commit 9aded61

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 6b21e17 commit 9aded61

File tree

2 files changed

+62
-2
lines changed

2 files changed

+62
-2
lines changed

bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -706,8 +706,21 @@ 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+
LLVM_DEBUG(
720+
dbgs() << "Failed to match indirect branch: ShiftVAL != 2 \n"
721+
);
722+
return false;
723+
}
711724

712725
if (ExtendType == AArch64_AM::SXTB)
713726
ScaleValue = 1LL;
@@ -752,6 +765,20 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
752765
return true;
753766
}
754767

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

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 instruction.
4+
// This pattern comes from libc, so needs to build '-static' binary to
5+
// 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+
23+
// REQUIRES: system-linux
24+
// RUN: %clang %s -o %t.exe -Wl,-q -static -fuse-ld=lld --target=aarch64-linux
25+
// RUN: llvm-bolt %t.exe -o %t.bolt --print-cfg \
26+
// RUN: --debug 2>&1 | FileCheck --match-full-lines %s
27+
28+
// CHECK: Failed to match indirect branch: nop/adr instead of adrp/add
29+
// CHECK: Failed to match indirect branch: ShiftVAL != 2
30+
31+
int main() {
32+
return 42;
33+
}

0 commit comments

Comments
 (0)