Skip to content

Commit 8ee9510

Browse files
committed
toolchain-bootstrap: apply patches related to computed gotos
The vendored patches were produced from the latest versions of the following PRs: * llvm/llvm-project#114990 * llvm/llvm-project#120267 The first improves codegen for computed gotos. There was a regression in LLVM 19 causing a ~10% performance drop in CPython. The second enables BOLT to work with computed gotos. This enables BOLT to accomplish more on CPython.
1 parent f673b0b commit 8ee9510

6 files changed

+613
-0
lines changed

toolchain-bootstrap/Earthfile

+1
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,7 @@ llvm-gnu-x86-64-linux-build:
367367
FOR toolchain IN cpython-x86-64-linux clang-bootstrap-x86-64-linux zstd-x86-64-linux
368368
COPY +$toolchain/install /toolchain/
369369
END
370+
COPY patches/*.patch /build/
370371
COPY scripts/clang-gnu-stage2.sh /build/
371372
RUN --secret SCCACHE_REGION --secret SCCACHE_BUCKET --secret AWS_ACCESS_KEY_ID --secret AWS_SECRET_ACCESS_KEY \
372373
PARALLEL_NINJA=${PARALLEL_NINJA} NINJA_MAX_LOAD=${NINJA_MAX_LOAD} \
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,271 @@
1+
commit 430cceda43be7e9306823fcacbd3c91c1f1a29d2
2+
Author: Gregory Szorc <[email protected]>
3+
Date: Sat Mar 8 13:30:46 2025 -0800
4+
5+
Squashed commit of the following:
6+
7+
commit bb4bf9f4c3ce9eae007b623e9be07f7338db7905
8+
Author: Ash Dobrescu <[email protected]>
9+
Date: Wed Feb 26 12:48:20 2025 +0000
10+
11+
Fix error message.
12+
13+
commit 8b51075b1b88f1265cfc117387a306c243c1e9bd
14+
Author: Ash Dobrescu <[email protected]>
15+
Date: Tue Feb 25 16:42:08 2025 +0000
16+
17+
Add extra check and formatting.
18+
19+
commit fea7541c63daa16d533bbe54e395837610d6927c
20+
Author: Ash Dobrescu <[email protected]>
21+
Date: Fri Feb 7 14:42:22 2025 +0000
22+
23+
Remove unnecessary brackets
24+
25+
commit fb865642f7d3cefaa52477dc8ae3bc03770cfef1
26+
Author: Ash Dobrescu <[email protected]>
27+
Date: Fri Feb 7 14:23:57 2025 +0000
28+
29+
Add BOLT-ERRORs
30+
31+
commit db722a9b5d02d90cdd647f3429c0636653093844
32+
Author: Ash Dobrescu <[email protected]>
33+
Date: Wed Feb 5 15:45:32 2025 +0000
34+
35+
Add checks
36+
37+
commit 39d46f3762fbc7efcf4bd8a9adce5616cbacbcd3
38+
Author: Ash Dobrescu <[email protected]>
39+
Date: Fri Jan 31 12:23:01 2025 +0000
40+
41+
Address comments regarding tests
42+
43+
commit b44c28a7ff27b48e8ce3db6842599c725d0b57e9
44+
Author: Rin Dobrescu <[email protected]>
45+
Date: Thu Jan 23 10:45:38 2025 +0000
46+
47+
Fix formatting issue.
48+
49+
commit b1d80333d48237f39efbdabe82fe2514bc77e753
50+
Author: Rin Dobrescu <[email protected]>
51+
Date: Mon Jan 20 14:50:11 2025 +0000
52+
53+
Add target independent test.
54+
55+
commit 1dd6d5a0d6b572036a004bb87a1a204fa0c5dd84
56+
Author: Rin Dobrescu <[email protected]>
57+
Date: Tue Dec 31 12:45:05 2024 +0000
58+
59+
Remove redundant test and expand different test.
60+
61+
commit dd67da54eba30b68350cc95f6e3eeb31d9dbb9ce
62+
Author: Rin Dobrescu <[email protected]>
63+
Date: Wed Dec 18 12:11:10 2024 +0000
64+
65+
Fix clang-format and address PR comments.
66+
67+
commit f6435e5499dd0384820381bf85995b823789c279
68+
Author: Rin Dobrescu <[email protected]>
69+
Date: Tue Dec 17 16:43:33 2024 +0000
70+
71+
[BOLT][AArch64] Create entry points for addresses referenced by dynamic relocations and allow getNewFunctionOrDataAddress to map addrs inside functions.
72+
73+
By adding addresses referenced by dynamic relocations as entry points,
74+
this patch fixes an issue where bolt fails on code using computing
75+
goto's. This also fixes a mapping issue with the bugfix from this
76+
PR: https://github.com/llvm/llvm-project/pull/117766.
77+
78+
diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp
79+
index 4329235d4704..1439b88c253d 100644
80+
--- a/bolt/lib/Rewrite/RewriteInstance.cpp
81+
+++ b/bolt/lib/Rewrite/RewriteInstance.cpp
82+
@@ -2439,6 +2439,33 @@ void RewriteInstance::readDynamicRelocations(const SectionRef &Section,
83+
if (Symbol)
84+
SymbolIndex[Symbol] = getRelocationSymbol(InputFile, Rel);
85+
86+
+ const uint64_t ReferencedAddress = SymbolAddress + Addend;
87+
+ BinaryFunction *Func =
88+
+ BC->getBinaryFunctionContainingAddress(ReferencedAddress);
89+
+
90+
+ if (Relocation::isRelative(RType) && SymbolAddress == 0) {
91+
+ if (Func) {
92+
+ if (!Func->isInConstantIsland(ReferencedAddress)) {
93+
+ if (const uint64_t ReferenceOffset =
94+
+ ReferencedAddress - Func->getAddress()) {
95+
+ Func->addEntryPointAtOffset(ReferenceOffset);
96+
+ } else if (ReferencedAddress < Func->getAddress()) {
97+
+ BC->errs() << "BOLT-ERROR: Unable to compute symbol offset.\n";
98+
+ exit(1);
99+
+ }
100+
+ } else {
101+
+ BC->errs() << "BOLT-ERROR: referenced address: " << ReferencedAddress
102+
+ << " is in constant island of function : " << *Func
103+
+ << "\n";
104+
+ exit(1);
105+
+ }
106+
+ }
107+
+ } else if (Relocation::isRelative(RType) && SymbolAddress != 0) {
108+
+ BC->errs() << "BOLT-ERROR: symbol address non zero for RELATIVE "
109+
+ "relocation type.\n";
110+
+ exit(1);
111+
+ }
112+
+
113+
BC->addDynamicRelocation(Rel.getOffset(), Symbol, RType, Addend);
114+
}
115+
}
116+
@@ -5599,7 +5626,7 @@ uint64_t RewriteInstance::getNewFunctionOrDataAddress(uint64_t OldAddress) {
117+
for (const BinaryBasicBlock &BB : *BF)
118+
if (BB.isEntryPoint() &&
119+
(BF->getAddress() + BB.getOffset()) == OldAddress)
120+
- return BF->getOutputAddress() + BB.getOffset();
121+
+ return BB.getOutputStartAddress();
122+
}
123+
BC->errs() << "BOLT-ERROR: unable to get new address corresponding to "
124+
"input address 0x"
125+
diff --git a/bolt/test/AArch64/computed-goto.s b/bolt/test/AArch64/computed-goto.s
126+
new file mode 100644
127+
index 000000000000..5d775b9a6aea
128+
--- /dev/null
129+
+++ b/bolt/test/AArch64/computed-goto.s
130+
@@ -0,0 +1,67 @@
131+
+// This test checks that BOLT creates entry points for addresses
132+
+// referenced by dynamic relocations.
133+
+// The test also checks that BOLT can map addresses inside functions.
134+
+
135+
+// Checks for error and entry points.
136+
+# RUN: llvm-mc -filetype=obj -triple aarch64-unknown-unknown %s -o %t.o
137+
+# RUN: %clang %cflags %t.o -o %t.exe -Wl,-q
138+
+# RUN: llvm-bolt %t.exe -o %t.bolt 2>&1 | FileCheck %s
139+
+# RUN: llvm-bolt %t.exe -o %t.bolt --print-cfg | FileCheck --check-prefix=CHECK-ENTRIES %s
140+
+
141+
+// Checks for dynamic relocations.
142+
+# RUN: llvm-readelf -dr %t.bolt > %t.out.txt
143+
+# RUN: llvm-objdump -j .rela.dyn -d %t.bolt >> %t.out.txt
144+
+# RUN: FileCheck --check-prefix=CHECK-RELOCS %s --input-file=%t.out.txt
145+
+
146+
+// Before bolt could handle mapping addresses within moved functions, it
147+
+// would bail out with an error of the form:
148+
+// BOLT-ERROR: unable to get new address corresponding to input address 0x10390 in function main. Consider adding this function to --skip-funcs=...
149+
+// These addresses arise if computed GOTO is in use.
150+
+// Check that bolt does not emit any error.
151+
+# CHECK-NOT: BOLT-ERROR
152+
+
153+
+// Check that there are dynamic relocations.
154+
+# CHECK-RELOCS: Dynamic section at offset {{.*}} contains {{.*}} entries:
155+
+# CHECK-RELOCS: Relocation section '.rela.dyn' at offset {{.*}} contains {{.*}} entries
156+
+
157+
+// Check that dynamic relocations were updated
158+
+# CHECK-RELOCS: [[#%x,OFF:]] [[#%x,INFO_DYN:]] R_AARCH64_RELATIVE [[#%x,ADDR:]]
159+
+# CHECK-RELOCS-NEXT: [[#OFF + 8]] {{0*}}[[#INFO_DYN]] R_AARCH64_RELATIVE [[#ADDR + 8]]
160+
+# CHECK-RELOCS: [[#ADDR]] <unknown>
161+
+# CHECK-RELOCS: [[#ADDR + 8]] <unknown>
162+
+
163+
+// Check that BOLT registers extra entry points for dynamic relocations.
164+
+# CHECK-ENTRIES: Binary Function "main" after building cfg {
165+
+# CHECK-ENTRIES: IsMultiEntry: 1
166+
+# CHECK-ENTRIES: .Ltmp0 {{.*}}
167+
+# CHECK-ENTRIES-NEXT: Secondary Entry Point: {{.*}}
168+
+# CHECK-ENTRIES: .Ltmp1 {{.*}}
169+
+# CHECK-ENTRIES-NEXT: Secondary Entry Point: {{.*}}
170+
+
171+
+.globl main
172+
+.p2align 2
173+
+.type main,@function
174+
+main:
175+
+.cfi_startproc
176+
+ adrp x8, .L__const.main.ptrs+8
177+
+ add x8, x8, :lo12:.L__const.main.ptrs+8
178+
+ ldr x9, [x8], #8
179+
+ br x9
180+
+
181+
+.Label0: // Block address taken
182+
+ ldr x9, [x8], #8
183+
+ br x9
184+
+
185+
+.Label1: // Block address taken
186+
+ mov w0, #42
187+
+ ret
188+
+
189+
+.Lfunc_end0:
190+
+.size main, .Lfunc_end0-main
191+
+.cfi_endproc
192+
+ .type .L__const.main.ptrs,@object
193+
+ .section .data.rel.ro,"aw",@progbits
194+
+ .p2align 3, 0x0
195+
+.L__const.main.ptrs:
196+
+ .xword .Label0
197+
+ .xword .Label1
198+
diff --git a/bolt/test/X86/Inputs/indirect_goto.c b/bolt/test/Inputs/indirect_goto.c
199+
similarity index 64%
200+
rename from bolt/test/X86/Inputs/indirect_goto.c
201+
rename to bolt/test/Inputs/indirect_goto.c
202+
index b781e9e03b6d..5b8d91526441 100644
203+
--- a/bolt/test/X86/Inputs/indirect_goto.c
204+
+++ b/bolt/test/Inputs/indirect_goto.c
205+
@@ -1,6 +1,6 @@
206+
int main(int argc, char *argv[]) {
207+
- static const void *T1[] = { &&L1, &&L2 };
208+
- static const void *T2[] = { &&L2, &&L3 };
209+
+ static const void *T1[] = {&&L1, &&L2};
210+
+ static const void *T2[] = {&&L2, &&L3};
211+
212+
const void **T = (argc > 1) ? T1 : T2;
213+
214+
diff --git a/bolt/test/X86/indirect-goto-pie.test b/bolt/test/X86/indirect-goto-pie.test
215+
deleted file mode 100644
216+
index 3311c1aec061..000000000000
217+
--- a/bolt/test/X86/indirect-goto-pie.test
218+
+++ /dev/null
219+
@@ -1,16 +0,0 @@
220+
-## Check that llvm-bolt fails to process PIC binaries with computed goto, as the
221+
-## support is not there yet for correctly updating dynamic relocations
222+
-## referencing code inside functions.
223+
-
224+
-REQUIRES: x86_64-linux
225+
-
226+
-RUN: %clang %S/Inputs/indirect_goto.c -o %t -fpic -pie -Wl,-q
227+
-RUN: not llvm-bolt %t -o %t.bolt --relocs=1 --print-cfg --print-only=main \
228+
-RUN: 2>&1 | FileCheck %s
229+
-
230+
-## Check that processing works if main() is skipped.
231+
-RUN: llvm-bolt %t -o %t.bolt --relocs=1 --skip-funcs=main
232+
-
233+
-CHECK: jmpq *%rax # UNKNOWN CONTROL FLOW
234+
-
235+
-CHECK: BOLT-ERROR: unable to get new address
236+
diff --git a/bolt/test/X86/indirect-goto.test b/bolt/test/X86/indirect-goto.test
237+
index 8d2cb5e62a97..aeb89de3f2fc 100644
238+
--- a/bolt/test/X86/indirect-goto.test
239+
+++ b/bolt/test/X86/indirect-goto.test
240+
@@ -1,5 +1,5 @@
241+
## Check llvm-bolt processes binaries compiled from sources that use indirect goto.
242+
-RUN: %clang %cflags -no-pie %S/Inputs/indirect_goto.c -Wl,-q -o %t
243+
+RUN: %clang %cflags -no-pie %S/../Inputs/indirect_goto.c -Wl,-q -o %t
244+
RUN: llvm-bolt %t -o %t.null --relocs=1 --print-cfg --print-only=main \
245+
RUN: --strict \
246+
RUN: 2>&1 | FileCheck %s
247+
diff --git a/bolt/test/indirect-goto-relocs.test b/bolt/test/indirect-goto-relocs.test
248+
new file mode 100644
249+
index 000000000000..30175dcb0b9c
250+
--- /dev/null
251+
+++ b/bolt/test/indirect-goto-relocs.test
252+
@@ -0,0 +1,19 @@
253+
+// This test checks that BOLT creates entry points from sources
254+
+// that use indirect goto.
255+
+
256+
+RUN: %clang %cflags -pie %S/Inputs/indirect_goto.c -o %t.exe -Wl,-q
257+
+RUN: llvm-bolt %t.exe -o %t.bolt --print-cfg | FileCheck --check-prefix=CHECK-PIE %s
258+
+
259+
+RUN: %clang %cflags -no-pie %S/Inputs/indirect_goto.c -o %t.exe -Wl,-q
260+
+RUN: llvm-bolt %t.exe -o %t.bolt --print-cfg | FileCheck --check-prefix=CHECK-NO-PIE %s
261+
+
262+
+// Check that BOLT registers extra entry points for dynamic relocations with PIE.
263+
+CHECK-PIE: Binary Function "main" after building cfg {
264+
+CHECK-PIE: IsMultiEntry: 1
265+
+CHECK-PIE: Secondary Entry Points : {{.*}}
266+
+
267+
+// Check that BOLT does not register extra entry points for dynamic relocations
268+
+// without PIE
269+
+CHECK-NO-PIE: Binary Function "main" after building cfg {
270+
+CHECK-NO-PIE-NOT: IsMultiEntry: 1
271+
+CHECK-NO-PIE-NOT: Secondary Entry Points : {{.*}}

0 commit comments

Comments
 (0)