Skip to content

Regression: AOT RecursiveTreeIterator foreach — Module.php:180 cross-function BBs (re-#27584, ext/spl/spl_iterators.c) #33974

Closed

Description

@PurHur

Category

bug · php-src-strict · AOT · SPL · pillar 4 (Correctness)

Problem

On master @ 2b3c52fd64, thin AOT compile of RecursiveTreeIterator foreach fails module verification (Module.php:180) with cross-function basic blocks (rti_walk_adv, ht_values_pk_head_*). Zend / VM match the expected tree strings.

ParentIterator / MultipleIterator alone still match Zend under AOT; the walk ABI is the regression surface from #27584.

Repro Zend / VM AOT (before)
RecursiveTreeIterator(RecursiveArrayIterator(["a"=>["b"=>1,"c"=>2]])) foreach \-Array| |-1| \-2| compile fatal: Referring to a basic block in another function
Parent + Multi + Tree (#27584 wrap) Parent:b / Multi:a:1 b:2 / Tree:\-Array|… same verify failure when Tree is present

Root cause (diagnosis)

RecursiveTreeIteratorBuildRuntime::emitWalk creates control-flow BBs on __compiler_rti_walk, but HashTableValuesLlvm / HashTableReadLlvm / strval append via BasicBlockHelper::append, which prefers Context::$loweringLlvmFunction (user main) over the walk insert parent — same class as #33896 (range) / #33934 (mktime).

php-src reference

PHP implementation target

  • lib/JIT/Builtin/RecursiveTreeIteratorBuildRuntime.php — BasicBlockHelper::scopeLoweringToFunction around walk/build emit (peer ArrayWalkLlvm / RangeIntRuntime)

Repro

./script/docker-exec.sh -- bash -lc 'php bin/compile.php -o /tmp/rti.bin test/repro/aot_recursive_tree_iterator_module_verify.php'

Done when

  • AOT compile succeeds; stdout matches Zend for the wrap repro
  • ./script/aot-smoke.sh stays 8/8
  • Unit guard under test/unit/ (@group llvm/aot)

lane overflow: #32122 / #31968 children closed; no open lane-C AOT crash in queue.

Activity

  1. added
    bugSomething isn't working
    phase-3:aotPhase 3 – AOT deployment
    implementation-readySpec complete: repro, php-src ref, done-when — safe for workers to claim
    on Aug 22, 2026
  2. PurHur commented on Aug 22, 2026

    @PurHur
    OwnerAuthor

    claim: worker-lane-c — starting this run (lane overflow: #32122/#31968 children closed; open queue had no unclaimed AOT crash). Fix: scope loweringLlvmFunction onto RTI walk/build ABIs.

  3. PurHur commented on Aug 22, 2026

    @PurHur
    OwnerAuthor

    merged: #33978

    Root cause: RecursiveTreeIteratorBuildRuntime emitWalk/emitBuild left Context::$loweringLlvmFunction on user main, so HashTable*Llvm / strval BBs landed in the wrong function while rti_walk_* stayed on __compiler_rti_walk → Module.php:180.

    Fix: BasicBlockHelper::scopeLoweringToFunction around walk/build emit (peer #33896 / #33934).

    Verification:

    • ./script/aot-smoke.sh → 8/8
    • ./script/phpunit.sh --filter Issue33974RecursiveTreeIteratorAotTest → OK (2 tests, 14 assertions)
    • wrap repro Zend/VM/AOT identical (Tree:\-Array| |-1| \-2|)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:compilerCompiler / CFG / JITbugSomething isn't workingimplementation-readySpec complete: repro, php-src ref, done-when — safe for workers to claimphase-3:aotPhase 3 – AOT deployment

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions