Skip to content

cleavir: a local mv-call's phi must name the block its arguments end in - #1853

Closed
dg1sbg wants to merge 1 commit into
clasp-developers:mainfrom
dg1sbg:fix/lmvc-phi-predecessor
Closed

dg1sbg wants to merge 1 commit into
clasp-developers:mainfrom
dg1sbg:fix/lmvc-phi-predecessor

Conversation

@dg1sbg

@dg1sbg dg1sbg commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

DIRECT-MV-LOCAL-CALL-VAS gives MERGE one phi per optional parameter, then in each switch case builds that case's argument values and records the case's own block as the phi predecessor.

Building a value can emit an invoke — the checked unbox a generated type-checker performs, whenever a landing pad is in scope — and IRC-CREATE-INVOKE-WFT ends the block and continues in a fresh normal-dest. The phi is then told about a block that no longer branches to MERGE:

PHI node entries do not match predecessors!
  %phi263 = phi float [ undef, %lmvc-optional-0 ], [ %single-float276, %lmvc-optional-1 ], ...
label %lmvc-optional-3
label %normal-dest295

Broken module → the image dies.

  • both loops now read the insert block after the values are built, and use that
  • optional cases and the more-than-enough case alike
  • values computed before an invoke still dominate: their block dominates the invoke's normal destination

Repro (no minimal case yet — see below): a CLIM toolkit compiled natively, FiveAM compiling test bodies at run time; died at test 1582/2101 in a MULTIPLE-VALUE-BIND of three single-floats from a typed function inside an UNWIND-PROTECT. With this change the same run completes all 2101.

  • full ninja test: exit 0, 2070 successes, no new failure
  • 34 826 such block splits recorded in one instrumented run; callees are all generated …-CHECKER local functions
  • no regression test: 26 standalone shapes, including that source form, compile cleanly — the trigger needs type information the running image accumulates. Happy to keep hunting if you want the small case before merging.

The local multiple-value-call translator gives MERGE one phi per optional
parameter and, in each switch case, builds that case's argument values and
then records the case's own block as the phi's predecessor.  Building a
value can emit an INVOKE -- the checked unbox of a declared single-float
optional does, whenever a landing pad is in scope -- and IRC-CREATE-INVOKE-WFT
ends the current block and continues in a fresh normal-destination block.
The phi is then told about a block that no longer branches to MERGE:

  PHI node entries do not match predecessors!
    %phi263 = phi float [ undef, %lmvc-optional-0 ], [ %single-float276, %lmvc-optional-1 ], ...
  label %lmvc-optional-3
  label %normal-dest295

and the module is rejected, killing the image.  Both loops now read the
insert block AFTER the values are built and use that as the predecessor,
for the optional cases and for the more-than-enough case alike; the values
computed before an invoke still dominate, since the block they are in
dominates the invoke's normal destination.

Reproduced on NeoCLIM (a CLIM II toolkit compiled natively on Clasp) with
FiveAM compiling test bodies at run time: the image died at test 1582 of
2099, in a MULTIPLE-VALUE-BIND of three single-floats from a typed function
inside an UNWIND-PROTECT.  With this change the same procedure completes all
2099 with no verifier error.  A minimal standalone case is not yet in hand --
twelve shapes, including that source form on its own, compile cleanly, so
the trigger needs type information the running image has accumulated -- and
this commit therefore carries no regression test; the hunt continues.

Scope: full ninja test on the rebuilt boehmprecise image, exit 0, 2070
successes, the same five pre-existing unexpected successes, no new failure.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant