From 96428e160de755d6b3b3b7dc1b9c81196957d679 Mon Sep 17 00:00:00 2001 From: Wayne Zuo Date: Thu, 2 Mar 2023 15:55:03 +0800 Subject: [PATCH] cmd/compile: split DIVV/DIVVU op on loong64 Previously, we need calculate both quotient and remainder together. However, in most cases, only one result is needed. By separating these instructions, we can save one instruction in most cases. Change-Id: I0a2d4167cda68ab606783ba1aa2720ede19d6b53 Reviewed-on: https://go-review.googlesource.com/c/go/+/475315 Reviewed-by: Than McIntosh Run-TryBot: Wayne Zuo Reviewed-by: abner chenc TryBot-Result: Gopher Robot Reviewed-by: David Chase --- src/cmd/compile/internal/loong64/ssa.go | 29 +- .../compile/internal/ssa/_gen/LOONG64.rules | 48 +- .../compile/internal/ssa/_gen/LOONG64Ops.go | 8 +- src/cmd/compile/internal/ssa/opGen.go | 52 +- .../compile/internal/ssa/rewriteLOONG64.go | 560 ++++++++---------- 5 files changed, 310 insertions(+), 387 deletions(-) diff --git a/src/cmd/compile/internal/loong64/ssa.go b/src/cmd/compile/internal/loong64/ssa.go index 54afacce7f..8193b4e321 100644 --- a/src/cmd/compile/internal/loong64/ssa.go +++ b/src/cmd/compile/internal/loong64/ssa.go @@ -141,7 +141,8 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) { ssa.OpLOONG64MULD, ssa.OpLOONG64DIVF, ssa.OpLOONG64DIVD, - ssa.OpLOONG64MULV, ssa.OpLOONG64MULHV, ssa.OpLOONG64MULHVU: + ssa.OpLOONG64MULV, ssa.OpLOONG64MULHV, ssa.OpLOONG64MULHVU, + ssa.OpLOONG64DIVV, ssa.OpLOONG64REMV, ssa.OpLOONG64DIVVU, ssa.OpLOONG64REMVU: p := s.Prog(v.Op.Asm()) p.From.Type = obj.TYPE_REG p.From.Reg = v.Args[1].Reg() @@ -175,32 +176,6 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) { p.Reg = v.Args[0].Reg() p.To.Type = obj.TYPE_REG p.To.Reg = v.Reg() - case ssa.OpLOONG64DIVV: - p := s.Prog(loong64.ADIVV) - p.From.Type = obj.TYPE_REG - p.From.Reg = v.Args[1].Reg() - p.Reg = v.Args[0].Reg() - p.To.Type = obj.TYPE_REG - p.To.Reg = v.Reg1() - p1 := s.Prog(loong64.AREMV) - p1.From.Type = obj.TYPE_REG - p1.From.Reg = v.Args[1].Reg() - p1.Reg = v.Args[0].Reg() - p1.To.Type = obj.TYPE_REG - p1.To.Reg = v.Reg0() - case ssa.OpLOONG64DIVVU: - p := s.Prog(loong64.ADIVVU) - p.From.Type = obj.TYPE_REG - p.From.Reg = v.Args[1].Reg() - p.Reg = v.Args[0].Reg() - p.To.Type = obj.TYPE_REG - p.To.Reg = v.Reg1() - p1 := s.Prog(loong64.AREMVU) - p1.From.Type = obj.TYPE_REG - p1.From.Reg = v.Args[1].Reg() - p1.Reg = v.Args[0].Reg() - p1.To.Type = obj.TYPE_REG - p1.To.Reg = v.Reg0() case ssa.OpLOONG64MOVVconst: r := v.Reg() p := s.Prog(v.Op.Asm()) diff --git a/src/cmd/compile/internal/ssa/_gen/LOONG64.rules b/src/cmd/compile/internal/ssa/_gen/LOONG64.rules index ab7774ed4e..4a47c4cd47 100644 --- a/src/cmd/compile/internal/ssa/_gen/LOONG64.rules +++ b/src/cmd/compile/internal/ssa/_gen/LOONG64.rules @@ -20,24 +20,24 @@ (Hmul32 x y) => (SRAVconst (MULV (SignExt32to64 x) (SignExt32to64 y)) [32]) (Hmul32u x y) => (SRLVconst (MULV (ZeroExt32to64 x) (ZeroExt32to64 y)) [32]) -(Div64 x y) => (Select1 (DIVV x y)) -(Div64u x y) => (Select1 (DIVVU x y)) -(Div32 x y) => (Select1 (DIVV (SignExt32to64 x) (SignExt32to64 y))) -(Div32u x y) => (Select1 (DIVVU (ZeroExt32to64 x) (ZeroExt32to64 y))) -(Div16 x y) => (Select1 (DIVV (SignExt16to64 x) (SignExt16to64 y))) -(Div16u x y) => (Select1 (DIVVU (ZeroExt16to64 x) (ZeroExt16to64 y))) -(Div8 x y) => (Select1 (DIVV (SignExt8to64 x) (SignExt8to64 y))) -(Div8u x y) => (Select1 (DIVVU (ZeroExt8to64 x) (ZeroExt8to64 y))) +(Div64 x y) => (DIVV x y) +(Div64u ...) => (DIVVU ...) +(Div32 x y) => (DIVV (SignExt32to64 x) (SignExt32to64 y)) +(Div32u x y) => (DIVVU (ZeroExt32to64 x) (ZeroExt32to64 y)) +(Div16 x y) => (DIVV (SignExt16to64 x) (SignExt16to64 y)) +(Div16u x y) => (DIVVU (ZeroExt16to64 x) (ZeroExt16to64 y)) +(Div8 x y) => (DIVV (SignExt8to64 x) (SignExt8to64 y)) +(Div8u x y) => (DIVVU (ZeroExt8to64 x) (ZeroExt8to64 y)) (Div(32|64)F ...) => (DIV(F|D) ...) -(Mod64 x y) => (Select0 (DIVV x y)) -(Mod64u x y) => (Select0 (DIVVU x y)) -(Mod32 x y) => (Select0 (DIVV (SignExt32to64 x) (SignExt32to64 y))) -(Mod32u x y) => (Select0 (DIVVU (ZeroExt32to64 x) (ZeroExt32to64 y))) -(Mod16 x y) => (Select0 (DIVV (SignExt16to64 x) (SignExt16to64 y))) -(Mod16u x y) => (Select0 (DIVVU (ZeroExt16to64 x) (ZeroExt16to64 y))) -(Mod8 x y) => (Select0 (DIVV (SignExt8to64 x) (SignExt8to64 y))) -(Mod8u x y) => (Select0 (DIVVU (ZeroExt8to64 x) (ZeroExt8to64 y))) +(Mod64 x y) => (REMV x y) +(Mod64u ...) => (REMVU ...) +(Mod32 x y) => (REMV (SignExt32to64 x) (SignExt32to64 y)) +(Mod32u x y) => (REMVU (ZeroExt32to64 x) (ZeroExt32to64 y)) +(Mod16 x y) => (REMV (SignExt16to64 x) (SignExt16to64 y)) +(Mod16u x y) => (REMVU (ZeroExt16to64 x) (ZeroExt16to64 y)) +(Mod8 x y) => (REMV (SignExt8to64 x) (SignExt8to64 y)) +(Mod8u x y) => (REMVU (ZeroExt8to64 x) (ZeroExt8to64 y)) (Select0 (Add64carry x y c)) => (ADDV (ADDV x y) c) (Select1 (Add64carry x y c)) => @@ -598,10 +598,10 @@ (MULV x (MOVVconst [c])) && isPowerOfTwo64(c) => (SLLVconst [log64(c)] x) // div by constant -(Select1 (DIVVU x (MOVVconst [1]))) => x -(Select1 (DIVVU x (MOVVconst [c]))) && isPowerOfTwo64(c) => (SRLVconst [log64(c)] x) -(Select0 (DIVVU _ (MOVVconst [1]))) => (MOVVconst [0]) // mod -(Select0 (DIVVU x (MOVVconst [c]))) && isPowerOfTwo64(c) => (ANDconst [c-1] x) // mod +(DIVVU x (MOVVconst [1])) => x +(DIVVU x (MOVVconst [c])) && isPowerOfTwo64(c) => (SRLVconst [log64(c)] x) +(REMVU _ (MOVVconst [1])) => (MOVVconst [0]) // mod +(REMVU x (MOVVconst [c])) && isPowerOfTwo64(c) => (ANDconst [c-1] x) // mod // generic simplifications (ADDV x (NEGV y)) => (SUBV x y) @@ -636,10 +636,10 @@ (SRLVconst [c] (MOVVconst [d])) => (MOVVconst [int64(uint64(d)>>uint64(c))]) (SRAVconst [c] (MOVVconst [d])) => (MOVVconst [d>>uint64(c)]) (MULV (MOVVconst [c]) (MOVVconst [d])) => (MOVVconst [c*d]) -(Select1 (DIVV (MOVVconst [c]) (MOVVconst [d]))) && d != 0 => (MOVVconst [c/d]) -(Select1 (DIVVU (MOVVconst [c]) (MOVVconst [d]))) && d != 0 => (MOVVconst [int64(uint64(c)/uint64(d))]) -(Select0 (DIVV (MOVVconst [c]) (MOVVconst [d]))) && d != 0 => (MOVVconst [c%d]) // mod -(Select0 (DIVVU (MOVVconst [c]) (MOVVconst [d]))) && d != 0 => (MOVVconst [int64(uint64(c)%uint64(d))]) // mod +(DIVV (MOVVconst [c]) (MOVVconst [d])) && d != 0 => (MOVVconst [c/d]) +(DIVVU (MOVVconst [c]) (MOVVconst [d])) && d != 0 => (MOVVconst [int64(uint64(c)/uint64(d))]) +(REMV (MOVVconst [c]) (MOVVconst [d])) && d != 0 => (MOVVconst [c%d]) // mod +(REMVU (MOVVconst [c]) (MOVVconst [d])) && d != 0 => (MOVVconst [int64(uint64(c)%uint64(d))]) // mod (ANDconst [c] (MOVVconst [d])) => (MOVVconst [c&d]) (ANDconst [c] (ANDconst [d] x)) => (ANDconst [c&d] x) (ORconst [c] (MOVVconst [d])) => (MOVVconst [c|d]) diff --git a/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go b/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go index b593d3d41a..23f20fddeb 100644 --- a/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go +++ b/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go @@ -124,7 +124,6 @@ func init() { // Common individual register masks var ( gp = buildReg("R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31") // R1 is LR, R2 is thread pointer, R3 is stack pointer, R21-unused, R22 is g, R30 is REGTMP - gps = buildReg("R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31") | buildReg("g") gpg = gp | buildReg("g") gpsp = gp | buildReg("SP") gpspg = gpg | buildReg("SP") @@ -142,7 +141,6 @@ func init() { gp11 = regInfo{inputs: []regMask{gpg}, outputs: []regMask{gp}} gp11sp = regInfo{inputs: []regMask{gpspg}, outputs: []regMask{gp}} gp21 = regInfo{inputs: []regMask{gpg, gpg}, outputs: []regMask{gp}} - gp22 = regInfo{inputs: []regMask{gps, gps}, outputs: []regMask{gp, gp}} gpload = regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{gp}} gpstore = regInfo{inputs: []regMask{gpspsbg, gpg}} gpstore0 = regInfo{inputs: []regMask{gpspsbg}} @@ -166,8 +164,10 @@ func init() { {name: "MULV", argLength: 2, reg: gp21, asm: "MULV", commutative: true, typ: "Int64"}, // arg0 * arg1 {name: "MULHV", argLength: 2, reg: gp21, asm: "MULHV", commutative: true, typ: "Int64"}, // (arg0 * arg1) >> 64, signed {name: "MULHVU", argLength: 2, reg: gp21, asm: "MULHVU", commutative: true, typ: "UInt64"}, // (arg0 * arg1) >> 64, unsigned - {name: "DIVV", argLength: 2, reg: gp22, resultNotInArgs: true, typ: "(Int64,Int64)"}, // arg0 / arg1, signed - {name: "DIVVU", argLength: 2, reg: gp22, resultNotInArgs: true, typ: "(UInt64,UInt64)"}, // arg0 / arg1, unsigned + {name: "DIVV", argLength: 2, reg: gp21, asm: "DIVV", typ: "Int64"}, // arg0 / arg1, signed + {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: "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 2f51869c24..16052abbde 100644 --- a/src/cmd/compile/internal/ssa/opGen.go +++ b/src/cmd/compile/internal/ssa/opGen.go @@ -1723,6 +1723,8 @@ const ( OpLOONG64MULHVU OpLOONG64DIVV OpLOONG64DIVVU + OpLOONG64REMV + OpLOONG64REMVU OpLOONG64ADDF OpLOONG64ADDD OpLOONG64SUBF @@ -22992,32 +22994,58 @@ var opcodeTable = [...]opInfo{ }, }, { - name: "DIVV", - argLen: 2, - resultNotInArgs: true, + name: "DIVV", + argLen: 2, + asm: loong64.ADIVV, reg: regInfo{ inputs: []inputInfo{ - {0, 1072496632}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 - {1, 1072496632}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 }, outputs: []outputInfo{ {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 - {1, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, { - name: "DIVVU", - argLen: 2, - resultNotInArgs: true, + name: "DIVVU", + argLen: 2, + asm: loong64.ADIVVU, reg: regInfo{ inputs: []inputInfo{ - {0, 1072496632}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 - {1, 1072496632}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + }, + outputs: []outputInfo{ + {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, + { + name: "REMV", + argLen: 2, + asm: loong64.AREMV, + reg: regInfo{ + inputs: []inputInfo{ + {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + }, + outputs: []outputInfo{ + {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 + }, + }, + }, + { + name: "REMVU", + argLen: 2, + asm: loong64.AREMVU, + reg: regInfo{ + inputs: []inputInfo{ + {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 + {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 }, outputs: []outputInfo{ {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 - {1, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31 }, }, }, diff --git a/src/cmd/compile/internal/ssa/rewriteLOONG64.go b/src/cmd/compile/internal/ssa/rewriteLOONG64.go index d0fb54fc03..e88b74cb22 100644 --- a/src/cmd/compile/internal/ssa/rewriteLOONG64.go +++ b/src/cmd/compile/internal/ssa/rewriteLOONG64.go @@ -166,7 +166,8 @@ func rewriteValueLOONG64(v *Value) bool { v.Op = OpLOONG64DIVD return true case OpDiv64u: - return rewriteValueLOONG64_OpDiv64u(v) + v.Op = OpLOONG64DIVVU + return true case OpDiv8: return rewriteValueLOONG64_OpDiv8(v) case OpDiv8u: @@ -223,6 +224,10 @@ func rewriteValueLOONG64(v *Value) bool { return rewriteValueLOONG64_OpLOONG64AND(v) case OpLOONG64ANDconst: return rewriteValueLOONG64_OpLOONG64ANDconst(v) + case OpLOONG64DIVV: + return rewriteValueLOONG64_OpLOONG64DIVV(v) + case OpLOONG64DIVVU: + return rewriteValueLOONG64_OpLOONG64DIVVU(v) case OpLOONG64LoweredAtomicAdd32: return rewriteValueLOONG64_OpLOONG64LoweredAtomicAdd32(v) case OpLOONG64LoweredAtomicAdd64: @@ -299,6 +304,10 @@ func rewriteValueLOONG64(v *Value) bool { return rewriteValueLOONG64_OpLOONG64OR(v) case OpLOONG64ORconst: return rewriteValueLOONG64_OpLOONG64ORconst(v) + case OpLOONG64REMV: + return rewriteValueLOONG64_OpLOONG64REMV(v) + case OpLOONG64REMVU: + return rewriteValueLOONG64_OpLOONG64REMVU(v) case OpLOONG64ROTR: return rewriteValueLOONG64_OpLOONG64ROTR(v) case OpLOONG64ROTRV: @@ -418,7 +427,8 @@ func rewriteValueLOONG64(v *Value) bool { case OpMod64: return rewriteValueLOONG64_OpMod64(v) case OpMod64u: - return rewriteValueLOONG64_OpMod64u(v) + v.Op = OpLOONG64REMVU + return true case OpMod8: return rewriteValueLOONG64_OpMod8(v) case OpMod8u: @@ -915,18 +925,16 @@ func rewriteValueLOONG64_OpDiv16(v *Value) bool { b := v.Block typ := &b.Func.Config.Types // match: (Div16 x y) - // result: (Select1 (DIVV (SignExt16to64 x) (SignExt16to64 y))) + // result: (DIVV (SignExt16to64 x) (SignExt16to64 y)) for { x := v_0 y := v_1 - v.reset(OpSelect1) - v0 := b.NewValue0(v.Pos, OpLOONG64DIVV, types.NewTuple(typ.Int64, typ.Int64)) + v.reset(OpLOONG64DIVV) + v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) + v0.AddArg(x) v1 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) - v1.AddArg(x) - v2 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) - v2.AddArg(y) - v0.AddArg2(v1, v2) - v.AddArg(v0) + v1.AddArg(y) + v.AddArg2(v0, v1) return true } } @@ -936,18 +944,16 @@ func rewriteValueLOONG64_OpDiv16u(v *Value) bool { b := v.Block typ := &b.Func.Config.Types // match: (Div16u x y) - // result: (Select1 (DIVVU (ZeroExt16to64 x) (ZeroExt16to64 y))) + // result: (DIVVU (ZeroExt16to64 x) (ZeroExt16to64 y)) for { x := v_0 y := v_1 - v.reset(OpSelect1) - v0 := b.NewValue0(v.Pos, OpLOONG64DIVVU, types.NewTuple(typ.UInt64, typ.UInt64)) + v.reset(OpLOONG64DIVVU) + v0 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) + v0.AddArg(x) v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) - v1.AddArg(x) - v2 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) - v2.AddArg(y) - v0.AddArg2(v1, v2) - v.AddArg(v0) + v1.AddArg(y) + v.AddArg2(v0, v1) return true } } @@ -957,18 +963,16 @@ func rewriteValueLOONG64_OpDiv32(v *Value) bool { b := v.Block typ := &b.Func.Config.Types // match: (Div32 x y) - // result: (Select1 (DIVV (SignExt32to64 x) (SignExt32to64 y))) + // result: (DIVV (SignExt32to64 x) (SignExt32to64 y)) for { x := v_0 y := v_1 - v.reset(OpSelect1) - v0 := b.NewValue0(v.Pos, OpLOONG64DIVV, types.NewTuple(typ.Int64, typ.Int64)) + v.reset(OpLOONG64DIVV) + v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) + v0.AddArg(x) v1 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) - v1.AddArg(x) - v2 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) - v2.AddArg(y) - v0.AddArg2(v1, v2) - v.AddArg(v0) + v1.AddArg(y) + v.AddArg2(v0, v1) return true } } @@ -978,52 +982,29 @@ func rewriteValueLOONG64_OpDiv32u(v *Value) bool { b := v.Block typ := &b.Func.Config.Types // match: (Div32u x y) - // result: (Select1 (DIVVU (ZeroExt32to64 x) (ZeroExt32to64 y))) + // result: (DIVVU (ZeroExt32to64 x) (ZeroExt32to64 y)) for { x := v_0 y := v_1 - v.reset(OpSelect1) - v0 := b.NewValue0(v.Pos, OpLOONG64DIVVU, types.NewTuple(typ.UInt64, typ.UInt64)) + v.reset(OpLOONG64DIVVU) + v0 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) + v0.AddArg(x) v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) - v1.AddArg(x) - v2 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) - v2.AddArg(y) - v0.AddArg2(v1, v2) - v.AddArg(v0) + v1.AddArg(y) + v.AddArg2(v0, v1) return true } } func rewriteValueLOONG64_OpDiv64(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] - b := v.Block - typ := &b.Func.Config.Types // match: (Div64 x y) - // result: (Select1 (DIVV x y)) - for { - x := v_0 - y := v_1 - v.reset(OpSelect1) - v0 := b.NewValue0(v.Pos, OpLOONG64DIVV, types.NewTuple(typ.Int64, typ.Int64)) - v0.AddArg2(x, y) - v.AddArg(v0) - return true - } -} -func rewriteValueLOONG64_OpDiv64u(v *Value) bool { - v_1 := v.Args[1] - v_0 := v.Args[0] - b := v.Block - typ := &b.Func.Config.Types - // match: (Div64u x y) - // result: (Select1 (DIVVU x y)) + // result: (DIVV x y) for { x := v_0 y := v_1 - v.reset(OpSelect1) - v0 := b.NewValue0(v.Pos, OpLOONG64DIVVU, types.NewTuple(typ.UInt64, typ.UInt64)) - v0.AddArg2(x, y) - v.AddArg(v0) + v.reset(OpLOONG64DIVV) + v.AddArg2(x, y) return true } } @@ -1033,18 +1014,16 @@ func rewriteValueLOONG64_OpDiv8(v *Value) bool { b := v.Block typ := &b.Func.Config.Types // match: (Div8 x y) - // result: (Select1 (DIVV (SignExt8to64 x) (SignExt8to64 y))) + // result: (DIVV (SignExt8to64 x) (SignExt8to64 y)) for { x := v_0 y := v_1 - v.reset(OpSelect1) - v0 := b.NewValue0(v.Pos, OpLOONG64DIVV, types.NewTuple(typ.Int64, typ.Int64)) + v.reset(OpLOONG64DIVV) + v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) + v0.AddArg(x) v1 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) - v1.AddArg(x) - v2 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) - v2.AddArg(y) - v0.AddArg2(v1, v2) - v.AddArg(v0) + v1.AddArg(y) + v.AddArg2(v0, v1) return true } } @@ -1054,18 +1033,16 @@ func rewriteValueLOONG64_OpDiv8u(v *Value) bool { b := v.Block typ := &b.Func.Config.Types // match: (Div8u x y) - // result: (Select1 (DIVVU (ZeroExt8to64 x) (ZeroExt8to64 y))) + // result: (DIVVU (ZeroExt8to64 x) (ZeroExt8to64 y)) for { x := v_0 y := v_1 - v.reset(OpSelect1) - v0 := b.NewValue0(v.Pos, OpLOONG64DIVVU, types.NewTuple(typ.UInt64, typ.UInt64)) + v.reset(OpLOONG64DIVVU) + v0 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) + v0.AddArg(x) v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) - v1.AddArg(x) - v2 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) - v2.AddArg(y) - v0.AddArg2(v1, v2) - v.AddArg(v0) + v1.AddArg(y) + v.AddArg2(v0, v1) return true } } @@ -1526,6 +1503,81 @@ func rewriteValueLOONG64_OpLOONG64ANDconst(v *Value) bool { } return false } +func rewriteValueLOONG64_OpLOONG64DIVV(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + // match: (DIVV (MOVVconst [c]) (MOVVconst [d])) + // cond: d != 0 + // result: (MOVVconst [c/d]) + for { + if v_0.Op != OpLOONG64MOVVconst { + break + } + c := auxIntToInt64(v_0.AuxInt) + if v_1.Op != OpLOONG64MOVVconst { + break + } + d := auxIntToInt64(v_1.AuxInt) + if !(d != 0) { + break + } + v.reset(OpLOONG64MOVVconst) + v.AuxInt = int64ToAuxInt(c / d) + return true + } + return false +} +func rewriteValueLOONG64_OpLOONG64DIVVU(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + // match: (DIVVU x (MOVVconst [1])) + // result: x + for { + x := v_0 + if v_1.Op != OpLOONG64MOVVconst || auxIntToInt64(v_1.AuxInt) != 1 { + break + } + v.copyOf(x) + return true + } + // match: (DIVVU x (MOVVconst [c])) + // cond: isPowerOfTwo64(c) + // result: (SRLVconst [log64(c)] x) + for { + x := v_0 + if v_1.Op != OpLOONG64MOVVconst { + break + } + c := auxIntToInt64(v_1.AuxInt) + if !(isPowerOfTwo64(c)) { + break + } + v.reset(OpLOONG64SRLVconst) + v.AuxInt = int64ToAuxInt(log64(c)) + v.AddArg(x) + return true + } + // match: (DIVVU (MOVVconst [c]) (MOVVconst [d])) + // cond: d != 0 + // result: (MOVVconst [int64(uint64(c)/uint64(d))]) + for { + if v_0.Op != OpLOONG64MOVVconst { + break + } + c := auxIntToInt64(v_0.AuxInt) + if v_1.Op != OpLOONG64MOVVconst { + break + } + d := auxIntToInt64(v_1.AuxInt) + if !(d != 0) { + break + } + v.reset(OpLOONG64MOVVconst) + v.AuxInt = int64ToAuxInt(int64(uint64(c) / uint64(d))) + return true + } + return false +} func rewriteValueLOONG64_OpLOONG64LoweredAtomicAdd32(v *Value) bool { v_2 := v.Args[2] v_1 := v.Args[1] @@ -3467,6 +3519,81 @@ func rewriteValueLOONG64_OpLOONG64ORconst(v *Value) bool { } return false } +func rewriteValueLOONG64_OpLOONG64REMV(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + // match: (REMV (MOVVconst [c]) (MOVVconst [d])) + // cond: d != 0 + // result: (MOVVconst [c%d]) + for { + if v_0.Op != OpLOONG64MOVVconst { + break + } + c := auxIntToInt64(v_0.AuxInt) + if v_1.Op != OpLOONG64MOVVconst { + break + } + d := auxIntToInt64(v_1.AuxInt) + if !(d != 0) { + break + } + v.reset(OpLOONG64MOVVconst) + v.AuxInt = int64ToAuxInt(c % d) + return true + } + return false +} +func rewriteValueLOONG64_OpLOONG64REMVU(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + // match: (REMVU _ (MOVVconst [1])) + // result: (MOVVconst [0]) + for { + if v_1.Op != OpLOONG64MOVVconst || auxIntToInt64(v_1.AuxInt) != 1 { + break + } + v.reset(OpLOONG64MOVVconst) + v.AuxInt = int64ToAuxInt(0) + return true + } + // match: (REMVU x (MOVVconst [c])) + // cond: isPowerOfTwo64(c) + // result: (ANDconst [c-1] x) + for { + x := v_0 + if v_1.Op != OpLOONG64MOVVconst { + break + } + c := auxIntToInt64(v_1.AuxInt) + if !(isPowerOfTwo64(c)) { + break + } + v.reset(OpLOONG64ANDconst) + v.AuxInt = int64ToAuxInt(c - 1) + v.AddArg(x) + return true + } + // match: (REMVU (MOVVconst [c]) (MOVVconst [d])) + // cond: d != 0 + // result: (MOVVconst [int64(uint64(c)%uint64(d))]) + for { + if v_0.Op != OpLOONG64MOVVconst { + break + } + c := auxIntToInt64(v_0.AuxInt) + if v_1.Op != OpLOONG64MOVVconst { + break + } + d := auxIntToInt64(v_1.AuxInt) + if !(d != 0) { + break + } + v.reset(OpLOONG64MOVVconst) + v.AuxInt = int64ToAuxInt(int64(uint64(c) % uint64(d))) + return true + } + return false +} func rewriteValueLOONG64_OpLOONG64ROTR(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] @@ -5131,18 +5258,16 @@ func rewriteValueLOONG64_OpMod16(v *Value) bool { b := v.Block typ := &b.Func.Config.Types // match: (Mod16 x y) - // result: (Select0 (DIVV (SignExt16to64 x) (SignExt16to64 y))) + // result: (REMV (SignExt16to64 x) (SignExt16to64 y)) for { x := v_0 y := v_1 - v.reset(OpSelect0) - v0 := b.NewValue0(v.Pos, OpLOONG64DIVV, types.NewTuple(typ.Int64, typ.Int64)) + v.reset(OpLOONG64REMV) + v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) + v0.AddArg(x) v1 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) - v1.AddArg(x) - v2 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) - v2.AddArg(y) - v0.AddArg2(v1, v2) - v.AddArg(v0) + v1.AddArg(y) + v.AddArg2(v0, v1) return true } } @@ -5152,18 +5277,16 @@ func rewriteValueLOONG64_OpMod16u(v *Value) bool { b := v.Block typ := &b.Func.Config.Types // match: (Mod16u x y) - // result: (Select0 (DIVVU (ZeroExt16to64 x) (ZeroExt16to64 y))) + // result: (REMVU (ZeroExt16to64 x) (ZeroExt16to64 y)) for { x := v_0 y := v_1 - v.reset(OpSelect0) - v0 := b.NewValue0(v.Pos, OpLOONG64DIVVU, types.NewTuple(typ.UInt64, typ.UInt64)) + v.reset(OpLOONG64REMVU) + v0 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) + v0.AddArg(x) v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) - v1.AddArg(x) - v2 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) - v2.AddArg(y) - v0.AddArg2(v1, v2) - v.AddArg(v0) + v1.AddArg(y) + v.AddArg2(v0, v1) return true } } @@ -5173,18 +5296,16 @@ func rewriteValueLOONG64_OpMod32(v *Value) bool { b := v.Block typ := &b.Func.Config.Types // match: (Mod32 x y) - // result: (Select0 (DIVV (SignExt32to64 x) (SignExt32to64 y))) + // result: (REMV (SignExt32to64 x) (SignExt32to64 y)) for { x := v_0 y := v_1 - v.reset(OpSelect0) - v0 := b.NewValue0(v.Pos, OpLOONG64DIVV, types.NewTuple(typ.Int64, typ.Int64)) + v.reset(OpLOONG64REMV) + v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) + v0.AddArg(x) v1 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) - v1.AddArg(x) - v2 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) - v2.AddArg(y) - v0.AddArg2(v1, v2) - v.AddArg(v0) + v1.AddArg(y) + v.AddArg2(v0, v1) return true } } @@ -5194,52 +5315,29 @@ func rewriteValueLOONG64_OpMod32u(v *Value) bool { b := v.Block typ := &b.Func.Config.Types // match: (Mod32u x y) - // result: (Select0 (DIVVU (ZeroExt32to64 x) (ZeroExt32to64 y))) + // result: (REMVU (ZeroExt32to64 x) (ZeroExt32to64 y)) for { x := v_0 y := v_1 - v.reset(OpSelect0) - v0 := b.NewValue0(v.Pos, OpLOONG64DIVVU, types.NewTuple(typ.UInt64, typ.UInt64)) + v.reset(OpLOONG64REMVU) + v0 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) + v0.AddArg(x) v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) - v1.AddArg(x) - v2 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) - v2.AddArg(y) - v0.AddArg2(v1, v2) - v.AddArg(v0) + v1.AddArg(y) + v.AddArg2(v0, v1) return true } } func rewriteValueLOONG64_OpMod64(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] - b := v.Block - typ := &b.Func.Config.Types // match: (Mod64 x y) - // result: (Select0 (DIVV x y)) - for { - x := v_0 - y := v_1 - v.reset(OpSelect0) - v0 := b.NewValue0(v.Pos, OpLOONG64DIVV, types.NewTuple(typ.Int64, typ.Int64)) - v0.AddArg2(x, y) - v.AddArg(v0) - return true - } -} -func rewriteValueLOONG64_OpMod64u(v *Value) bool { - v_1 := v.Args[1] - v_0 := v.Args[0] - b := v.Block - typ := &b.Func.Config.Types - // match: (Mod64u x y) - // result: (Select0 (DIVVU x y)) + // result: (REMV x y) for { x := v_0 y := v_1 - v.reset(OpSelect0) - v0 := b.NewValue0(v.Pos, OpLOONG64DIVVU, types.NewTuple(typ.UInt64, typ.UInt64)) - v0.AddArg2(x, y) - v.AddArg(v0) + v.reset(OpLOONG64REMV) + v.AddArg2(x, y) return true } } @@ -5249,18 +5347,16 @@ func rewriteValueLOONG64_OpMod8(v *Value) bool { b := v.Block typ := &b.Func.Config.Types // match: (Mod8 x y) - // result: (Select0 (DIVV (SignExt8to64 x) (SignExt8to64 y))) + // result: (REMV (SignExt8to64 x) (SignExt8to64 y)) for { x := v_0 y := v_1 - v.reset(OpSelect0) - v0 := b.NewValue0(v.Pos, OpLOONG64DIVV, types.NewTuple(typ.Int64, typ.Int64)) + v.reset(OpLOONG64REMV) + v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) + v0.AddArg(x) v1 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) - v1.AddArg(x) - v2 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) - v2.AddArg(y) - v0.AddArg2(v1, v2) - v.AddArg(v0) + v1.AddArg(y) + v.AddArg2(v0, v1) return true } } @@ -5270,18 +5366,16 @@ func rewriteValueLOONG64_OpMod8u(v *Value) bool { b := v.Block typ := &b.Func.Config.Types // match: (Mod8u x y) - // result: (Select0 (DIVVU (ZeroExt8to64 x) (ZeroExt8to64 y))) + // result: (REMVU (ZeroExt8to64 x) (ZeroExt8to64 y)) for { x := v_0 y := v_1 - v.reset(OpSelect0) - v0 := b.NewValue0(v.Pos, OpLOONG64DIVVU, types.NewTuple(typ.UInt64, typ.UInt64)) + v.reset(OpLOONG64REMVU) + v0 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) + v0.AddArg(x) v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) - v1.AddArg(x) - v2 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) - v2.AddArg(y) - v0.AddArg2(v1, v2) - v.AddArg(v0) + v1.AddArg(y) + v.AddArg2(v0, v1) return true } } @@ -6919,93 +7013,6 @@ func rewriteValueLOONG64_OpSelect0(v *Value) bool { v.AddArg2(v0, c) return true } - // match: (Select0 (DIVVU _ (MOVVconst [1]))) - // result: (MOVVconst [0]) - for { - if v_0.Op != OpLOONG64DIVVU { - break - } - _ = v_0.Args[1] - v_0_1 := v_0.Args[1] - if v_0_1.Op != OpLOONG64MOVVconst || auxIntToInt64(v_0_1.AuxInt) != 1 { - break - } - v.reset(OpLOONG64MOVVconst) - v.AuxInt = int64ToAuxInt(0) - return true - } - // match: (Select0 (DIVVU x (MOVVconst [c]))) - // cond: isPowerOfTwo64(c) - // result: (ANDconst [c-1] x) - for { - if v_0.Op != OpLOONG64DIVVU { - break - } - _ = v_0.Args[1] - x := v_0.Args[0] - v_0_1 := v_0.Args[1] - if v_0_1.Op != OpLOONG64MOVVconst { - break - } - c := auxIntToInt64(v_0_1.AuxInt) - if !(isPowerOfTwo64(c)) { - break - } - v.reset(OpLOONG64ANDconst) - v.AuxInt = int64ToAuxInt(c - 1) - v.AddArg(x) - return true - } - // match: (Select0 (DIVV (MOVVconst [c]) (MOVVconst [d]))) - // cond: d != 0 - // result: (MOVVconst [c%d]) - for { - if v_0.Op != OpLOONG64DIVV { - break - } - _ = v_0.Args[1] - v_0_0 := v_0.Args[0] - if v_0_0.Op != OpLOONG64MOVVconst { - break - } - c := auxIntToInt64(v_0_0.AuxInt) - v_0_1 := v_0.Args[1] - if v_0_1.Op != OpLOONG64MOVVconst { - break - } - d := auxIntToInt64(v_0_1.AuxInt) - if !(d != 0) { - break - } - v.reset(OpLOONG64MOVVconst) - v.AuxInt = int64ToAuxInt(c % d) - return true - } - // match: (Select0 (DIVVU (MOVVconst [c]) (MOVVconst [d]))) - // cond: d != 0 - // result: (MOVVconst [int64(uint64(c)%uint64(d))]) - for { - if v_0.Op != OpLOONG64DIVVU { - break - } - _ = v_0.Args[1] - v_0_0 := v_0.Args[0] - if v_0_0.Op != OpLOONG64MOVVconst { - break - } - c := auxIntToInt64(v_0_0.AuxInt) - v_0_1 := v_0.Args[1] - if v_0_1.Op != OpLOONG64MOVVconst { - break - } - d := auxIntToInt64(v_0_1.AuxInt) - if !(d != 0) { - break - } - v.reset(OpLOONG64MOVVconst) - v.AuxInt = int64ToAuxInt(int64(uint64(c) % uint64(d))) - return true - } return false } func rewriteValueLOONG64_OpSelect1(v *Value) bool { @@ -7085,93 +7092,6 @@ func rewriteValueLOONG64_OpSelect1(v *Value) bool { v.AddArg2(v0, v2) return true } - // match: (Select1 (DIVVU x (MOVVconst [1]))) - // result: x - for { - if v_0.Op != OpLOONG64DIVVU { - break - } - _ = v_0.Args[1] - x := v_0.Args[0] - v_0_1 := v_0.Args[1] - if v_0_1.Op != OpLOONG64MOVVconst || auxIntToInt64(v_0_1.AuxInt) != 1 { - break - } - v.copyOf(x) - return true - } - // match: (Select1 (DIVVU x (MOVVconst [c]))) - // cond: isPowerOfTwo64(c) - // result: (SRLVconst [log64(c)] x) - for { - if v_0.Op != OpLOONG64DIVVU { - break - } - _ = v_0.Args[1] - x := v_0.Args[0] - v_0_1 := v_0.Args[1] - if v_0_1.Op != OpLOONG64MOVVconst { - break - } - c := auxIntToInt64(v_0_1.AuxInt) - if !(isPowerOfTwo64(c)) { - break - } - v.reset(OpLOONG64SRLVconst) - v.AuxInt = int64ToAuxInt(log64(c)) - v.AddArg(x) - return true - } - // match: (Select1 (DIVV (MOVVconst [c]) (MOVVconst [d]))) - // cond: d != 0 - // result: (MOVVconst [c/d]) - for { - if v_0.Op != OpLOONG64DIVV { - break - } - _ = v_0.Args[1] - v_0_0 := v_0.Args[0] - if v_0_0.Op != OpLOONG64MOVVconst { - break - } - c := auxIntToInt64(v_0_0.AuxInt) - v_0_1 := v_0.Args[1] - if v_0_1.Op != OpLOONG64MOVVconst { - break - } - d := auxIntToInt64(v_0_1.AuxInt) - if !(d != 0) { - break - } - v.reset(OpLOONG64MOVVconst) - v.AuxInt = int64ToAuxInt(c / d) - return true - } - // match: (Select1 (DIVVU (MOVVconst [c]) (MOVVconst [d]))) - // cond: d != 0 - // result: (MOVVconst [int64(uint64(c)/uint64(d))]) - for { - if v_0.Op != OpLOONG64DIVVU { - break - } - _ = v_0.Args[1] - v_0_0 := v_0.Args[0] - if v_0_0.Op != OpLOONG64MOVVconst { - break - } - c := auxIntToInt64(v_0_0.AuxInt) - v_0_1 := v_0.Args[1] - if v_0_1.Op != OpLOONG64MOVVconst { - break - } - d := auxIntToInt64(v_0_1.AuxInt) - if !(d != 0) { - break - } - v.reset(OpLOONG64MOVVconst) - v.AuxInt = int64ToAuxInt(int64(uint64(c) / uint64(d))) - return true - } return false } func rewriteValueLOONG64_OpSlicemask(v *Value) bool { -- 2.48.1