]> Cypherpunks repositories - gostls13.git/commitdiff
[release-branch.go1.9] cmd/compile: fix decomposition of 1-element arrays
authorKeith Randall <khr@golang.org>
Mon, 13 Nov 2017 18:48:52 +0000 (10:48 -0800)
committerAndrew Bonventre <andybons@golang.org>
Mon, 22 Jan 2018 20:25:08 +0000 (20:25 +0000)
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 <andybons@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: David Chase <drchase@google.com>
src/cmd/compile/internal/ssa/gen/generic.rules
src/cmd/compile/internal/ssa/rewritegeneric.go
test/fixedbugs/issue22683.go [new file with mode: 0644]
test/fixedbugs/issue22683.out [new file with mode: 0644]

index 944a84df85206adf7dd89bb58ea7ce54ecf75569..10e49fc4f7bac23473b00975a9e36c25d92bb929 100644 (file)
 (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 <v.Type> ptr mem)
 
 // Putting [1]{*byte} and similar into direct interfaces.
 (IMake typ (ArrayMake1 val)) -> (IMake typ val)
index c67e4f90eb150d0a2674a1db86217c7e565e0bc3..fddfebdf42abba3180491d89d3247a2fa4e0913e 100644 (file)
@@ -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 <v.Type> 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 (file)
index 0000000..a59a0ed
--- /dev/null
@@ -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 (file)
index 0000000..27ba77d
--- /dev/null
@@ -0,0 +1 @@
+true