Commit 8aa57f1e authored by Richard Musiol's avatar Richard Musiol Committed by Cherry Zhang

cmd/compile: fix write barrier control value on wasm

This commit fixes a regression with wasm caused by a367f44c.
It adds optimizations to the lowering rules of wasm to ensure
that the lowered version of the code generated for write barriers
is simple enough so it can be processed by Liveness.markUnsafePoints.

Change-Id: Ic98f0dd3791fe1df23dcb34d2457fbde7ffce441
Reviewed-on: https://go-review.googlesource.com/114375
Run-TryBot: Cherry Zhang <cherryyz@google.com>
Reviewed-by: 's avatarCherry Zhang <cherryyz@google.com>
parent c730a93f
......@@ -729,7 +729,7 @@ func (lv *Liveness) markUnsafePoints() {
v = v.Args[0]
continue
}
case ssa.Op386MOVLload, ssa.OpARM64MOVWUload, ssa.OpPPC64MOVWZload:
case ssa.Op386MOVLload, ssa.OpARM64MOVWUload, ssa.OpPPC64MOVWZload, ssa.OpWasmI64Load32U:
// Args[0] is the address of the write
// barrier control. Ignore Args[1],
// which is the mem operand.
......
......@@ -50,10 +50,16 @@
(OffPtr [off] ptr) && off > 0 -> (I64AddConst [off] ptr)
// Lowering extension
// It is unnecessary to extend loads
(SignExt32to64 x:(I64Load32S _ _)) -> x
(SignExt16to(64|32) x:(I64Load16S _ _)) -> x
(SignExt8to(64|32|16) x:(I64Load8S _ _)) -> x
(ZeroExt32to64 x:(I64Load32U _ _)) -> x
(ZeroExt16to(64|32) x:(I64Load16U _ _)) -> x
(ZeroExt8to(64|32|16) x:(I64Load8U _ _)) -> x
(SignExt32to64 x) -> (I64ShrS (I64Shl x (I64Const [32])) (I64Const [32]))
(SignExt16to(64|32) x) -> (I64ShrS (I64Shl x (I64Const [48])) (I64Const [48]))
(SignExt8to(64|32|16) x) -> (I64ShrS (I64Shl x (I64Const [56])) (I64Const [56]))
(ZeroExt32to64 x) -> (I64ShrU (I64Shl x (I64Const [32])) (I64Const [32]))
(ZeroExt16to(64|32) x) -> (I64ShrU (I64Shl x (I64Const [48])) (I64Const [48]))
(ZeroExt8to(64|32|16) x) -> (I64ShrU (I64Shl x (I64Const [56])) (I64Const [56]))
......@@ -364,6 +370,10 @@
(I64Ne (I64Const [x]) (I64Const [y])) && x == y -> (I64Const [0])
(I64Ne (I64Const [x]) (I64Const [y])) && x != y -> (I64Const [1])
(I64Shl (I64Const [x]) (I64Const [y])) -> (I64Const [x << uint64(y)])
(I64ShrU (I64Const [x]) (I64Const [y])) -> (I64Const [int64(uint64(x) >> uint64(y))])
(I64ShrS (I64Const [x]) (I64Const [y])) -> (I64Const [x >> uint64(y)])
(I64Add (I64Const [x]) y) -> (I64Add y (I64Const [x]))
(I64Mul (I64Const [x]) y) -> (I64Mul y (I64Const [x]))
(I64And (I64Const [x]) y) -> (I64And y (I64Const [x]))
......@@ -374,6 +384,9 @@
(I64Eq (I64Const [x]) y) -> (I64Eq y (I64Const [x]))
(I64Ne (I64Const [x]) y) -> (I64Ne y (I64Const [x]))
(I64Eq x (I64Const [0])) -> (I64Eqz x)
(I64Ne x (I64Const [0])) -> (I64Eqz (I64Eqz x))
(I64Add x (I64Const [y])) -> (I64AddConst [y] x)
(I64Eqz (I64Eqz (I64Eqz x))) -> (I64Eqz x)
......
......@@ -489,6 +489,12 @@ func rewriteValueWasm(v *Value) bool {
return rewriteValueWasm_OpWasmI64Ne_0(v)
case OpWasmI64Or:
return rewriteValueWasm_OpWasmI64Or_0(v)
case OpWasmI64Shl:
return rewriteValueWasm_OpWasmI64Shl_0(v)
case OpWasmI64ShrS:
return rewriteValueWasm_OpWasmI64ShrS_0(v)
case OpWasmI64ShrU:
return rewriteValueWasm_OpWasmI64ShrU_0(v)
case OpWasmI64Store:
return rewriteValueWasm_OpWasmI64Store_0(v)
case OpWasmI64Store16:
......@@ -4503,6 +4509,20 @@ func rewriteValueWasm_OpSignExt16to32_0(v *Value) bool {
_ = b
typ := &b.Func.Config.Types
_ = typ
// match: (SignExt16to32 x:(I64Load16S _ _))
// cond:
// result: x
for {
x := v.Args[0]
if x.Op != OpWasmI64Load16S {
break
}
_ = x.Args[1]
v.reset(OpCopy)
v.Type = x.Type
v.AddArg(x)
return true
}
// match: (SignExt16to32 x)
// cond:
// result: (I64ShrS (I64Shl x (I64Const [48])) (I64Const [48]))
......@@ -4526,6 +4546,20 @@ func rewriteValueWasm_OpSignExt16to64_0(v *Value) bool {
_ = b
typ := &b.Func.Config.Types
_ = typ
// match: (SignExt16to64 x:(I64Load16S _ _))
// cond:
// result: x
for {
x := v.Args[0]
if x.Op != OpWasmI64Load16S {
break
}
_ = x.Args[1]
v.reset(OpCopy)
v.Type = x.Type
v.AddArg(x)
return true
}
// match: (SignExt16to64 x)
// cond:
// result: (I64ShrS (I64Shl x (I64Const [48])) (I64Const [48]))
......@@ -4549,6 +4583,20 @@ func rewriteValueWasm_OpSignExt32to64_0(v *Value) bool {
_ = b
typ := &b.Func.Config.Types
_ = typ
// match: (SignExt32to64 x:(I64Load32S _ _))
// cond:
// result: x
for {
x := v.Args[0]
if x.Op != OpWasmI64Load32S {
break
}
_ = x.Args[1]
v.reset(OpCopy)
v.Type = x.Type
v.AddArg(x)
return true
}
// match: (SignExt32to64 x)
// cond:
// result: (I64ShrS (I64Shl x (I64Const [32])) (I64Const [32]))
......@@ -4572,6 +4620,20 @@ func rewriteValueWasm_OpSignExt8to16_0(v *Value) bool {
_ = b
typ := &b.Func.Config.Types
_ = typ
// match: (SignExt8to16 x:(I64Load8S _ _))
// cond:
// result: x
for {
x := v.Args[0]
if x.Op != OpWasmI64Load8S {
break
}
_ = x.Args[1]
v.reset(OpCopy)
v.Type = x.Type
v.AddArg(x)
return true
}
// match: (SignExt8to16 x)
// cond:
// result: (I64ShrS (I64Shl x (I64Const [56])) (I64Const [56]))
......@@ -4595,6 +4657,20 @@ func rewriteValueWasm_OpSignExt8to32_0(v *Value) bool {
_ = b
typ := &b.Func.Config.Types
_ = typ
// match: (SignExt8to32 x:(I64Load8S _ _))
// cond:
// result: x
for {
x := v.Args[0]
if x.Op != OpWasmI64Load8S {
break
}
_ = x.Args[1]
v.reset(OpCopy)
v.Type = x.Type
v.AddArg(x)
return true
}
// match: (SignExt8to32 x)
// cond:
// result: (I64ShrS (I64Shl x (I64Const [56])) (I64Const [56]))
......@@ -4618,6 +4694,20 @@ func rewriteValueWasm_OpSignExt8to64_0(v *Value) bool {
_ = b
typ := &b.Func.Config.Types
_ = typ
// match: (SignExt8to64 x:(I64Load8S _ _))
// cond:
// result: x
for {
x := v.Args[0]
if x.Op != OpWasmI64Load8S {
break
}
_ = x.Args[1]
v.reset(OpCopy)
v.Type = x.Type
v.AddArg(x)
return true
}
// match: (SignExt8to64 x)
// cond:
// result: (I64ShrS (I64Shl x (I64Const [56])) (I64Const [56]))
......@@ -5232,6 +5322,23 @@ func rewriteValueWasm_OpWasmI64Eq_0(v *Value) bool {
v.AddArg(v0)
return true
}
// match: (I64Eq x (I64Const [0]))
// cond:
// result: (I64Eqz x)
for {
_ = v.Args[1]
x := v.Args[0]
v_1 := v.Args[1]
if v_1.Op != OpWasmI64Const {
break
}
if v_1.AuxInt != 0 {
break
}
v.reset(OpWasmI64Eqz)
v.AddArg(x)
return true
}
return false
}
func rewriteValueWasm_OpWasmI64Eqz_0(v *Value) bool {
......@@ -5540,6 +5647,25 @@ func rewriteValueWasm_OpWasmI64Ne_0(v *Value) bool {
v.AddArg(v0)
return true
}
// match: (I64Ne x (I64Const [0]))
// cond:
// result: (I64Eqz (I64Eqz x))
for {
_ = v.Args[1]
x := v.Args[0]
v_1 := v.Args[1]
if v_1.Op != OpWasmI64Const {
break
}
if v_1.AuxInt != 0 {
break
}
v.reset(OpWasmI64Eqz)
v0 := b.NewValue0(v.Pos, OpWasmI64Eqz, typ.Bool)
v0.AddArg(x)
v.AddArg(v0)
return true
}
return false
}
func rewriteValueWasm_OpWasmI64Or_0(v *Value) bool {
......@@ -5586,6 +5712,72 @@ func rewriteValueWasm_OpWasmI64Or_0(v *Value) bool {
}
return false
}
func rewriteValueWasm_OpWasmI64Shl_0(v *Value) bool {
// match: (I64Shl (I64Const [x]) (I64Const [y]))
// cond:
// result: (I64Const [x << uint64(y)])
for {
_ = v.Args[1]
v_0 := v.Args[0]
if v_0.Op != OpWasmI64Const {
break
}
x := v_0.AuxInt
v_1 := v.Args[1]
if v_1.Op != OpWasmI64Const {
break
}
y := v_1.AuxInt
v.reset(OpWasmI64Const)
v.AuxInt = x << uint64(y)
return true
}
return false
}
func rewriteValueWasm_OpWasmI64ShrS_0(v *Value) bool {
// match: (I64ShrS (I64Const [x]) (I64Const [y]))
// cond:
// result: (I64Const [x >> uint64(y)])
for {
_ = v.Args[1]
v_0 := v.Args[0]
if v_0.Op != OpWasmI64Const {
break
}
x := v_0.AuxInt
v_1 := v.Args[1]
if v_1.Op != OpWasmI64Const {
break
}
y := v_1.AuxInt
v.reset(OpWasmI64Const)
v.AuxInt = x >> uint64(y)
return true
}
return false
}
func rewriteValueWasm_OpWasmI64ShrU_0(v *Value) bool {
// match: (I64ShrU (I64Const [x]) (I64Const [y]))
// cond:
// result: (I64Const [int64(uint64(x) >> uint64(y))])
for {
_ = v.Args[1]
v_0 := v.Args[0]
if v_0.Op != OpWasmI64Const {
break
}
x := v_0.AuxInt
v_1 := v.Args[1]
if v_1.Op != OpWasmI64Const {
break
}
y := v_1.AuxInt
v.reset(OpWasmI64Const)
v.AuxInt = int64(uint64(x) >> uint64(y))
return true
}
return false
}
func rewriteValueWasm_OpWasmI64Store_0(v *Value) bool {
// match: (I64Store [off] (I64AddConst [off2] ptr) val mem)
// cond: isU32Bit(off+off2)
......@@ -6138,6 +6330,20 @@ func rewriteValueWasm_OpZeroExt16to32_0(v *Value) bool {
_ = b
typ := &b.Func.Config.Types
_ = typ
// match: (ZeroExt16to32 x:(I64Load16U _ _))
// cond:
// result: x
for {
x := v.Args[0]
if x.Op != OpWasmI64Load16U {
break
}
_ = x.Args[1]
v.reset(OpCopy)
v.Type = x.Type
v.AddArg(x)
return true
}
// match: (ZeroExt16to32 x)
// cond:
// result: (I64ShrU (I64Shl x (I64Const [48])) (I64Const [48]))
......@@ -6161,6 +6367,20 @@ func rewriteValueWasm_OpZeroExt16to64_0(v *Value) bool {
_ = b
typ := &b.Func.Config.Types
_ = typ
// match: (ZeroExt16to64 x:(I64Load16U _ _))
// cond:
// result: x
for {
x := v.Args[0]
if x.Op != OpWasmI64Load16U {
break
}
_ = x.Args[1]
v.reset(OpCopy)
v.Type = x.Type
v.AddArg(x)
return true
}
// match: (ZeroExt16to64 x)
// cond:
// result: (I64ShrU (I64Shl x (I64Const [48])) (I64Const [48]))
......@@ -6184,6 +6404,20 @@ func rewriteValueWasm_OpZeroExt32to64_0(v *Value) bool {
_ = b
typ := &b.Func.Config.Types
_ = typ
// match: (ZeroExt32to64 x:(I64Load32U _ _))
// cond:
// result: x
for {
x := v.Args[0]
if x.Op != OpWasmI64Load32U {
break
}
_ = x.Args[1]
v.reset(OpCopy)
v.Type = x.Type
v.AddArg(x)
return true
}
// match: (ZeroExt32to64 x)
// cond:
// result: (I64ShrU (I64Shl x (I64Const [32])) (I64Const [32]))
......@@ -6207,6 +6441,20 @@ func rewriteValueWasm_OpZeroExt8to16_0(v *Value) bool {
_ = b
typ := &b.Func.Config.Types
_ = typ
// match: (ZeroExt8to16 x:(I64Load8U _ _))
// cond:
// result: x
for {
x := v.Args[0]
if x.Op != OpWasmI64Load8U {
break
}
_ = x.Args[1]
v.reset(OpCopy)
v.Type = x.Type
v.AddArg(x)
return true
}
// match: (ZeroExt8to16 x)
// cond:
// result: (I64ShrU (I64Shl x (I64Const [56])) (I64Const [56]))
......@@ -6230,6 +6478,20 @@ func rewriteValueWasm_OpZeroExt8to32_0(v *Value) bool {
_ = b
typ := &b.Func.Config.Types
_ = typ
// match: (ZeroExt8to32 x:(I64Load8U _ _))
// cond:
// result: x
for {
x := v.Args[0]
if x.Op != OpWasmI64Load8U {
break
}
_ = x.Args[1]
v.reset(OpCopy)
v.Type = x.Type
v.AddArg(x)
return true
}
// match: (ZeroExt8to32 x)
// cond:
// result: (I64ShrU (I64Shl x (I64Const [56])) (I64Const [56]))
......@@ -6253,6 +6515,20 @@ func rewriteValueWasm_OpZeroExt8to64_0(v *Value) bool {
_ = b
typ := &b.Func.Config.Types
_ = typ
// match: (ZeroExt8to64 x:(I64Load8U _ _))
// cond:
// result: x
for {
x := v.Args[0]
if x.Op != OpWasmI64Load8U {
break
}
_ = x.Args[1]
v.reset(OpCopy)
v.Type = x.Type
v.AddArg(x)
return true
}
// match: (ZeroExt8to64 x)
// cond:
// result: (I64ShrU (I64Shl x (I64Const [56])) (I64Const [56]))
......
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