← board

Generator yield of a call expression lowers to unsupported IR

Symptom

examples/chess/chess.pas fails in the move generator:

Unsupported linear node in IR codegen! Kind=10 node=120 IRA=8 IRB=107 IRC=-1 IRIVal=90
pascal26:629: error: Unsupported linear node in IR codegen ()

The source reported at line 629 is the closing end of GenMoves, but the IR dump shows unsupported nodes immediately under IR_YIELD. The first offending source construct is:

if RankOf(dest) = promoRank then
begin
  yield MkMove(from, dest, pkQueen,  [mfPromo]);
  yield MkMove(from, dest, pkRook,   [mfPromo]);
  yield MkMove(from, dest, pkBishop, [mfPromo]);
  yield MkMove(from, dest, pkKnight, [mfPromo]);
end

MkMove(...) returns a TMove record. The same shape appears throughout GenMoves:

yield MkMove(from, dest, pkNone, [mfCapture]);
yield MkMove(4, 6, pkNone, [mfCastleK]);

--dump-ir shows:

unsupported a=8 ... ival=90 ...
yield a=<unsupported-node> ...

where IR_UNSUPPORTED carries a=8, i.e. AN_CALL.

Root Cause

IR lowering for stackful generator yield can handle record-yield storage once it has a lowered value/address, but AN_YIELD does not lower a record-returning call expression used directly as the yielded value. The call expression falls through to IR_UNSUPPORTED, then x86-64 codegen reports the generic unsupported linear node.

Using a local temporary is expected to sidestep the issue:

tmp := MkMove(from, dest, pkQueen, [mfPromo]);
yield tmp;

but the direct expression is legal source and should compile.

Direction

Acceptance

Log

Resolved-in: 085be11 (finalizing commit)