[tools] go/ssa: emit short-circuit control flow for boolean switch cases

1 view
Skip to first unread message

Alan Donovan (Gerrit)

unread,
Feb 26, 2026, 6:25:14 PM (21 hours ago) Feb 26
to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

Alan Donovan has uploaded the change for review

Commit message

go/ssa: emit short-circuit control flow for boolean switch cases

Previously, switch { case x && y: ... } would materialize the
condition as a boolean. In this case, because it contains &&,
it would be a phi node. This extra phi caused the yield analyzer
to emit false positives compared to the equivalent if/else chain.

Now, the SSA builder emits short-circuit control flow for boolean
switch cases. Happily, this crosses off a TODO that has been there
since day 1: https://go.dev/issue/77681#issuecomment-3969760732

+ regression test for gopls' yield analyzer

Fixes golang/go#77681
Change-Id: Ife9dee8443c0f2c09e95cacbfcefd5baacc97d99

Change diff

diff --git a/go/ssa/builder.go b/go/ssa/builder.go
index a75257c..3336203 100644
--- a/go/ssa/builder.go
+++ b/go/ssa/builder.go
@@ -1467,13 +1467,14 @@
var nextCond *BasicBlock
for _, cond := range cc.List {
nextCond = fn.newBasicBlock("switch.next")
- // TODO(adonovan): opt: when tag==vTrue, we'd
- // get better code if we use b.cond(cond)
- // instead of BinOp(EQL, tag, b.expr(cond))
- // followed by If. Don't forget conversions
- // though.
- cond := emitCompare(fn, token.EQL, tag, b.expr(fn, cond), cond.Pos())
- emitIf(fn, cond, body, nextCond)
+ // For boolean switches, emit short-circuit control flow,
+ // just like an if/else-chain.
+ if tag == vTrue && !isNonTypeParamInterface(fn.info.Types[cond].Type) {
+ b.cond(fn, cond, body, nextCond)
+ } else {
+ c := emitCompare(fn, token.EQL, tag, b.expr(fn, cond), cond.Pos())
+ emitIf(fn, c, body, nextCond)
+ }
fn.currentBlock = nextCond
}
fn.currentBlock = body
diff --git a/gopls/internal/analysis/yield/testdata/src/a/a.go b/gopls/internal/analysis/yield/testdata/src/a/a.go
index 820cabd..15ee3f5 100644
--- a/gopls/internal/analysis/yield/testdata/src/a/a.go
+++ b/gopls/internal/analysis/yield/testdata/src/a/a.go
@@ -145,3 +145,21 @@
}
}
}
+
+// Regression test for issue #77681. A boolean switch is now
+// handled just like an if/else chain in the SSA builder.
+func switchShortCircuit(seq iter.Seq[int]) iter.Seq[int] {
+ return func(yield func(int) bool) {
+ for item := range seq {
+ isZero := item == 0
+ switch {
+ case !isZero && !yield(item): // ok
+ return
+ case !isZero:
+ continue
+ case !yield(0): // ok
+ return
+ }
+ }
+ }
+}

Change information

Files:
  • M go/ssa/builder.go
  • M gopls/internal/analysis/yield/testdata/src/a/a.go
Change size: S
Delta: 2 files changed, 26 insertions(+), 7 deletions(-)
Open in Gerrit

Related details

Attention set is empty
Submit Requirements:
  • requirement is not satisfiedCode-Review
  • requirement satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
  • requirement is not satisfiedTryBots-Pass
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: newchange
Gerrit-Project: tools
Gerrit-Branch: master
Gerrit-Change-Id: Ife9dee8443c0f2c09e95cacbfcefd5baacc97d99
Gerrit-Change-Number: 749580
Gerrit-PatchSet: 1
Gerrit-Owner: Alan Donovan <adon...@google.com>
Gerrit-Reviewer: Alan Donovan <adon...@google.com>
unsatisfied_requirement
satisfied_requirement
open
diffy

Alan Donovan (Gerrit)

unread,
Feb 26, 2026, 6:25:37 PM (21 hours ago) Feb 26
to goph...@pubsubhelper.golang.org, Robert Griesemer, Go LUCI, golang-co...@googlegroups.com
Attention needed from Robert Griesemer

Alan Donovan voted Auto-Submit+1

Auto-Submit+1
Open in Gerrit

Related details

Attention is currently required from:
  • Robert Griesemer
Submit Requirements:
  • requirement is not satisfiedCode-Review
  • requirement satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
  • requirement is not satisfiedTryBots-Pass
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: tools
Gerrit-Branch: master
Gerrit-Change-Id: Ife9dee8443c0f2c09e95cacbfcefd5baacc97d99
Gerrit-Change-Number: 749580
Gerrit-PatchSet: 1
Gerrit-Owner: Alan Donovan <adon...@google.com>
Gerrit-Reviewer: Alan Donovan <adon...@google.com>
Gerrit-Reviewer: Robert Griesemer <g...@google.com>
Gerrit-Attention: Robert Griesemer <g...@google.com>
Gerrit-Comment-Date: Thu, 26 Feb 2026 23:25:32 +0000
Gerrit-HasComments: No
Gerrit-Has-Labels: Yes
unsatisfied_requirement
satisfied_requirement
open
diffy

Alan Donovan (Gerrit)

unread,
10:01 AM (5 hours ago) 10:01 AM
to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com
Attention needed from Alan Donovan and Robert Griesemer

Alan Donovan uploaded new patchset

Alan Donovan uploaded patch set #2 to this change.
Open in Gerrit

Related details

Attention is currently required from:
  • Alan Donovan
  • Robert Griesemer
Submit Requirements:
    • requirement is not satisfiedCode-Review
    • requirement satisfiedNo-Unresolved-Comments
    • requirement is not satisfiedReview-Enforcement
    • requirement satisfiedTryBots-Pass
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: newpatchset
    Gerrit-Project: tools
    Gerrit-Branch: master
    Gerrit-Change-Id: Ife9dee8443c0f2c09e95cacbfcefd5baacc97d99
    Gerrit-Change-Number: 749580
    Gerrit-PatchSet: 2
    Gerrit-Owner: Alan Donovan <adon...@google.com>
    Gerrit-Reviewer: Alan Donovan <adon...@google.com>
    Gerrit-Reviewer: Robert Griesemer <g...@google.com>
    Gerrit-Attention: Robert Griesemer <g...@google.com>
    Gerrit-Attention: Alan Donovan <adon...@google.com>
    unsatisfied_requirement
    satisfied_requirement
    open
    diffy
    Reply all
    Reply to author
    Forward
    0 new messages