|
1 | 1 | // Test how BOLT handles indirect branch sequence of instructions in |
2 | 2 | // AArch64MCPlus builder. |
3 | | -// This test checks the pattern where there is no shift amount after add |
4 | | -// instruction. The pattern come from libc, it can be reproduced with |
5 | | -// a 'static' built binary. |
| 3 | + |
| 4 | +// clang-format off |
| 5 | + |
| 6 | +// REQUIRES: system-linux |
| 7 | +// RUN: llvm-mc -filetype=obj -triple aarch64-unknown-unknown %s -o %t.o |
| 8 | +// RUN: %clang %cflags --target=aarch64-unknown-linux %t.o -o %t.exe -Wl,-q |
| 9 | +// RUN: llvm-bolt %t.exe -o %t.bolt --print-cfg \ |
| 10 | +// RUN: -v=1 2>&1 | FileCheck %s |
| 11 | + |
| 12 | +// Pattern 1: there is no shift amount after the 'add' instruction. |
6 | 13 | // |
7 | 14 | // adr x6, 0x219fb0 <sigall_set+0x88> |
8 | 15 | // add x6, x6, x14, lsl #2 |
9 | 16 | // ldr w7, [x6] |
10 | 17 | // add x6, x6, w7, sxtw => no shift amount |
11 | 18 | // br x6 |
12 | 19 | // |
13 | | -// It also tests another case where there is no adrp/add pair. |
14 | | -// The pattern also come from libc, and it only represents in the binary |
15 | | -// if the lld linker is used to create the static binary. |
16 | | -// It doesn't occur with GCC ld linker. |
| 20 | + |
| 21 | +// Pattern 2: nop/adr pair is used in place of adrp/add |
17 | 22 | // |
18 | 23 | // nop => nop/adr instead of adrp/add |
19 | 24 | // adr x13, 0x215a18 <_nl_value_type_LC_COLLATE+0x50> |
|
22 | 27 | // add x13, x12, w13, sxth #2 |
23 | 28 | // br x13 |
24 | 29 |
|
25 | | -// clang-format off |
26 | | - |
27 | | -// REQUIRES: system-linux |
28 | | -// RUN: llvm-mc -filetype=obj -triple aarch64-unknown-unknown %s -o %t.o |
29 | | -// RUN: %clang %cflags --target=aarch64-unknown-linux %t.o -o %t.exe -Wl,-q |
30 | | -// RUN: llvm-bolt %t.exe -o %t.bolt --print-cfg \ |
31 | | -// RUN: -v=1 2>&1 | FileCheck %s |
32 | | - |
33 | | -// CHECK: BOLT-WARNING: Failed to match indirect branch: nop/adr instead of adrp/add |
34 | | -// CHECK: BOLT-WARNING: Failed to match indirect branch: ShiftVAL != 2 |
35 | | - |
36 | | - |
37 | 30 | .section .text |
38 | 31 | .align 4 |
39 | 32 | .globl _start |
40 | 33 | .type _start, %function |
41 | 34 | _start: |
42 | | - bl bar |
43 | | - bl end |
| 35 | + mov w1, #1 |
| 36 | + bl bar |
44 | 37 | mov x0, #4 |
45 | 38 | mov w8, #93 |
46 | 39 | svc #0 |
47 | 40 |
|
48 | 41 | bar: |
49 | | - mov w1, #3 |
50 | | - cmp x1, #0 |
51 | | - b.eq end |
52 | 42 | nop |
53 | 43 | adr x3, jump_table |
54 | 44 | ldrh w3, [x3, x1, lsl #1] |
55 | 45 | adr x1, .case0 |
56 | 46 | add x3, x1, w3, sxth #2 |
57 | 47 | br x3 |
| 48 | +// CHECK: BOLT-WARNING: Failed to match indirect branch: nop/adr instead of adrp/add |
58 | 49 | .case0: |
59 | 50 | mov w0, #1 |
60 | 51 | ret |
61 | 52 | .case1: |
62 | | - mov w0, #2 |
63 | | - ret |
64 | | -.case3: |
65 | | - mov w0, #3 |
66 | | - ret |
67 | | -.case4: |
68 | | - nop |
69 | 53 | mov x1, #0 |
70 | 54 | adr x3, datatable |
71 | 55 | add x3, x3, x1, lsl #2 |
72 | 56 | ldr w2, [x3] |
73 | 57 | add x3, x3, w2, sxtw |
74 | 58 | br x3 |
75 | | - nop |
76 | | - mov w0, #4 |
77 | | - ret |
78 | | -.case7: |
79 | | - mov w0, #4 |
80 | | - ret |
81 | | - |
| 59 | +// CHECK: BOLT-WARNING: Failed to match indirect branch: ShiftVAL != 2 |
82 | 60 | foo1: |
83 | 61 | ret |
84 | | - |
85 | 62 | foo2: |
86 | | - add w0, w0, #3 |
87 | 63 | ret |
88 | | - |
89 | 64 | foo3: |
90 | | - add w0, w0, #3 |
91 | 65 | ret |
92 | 66 |
|
93 | | -end: |
94 | | - add x0, x0, #99 |
95 | | - ret |
96 | | - |
97 | 67 | .section .rodata,"a",@progbits |
98 | 68 | jump_table: |
99 | 69 | .hword (.case0-.case0)>>2 |
100 | 70 | .hword (.case1-.case0)>>2 |
101 | | - .hword (.case3-.case0)>>2 |
102 | | - .hword (.case4-.case0)>>2 |
103 | | - .hword (.case7-.case0)>>2 |
104 | | - |
105 | 71 |
|
106 | 72 | datatable: |
107 | 73 | .word foo1-datatable |
108 | 74 | .word foo2-datatable |
109 | 75 | .word foo3-datatable |
110 | | - .word 20 |
0 commit comments