aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Dempsky <mdempsky@google.com>2023-06-27 16:51:24 -0700
committerCarlos Amedee <carlos@golang.org>2023-06-28 16:07:47 +0000
commit79d4defa75a26dd975c6ba3ac938e0e414dfd3e9 (patch)
treeb2a88c1dab06df2cef15a7341eb11740756fd8c7
parenta3093eca64f9efc830c153c835291d751ea167f9 (diff)
downloadgo-79d4defa75a26dd975c6ba3ac938e0e414dfd3e9.tar.gz
go-79d4defa75a26dd975c6ba3ac938e0e414dfd3e9.zip
cmd/compile/internal/ssagen: fix min/max codegen, again
The large-function phi placement algorithm evidently doesn't like the same pseudo-variable being used to represent expressions of varying types. Instead, use the same tactic as used for "valVar" (ssa.go:6585--6587), which is to just generate a fresh marker node each time. Maybe we could just use the OMIN/OMAX nodes themselves as the key (like we do for OANDAND/OOROR), but that just seems needlessly risky for negligible memory savings. Using fresh marker values each time seems obviously safe by comparison. Fixes #61041. Change-Id: Ie2600c9c37b599c2e26ae01f5f8a433025d7fd08 Reviewed-on: https://go-review.googlesource.com/c/go/+/506679 TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
-rw-r--r--src/cmd/compile/internal/ssagen/ssa.go5
-rw-r--r--test/fixedbugs/issue60982.go7
2 files changed, 10 insertions, 2 deletions
diff --git a/src/cmd/compile/internal/ssagen/ssa.go b/src/cmd/compile/internal/ssagen/ssa.go
index 4aedf9cd35..678e1ebc11 100644
--- a/src/cmd/compile/internal/ssagen/ssa.go
+++ b/src/cmd/compile/internal/ssagen/ssa.go
@@ -949,7 +949,6 @@ var (
typVar = ssaMarker("typ")
okVar = ssaMarker("ok")
deferBitsVar = ssaMarker("deferBits")
- ternaryVar = ssaMarker("ternary")
)
// startBlock sets the current block we're generating code in to b.
@@ -3621,6 +3620,10 @@ func (s *state) minMax(n *ir.CallExpr) *ssa.Value {
// ternary emits code to evaluate cond ? x : y.
func (s *state) ternary(cond, x, y *ssa.Value) *ssa.Value {
+ // Note that we need a new ternaryVar each time (unlike okVar where we can
+ // reuse the variable) because it might have a different type every time.
+ ternaryVar := ssaMarker("ternary")
+
bThen := s.f.NewBlock(ssa.BlockPlain)
bElse := s.f.NewBlock(ssa.BlockPlain)
bEnd := s.f.NewBlock(ssa.BlockPlain)
diff --git a/test/fixedbugs/issue60982.go b/test/fixedbugs/issue60982.go
index 11c3af214f..4e5fc34646 100644
--- a/test/fixedbugs/issue60982.go
+++ b/test/fixedbugs/issue60982.go
@@ -6,8 +6,13 @@
package main
-func f(x int) int {
+func f(x int, b bool) int {
if x >= 1000 {
+ if b { // from #61041
+ var a struct{ f int64 }
+ _ = max(0, a.f)
+ }
+
return max(x, 2000)
}
// generate 1000 basic blocks to put this function