From: Xiaolin Zhao Date: Tue, 18 Nov 2025 05:00:15 +0000 (+0800) Subject: cmd/compile: use 32x32->64 multiplies on loong64 X-Git-Tag: go1.26rc1~165 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=feae743bdbb7dc4b9d053117dbea494202d6a2de;p=gostls13.git cmd/compile: use 32x32->64 multiplies on loong64 Gets rid of some sign extensions, like arm64. Change-Id: I9fc37e15a82718bfcf53db8cab0c4e7baaa0a747 Reviewed-on: https://go-review.googlesource.com/c/go/+/721522 Reviewed-by: Keith Randall Reviewed-by: Keith Randall Reviewed-by: Meidan Li Reviewed-by: Mark Freeman Reviewed-by: abner chenc LUCI-TryBot-Result: Go LUCI --- diff --git a/src/cmd/compile/internal/loong64/ssa.go b/src/cmd/compile/internal/loong64/ssa.go index 71953109c4..dc737732f1 100644 --- a/src/cmd/compile/internal/loong64/ssa.go +++ b/src/cmd/compile/internal/loong64/ssa.go @@ -187,6 +187,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) { ssa.OpLOONG64DIVD, ssa.OpLOONG64MULV, ssa.OpLOONG64MULHV, ssa.OpLOONG64MULHVU, ssa.OpLOONG64MULH, ssa.OpLOONG64MULHU, ssa.OpLOONG64DIVV, ssa.OpLOONG64REMV, ssa.OpLOONG64DIVVU, ssa.OpLOONG64REMVU, + ssa.OpLOONG64MULWVW, ssa.OpLOONG64MULWVWU, ssa.OpLOONG64FCOPYSGD: p := s.Prog(v.Op.Asm()) p.From.Type = obj.TYPE_REG diff --git a/src/cmd/compile/internal/ssa/_gen/LOONG64.rules b/src/cmd/compile/internal/ssa/_gen/LOONG64.rules index 2beba0b1c5..b15043032c 100644 --- a/src/cmd/compile/internal/ssa/_gen/LOONG64.rules +++ b/src/cmd/compile/internal/ssa/_gen/LOONG64.rules @@ -15,6 +15,10 @@ (Select0 (Mul64uover x y)) => (MULV x y) (Select1 (Mul64uover x y)) => (SGTU (MULHVU x y) (MOVVconst [0])) +// 32 mul 32 -> 64 +(MULV r:(MOVWUreg x) s:(MOVWUreg y)) && r.Uses == 1 && s.Uses == 1 => (MULWVWU x y) +(MULV r:(MOVWreg x) s:(MOVWreg y)) && r.Uses == 1 && s.Uses == 1 => (MULWVW x y) + (Hmul64 ...) => (MULHV ...) (Hmul64u ...) => (MULHVU ...) (Hmul32 ...) => (MULH ...) diff --git a/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go b/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go index 81d3a3665b..9fd5ede869 100644 --- a/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go +++ b/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go @@ -205,6 +205,8 @@ func init() { {name: "DIVVU", argLength: 2, reg: gp21, asm: "DIVVU", typ: "UInt64"}, // arg0 / arg1, unsigned {name: "REMV", argLength: 2, reg: gp21, asm: "REMV", typ: "Int64"}, // arg0 / arg1, signed {name: "REMVU", argLength: 2, reg: gp21, asm: "REMVU", typ: "UInt64"}, // arg0 / arg1, unsigned + {name: "MULWVW", argLength: 2, reg: gp21, asm: "MULWVW", commutative: true}, // arg0 * arg1, signed, 32-bit mult results in 64-bit + {name: "MULWVWU", argLength: 2, reg: gp21, asm: "MULWVWU", commutative: true}, // arg0 * arg1, unsigned, 32-bit mult results in 64-bit {name: "ADDF", argLength: 2, reg: fp21, asm: "ADDF", commutative: true}, // arg0 + arg1 {name: "ADDD", argLength: 2, reg: fp21, asm: "ADDD", commutative: true}, // arg0 + arg1 diff --git a/src/cmd/compile/internal/ssa/opGen.go b/src/cmd/compile/internal/ssa/opGen.go index f13373d2c0..26ab2cacce 100644 --- a/src/cmd/compile/internal/ssa/opGen.go +++ b/src/cmd/compile/internal/ssa/opGen.go @@ -1814,6 +1814,8 @@ const ( OpLOONG64DIVVU OpLOONG64REMV OpLOONG64REMVU + OpLOONG64MULWVW + OpLOONG64MULWVWU OpLOONG64ADDF OpLOONG64ADDD OpLOONG64SUBF @@ -24380,6 +24382,36 @@ var opcodeTable = [...]opInfo{ }, }, }, + { + name: "MULWVW", + argLen: 2, + commutative: true, + asm: loong64.AMULWVW, + reg: regInfo{ + inputs: []inputInfo{ + {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + {1, 1073741817}, // ZERO R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + }, + outputs: []outputInfo{ + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, + { + name: "MULWVWU", + argLen: 2, + commutative: true, + asm: loong64.AMULWVWU, + reg: regInfo{ + inputs: []inputInfo{ + {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + {1, 1073741817}, // ZERO R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 + }, + outputs: []outputInfo{ + {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, { name: "ADDF", argLen: 2, diff --git a/src/cmd/compile/internal/ssa/rewriteLOONG64.go b/src/cmd/compile/internal/ssa/rewriteLOONG64.go index bf2dd114a9..30ce419d40 100644 --- a/src/cmd/compile/internal/ssa/rewriteLOONG64.go +++ b/src/cmd/compile/internal/ssa/rewriteLOONG64.go @@ -5866,6 +5866,54 @@ func rewriteValueLOONG64_OpLOONG64MULV(v *Value) bool { v_0 := v.Args[0] b := v.Block config := b.Func.Config + // match: (MULV r:(MOVWUreg x) s:(MOVWUreg y)) + // cond: r.Uses == 1 && s.Uses == 1 + // result: (MULWVWU x y) + for { + for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { + r := v_0 + if r.Op != OpLOONG64MOVWUreg { + continue + } + x := r.Args[0] + s := v_1 + if s.Op != OpLOONG64MOVWUreg { + continue + } + y := s.Args[0] + if !(r.Uses == 1 && s.Uses == 1) { + continue + } + v.reset(OpLOONG64MULWVWU) + v.AddArg2(x, y) + return true + } + break + } + // match: (MULV r:(MOVWreg x) s:(MOVWreg y)) + // cond: r.Uses == 1 && s.Uses == 1 + // result: (MULWVW x y) + for { + for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { + r := v_0 + if r.Op != OpLOONG64MOVWreg { + continue + } + x := r.Args[0] + s := v_1 + if s.Op != OpLOONG64MOVWreg { + continue + } + y := s.Args[0] + if !(r.Uses == 1 && s.Uses == 1) { + continue + } + v.reset(OpLOONG64MULWVW) + v.AddArg2(x, y) + return true + } + break + } // match: (MULV _ (MOVVconst [0])) // result: (MOVVconst [0]) for { diff --git a/test/codegen/arithmetic.go b/test/codegen/arithmetic.go index 29764bf817..7cc6cf77e1 100644 --- a/test/codegen/arithmetic.go +++ b/test/codegen/arithmetic.go @@ -335,11 +335,13 @@ func Fold2NegMul(a, b int) int { func Mul32(a, b int32) int64 { // arm64:"SMULL" -"MOVW" + // loong64:"MULWVW" -"MOVW" return int64(a) * int64(b) } func Mul32U(a, b uint32) uint64 { // arm64:"UMULL" -"MOVWU" + // loong64:"MULWVWU" -"MOVWU" return uint64(a) * uint64(b) }