From 9b25da732b62d294bc0762d45c77d1a0095d81fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandru=20Mo=C8=99oi?= Date: Fri, 31 Jul 2015 12:32:22 +0200 Subject: [PATCH] [dev.ssa] cmd/compile/internal/ssa/gen: add more simplifications rules This is a follow up on https://go-review.googlesource.com/#/c/12420/ with some rules moved to AMD64 closer to the existing rules. Change-Id: Id346bb0fc4459b3c49b826a59cc74308a590310e Reviewed-on: https://go-review.googlesource.com/12906 Reviewed-by: Keith Randall --- .../compile/internal/gc/testdata/arith_ssa.go | 36 ++ src/cmd/compile/internal/ssa/gen/AMD64.rules | 35 + .../compile/internal/ssa/gen/generic.rules | 8 + src/cmd/compile/internal/ssa/gen/rulegen.go | 4 +- src/cmd/compile/internal/ssa/rewriteAMD64.go | 612 ++++++++++++++++++ .../compile/internal/ssa/rewritegeneric.go | 154 ++++- 6 files changed, 846 insertions(+), 3 deletions(-) diff --git a/src/cmd/compile/internal/gc/testdata/arith_ssa.go b/src/cmd/compile/internal/gc/testdata/arith_ssa.go index 0a2290ef7b..1c8445fbda 100644 --- a/src/cmd/compile/internal/gc/testdata/arith_ssa.go +++ b/src/cmd/compile/internal/gc/testdata/arith_ssa.go @@ -67,6 +67,30 @@ func testBitwiseLogic() { println("testBitwiseXor failed, wanted", want, "got", got) failed = true } + if want, got := int32(832), testBitwiseLsh_ssa(13, 4, 2); want != got { + println("testBitwiseXor failed, wanted", want, "got", got) + failed = true + } + if want, got := int32(0), testBitwiseLsh_ssa(13, 25, 15); want != got { + println("testBitwiseLsh failed, wanted", want, "got", got) + failed = true + } + if want, got := int32(0), testBitwiseLsh_ssa(-13, 25, 15); want != got { + println("testBitwiseLsh failed, wanted", want, "got", got) + failed = true + } + if want, got := int32(0), testBitwiseRsh_ssa(-13, 25, 15); want != got { + println("testBitwiseLsh failed, wanted", want, "got", got) + failed = true + } + if want, got := int32(0), testBitwiseRsh_ssa(13, 25, 15); want != got { + println("testBitwiseLsh failed, wanted", want, "got", got) + failed = true + } + if want, got := int32(-1), testBitwiseRsh_ssa(-13, 25, 15); want != got { + println("testBitwiseLsh failed, wanted", want, "got", got) + failed = true + } } func testBitwiseAnd_ssa(a, b uint32) uint32 { @@ -87,6 +111,18 @@ func testBitwiseXor_ssa(a, b uint32) uint32 { return a ^ b } +func testBitwiseLsh_ssa(a int32, b, c uint32) int32 { + switch { // prevent inlining + } + return a << b << c +} + +func testBitwiseRsh_ssa(a int32, b, c uint32) int32 { + switch { // prevent inlining + } + return a >> b >> c +} + // testSubqToNegq ensures that the SUBQ -> NEGQ translation works correctly. func testSubqToNegq(a, b, c, d, e, f, g, h, i, j, k int64) { want := a + 8207351403619448057 - b - 1779494519303207690 + c*8810076340510052032*d - 4465874067674546219 - e*4361839741470334295 - f + 8688847565426072650*g*8065564729145417479 diff --git a/src/cmd/compile/internal/ssa/gen/AMD64.rules b/src/cmd/compile/internal/ssa/gen/AMD64.rules index d0f5e5b073..dd34404b70 100644 --- a/src/cmd/compile/internal/ssa/gen/AMD64.rules +++ b/src/cmd/compile/internal/ssa/gen/AMD64.rules @@ -445,10 +445,22 @@ (ADDLconst [c] (MOVLconst [d])) -> (MOVLconst [c+d]) (ADDWconst [c] (MOVWconst [d])) -> (MOVWconst [c+d]) (ADDBconst [c] (MOVBconst [d])) -> (MOVBconst [c+d]) +(ADDQconst [c] (ADDQconst [d] x)) -> (ADDQconst [c+d] x) +(ADDLconst [c] (ADDLconst [d] x)) -> (ADDLconst [c+d] x) +(ADDWconst [c] (ADDWconst [d] x)) -> (ADDWconst [c+d] x) +(ADDBconst [c] (ADDBconst [d] x)) -> (ADDBconst [c+d] x) (SUBQconst [c] (MOVQconst [d])) -> (MOVQconst [c-d]) (SUBLconst [c] (MOVLconst [d])) -> (MOVLconst [c-d]) (SUBWconst [c] (MOVWconst [d])) -> (MOVWconst [c-d]) (SUBBconst [c] (MOVBconst [d])) -> (MOVBconst [c-d]) +(SUBQconst [c] (SUBQconst [d] x)) -> (ADDQconst [c-d] x) +(SUBLconst [c] (SUBLconst [d] x)) -> (ADDLconst [c-d] x) +(SUBWconst [c] (SUBWconst [d] x)) -> (ADDWconst [c-d] x) +(SUBBconst [c] (SUBBconst [d] x)) -> (ADDBconst [c-d] x) +(NEGQ (MOVQconst [c])) -> (MOVQconst [-c]) +(NEGL (MOVLconst [c])) -> (MOVLconst [-c]) +(NEGW (MOVWconst [c])) -> (MOVWconst [-c]) +(NEGB (MOVBconst [c])) -> (MOVBconst [-c]) (MULQconst [c] (MOVQconst [d])) -> (MOVQconst [c*d]) (MULLconst [c] (MOVLconst [d])) -> (MOVLconst [c*d]) (MULWconst [c] (MOVWconst [d])) -> (MOVWconst [c*d]) @@ -468,3 +480,26 @@ (NOTL (MOVLconst [c])) -> (MOVLconst [^c]) (NOTW (MOVWconst [c])) -> (MOVWconst [^c]) (NOTB (MOVBconst [c])) -> (MOVBconst [^c]) + +// generic simplifications +// TODO: more of this +(ADDQ x (NEGQ y)) -> (SUBQ x y) +(ADDL x (NEGL y)) -> (SUBL x y) +(ADDW x (NEGW y)) -> (SUBW x y) +(ADDB x (NEGB y)) -> (SUBB x y) +(SUBQ x x) -> (MOVQconst [0]) +(SUBL x x) -> (MOVLconst [0]) +(SUBW x x) -> (MOVWconst [0]) +(SUBB x x) -> (MOVBconst [0]) +(ANDQ x x) -> (Copy x) +(ANDL x x) -> (Copy x) +(ANDW x x) -> (Copy x) +(ANDB x x) -> (Copy x) +(ORQ x x) -> (Copy x) +(ORL x x) -> (Copy x) +(ORW x x) -> (Copy x) +(ORB x x) -> (Copy x) +(XORQ x x) -> (MOVQconst [0]) +(XORL x x) -> (MOVLconst [0]) +(XORW x x) -> (MOVWconst [0]) +(XORB x x) -> (MOVBconst [0]) diff --git a/src/cmd/compile/internal/ssa/gen/generic.rules b/src/cmd/compile/internal/ssa/gen/generic.rules index 6a8952d6cb..9cc2f1b9ad 100644 --- a/src/cmd/compile/internal/ssa/gen/generic.rules +++ b/src/cmd/compile/internal/ssa/gen/generic.rules @@ -25,6 +25,14 @@ (Mul64 (Const64 [c]) (Const64 [d])) -> (Const64 [c*d]) (MulPtr (ConstPtr [c]) (ConstPtr [d])) -> (ConstPtr [c*d]) (IsInBounds (ConstPtr [c]) (ConstPtr [d])) -> (ConstPtr {inBounds(c,d)}) +(Eq64 x x) -> (ConstBool {true}) +(Eq32 x x) -> (ConstBool {true}) +(Eq16 x x) -> (ConstBool {true}) +(Eq8 x x) -> (ConstBool {true}) +(Neq64 x x) -> (ConstBool {false}) +(Neq32 x x) -> (ConstBool {false}) +(Neq16 x x) -> (ConstBool {false}) +(Neq8 x x) -> (ConstBool {false}) // tear apart slices // TODO: anything that generates a slice needs to go in here. diff --git a/src/cmd/compile/internal/ssa/gen/rulegen.go b/src/cmd/compile/internal/ssa/gen/rulegen.go index 03cbf7cd57..4b3775ca98 100644 --- a/src/cmd/compile/internal/ssa/gen/rulegen.go +++ b/src/cmd/compile/internal/ssa/gen/rulegen.go @@ -285,12 +285,12 @@ func genMatch(w io.Writer, arch arch, match, fail string) { func genMatch0(w io.Writer, arch arch, match, v, fail string, m map[string]string, top bool) { if match[0] != '(' { - if x, ok := m[match]; ok { + if _, ok := m[match]; ok { // variable already has a definition. Check whether // the old definition and the new definition match. // For example, (add x x). Equality is just pointer equality // on Values (so cse is important to do before lowering). - fmt.Fprintf(w, "if %s != %s %s", v, x, fail) + fmt.Fprintf(w, "if %s != %s %s", v, match, fail) return } // remember that this variable references the given value diff --git a/src/cmd/compile/internal/ssa/rewriteAMD64.go b/src/cmd/compile/internal/ssa/rewriteAMD64.go index 9e4f133f3b..9157989035 100644 --- a/src/cmd/compile/internal/ssa/rewriteAMD64.go +++ b/src/cmd/compile/internal/ssa/rewriteAMD64.go @@ -45,6 +45,26 @@ func rewriteValueAMD64(v *Value, config *Config) bool { goto end28aa1a4abe7e1abcdd64135e9967d39d end28aa1a4abe7e1abcdd64135e9967d39d: ; + // match: (ADDB x (NEGB y)) + // cond: + // result: (SUBB x y) + { + x := v.Args[0] + if v.Args[1].Op != OpAMD64NEGB { + goto end9464509b8874ffb00b43b843da01f0bc + } + y := v.Args[1].Args[0] + v.Op = OpAMD64SUBB + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.AddArg(x) + v.AddArg(y) + return true + } + goto end9464509b8874ffb00b43b843da01f0bc + end9464509b8874ffb00b43b843da01f0bc: + ; case OpAMD64ADDBconst: // match: (ADDBconst [c] (MOVBconst [d])) // cond: @@ -65,6 +85,27 @@ func rewriteValueAMD64(v *Value, config *Config) bool { goto enda9b1e9e31ccdf0af5f4fe57bf4b1343f enda9b1e9e31ccdf0af5f4fe57bf4b1343f: ; + // match: (ADDBconst [c] (ADDBconst [d] x)) + // cond: + // result: (ADDBconst [c+d] x) + { + c := v.AuxInt + if v.Args[0].Op != OpAMD64ADDBconst { + goto end9b1e6890adbf9d9e447d591b4148cbd0 + } + d := v.Args[0].AuxInt + x := v.Args[0].Args[0] + v.Op = OpAMD64ADDBconst + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.AuxInt = c + d + v.AddArg(x) + return true + } + goto end9b1e6890adbf9d9e447d591b4148cbd0 + end9b1e6890adbf9d9e447d591b4148cbd0: + ; case OpAMD64ADDL: // match: (ADDL x (MOVLconst [c])) // cond: @@ -106,6 +147,26 @@ func rewriteValueAMD64(v *Value, config *Config) bool { goto end739561e08a561e26ce3634dc0d5ec733 end739561e08a561e26ce3634dc0d5ec733: ; + // match: (ADDL x (NEGL y)) + // cond: + // result: (SUBL x y) + { + x := v.Args[0] + if v.Args[1].Op != OpAMD64NEGL { + goto end9596df31f2685a49df67c6fb912a521d + } + y := v.Args[1].Args[0] + v.Op = OpAMD64SUBL + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.AddArg(x) + v.AddArg(y) + return true + } + goto end9596df31f2685a49df67c6fb912a521d + end9596df31f2685a49df67c6fb912a521d: + ; case OpAMD64ADDLconst: // match: (ADDLconst [c] (MOVLconst [d])) // cond: @@ -126,6 +187,27 @@ func rewriteValueAMD64(v *Value, config *Config) bool { goto ende04850e987890abf1d66199042a19c23 ende04850e987890abf1d66199042a19c23: ; + // match: (ADDLconst [c] (ADDLconst [d] x)) + // cond: + // result: (ADDLconst [c+d] x) + { + c := v.AuxInt + if v.Args[0].Op != OpAMD64ADDLconst { + goto endf1dd8673b2fef4950aec87aa7523a236 + } + d := v.Args[0].AuxInt + x := v.Args[0].Args[0] + v.Op = OpAMD64ADDLconst + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.AuxInt = c + d + v.AddArg(x) + return true + } + goto endf1dd8673b2fef4950aec87aa7523a236 + endf1dd8673b2fef4950aec87aa7523a236: + ; case OpAMD64ADDQ: // match: (ADDQ x (MOVQconst [c])) // cond: is32Bit(c) @@ -196,6 +278,26 @@ func rewriteValueAMD64(v *Value, config *Config) bool { goto endc02313d35a0525d1d680cd58992e820d endc02313d35a0525d1d680cd58992e820d: ; + // match: (ADDQ x (NEGQ y)) + // cond: + // result: (SUBQ x y) + { + x := v.Args[0] + if v.Args[1].Op != OpAMD64NEGQ { + goto endec8f899c6e175a0147a90750f9bfe0a2 + } + y := v.Args[1].Args[0] + v.Op = OpAMD64SUBQ + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.AddArg(x) + v.AddArg(y) + return true + } + goto endec8f899c6e175a0147a90750f9bfe0a2 + endec8f899c6e175a0147a90750f9bfe0a2: + ; case OpAMD64ADDQconst: // match: (ADDQconst [c] (LEAQ8 [d] x y)) // cond: @@ -257,6 +359,27 @@ func rewriteValueAMD64(v *Value, config *Config) bool { goto end09dc54395b4e96e8332cf8e4e7481c52 end09dc54395b4e96e8332cf8e4e7481c52: ; + // match: (ADDQconst [c] (ADDQconst [d] x)) + // cond: + // result: (ADDQconst [c+d] x) + { + c := v.AuxInt + if v.Args[0].Op != OpAMD64ADDQconst { + goto endd4cb539641f0dc40bfd0cb7fbb9b0405 + } + d := v.Args[0].AuxInt + x := v.Args[0].Args[0] + v.Op = OpAMD64ADDQconst + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.AuxInt = c + d + v.AddArg(x) + return true + } + goto endd4cb539641f0dc40bfd0cb7fbb9b0405 + endd4cb539641f0dc40bfd0cb7fbb9b0405: + ; case OpAMD64ADDW: // match: (ADDW x (MOVWconst [c])) // cond: @@ -298,6 +421,26 @@ func rewriteValueAMD64(v *Value, config *Config) bool { goto ende3aede99966f388afc624f9e86676fd2 ende3aede99966f388afc624f9e86676fd2: ; + // match: (ADDW x (NEGW y)) + // cond: + // result: (SUBW x y) + { + x := v.Args[0] + if v.Args[1].Op != OpAMD64NEGW { + goto end55cf2af0d75f3ec413528eeb799e94d5 + } + y := v.Args[1].Args[0] + v.Op = OpAMD64SUBW + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.AddArg(x) + v.AddArg(y) + return true + } + goto end55cf2af0d75f3ec413528eeb799e94d5 + end55cf2af0d75f3ec413528eeb799e94d5: + ; case OpAMD64ADDWconst: // match: (ADDWconst [c] (MOVWconst [d])) // cond: @@ -318,6 +461,27 @@ func rewriteValueAMD64(v *Value, config *Config) bool { goto end32541920f2f5a920dfae41d8ebbef00f end32541920f2f5a920dfae41d8ebbef00f: ; + // match: (ADDWconst [c] (ADDWconst [d] x)) + // cond: + // result: (ADDWconst [c+d] x) + { + c := v.AuxInt + if v.Args[0].Op != OpAMD64ADDWconst { + goto end73944f6ddda7e4c050f11d17484ff9a5 + } + d := v.Args[0].AuxInt + x := v.Args[0].Args[0] + v.Op = OpAMD64ADDWconst + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.AuxInt = c + d + v.AddArg(x) + return true + } + goto end73944f6ddda7e4c050f11d17484ff9a5 + end73944f6ddda7e4c050f11d17484ff9a5: + ; case OpAMD64ANDB: // match: (ANDB x (MOVBconst [c])) // cond: @@ -359,6 +523,24 @@ func rewriteValueAMD64(v *Value, config *Config) bool { goto end4068edac2ae0f354cf581db210288b98 end4068edac2ae0f354cf581db210288b98: ; + // match: (ANDB x x) + // cond: + // result: (Copy x) + { + x := v.Args[0] + if v.Args[1] != x { + goto end1c1e017efac06c84c72f2d09d6afadc0 + } + v.Op = OpCopy + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.AddArg(x) + return true + } + goto end1c1e017efac06c84c72f2d09d6afadc0 + end1c1e017efac06c84c72f2d09d6afadc0: + ; case OpAMD64ANDBconst: // match: (ANDBconst [c] _) // cond: int8(c)==0 @@ -457,6 +639,24 @@ func rewriteValueAMD64(v *Value, config *Config) bool { goto end0529ba323d9b6f15c41add401ef67959 end0529ba323d9b6f15c41add401ef67959: ; + // match: (ANDL x x) + // cond: + // result: (Copy x) + { + x := v.Args[0] + if v.Args[1] != x { + goto end0ff7ad77f6811c422b0b588f48474ddc + } + v.Op = OpCopy + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.AddArg(x) + return true + } + goto end0ff7ad77f6811c422b0b588f48474ddc + end0ff7ad77f6811c422b0b588f48474ddc: + ; case OpAMD64ANDLconst: // match: (ANDLconst [c] _) // cond: int32(c)==0 @@ -561,6 +761,24 @@ func rewriteValueAMD64(v *Value, config *Config) bool { goto end3035a3bf650b708705fd27dd857ab0a4 end3035a3bf650b708705fd27dd857ab0a4: ; + // match: (ANDQ x x) + // cond: + // result: (Copy x) + { + x := v.Args[0] + if v.Args[1] != x { + goto endb54d87d7a12ba29a9d19b808319ab055 + } + v.Op = OpCopy + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.AddArg(x) + return true + } + goto endb54d87d7a12ba29a9d19b808319ab055 + endb54d87d7a12ba29a9d19b808319ab055: + ; case OpAMD64ANDQconst: // match: (ANDQconst [0] _) // cond: @@ -657,6 +875,24 @@ func rewriteValueAMD64(v *Value, config *Config) bool { goto endea2a25eb525a5dbf6d5132d84ea4e7a5 endea2a25eb525a5dbf6d5132d84ea4e7a5: ; + // match: (ANDW x x) + // cond: + // result: (Copy x) + { + x := v.Args[0] + if v.Args[1] != x { + goto end08c49eea4ac769acc212ebd833934be8 + } + v.Op = OpCopy + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.AddArg(x) + return true + } + goto end08c49eea4ac769acc212ebd833934be8 + end08c49eea4ac769acc212ebd833934be8: + ; case OpAMD64ANDWconst: // match: (ANDWconst [c] _) // cond: int16(c)==0 @@ -3504,6 +3740,82 @@ func rewriteValueAMD64(v *Value, config *Config) bool { goto endbbedad106c011a93243e2062afdcc75f endbbedad106c011a93243e2062afdcc75f: ; + case OpAMD64NEGB: + // match: (NEGB (MOVBconst [c])) + // cond: + // result: (MOVBconst [-c]) + { + if v.Args[0].Op != OpAMD64MOVBconst { + goto end36d0300ba9eab8c9da86246ff653ca96 + } + c := v.Args[0].AuxInt + v.Op = OpAMD64MOVBconst + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.AuxInt = -c + return true + } + goto end36d0300ba9eab8c9da86246ff653ca96 + end36d0300ba9eab8c9da86246ff653ca96: + ; + case OpAMD64NEGL: + // match: (NEGL (MOVLconst [c])) + // cond: + // result: (MOVLconst [-c]) + { + if v.Args[0].Op != OpAMD64MOVLconst { + goto end7a245ec67e56bd51911e5ba2d0aa0a16 + } + c := v.Args[0].AuxInt + v.Op = OpAMD64MOVLconst + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.AuxInt = -c + return true + } + goto end7a245ec67e56bd51911e5ba2d0aa0a16 + end7a245ec67e56bd51911e5ba2d0aa0a16: + ; + case OpAMD64NEGQ: + // match: (NEGQ (MOVQconst [c])) + // cond: + // result: (MOVQconst [-c]) + { + if v.Args[0].Op != OpAMD64MOVQconst { + goto end04ddd98bc6724ecb85c80c2a4e2bca5a + } + c := v.Args[0].AuxInt + v.Op = OpAMD64MOVQconst + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.AuxInt = -c + return true + } + goto end04ddd98bc6724ecb85c80c2a4e2bca5a + end04ddd98bc6724ecb85c80c2a4e2bca5a: + ; + case OpAMD64NEGW: + // match: (NEGW (MOVWconst [c])) + // cond: + // result: (MOVWconst [-c]) + { + if v.Args[0].Op != OpAMD64MOVWconst { + goto end1db6636f0a51848d8a34f6561ecfe7ae + } + c := v.Args[0].AuxInt + v.Op = OpAMD64MOVWconst + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.AuxInt = -c + return true + } + goto end1db6636f0a51848d8a34f6561ecfe7ae + end1db6636f0a51848d8a34f6561ecfe7ae: + ; case OpAMD64NOTB: // match: (NOTB (MOVBconst [c])) // cond: @@ -3807,6 +4119,24 @@ func rewriteValueAMD64(v *Value, config *Config) bool { goto end70b43d531e2097a4f6293f66256a642e end70b43d531e2097a4f6293f66256a642e: ; + // match: (ORB x x) + // cond: + // result: (Copy x) + { + x := v.Args[0] + if v.Args[1] != x { + goto endd53ede4886d67f4b4ae970316a2febb4 + } + v.Op = OpCopy + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.AddArg(x) + return true + } + goto endd53ede4886d67f4b4ae970316a2febb4 + endd53ede4886d67f4b4ae970316a2febb4: + ; case OpAMD64ORBconst: // match: (ORBconst [c] x) // cond: int8(c)==0 @@ -3905,6 +4235,24 @@ func rewriteValueAMD64(v *Value, config *Config) bool { goto enda5bc49524a0cbd2241f792837d0a48a8 enda5bc49524a0cbd2241f792837d0a48a8: ; + // match: (ORL x x) + // cond: + // result: (Copy x) + { + x := v.Args[0] + if v.Args[1] != x { + goto end556b9151cacb9db2803373ce10829b2a + } + v.Op = OpCopy + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.AddArg(x) + return true + } + goto end556b9151cacb9db2803373ce10829b2a + end556b9151cacb9db2803373ce10829b2a: + ; case OpAMD64ORLconst: // match: (ORLconst [c] x) // cond: int32(c)==0 @@ -4009,6 +4357,24 @@ func rewriteValueAMD64(v *Value, config *Config) bool { goto end010afbebcd314e288509d79a16a6d5cc end010afbebcd314e288509d79a16a6d5cc: ; + // match: (ORQ x x) + // cond: + // result: (Copy x) + { + x := v.Args[0] + if v.Args[1] != x { + goto endcad306e115ea011a2a70f4e4e5440de4 + } + v.Op = OpCopy + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.AddArg(x) + return true + } + goto endcad306e115ea011a2a70f4e4e5440de4 + endcad306e115ea011a2a70f4e4e5440de4: + ; case OpAMD64ORQconst: // match: (ORQconst [0] x) // cond: @@ -4105,6 +4471,24 @@ func rewriteValueAMD64(v *Value, config *Config) bool { goto end96405942c9ceb5fcb0ddb85a8709d015 end96405942c9ceb5fcb0ddb85a8709d015: ; + // match: (ORW x x) + // cond: + // result: (Copy x) + { + x := v.Args[0] + if v.Args[1] != x { + goto end7c69794f4a3a6ada00bd868f743d86f8 + } + v.Op = OpCopy + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.AddArg(x) + return true + } + goto end7c69794f4a3a6ada00bd868f743d86f8 + end7c69794f4a3a6ada00bd868f743d86f8: + ; case OpAMD64ORWconst: // match: (ORWconst [c] x) // cond: int16(c)==0 @@ -5963,6 +6347,24 @@ func rewriteValueAMD64(v *Value, config *Config) bool { goto endc288755d69b04d24a6aac32a73956411 endc288755d69b04d24a6aac32a73956411: ; + // match: (SUBB x x) + // cond: + // result: (MOVBconst [0]) + { + x := v.Args[0] + if v.Args[1] != x { + goto ende8904403d937d95b0d6133d3ec92bb45 + } + v.Op = OpAMD64MOVBconst + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.AuxInt = 0 + return true + } + goto ende8904403d937d95b0d6133d3ec92bb45 + ende8904403d937d95b0d6133d3ec92bb45: + ; case OpAMD64SUBBconst: // match: (SUBBconst [c] (MOVBconst [d])) // cond: @@ -5983,6 +6385,27 @@ func rewriteValueAMD64(v *Value, config *Config) bool { goto end0e2d5c3e3c02001a20d5433daa9e8317 end0e2d5c3e3c02001a20d5433daa9e8317: ; + // match: (SUBBconst [c] (SUBBconst [d] x)) + // cond: + // result: (ADDBconst [c-d] x) + { + c := v.AuxInt + if v.Args[0].Op != OpAMD64SUBBconst { + goto end48eccb421dfe0c678ea9c47113521d5a + } + d := v.Args[0].AuxInt + x := v.Args[0].Args[0] + v.Op = OpAMD64ADDBconst + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.AuxInt = c - d + v.AddArg(x) + return true + } + goto end48eccb421dfe0c678ea9c47113521d5a + end48eccb421dfe0c678ea9c47113521d5a: + ; case OpAMD64SUBL: // match: (SUBL x (MOVLconst [c])) // cond: @@ -6027,6 +6450,24 @@ func rewriteValueAMD64(v *Value, config *Config) bool { goto endb0efe6e15ec20486b849534a00483ae2 endb0efe6e15ec20486b849534a00483ae2: ; + // match: (SUBL x x) + // cond: + // result: (MOVLconst [0]) + { + x := v.Args[0] + if v.Args[1] != x { + goto end332f1f641f875c69bea7289191e69133 + } + v.Op = OpAMD64MOVLconst + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.AuxInt = 0 + return true + } + goto end332f1f641f875c69bea7289191e69133 + end332f1f641f875c69bea7289191e69133: + ; case OpAMD64SUBLconst: // match: (SUBLconst [c] (MOVLconst [d])) // cond: @@ -6047,6 +6488,27 @@ func rewriteValueAMD64(v *Value, config *Config) bool { goto endbe7466f3c09d9645544bdfc44c37c922 endbe7466f3c09d9645544bdfc44c37c922: ; + // match: (SUBLconst [c] (SUBLconst [d] x)) + // cond: + // result: (ADDLconst [c-d] x) + { + c := v.AuxInt + if v.Args[0].Op != OpAMD64SUBLconst { + goto endb5106962a865bc4654b170c2e29a72c4 + } + d := v.Args[0].AuxInt + x := v.Args[0].Args[0] + v.Op = OpAMD64ADDLconst + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.AuxInt = c - d + v.AddArg(x) + return true + } + goto endb5106962a865bc4654b170c2e29a72c4 + endb5106962a865bc4654b170c2e29a72c4: + ; case OpAMD64SUBQ: // match: (SUBQ x (MOVQconst [c])) // cond: is32Bit(c) @@ -6097,6 +6559,24 @@ func rewriteValueAMD64(v *Value, config *Config) bool { goto end8beb96de3efee9206d1bd4b7d777d2cb end8beb96de3efee9206d1bd4b7d777d2cb: ; + // match: (SUBQ x x) + // cond: + // result: (MOVQconst [0]) + { + x := v.Args[0] + if v.Args[1] != x { + goto endd87d1d839d2dc54d9c90fa4f73383480 + } + v.Op = OpAMD64MOVQconst + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.AuxInt = 0 + return true + } + goto endd87d1d839d2dc54d9c90fa4f73383480 + endd87d1d839d2dc54d9c90fa4f73383480: + ; case OpAMD64SUBQconst: // match: (SUBQconst [c] (MOVQconst [d])) // cond: @@ -6117,6 +6597,27 @@ func rewriteValueAMD64(v *Value, config *Config) bool { goto end96c09479fb3c043e875d89d3eb92f1d8 end96c09479fb3c043e875d89d3eb92f1d8: ; + // match: (SUBQconst [c] (SUBQconst [d] x)) + // cond: + // result: (ADDQconst [c-d] x) + { + c := v.AuxInt + if v.Args[0].Op != OpAMD64SUBQconst { + goto enddd9d61b404480adb40cfd7fedd7e5ec4 + } + d := v.Args[0].AuxInt + x := v.Args[0].Args[0] + v.Op = OpAMD64ADDQconst + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.AuxInt = c - d + v.AddArg(x) + return true + } + goto enddd9d61b404480adb40cfd7fedd7e5ec4 + enddd9d61b404480adb40cfd7fedd7e5ec4: + ; case OpAMD64SUBW: // match: (SUBW x (MOVWconst [c])) // cond: @@ -6161,6 +6662,24 @@ func rewriteValueAMD64(v *Value, config *Config) bool { goto end44d23f7e65a4b1c42d0e6463f8e493b6 end44d23f7e65a4b1c42d0e6463f8e493b6: ; + // match: (SUBW x x) + // cond: + // result: (MOVWconst [0]) + { + x := v.Args[0] + if v.Args[1] != x { + goto endb970e7c318d04a1afe1dfe08a7ca0d9c + } + v.Op = OpAMD64MOVWconst + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.AuxInt = 0 + return true + } + goto endb970e7c318d04a1afe1dfe08a7ca0d9c + endb970e7c318d04a1afe1dfe08a7ca0d9c: + ; case OpAMD64SUBWconst: // match: (SUBWconst [c] (MOVWconst [d])) // cond: @@ -6181,6 +6700,27 @@ func rewriteValueAMD64(v *Value, config *Config) bool { goto end0e5079577fcf00f5925291dbd68306aa end0e5079577fcf00f5925291dbd68306aa: ; + // match: (SUBWconst [c] (SUBWconst [d] x)) + // cond: + // result: (ADDWconst [c-d] x) + { + c := v.AuxInt + if v.Args[0].Op != OpAMD64SUBWconst { + goto endb628696cf5b329d03782b8093093269b + } + d := v.Args[0].AuxInt + x := v.Args[0].Args[0] + v.Op = OpAMD64ADDWconst + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.AuxInt = c - d + v.AddArg(x) + return true + } + goto endb628696cf5b329d03782b8093093269b + endb628696cf5b329d03782b8093093269b: + ; case OpSignExt16to32: // match: (SignExt16to32 x) // cond: @@ -6617,6 +7157,24 @@ func rewriteValueAMD64(v *Value, config *Config) bool { goto endb02a07d9dc7b802c59f013116e952f3f endb02a07d9dc7b802c59f013116e952f3f: ; + // match: (XORB x x) + // cond: + // result: (MOVBconst [0]) + { + x := v.Args[0] + if v.Args[1] != x { + goto end2afddc39503d04d572a3a07878f6c9c9 + } + v.Op = OpAMD64MOVBconst + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.AuxInt = 0 + return true + } + goto end2afddc39503d04d572a3a07878f6c9c9 + end2afddc39503d04d572a3a07878f6c9c9: + ; case OpAMD64XORBconst: // match: (XORBconst [c] (MOVBconst [d])) // cond: @@ -6678,6 +7236,24 @@ func rewriteValueAMD64(v *Value, config *Config) bool { goto end9c1a0af00eeadd8aa325e55f1f3fb89c end9c1a0af00eeadd8aa325e55f1f3fb89c: ; + // match: (XORL x x) + // cond: + // result: (MOVLconst [0]) + { + x := v.Args[0] + if v.Args[1] != x { + goto end7bcf9cfeb69a0d7647389124eb53ce2a + } + v.Op = OpAMD64MOVLconst + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.AuxInt = 0 + return true + } + goto end7bcf9cfeb69a0d7647389124eb53ce2a + end7bcf9cfeb69a0d7647389124eb53ce2a: + ; case OpAMD64XORLconst: // match: (XORLconst [c] (MOVLconst [d])) // cond: @@ -6745,6 +7321,24 @@ func rewriteValueAMD64(v *Value, config *Config) bool { goto endd221a7e3daaaaa29ee385ad36e061b57 endd221a7e3daaaaa29ee385ad36e061b57: ; + // match: (XORQ x x) + // cond: + // result: (MOVQconst [0]) + { + x := v.Args[0] + if v.Args[1] != x { + goto end10575a5d711cf14e6d4dffbb0e8dfaeb + } + v.Op = OpAMD64MOVQconst + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.AuxInt = 0 + return true + } + goto end10575a5d711cf14e6d4dffbb0e8dfaeb + end10575a5d711cf14e6d4dffbb0e8dfaeb: + ; case OpAMD64XORQconst: // match: (XORQconst [c] (MOVQconst [d])) // cond: @@ -6806,6 +7400,24 @@ func rewriteValueAMD64(v *Value, config *Config) bool { goto end51ee62a06d4301e5a4aed7a6639b1d53 end51ee62a06d4301e5a4aed7a6639b1d53: ; + // match: (XORW x x) + // cond: + // result: (MOVWconst [0]) + { + x := v.Args[0] + if v.Args[1] != x { + goto end07f332e857be0c2707797ed480a2faf4 + } + v.Op = OpAMD64MOVWconst + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.AuxInt = 0 + return true + } + goto end07f332e857be0c2707797ed480a2faf4 + end07f332e857be0c2707797ed480a2faf4: + ; case OpAMD64XORWconst: // match: (XORWconst [c] (MOVWconst [d])) // cond: diff --git a/src/cmd/compile/internal/ssa/rewritegeneric.go b/src/cmd/compile/internal/ssa/rewritegeneric.go index 7d889b89f1..17608d71c4 100644 --- a/src/cmd/compile/internal/ssa/rewritegeneric.go +++ b/src/cmd/compile/internal/ssa/rewritegeneric.go @@ -102,6 +102,82 @@ func rewriteValuegeneric(v *Value, config *Config) bool { goto end68cc91679848c7c30bd8b0a8ed533843 end68cc91679848c7c30bd8b0a8ed533843: ; + case OpEq16: + // match: (Eq16 x x) + // cond: + // result: (ConstBool {true}) + { + x := v.Args[0] + if v.Args[1] != x { + goto enda503589f9b617e708a5ad3ddb047809f + } + v.Op = OpConstBool + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.Aux = true + return true + } + goto enda503589f9b617e708a5ad3ddb047809f + enda503589f9b617e708a5ad3ddb047809f: + ; + case OpEq32: + // match: (Eq32 x x) + // cond: + // result: (ConstBool {true}) + { + x := v.Args[0] + if v.Args[1] != x { + goto endc94ae3b97d0090257b02152e437b3e17 + } + v.Op = OpConstBool + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.Aux = true + return true + } + goto endc94ae3b97d0090257b02152e437b3e17 + endc94ae3b97d0090257b02152e437b3e17: + ; + case OpEq64: + // match: (Eq64 x x) + // cond: + // result: (ConstBool {true}) + { + x := v.Args[0] + if v.Args[1] != x { + goto end4d21cead60174989467a9c8202dbb91d + } + v.Op = OpConstBool + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.Aux = true + return true + } + goto end4d21cead60174989467a9c8202dbb91d + end4d21cead60174989467a9c8202dbb91d: + ; + case OpEq8: + // match: (Eq8 x x) + // cond: + // result: (ConstBool {true}) + { + x := v.Args[0] + if v.Args[1] != x { + goto end73dce8bba164e4f4a1dd701bf8cfb362 + } + v.Op = OpConstBool + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.Aux = true + return true + } + goto end73dce8bba164e4f4a1dd701bf8cfb362 + end73dce8bba164e4f4a1dd701bf8cfb362: + ; case OpEqFat: // match: (EqFat x y) // cond: x.Op == OpConstNil && y.Op != OpConstNil @@ -256,6 +332,82 @@ func rewriteValuegeneric(v *Value, config *Config) bool { goto end808c190f346658bb1ad032bf37a1059f end808c190f346658bb1ad032bf37a1059f: ; + case OpNeq16: + // match: (Neq16 x x) + // cond: + // result: (ConstBool {false}) + { + x := v.Args[0] + if v.Args[1] != x { + goto end192755dd3c2be992e9d3deb53794a8d2 + } + v.Op = OpConstBool + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.Aux = false + return true + } + goto end192755dd3c2be992e9d3deb53794a8d2 + end192755dd3c2be992e9d3deb53794a8d2: + ; + case OpNeq32: + // match: (Neq32 x x) + // cond: + // result: (ConstBool {false}) + { + x := v.Args[0] + if v.Args[1] != x { + goto endeb23619fc85950a8df7b31126252c4dd + } + v.Op = OpConstBool + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.Aux = false + return true + } + goto endeb23619fc85950a8df7b31126252c4dd + endeb23619fc85950a8df7b31126252c4dd: + ; + case OpNeq64: + // match: (Neq64 x x) + // cond: + // result: (ConstBool {false}) + { + x := v.Args[0] + if v.Args[1] != x { + goto endfc6eea780fb4056afb9e4287076da60c + } + v.Op = OpConstBool + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.Aux = false + return true + } + goto endfc6eea780fb4056afb9e4287076da60c + endfc6eea780fb4056afb9e4287076da60c: + ; + case OpNeq8: + // match: (Neq8 x x) + // cond: + // result: (ConstBool {false}) + { + x := v.Args[0] + if v.Args[1] != x { + goto endcccf700d93c6d57765b80f92f7b3fa81 + } + v.Op = OpConstBool + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.Aux = false + return true + } + goto endcccf700d93c6d57765b80f92f7b3fa81 + endcccf700d93c6d57765b80f92f7b3fa81: + ; case OpNeqFat: // match: (NeqFat x y) // cond: x.Op == OpConstNil && y.Op != OpConstNil @@ -422,7 +574,7 @@ func rewriteValuegeneric(v *Value, config *Config) bool { t := v.Args[1].Type src := v.Args[1].Args[0] mem := v.Args[1].Args[1] - if v.Args[2] != v.Args[1].Args[1] { + if v.Args[2] != mem { goto end324ffb6d2771808da4267f62c854e9c8 } if !(t.Size() > 8) {