From 2308c9c95eb2bb87ed3979961d3433e8428f8912 Mon Sep 17 00:00:00 2001 From: Keith Randall Date: Mon, 13 Nov 2017 10:48:52 -0800 Subject: [release-branch.go1.9] cmd/compile: fix decomposition of 1-element arrays The offending rule could move the load to a different block, which is always a bad idea. Fixes #22683 Change-Id: I973c88389b2359f734924d9f45c3fb38e166691d Reviewed-on: https://go-review.googlesource.com/77331 Run-TryBot: Andrew Bonventre Reviewed-by: Keith Randall Reviewed-by: David Chase --- src/cmd/compile/internal/ssa/gen/generic.rules | 2 +- src/cmd/compile/internal/ssa/rewritegeneric.go | 25 ++++++++++++--------- test/fixedbugs/issue22683.go | 30 ++++++++++++++++++++++++++ test/fixedbugs/issue22683.out | 1 + 4 files changed, 47 insertions(+), 11 deletions(-) create mode 100644 test/fixedbugs/issue22683.go create mode 100644 test/fixedbugs/issue22683.out diff --git a/src/cmd/compile/internal/ssa/gen/generic.rules b/src/cmd/compile/internal/ssa/gen/generic.rules index 944a84df85..10e49fc4f7 100644 --- a/src/cmd/compile/internal/ssa/gen/generic.rules +++ b/src/cmd/compile/internal/ssa/gen/generic.rules @@ -819,7 +819,7 @@ (Store _ (ArrayMake0) mem) -> mem (Store dst (ArrayMake1 e) mem) -> (Store {e.Type} dst e mem) -(ArraySelect [0] (Load ptr mem)) -> (Load ptr mem) +(ArraySelect [0] x:(Load ptr mem)) -> @x.Block (Load ptr mem) // Putting [1]{*byte} and similar into direct interfaces. (IMake typ (ArrayMake1 val)) -> (IMake typ val) diff --git a/src/cmd/compile/internal/ssa/rewritegeneric.go b/src/cmd/compile/internal/ssa/rewritegeneric.go index c67e4f90eb..fddfebdf42 100644 --- a/src/cmd/compile/internal/ssa/rewritegeneric.go +++ b/src/cmd/compile/internal/ssa/rewritegeneric.go @@ -5670,6 +5670,8 @@ func rewriteValuegeneric_OpArg_10(v *Value) bool { return false } func rewriteValuegeneric_OpArraySelect_0(v *Value) bool { + b := v.Block + _ = b // match: (ArraySelect (ArrayMake1 x)) // cond: // result: x @@ -5684,23 +5686,26 @@ func rewriteValuegeneric_OpArraySelect_0(v *Value) bool { v.AddArg(x) return true } - // match: (ArraySelect [0] (Load ptr mem)) + // match: (ArraySelect [0] x:(Load ptr mem)) // cond: - // result: (Load ptr mem) + // result: @x.Block (Load ptr mem) for { if v.AuxInt != 0 { break } - v_0 := v.Args[0] - if v_0.Op != OpLoad { + x := v.Args[0] + if x.Op != OpLoad { break } - _ = v_0.Args[1] - ptr := v_0.Args[0] - mem := v_0.Args[1] - v.reset(OpLoad) - v.AddArg(ptr) - v.AddArg(mem) + _ = x.Args[1] + ptr := x.Args[0] + mem := x.Args[1] + b = x.Block + v0 := b.NewValue0(v.Pos, OpLoad, v.Type) + v.reset(OpCopy) + v.AddArg(v0) + v0.AddArg(ptr) + v0.AddArg(mem) return true } // match: (ArraySelect [0] x:(IData _)) diff --git a/test/fixedbugs/issue22683.go b/test/fixedbugs/issue22683.go new file mode 100644 index 0000000000..a59a0edaf4 --- /dev/null +++ b/test/fixedbugs/issue22683.go @@ -0,0 +1,30 @@ +// cmpout + +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "fmt" +) + +type foo struct { + bar [1]*int +} + +func main() { + ch := make(chan foo, 2) + var a int + var b [1]*int + b[0] = &a + ch <- foo{bar: b} + close(ch) + + for v := range ch { + for i := 0; i < 1; i++ { + fmt.Println(v.bar[0] != nil) + } + } +} diff --git a/test/fixedbugs/issue22683.out b/test/fixedbugs/issue22683.out new file mode 100644 index 0000000000..27ba77ddaf --- /dev/null +++ b/test/fixedbugs/issue22683.out @@ -0,0 +1 @@ +true -- cgit v1.2.3-54-g00ecf