diff --git a/src/cmd/compile/internal/ssa/_gen/ARM64.rules b/src/cmd/compile/internal/ssa/_gen/ARM64.rules index a0069eb5dc..01fe3a74f7 100644 --- a/src/cmd/compile/internal/ssa/_gen/ARM64.rules +++ b/src/cmd/compile/internal/ssa/_gen/ARM64.rules @@ -1198,6 +1198,7 @@ // generic simplifications (ADD x (NEG y)) => (SUB x y) +(SUB x (NEG y)) => (ADD x y) (SUB x x) => (MOVDconst [0]) (AND x x) => x (OR x x) => x @@ -1209,6 +1210,7 @@ (XOR x (MVN y)) => (EON x y) (OR x (MVN y)) => (ORN x y) (MVN (XOR x y)) => (EON x y) +(NEG (SUB x y)) => (SUB y x) (NEG (NEG x)) => x (CSEL [cc] (MOVDconst [-1]) (MOVDconst [0]) flag) => (CSETM [cc] flag) diff --git a/src/cmd/compile/internal/ssa/rewriteARM64.go b/src/cmd/compile/internal/ssa/rewriteARM64.go index c3b961dde8..792967c001 100644 --- a/src/cmd/compile/internal/ssa/rewriteARM64.go +++ b/src/cmd/compile/internal/ssa/rewriteARM64.go @@ -12699,6 +12699,18 @@ func rewriteValueARM64_OpARM64NEG(v *Value) bool { v.AddArg2(x, y) return true } + // match: (NEG (SUB x y)) + // result: (SUB y x) + for { + if v_0.Op != OpARM64SUB { + break + } + y := v_0.Args[1] + x := v_0.Args[0] + v.reset(OpARM64SUB) + v.AddArg2(y, x) + return true + } // match: (NEG (NEG x)) // result: x for { @@ -15204,6 +15216,18 @@ func rewriteValueARM64_OpARM64SUB(v *Value) bool { v.AddArg(v0) return true } + // match: (SUB x (NEG y)) + // result: (ADD x y) + for { + x := v_0 + if v_1.Op != OpARM64NEG { + break + } + y := v_1.Args[0] + v.reset(OpARM64ADD) + v.AddArg2(x, y) + return true + } // match: (SUB x x) // result: (MOVDconst [0]) for { diff --git a/test/codegen/arithmetic.go b/test/codegen/arithmetic.go index 6d8e62c721..bd5540ec4b 100644 --- a/test/codegen/arithmetic.go +++ b/test/codegen/arithmetic.go @@ -91,6 +91,7 @@ func SubFromConst(a int) int { } func SubFromConstNeg(a int) int { + // arm64: "ADD\t\\$40" // loong64: "ADDV[U]\t\\$40" // mips: "ADD[U]\t\\$40" // mips64: "ADDV[U]\t\\$40" @@ -101,6 +102,7 @@ func SubFromConstNeg(a int) int { } func SubSubFromConst(a int) int { + // arm64: "ADD\t\\$20" // loong64: "ADDV[U]\t\\$20" // mips: "ADD[U]\t\\$20" // mips64: "ADDV[U]\t\\$20" @@ -118,6 +120,7 @@ func AddSubFromConst(a int) int { } func NegSubFromConst(a int) int { + // arm64: "SUB\t\\$20" // loong64: "ADDV[U]\t\\$-20" // mips: "ADD[U]\t\\$-20" // mips64: "ADDV[U]\t\\$-20" @@ -128,6 +131,7 @@ func NegSubFromConst(a int) int { } func NegAddFromConstNeg(a int) int { + // arm64: "SUB\t\\$40","NEG" // loong64: "ADDV[U]\t\\$-40","SUBV" // mips: "ADD[U]\t\\$-40","SUB" // mips64: "ADDV[U]\t\\$-40","SUBV" @@ -139,6 +143,7 @@ func NegAddFromConstNeg(a int) int { func SubSubNegSimplify(a, b int) int { // amd64:"NEGQ" + // arm64:"NEG" // loong64:"SUBV" // mips:"SUB" // mips64:"SUBV" @@ -150,6 +155,7 @@ func SubSubNegSimplify(a, b int) int { func SubAddSimplify(a, b int) int { // amd64:-"SUBQ",-"ADDQ" + // arm64:-"SUB",-"ADD" // loong64:-"SUBV",-"ADDV" // mips:-"SUB",-"ADD" // mips64:-"SUBV",-"ADDV" @@ -161,6 +167,7 @@ func SubAddSimplify(a, b int) int { func SubAddSimplify2(a, b, c int) (int, int, int, int, int, int) { // amd64:-"ADDQ" + // arm64:-"ADD" // mips:"SUB",-"ADD" // mips64:"SUBV",-"ADDV" // loong64:"SUBV",-"ADDV" @@ -172,6 +179,7 @@ func SubAddSimplify2(a, b, c int) (int, int, int, int, int, int) { // amd64:-"ADDQ" r3 := (b + a) - (c + a) // amd64:-"SUBQ" + // arm64:-"SUB" // mips:"ADD",-"SUB" // mips64:"ADDV",-"SUBV" // loong64:"ADDV",-"SUBV" @@ -183,6 +191,7 @@ func SubAddSimplify2(a, b, c int) (int, int, int, int, int, int) { func SubAddNegSimplify(a, b int) int { // amd64:"NEGQ",-"ADDQ",-"SUBQ" + // arm64:"NEG",-"ADD",-"SUB" // loong64:"SUBV",-"ADDV" // mips:"SUB",-"ADD" // mips64:"SUBV",-"ADDV" @@ -194,6 +203,7 @@ func SubAddNegSimplify(a, b int) int { func AddAddSubSimplify(a, b, c int) int { // amd64:-"SUBQ" + // arm64:"ADD",-"SUB" // loong64:"ADDV",-"SUBV" // mips:"ADD",-"SUB" // mips64:"ADDV",-"SUBV"