Skip to content

Codegen is not run-to-run deterministic: string-constant numbering, function-name registration order, and method-callee selection permute #7622

Description

@proggeramlug

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions