Bug description:
CPython's --enable-bolt build sets -icf=1 in BOLT_APPLY_FLAGS (configure.ac:2258), enabling BOLT's aggressive Identical Code Folding. ICF merges functions with identical machine code into a single address, including address-taken functions — concrete type-slot implementations like _PyTuple_Concat, _PyList_Concat, and slot_nb_* wrappers.
This violates two CPython invariants:
- Type slots require a function pointer matching the type's layout. When
_PyList_Concat and _PyTuple_Concat are folded, calls via sq_concat access the object through the wrong layout → SIGSEGV.
binary_op1 in Objects/abstract.c compares slot pointers (slotw == slotv) to drive reflected-operator dispatch. ICF-induced false equality skips __radd__.
test_no_comdat_folding in Lib/test/test_list.py / Lib/test/test_tuple.py exists exactly to detect this class of bug (originally for MSVC COMDAT folding, gh-8847).
Reproduction
./configure --enable-bolt CC=clang LDFLAGS=-fuse-ld=lld
make -j4
./python -m test -j4
Observed failures (main @ d206d42834b, BOLT build)
== Python build: release BOLT
[268/502] test_list worker non-zero exit code (Exit code -11 (SIGSEGV))
_PyList_Concat+0x88
PyNumber_Add+0x11
File "Lib/test/test_list.py", line 227 in test_no_comdat_folding
[435/502] test_tuple worker non-zero exit code (Exit code -11 (SIGSEGV))
_PyTuple_Concat+0xbb
PyNumber_Add+0x11
File "Lib/test/test_tuple.py", line 427 in test_no_comdat_folding
test test_descr failed -- test_gh146587
self.assertIsNone(B() + A())
TypeError: can only concatenate tuple (not "A") to tuple
test test_datetime failed -- test_computations
self.assertRaises(TypeError, lambda: a+i)
AssertionError: TypeError not raised by <lambda>
test test_perf_profiler failed
ValueError: Perf failed with return code -11
5 tests failed: test_datetime test_descr test_list test_perf_profiler test_tuple
Fix
Switch -icf=1 → -icf=0 in configure.ac. Disabling ICF preserves the C guarantee (C17 §6.5.9/6) that CPython's type-slot dispatch depends on — every address-taken function keeps a unique identity. Other BOLT passes (-reorder-blocks, -reorder-functions, -split-functions, -inline-all, …) are unaffected; BOLT's ICF in CPython gives <1% .text size and sub-percent throughput, so the cost is negligible.
(-icf=safe would be the theoretically nicer choice — fold non-address-taken only — but it is not recognized by BOLT shipped with LLVM ≤19 which CI uses, so -icf=0 is the portable fix.)
After the change, 4 of 5 failures disappear on ./python -m test -j4. (test_perf_profiler is a separate, pre-existing -Xperf_jit + BOLT issue, not caused by ICF.)
PR: gh-148833.
CPython versions tested on:
CPython main branch
Operating systems tested on:
Linux
Bug description:
CPython's
--enable-boltbuild sets-icf=1inBOLT_APPLY_FLAGS(configure.ac:2258), enabling BOLT's aggressive Identical Code Folding. ICF merges functions with identical machine code into a single address, including address-taken functions — concrete type-slot implementations like_PyTuple_Concat,_PyList_Concat, andslot_nb_*wrappers.This violates two CPython invariants:
_PyList_Concatand_PyTuple_Concatare folded, calls viasq_concataccess the object through the wrong layout → SIGSEGV.binary_op1inObjects/abstract.ccompares slot pointers (slotw == slotv) to drive reflected-operator dispatch. ICF-induced false equality skips__radd__.test_no_comdat_foldinginLib/test/test_list.py/Lib/test/test_tuple.pyexists exactly to detect this class of bug (originally for MSVC COMDAT folding, gh-8847).Reproduction
Observed failures (
main@d206d42834b, BOLT build)Fix
Switch
-icf=1→-icf=0inconfigure.ac. Disabling ICF preserves the C guarantee (C17 §6.5.9/6) that CPython's type-slot dispatch depends on — every address-taken function keeps a unique identity. Other BOLT passes (-reorder-blocks,-reorder-functions,-split-functions,-inline-all, …) are unaffected; BOLT's ICF in CPython gives <1%.textsize and sub-percent throughput, so the cost is negligible.(
-icf=safewould be the theoretically nicer choice — fold non-address-taken only — but it is not recognized by BOLT shipped with LLVM ≤19 which CI uses, so-icf=0is the portable fix.)After the change, 4 of 5 failures disappear on
./python -m test -j4. (test_perf_profileris a separate, pre-existing-Xperf_jit+ BOLT issue, not caused by ICF.)PR: gh-148833.
CPython versions tested on:
CPython main branch
Operating systems tested on:
Linux