diff --git a/src/cmd/compile/internal/ssa/gen/S390X.rules b/src/cmd/compile/internal/ssa/gen/S390X.rules index c26515c569..4ba4ddb11c 100644 --- a/src/cmd/compile/internal/ssa/gen/S390X.rules +++ b/src/cmd/compile/internal/ssa/gen/S390X.rules @@ -448,7 +448,15 @@ // *************************** // TODO: Should the optimizations be a separate pass? -// if a register move has only 1 use, just use the same register without emitting instruction +// Fold unnecessary type conversions. +(MOVDreg x) && t.Compare(x.Type) == CMPeq -> x +(MOVDnop x) && t.Compare(x.Type) == CMPeq -> x + +// Propagate constants through type conversions. +(MOVDreg (MOVDconst [c])) -> (MOVDconst [c]) +(MOVDnop (MOVDconst [c])) -> (MOVDconst [c]) + +// If a register move has only 1 use, just use the same register without emitting instruction. // MOVDnop doesn't emit instruction, only for ensuring the type. (MOVDreg x) && x.Uses == 1 -> (MOVDnop x) diff --git a/src/cmd/compile/internal/ssa/rewriteS390X.go b/src/cmd/compile/internal/ssa/rewriteS390X.go index 0425ced330..ae86541a03 100644 --- a/src/cmd/compile/internal/ssa/rewriteS390X.go +++ b/src/cmd/compile/internal/ssa/rewriteS390X.go @@ -524,6 +524,8 @@ func rewriteValueS390X(v *Value, config *Config) bool { return rewriteValueS390X_OpS390XMOVDload(v, config) case OpS390XMOVDloadidx: return rewriteValueS390X_OpS390XMOVDloadidx(v, config) + case OpS390XMOVDnop: + return rewriteValueS390X_OpS390XMOVDnop(v, config) case OpS390XMOVDreg: return rewriteValueS390X_OpS390XMOVDreg(v, config) case OpS390XMOVDstore: @@ -10195,9 +10197,68 @@ func rewriteValueS390X_OpS390XMOVDloadidx(v *Value, config *Config) bool { } return false } +func rewriteValueS390X_OpS390XMOVDnop(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (MOVDnop x) + // cond: t.Compare(x.Type) == CMPeq + // result: x + for { + t := v.Type + x := v.Args[0] + if !(t.Compare(x.Type) == CMPeq) { + break + } + v.reset(OpCopy) + v.Type = x.Type + v.AddArg(x) + return true + } + // match: (MOVDnop (MOVDconst [c])) + // cond: + // result: (MOVDconst [c]) + for { + v_0 := v.Args[0] + if v_0.Op != OpS390XMOVDconst { + break + } + c := v_0.AuxInt + v.reset(OpS390XMOVDconst) + v.AuxInt = c + return true + } + return false +} func rewriteValueS390X_OpS390XMOVDreg(v *Value, config *Config) bool { b := v.Block _ = b + // match: (MOVDreg x) + // cond: t.Compare(x.Type) == CMPeq + // result: x + for { + t := v.Type + x := v.Args[0] + if !(t.Compare(x.Type) == CMPeq) { + break + } + v.reset(OpCopy) + v.Type = x.Type + v.AddArg(x) + return true + } + // match: (MOVDreg (MOVDconst [c])) + // cond: + // result: (MOVDconst [c]) + for { + v_0 := v.Args[0] + if v_0.Op != OpS390XMOVDconst { + break + } + c := v_0.AuxInt + v.reset(OpS390XMOVDconst) + v.AuxInt = c + return true + } // match: (MOVDreg x) // cond: x.Uses == 1 // result: (MOVDnop x)