From 6300161d40e50902e16b3144c36aaf9279ab6208 Mon Sep 17 00:00:00 2001 From: Keith Randall Date: Fri, 30 Sep 2016 09:03:38 -0700 Subject: [PATCH] cmd/compile: force folding of MOVDaddr into storezero Fold MOVDaddr ops into MOVXstorezero ops. Also fold ADDconst into MOVDaddr so we're sure there isn't (MOVDstorezero (ADDconst (MOVDaddr ..))) Without this CL, we get: v1 = MOVDaddr {s} v2 = VARDEF {s} v3 = MOVDstorezero v1 v2 The liveness pass thinks the MOVDaddr is a read of s, so s is incorrectly thought to be live at the start of the function. Fixes #17194 Change-Id: I2b4a2f13b12aa5b072941ee1c7b89f3793650cdc Reviewed-on: https://go-review.googlesource.com/30086 Run-TryBot: Keith Randall TryBot-Result: Gobot Gobot Reviewed-by: Lynn Boger Reviewed-by: Michael Munday --- src/cmd/compile/internal/ssa/gen/PPC64.rules | 11 ++ src/cmd/compile/internal/ssa/rewritePPC64.go | 114 +++++++++++++++++++ test/fixedbugs/issue17194.go | 17 +++ 3 files changed, 142 insertions(+) create mode 100644 test/fixedbugs/issue17194.go diff --git a/src/cmd/compile/internal/ssa/gen/PPC64.rules b/src/cmd/compile/internal/ssa/gen/PPC64.rules index 9bb8cafadc..3d885a9aaa 100644 --- a/src/cmd/compile/internal/ssa/gen/PPC64.rules +++ b/src/cmd/compile/internal/ssa/gen/PPC64.rules @@ -523,6 +523,7 @@ (ADD (MOVDconst [c]) x) && is32Bit(c) -> (ADDconst [c] x) (ADD x (MOVDconst [c])) && is32Bit(c) -> (ADDconst [c] x) (ADDconst [c] (ADDconst [d] x)) && is32Bit(c+d) -> (ADDconst [c+d] x) +(ADDconst [c] (MOVDaddr [d] {sym} x)) -> (MOVDaddr [c+d] {sym} x) (ADDconst [0] x) -> x (ANDconst [-1] x) -> x (ANDconst [0] _) -> (MOVDconst [0]) @@ -600,6 +601,16 @@ (MOVBstorezero [off1] {sym} (ADDconst [off2] x) mem) && is16Bit(off1+off2) -> (MOVBstorezero [off1+off2] {sym} x mem) +// Fold symbols into storezero +(MOVDstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} x) mem) && canMergeSym(sym1,sym2) -> + (MOVDstorezero [off1+off2] {mergeSym(sym1,sym2)} x mem) +(MOVWstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} x) mem) && canMergeSym(sym1,sym2) -> + (MOVWstorezero [off1+off2] {mergeSym(sym1,sym2)} x mem) +(MOVHstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} x) mem) && canMergeSym(sym1,sym2) -> + (MOVHstorezero [off1+off2] {mergeSym(sym1,sym2)} x mem) +(MOVBstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} x) mem) && canMergeSym(sym1,sym2) -> + (MOVBstorezero [off1+off2] {mergeSym(sym1,sym2)} x mem) + // Lowering extension // Note: we always extend to 64 bits even though some ops don't need that many result bits. (SignExt8to16 x) -> (MOVBreg x) diff --git a/src/cmd/compile/internal/ssa/rewritePPC64.go b/src/cmd/compile/internal/ssa/rewritePPC64.go index 28b22b9e0a..e71f7f5a55 100644 --- a/src/cmd/compile/internal/ssa/rewritePPC64.go +++ b/src/cmd/compile/internal/ssa/rewritePPC64.go @@ -4101,6 +4101,24 @@ func rewriteValuePPC64_OpPPC64ADDconst(v *Value, config *Config) bool { v.AddArg(x) return true } + // match: (ADDconst [c] (MOVDaddr [d] {sym} x)) + // cond: + // result: (MOVDaddr [c+d] {sym} x) + for { + c := v.AuxInt + v_0 := v.Args[0] + if v_0.Op != OpPPC64MOVDaddr { + break + } + d := v_0.AuxInt + sym := v_0.Aux + x := v_0.Args[0] + v.reset(OpPPC64MOVDaddr) + v.AuxInt = c + d + v.Aux = sym + v.AddArg(x) + return true + } // match: (ADDconst [0] x) // cond: // result: x @@ -5263,6 +5281,30 @@ func rewriteValuePPC64_OpPPC64MOVBstorezero(v *Value, config *Config) bool { v.AddArg(mem) return true } + // match: (MOVBstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} x) mem) + // cond: canMergeSym(sym1,sym2) + // result: (MOVBstorezero [off1+off2] {mergeSym(sym1,sym2)} x mem) + for { + off1 := v.AuxInt + sym1 := v.Aux + v_0 := v.Args[0] + if v_0.Op != OpPPC64MOVDaddr { + break + } + off2 := v_0.AuxInt + sym2 := v_0.Aux + x := v_0.Args[0] + mem := v.Args[1] + if !(canMergeSym(sym1, sym2)) { + break + } + v.reset(OpPPC64MOVBstorezero) + v.AuxInt = off1 + off2 + v.Aux = mergeSym(sym1, sym2) + v.AddArg(x) + v.AddArg(mem) + return true + } return false } func rewriteValuePPC64_OpPPC64MOVDload(v *Value, config *Config) bool { @@ -5422,6 +5464,30 @@ func rewriteValuePPC64_OpPPC64MOVDstorezero(v *Value, config *Config) bool { v.AddArg(mem) return true } + // match: (MOVDstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} x) mem) + // cond: canMergeSym(sym1,sym2) + // result: (MOVDstorezero [off1+off2] {mergeSym(sym1,sym2)} x mem) + for { + off1 := v.AuxInt + sym1 := v.Aux + v_0 := v.Args[0] + if v_0.Op != OpPPC64MOVDaddr { + break + } + off2 := v_0.AuxInt + sym2 := v_0.Aux + x := v_0.Args[0] + mem := v.Args[1] + if !(canMergeSym(sym1, sym2)) { + break + } + v.reset(OpPPC64MOVDstorezero) + v.AuxInt = off1 + off2 + v.Aux = mergeSym(sym1, sym2) + v.AddArg(x) + v.AddArg(mem) + return true + } return false } func rewriteValuePPC64_OpPPC64MOVHZload(v *Value, config *Config) bool { @@ -5737,6 +5803,30 @@ func rewriteValuePPC64_OpPPC64MOVHstorezero(v *Value, config *Config) bool { v.AddArg(mem) return true } + // match: (MOVHstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} x) mem) + // cond: canMergeSym(sym1,sym2) + // result: (MOVHstorezero [off1+off2] {mergeSym(sym1,sym2)} x mem) + for { + off1 := v.AuxInt + sym1 := v.Aux + v_0 := v.Args[0] + if v_0.Op != OpPPC64MOVDaddr { + break + } + off2 := v_0.AuxInt + sym2 := v_0.Aux + x := v_0.Args[0] + mem := v.Args[1] + if !(canMergeSym(sym1, sym2)) { + break + } + v.reset(OpPPC64MOVHstorezero) + v.AuxInt = off1 + off2 + v.Aux = mergeSym(sym1, sym2) + v.AddArg(x) + v.AddArg(mem) + return true + } return false } func rewriteValuePPC64_OpPPC64MOVWZload(v *Value, config *Config) bool { @@ -5948,6 +6038,30 @@ func rewriteValuePPC64_OpPPC64MOVWstorezero(v *Value, config *Config) bool { v.AddArg(mem) return true } + // match: (MOVWstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} x) mem) + // cond: canMergeSym(sym1,sym2) + // result: (MOVWstorezero [off1+off2] {mergeSym(sym1,sym2)} x mem) + for { + off1 := v.AuxInt + sym1 := v.Aux + v_0 := v.Args[0] + if v_0.Op != OpPPC64MOVDaddr { + break + } + off2 := v_0.AuxInt + sym2 := v_0.Aux + x := v_0.Args[0] + mem := v.Args[1] + if !(canMergeSym(sym1, sym2)) { + break + } + v.reset(OpPPC64MOVWstorezero) + v.AuxInt = off1 + off2 + v.Aux = mergeSym(sym1, sym2) + v.AddArg(x) + v.AddArg(mem) + return true + } return false } func rewriteValuePPC64_OpPPC64NotEqual(v *Value, config *Config) bool { diff --git a/test/fixedbugs/issue17194.go b/test/fixedbugs/issue17194.go new file mode 100644 index 0000000000..0594e1cbdc --- /dev/null +++ b/test/fixedbugs/issue17194.go @@ -0,0 +1,17 @@ +// compile + +// Copyright 2016 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 foo + +func f(x []interface{}) (err error) { + for _, d := range x { + _, ok := d.(*int) + if ok { + return + } + } + return +} -- 2.48.1