From 0ca355318f6c407edb4a82a0bb0c249ffd31840b Mon Sep 17 00:00:00 2001 From: Joel Sing Date: Sun, 4 Sep 2022 05:26:54 +1000 Subject: [PATCH] cmd/compile: combine masking and zero extension on riscv64 Combine masking with a negative value and zero extension into a single AND operation. Change-Id: I0b2a735b696d65568839fc4504445eeac3d869a6 Reviewed-on: https://go-review.googlesource.com/c/go/+/428498 Reviewed-by: Joedian Reid Reviewed-by: Cherry Mui TryBot-Result: Gopher Robot Run-TryBot: Joel Sing --- .../compile/internal/ssa/_gen/RISCV64.rules | 5 ++ .../compile/internal/ssa/rewriteRISCV64.go | 53 +++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/src/cmd/compile/internal/ssa/_gen/RISCV64.rules b/src/cmd/compile/internal/ssa/_gen/RISCV64.rules index ad46cf30da..9882505b6b 100644 --- a/src/cmd/compile/internal/ssa/_gen/RISCV64.rules +++ b/src/cmd/compile/internal/ssa/_gen/RISCV64.rules @@ -667,6 +667,11 @@ (MOVHUreg x:(ANDI [c] y)) && c >= 0 && int64(uint16(c)) == c => x (MOVWUreg x:(ANDI [c] y)) && c >= 0 && int64(uint32(c)) == c => x +// Combine masking and zero extension. +(MOVBUreg (ANDI [c] x)) && c < 0 => (ANDI [int64(uint8(c))] x) +(MOVHUreg (ANDI [c] x)) && c < 0 => (ANDI [int64(uint16(c))] x) +(MOVWUreg (ANDI [c] x)) && c < 0 => (AND (MOVDconst [int64(uint32(c))]) x) + // Avoid sign/zero extension for consts. (MOVBreg (MOVDconst [c])) => (MOVDconst [int64(int8(c))]) (MOVHreg (MOVDconst [c])) => (MOVDconst [int64(int16(c))]) diff --git a/src/cmd/compile/internal/ssa/rewriteRISCV64.go b/src/cmd/compile/internal/ssa/rewriteRISCV64.go index 9ec5169433..ff40a7b6ef 100644 --- a/src/cmd/compile/internal/ssa/rewriteRISCV64.go +++ b/src/cmd/compile/internal/ssa/rewriteRISCV64.go @@ -3635,6 +3635,23 @@ func rewriteValueRISCV64_OpRISCV64MOVBUreg(v *Value) bool { v.copyOf(x) return true } + // match: (MOVBUreg (ANDI [c] x)) + // cond: c < 0 + // result: (ANDI [int64(uint8(c))] x) + for { + if v_0.Op != OpRISCV64ANDI { + break + } + c := auxIntToInt64(v_0.AuxInt) + x := v_0.Args[0] + if !(c < 0) { + break + } + v.reset(OpRISCV64ANDI) + v.AuxInt = int64ToAuxInt(int64(uint8(c))) + v.AddArg(x) + return true + } // match: (MOVBUreg (MOVDconst [c])) // result: (MOVDconst [int64(uint8(c))]) for { @@ -4341,6 +4358,23 @@ func rewriteValueRISCV64_OpRISCV64MOVHUreg(v *Value) bool { v.copyOf(x) return true } + // match: (MOVHUreg (ANDI [c] x)) + // cond: c < 0 + // result: (ANDI [int64(uint16(c))] x) + for { + if v_0.Op != OpRISCV64ANDI { + break + } + c := auxIntToInt64(v_0.AuxInt) + x := v_0.Args[0] + if !(c < 0) { + break + } + v.reset(OpRISCV64ANDI) + v.AuxInt = int64ToAuxInt(int64(uint16(c))) + v.AddArg(x) + return true + } // match: (MOVHUreg (MOVDconst [c])) // result: (MOVDconst [int64(uint16(c))]) for { @@ -4825,6 +4859,7 @@ func rewriteValueRISCV64_OpRISCV64MOVWUload(v *Value) bool { func rewriteValueRISCV64_OpRISCV64MOVWUreg(v *Value) bool { v_0 := v.Args[0] b := v.Block + typ := &b.Func.Config.Types // match: (MOVWUreg x:(ANDI [c] y)) // cond: c >= 0 && int64(uint32(c)) == c // result: x @@ -4840,6 +4875,24 @@ func rewriteValueRISCV64_OpRISCV64MOVWUreg(v *Value) bool { v.copyOf(x) return true } + // match: (MOVWUreg (ANDI [c] x)) + // cond: c < 0 + // result: (AND (MOVDconst [int64(uint32(c))]) x) + for { + if v_0.Op != OpRISCV64ANDI { + break + } + c := auxIntToInt64(v_0.AuxInt) + x := v_0.Args[0] + if !(c < 0) { + break + } + v.reset(OpRISCV64AND) + v0 := b.NewValue0(v.Pos, OpRISCV64MOVDconst, typ.UInt64) + v0.AuxInt = int64ToAuxInt(int64(uint32(c))) + v.AddArg2(v0, x) + return true + } // match: (MOVWUreg (MOVDconst [c])) // result: (MOVDconst [int64(uint32(c))]) for {