diff --git a/src/cmd/compile/internal/ssa/_gen/LOONG64.rules b/src/cmd/compile/internal/ssa/_gen/LOONG64.rules index 74bc60a3027..33cc8a6ae3a 100644 --- a/src/cmd/compile/internal/ssa/_gen/LOONG64.rules +++ b/src/cmd/compile/internal/ssa/_gen/LOONG64.rules @@ -42,6 +42,10 @@ (Select1 (Add64carry x y c)) => (OR (SGTU x s:(ADDV x y)) (SGTU s (ADDV s c))) +(Select0 (Sub64borrow x y c)) => (SUBV (SUBV x y) c) +(Select1 (Sub64borrow x y c)) => + (OR (SGTU s:(SUBV x y) x) (SGTU (SUBV s c) s)) + // (x + y) / 2 with x>=y => (x - y) / 2 + y (Avg64u x y) => (ADDV (SRLVconst (SUBV x y) [1]) y) diff --git a/src/cmd/compile/internal/ssa/rewriteLOONG64.go b/src/cmd/compile/internal/ssa/rewriteLOONG64.go index e2d0d20efb3..fbe49e58194 100644 --- a/src/cmd/compile/internal/ssa/rewriteLOONG64.go +++ b/src/cmd/compile/internal/ssa/rewriteLOONG64.go @@ -6844,6 +6844,22 @@ func rewriteValueLOONG64_OpSelect0(v *Value) bool { v.AddArg2(v0, c) return true } + // match: (Select0 (Sub64borrow x y c)) + // result: (SUBV (SUBV x y) c) + for { + t := v.Type + if v_0.Op != OpSub64borrow { + break + } + c := v_0.Args[2] + x := v_0.Args[0] + y := v_0.Args[1] + v.reset(OpLOONG64SUBV) + v0 := b.NewValue0(v.Pos, OpLOONG64SUBV, t) + v0.AddArg2(x, y) + v.AddArg2(v0, c) + return true + } // match: (Select0 (DIVVU _ (MOVVconst [1]))) // result: (MOVVconst [0]) for { @@ -6978,6 +6994,28 @@ func rewriteValueLOONG64_OpSelect1(v *Value) bool { v.AddArg2(v0, v2) return true } + // match: (Select1 (Sub64borrow x y c)) + // result: (OR (SGTU s:(SUBV x y) x) (SGTU (SUBV s c) s)) + for { + t := v.Type + if v_0.Op != OpSub64borrow { + break + } + c := v_0.Args[2] + x := v_0.Args[0] + y := v_0.Args[1] + v.reset(OpLOONG64OR) + v0 := b.NewValue0(v.Pos, OpLOONG64SGTU, t) + s := b.NewValue0(v.Pos, OpLOONG64SUBV, t) + s.AddArg2(x, y) + v0.AddArg2(s, x) + v2 := b.NewValue0(v.Pos, OpLOONG64SGTU, t) + v3 := b.NewValue0(v.Pos, OpLOONG64SUBV, t) + v3.AddArg2(s, c) + v2.AddArg2(v3, s) + v.AddArg2(v0, v2) + return true + } // match: (Select1 (MULVU x (MOVVconst [-1]))) // result: (NEGV x) for { diff --git a/src/cmd/compile/internal/ssagen/ssa.go b/src/cmd/compile/internal/ssagen/ssa.go index f4601c56cf7..77307f4c2df 100644 --- a/src/cmd/compile/internal/ssagen/ssa.go +++ b/src/cmd/compile/internal/ssagen/ssa.go @@ -4736,8 +4736,8 @@ func InitTables() { func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { return s.newValue3(ssa.OpSub64borrow, types.NewTuple(types.Types[types.TUINT64], types.Types[types.TUINT64]), args[0], args[1], args[2]) }, - sys.AMD64, sys.ARM64, sys.PPC64, sys.S390X, sys.RISCV64) - alias("math/bits", "Sub", "math/bits", "Sub64", sys.ArchAMD64, sys.ArchARM64, sys.ArchS390X, sys.ArchRISCV64) + sys.AMD64, sys.ARM64, sys.PPC64, sys.S390X, sys.RISCV64, sys.Loong64) + alias("math/bits", "Sub", "math/bits", "Sub64", p8...) addF("math/bits", "Div64", func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { // check for divide-by-zero/overflow and panic with appropriate message diff --git a/test/codegen/mathbits.go b/test/codegen/mathbits.go index bd23b90b9b4..acc9930c61d 100644 --- a/test/codegen/mathbits.go +++ b/test/codegen/mathbits.go @@ -627,6 +627,7 @@ func Add64MPanicOnOverflowGT(a, b [2]uint64) [2]uint64 { func Sub(x, y, ci uint) (r, co uint) { // amd64:"NEGL","SBBQ","NEGQ" // arm64:"NEGS","SBCS","NGC","NEG",-"ADD",-"SUB",-"CMP" + // loong64:"SUBV","SGTU" // ppc64:"SUBC", "SUBE", "SUBZE", "NEG" // ppc64le:"SUBC", "SUBE", "SUBZE", "NEG" // s390x:"SUBE" @@ -637,6 +638,7 @@ func Sub(x, y, ci uint) (r, co uint) { func SubC(x, ci uint) (r, co uint) { // amd64:"NEGL","SBBQ","NEGQ" // arm64:"NEGS","SBCS","NGC","NEG",-"ADD",-"SUB",-"CMP" + // loong64:"SUBV","SGTU" // ppc64:"SUBC", "SUBE", "SUBZE", "NEG" // ppc64le:"SUBC", "SUBE", "SUBZE", "NEG" // s390x:"SUBE" @@ -647,6 +649,7 @@ func SubC(x, ci uint) (r, co uint) { func SubZ(x, y uint) (r, co uint) { // amd64:"SUBQ","SBBQ","NEGQ",-"NEGL" // arm64:"SUBS","NGC","NEG",-"SBCS",-"ADD",-"SUB\t",-"CMP" + // loong64:"SUBV","SGTU" // ppc64:"SUBC", -"SUBE", "SUBZE", "NEG" // ppc64le:"SUBC", -"SUBE", "SUBZE", "NEG" // s390x:"SUBC" @@ -657,6 +660,7 @@ func SubZ(x, y uint) (r, co uint) { func SubR(x, y, ci uint) uint { // amd64:"NEGL","SBBQ",-"NEGQ" // arm64:"NEGS","SBCS",-"NGC",-"NEG\t",-"ADD",-"SUB",-"CMP" + // loong64:"SUBV",-"SGTU" // ppc64:"SUBC", "SUBE", -"SUBZE", -"NEG" // ppc64le:"SUBC", "SUBE", -"SUBZE", -"NEG" // s390x:"SUBE" @@ -679,6 +683,7 @@ func SubM(p, q, r *[3]uint) { func Sub64(x, y, ci uint64) (r, co uint64) { // amd64:"NEGL","SBBQ","NEGQ" // arm64:"NEGS","SBCS","NGC","NEG",-"ADD",-"SUB",-"CMP" + // loong64:"SUBV","SGTU" // ppc64:"SUBC", "SUBE", "SUBZE", "NEG" // ppc64le:"SUBC", "SUBE", "SUBZE", "NEG" // s390x:"SUBE" @@ -689,6 +694,7 @@ func Sub64(x, y, ci uint64) (r, co uint64) { func Sub64C(x, ci uint64) (r, co uint64) { // amd64:"NEGL","SBBQ","NEGQ" // arm64:"NEGS","SBCS","NGC","NEG",-"ADD",-"SUB",-"CMP" + // loong64:"SUBV","SGTU" // ppc64:"SUBC", "SUBE", "SUBZE", "NEG" // ppc64le:"SUBC", "SUBE", "SUBZE", "NEG" // s390x:"SUBE" @@ -699,6 +705,7 @@ func Sub64C(x, ci uint64) (r, co uint64) { func Sub64Z(x, y uint64) (r, co uint64) { // amd64:"SUBQ","SBBQ","NEGQ",-"NEGL" // arm64:"SUBS","NGC","NEG",-"SBCS",-"ADD",-"SUB\t",-"CMP" + // loong64:"SUBV","SGTU" // ppc64:"SUBC", -"SUBE", "SUBZE", "NEG" // ppc64le:"SUBC", -"SUBE", "SUBZE", "NEG" // s390x:"SUBC" @@ -709,6 +716,7 @@ func Sub64Z(x, y uint64) (r, co uint64) { func Sub64R(x, y, ci uint64) uint64 { // amd64:"NEGL","SBBQ",-"NEGQ" // arm64:"NEGS","SBCS",-"NGC",-"NEG\t",-"ADD",-"SUB",-"CMP" + // loong64:"SUBV",-"SGTU" // ppc64:"SUBC", "SUBE", -"SUBZE", -"NEG" // ppc64le:"SUBC", "SUBE", -"SUBZE", -"NEG" // s390x:"SUBE"