@@ -475,23 +475,9 @@ func (c *Compiler) extractCondExprs(expr ast.Expression, cond llvm.Value, temps
475475 // Comparisons with ranges can be extracted only when all required iterators
476476 // are already bound by an outer loop (no pending ranges).
477477 if infix , ok := expr .(* ast.InfixExpression ); ok && info .HasCondScalar () && len (c .pendingLoopRanges (info .Ranges )) == 0 {
478- // Bottom-up: extract conditions from operands first
479478 cond , temps = c .extractCondExprs (infix .Left , cond , temps )
480479 cond , temps = c .extractCondExprs (infix .Right , cond , temps )
481-
482- // Compile both operands (may return pre-extracted values)
483- left := c .compileExpression (infix .Left , nil )
484- right := c .compileExpression (infix .Right , nil )
485-
486- var lhsSyms []* Symbol
487- lhsSyms , cond = c .handleComparisons (infix .Operator , left , right , info , cond )
488-
489- c .requireCondLHSFrame ()[key (c .FuncNameMangled , expr )] = lhsSyms
490- temps = append (temps , condTemp {infix .Left , left })
491- // Free right-side temporaries (only used for comparison).
492- // Left-side values are retained in condLHS for later substitution.
493- c .freeTemporary (infix .Right , right )
494- return cond , temps
480+ return c .extractCondExprSelf (infix , info , cond , temps )
495481 }
496482
497483 // Not a conditional expression — recurse into children
@@ -501,6 +487,21 @@ func (c *Compiler) extractCondExprs(expr ast.Expression, cond llvm.Value, temps
501487 return cond , temps
502488}
503489
490+ func (c * Compiler ) extractCondExprSelf (infix * ast.InfixExpression , info * ExprInfo , cond llvm.Value , temps []condTemp ) (llvm.Value , []condTemp ) {
491+ left := c .compileExpression (infix .Left , nil )
492+ right := c .compileExpression (infix .Right , nil )
493+
494+ var lhsSyms []* Symbol
495+ lhsSyms , cond = c .handleComparisons (infix .Operator , left , right , info , cond )
496+
497+ c .requireCondLHSFrame ()[key (c .FuncNameMangled , infix )] = lhsSyms
498+ temps = append (temps , condTemp {infix .Left , left })
499+ // Free right-side temporaries (only used for comparison).
500+ // Left-side values are retained in condLHS for later substitution.
501+ c .freeTemporary (infix .Right , right )
502+ return cond , temps
503+ }
504+
504505// cleanupCondExprElse frees temporaries retained during cond-expr extraction
505506// that are not consumed when the condition evaluates to false.
506507func (c * Compiler ) cleanupCondExprElse (temps []condTemp ) {
@@ -530,7 +531,7 @@ func (c *Compiler) compileCondExprValue(expr ast.Expression, baseCond llvm.Value
530531
531532func (c * Compiler ) compileCondExprValueInFrame (expr ast.Expression , baseCond llvm.Value , onTrue func ()) {
532533 if c .hasLogicalOrCondExprInTree (expr ) {
533- c .compileCondExprAlternative (expr , baseCond , onTrue , func () {})
534+ c .compileCondExprWithFailure (expr , baseCond , onTrue , func () {})
534535 return
535536 }
536537
@@ -591,7 +592,7 @@ func (c *Compiler) compileCondExprChildrenInFrame(children []ast.Expression, bas
591592 child := children [0 ]
592593 rest := children [1 :]
593594 if c .hasCondExprInTree (child ) {
594- c .compileCondExprAlternative (child , baseCond , func () {
595+ c .compileCondExprWithFailure (child , baseCond , func () {
595596 c .compileCondExprChildrenInFrame (rest , llvm.Value {}, onTrue , onFalse )
596597 }, onFalse )
597598 return
@@ -600,9 +601,9 @@ func (c *Compiler) compileCondExprChildrenInFrame(children []ast.Expression, bas
600601 c .compileCondExprChildrenInFrame (rest , baseCond , onTrue , onFalse )
601602}
602603
603- func (c * Compiler ) compileCondExprAlternative (expr ast.Expression , baseCond llvm.Value , onTrue func (), onFalse func ()) {
604+ func (c * Compiler ) compileCondExprWithFailure (expr ast.Expression , baseCond llvm.Value , onTrue func (), onFalse func ()) {
604605 if logicalOr , ok := c .logicalOrCondExpr (expr ); ok {
605- c .compileLogicalOrCondExprAlternative (logicalOr , baseCond , onTrue , onFalse )
606+ c .compileLogicalOrCondExprWithFailure (logicalOr , baseCond , onTrue , onFalse )
606607 return
607608 }
608609
@@ -616,13 +617,7 @@ func (c *Compiler) compileCondExprAlternative(expr ast.Expression, baseCond llvm
616617 if infix , ok := expr .(* ast.InfixExpression ); ok {
617618 info := c .ExprCache [key (c .FuncNameMangled , infix )]
618619 if info != nil && info .HasCondScalar () && len (c .pendingLoopRanges (info .Ranges )) == 0 {
619- left := c .compileExpression (infix .Left , nil )
620- right := c .compileExpression (infix .Right , nil )
621-
622- lhsSyms , cond := c .handleComparisons (infix .Operator , left , right , info , llvm.Value {})
623- c .requireCondLHSFrame ()[key (c .FuncNameMangled , expr )] = lhsSyms
624- temps := []condTemp {{infix .Left , left }}
625- c .freeTemporary (infix .Right , right )
620+ cond , temps := c .extractCondExprSelf (infix , info , llvm.Value {}, nil )
626621 c .compileCondExprBranchWithFailure (cond , temps , onTrue , onFalse )
627622 return
628623 }
@@ -645,7 +640,14 @@ func (c *Compiler) withCondLHS(expr ast.Expression, syms []*Symbol, body func())
645640 delete (frame , exprKey )
646641}
647642
648- func (c * Compiler ) compileLogicalOrCondExprAlternative (expr * ast.InfixExpression , baseCond llvm.Value , onTrue func (), onFalse func ()) {
643+ func (c * Compiler ) compileLogicalOrCondExprWithFailure (expr * ast.InfixExpression , baseCond llvm.Value , onTrue func (), onFalse func ()) {
644+ if ! baseCond .IsNil () {
645+ c .compileCondExprBranchWithFailure (baseCond , nil , func () {
646+ c .compileLogicalOrCondExprWithFailure (expr , llvm.Value {}, onTrue , onFalse )
647+ }, onFalse )
648+ return
649+ }
650+
649651 leftTrue := func () {
650652 left := c .compileExpression (expr .Left , nil )
651653 c .withCondLHS (expr , left , onTrue )
@@ -655,8 +657,8 @@ func (c *Compiler) compileLogicalOrCondExprAlternative(expr *ast.InfixExpression
655657 c .withCondLHS (expr , right , onTrue )
656658 }
657659
658- c .compileCondExprAlternative (expr .Left , baseCond , leftTrue , func () {
659- c .compileCondExprAlternative (expr .Right , baseCond , rightTrue , onFalse )
660+ c .compileCondExprWithFailure (expr .Left , llvm. Value {} , leftTrue , func () {
661+ c .compileCondExprWithFailure (expr .Right , llvm. Value {} , rightTrue , onFalse )
660662 })
661663}
662664
0 commit comments