mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
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>
This commit is contained in:
parent
54f5a6674a
commit
c96e3bcc97
4 changed files with 120 additions and 67 deletions
|
|
@ -1545,8 +1545,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)
|
||||
|
|
@ -1554,12 +1554,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)
|
||||
|
|
@ -1570,14 +1570,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)
|
||||
|
|
@ -1591,16 +1591,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)
|
||||
|
|
@ -1608,13 +1608,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)
|
||||
|
|
@ -1625,15 +1625,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)
|
||||
|
|
@ -1647,10 +1647,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
|
||||
|
|
|
|||
|
|
@ -42647,4 +42647,4 @@ func rewriteBlockARM64(b *Block) bool {
|
|||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16151,9 +16151,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
|
||||
|
|
@ -16170,6 +16170,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]
|
||||
|
|
@ -16183,6 +16184,7 @@ func rewriteValuegeneric_OpMove_0(v *Value) bool {
|
|||
if op3.Op != OpOffPtr {
|
||||
break
|
||||
}
|
||||
tt3 := op3.Type
|
||||
if op3.AuxInt != 0 {
|
||||
break
|
||||
}
|
||||
|
|
@ -16193,14 +16195,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)
|
||||
|
|
@ -16209,9 +16211,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
|
||||
|
|
@ -16228,6 +16230,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]
|
||||
|
|
@ -16241,6 +16244,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]
|
||||
|
|
@ -16254,6 +16258,7 @@ func rewriteValuegeneric_OpMove_0(v *Value) bool {
|
|||
if op4.Op != OpOffPtr {
|
||||
break
|
||||
}
|
||||
tt4 := op4.Type
|
||||
if op4.AuxInt != 0 {
|
||||
break
|
||||
}
|
||||
|
|
@ -16264,21 +16269,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)
|
||||
|
|
@ -16288,9 +16293,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
|
||||
|
|
@ -16307,6 +16312,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]
|
||||
|
|
@ -16320,6 +16326,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]
|
||||
|
|
@ -16333,6 +16340,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]
|
||||
|
|
@ -16346,6 +16354,7 @@ func rewriteValuegeneric_OpMove_0(v *Value) bool {
|
|||
if op5.Op != OpOffPtr {
|
||||
break
|
||||
}
|
||||
tt5 := op5.Type
|
||||
if op5.AuxInt != 0 {
|
||||
break
|
||||
}
|
||||
|
|
@ -16356,28 +16365,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)
|
||||
|
|
@ -16393,9 +16402,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
|
||||
|
|
@ -16416,6 +16425,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]
|
||||
|
|
@ -16429,6 +16439,7 @@ func rewriteValuegeneric_OpMove_10(v *Value) bool {
|
|||
if op3.Op != OpOffPtr {
|
||||
break
|
||||
}
|
||||
tt3 := op3.Type
|
||||
if op3.AuxInt != 0 {
|
||||
break
|
||||
}
|
||||
|
|
@ -16439,14 +16450,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)
|
||||
|
|
@ -16455,9 +16466,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
|
||||
|
|
@ -16478,6 +16489,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]
|
||||
|
|
@ -16491,6 +16503,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]
|
||||
|
|
@ -16504,6 +16517,7 @@ func rewriteValuegeneric_OpMove_10(v *Value) bool {
|
|||
if op4.Op != OpOffPtr {
|
||||
break
|
||||
}
|
||||
tt4 := op4.Type
|
||||
if op4.AuxInt != 0 {
|
||||
break
|
||||
}
|
||||
|
|
@ -16514,21 +16528,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)
|
||||
|
|
@ -16538,9 +16552,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
|
||||
|
|
@ -16561,6 +16575,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]
|
||||
|
|
@ -16574,6 +16589,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]
|
||||
|
|
@ -16587,6 +16603,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]
|
||||
|
|
@ -16600,6 +16617,7 @@ func rewriteValuegeneric_OpMove_10(v *Value) bool {
|
|||
if op5.Op != OpOffPtr {
|
||||
break
|
||||
}
|
||||
tt5 := op5.Type
|
||||
if op5.AuxInt != 0 {
|
||||
break
|
||||
}
|
||||
|
|
@ -16610,28 +16628,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)
|
||||
|
|
|
|||
35
test/fixedbugs/issue27961.go
Normal file
35
test/fixedbugs/issue27961.go
Normal file
|
|
@ -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])
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue