aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCherry Zhang <cherryyz@google.com>2018-10-02 22:04:45 -0400
committerBrad Fitzpatrick <bradfitz@golang.org>2018-10-03 18:08:44 +0000
commitaa0966105ea3c6fd338eb0e52d6e741702e79402 (patch)
tree279a379e5612440e2b9e4f1e05d3f27131d0a68d
parent19fe28a3dc91ffb6f3ec31211abb3bf7ae088fb6 (diff)
downloadgo-aa0966105ea3c6fd338eb0e52d6e741702e79402.tar.gz
go-aa0966105ea3c6fd338eb0e52d6e741702e79402.zip
[release-branch.go1.11] cmd/compile: fix type of OffPtr in some optimization rules
In some optimization rules the type of generated OffPtr was incorrectly set to the type of the pointee, instead of the pointer. When the OffPtr value is spilled, this may generate a spill of the wrong type, e.g. a floating point spill of an integer (pointer) value. On Wasm, this leads to invalid bytecode. Fixes #27961. Change-Id: I5d464847eb900ed90794105c0013a1a7330756cc Reviewed-on: https://go-review.googlesource.com/c/139257 Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Richard Musiol <neelance@gmail.com> (cherry picked from commit c96e3bcc97a965b3e2947cc1d8d831b8d39c1d73) Reviewed-on: https://go-review.googlesource.com/c/139104 Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com>
-rw-r--r--src/cmd/compile/internal/ssa/gen/generic.rules72
-rw-r--r--src/cmd/compile/internal/ssa/rewritegeneric.go78
-rw-r--r--test/fixedbugs/issue27961.go35
3 files changed, 119 insertions, 66 deletions
diff --git a/src/cmd/compile/internal/ssa/gen/generic.rules b/src/cmd/compile/internal/ssa/gen/generic.rules
index 0b68db7f04..0c397c6873 100644
--- a/src/cmd/compile/internal/ssa/gen/generic.rules
+++ b/src/cmd/compile/internal/ssa/gen/generic.rules
@@ -1539,8 +1539,8 @@
// Don't Move from memory if the values are likely to already be
// in registers.
(Move {t1} [n] dst p1
- mem:(Store {t2} op2:(OffPtr [o2] p2) d1
- (Store {t3} op3:(OffPtr [0] p3) d2 _)))
+ mem:(Store {t2} op2:(OffPtr <tt2> [o2] p2) d1
+ (Store {t3} op3:(OffPtr <tt3> [0] p3) d2 _)))
&& isSamePtr(p1, p2) && isSamePtr(p2, p3)
&& alignof(t2) <= alignof(t1)
&& alignof(t3) <= alignof(t1)
@@ -1548,12 +1548,12 @@
&& registerizable(b, t3)
&& o2 == sizeof(t3)
&& n == sizeof(t2) + sizeof(t3)
- -> (Store {t2} (OffPtr <t2.(*types.Type)> [o2] dst) d1
- (Store {t3} (OffPtr <t3.(*types.Type)> [0] dst) d2 mem))
+ -> (Store {t2} (OffPtr <tt2> [o2] dst) d1
+ (Store {t3} (OffPtr <tt3> [0] dst) d2 mem))
(Move {t1} [n] dst p1
- mem:(Store {t2} op2:(OffPtr [o2] p2) d1
- (Store {t3} op3:(OffPtr [o3] p3) d2
- (Store {t4} op4:(OffPtr [0] p4) d3 _))))
+ mem:(Store {t2} op2:(OffPtr <tt2> [o2] p2) d1
+ (Store {t3} op3:(OffPtr <tt3> [o3] p3) d2
+ (Store {t4} op4:(OffPtr <tt4> [0] p4) d3 _))))
&& isSamePtr(p1, p2) && isSamePtr(p2, p3) && isSamePtr(p3, p4)
&& alignof(t2) <= alignof(t1)
&& alignof(t3) <= alignof(t1)
@@ -1564,14 +1564,14 @@
&& o3 == sizeof(t4)
&& o2-o3 == sizeof(t3)
&& n == sizeof(t2) + sizeof(t3) + sizeof(t4)
- -> (Store {t2} (OffPtr <t2.(*types.Type)> [o2] dst) d1
- (Store {t3} (OffPtr <t3.(*types.Type)> [o3] dst) d2
- (Store {t4} (OffPtr <t4.(*types.Type)> [0] dst) d3 mem)))
+ -> (Store {t2} (OffPtr <tt2> [o2] dst) d1
+ (Store {t3} (OffPtr <tt3> [o3] dst) d2
+ (Store {t4} (OffPtr <tt4> [0] dst) d3 mem)))
(Move {t1} [n] dst p1
- mem:(Store {t2} op2:(OffPtr [o2] p2) d1
- (Store {t3} op3:(OffPtr [o3] p3) d2
- (Store {t4} op4:(OffPtr [o4] p4) d3
- (Store {t5} op5:(OffPtr [0] p5) d4 _)))))
+ mem:(Store {t2} op2:(OffPtr <tt2> [o2] p2) d1
+ (Store {t3} op3:(OffPtr <tt3> [o3] p3) d2
+ (Store {t4} op4:(OffPtr <tt4> [o4] p4) d3
+ (Store {t5} op5:(OffPtr <tt5> [0] p5) d4 _)))))
&& isSamePtr(p1, p2) && isSamePtr(p2, p3) && isSamePtr(p3, p4) && isSamePtr(p4, p5)
&& alignof(t2) <= alignof(t1)
&& alignof(t3) <= alignof(t1)
@@ -1585,16 +1585,16 @@
&& o3-o4 == sizeof(t4)
&& o2-o3 == sizeof(t3)
&& n == sizeof(t2) + sizeof(t3) + sizeof(t4) + sizeof(t5)
- -> (Store {t2} (OffPtr <t2.(*types.Type)> [o2] dst) d1
- (Store {t3} (OffPtr <t3.(*types.Type)> [o3] dst) d2
- (Store {t4} (OffPtr <t4.(*types.Type)> [o4] dst) d3
- (Store {t5} (OffPtr <t5.(*types.Type)> [0] dst) d4 mem))))
+ -> (Store {t2} (OffPtr <tt2> [o2] dst) d1
+ (Store {t3} (OffPtr <tt3> [o3] dst) d2
+ (Store {t4} (OffPtr <tt4> [o4] dst) d3
+ (Store {t5} (OffPtr <tt5> [0] dst) d4 mem))))
// Same thing but with VarDef in the middle.
(Move {t1} [n] dst p1
mem:(VarDef
- (Store {t2} op2:(OffPtr [o2] p2) d1
- (Store {t3} op3:(OffPtr [0] p3) d2 _))))
+ (Store {t2} op2:(OffPtr <tt2> [o2] p2) d1
+ (Store {t3} op3:(OffPtr <tt3> [0] p3) d2 _))))
&& isSamePtr(p1, p2) && isSamePtr(p2, p3)
&& alignof(t2) <= alignof(t1)
&& alignof(t3) <= alignof(t1)
@@ -1602,13 +1602,13 @@
&& registerizable(b, t3)
&& o2 == sizeof(t3)
&& n == sizeof(t2) + sizeof(t3)
- -> (Store {t2} (OffPtr <t2.(*types.Type)> [o2] dst) d1
- (Store {t3} (OffPtr <t3.(*types.Type)> [0] dst) d2 mem))
+ -> (Store {t2} (OffPtr <tt2> [o2] dst) d1
+ (Store {t3} (OffPtr <tt3> [0] dst) d2 mem))
(Move {t1} [n] dst p1
mem:(VarDef
- (Store {t2} op2:(OffPtr [o2] p2) d1
- (Store {t3} op3:(OffPtr [o3] p3) d2
- (Store {t4} op4:(OffPtr [0] p4) d3 _)))))
+ (Store {t2} op2:(OffPtr <tt2> [o2] p2) d1
+ (Store {t3} op3:(OffPtr <tt3> [o3] p3) d2
+ (Store {t4} op4:(OffPtr <tt4> [0] p4) d3 _)))))
&& isSamePtr(p1, p2) && isSamePtr(p2, p3) && isSamePtr(p3, p4)
&& alignof(t2) <= alignof(t1)
&& alignof(t3) <= alignof(t1)
@@ -1619,15 +1619,15 @@
&& o3 == sizeof(t4)
&& o2-o3 == sizeof(t3)
&& n == sizeof(t2) + sizeof(t3) + sizeof(t4)
- -> (Store {t2} (OffPtr <t2.(*types.Type)> [o2] dst) d1
- (Store {t3} (OffPtr <t3.(*types.Type)> [o3] dst) d2
- (Store {t4} (OffPtr <t4.(*types.Type)> [0] dst) d3 mem)))
+ -> (Store {t2} (OffPtr <tt2> [o2] dst) d1
+ (Store {t3} (OffPtr <tt3> [o3] dst) d2
+ (Store {t4} (OffPtr <tt4> [0] dst) d3 mem)))
(Move {t1} [n] dst p1
mem:(VarDef
- (Store {t2} op2:(OffPtr [o2] p2) d1
- (Store {t3} op3:(OffPtr [o3] p3) d2
- (Store {t4} op4:(OffPtr [o4] p4) d3
- (Store {t5} op5:(OffPtr [0] p5) d4 _))))))
+ (Store {t2} op2:(OffPtr <tt2> [o2] p2) d1
+ (Store {t3} op3:(OffPtr <tt3> [o3] p3) d2
+ (Store {t4} op4:(OffPtr <tt4> [o4] p4) d3
+ (Store {t5} op5:(OffPtr <tt5> [0] p5) d4 _))))))
&& isSamePtr(p1, p2) && isSamePtr(p2, p3) && isSamePtr(p3, p4) && isSamePtr(p4, p5)
&& alignof(t2) <= alignof(t1)
&& alignof(t3) <= alignof(t1)
@@ -1641,10 +1641,10 @@
&& o3-o4 == sizeof(t4)
&& o2-o3 == sizeof(t3)
&& n == sizeof(t2) + sizeof(t3) + sizeof(t4) + sizeof(t5)
- -> (Store {t2} (OffPtr <t2.(*types.Type)> [o2] dst) d1
- (Store {t3} (OffPtr <t3.(*types.Type)> [o3] dst) d2
- (Store {t4} (OffPtr <t4.(*types.Type)> [o4] dst) d3
- (Store {t5} (OffPtr <t5.(*types.Type)> [0] dst) d4 mem))))
+ -> (Store {t2} (OffPtr <tt2> [o2] dst) d1
+ (Store {t3} (OffPtr <tt3> [o3] dst) d2
+ (Store {t4} (OffPtr <tt4> [o4] dst) d3
+ (Store {t5} (OffPtr <tt5> [0] dst) d4 mem))))
// Prefer to Zero and Store than to Move.
(Move {t1} [n] dst p1
diff --git a/src/cmd/compile/internal/ssa/rewritegeneric.go b/src/cmd/compile/internal/ssa/rewritegeneric.go
index a1c83ea378..7936bdf129 100644
--- a/src/cmd/compile/internal/ssa/rewritegeneric.go
+++ b/src/cmd/compile/internal/ssa/rewritegeneric.go
@@ -16223,9 +16223,9 @@ func rewriteValuegeneric_OpMove_0(v *Value) bool {
v.AddArg(v0)
return true
}
- // match: (Move {t1} [n] dst p1 mem:(Store {t2} op2:(OffPtr [o2] p2) d1 (Store {t3} op3:(OffPtr [0] p3) d2 _)))
+ // match: (Move {t1} [n] dst p1 mem:(Store {t2} op2:(OffPtr <tt2> [o2] p2) d1 (Store {t3} op3:(OffPtr <tt3> [0] p3) d2 _)))
// cond: isSamePtr(p1, p2) && isSamePtr(p2, p3) && alignof(t2) <= alignof(t1) && alignof(t3) <= alignof(t1) && registerizable(b, t2) && registerizable(b, t3) && o2 == sizeof(t3) && n == sizeof(t2) + sizeof(t3)
- // result: (Store {t2} (OffPtr <t2.(*types.Type)> [o2] dst) d1 (Store {t3} (OffPtr <t3.(*types.Type)> [0] dst) d2 mem))
+ // result: (Store {t2} (OffPtr <tt2> [o2] dst) d1 (Store {t3} (OffPtr <tt3> [0] dst) d2 mem))
for {
n := v.AuxInt
t1 := v.Aux
@@ -16242,6 +16242,7 @@ func rewriteValuegeneric_OpMove_0(v *Value) bool {
if op2.Op != OpOffPtr {
break
}
+ tt2 := op2.Type
o2 := op2.AuxInt
p2 := op2.Args[0]
d1 := mem.Args[1]
@@ -16255,6 +16256,7 @@ func rewriteValuegeneric_OpMove_0(v *Value) bool {
if op3.Op != OpOffPtr {
break
}
+ tt3 := op3.Type
if op3.AuxInt != 0 {
break
}
@@ -16265,14 +16267,14 @@ func rewriteValuegeneric_OpMove_0(v *Value) bool {
}
v.reset(OpStore)
v.Aux = t2
- v0 := b.NewValue0(v.Pos, OpOffPtr, t2.(*types.Type))
+ v0 := b.NewValue0(v.Pos, OpOffPtr, tt2)
v0.AuxInt = o2
v0.AddArg(dst)
v.AddArg(v0)
v.AddArg(d1)
v1 := b.NewValue0(v.Pos, OpStore, types.TypeMem)
v1.Aux = t3
- v2 := b.NewValue0(v.Pos, OpOffPtr, t3.(*types.Type))
+ v2 := b.NewValue0(v.Pos, OpOffPtr, tt3)
v2.AuxInt = 0
v2.AddArg(dst)
v1.AddArg(v2)
@@ -16281,9 +16283,9 @@ func rewriteValuegeneric_OpMove_0(v *Value) bool {
v.AddArg(v1)
return true
}
- // match: (Move {t1} [n] dst p1 mem:(Store {t2} op2:(OffPtr [o2] p2) d1 (Store {t3} op3:(OffPtr [o3] p3) d2 (Store {t4} op4:(OffPtr [0] p4) d3 _))))
+ // match: (Move {t1} [n] dst p1 mem:(Store {t2} op2:(OffPtr <tt2> [o2] p2) d1 (Store {t3} op3:(OffPtr <tt3> [o3] p3) d2 (Store {t4} op4:(OffPtr <tt4> [0] p4) d3 _))))
// cond: isSamePtr(p1, p2) && isSamePtr(p2, p3) && isSamePtr(p3, p4) && alignof(t2) <= alignof(t1) && alignof(t3) <= alignof(t1) && alignof(t4) <= alignof(t1) && registerizable(b, t2) && registerizable(b, t3) && registerizable(b, t4) && o3 == sizeof(t4) && o2-o3 == sizeof(t3) && n == sizeof(t2) + sizeof(t3) + sizeof(t4)
- // result: (Store {t2} (OffPtr <t2.(*types.Type)> [o2] dst) d1 (Store {t3} (OffPtr <t3.(*types.Type)> [o3] dst) d2 (Store {t4} (OffPtr <t4.(*types.Type)> [0] dst) d3 mem)))
+ // result: (Store {t2} (OffPtr <tt2> [o2] dst) d1 (Store {t3} (OffPtr <tt3> [o3] dst) d2 (Store {t4} (OffPtr <tt4> [0] dst) d3 mem)))
for {
n := v.AuxInt
t1 := v.Aux
@@ -16300,6 +16302,7 @@ func rewriteValuegeneric_OpMove_0(v *Value) bool {
if op2.Op != OpOffPtr {
break
}
+ tt2 := op2.Type
o2 := op2.AuxInt
p2 := op2.Args[0]
d1 := mem.Args[1]
@@ -16313,6 +16316,7 @@ func rewriteValuegeneric_OpMove_0(v *Value) bool {
if op3.Op != OpOffPtr {
break
}
+ tt3 := op3.Type
o3 := op3.AuxInt
p3 := op3.Args[0]
d2 := mem_2.Args[1]
@@ -16326,6 +16330,7 @@ func rewriteValuegeneric_OpMove_0(v *Value) bool {
if op4.Op != OpOffPtr {
break
}
+ tt4 := op4.Type
if op4.AuxInt != 0 {
break
}
@@ -16336,21 +16341,21 @@ func rewriteValuegeneric_OpMove_0(v *Value) bool {
}
v.reset(OpStore)
v.Aux = t2
- v0 := b.NewValue0(v.Pos, OpOffPtr, t2.(*types.Type))
+ v0 := b.NewValue0(v.Pos, OpOffPtr, tt2)
v0.AuxInt = o2
v0.AddArg(dst)
v.AddArg(v0)
v.AddArg(d1)
v1 := b.NewValue0(v.Pos, OpStore, types.TypeMem)
v1.Aux = t3
- v2 := b.NewValue0(v.Pos, OpOffPtr, t3.(*types.Type))
+ v2 := b.NewValue0(v.Pos, OpOffPtr, tt3)
v2.AuxInt = o3
v2.AddArg(dst)
v1.AddArg(v2)
v1.AddArg(d2)
v3 := b.NewValue0(v.Pos, OpStore, types.TypeMem)
v3.Aux = t4
- v4 := b.NewValue0(v.Pos, OpOffPtr, t4.(*types.Type))
+ v4 := b.NewValue0(v.Pos, OpOffPtr, tt4)
v4.AuxInt = 0
v4.AddArg(dst)
v3.AddArg(v4)
@@ -16360,9 +16365,9 @@ func rewriteValuegeneric_OpMove_0(v *Value) bool {
v.AddArg(v1)
return true
}
- // match: (Move {t1} [n] dst p1 mem:(Store {t2} op2:(OffPtr [o2] p2) d1 (Store {t3} op3:(OffPtr [o3] p3) d2 (Store {t4} op4:(OffPtr [o4] p4) d3 (Store {t5} op5:(OffPtr [0] p5) d4 _)))))
+ // match: (Move {t1} [n] dst p1 mem:(Store {t2} op2:(OffPtr <tt2> [o2] p2) d1 (Store {t3} op3:(OffPtr <tt3> [o3] p3) d2 (Store {t4} op4:(OffPtr <tt4> [o4] p4) d3 (Store {t5} op5:(OffPtr <tt5> [0] p5) d4 _)))))
// cond: isSamePtr(p1, p2) && isSamePtr(p2, p3) && isSamePtr(p3, p4) && isSamePtr(p4, p5) && alignof(t2) <= alignof(t1) && alignof(t3) <= alignof(t1) && alignof(t4) <= alignof(t1) && alignof(t5) <= alignof(t1) && registerizable(b, t2) && registerizable(b, t3) && registerizable(b, t4) && registerizable(b, t5) && o4 == sizeof(t5) && o3-o4 == sizeof(t4) && o2-o3 == sizeof(t3) && n == sizeof(t2) + sizeof(t3) + sizeof(t4) + sizeof(t5)
- // result: (Store {t2} (OffPtr <t2.(*types.Type)> [o2] dst) d1 (Store {t3} (OffPtr <t3.(*types.Type)> [o3] dst) d2 (Store {t4} (OffPtr <t4.(*types.Type)> [o4] dst) d3 (Store {t5} (OffPtr <t5.(*types.Type)> [0] dst) d4 mem))))
+ // result: (Store {t2} (OffPtr <tt2> [o2] dst) d1 (Store {t3} (OffPtr <tt3> [o3] dst) d2 (Store {t4} (OffPtr <tt4> [o4] dst) d3 (Store {t5} (OffPtr <tt5> [0] dst) d4 mem))))
for {
n := v.AuxInt
t1 := v.Aux
@@ -16379,6 +16384,7 @@ func rewriteValuegeneric_OpMove_0(v *Value) bool {
if op2.Op != OpOffPtr {
break
}
+ tt2 := op2.Type
o2 := op2.AuxInt
p2 := op2.Args[0]
d1 := mem.Args[1]
@@ -16392,6 +16398,7 @@ func rewriteValuegeneric_OpMove_0(v *Value) bool {
if op3.Op != OpOffPtr {
break
}
+ tt3 := op3.Type
o3 := op3.AuxInt
p3 := op3.Args[0]
d2 := mem_2.Args[1]
@@ -16405,6 +16412,7 @@ func rewriteValuegeneric_OpMove_0(v *Value) bool {
if op4.Op != OpOffPtr {
break
}
+ tt4 := op4.Type
o4 := op4.AuxInt
p4 := op4.Args[0]
d3 := mem_2_2.Args[1]
@@ -16418,6 +16426,7 @@ func rewriteValuegeneric_OpMove_0(v *Value) bool {
if op5.Op != OpOffPtr {
break
}
+ tt5 := op5.Type
if op5.AuxInt != 0 {
break
}
@@ -16428,28 +16437,28 @@ func rewriteValuegeneric_OpMove_0(v *Value) bool {
}
v.reset(OpStore)
v.Aux = t2
- v0 := b.NewValue0(v.Pos, OpOffPtr, t2.(*types.Type))
+ v0 := b.NewValue0(v.Pos, OpOffPtr, tt2)
v0.AuxInt = o2
v0.AddArg(dst)
v.AddArg(v0)
v.AddArg(d1)
v1 := b.NewValue0(v.Pos, OpStore, types.TypeMem)
v1.Aux = t3
- v2 := b.NewValue0(v.Pos, OpOffPtr, t3.(*types.Type))
+ v2 := b.NewValue0(v.Pos, OpOffPtr, tt3)
v2.AuxInt = o3
v2.AddArg(dst)
v1.AddArg(v2)
v1.AddArg(d2)
v3 := b.NewValue0(v.Pos, OpStore, types.TypeMem)
v3.Aux = t4
- v4 := b.NewValue0(v.Pos, OpOffPtr, t4.(*types.Type))
+ v4 := b.NewValue0(v.Pos, OpOffPtr, tt4)
v4.AuxInt = o4
v4.AddArg(dst)
v3.AddArg(v4)
v3.AddArg(d3)
v5 := b.NewValue0(v.Pos, OpStore, types.TypeMem)
v5.Aux = t5
- v6 := b.NewValue0(v.Pos, OpOffPtr, t5.(*types.Type))
+ v6 := b.NewValue0(v.Pos, OpOffPtr, tt5)
v6.AuxInt = 0
v6.AddArg(dst)
v5.AddArg(v6)
@@ -16465,9 +16474,9 @@ func rewriteValuegeneric_OpMove_0(v *Value) bool {
func rewriteValuegeneric_OpMove_10(v *Value) bool {
b := v.Block
_ = b
- // match: (Move {t1} [n] dst p1 mem:(VarDef (Store {t2} op2:(OffPtr [o2] p2) d1 (Store {t3} op3:(OffPtr [0] p3) d2 _))))
+ // match: (Move {t1} [n] dst p1 mem:(VarDef (Store {t2} op2:(OffPtr <tt2> [o2] p2) d1 (Store {t3} op3:(OffPtr <tt3> [0] p3) d2 _))))
// cond: isSamePtr(p1, p2) && isSamePtr(p2, p3) && alignof(t2) <= alignof(t1) && alignof(t3) <= alignof(t1) && registerizable(b, t2) && registerizable(b, t3) && o2 == sizeof(t3) && n == sizeof(t2) + sizeof(t3)
- // result: (Store {t2} (OffPtr <t2.(*types.Type)> [o2] dst) d1 (Store {t3} (OffPtr <t3.(*types.Type)> [0] dst) d2 mem))
+ // result: (Store {t2} (OffPtr <tt2> [o2] dst) d1 (Store {t3} (OffPtr <tt3> [0] dst) d2 mem))
for {
n := v.AuxInt
t1 := v.Aux
@@ -16488,6 +16497,7 @@ func rewriteValuegeneric_OpMove_10(v *Value) bool {
if op2.Op != OpOffPtr {
break
}
+ tt2 := op2.Type
o2 := op2.AuxInt
p2 := op2.Args[0]
d1 := mem_0.Args[1]
@@ -16501,6 +16511,7 @@ func rewriteValuegeneric_OpMove_10(v *Value) bool {
if op3.Op != OpOffPtr {
break
}
+ tt3 := op3.Type
if op3.AuxInt != 0 {
break
}
@@ -16511,14 +16522,14 @@ func rewriteValuegeneric_OpMove_10(v *Value) bool {
}
v.reset(OpStore)
v.Aux = t2
- v0 := b.NewValue0(v.Pos, OpOffPtr, t2.(*types.Type))
+ v0 := b.NewValue0(v.Pos, OpOffPtr, tt2)
v0.AuxInt = o2
v0.AddArg(dst)
v.AddArg(v0)
v.AddArg(d1)
v1 := b.NewValue0(v.Pos, OpStore, types.TypeMem)
v1.Aux = t3
- v2 := b.NewValue0(v.Pos, OpOffPtr, t3.(*types.Type))
+ v2 := b.NewValue0(v.Pos, OpOffPtr, tt3)
v2.AuxInt = 0
v2.AddArg(dst)
v1.AddArg(v2)
@@ -16527,9 +16538,9 @@ func rewriteValuegeneric_OpMove_10(v *Value) bool {
v.AddArg(v1)
return true
}
- // match: (Move {t1} [n] dst p1 mem:(VarDef (Store {t2} op2:(OffPtr [o2] p2) d1 (Store {t3} op3:(OffPtr [o3] p3) d2 (Store {t4} op4:(OffPtr [0] p4) d3 _)))))
+ // match: (Move {t1} [n] dst p1 mem:(VarDef (Store {t2} op2:(OffPtr <tt2> [o2] p2) d1 (Store {t3} op3:(OffPtr <tt3> [o3] p3) d2 (Store {t4} op4:(OffPtr <tt4> [0] p4) d3 _)))))
// cond: isSamePtr(p1, p2) && isSamePtr(p2, p3) && isSamePtr(p3, p4) && alignof(t2) <= alignof(t1) && alignof(t3) <= alignof(t1) && alignof(t4) <= alignof(t1) && registerizable(b, t2) && registerizable(b, t3) && registerizable(b, t4) && o3 == sizeof(t4) && o2-o3 == sizeof(t3) && n == sizeof(t2) + sizeof(t3) + sizeof(t4)
- // result: (Store {t2} (OffPtr <t2.(*types.Type)> [o2] dst) d1 (Store {t3} (OffPtr <t3.(*types.Type)> [o3] dst) d2 (Store {t4} (OffPtr <t4.(*types.Type)> [0] dst) d3 mem)))
+ // result: (Store {t2} (OffPtr <tt2> [o2] dst) d1 (Store {t3} (OffPtr <tt3> [o3] dst) d2 (Store {t4} (OffPtr <tt4> [0] dst) d3 mem)))
for {
n := v.AuxInt
t1 := v.Aux
@@ -16550,6 +16561,7 @@ func rewriteValuegeneric_OpMove_10(v *Value) bool {
if op2.Op != OpOffPtr {
break
}
+ tt2 := op2.Type
o2 := op2.AuxInt
p2 := op2.Args[0]
d1 := mem_0.Args[1]
@@ -16563,6 +16575,7 @@ func rewriteValuegeneric_OpMove_10(v *Value) bool {
if op3.Op != OpOffPtr {
break
}
+ tt3 := op3.Type
o3 := op3.AuxInt
p3 := op3.Args[0]
d2 := mem_0_2.Args[1]
@@ -16576,6 +16589,7 @@ func rewriteValuegeneric_OpMove_10(v *Value) bool {
if op4.Op != OpOffPtr {
break
}
+ tt4 := op4.Type
if op4.AuxInt != 0 {
break
}
@@ -16586,21 +16600,21 @@ func rewriteValuegeneric_OpMove_10(v *Value) bool {
}
v.reset(OpStore)
v.Aux = t2
- v0 := b.NewValue0(v.Pos, OpOffPtr, t2.(*types.Type))
+ v0 := b.NewValue0(v.Pos, OpOffPtr, tt2)
v0.AuxInt = o2
v0.AddArg(dst)
v.AddArg(v0)
v.AddArg(d1)
v1 := b.NewValue0(v.Pos, OpStore, types.TypeMem)
v1.Aux = t3
- v2 := b.NewValue0(v.Pos, OpOffPtr, t3.(*types.Type))
+ v2 := b.NewValue0(v.Pos, OpOffPtr, tt3)
v2.AuxInt = o3
v2.AddArg(dst)
v1.AddArg(v2)
v1.AddArg(d2)
v3 := b.NewValue0(v.Pos, OpStore, types.TypeMem)
v3.Aux = t4
- v4 := b.NewValue0(v.Pos, OpOffPtr, t4.(*types.Type))
+ v4 := b.NewValue0(v.Pos, OpOffPtr, tt4)
v4.AuxInt = 0
v4.AddArg(dst)
v3.AddArg(v4)
@@ -16610,9 +16624,9 @@ func rewriteValuegeneric_OpMove_10(v *Value) bool {
v.AddArg(v1)
return true
}
- // match: (Move {t1} [n] dst p1 mem:(VarDef (Store {t2} op2:(OffPtr [o2] p2) d1 (Store {t3} op3:(OffPtr [o3] p3) d2 (Store {t4} op4:(OffPtr [o4] p4) d3 (Store {t5} op5:(OffPtr [0] p5) d4 _))))))
+ // match: (Move {t1} [n] dst p1 mem:(VarDef (Store {t2} op2:(OffPtr <tt2> [o2] p2) d1 (Store {t3} op3:(OffPtr <tt3> [o3] p3) d2 (Store {t4} op4:(OffPtr <tt4> [o4] p4) d3 (Store {t5} op5:(OffPtr <tt5> [0] p5) d4 _))))))
// cond: isSamePtr(p1, p2) && isSamePtr(p2, p3) && isSamePtr(p3, p4) && isSamePtr(p4, p5) && alignof(t2) <= alignof(t1) && alignof(t3) <= alignof(t1) && alignof(t4) <= alignof(t1) && alignof(t5) <= alignof(t1) && registerizable(b, t2) && registerizable(b, t3) && registerizable(b, t4) && registerizable(b, t5) && o4 == sizeof(t5) && o3-o4 == sizeof(t4) && o2-o3 == sizeof(t3) && n == sizeof(t2) + sizeof(t3) + sizeof(t4) + sizeof(t5)
- // result: (Store {t2} (OffPtr <t2.(*types.Type)> [o2] dst) d1 (Store {t3} (OffPtr <t3.(*types.Type)> [o3] dst) d2 (Store {t4} (OffPtr <t4.(*types.Type)> [o4] dst) d3 (Store {t5} (OffPtr <t5.(*types.Type)> [0] dst) d4 mem))))
+ // result: (Store {t2} (OffPtr <tt2> [o2] dst) d1 (Store {t3} (OffPtr <tt3> [o3] dst) d2 (Store {t4} (OffPtr <tt4> [o4] dst) d3 (Store {t5} (OffPtr <tt5> [0] dst) d4 mem))))
for {
n := v.AuxInt
t1 := v.Aux
@@ -16633,6 +16647,7 @@ func rewriteValuegeneric_OpMove_10(v *Value) bool {
if op2.Op != OpOffPtr {
break
}
+ tt2 := op2.Type
o2 := op2.AuxInt
p2 := op2.Args[0]
d1 := mem_0.Args[1]
@@ -16646,6 +16661,7 @@ func rewriteValuegeneric_OpMove_10(v *Value) bool {
if op3.Op != OpOffPtr {
break
}
+ tt3 := op3.Type
o3 := op3.AuxInt
p3 := op3.Args[0]
d2 := mem_0_2.Args[1]
@@ -16659,6 +16675,7 @@ func rewriteValuegeneric_OpMove_10(v *Value) bool {
if op4.Op != OpOffPtr {
break
}
+ tt4 := op4.Type
o4 := op4.AuxInt
p4 := op4.Args[0]
d3 := mem_0_2_2.Args[1]
@@ -16672,6 +16689,7 @@ func rewriteValuegeneric_OpMove_10(v *Value) bool {
if op5.Op != OpOffPtr {
break
}
+ tt5 := op5.Type
if op5.AuxInt != 0 {
break
}
@@ -16682,28 +16700,28 @@ func rewriteValuegeneric_OpMove_10(v *Value) bool {
}
v.reset(OpStore)
v.Aux = t2
- v0 := b.NewValue0(v.Pos, OpOffPtr, t2.(*types.Type))
+ v0 := b.NewValue0(v.Pos, OpOffPtr, tt2)
v0.AuxInt = o2
v0.AddArg(dst)
v.AddArg(v0)
v.AddArg(d1)
v1 := b.NewValue0(v.Pos, OpStore, types.TypeMem)
v1.Aux = t3
- v2 := b.NewValue0(v.Pos, OpOffPtr, t3.(*types.Type))
+ v2 := b.NewValue0(v.Pos, OpOffPtr, tt3)
v2.AuxInt = o3
v2.AddArg(dst)
v1.AddArg(v2)
v1.AddArg(d2)
v3 := b.NewValue0(v.Pos, OpStore, types.TypeMem)
v3.Aux = t4
- v4 := b.NewValue0(v.Pos, OpOffPtr, t4.(*types.Type))
+ v4 := b.NewValue0(v.Pos, OpOffPtr, tt4)
v4.AuxInt = o4
v4.AddArg(dst)
v3.AddArg(v4)
v3.AddArg(d3)
v5 := b.NewValue0(v.Pos, OpStore, types.TypeMem)
v5.Aux = t5
- v6 := b.NewValue0(v.Pos, OpOffPtr, t5.(*types.Type))
+ v6 := b.NewValue0(v.Pos, OpOffPtr, tt5)
v6.AuxInt = 0
v6.AddArg(dst)
v5.AddArg(v6)
diff --git a/test/fixedbugs/issue27961.go b/test/fixedbugs/issue27961.go
new file mode 100644
index 0000000000..f8b4f669c4
--- /dev/null
+++ b/test/fixedbugs/issue27961.go
@@ -0,0 +1,35 @@
+// run
+
+// Copyright 2018 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.
+
+// Issue 27961: some optimizations generate OffPtr with wrong
+// types, which causes invalid bytecode on Wasm.
+
+package main
+
+import "math"
+
+type Vec2 [2]float64
+
+func main() {
+ var a Vec2
+ a.A().B().C().D()
+}
+
+func (v Vec2) A() Vec2 {
+ return Vec2{v[0], v[0]}
+}
+
+func (v Vec2) B() Vec2 {
+ return Vec2{1.0 / v.D(), 0}
+}
+
+func (v Vec2) C() Vec2 {
+ return Vec2{v[0], v[0]}
+}
+
+func (v Vec2) D() float64 {
+ return math.Sqrt(v[0])
+}