Repository navigation
Conversation
…decline stepped probes With stackalloc on: - Bounds propagation ran up to ops.len() sweeps before widening, so a nonconvergent pointer bound cost O(n^2): dash readtoken1 (O0) went from 2.5 s to over 400 s. Widen after 64 sweeps, at most eight times. - An address built as base + 8 - n beside SP = base - n (clang -O2's `neg %rax; mov %edx,8(%rcx,%rax,1)`, and x86 SIB `disp + base + index` placing the constant first) kept addressing the old frame, emitting `__builtin_dwarf_cfa()[-n] = 7`. Treat a constant-first INT_ADD as a constant step and rewrite dominated displaced copies from the buffer. - GCC -fstack-clash-protection lowers SP a page per iteration and then subtracts the residual; recovering that residual as the allocation emitted __builtin_alloca(size & 4095) and smashed the stack at size >= 4096. Decline a base carried around a loop by a nonzero step. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BEr111CDLJsQMzY3YSyWXD
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BEr111CDLJsQMzY3YSyWXD
|
[AUTOMATED] Pushed 02ccabb (plus a merge of main to clear an
New cases: |
|
[AUTOMATED] The default-off path is byte-identical and the option's counts and docs check out. Fixes pushed in 02ccabb: bounded the quadratic bounds propagation, handled the constant-first SIB address, and declined gcc's stepped stack-clash probes. Two option-on outputs are still wrong, so this stays open:
printf '__attribute__((noinline)) int obs(char*p,int n){p[n-1]^=(char)n;return (unsigned char)p[0]+(unsigned char)p[n-1];}\nint f(int n){int t=0;for(int i=0;i<20000;i++){char d[n+4000];d[0]=(char)i;t+=obs(d,n+4000);}return t;}\n' > s.c
clang -O0 -shared -fPIC -nostdlib -Wl,-Bsymbolic s.c -o s.so
kuna decompile s.so f --option stackalloc onEither decline when the loop back edge restores SP instead of deriving it from the allocation, or emit a block-scoped VLA. Also, all 8 |
|
[AUTOMATED] Addressed in 8177465 (with current main merged in 67f1c0a):
Preserved your bounded propagation, displaced-address and stepped stack-clash-probe fixes. Local focused validation passes: 24 allocation tests, eight ISA tests with 98,496 native/recompiled comparisons, and five catalog checks. No full local suite was run; CI is pending for the updated merge. CI follow-up in 1cac0c4: refresh the listing snapshot for the intentional |
Runtime-sized stack buffers can become addresses below a fixed C local, so recompiling the output corrupts memory across calls. This proposal adds an explicit
stackalloc onoption to preserve function-lifetime allocations across control flow.Without recovery, the buffer addresses a fixed local. With it, generated C uses
__builtin_allocaand returns 16 forn > 1, matching the native function.Validation: 24 focused Clang allocation tests; eight targets (x86/AMD64, ARM/AArch64, RISC-V32/64, SPARC32/64), 98,496 native/recompiled comparisons at O0/O2, checking values, helper calls and input digests. Scoped VLAs and unbounded SP loops must decline. CI installs Clang, LLD, QEMU and the SPARC linker, and reruns these tests with missing tools treated as failures. SPARC uses
noreturn_disc offto isolate existing no-return inference. Independent IR regressions cover zero and unrelated alignment masks. Catalog checks pass; full suite left to CI. Design, ABI references and timing limits:notes/dynamic-stack-allocation.md.