From 170a4722cb6320e1c01d7e8ab8ed951cd99730b7 Mon Sep 17 00:00:00 2001 From: Raezil Date: Sat, 5 Jul 2025 15:06:39 +0200 Subject: [PATCH 1/2] fix loopbce bug --- src/cmd/compile/internal/ssa/loopbce.go | 29 ++++++++++++++++--------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/src/cmd/compile/internal/ssa/loopbce.go b/src/cmd/compile/internal/ssa/loopbce.go index dd1f39dbef7439..c9783959b00217 100644 --- a/src/cmd/compile/internal/ssa/loopbce.go +++ b/src/cmd/compile/internal/ssa/loopbce.go @@ -169,18 +169,27 @@ func findIndVar(f *Func) []indVar { // Two conditions must happen listed below to accept ind // as an induction variable. - // First condition: loop entry has a single predecessor, which - // is the header block. This implies that b.Succs[0] is - // reached iff ind < limit. - if len(b.Succs[0].b.Preds) != 1 { - // b.Succs[1] must exit the loop. + // Identify which successor is the *loop entry* (where nxt is computed) + var entry, exit *Block + if sdom.IsAncestorEq(b.Succs[0].b, nxt.Block) { + entry = b.Succs[0].b + exit = b.Succs[1].b + } else if sdom.IsAncestorEq(b.Succs[1].b, nxt.Block) { + entry = b.Succs[1].b + exit = b.Succs[0].b + } else { + // Neither successor dominates nxt; shape is not a simple for-loop header. + continue + } + + // First condition: loop entry has exactly one predecessor (the header). + if len(entry.Preds) != 1 { continue } - // Second condition: b.Succs[0] dominates nxt so that - // nxt is computed when inc < limit. - if !sdom.IsAncestorEq(b.Succs[0].b, nxt.Block) { - // inc+ind can only be reached through the branch that enters the loop. + // Second condition: entry must dominate nxt so that nxt = ind+inc + // is only reachable when the loop is taken. + if !sdom.IsAncestorEq(entry, nxt.Block) { continue } @@ -298,7 +307,7 @@ func findIndVar(f *Func) []indVar { nxt: nxt, min: min, max: max, - entry: b.Succs[0].b, + entry: entry, flags: flags, }) b.Logf("found induction variable %v (inc = %v, min = %v, max = %v)\n", ind, inc, min, max) From 1bafe025464d282a3de3d504edcc90e8ca9f20b1 Mon Sep 17 00:00:00 2001 From: Raezil Date: Sat, 5 Jul 2025 15:37:29 +0200 Subject: [PATCH 2/2] update loopbce.go --- src/cmd/compile/internal/ssa/loopbce.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/cmd/compile/internal/ssa/loopbce.go b/src/cmd/compile/internal/ssa/loopbce.go index c9783959b00217..f7a693f17795c5 100644 --- a/src/cmd/compile/internal/ssa/loopbce.go +++ b/src/cmd/compile/internal/ssa/loopbce.go @@ -170,13 +170,11 @@ func findIndVar(f *Func) []indVar { // as an induction variable. // Identify which successor is the *loop entry* (where nxt is computed) - var entry, exit *Block + var entry *Block if sdom.IsAncestorEq(b.Succs[0].b, nxt.Block) { entry = b.Succs[0].b - exit = b.Succs[1].b } else if sdom.IsAncestorEq(b.Succs[1].b, nxt.Block) { entry = b.Succs[1].b - exit = b.Succs[0].b } else { // Neither successor dominates nxt; shape is not a simple for-loop header. continue