Compiling the same source twice with the same perry binary produces different LLVM IR. Not a miscompile — the programs behave identically — but it defeats any byte-level IR A/B, which is the primary evidence a rooting-campaign slice offers (#7615).
Repro
cargo build --release -p perry -p perry-runtime-static -p perry-stdlib-static
for run in 1 2; do
mkdir -p /tmp/det/$run && cd /tmp/det/$run
env PERRY_RS4GC=0 PERRY_GC_MOVING_LOOP_POLLS=1 PERRY_INLINE_SHADOW_SLOT=0 \
PERRY_NO_AUTO_OPTIMIZE=1 \
perry compile test-files/test_gap_object_create_method_this.ts -o out --trace llvm
done
diff /tmp/det/1/.perry-trace/llvm/*.ll /tmp/det/2/.perry-trace/llvm/*.ll
Two independent shapes, both reproducible:
1. String-constant numbering and function-name registration order.
< @.str.3 = private unnamed_addr constant [9 x i8] c"describe\00"
< @.str.4 = private unnamed_addr constant [9 x i8] c"getState\00"
< @.str.5 = private unnamed_addr constant [5 x i8] c"wrap\00"
---
> @.str.3 = private unnamed_addr constant [5 x i8] c"wrap\00"
> @.str.4 = private unnamed_addr constant [9 x i8] c"describe\00"
> @.str.5 = private unnamed_addr constant [9 x i8] c"getState\00"
with the matching permutation of js_register_function_name calls in __perry_init_strings_*_chunk0.
2. Method-callee selection permutes. In test_gap_class_expr_dynamic_parent_ctor, three consecutive dispatches swap which perry_method_* symbol each call site names:
< %r2492 = call double @perry_method_..._DerA__promise(double %r2956)
> %r2492 = call double @perry_method_..___anon_class_17__promise(double %r2956)
< %r2493 = call double @perry_method_..___anon_class_17__promise(double %r2955)
> %r2493 = call double @perry_method_..._DerB__promise(double %r2955)
Both smell like iteration over a HashMap/HashSet whose order is randomised per process.
Why it matters beyond tidiness
Filed from #7620; not fixed there.
Compiling the same source twice with the same
perrybinary produces different LLVM IR. Not a miscompile — the programs behave identically — but it defeats any byte-level IR A/B, which is the primary evidence a rooting-campaign slice offers (#7615).Repro
Two independent shapes, both reproducible:
1. String-constant numbering and function-name registration order.
with the matching permutation of
js_register_function_namecalls in__perry_init_strings_*_chunk0.2. Method-callee selection permutes. In
test_gap_class_expr_dynamic_parent_ctor, three consecutive dispatches swap whichperry_method_*symbol each call site names:Both smell like iteration over a
HashMap/HashSetwhose order is randomised per process.Why it matters beyond tidiness
diffwould have reported three phantom differences; one that used a multiset comparison and did not check determinism would have quietly dismissed a real ordering change..perry-cachekeys on codegen env vars (build: the object cache doesn't key on codegen env vars — PERRY_WRITE_BARRIERS=0 silently does nothing with a warm cache #6394), not on output. A nondeterministic emitter means two cache entries for the same inputs can differ.Filed from #7620; not fixed there.