bootstrap-aot-link: VALUE-box concat + ordered float compare lowering#8563
bootstrap-aot-link: VALUE-box concat + ordered float compare lowering#8563PurHur wants to merge 10 commits into
Conversation
Route TYPE_CONCAT into __value__ slots instead of native string concat, and lower boxed __value__ vs native double relational compares so deferred stdlib smoke and string concat AOT targets compile again (21→13 gate failures). Co-authored-by: Cursor <cursoragent@cursor.com>
Load script-global VALUE arrays via valuePtrFromVariable before readHashtable (foreach_by_ref), guard string dimAssign to real char lvalues, and rebind && short-circuit false-branch phi slots that were mis-typed from string offset fetches (ns_func compile). Co-authored-by: Cursor <cursoragent@cursor.com>
When logical-and if conditions compare a string offset (e.g. $path[1] === ':'), the CFG reuses the dim-fetch operand for the bool === result; box the bool into __value__ instead of throwing assign type mismatch (ns_func AOT compile). Co-authored-by: Cursor <cursoragent@cursor.com>
Remove broken Helper fast paths for VALUE===bool (used wrong pointers). Branch identicalToNative bool/long checks so LLVM select does not eagerly call __value__readLong on non-matching tags. Add JitValueBox::readStringOrNull for ?string ternary returns; copy getenv __value__* rvalues into stack slots on first bind. Gate still 13 failures — getenv===false and ternary string return segfault at runtime (repro: test/repro/getenv_identical_false.php). Co-authored-by: Cursor <cursoragent@cursor.com>
Patch php-types getenv to string|false so CFG inference uses VALUE-box IDENTICAL lowering; reorder Helper IDENTICAL before JitLongArg; narrow type_pair self-host stub skip; use __value__readString for nullable string returns; split valueSlot/valueRef in VALUE dest assigns. Co-authored-by: Cursor <cursoragent@cursor.com>
Track function scope slots via jitCurrentBlock (not only entry block) so branch assigns and merge RETURN share one VALUE box. Skip freeing unnamed return phi temps marked dead by php-cfg, and resolve RETURN operands through functionScopeSlotBindings. AOT ?string ternary return still segfaults — next step is dominator-safe entry alloca or CoalesceHelper-style merge for string|null phi (#8555). Co-authored-by: Cursor <cursoragent@cursor.com>
Stabilize ?: phi scope bindings across CFG blocks, compile non-string arms before string arms for shared RETURN merges, and add readOwnedStringOrNull for nullable returns. AOT still segfaults when the string arm is php-cfg block1 (if-entry); VM/JIT pass. Adds repro scripts and debug-phi-root probe. Co-authored-by: Cursor <cursoragent@cursor.com>
Return typed string operands directly from the if-entry arm instead of reading the shared phi VALUE box after merge-block dead-operand frees. Nullable/union if-arms keep per-arm RETURN from the phi slot; pure string params skip the box on the string arm only. Verification: - test/repro/ns_nullable_ternary_return.php AOT exit 0 (was segfault) - test/repro/aot_ternary_bool.php AOT exit 0 - test/repro/getenv_identical_false.php AOT prints yes - make bootstrap-aot-link still 16 failures (ns_func, ne_null, …) Co-authored-by: Cursor <cursoragent@cursor.com>
|
claim: worker-lane-b-automation — starting this run |
…hape When a ?: return merge has a boxed ?string on the if-entry arm, swap CFG arms and invert the branch condition so codegen matches the working null === $x ? null : $x shape (issue #8555). AOT standalone still segfaults on test/repro/aot_ternary_ne_null.php f('hello') (JIT/VM pass); ns_func blocked on return-inside-if after dim-fetch condition. bootstrap-aot-link still 16 failures — not merge-ready. Co-authored-by: Cursor <cursoragent@cursor.com>
Update (lane C)Added commit Still not merge-ready — Key blockers documented on #8555:
|
Lane B update (WIP — not merging)Continued #8555/#8563 bootstrap-aot-link work on branch Root cause isolated
JIT ( Changes this run
Verification./script/docker-exec.sh -- bash -lc './vendor/bin/phpunit test/unit/TernaryReturnMergeSlotTest.php'
# OK (3 tests)
./script/docker-exec.sh -- bash -lc 'php script/bootstrap-inventory.php --check'
# OK 2669/2669
# Still blocked
./script/docker-exec.sh -- bash -lc 'export PHP_COMPILER_BOOTSTRAP_AOT_LINK=1; php bin/compile.php -o /tmp/t test/repro/aot_ternary_ne_null.php && /tmp/t'
# segfault 139
# No regression
./script/docker-exec.sh -- bash -lc 'export PHP_COMPILER_BOOTSTRAP_AOT_LINK=1; php bin/compile.php -o /tmp/t test/repro/ns_nullable_ternary_return.php && /tmp/t'
# OKNext stepPer d87ae06: dominator-safe entry alloca or CoalesceHelper-style merge for |
- Narrow ?: arm-tail RETURN opt to pure-string if arms; add branch-target swap hooks for nullable ?string if-entry patterns (#8563) - Add VM unit test for null !== $param ? $param : null return shape - Sync docs/bootstrap-inventory.md (2669 files, 0 blockers) Blocker: AOT still segfaults on test/repro/aot_ternary_ne_null.php when ?string param is returned from the if-entry CFG arm (literal if-arm OK; else-entry param return OK). JIT path passes; next: dominator-safe entry alloca per d87ae06 or Compiler assign-then-return rewrite. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Superseded by #8584 (clean branch from master with compile-time CFG rewrite). Old branch had merge conflicts with master JIT landing. |
…8563) (#8586) * Fix AOT ?: return for null !== $param ? $param : null pattern (#8563). Compile-time rewrite maps the if-entry ?string arm to null === $param ? null : $param (php-src equivalent) and tracks the JumpIf so branch targets stay aligned with IDENTICAL. Verification: php vendor/bin/phpunit test/unit/NullableNeNullTernaryRewriteTest.php test/unit/TernaryReturnMergeSlotTest.php php bin/vm.php test/repro/aot_ternary_ne_null.php PHP_COMPILER_BOOTSTRAP_AOT_LINK=1 php bin/compile.php -o /tmp/n test/repro/aot_ternary_ne_null.php && /tmp/n Co-authored-by: Cursor <cursoragent@cursor.com> * Fix AOT ?: return when non-null arm is if-entry (#8555) Return typed string operands directly from the if-entry arm instead of reading the shared phi VALUE box after merge-block dead-operand frees. Nullable/union if-arms keep per-arm RETURN from the phi slot; pure string params skip the box on the string arm only. Verification: - test/repro/ns_nullable_ternary_return.php AOT exit 0 (was segfault) - test/repro/aot_ternary_bool.php AOT exit 0 - test/repro/getenv_identical_false.php AOT prints yes - make bootstrap-aot-link still 16 failures (ns_func, ne_null, …) Co-authored-by: Cursor <cursoragent@cursor.com> * Fix AOT nullable ?string param returns via compile-time ?? rewrite (#8563). Rewrite direct and ternary returns of explicit ?T params to $param ?? null (php-src equivalent) so native AOT uses the proven coalesce VALUE-box path. Register nullable scalar returns as __value__* in JIT ABI; cherry-pick ?: merge lowering from #8555. Verification: php vendor/bin/phpunit test/unit/NullableNeNullTernaryRewriteTest.php test/unit/NullableStringReturnAbiTest.php PHP_COMPILER_BOOTSTRAP_AOT_LINK=1 php bin/compile.php -o /tmp/t test/repro/aot_ternary_ne_null.php && /tmp/t PHP_COMPILER_BOOTSTRAP_AOT_LINK=1 php bin/compile.php -o /tmp/t test/repro/aot_nullable_param_direct_return.php && /tmp/t Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: PurHur <PurHur@users.noreply.github.com> Co-authored-by: Cursor <cursoragent@cursor.com>
|
Merged #8586 Fix: compile-time rewrite of nullable param returns to Verification (all exit 0): PHP_COMPILER_BOOTSTRAP_AOT_LINK=1 php bin/compile.php -o /tmp/ne test/repro/aot_ternary_ne_null.php && /tmp/ne
PHP_COMPILER_BOOTSTRAP_AOT_LINK=1 php bin/compile.php -o /tmp/v test/repro/aot_ternary_var_nullable.php && /tmp/v
PHP_COMPILER_BOOTSTRAP_AOT_LINK=1 php bin/compile.php -o /tmp/d test/repro/aot_nullable_param_direct_return.php && /tmp/d
php vendor/bin/phpunit test/unit/NullableNeNullTernaryRewriteTest.php test/unit/NullableStringReturnAbiTest.php |
|
Merged #8586 — nullable param AOT returns green (see PR body for verification commands). |
* Fix AOT ?: return for null !== $param ? $param : null pattern (#8563). Compile-time rewrite maps the if-entry ?string arm to null === $param ? null : $param (php-src equivalent) and tracks the JumpIf so branch targets stay aligned with IDENTICAL. Verification: php vendor/bin/phpunit test/unit/NullableNeNullTernaryRewriteTest.php test/unit/TernaryReturnMergeSlotTest.php php bin/vm.php test/repro/aot_ternary_ne_null.php PHP_COMPILER_BOOTSTRAP_AOT_LINK=1 php bin/compile.php -o /tmp/n test/repro/aot_ternary_ne_null.php && /tmp/n Co-authored-by: Cursor <cursoragent@cursor.com> * Fix AOT ?: return when non-null arm is if-entry (#8555) Return typed string operands directly from the if-entry arm instead of reading the shared phi VALUE box after merge-block dead-operand frees. Nullable/union if-arms keep per-arm RETURN from the phi slot; pure string params skip the box on the string arm only. Verification: - test/repro/ns_nullable_ternary_return.php AOT exit 0 (was segfault) - test/repro/aot_ternary_bool.php AOT exit 0 - test/repro/getenv_identical_false.php AOT prints yes - make bootstrap-aot-link still 16 failures (ns_func, ne_null, …) Co-authored-by: Cursor <cursoragent@cursor.com> * Fix AOT nullable ?string param returns via compile-time ?? rewrite (#8563). Rewrite direct and ternary returns of explicit ?T params to $param ?? null (php-src equivalent) so native AOT uses the proven coalesce VALUE-box path. Register nullable scalar returns as __value__* in JIT ABI; cherry-pick ?: merge lowering from #8555. Verification: php vendor/bin/phpunit test/unit/NullableNeNullTernaryRewriteTest.php test/unit/NullableStringReturnAbiTest.php PHP_COMPILER_BOOTSTRAP_AOT_LINK=1 php bin/compile.php -o /tmp/t test/repro/aot_ternary_ne_null.php && /tmp/t PHP_COMPILER_BOOTSTRAP_AOT_LINK=1 php bin/compile.php -o /tmp/t test/repro/aot_nullable_param_direct_return.php && /tmp/t Co-authored-by: Cursor <cursoragent@cursor.com> * Extend inline expr call-arg bridging to new expressions (#8561). php-cfg also splits Expr_New results from FuncCall/New ctor args; route TYPE_ARG_SEND through the producer slot directly to avoid AOT assign type mismatches. Unblocks const_string_folder bootstrap smokes. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: PurHur <PurHur@users.noreply.github.com> Co-authored-by: Cursor <cursoragent@cursor.com>
Summary
Continues #8555 (bootstrap-aot-link): fixes AOT segfault on
?stringternary returns when the non-null value is assigned on the if-entry CFG arm.This commit (
cbf095b61):jumpIfTargetsReturnMerge)string-typed assign sources: emit RETURN from the assign operand on the if arm (skip phi VALUE-box read that was use-after-free under merge-block dead operands)Verification
Blockers (next)
test/repro/aot_ternary_ne_null.php—?stringparam on if-entry still segfaults (phi return)test/bootstrap-aot/ns_func.php— nested ternary / concat candidate pathmake bootstrap-aot-linkstill redCloses #8555