From d2150c83284c06ef3d7e106ca52160a8d1caeca2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandru=20Mo=C8=99oi?= Date: Thu, 6 Aug 2015 18:33:49 +0200 Subject: [PATCH] [dev.ssa] cmd/compile/internal/ssa/gen: generate better code when right-shifting with a constant. The lowering rules were missing the non-64 bit case. SBBLcarrymask can be folded to a int32 integer whose type has a smaller bit size. Without the new AND rules the following would be generated: v19 = MOVLconst [-1] : SI v20 = ANDB v18 v19 : DI which is obviously a NOP. Fixes #12022 Change-Id: I5f4209f78edc0f118e5b9b2908739f09cefebca4 Reviewed-on: https://go-review.googlesource.com/13301 Reviewed-by: Keith Randall --- src/cmd/compile/internal/ssa/gen/AMD64.rules | 12 + src/cmd/compile/internal/ssa/rewriteAMD64.go | 281 +++++++++++++++++++ 2 files changed, 293 insertions(+) diff --git a/src/cmd/compile/internal/ssa/gen/AMD64.rules b/src/cmd/compile/internal/ssa/gen/AMD64.rules index ea2311cae0..2a54bb075a 100644 --- a/src/cmd/compile/internal/ssa/gen/AMD64.rules +++ b/src/cmd/compile/internal/ssa/gen/AMD64.rules @@ -279,8 +279,12 @@ (ANDQ (MOVQconst [c]) x) && is32Bit(c) -> (ANDQconst [c] x) (ANDL x (MOVLconst [c])) -> (ANDLconst [c] x) (ANDL (MOVLconst [c]) x) -> (ANDLconst [c] x) +(ANDW x (MOVLconst [c])) -> (ANDWconst [c] x) +(ANDW (MOVLconst [c]) x) -> (ANDWconst [c] x) (ANDW x (MOVWconst [c])) -> (ANDWconst [c] x) (ANDW (MOVWconst [c]) x) -> (ANDWconst [c] x) +(ANDB x (MOVLconst [c])) -> (ANDBconst [c] x) +(ANDB (MOVLconst [c]) x) -> (ANDBconst [c] x) (ANDB x (MOVBconst [c])) -> (ANDBconst [c] x) (ANDB (MOVBconst [c]) x) -> (ANDBconst [c] x) @@ -424,6 +428,14 @@ (SBBQcarrymask (CMPWconst [c] (MOVWconst [d]))) && !inBounds(int64(int16(d)), int64(int16(c))) -> (MOVQconst [0]) (SBBQcarrymask (CMPBconst [c] (MOVBconst [d]))) && inBounds(int64(int8(d)), int64(int8(c))) -> (MOVQconst [-1]) (SBBQcarrymask (CMPBconst [c] (MOVBconst [d]))) && !inBounds(int64(int8(d)), int64(int8(c))) -> (MOVQconst [0]) +(SBBLcarrymask (CMPQconst [c] (MOVQconst [d]))) && inBounds(d, c) -> (MOVLconst [-1]) +(SBBLcarrymask (CMPQconst [c] (MOVQconst [d]))) && !inBounds(d, c) -> (MOVLconst [0]) +(SBBLcarrymask (CMPLconst [c] (MOVLconst [d]))) && inBounds(int64(int32(d)), int64(int32(c))) -> (MOVLconst [-1]) +(SBBLcarrymask (CMPLconst [c] (MOVLconst [d]))) && !inBounds(int64(int32(d)), int64(int32(c))) -> (MOVLconst [0]) +(SBBLcarrymask (CMPWconst [c] (MOVWconst [d]))) && inBounds(int64(int16(d)), int64(int16(c))) -> (MOVLconst [-1]) +(SBBLcarrymask (CMPWconst [c] (MOVWconst [d]))) && !inBounds(int64(int16(d)), int64(int16(c))) -> (MOVLconst [0]) +(SBBLcarrymask (CMPBconst [c] (MOVBconst [d]))) && inBounds(int64(int8(d)), int64(int8(c))) -> (MOVLconst [-1]) +(SBBLcarrymask (CMPBconst [c] (MOVBconst [d]))) && !inBounds(int64(int8(d)), int64(int8(c))) -> (MOVLconst [0]) (ANDQconst [0] _) -> (MOVQconst [0]) (ANDLconst [c] _) && int32(c)==0 -> (MOVLconst [0]) (ANDWconst [c] _) && int16(c)==0 -> (MOVWconst [0]) diff --git a/src/cmd/compile/internal/ssa/rewriteAMD64.go b/src/cmd/compile/internal/ssa/rewriteAMD64.go index 4fa95a4726..bdcb99174e 100644 --- a/src/cmd/compile/internal/ssa/rewriteAMD64.go +++ b/src/cmd/compile/internal/ssa/rewriteAMD64.go @@ -484,6 +484,46 @@ func rewriteValueAMD64(v *Value, config *Config) bool { end73944f6ddda7e4c050f11d17484ff9a5: ; case OpAMD64ANDB: + // match: (ANDB x (MOVLconst [c])) + // cond: + // result: (ANDBconst [c] x) + { + x := v.Args[0] + if v.Args[1].Op != OpAMD64MOVLconst { + goto end01100cd255396e29bfdb130f4fbc9bbc + } + c := v.Args[1].AuxInt + v.Op = OpAMD64ANDBconst + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.AuxInt = c + v.AddArg(x) + return true + } + goto end01100cd255396e29bfdb130f4fbc9bbc + end01100cd255396e29bfdb130f4fbc9bbc: + ; + // match: (ANDB (MOVLconst [c]) x) + // cond: + // result: (ANDBconst [c] x) + { + if v.Args[0].Op != OpAMD64MOVLconst { + goto end70830ce2834dc5f8d786fa6789460926 + } + c := v.Args[0].AuxInt + x := v.Args[1] + v.Op = OpAMD64ANDBconst + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.AuxInt = c + v.AddArg(x) + return true + } + goto end70830ce2834dc5f8d786fa6789460926 + end70830ce2834dc5f8d786fa6789460926: + ; // match: (ANDB x (MOVBconst [c])) // cond: // result: (ANDBconst [c] x) @@ -836,6 +876,46 @@ func rewriteValueAMD64(v *Value, config *Config) bool { end67ca66494705b0345a5f22c710225292: ; case OpAMD64ANDW: + // match: (ANDW x (MOVLconst [c])) + // cond: + // result: (ANDWconst [c] x) + { + x := v.Args[0] + if v.Args[1].Op != OpAMD64MOVLconst { + goto endce6f557823ee2fdd7a8f47b6f925fc7c + } + c := v.Args[1].AuxInt + v.Op = OpAMD64ANDWconst + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.AuxInt = c + v.AddArg(x) + return true + } + goto endce6f557823ee2fdd7a8f47b6f925fc7c + endce6f557823ee2fdd7a8f47b6f925fc7c: + ; + // match: (ANDW (MOVLconst [c]) x) + // cond: + // result: (ANDWconst [c] x) + { + if v.Args[0].Op != OpAMD64MOVLconst { + goto endc46af0d9265c08b09f1f1fba24feda80 + } + c := v.Args[0].AuxInt + x := v.Args[1] + v.Op = OpAMD64ANDWconst + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.AuxInt = c + v.AddArg(x) + return true + } + goto endc46af0d9265c08b09f1f1fba24feda80 + endc46af0d9265c08b09f1f1fba24feda80: + ; // match: (ANDW x (MOVWconst [c])) // cond: // result: (ANDWconst [c] x) @@ -5766,6 +5846,207 @@ func rewriteValueAMD64(v *Value, config *Config) bool { goto endc46e3f211f94238f9a0aec3c498af490 endc46e3f211f94238f9a0aec3c498af490: ; + case OpAMD64SBBLcarrymask: + // match: (SBBLcarrymask (CMPQconst [c] (MOVQconst [d]))) + // cond: inBounds(d, c) + // result: (MOVLconst [-1]) + { + if v.Args[0].Op != OpAMD64CMPQconst { + goto enda9e02a887246381d02b3259b9df4050c + } + c := v.Args[0].AuxInt + if v.Args[0].Args[0].Op != OpAMD64MOVQconst { + goto enda9e02a887246381d02b3259b9df4050c + } + d := v.Args[0].Args[0].AuxInt + if !(inBounds(d, c)) { + goto enda9e02a887246381d02b3259b9df4050c + } + v.Op = OpAMD64MOVLconst + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.AuxInt = -1 + return true + } + goto enda9e02a887246381d02b3259b9df4050c + enda9e02a887246381d02b3259b9df4050c: + ; + // match: (SBBLcarrymask (CMPQconst [c] (MOVQconst [d]))) + // cond: !inBounds(d, c) + // result: (MOVLconst [0]) + { + if v.Args[0].Op != OpAMD64CMPQconst { + goto end3f8220527278b72a64148fcf9dc58bfe + } + c := v.Args[0].AuxInt + if v.Args[0].Args[0].Op != OpAMD64MOVQconst { + goto end3f8220527278b72a64148fcf9dc58bfe + } + d := v.Args[0].Args[0].AuxInt + if !(!inBounds(d, c)) { + goto end3f8220527278b72a64148fcf9dc58bfe + } + v.Op = OpAMD64MOVLconst + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.AuxInt = 0 + return true + } + goto end3f8220527278b72a64148fcf9dc58bfe + end3f8220527278b72a64148fcf9dc58bfe: + ; + // match: (SBBLcarrymask (CMPLconst [c] (MOVLconst [d]))) + // cond: inBounds(int64(int32(d)), int64(int32(c))) + // result: (MOVLconst [-1]) + { + if v.Args[0].Op != OpAMD64CMPLconst { + goto end880a2b9a12ed4f551bbd46473b9439bc + } + c := v.Args[0].AuxInt + if v.Args[0].Args[0].Op != OpAMD64MOVLconst { + goto end880a2b9a12ed4f551bbd46473b9439bc + } + d := v.Args[0].Args[0].AuxInt + if !(inBounds(int64(int32(d)), int64(int32(c)))) { + goto end880a2b9a12ed4f551bbd46473b9439bc + } + v.Op = OpAMD64MOVLconst + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.AuxInt = -1 + return true + } + goto end880a2b9a12ed4f551bbd46473b9439bc + end880a2b9a12ed4f551bbd46473b9439bc: + ; + // match: (SBBLcarrymask (CMPLconst [c] (MOVLconst [d]))) + // cond: !inBounds(int64(int32(d)), int64(int32(c))) + // result: (MOVLconst [0]) + { + if v.Args[0].Op != OpAMD64CMPLconst { + goto end3f08080e0f55d51afca2a131ed0c672e + } + c := v.Args[0].AuxInt + if v.Args[0].Args[0].Op != OpAMD64MOVLconst { + goto end3f08080e0f55d51afca2a131ed0c672e + } + d := v.Args[0].Args[0].AuxInt + if !(!inBounds(int64(int32(d)), int64(int32(c)))) { + goto end3f08080e0f55d51afca2a131ed0c672e + } + v.Op = OpAMD64MOVLconst + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.AuxInt = 0 + return true + } + goto end3f08080e0f55d51afca2a131ed0c672e + end3f08080e0f55d51afca2a131ed0c672e: + ; + // match: (SBBLcarrymask (CMPWconst [c] (MOVWconst [d]))) + // cond: inBounds(int64(int16(d)), int64(int16(c))) + // result: (MOVLconst [-1]) + { + if v.Args[0].Op != OpAMD64CMPWconst { + goto end91ed02166e0c0d696730e1704d0a682e + } + c := v.Args[0].AuxInt + if v.Args[0].Args[0].Op != OpAMD64MOVWconst { + goto end91ed02166e0c0d696730e1704d0a682e + } + d := v.Args[0].Args[0].AuxInt + if !(inBounds(int64(int16(d)), int64(int16(c)))) { + goto end91ed02166e0c0d696730e1704d0a682e + } + v.Op = OpAMD64MOVLconst + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.AuxInt = -1 + return true + } + goto end91ed02166e0c0d696730e1704d0a682e + end91ed02166e0c0d696730e1704d0a682e: + ; + // match: (SBBLcarrymask (CMPWconst [c] (MOVWconst [d]))) + // cond: !inBounds(int64(int16(d)), int64(int16(c))) + // result: (MOVLconst [0]) + { + if v.Args[0].Op != OpAMD64CMPWconst { + goto endc7edc3a13ec73ec4e6e87e7ab421a71a + } + c := v.Args[0].AuxInt + if v.Args[0].Args[0].Op != OpAMD64MOVWconst { + goto endc7edc3a13ec73ec4e6e87e7ab421a71a + } + d := v.Args[0].Args[0].AuxInt + if !(!inBounds(int64(int16(d)), int64(int16(c)))) { + goto endc7edc3a13ec73ec4e6e87e7ab421a71a + } + v.Op = OpAMD64MOVLconst + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.AuxInt = 0 + return true + } + goto endc7edc3a13ec73ec4e6e87e7ab421a71a + endc7edc3a13ec73ec4e6e87e7ab421a71a: + ; + // match: (SBBLcarrymask (CMPBconst [c] (MOVBconst [d]))) + // cond: inBounds(int64(int8(d)), int64(int8(c))) + // result: (MOVLconst [-1]) + { + if v.Args[0].Op != OpAMD64CMPBconst { + goto end0fe2997fc76ce00b1d496f7289ab345a + } + c := v.Args[0].AuxInt + if v.Args[0].Args[0].Op != OpAMD64MOVBconst { + goto end0fe2997fc76ce00b1d496f7289ab345a + } + d := v.Args[0].Args[0].AuxInt + if !(inBounds(int64(int8(d)), int64(int8(c)))) { + goto end0fe2997fc76ce00b1d496f7289ab345a + } + v.Op = OpAMD64MOVLconst + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.AuxInt = -1 + return true + } + goto end0fe2997fc76ce00b1d496f7289ab345a + end0fe2997fc76ce00b1d496f7289ab345a: + ; + // match: (SBBLcarrymask (CMPBconst [c] (MOVBconst [d]))) + // cond: !inBounds(int64(int8(d)), int64(int8(c))) + // result: (MOVLconst [0]) + { + if v.Args[0].Op != OpAMD64CMPBconst { + goto end3a07121fcc82f1a19da4226b07a757ce + } + c := v.Args[0].AuxInt + if v.Args[0].Args[0].Op != OpAMD64MOVBconst { + goto end3a07121fcc82f1a19da4226b07a757ce + } + d := v.Args[0].Args[0].AuxInt + if !(!inBounds(int64(int8(d)), int64(int8(c)))) { + goto end3a07121fcc82f1a19da4226b07a757ce + } + v.Op = OpAMD64MOVLconst + v.AuxInt = 0 + v.Aux = nil + v.resetArgs() + v.AuxInt = 0 + return true + } + goto end3a07121fcc82f1a19da4226b07a757ce + end3a07121fcc82f1a19da4226b07a757ce: + ; case OpAMD64SBBQcarrymask: // match: (SBBQcarrymask (CMPQconst [c] (MOVQconst [d]))) // cond: inBounds(d, c)