Commit c96e3bcc authored by Cherry Zhang's avatar Cherry Zhang

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: default avatarKeith Randall <khr@golang.org>
Reviewed-by: default avatarRichard Musiol <neelance@gmail.com>
parent 54f5a667
......@@ -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
}
\ No newline at end of file
}
// 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])
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment