diff --git a/src/cmd/compile/internal/gc/asm_test.go b/src/cmd/compile/internal/gc/asm_test.go index 9eb31e152a2..29ed0739cff 100644 --- a/src/cmd/compile/internal/gc/asm_test.go +++ b/src/cmd/compile/internal/gc/asm_test.go @@ -234,6 +234,212 @@ func f(t *T) { []string{"\tMOVQ\t\\$0, \\(.*\\)", "\tMOVQ\t\\$0, 8\\(.*\\)", "\tMOVQ\t\\$0, 16\\(.*\\)"}, }, // TODO: add a test for *t = T{3,4,5} when we fix that. + + // Rotate tests + {"amd64", "linux", ` + func f(x uint64) uint64 { + return x<<7 | x>>57 + } +`, + []string{"\tROLQ\t[$]7,"}, + }, + {"amd64", "linux", ` + func f(x uint64) uint64 { + return x<<7 + x>>57 + } +`, + []string{"\tROLQ\t[$]7,"}, + }, + {"amd64", "linux", ` + func f(x uint64) uint64 { + return x<<7 ^ x>>57 + } +`, + []string{"\tROLQ\t[$]7,"}, + }, + {"amd64", "linux", ` + func f(x uint32) uint32 { + return x<<7 + x>>25 + } +`, + []string{"\tROLL\t[$]7,"}, + }, + {"amd64", "linux", ` + func f(x uint32) uint32 { + return x<<7 | x>>25 + } +`, + []string{"\tROLL\t[$]7,"}, + }, + {"amd64", "linux", ` + func f(x uint32) uint32 { + return x<<7 ^ x>>25 + } +`, + []string{"\tROLL\t[$]7,"}, + }, + {"amd64", "linux", ` + func f(x uint16) uint16 { + return x<<7 + x>>9 + } +`, + []string{"\tROLW\t[$]7,"}, + }, + {"amd64", "linux", ` + func f(x uint16) uint16 { + return x<<7 | x>>9 + } +`, + []string{"\tROLW\t[$]7,"}, + }, + {"amd64", "linux", ` + func f(x uint16) uint16 { + return x<<7 ^ x>>9 + } +`, + []string{"\tROLW\t[$]7,"}, + }, + {"amd64", "linux", ` + func f(x uint8) uint8 { + return x<<7 + x>>1 + } +`, + []string{"\tROLB\t[$]7,"}, + }, + {"amd64", "linux", ` + func f(x uint8) uint8 { + return x<<7 | x>>1 + } +`, + []string{"\tROLB\t[$]7,"}, + }, + {"amd64", "linux", ` + func f(x uint8) uint8 { + return x<<7 ^ x>>1 + } +`, + []string{"\tROLB\t[$]7,"}, + }, + + {"arm", "linux", ` + func f(x uint32) uint32 { + return x<<7 + x>>25 + } +`, + []string{"\tMOVW\tR[0-9]+@>25,"}, + }, + {"arm", "linux", ` + func f(x uint32) uint32 { + return x<<7 | x>>25 + } +`, + []string{"\tMOVW\tR[0-9]+@>25,"}, + }, + {"arm", "linux", ` + func f(x uint32) uint32 { + return x<<7 ^ x>>25 + } +`, + []string{"\tMOVW\tR[0-9]+@>25,"}, + }, + + {"arm64", "linux", ` + func f(x uint64) uint64 { + return x<<7 + x>>57 + } +`, + []string{"\tROR\t[$]57,"}, + }, + {"arm64", "linux", ` + func f(x uint64) uint64 { + return x<<7 | x>>57 + } +`, + []string{"\tROR\t[$]57,"}, + }, + {"arm64", "linux", ` + func f(x uint64) uint64 { + return x<<7 ^ x>>57 + } +`, + []string{"\tROR\t[$]57,"}, + }, + {"arm64", "linux", ` + func f(x uint32) uint32 { + return x<<7 + x>>25 + } +`, + []string{"\tRORW\t[$]25,"}, + }, + {"arm64", "linux", ` + func f(x uint32) uint32 { + return x<<7 | x>>25 + } +`, + []string{"\tRORW\t[$]25,"}, + }, + {"arm64", "linux", ` + func f(x uint32) uint32 { + return x<<7 ^ x>>25 + } +`, + []string{"\tRORW\t[$]25,"}, + }, + + {"s390x", "linux", ` + func f(x uint64) uint64 { + return x<<7 + x>>57 + } +`, + []string{"\tRLLG\t[$]7,"}, + }, + {"s390x", "linux", ` + func f(x uint64) uint64 { + return x<<7 | x>>57 + } +`, + []string{"\tRLLG\t[$]7,"}, + }, + {"s390x", "linux", ` + func f(x uint64) uint64 { + return x<<7 ^ x>>57 + } +`, + []string{"\tRLLG\t[$]7,"}, + }, + {"s390x", "linux", ` + func f(x uint32) uint32 { + return x<<7 + x>>25 + } +`, + []string{"\tRLL\t[$]7,"}, + }, + {"s390x", "linux", ` + func f(x uint32) uint32 { + return x<<7 | x>>25 + } +`, + []string{"\tRLL\t[$]7,"}, + }, + {"s390x", "linux", ` + func f(x uint32) uint32 { + return x<<7 ^ x>>25 + } +`, + []string{"\tRLL\t[$]7,"}, + }, + + // Rotate after inlining (see issue 18254). + {"amd64", "linux", ` + func f(x uint32, k uint) uint32 { + return x<>(32-k) + } + func g(x uint32) uint32 { + return f(x, 7) + } +`, + []string{"\tROLL\t[$]7,"}, + }, } // mergeEnvLists merges the two environment lists such that diff --git a/src/cmd/compile/internal/gc/opnames.go b/src/cmd/compile/internal/gc/opnames.go index 01faaf827e2..c8196a0f742 100644 --- a/src/cmd/compile/internal/gc/opnames.go +++ b/src/cmd/compile/internal/gc/opnames.go @@ -158,7 +158,6 @@ var opnames = []string{ OINC: "INC", OEXTEND: "EXTEND", OHMUL: "HMUL", - OLROT: "LROT", ORROTC: "RROTC", ORETJMP: "RETJMP", OPS: "PS", diff --git a/src/cmd/compile/internal/gc/racewalk.go b/src/cmd/compile/internal/gc/racewalk.go index 78335ca76bb..b9fd64a1ac5 100644 --- a/src/cmd/compile/internal/gc/racewalk.go +++ b/src/cmd/compile/internal/gc/racewalk.go @@ -226,7 +226,6 @@ func instrumentnode(np **Node, init *Nodes, wr int, skip int) { case OLSH, ORSH, - OLROT, OAND, OANDNOT, OOR, diff --git a/src/cmd/compile/internal/gc/ssa.go b/src/cmd/compile/internal/gc/ssa.go index 8d0c33a1176..078184d5632 100644 --- a/src/cmd/compile/internal/gc/ssa.go +++ b/src/cmd/compile/internal/gc/ssa.go @@ -1205,11 +1205,6 @@ var opToSSA = map[opAndType]ssa.Op{ opAndType{OGE, TUINT64}: ssa.OpGeq64U, opAndType{OGE, TFLOAT64}: ssa.OpGeq64F, opAndType{OGE, TFLOAT32}: ssa.OpGeq32F, - - opAndType{OLROT, TUINT8}: ssa.OpLrot8, - opAndType{OLROT, TUINT16}: ssa.OpLrot16, - opAndType{OLROT, TUINT32}: ssa.OpLrot32, - opAndType{OLROT, TUINT64}: ssa.OpLrot64, } func (s *state) concreteEtype(t *Type) EType { @@ -1881,13 +1876,6 @@ func (s *state) expr(n *Node) *ssa.Value { a := s.expr(n.Left) b := s.expr(n.Right) return s.newValue2(s.ssaShiftOp(n.Op, n.Type, n.Right.Type), a.Type, a, b) - case OLROT: - a := s.expr(n.Left) - i := n.Right.Int64() - if i <= 0 || i >= n.Type.Size()*8 { - s.Fatalf("Wrong rotate distance for LROT, expected 1 through %d, saw %d", n.Type.Size()*8-1, i) - } - return s.newValue1I(s.ssaRotateOp(n.Op, n.Type), a.Type, i, a) case OANDAND, OOROR: // To implement OANDAND (and OOROR), we introduce a // new temporary variable to hold the result. The diff --git a/src/cmd/compile/internal/gc/syntax.go b/src/cmd/compile/internal/gc/syntax.go index e9e5d8fbe12..6003a29478a 100644 --- a/src/cmd/compile/internal/gc/syntax.go +++ b/src/cmd/compile/internal/gc/syntax.go @@ -500,7 +500,6 @@ const ( OINC // increment: AINC. OEXTEND // extend: ACWD/ACDQ/ACQO. OHMUL // high mul: AMUL/AIMUL for unsigned/signed (OMUL uses AIMUL for both). - OLROT // left rotate: AROL. ORROTC // right rotate-carry: ARCR. ORETJMP // return to other function OPS // compare parity set (for x86 NaN check) diff --git a/src/cmd/compile/internal/gc/walk.go b/src/cmd/compile/internal/gc/walk.go index a380f66fb2e..d5da1701193 100644 --- a/src/cmd/compile/internal/gc/walk.go +++ b/src/cmd/compile/internal/gc/walk.go @@ -551,8 +551,9 @@ opswitch: OGE, OGT, OADD, - OCOMPLEX, - OLROT: + OOR, + OXOR, + OCOMPLEX: if n.Op == OCOMPLEX && n.Left == nil && n.Right == nil { n.Left = n.List.First() n.Right = n.List.Second() @@ -561,11 +562,6 @@ opswitch: n.Left = walkexpr(n.Left, init) n.Right = walkexpr(n.Right, init) - case OOR, OXOR: - n.Left = walkexpr(n.Left, init) - n.Right = walkexpr(n.Right, init) - n = walkrotate(n) - case OEQ, ONE: n.Left = walkexpr(n.Left, init) n.Right = walkexpr(n.Right, init) @@ -3231,63 +3227,6 @@ func samecheap(a *Node, b *Node) bool { return false } -// The result of walkrotate MUST be assigned back to n, e.g. -// n.Left = walkrotate(n.Left) -func walkrotate(n *Node) *Node { - if Thearch.LinkArch.InFamily(sys.MIPS, sys.MIPS64, sys.PPC64) { - return n - } - - // Want << | >> or >> | << or << ^ >> or >> ^ << on unsigned value. - l := n.Left - - r := n.Right - if (n.Op != OOR && n.Op != OXOR) || (l.Op != OLSH && l.Op != ORSH) || (r.Op != OLSH && r.Op != ORSH) || n.Type == nil || n.Type.IsSigned() || l.Op == r.Op { - return n - } - - // Want same, side effect-free expression on lhs of both shifts. - if !samecheap(l.Left, r.Left) { - return n - } - - // Constants adding to width? - w := int(l.Type.Width * 8) - - if Thearch.LinkArch.Family == sys.S390X && w != 32 && w != 64 { - // only supports 32-bit and 64-bit rotates - return n - } - - if smallintconst(l.Right) && smallintconst(r.Right) { - sl := int(l.Right.Int64()) - if sl >= 0 { - sr := int(r.Right.Int64()) - if sr >= 0 && sl+sr == w { - // Rewrite left shift half to left rotate. - if l.Op == OLSH { - n = l - } else { - n = r - } - n.Op = OLROT - - // Remove rotate 0 and rotate w. - s := int(n.Right.Int64()) - - if s == 0 || s == w { - n = n.Left - } - return n - } - } - return n - } - - // TODO: Could allow s and 32-s if s is bounded (maybe s&31 and 32-s&31). - return n -} - // isIntOrdering reports whether n is a <, ≤, >, or ≥ ordering between integers. func (n *Node) isIntOrdering() bool { switch n.Op { diff --git a/src/cmd/compile/internal/ssa/gen/386.rules b/src/cmd/compile/internal/ssa/gen/386.rules index a3f2ecb8c38..cd4bf9cf8a7 100644 --- a/src/cmd/compile/internal/ssa/gen/386.rules +++ b/src/cmd/compile/internal/ssa/gen/386.rules @@ -135,10 +135,6 @@ (Lsh8x16 x y) -> (ANDL (SHLL x y) (SBBLcarrymask (CMPWconst y [32]))) (Lsh8x8 x y) -> (ANDL (SHLL x y) (SBBLcarrymask (CMPBconst y [32]))) -(Lrot32 x [c]) -> (ROLLconst [c&31] x) -(Lrot16 x [c]) -> (ROLWconst [c&15] x) -(Lrot8 x [c]) -> (ROLBconst [c&7] x) - (Rsh32Ux32 x y) -> (ANDL (SHRL x y) (SBBLcarrymask (CMPLconst y [32]))) (Rsh32Ux16 x y) -> (ANDL (SHRL x y) (SBBLcarrymask (CMPWconst y [32]))) (Rsh32Ux8 x y) -> (ANDL (SHRL x y) (SBBLcarrymask (CMPBconst y [32]))) @@ -468,25 +464,15 @@ (XORL (MOVLconst [c]) x) -> (XORLconst [c] x) (SHLL x (MOVLconst [c])) -> (SHLLconst [c&31] x) -(SHLL x (MOVLconst [c])) -> (SHLLconst [c&31] x) - (SHRL x (MOVLconst [c])) -> (SHRLconst [c&31] x) -(SHRL x (MOVLconst [c])) -> (SHRLconst [c&31] x) - -(SHRW x (MOVLconst [c])) -> (SHRWconst [c&31] x) -(SHRW x (MOVLconst [c])) -> (SHRWconst [c&31] x) - -(SHRB x (MOVLconst [c])) -> (SHRBconst [c&31] x) -(SHRB x (MOVLconst [c])) -> (SHRBconst [c&31] x) +(SHRW x (MOVLconst [c])) && c&31 < 16 -> (SHRWconst [c&31] x) +(SHRW _ (MOVLconst [c])) && c&31 >= 16 -> (MOVLconst [0]) +(SHRB x (MOVLconst [c])) && c&31 < 8 -> (SHRBconst [c&31] x) +(SHRB _ (MOVLconst [c])) && c&31 >= 8 -> (MOVLconst [0]) (SARL x (MOVLconst [c])) -> (SARLconst [c&31] x) -(SARL x (MOVLconst [c])) -> (SARLconst [c&31] x) - -(SARW x (MOVLconst [c])) -> (SARWconst [c&31] x) -(SARW x (MOVLconst [c])) -> (SARWconst [c&31] x) - -(SARB x (MOVLconst [c])) -> (SARBconst [c&31] x) -(SARB x (MOVLconst [c])) -> (SARBconst [c&31] x) +(SARW x (MOVLconst [c])) -> (SARWconst [min(c&31,15)] x) +(SARB x (MOVLconst [c])) -> (SARBconst [min(c&31,7)] x) (SARL x (ANDLconst [31] y)) -> (SARL x y) @@ -494,10 +480,45 @@ (SHRL x (ANDLconst [31] y)) -> (SHRL x y) +// Rotate instructions + +(ADDL (SHLLconst [c] x) (SHRLconst [32-c] x)) -> (ROLLconst [c ] x) +( ORL (SHLLconst [c] x) (SHRLconst [32-c] x)) -> (ROLLconst [c ] x) +(XORL (SHLLconst [c] x) (SHRLconst [32-c] x)) -> (ROLLconst [c ] x) +(ADDL (SHRLconst [c] x) (SHLLconst [32-c] x)) -> (ROLLconst [32-c] x) +( ORL (SHRLconst [c] x) (SHLLconst [32-c] x)) -> (ROLLconst [32-c] x) +(XORL (SHRLconst [c] x) (SHLLconst [32-c] x)) -> (ROLLconst [32-c] x) + +(ADDL (SHLLconst x [c]) (SHRWconst x [16-c])) && c < 16 && t.Size() == 2 -> (ROLWconst x [ c]) +( ORL (SHLLconst x [c]) (SHRWconst x [16-c])) && c < 16 && t.Size() == 2 -> (ROLWconst x [ c]) +(XORL (SHLLconst x [c]) (SHRWconst x [16-c])) && c < 16 && t.Size() == 2 -> (ROLWconst x [ c]) +(ADDL (SHRWconst x [c]) (SHLLconst x [16-c])) && c > 0 && t.Size() == 2 -> (ROLWconst x [16-c]) +( ORL (SHRWconst x [c]) (SHLLconst x [16-c])) && c > 0 && t.Size() == 2 -> (ROLWconst x [16-c]) +(XORL (SHRWconst x [c]) (SHLLconst x [16-c])) && c > 0 && t.Size() == 2 -> (ROLWconst x [16-c]) + +(ADDL (SHLLconst x [c]) (SHRBconst x [ 8-c])) && c < 8 && t.Size() == 1 -> (ROLBconst x [ c]) +( ORL (SHLLconst x [c]) (SHRBconst x [ 8-c])) && c < 8 && t.Size() == 1 -> (ROLBconst x [ c]) +(XORL (SHLLconst x [c]) (SHRBconst x [ 8-c])) && c < 8 && t.Size() == 1 -> (ROLBconst x [ c]) +(ADDL (SHRBconst x [c]) (SHLLconst x [ 8-c])) && c > 0 && t.Size() == 1 -> (ROLBconst x [ 8-c]) +( ORL (SHRBconst x [c]) (SHLLconst x [ 8-c])) && c > 0 && t.Size() == 1 -> (ROLBconst x [ 8-c]) +(XORL (SHRBconst x [c]) (SHLLconst x [ 8-c])) && c > 0 && t.Size() == 1 -> (ROLBconst x [ 8-c]) + (ROLLconst [c] (ROLLconst [d] x)) -> (ROLLconst [(c+d)&31] x) (ROLWconst [c] (ROLWconst [d] x)) -> (ROLWconst [(c+d)&15] x) (ROLBconst [c] (ROLBconst [d] x)) -> (ROLBconst [(c+d)& 7] x) +// Constant shift simplifications + +(SHLLconst x [0]) -> x +(SHRLconst x [0]) -> x +(SARLconst x [0]) -> x + +(SHRWconst x [0]) -> x +(SARWconst x [0]) -> x + +(SHRBconst x [0]) -> x +(SARBconst x [0]) -> x + (ROLLconst [0] x) -> x (ROLWconst [0] x) -> x (ROLBconst [0] x) -> x diff --git a/src/cmd/compile/internal/ssa/gen/386Ops.go b/src/cmd/compile/internal/ssa/gen/386Ops.go index d09f497413b..1d150db6644 100644 --- a/src/cmd/compile/internal/ssa/gen/386Ops.go +++ b/src/cmd/compile/internal/ssa/gen/386Ops.go @@ -246,15 +246,15 @@ func init() { {name: "SHRW", argLength: 2, reg: gp21shift, asm: "SHRW", resultInArg0: true, clobberFlags: true}, // unsigned arg0 >> arg1, shift amount is mod 32 {name: "SHRB", argLength: 2, reg: gp21shift, asm: "SHRB", resultInArg0: true, clobberFlags: true}, // unsigned arg0 >> arg1, shift amount is mod 32 {name: "SHRLconst", argLength: 1, reg: gp11, asm: "SHRL", aux: "Int32", resultInArg0: true, clobberFlags: true}, // unsigned arg0 >> auxint, shift amount 0-31 - {name: "SHRWconst", argLength: 1, reg: gp11, asm: "SHRW", aux: "Int16", resultInArg0: true, clobberFlags: true}, // unsigned arg0 >> auxint, shift amount 0-31 - {name: "SHRBconst", argLength: 1, reg: gp11, asm: "SHRB", aux: "Int8", resultInArg0: true, clobberFlags: true}, // unsigned arg0 >> auxint, shift amount 0-31 + {name: "SHRWconst", argLength: 1, reg: gp11, asm: "SHRW", aux: "Int16", resultInArg0: true, clobberFlags: true}, // unsigned arg0 >> auxint, shift amount 0-15 + {name: "SHRBconst", argLength: 1, reg: gp11, asm: "SHRB", aux: "Int8", resultInArg0: true, clobberFlags: true}, // unsigned arg0 >> auxint, shift amount 0-7 {name: "SARL", argLength: 2, reg: gp21shift, asm: "SARL", resultInArg0: true, clobberFlags: true}, // signed arg0 >> arg1, shift amount is mod 32 {name: "SARW", argLength: 2, reg: gp21shift, asm: "SARW", resultInArg0: true, clobberFlags: true}, // signed arg0 >> arg1, shift amount is mod 32 {name: "SARB", argLength: 2, reg: gp21shift, asm: "SARB", resultInArg0: true, clobberFlags: true}, // signed arg0 >> arg1, shift amount is mod 32 {name: "SARLconst", argLength: 1, reg: gp11, asm: "SARL", aux: "Int32", resultInArg0: true, clobberFlags: true}, // signed arg0 >> auxint, shift amount 0-31 - {name: "SARWconst", argLength: 1, reg: gp11, asm: "SARW", aux: "Int16", resultInArg0: true, clobberFlags: true}, // signed arg0 >> auxint, shift amount 0-31 - {name: "SARBconst", argLength: 1, reg: gp11, asm: "SARB", aux: "Int8", resultInArg0: true, clobberFlags: true}, // signed arg0 >> auxint, shift amount 0-31 + {name: "SARWconst", argLength: 1, reg: gp11, asm: "SARW", aux: "Int16", resultInArg0: true, clobberFlags: true}, // signed arg0 >> auxint, shift amount 0-15 + {name: "SARBconst", argLength: 1, reg: gp11, asm: "SARB", aux: "Int8", resultInArg0: true, clobberFlags: true}, // signed arg0 >> auxint, shift amount 0-7 {name: "ROLLconst", argLength: 1, reg: gp11, asm: "ROLL", aux: "Int32", resultInArg0: true, clobberFlags: true}, // arg0 rotate left auxint, rotate amount 0-31 {name: "ROLWconst", argLength: 1, reg: gp11, asm: "ROLW", aux: "Int16", resultInArg0: true, clobberFlags: true}, // arg0 rotate left auxint, rotate amount 0-15 diff --git a/src/cmd/compile/internal/ssa/gen/AMD64.rules b/src/cmd/compile/internal/ssa/gen/AMD64.rules index 5b4649cb143..8636118669f 100644 --- a/src/cmd/compile/internal/ssa/gen/AMD64.rules +++ b/src/cmd/compile/internal/ssa/gen/AMD64.rules @@ -173,11 +173,6 @@ (Lsh8x16 x y) -> (ANDL (SHLL x y) (SBBLcarrymask (CMPWconst y [32]))) (Lsh8x8 x y) -> (ANDL (SHLL x y) (SBBLcarrymask (CMPBconst y [32]))) -(Lrot64 x [c]) -> (ROLQconst [c&63] x) -(Lrot32 x [c]) -> (ROLLconst [c&31] x) -(Lrot16 x [c]) -> (ROLWconst [c&15] x) -(Lrot8 x [c]) -> (ROLBconst [c&7] x) - (Rsh64Ux64 x y) -> (ANDQ (SHRQ x y) (SBBQcarrymask (CMPQconst y [64]))) (Rsh64Ux32 x y) -> (ANDQ (SHRQ x y) (SBBQcarrymask (CMPLconst y [64]))) (Rsh64Ux16 x y) -> (ANDQ (SHRQ x y) (SBBQcarrymask (CMPWconst y [64]))) @@ -582,11 +577,15 @@ (SHRL x (MOVQconst [c])) -> (SHRLconst [c&31] x) (SHRL x (MOVLconst [c])) -> (SHRLconst [c&31] x) -(SHRW x (MOVQconst [c])) -> (SHRWconst [c&31] x) -(SHRW x (MOVLconst [c])) -> (SHRWconst [c&31] x) +(SHRW x (MOVQconst [c])) && c&31 < 16 -> (SHRWconst [c&31] x) +(SHRW x (MOVLconst [c])) && c&31 < 16 -> (SHRWconst [c&31] x) +(SHRW _ (MOVQconst [c])) && c&31 >= 16 -> (MOVLconst [0]) +(SHRW _ (MOVLconst [c])) && c&31 >= 16 -> (MOVLconst [0]) -(SHRB x (MOVQconst [c])) -> (SHRBconst [c&31] x) -(SHRB x (MOVLconst [c])) -> (SHRBconst [c&31] x) +(SHRB x (MOVQconst [c])) && c&31 < 8 -> (SHRBconst [c&31] x) +(SHRB x (MOVLconst [c])) && c&31 < 8 -> (SHRBconst [c&31] x) +(SHRB _ (MOVQconst [c])) && c&31 >= 8 -> (MOVLconst [0]) +(SHRB _ (MOVLconst [c])) && c&31 >= 8 -> (MOVLconst [0]) (SARQ x (MOVQconst [c])) -> (SARQconst [c&63] x) (SARQ x (MOVLconst [c])) -> (SARQconst [c&63] x) @@ -594,11 +593,11 @@ (SARL x (MOVQconst [c])) -> (SARLconst [c&31] x) (SARL x (MOVLconst [c])) -> (SARLconst [c&31] x) -(SARW x (MOVQconst [c])) -> (SARWconst [c&31] x) -(SARW x (MOVLconst [c])) -> (SARWconst [c&31] x) +(SARW x (MOVQconst [c])) -> (SARWconst [min(c&31,15)] x) +(SARW x (MOVLconst [c])) -> (SARWconst [min(c&31,15)] x) -(SARB x (MOVQconst [c])) -> (SARBconst [c&31] x) -(SARB x (MOVLconst [c])) -> (SARBconst [c&31] x) +(SARB x (MOVQconst [c])) -> (SARBconst [min(c&31,7)] x) +(SARB x (MOVLconst [c])) -> (SARBconst [min(c&31,7)] x) (SARL x (ANDLconst [31] y)) -> (SARL x y) (SARQ x (ANDQconst [63] y)) -> (SARQ x y) @@ -609,15 +608,63 @@ (SHRL x (ANDLconst [31] y)) -> (SHRL x y) (SHRQ x (ANDQconst [63] y)) -> (SHRQ x y) +// Rotate instructions + +(ADDQ (SHLQconst x [c]) (SHRQconst x [64-c])) -> (ROLQconst x [ c]) +( ORQ (SHLQconst x [c]) (SHRQconst x [64-c])) -> (ROLQconst x [ c]) +(XORQ (SHLQconst x [c]) (SHRQconst x [64-c])) -> (ROLQconst x [ c]) +(ADDQ (SHRQconst x [c]) (SHLQconst x [64-c])) -> (ROLQconst x [64-c]) +( ORQ (SHRQconst x [c]) (SHLQconst x [64-c])) -> (ROLQconst x [64-c]) +(XORQ (SHRQconst x [c]) (SHLQconst x [64-c])) -> (ROLQconst x [64-c]) + +(ADDL (SHLLconst x [c]) (SHRLconst x [32-c])) -> (ROLLconst x [ c]) +( ORL (SHLLconst x [c]) (SHRLconst x [32-c])) -> (ROLLconst x [ c]) +(XORL (SHLLconst x [c]) (SHRLconst x [32-c])) -> (ROLLconst x [ c]) +(ADDL (SHRLconst x [c]) (SHLLconst x [32-c])) -> (ROLLconst x [32-c]) +( ORL (SHRLconst x [c]) (SHLLconst x [32-c])) -> (ROLLconst x [32-c]) +(XORL (SHRLconst x [c]) (SHLLconst x [32-c])) -> (ROLLconst x [32-c]) + +(ADDL (SHLLconst x [c]) (SHRWconst x [16-c])) && c < 16 && t.Size() == 2 -> (ROLWconst x [ c]) +( ORL (SHLLconst x [c]) (SHRWconst x [16-c])) && c < 16 && t.Size() == 2 -> (ROLWconst x [ c]) +(XORL (SHLLconst x [c]) (SHRWconst x [16-c])) && c < 16 && t.Size() == 2 -> (ROLWconst x [ c]) +(ADDL (SHRWconst x [c]) (SHLLconst x [16-c])) && c > 0 && t.Size() == 2 -> (ROLWconst x [16-c]) +( ORL (SHRWconst x [c]) (SHLLconst x [16-c])) && c > 0 && t.Size() == 2 -> (ROLWconst x [16-c]) +(XORL (SHRWconst x [c]) (SHLLconst x [16-c])) && c > 0 && t.Size() == 2 -> (ROLWconst x [16-c]) + +(ADDL (SHLLconst x [c]) (SHRBconst x [ 8-c])) && c < 8 && t.Size() == 1 -> (ROLBconst x [ c]) +( ORL (SHLLconst x [c]) (SHRBconst x [ 8-c])) && c < 8 && t.Size() == 1 -> (ROLBconst x [ c]) +(XORL (SHLLconst x [c]) (SHRBconst x [ 8-c])) && c < 8 && t.Size() == 1 -> (ROLBconst x [ c]) +(ADDL (SHRBconst x [c]) (SHLLconst x [ 8-c])) && c > 0 && t.Size() == 1 -> (ROLBconst x [ 8-c]) +( ORL (SHRBconst x [c]) (SHLLconst x [ 8-c])) && c > 0 && t.Size() == 1 -> (ROLBconst x [ 8-c]) +(XORL (SHRBconst x [c]) (SHLLconst x [ 8-c])) && c > 0 && t.Size() == 1 -> (ROLBconst x [ 8-c]) + (ROLQconst [c] (ROLQconst [d] x)) -> (ROLQconst [(c+d)&63] x) (ROLLconst [c] (ROLLconst [d] x)) -> (ROLLconst [(c+d)&31] x) (ROLWconst [c] (ROLWconst [d] x)) -> (ROLWconst [(c+d)&15] x) (ROLBconst [c] (ROLBconst [d] x)) -> (ROLBconst [(c+d)& 7] x) -(ROLQconst [0] x) -> x -(ROLLconst [0] x) -> x -(ROLWconst [0] x) -> x -(ROLBconst [0] x) -> x +// TODO: non-constant rotates if shift amount is known to be bounded (shift & 63 or something). + +// Constant shift simplifications + +(SHLQconst x [0]) -> x +(SHRQconst x [0]) -> x +(SARQconst x [0]) -> x + +(SHLLconst x [0]) -> x +(SHRLconst x [0]) -> x +(SARLconst x [0]) -> x + +(SHRWconst x [0]) -> x +(SARWconst x [0]) -> x + +(SHRBconst x [0]) -> x +(SARBconst x [0]) -> x + +(ROLQconst x [0]) -> x +(ROLLconst x [0]) -> x +(ROLWconst x [0]) -> x +(ROLBconst x [0]) -> x // Note: the word and byte shifts keep the low 5 bits (not the low 4 or 3 bits) // because the x86 instructions are defined to use all 5 bits of the shift even diff --git a/src/cmd/compile/internal/ssa/gen/AMD64Ops.go b/src/cmd/compile/internal/ssa/gen/AMD64Ops.go index 5a293d1b6a3..b42ede4ad00 100644 --- a/src/cmd/compile/internal/ssa/gen/AMD64Ops.go +++ b/src/cmd/compile/internal/ssa/gen/AMD64Ops.go @@ -262,8 +262,8 @@ func init() { {name: "SHRB", argLength: 2, reg: gp21shift, asm: "SHRB", resultInArg0: true, clobberFlags: true}, // unsigned arg0 >> arg1, shift amount is mod 32 {name: "SHRQconst", argLength: 1, reg: gp11, asm: "SHRQ", aux: "Int64", resultInArg0: true, clobberFlags: true}, // unsigned arg0 >> auxint, shift amount 0-63 {name: "SHRLconst", argLength: 1, reg: gp11, asm: "SHRL", aux: "Int32", resultInArg0: true, clobberFlags: true}, // unsigned arg0 >> auxint, shift amount 0-31 - {name: "SHRWconst", argLength: 1, reg: gp11, asm: "SHRW", aux: "Int16", resultInArg0: true, clobberFlags: true}, // unsigned arg0 >> auxint, shift amount 0-31 - {name: "SHRBconst", argLength: 1, reg: gp11, asm: "SHRB", aux: "Int8", resultInArg0: true, clobberFlags: true}, // unsigned arg0 >> auxint, shift amount 0-31 + {name: "SHRWconst", argLength: 1, reg: gp11, asm: "SHRW", aux: "Int16", resultInArg0: true, clobberFlags: true}, // unsigned arg0 >> auxint, shift amount 0-15 + {name: "SHRBconst", argLength: 1, reg: gp11, asm: "SHRB", aux: "Int8", resultInArg0: true, clobberFlags: true}, // unsigned arg0 >> auxint, shift amount 0-7 {name: "SARQ", argLength: 2, reg: gp21shift, asm: "SARQ", resultInArg0: true, clobberFlags: true}, // signed arg0 >> arg1, shift amount is mod 64 {name: "SARL", argLength: 2, reg: gp21shift, asm: "SARL", resultInArg0: true, clobberFlags: true}, // signed arg0 >> arg1, shift amount is mod 32 @@ -271,8 +271,8 @@ func init() { {name: "SARB", argLength: 2, reg: gp21shift, asm: "SARB", resultInArg0: true, clobberFlags: true}, // signed arg0 >> arg1, shift amount is mod 32 {name: "SARQconst", argLength: 1, reg: gp11, asm: "SARQ", aux: "Int64", resultInArg0: true, clobberFlags: true}, // signed arg0 >> auxint, shift amount 0-63 {name: "SARLconst", argLength: 1, reg: gp11, asm: "SARL", aux: "Int32", resultInArg0: true, clobberFlags: true}, // signed arg0 >> auxint, shift amount 0-31 - {name: "SARWconst", argLength: 1, reg: gp11, asm: "SARW", aux: "Int16", resultInArg0: true, clobberFlags: true}, // signed arg0 >> auxint, shift amount 0-31 - {name: "SARBconst", argLength: 1, reg: gp11, asm: "SARB", aux: "Int8", resultInArg0: true, clobberFlags: true}, // signed arg0 >> auxint, shift amount 0-31 + {name: "SARWconst", argLength: 1, reg: gp11, asm: "SARW", aux: "Int16", resultInArg0: true, clobberFlags: true}, // signed arg0 >> auxint, shift amount 0-15 + {name: "SARBconst", argLength: 1, reg: gp11, asm: "SARB", aux: "Int8", resultInArg0: true, clobberFlags: true}, // signed arg0 >> auxint, shift amount 0-7 {name: "ROLQconst", argLength: 1, reg: gp11, asm: "ROLQ", aux: "Int64", resultInArg0: true, clobberFlags: true}, // arg0 rotate left auxint, rotate amount 0-63 {name: "ROLLconst", argLength: 1, reg: gp11, asm: "ROLL", aux: "Int32", resultInArg0: true, clobberFlags: true}, // arg0 rotate left auxint, rotate amount 0-31 diff --git a/src/cmd/compile/internal/ssa/gen/ARM.rules b/src/cmd/compile/internal/ssa/gen/ARM.rules index bea9d6c7088..28f074fc204 100644 --- a/src/cmd/compile/internal/ssa/gen/ARM.rules +++ b/src/cmd/compile/internal/ssa/gen/ARM.rules @@ -177,10 +177,6 @@ (Rsh16x64 x (Const64 [c])) && uint64(c) >= 16 -> (SRAconst (SLLconst x [16]) [31]) (Rsh8x64 x (Const64 [c])) && uint64(c) >= 8 -> (SRAconst (SLLconst x [24]) [31]) -(Lrot32 x [c]) -> (SRRconst x [32-c&31]) -(Lrot16 x [c]) -> (OR (SLLconst x [c&15]) (SRLconst x [16-c&15])) -(Lrot8 x [c]) -> (OR (SLLconst x [c&7]) (SRLconst x [8-c&7])) - // constants (Const8 [val]) -> (MOVWconst [val]) (Const16 [val]) -> (MOVWconst [val]) @@ -1159,6 +1155,14 @@ (CMPshiftRLreg x y (MOVWconst [c])) -> (CMPshiftRL x y [c]) (CMPshiftRAreg x y (MOVWconst [c])) -> (CMPshiftRA x y [c]) +// Generate rotates +(ADDshiftLL [c] (SRLconst x [32-c]) x) -> (SRRconst [32-c] x) +( ORshiftLL [c] (SRLconst x [32-c]) x) -> (SRRconst [32-c] x) +(XORshiftLL [c] (SRLconst x [32-c]) x) -> (SRRconst [32-c] x) +(ADDshiftRL [c] (SLLconst x [32-c]) x) -> (SRRconst [ c] x) +( ORshiftRL [c] (SLLconst x [32-c]) x) -> (SRRconst [ c] x) +(XORshiftRL [c] (SLLconst x [32-c]) x) -> (SRRconst [ c] x) + // use indexed loads and stores (MOVWload [0] {sym} (ADD ptr idx) mem) && sym == nil && !config.nacl -> (MOVWloadidx ptr idx mem) (MOVWstore [0] {sym} (ADD ptr idx) val mem) && sym == nil && !config.nacl -> (MOVWstoreidx ptr idx val mem) diff --git a/src/cmd/compile/internal/ssa/gen/ARM64.rules b/src/cmd/compile/internal/ssa/gen/ARM64.rules index c36b6f755ca..53b364a12b5 100644 --- a/src/cmd/compile/internal/ssa/gen/ARM64.rules +++ b/src/cmd/compile/internal/ssa/gen/ARM64.rules @@ -192,11 +192,6 @@ (Rsh8x16 x y) -> (SRA (SignExt8to64 x) (CSELULT (ZeroExt16to64 y) (Const64 [63]) (CMPconst [64] (ZeroExt16to64 y)))) (Rsh8x8 x y) -> (SRA (SignExt8to64 x) (CSELULT (ZeroExt8to64 y) (Const64 [63]) (CMPconst [64] (ZeroExt8to64 y)))) -(Lrot64 x [c]) -> (RORconst x [64-c&63]) -(Lrot32 x [c]) -> (RORWconst x [32-c&31]) -(Lrot16 x [c]) -> (OR (SLLconst x [c&15]) (SRLconst (ZeroExt16to64 x) [16-c&15])) -(Lrot8 x [c]) -> (OR (SLLconst x [c&7]) (SRLconst (ZeroExt8to64 x) [8-c&7])) - // constants (Const64 [val]) -> (MOVDconst [val]) (Const32 [val]) -> (MOVDconst [val]) @@ -1135,6 +1130,21 @@ (BICshiftRL x (SRLconst x [c]) [d]) && c==d -> (MOVDconst [0]) (BICshiftRA x (SRAconst x [c]) [d]) && c==d -> (MOVDconst [0]) +// Generate rotates +(ADDshiftLL [c] (SRLconst x [64-c]) x) -> (RORconst [64-c] x) +( ORshiftLL [c] (SRLconst x [64-c]) x) -> (RORconst [64-c] x) +(XORshiftLL [c] (SRLconst x [64-c]) x) -> (RORconst [64-c] x) +(ADDshiftRL [c] (SLLconst x [64-c]) x) -> (RORconst [ c] x) +( ORshiftRL [c] (SLLconst x [64-c]) x) -> (RORconst [ c] x) +(XORshiftRL [c] (SLLconst x [64-c]) x) -> (RORconst [ c] x) + +(ADDshiftLL [c] (SRLconst (MOVWUreg x) [32-c]) x) && c < 32 && t.Size() == 4 -> (RORWconst [32-c] x) +( ORshiftLL [c] (SRLconst (MOVWUreg x) [32-c]) x) && c < 32 && t.Size() == 4 -> (RORWconst [32-c] x) +(XORshiftLL [c] (SRLconst (MOVWUreg x) [32-c]) x) && c < 32 && t.Size() == 4 -> (RORWconst [32-c] x) +(ADDshiftRL [c] (SLLconst x [32-c]) (MOVWUreg x)) && c < 32 && t.Size() == 4 -> (RORWconst [ c] x) +( ORshiftRL [c] (SLLconst x [32-c]) (MOVWUreg x)) && c < 32 && t.Size() == 4 -> (RORWconst [ c] x) +(XORshiftRL [c] (SLLconst x [32-c]) (MOVWUreg x)) && c < 32 && t.Size() == 4 -> (RORWconst [ c] x) + // do combined loads // little endian loads // b[0] | b[1]<<8 -> load 16-bit diff --git a/src/cmd/compile/internal/ssa/gen/S390X.rules b/src/cmd/compile/internal/ssa/gen/S390X.rules index be0d581fe09..c609d0d8b11 100644 --- a/src/cmd/compile/internal/ssa/gen/S390X.rules +++ b/src/cmd/compile/internal/ssa/gen/S390X.rules @@ -200,9 +200,6 @@ (Lsh8x16 x y) -> (ANDW (SLW x y) (SUBEWcarrymask (CMPWUconst (MOVHZreg y) [31]))) (Lsh8x8 x y) -> (ANDW (SLW x y) (SUBEWcarrymask (CMPWUconst (MOVBZreg y) [31]))) -(Lrot64 x [c]) -> (RLLGconst [c&63] x) -(Lrot32 x [c]) -> (RLLconst [c&31] x) - (Rsh64Ux64 x y) -> (AND (SRD x y) (SUBEcarrymask (CMPUconst y [63]))) (Rsh64Ux32 x y) -> (AND (SRD x y) (SUBEcarrymask (CMPWUconst y [63]))) (Rsh64Ux16 x y) -> (AND (SRD x y) (SUBEcarrymask (CMPWUconst (MOVHZreg y) [63]))) @@ -518,6 +515,21 @@ (SRW x (ANDWconst [63] y)) -> (SRW x y) (SRD x (ANDconst [63] y)) -> (SRD x y) +// Rotate generation +(ADD (SLDconst x [c]) (SRDconst x [64-c])) -> (RLLGconst [ c] x) +( OR (SLDconst x [c]) (SRDconst x [64-c])) -> (RLLGconst [ c] x) +(XOR (SLDconst x [c]) (SRDconst x [64-c])) -> (RLLGconst [ c] x) +(ADD (SRDconst x [c]) (SLDconst x [64-c])) -> (RLLGconst [64-c] x) +( OR (SRDconst x [c]) (SLDconst x [64-c])) -> (RLLGconst [64-c] x) +(XOR (SRDconst x [c]) (SLDconst x [64-c])) -> (RLLGconst [64-c] x) + +(ADDW (SLWconst x [c]) (SRWconst x [32-c])) -> (RLLconst [ c] x) +( ORW (SLWconst x [c]) (SRWconst x [32-c])) -> (RLLconst [ c] x) +(XORW (SLWconst x [c]) (SRWconst x [32-c])) -> (RLLconst [ c] x) +(ADDW (SRWconst x [c]) (SLWconst x [32-c])) -> (RLLconst [32-c] x) +( ORW (SRWconst x [c]) (SLWconst x [32-c])) -> (RLLconst [32-c] x) +(XORW (SRWconst x [c]) (SLWconst x [32-c])) -> (RLLconst [32-c] x) + (CMP x (MOVDconst [c])) && is32Bit(c) -> (CMPconst x [c]) (CMP (MOVDconst [c]) x) && is32Bit(c) -> (InvertFlags (CMPconst x [c])) (CMPW x (MOVDconst [c])) -> (CMPWconst x [c]) diff --git a/src/cmd/compile/internal/ssa/gen/dec64.rules b/src/cmd/compile/internal/ssa/gen/dec64.rules index 961ffc7d6d0..d8b755b8d73 100644 --- a/src/cmd/compile/internal/ssa/gen/dec64.rules +++ b/src/cmd/compile/internal/ssa/gen/dec64.rules @@ -365,16 +365,6 @@ //(Rsh64x32 x (Const32 [0])) -> x //(Rsh64Ux32 x (Const32 [0])) -> x -(Lrot64 (Int64Make hi lo) [c]) && c <= 32 -> - (Int64Make - (Or32 - (Lsh32x32 hi (Const32 [c])) - (Rsh32Ux32 lo (Const32 [32-c]))) - (Or32 - (Lsh32x32 lo (Const32 [c])) - (Rsh32Ux32 hi (Const32 [32-c])))) -(Lrot64 (Int64Make hi lo) [c]) && c > 32 -> (Lrot64 (Int64Make lo hi) [c-32]) - (Const64 [c]) && t.IsSigned() -> (Int64Make (Const32 [c>>32]) (Const32 [int64(int32(c))])) (Const64 [c]) && !t.IsSigned() -> diff --git a/src/cmd/compile/internal/ssa/gen/genericOps.go b/src/cmd/compile/internal/ssa/gen/genericOps.go index fe93e521e31..b825f134750 100644 --- a/src/cmd/compile/internal/ssa/gen/genericOps.go +++ b/src/cmd/compile/internal/ssa/gen/genericOps.go @@ -151,31 +151,6 @@ var genericOps = []opData{ {name: "Rsh64Ux32", argLength: 2}, {name: "Rsh64Ux64", argLength: 2}, - // (Left) rotates replace pattern matches in the front end - // of (arg0 << arg1) ^ (arg0 >> (A-arg1)) - // where A is the bit width of arg0 and result. - // Note that because rotates are pattern-matched from - // shifts, that a rotate of arg1=A+k (k > 0) bits originated from - // (arg0 << A+k) ^ (arg0 >> -k) = - // 0 ^ arg0>>huge_unsigned = - // 0 ^ 0 = 0 - // which is not the same as a rotation by A+k - // - // However, in the specific case of k = 0, the result of - // the shift idiom is the same as the result for the - // rotate idiom, i.e., result=arg0. - // This is different from shifts, where - // arg0 << A is defined to be zero. - // - // Because of this, and also because the primary use case - // for rotates is hashing and crypto code with constant - // distance, rotate instructions are only substituted - // when arg1 is a constant between 1 and A-1, inclusive. - {name: "Lrot8", argLength: 1, aux: "Int64"}, - {name: "Lrot16", argLength: 1, aux: "Int64"}, - {name: "Lrot32", argLength: 1, aux: "Int64"}, - {name: "Lrot64", argLength: 1, aux: "Int64"}, - // 2-input comparisons {name: "Eq8", argLength: 2, commutative: true, typ: "Bool"}, // arg0 == arg1 {name: "Eq16", argLength: 2, commutative: true, typ: "Bool"}, diff --git a/src/cmd/compile/internal/ssa/opGen.go b/src/cmd/compile/internal/ssa/opGen.go index a63c5b9953b..510fcfea102 100644 --- a/src/cmd/compile/internal/ssa/opGen.go +++ b/src/cmd/compile/internal/ssa/opGen.go @@ -1670,10 +1670,6 @@ const ( OpRsh64Ux16 OpRsh64Ux32 OpRsh64Ux64 - OpLrot8 - OpLrot16 - OpLrot32 - OpLrot64 OpEq8 OpEq16 OpEq32 @@ -20315,30 +20311,6 @@ var opcodeTable = [...]opInfo{ argLen: 2, generic: true, }, - { - name: "Lrot8", - auxType: auxInt64, - argLen: 1, - generic: true, - }, - { - name: "Lrot16", - auxType: auxInt64, - argLen: 1, - generic: true, - }, - { - name: "Lrot32", - auxType: auxInt64, - argLen: 1, - generic: true, - }, - { - name: "Lrot64", - auxType: auxInt64, - argLen: 1, - generic: true, - }, { name: "Eq8", argLen: 2, diff --git a/src/cmd/compile/internal/ssa/rewrite.go b/src/cmd/compile/internal/ssa/rewrite.go index 11d1e9d8c94..a0e278fb159 100644 --- a/src/cmd/compile/internal/ssa/rewrite.go +++ b/src/cmd/compile/internal/ssa/rewrite.go @@ -518,3 +518,10 @@ func logRule(s string) { } var ruleFile *os.File + +func min(x, y int64) int64 { + if x < y { + return x + } + return y +} diff --git a/src/cmd/compile/internal/ssa/rewrite386.go b/src/cmd/compile/internal/ssa/rewrite386.go index 99b665783ef..e05810bb1d4 100644 --- a/src/cmd/compile/internal/ssa/rewrite386.go +++ b/src/cmd/compile/internal/ssa/rewrite386.go @@ -186,12 +186,20 @@ func rewriteValue386(v *Value, config *Config) bool { return rewriteValue386_Op386SETNE(v, config) case Op386SHLL: return rewriteValue386_Op386SHLL(v, config) + case Op386SHLLconst: + return rewriteValue386_Op386SHLLconst(v, config) case Op386SHRB: return rewriteValue386_Op386SHRB(v, config) + case Op386SHRBconst: + return rewriteValue386_Op386SHRBconst(v, config) case Op386SHRL: return rewriteValue386_Op386SHRL(v, config) + case Op386SHRLconst: + return rewriteValue386_Op386SHRLconst(v, config) case Op386SHRW: return rewriteValue386_Op386SHRW(v, config) + case Op386SHRWconst: + return rewriteValue386_Op386SHRWconst(v, config) case Op386SUBL: return rewriteValue386_Op386SUBL(v, config) case Op386SUBLcarry: @@ -390,12 +398,6 @@ func rewriteValue386(v *Value, config *Config) bool { return rewriteValue386_OpLess8U(v, config) case OpLoad: return rewriteValue386_OpLoad(v, config) - case OpLrot16: - return rewriteValue386_OpLrot16(v, config) - case OpLrot32: - return rewriteValue386_OpLrot32(v, config) - case OpLrot8: - return rewriteValue386_OpLrot8(v, config) case OpLsh16x16: return rewriteValue386_OpLsh16x16(v, config) case OpLsh16x32: @@ -661,6 +663,172 @@ func rewriteValue386_Op386ADDL(v *Value, config *Config) bool { v.AddArg(x) return true } + // match: (ADDL (SHLLconst [c] x) (SHRLconst [32-c] x)) + // cond: + // result: (ROLLconst [c ] x) + for { + v_0 := v.Args[0] + if v_0.Op != Op386SHLLconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != Op386SHRLconst { + break + } + if v_1.AuxInt != 32-c { + break + } + if x != v_1.Args[0] { + break + } + v.reset(Op386ROLLconst) + v.AuxInt = c + v.AddArg(x) + return true + } + // match: (ADDL (SHRLconst [c] x) (SHLLconst [32-c] x)) + // cond: + // result: (ROLLconst [32-c] x) + for { + v_0 := v.Args[0] + if v_0.Op != Op386SHRLconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != Op386SHLLconst { + break + } + if v_1.AuxInt != 32-c { + break + } + if x != v_1.Args[0] { + break + } + v.reset(Op386ROLLconst) + v.AuxInt = 32 - c + v.AddArg(x) + return true + } + // match: (ADDL (SHLLconst x [c]) (SHRWconst x [16-c])) + // cond: c < 16 && t.Size() == 2 + // result: (ROLWconst x [ c]) + for { + t := v.Type + v_0 := v.Args[0] + if v_0.Op != Op386SHLLconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != Op386SHRWconst { + break + } + if v_1.AuxInt != 16-c { + break + } + if x != v_1.Args[0] { + break + } + if !(c < 16 && t.Size() == 2) { + break + } + v.reset(Op386ROLWconst) + v.AuxInt = c + v.AddArg(x) + return true + } + // match: (ADDL (SHRWconst x [c]) (SHLLconst x [16-c])) + // cond: c > 0 && t.Size() == 2 + // result: (ROLWconst x [16-c]) + for { + t := v.Type + v_0 := v.Args[0] + if v_0.Op != Op386SHRWconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != Op386SHLLconst { + break + } + if v_1.AuxInt != 16-c { + break + } + if x != v_1.Args[0] { + break + } + if !(c > 0 && t.Size() == 2) { + break + } + v.reset(Op386ROLWconst) + v.AuxInt = 16 - c + v.AddArg(x) + return true + } + // match: (ADDL (SHLLconst x [c]) (SHRBconst x [ 8-c])) + // cond: c < 8 && t.Size() == 1 + // result: (ROLBconst x [ c]) + for { + t := v.Type + v_0 := v.Args[0] + if v_0.Op != Op386SHLLconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != Op386SHRBconst { + break + } + if v_1.AuxInt != 8-c { + break + } + if x != v_1.Args[0] { + break + } + if !(c < 8 && t.Size() == 1) { + break + } + v.reset(Op386ROLBconst) + v.AuxInt = c + v.AddArg(x) + return true + } + // match: (ADDL (SHRBconst x [c]) (SHLLconst x [ 8-c])) + // cond: c > 0 && t.Size() == 1 + // result: (ROLBconst x [ 8-c]) + for { + t := v.Type + v_0 := v.Args[0] + if v_0.Op != Op386SHRBconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != Op386SHLLconst { + break + } + if v_1.AuxInt != 8-c { + break + } + if x != v_1.Args[0] { + break + } + if !(c > 0 && t.Size() == 1) { + break + } + v.reset(Op386ROLBconst) + v.AuxInt = 8 - c + v.AddArg(x) + return true + } // match: (ADDL x (SHLLconst [3] y)) // cond: // result: (LEAL8 x y) @@ -7118,6 +7286,172 @@ func rewriteValue386_Op386ORL(v *Value, config *Config) bool { v.AddArg(x) return true } + // match: ( ORL (SHLLconst [c] x) (SHRLconst [32-c] x)) + // cond: + // result: (ROLLconst [c ] x) + for { + v_0 := v.Args[0] + if v_0.Op != Op386SHLLconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != Op386SHRLconst { + break + } + if v_1.AuxInt != 32-c { + break + } + if x != v_1.Args[0] { + break + } + v.reset(Op386ROLLconst) + v.AuxInt = c + v.AddArg(x) + return true + } + // match: ( ORL (SHRLconst [c] x) (SHLLconst [32-c] x)) + // cond: + // result: (ROLLconst [32-c] x) + for { + v_0 := v.Args[0] + if v_0.Op != Op386SHRLconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != Op386SHLLconst { + break + } + if v_1.AuxInt != 32-c { + break + } + if x != v_1.Args[0] { + break + } + v.reset(Op386ROLLconst) + v.AuxInt = 32 - c + v.AddArg(x) + return true + } + // match: ( ORL (SHLLconst x [c]) (SHRWconst x [16-c])) + // cond: c < 16 && t.Size() == 2 + // result: (ROLWconst x [ c]) + for { + t := v.Type + v_0 := v.Args[0] + if v_0.Op != Op386SHLLconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != Op386SHRWconst { + break + } + if v_1.AuxInt != 16-c { + break + } + if x != v_1.Args[0] { + break + } + if !(c < 16 && t.Size() == 2) { + break + } + v.reset(Op386ROLWconst) + v.AuxInt = c + v.AddArg(x) + return true + } + // match: ( ORL (SHRWconst x [c]) (SHLLconst x [16-c])) + // cond: c > 0 && t.Size() == 2 + // result: (ROLWconst x [16-c]) + for { + t := v.Type + v_0 := v.Args[0] + if v_0.Op != Op386SHRWconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != Op386SHLLconst { + break + } + if v_1.AuxInt != 16-c { + break + } + if x != v_1.Args[0] { + break + } + if !(c > 0 && t.Size() == 2) { + break + } + v.reset(Op386ROLWconst) + v.AuxInt = 16 - c + v.AddArg(x) + return true + } + // match: ( ORL (SHLLconst x [c]) (SHRBconst x [ 8-c])) + // cond: c < 8 && t.Size() == 1 + // result: (ROLBconst x [ c]) + for { + t := v.Type + v_0 := v.Args[0] + if v_0.Op != Op386SHLLconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != Op386SHRBconst { + break + } + if v_1.AuxInt != 8-c { + break + } + if x != v_1.Args[0] { + break + } + if !(c < 8 && t.Size() == 1) { + break + } + v.reset(Op386ROLBconst) + v.AuxInt = c + v.AddArg(x) + return true + } + // match: ( ORL (SHRBconst x [c]) (SHLLconst x [ 8-c])) + // cond: c > 0 && t.Size() == 1 + // result: (ROLBconst x [ 8-c]) + for { + t := v.Type + v_0 := v.Args[0] + if v_0.Op != Op386SHRBconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != Op386SHLLconst { + break + } + if v_1.AuxInt != 8-c { + break + } + if x != v_1.Args[0] { + break + } + if !(c > 0 && t.Size() == 1) { + break + } + v.reset(Op386ROLBconst) + v.AuxInt = 8 - c + v.AddArg(x) + return true + } // match: (ORL x x) // cond: // result: x @@ -7544,7 +7878,7 @@ func rewriteValue386_Op386SARB(v *Value, config *Config) bool { _ = b // match: (SARB x (MOVLconst [c])) // cond: - // result: (SARBconst [c&31] x) + // result: (SARBconst [min(c&31,7)] x) for { x := v.Args[0] v_1 := v.Args[1] @@ -7553,22 +7887,7 @@ func rewriteValue386_Op386SARB(v *Value, config *Config) bool { } c := v_1.AuxInt v.reset(Op386SARBconst) - v.AuxInt = c & 31 - v.AddArg(x) - return true - } - // match: (SARB x (MOVLconst [c])) - // cond: - // result: (SARBconst [c&31] x) - for { - x := v.Args[0] - v_1 := v.Args[1] - if v_1.Op != Op386MOVLconst { - break - } - c := v_1.AuxInt - v.reset(Op386SARBconst) - v.AuxInt = c & 31 + v.AuxInt = min(c&31, 7) v.AddArg(x) return true } @@ -7577,6 +7896,19 @@ func rewriteValue386_Op386SARB(v *Value, config *Config) bool { func rewriteValue386_Op386SARBconst(v *Value, config *Config) bool { b := v.Block _ = b + // match: (SARBconst x [0]) + // cond: + // result: x + for { + if v.AuxInt != 0 { + break + } + x := v.Args[0] + v.reset(OpCopy) + v.Type = x.Type + v.AddArg(x) + return true + } // match: (SARBconst [c] (MOVLconst [d])) // cond: // result: (MOVLconst [d>>uint64(c)]) @@ -7611,21 +7943,6 @@ func rewriteValue386_Op386SARL(v *Value, config *Config) bool { v.AddArg(x) return true } - // match: (SARL x (MOVLconst [c])) - // cond: - // result: (SARLconst [c&31] x) - for { - x := v.Args[0] - v_1 := v.Args[1] - if v_1.Op != Op386MOVLconst { - break - } - c := v_1.AuxInt - v.reset(Op386SARLconst) - v.AuxInt = c & 31 - v.AddArg(x) - return true - } // match: (SARL x (ANDLconst [31] y)) // cond: // result: (SARL x y) @@ -7649,6 +7966,19 @@ func rewriteValue386_Op386SARL(v *Value, config *Config) bool { func rewriteValue386_Op386SARLconst(v *Value, config *Config) bool { b := v.Block _ = b + // match: (SARLconst x [0]) + // cond: + // result: x + for { + if v.AuxInt != 0 { + break + } + x := v.Args[0] + v.reset(OpCopy) + v.Type = x.Type + v.AddArg(x) + return true + } // match: (SARLconst [c] (MOVLconst [d])) // cond: // result: (MOVLconst [d>>uint64(c)]) @@ -7670,7 +8000,7 @@ func rewriteValue386_Op386SARW(v *Value, config *Config) bool { _ = b // match: (SARW x (MOVLconst [c])) // cond: - // result: (SARWconst [c&31] x) + // result: (SARWconst [min(c&31,15)] x) for { x := v.Args[0] v_1 := v.Args[1] @@ -7679,22 +8009,7 @@ func rewriteValue386_Op386SARW(v *Value, config *Config) bool { } c := v_1.AuxInt v.reset(Op386SARWconst) - v.AuxInt = c & 31 - v.AddArg(x) - return true - } - // match: (SARW x (MOVLconst [c])) - // cond: - // result: (SARWconst [c&31] x) - for { - x := v.Args[0] - v_1 := v.Args[1] - if v_1.Op != Op386MOVLconst { - break - } - c := v_1.AuxInt - v.reset(Op386SARWconst) - v.AuxInt = c & 31 + v.AuxInt = min(c&31, 15) v.AddArg(x) return true } @@ -7703,6 +8018,19 @@ func rewriteValue386_Op386SARW(v *Value, config *Config) bool { func rewriteValue386_Op386SARWconst(v *Value, config *Config) bool { b := v.Block _ = b + // match: (SARWconst x [0]) + // cond: + // result: x + for { + if v.AuxInt != 0 { + break + } + x := v.Args[0] + v.reset(OpCopy) + v.Type = x.Type + v.AddArg(x) + return true + } // match: (SARWconst [c] (MOVLconst [d])) // cond: // result: (MOVLconst [d>>uint64(c)]) @@ -8604,21 +8932,6 @@ func rewriteValue386_Op386SHLL(v *Value, config *Config) bool { v.AddArg(x) return true } - // match: (SHLL x (MOVLconst [c])) - // cond: - // result: (SHLLconst [c&31] x) - for { - x := v.Args[0] - v_1 := v.Args[1] - if v_1.Op != Op386MOVLconst { - break - } - c := v_1.AuxInt - v.reset(Op386SHLLconst) - v.AuxInt = c & 31 - v.AddArg(x) - return true - } // match: (SHLL x (ANDLconst [31] y)) // cond: // result: (SHLL x y) @@ -8639,11 +8952,29 @@ func rewriteValue386_Op386SHLL(v *Value, config *Config) bool { } return false } +func rewriteValue386_Op386SHLLconst(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (SHLLconst x [0]) + // cond: + // result: x + for { + if v.AuxInt != 0 { + break + } + x := v.Args[0] + v.reset(OpCopy) + v.Type = x.Type + v.AddArg(x) + return true + } + return false +} func rewriteValue386_Op386SHRB(v *Value, config *Config) bool { b := v.Block _ = b // match: (SHRB x (MOVLconst [c])) - // cond: + // cond: c&31 < 8 // result: (SHRBconst [c&31] x) for { x := v.Args[0] @@ -8652,23 +8983,45 @@ func rewriteValue386_Op386SHRB(v *Value, config *Config) bool { break } c := v_1.AuxInt + if !(c&31 < 8) { + break + } v.reset(Op386SHRBconst) v.AuxInt = c & 31 v.AddArg(x) return true } - // match: (SHRB x (MOVLconst [c])) - // cond: - // result: (SHRBconst [c&31] x) + // match: (SHRB _ (MOVLconst [c])) + // cond: c&31 >= 8 + // result: (MOVLconst [0]) for { - x := v.Args[0] v_1 := v.Args[1] if v_1.Op != Op386MOVLconst { break } c := v_1.AuxInt - v.reset(Op386SHRBconst) - v.AuxInt = c & 31 + if !(c&31 >= 8) { + break + } + v.reset(Op386MOVLconst) + v.AuxInt = 0 + return true + } + return false +} +func rewriteValue386_Op386SHRBconst(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (SHRBconst x [0]) + // cond: + // result: x + for { + if v.AuxInt != 0 { + break + } + x := v.Args[0] + v.reset(OpCopy) + v.Type = x.Type v.AddArg(x) return true } @@ -8692,21 +9045,6 @@ func rewriteValue386_Op386SHRL(v *Value, config *Config) bool { v.AddArg(x) return true } - // match: (SHRL x (MOVLconst [c])) - // cond: - // result: (SHRLconst [c&31] x) - for { - x := v.Args[0] - v_1 := v.Args[1] - if v_1.Op != Op386MOVLconst { - break - } - c := v_1.AuxInt - v.reset(Op386SHRLconst) - v.AuxInt = c & 31 - v.AddArg(x) - return true - } // match: (SHRL x (ANDLconst [31] y)) // cond: // result: (SHRL x y) @@ -8727,11 +9065,29 @@ func rewriteValue386_Op386SHRL(v *Value, config *Config) bool { } return false } +func rewriteValue386_Op386SHRLconst(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (SHRLconst x [0]) + // cond: + // result: x + for { + if v.AuxInt != 0 { + break + } + x := v.Args[0] + v.reset(OpCopy) + v.Type = x.Type + v.AddArg(x) + return true + } + return false +} func rewriteValue386_Op386SHRW(v *Value, config *Config) bool { b := v.Block _ = b // match: (SHRW x (MOVLconst [c])) - // cond: + // cond: c&31 < 16 // result: (SHRWconst [c&31] x) for { x := v.Args[0] @@ -8740,23 +9096,45 @@ func rewriteValue386_Op386SHRW(v *Value, config *Config) bool { break } c := v_1.AuxInt + if !(c&31 < 16) { + break + } v.reset(Op386SHRWconst) v.AuxInt = c & 31 v.AddArg(x) return true } - // match: (SHRW x (MOVLconst [c])) - // cond: - // result: (SHRWconst [c&31] x) + // match: (SHRW _ (MOVLconst [c])) + // cond: c&31 >= 16 + // result: (MOVLconst [0]) for { - x := v.Args[0] v_1 := v.Args[1] if v_1.Op != Op386MOVLconst { break } c := v_1.AuxInt - v.reset(Op386SHRWconst) - v.AuxInt = c & 31 + if !(c&31 >= 16) { + break + } + v.reset(Op386MOVLconst) + v.AuxInt = 0 + return true + } + return false +} +func rewriteValue386_Op386SHRWconst(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (SHRWconst x [0]) + // cond: + // result: x + for { + if v.AuxInt != 0 { + break + } + x := v.Args[0] + v.reset(OpCopy) + v.Type = x.Type v.AddArg(x) return true } @@ -8893,6 +9271,172 @@ func rewriteValue386_Op386XORL(v *Value, config *Config) bool { v.AddArg(x) return true } + // match: (XORL (SHLLconst [c] x) (SHRLconst [32-c] x)) + // cond: + // result: (ROLLconst [c ] x) + for { + v_0 := v.Args[0] + if v_0.Op != Op386SHLLconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != Op386SHRLconst { + break + } + if v_1.AuxInt != 32-c { + break + } + if x != v_1.Args[0] { + break + } + v.reset(Op386ROLLconst) + v.AuxInt = c + v.AddArg(x) + return true + } + // match: (XORL (SHRLconst [c] x) (SHLLconst [32-c] x)) + // cond: + // result: (ROLLconst [32-c] x) + for { + v_0 := v.Args[0] + if v_0.Op != Op386SHRLconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != Op386SHLLconst { + break + } + if v_1.AuxInt != 32-c { + break + } + if x != v_1.Args[0] { + break + } + v.reset(Op386ROLLconst) + v.AuxInt = 32 - c + v.AddArg(x) + return true + } + // match: (XORL (SHLLconst x [c]) (SHRWconst x [16-c])) + // cond: c < 16 && t.Size() == 2 + // result: (ROLWconst x [ c]) + for { + t := v.Type + v_0 := v.Args[0] + if v_0.Op != Op386SHLLconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != Op386SHRWconst { + break + } + if v_1.AuxInt != 16-c { + break + } + if x != v_1.Args[0] { + break + } + if !(c < 16 && t.Size() == 2) { + break + } + v.reset(Op386ROLWconst) + v.AuxInt = c + v.AddArg(x) + return true + } + // match: (XORL (SHRWconst x [c]) (SHLLconst x [16-c])) + // cond: c > 0 && t.Size() == 2 + // result: (ROLWconst x [16-c]) + for { + t := v.Type + v_0 := v.Args[0] + if v_0.Op != Op386SHRWconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != Op386SHLLconst { + break + } + if v_1.AuxInt != 16-c { + break + } + if x != v_1.Args[0] { + break + } + if !(c > 0 && t.Size() == 2) { + break + } + v.reset(Op386ROLWconst) + v.AuxInt = 16 - c + v.AddArg(x) + return true + } + // match: (XORL (SHLLconst x [c]) (SHRBconst x [ 8-c])) + // cond: c < 8 && t.Size() == 1 + // result: (ROLBconst x [ c]) + for { + t := v.Type + v_0 := v.Args[0] + if v_0.Op != Op386SHLLconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != Op386SHRBconst { + break + } + if v_1.AuxInt != 8-c { + break + } + if x != v_1.Args[0] { + break + } + if !(c < 8 && t.Size() == 1) { + break + } + v.reset(Op386ROLBconst) + v.AuxInt = c + v.AddArg(x) + return true + } + // match: (XORL (SHRBconst x [c]) (SHLLconst x [ 8-c])) + // cond: c > 0 && t.Size() == 1 + // result: (ROLBconst x [ 8-c]) + for { + t := v.Type + v_0 := v.Args[0] + if v_0.Op != Op386SHRBconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != Op386SHLLconst { + break + } + if v_1.AuxInt != 8-c { + break + } + if x != v_1.Args[0] { + break + } + if !(c > 0 && t.Size() == 1) { + break + } + v.reset(Op386ROLBconst) + v.AuxInt = 8 - c + v.AddArg(x) + return true + } // match: (XORL x x) // cond: // result: (MOVLconst [0]) @@ -10491,57 +11035,6 @@ func rewriteValue386_OpLoad(v *Value, config *Config) bool { } return false } -func rewriteValue386_OpLrot16(v *Value, config *Config) bool { - b := v.Block - _ = b - // match: (Lrot16 x [c]) - // cond: - // result: (ROLWconst [c&15] x) - for { - t := v.Type - c := v.AuxInt - x := v.Args[0] - v.reset(Op386ROLWconst) - v.Type = t - v.AuxInt = c & 15 - v.AddArg(x) - return true - } -} -func rewriteValue386_OpLrot32(v *Value, config *Config) bool { - b := v.Block - _ = b - // match: (Lrot32 x [c]) - // cond: - // result: (ROLLconst [c&31] x) - for { - t := v.Type - c := v.AuxInt - x := v.Args[0] - v.reset(Op386ROLLconst) - v.Type = t - v.AuxInt = c & 31 - v.AddArg(x) - return true - } -} -func rewriteValue386_OpLrot8(v *Value, config *Config) bool { - b := v.Block - _ = b - // match: (Lrot8 x [c]) - // cond: - // result: (ROLBconst [c&7] x) - for { - t := v.Type - c := v.AuxInt - x := v.Args[0] - v.reset(Op386ROLBconst) - v.Type = t - v.AuxInt = c & 7 - v.AddArg(x) - return true - } -} func rewriteValue386_OpLsh16x16(v *Value, config *Config) bool { b := v.Block _ = b diff --git a/src/cmd/compile/internal/ssa/rewriteAMD64.go b/src/cmd/compile/internal/ssa/rewriteAMD64.go index 2b05e9b9821..680f212bb76 100644 --- a/src/cmd/compile/internal/ssa/rewriteAMD64.go +++ b/src/cmd/compile/internal/ssa/rewriteAMD64.go @@ -246,16 +246,28 @@ func rewriteValueAMD64(v *Value, config *Config) bool { return rewriteValueAMD64_OpAMD64SETNE(v, config) case OpAMD64SHLL: return rewriteValueAMD64_OpAMD64SHLL(v, config) + case OpAMD64SHLLconst: + return rewriteValueAMD64_OpAMD64SHLLconst(v, config) case OpAMD64SHLQ: return rewriteValueAMD64_OpAMD64SHLQ(v, config) + case OpAMD64SHLQconst: + return rewriteValueAMD64_OpAMD64SHLQconst(v, config) case OpAMD64SHRB: return rewriteValueAMD64_OpAMD64SHRB(v, config) + case OpAMD64SHRBconst: + return rewriteValueAMD64_OpAMD64SHRBconst(v, config) case OpAMD64SHRL: return rewriteValueAMD64_OpAMD64SHRL(v, config) + case OpAMD64SHRLconst: + return rewriteValueAMD64_OpAMD64SHRLconst(v, config) case OpAMD64SHRQ: return rewriteValueAMD64_OpAMD64SHRQ(v, config) + case OpAMD64SHRQconst: + return rewriteValueAMD64_OpAMD64SHRQconst(v, config) case OpAMD64SHRW: return rewriteValueAMD64_OpAMD64SHRW(v, config) + case OpAMD64SHRWconst: + return rewriteValueAMD64_OpAMD64SHRWconst(v, config) case OpAMD64SUBL: return rewriteValueAMD64_OpAMD64SUBL(v, config) case OpAMD64SUBLconst: @@ -546,14 +558,6 @@ func rewriteValueAMD64(v *Value, config *Config) bool { return rewriteValueAMD64_OpLess8U(v, config) case OpLoad: return rewriteValueAMD64_OpLoad(v, config) - case OpLrot16: - return rewriteValueAMD64_OpLrot16(v, config) - case OpLrot32: - return rewriteValueAMD64_OpLrot32(v, config) - case OpLrot64: - return rewriteValueAMD64_OpLrot64(v, config) - case OpLrot8: - return rewriteValueAMD64_OpLrot8(v, config) case OpLsh16x16: return rewriteValueAMD64_OpLsh16x16(v, config) case OpLsh16x32: @@ -834,6 +838,172 @@ func rewriteValueAMD64_OpAMD64ADDL(v *Value, config *Config) bool { v.AddArg(x) return true } + // match: (ADDL (SHLLconst x [c]) (SHRLconst x [32-c])) + // cond: + // result: (ROLLconst x [ c]) + for { + v_0 := v.Args[0] + if v_0.Op != OpAMD64SHLLconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpAMD64SHRLconst { + break + } + if v_1.AuxInt != 32-c { + break + } + if x != v_1.Args[0] { + break + } + v.reset(OpAMD64ROLLconst) + v.AuxInt = c + v.AddArg(x) + return true + } + // match: (ADDL (SHRLconst x [c]) (SHLLconst x [32-c])) + // cond: + // result: (ROLLconst x [32-c]) + for { + v_0 := v.Args[0] + if v_0.Op != OpAMD64SHRLconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpAMD64SHLLconst { + break + } + if v_1.AuxInt != 32-c { + break + } + if x != v_1.Args[0] { + break + } + v.reset(OpAMD64ROLLconst) + v.AuxInt = 32 - c + v.AddArg(x) + return true + } + // match: (ADDL (SHLLconst x [c]) (SHRWconst x [16-c])) + // cond: c < 16 && t.Size() == 2 + // result: (ROLWconst x [ c]) + for { + t := v.Type + v_0 := v.Args[0] + if v_0.Op != OpAMD64SHLLconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpAMD64SHRWconst { + break + } + if v_1.AuxInt != 16-c { + break + } + if x != v_1.Args[0] { + break + } + if !(c < 16 && t.Size() == 2) { + break + } + v.reset(OpAMD64ROLWconst) + v.AuxInt = c + v.AddArg(x) + return true + } + // match: (ADDL (SHRWconst x [c]) (SHLLconst x [16-c])) + // cond: c > 0 && t.Size() == 2 + // result: (ROLWconst x [16-c]) + for { + t := v.Type + v_0 := v.Args[0] + if v_0.Op != OpAMD64SHRWconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpAMD64SHLLconst { + break + } + if v_1.AuxInt != 16-c { + break + } + if x != v_1.Args[0] { + break + } + if !(c > 0 && t.Size() == 2) { + break + } + v.reset(OpAMD64ROLWconst) + v.AuxInt = 16 - c + v.AddArg(x) + return true + } + // match: (ADDL (SHLLconst x [c]) (SHRBconst x [ 8-c])) + // cond: c < 8 && t.Size() == 1 + // result: (ROLBconst x [ c]) + for { + t := v.Type + v_0 := v.Args[0] + if v_0.Op != OpAMD64SHLLconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpAMD64SHRBconst { + break + } + if v_1.AuxInt != 8-c { + break + } + if x != v_1.Args[0] { + break + } + if !(c < 8 && t.Size() == 1) { + break + } + v.reset(OpAMD64ROLBconst) + v.AuxInt = c + v.AddArg(x) + return true + } + // match: (ADDL (SHRBconst x [c]) (SHLLconst x [ 8-c])) + // cond: c > 0 && t.Size() == 1 + // result: (ROLBconst x [ 8-c]) + for { + t := v.Type + v_0 := v.Args[0] + if v_0.Op != OpAMD64SHRBconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpAMD64SHLLconst { + break + } + if v_1.AuxInt != 8-c { + break + } + if x != v_1.Args[0] { + break + } + if !(c > 0 && t.Size() == 1) { + break + } + v.reset(OpAMD64ROLBconst) + v.AuxInt = 8 - c + v.AddArg(x) + return true + } // match: (ADDL x (NEGL y)) // cond: // result: (SUBL x y) @@ -960,6 +1130,56 @@ func rewriteValueAMD64_OpAMD64ADDQ(v *Value, config *Config) bool { v.AddArg(x) return true } + // match: (ADDQ (SHLQconst x [c]) (SHRQconst x [64-c])) + // cond: + // result: (ROLQconst x [ c]) + for { + v_0 := v.Args[0] + if v_0.Op != OpAMD64SHLQconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpAMD64SHRQconst { + break + } + if v_1.AuxInt != 64-c { + break + } + if x != v_1.Args[0] { + break + } + v.reset(OpAMD64ROLQconst) + v.AuxInt = c + v.AddArg(x) + return true + } + // match: (ADDQ (SHRQconst x [c]) (SHLQconst x [64-c])) + // cond: + // result: (ROLQconst x [64-c]) + for { + v_0 := v.Args[0] + if v_0.Op != OpAMD64SHRQconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpAMD64SHLQconst { + break + } + if v_1.AuxInt != 64-c { + break + } + if x != v_1.Args[0] { + break + } + v.reset(OpAMD64ROLQconst) + v.AuxInt = 64 - c + v.AddArg(x) + return true + } // match: (ADDQ x (SHLQconst [3] y)) // cond: // result: (LEAQ8 x y) @@ -10883,6 +11103,172 @@ func rewriteValueAMD64_OpAMD64ORL(v *Value, config *Config) bool { v.AddArg(x) return true } + // match: ( ORL (SHLLconst x [c]) (SHRLconst x [32-c])) + // cond: + // result: (ROLLconst x [ c]) + for { + v_0 := v.Args[0] + if v_0.Op != OpAMD64SHLLconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpAMD64SHRLconst { + break + } + if v_1.AuxInt != 32-c { + break + } + if x != v_1.Args[0] { + break + } + v.reset(OpAMD64ROLLconst) + v.AuxInt = c + v.AddArg(x) + return true + } + // match: ( ORL (SHRLconst x [c]) (SHLLconst x [32-c])) + // cond: + // result: (ROLLconst x [32-c]) + for { + v_0 := v.Args[0] + if v_0.Op != OpAMD64SHRLconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpAMD64SHLLconst { + break + } + if v_1.AuxInt != 32-c { + break + } + if x != v_1.Args[0] { + break + } + v.reset(OpAMD64ROLLconst) + v.AuxInt = 32 - c + v.AddArg(x) + return true + } + // match: ( ORL (SHLLconst x [c]) (SHRWconst x [16-c])) + // cond: c < 16 && t.Size() == 2 + // result: (ROLWconst x [ c]) + for { + t := v.Type + v_0 := v.Args[0] + if v_0.Op != OpAMD64SHLLconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpAMD64SHRWconst { + break + } + if v_1.AuxInt != 16-c { + break + } + if x != v_1.Args[0] { + break + } + if !(c < 16 && t.Size() == 2) { + break + } + v.reset(OpAMD64ROLWconst) + v.AuxInt = c + v.AddArg(x) + return true + } + // match: ( ORL (SHRWconst x [c]) (SHLLconst x [16-c])) + // cond: c > 0 && t.Size() == 2 + // result: (ROLWconst x [16-c]) + for { + t := v.Type + v_0 := v.Args[0] + if v_0.Op != OpAMD64SHRWconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpAMD64SHLLconst { + break + } + if v_1.AuxInt != 16-c { + break + } + if x != v_1.Args[0] { + break + } + if !(c > 0 && t.Size() == 2) { + break + } + v.reset(OpAMD64ROLWconst) + v.AuxInt = 16 - c + v.AddArg(x) + return true + } + // match: ( ORL (SHLLconst x [c]) (SHRBconst x [ 8-c])) + // cond: c < 8 && t.Size() == 1 + // result: (ROLBconst x [ c]) + for { + t := v.Type + v_0 := v.Args[0] + if v_0.Op != OpAMD64SHLLconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpAMD64SHRBconst { + break + } + if v_1.AuxInt != 8-c { + break + } + if x != v_1.Args[0] { + break + } + if !(c < 8 && t.Size() == 1) { + break + } + v.reset(OpAMD64ROLBconst) + v.AuxInt = c + v.AddArg(x) + return true + } + // match: ( ORL (SHRBconst x [c]) (SHLLconst x [ 8-c])) + // cond: c > 0 && t.Size() == 1 + // result: (ROLBconst x [ 8-c]) + for { + t := v.Type + v_0 := v.Args[0] + if v_0.Op != OpAMD64SHRBconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpAMD64SHLLconst { + break + } + if v_1.AuxInt != 8-c { + break + } + if x != v_1.Args[0] { + break + } + if !(c > 0 && t.Size() == 1) { + break + } + v.reset(OpAMD64ROLBconst) + v.AuxInt = 8 - c + v.AddArg(x) + return true + } // match: (ORL x x) // cond: // result: x @@ -11460,6 +11846,56 @@ func rewriteValueAMD64_OpAMD64ORQ(v *Value, config *Config) bool { v.AddArg(x) return true } + // match: ( ORQ (SHLQconst x [c]) (SHRQconst x [64-c])) + // cond: + // result: (ROLQconst x [ c]) + for { + v_0 := v.Args[0] + if v_0.Op != OpAMD64SHLQconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpAMD64SHRQconst { + break + } + if v_1.AuxInt != 64-c { + break + } + if x != v_1.Args[0] { + break + } + v.reset(OpAMD64ROLQconst) + v.AuxInt = c + v.AddArg(x) + return true + } + // match: ( ORQ (SHRQconst x [c]) (SHLQconst x [64-c])) + // cond: + // result: (ROLQconst x [64-c]) + for { + v_0 := v.Args[0] + if v_0.Op != OpAMD64SHRQconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpAMD64SHLQconst { + break + } + if v_1.AuxInt != 64-c { + break + } + if x != v_1.Args[0] { + break + } + v.reset(OpAMD64ROLQconst) + v.AuxInt = 64 - c + v.AddArg(x) + return true + } // match: (ORQ x x) // cond: // result: x @@ -12427,7 +12863,7 @@ func rewriteValueAMD64_OpAMD64ROLBconst(v *Value, config *Config) bool { v.AddArg(x) return true } - // match: (ROLBconst [0] x) + // match: (ROLBconst x [0]) // cond: // result: x for { @@ -12461,7 +12897,7 @@ func rewriteValueAMD64_OpAMD64ROLLconst(v *Value, config *Config) bool { v.AddArg(x) return true } - // match: (ROLLconst [0] x) + // match: (ROLLconst x [0]) // cond: // result: x for { @@ -12495,7 +12931,7 @@ func rewriteValueAMD64_OpAMD64ROLQconst(v *Value, config *Config) bool { v.AddArg(x) return true } - // match: (ROLQconst [0] x) + // match: (ROLQconst x [0]) // cond: // result: x for { @@ -12529,7 +12965,7 @@ func rewriteValueAMD64_OpAMD64ROLWconst(v *Value, config *Config) bool { v.AddArg(x) return true } - // match: (ROLWconst [0] x) + // match: (ROLWconst x [0]) // cond: // result: x for { @@ -12549,7 +12985,7 @@ func rewriteValueAMD64_OpAMD64SARB(v *Value, config *Config) bool { _ = b // match: (SARB x (MOVQconst [c])) // cond: - // result: (SARBconst [c&31] x) + // result: (SARBconst [min(c&31,7)] x) for { x := v.Args[0] v_1 := v.Args[1] @@ -12558,13 +12994,13 @@ func rewriteValueAMD64_OpAMD64SARB(v *Value, config *Config) bool { } c := v_1.AuxInt v.reset(OpAMD64SARBconst) - v.AuxInt = c & 31 + v.AuxInt = min(c&31, 7) v.AddArg(x) return true } // match: (SARB x (MOVLconst [c])) // cond: - // result: (SARBconst [c&31] x) + // result: (SARBconst [min(c&31,7)] x) for { x := v.Args[0] v_1 := v.Args[1] @@ -12573,7 +13009,7 @@ func rewriteValueAMD64_OpAMD64SARB(v *Value, config *Config) bool { } c := v_1.AuxInt v.reset(OpAMD64SARBconst) - v.AuxInt = c & 31 + v.AuxInt = min(c&31, 7) v.AddArg(x) return true } @@ -12582,6 +13018,19 @@ func rewriteValueAMD64_OpAMD64SARB(v *Value, config *Config) bool { func rewriteValueAMD64_OpAMD64SARBconst(v *Value, config *Config) bool { b := v.Block _ = b + // match: (SARBconst x [0]) + // cond: + // result: x + for { + if v.AuxInt != 0 { + break + } + x := v.Args[0] + v.reset(OpCopy) + v.Type = x.Type + v.AddArg(x) + return true + } // match: (SARBconst [c] (MOVQconst [d])) // cond: // result: (MOVQconst [d>>uint64(c)]) @@ -12654,6 +13103,19 @@ func rewriteValueAMD64_OpAMD64SARL(v *Value, config *Config) bool { func rewriteValueAMD64_OpAMD64SARLconst(v *Value, config *Config) bool { b := v.Block _ = b + // match: (SARLconst x [0]) + // cond: + // result: x + for { + if v.AuxInt != 0 { + break + } + x := v.Args[0] + v.reset(OpCopy) + v.Type = x.Type + v.AddArg(x) + return true + } // match: (SARLconst [c] (MOVQconst [d])) // cond: // result: (MOVQconst [d>>uint64(c)]) @@ -12726,6 +13188,19 @@ func rewriteValueAMD64_OpAMD64SARQ(v *Value, config *Config) bool { func rewriteValueAMD64_OpAMD64SARQconst(v *Value, config *Config) bool { b := v.Block _ = b + // match: (SARQconst x [0]) + // cond: + // result: x + for { + if v.AuxInt != 0 { + break + } + x := v.Args[0] + v.reset(OpCopy) + v.Type = x.Type + v.AddArg(x) + return true + } // match: (SARQconst [c] (MOVQconst [d])) // cond: // result: (MOVQconst [d>>uint64(c)]) @@ -12747,7 +13222,7 @@ func rewriteValueAMD64_OpAMD64SARW(v *Value, config *Config) bool { _ = b // match: (SARW x (MOVQconst [c])) // cond: - // result: (SARWconst [c&31] x) + // result: (SARWconst [min(c&31,15)] x) for { x := v.Args[0] v_1 := v.Args[1] @@ -12756,13 +13231,13 @@ func rewriteValueAMD64_OpAMD64SARW(v *Value, config *Config) bool { } c := v_1.AuxInt v.reset(OpAMD64SARWconst) - v.AuxInt = c & 31 + v.AuxInt = min(c&31, 15) v.AddArg(x) return true } // match: (SARW x (MOVLconst [c])) // cond: - // result: (SARWconst [c&31] x) + // result: (SARWconst [min(c&31,15)] x) for { x := v.Args[0] v_1 := v.Args[1] @@ -12771,7 +13246,7 @@ func rewriteValueAMD64_OpAMD64SARW(v *Value, config *Config) bool { } c := v_1.AuxInt v.reset(OpAMD64SARWconst) - v.AuxInt = c & 31 + v.AuxInt = min(c&31, 15) v.AddArg(x) return true } @@ -12780,6 +13255,19 @@ func rewriteValueAMD64_OpAMD64SARW(v *Value, config *Config) bool { func rewriteValueAMD64_OpAMD64SARWconst(v *Value, config *Config) bool { b := v.Block _ = b + // match: (SARWconst x [0]) + // cond: + // result: x + for { + if v.AuxInt != 0 { + break + } + x := v.Args[0] + v.reset(OpCopy) + v.Type = x.Type + v.AddArg(x) + return true + } // match: (SARWconst [c] (MOVQconst [d])) // cond: // result: (MOVQconst [d>>uint64(c)]) @@ -13759,6 +14247,24 @@ func rewriteValueAMD64_OpAMD64SHLL(v *Value, config *Config) bool { } return false } +func rewriteValueAMD64_OpAMD64SHLLconst(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (SHLLconst x [0]) + // cond: + // result: x + for { + if v.AuxInt != 0 { + break + } + x := v.Args[0] + v.reset(OpCopy) + v.Type = x.Type + v.AddArg(x) + return true + } + return false +} func rewriteValueAMD64_OpAMD64SHLQ(v *Value, config *Config) bool { b := v.Block _ = b @@ -13812,11 +14318,29 @@ func rewriteValueAMD64_OpAMD64SHLQ(v *Value, config *Config) bool { } return false } +func rewriteValueAMD64_OpAMD64SHLQconst(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (SHLQconst x [0]) + // cond: + // result: x + for { + if v.AuxInt != 0 { + break + } + x := v.Args[0] + v.reset(OpCopy) + v.Type = x.Type + v.AddArg(x) + return true + } + return false +} func rewriteValueAMD64_OpAMD64SHRB(v *Value, config *Config) bool { b := v.Block _ = b // match: (SHRB x (MOVQconst [c])) - // cond: + // cond: c&31 < 8 // result: (SHRBconst [c&31] x) for { x := v.Args[0] @@ -13825,13 +14349,16 @@ func rewriteValueAMD64_OpAMD64SHRB(v *Value, config *Config) bool { break } c := v_1.AuxInt + if !(c&31 < 8) { + break + } v.reset(OpAMD64SHRBconst) v.AuxInt = c & 31 v.AddArg(x) return true } // match: (SHRB x (MOVLconst [c])) - // cond: + // cond: c&31 < 8 // result: (SHRBconst [c&31] x) for { x := v.Args[0] @@ -13840,11 +14367,64 @@ func rewriteValueAMD64_OpAMD64SHRB(v *Value, config *Config) bool { break } c := v_1.AuxInt + if !(c&31 < 8) { + break + } v.reset(OpAMD64SHRBconst) v.AuxInt = c & 31 v.AddArg(x) return true } + // match: (SHRB _ (MOVQconst [c])) + // cond: c&31 >= 8 + // result: (MOVLconst [0]) + for { + v_1 := v.Args[1] + if v_1.Op != OpAMD64MOVQconst { + break + } + c := v_1.AuxInt + if !(c&31 >= 8) { + break + } + v.reset(OpAMD64MOVLconst) + v.AuxInt = 0 + return true + } + // match: (SHRB _ (MOVLconst [c])) + // cond: c&31 >= 8 + // result: (MOVLconst [0]) + for { + v_1 := v.Args[1] + if v_1.Op != OpAMD64MOVLconst { + break + } + c := v_1.AuxInt + if !(c&31 >= 8) { + break + } + v.reset(OpAMD64MOVLconst) + v.AuxInt = 0 + return true + } + return false +} +func rewriteValueAMD64_OpAMD64SHRBconst(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (SHRBconst x [0]) + // cond: + // result: x + for { + if v.AuxInt != 0 { + break + } + x := v.Args[0] + v.reset(OpCopy) + v.Type = x.Type + v.AddArg(x) + return true + } return false } func rewriteValueAMD64_OpAMD64SHRL(v *Value, config *Config) bool { @@ -13900,6 +14480,24 @@ func rewriteValueAMD64_OpAMD64SHRL(v *Value, config *Config) bool { } return false } +func rewriteValueAMD64_OpAMD64SHRLconst(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (SHRLconst x [0]) + // cond: + // result: x + for { + if v.AuxInt != 0 { + break + } + x := v.Args[0] + v.reset(OpCopy) + v.Type = x.Type + v.AddArg(x) + return true + } + return false +} func rewriteValueAMD64_OpAMD64SHRQ(v *Value, config *Config) bool { b := v.Block _ = b @@ -13953,11 +14551,29 @@ func rewriteValueAMD64_OpAMD64SHRQ(v *Value, config *Config) bool { } return false } +func rewriteValueAMD64_OpAMD64SHRQconst(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (SHRQconst x [0]) + // cond: + // result: x + for { + if v.AuxInt != 0 { + break + } + x := v.Args[0] + v.reset(OpCopy) + v.Type = x.Type + v.AddArg(x) + return true + } + return false +} func rewriteValueAMD64_OpAMD64SHRW(v *Value, config *Config) bool { b := v.Block _ = b // match: (SHRW x (MOVQconst [c])) - // cond: + // cond: c&31 < 16 // result: (SHRWconst [c&31] x) for { x := v.Args[0] @@ -13966,13 +14582,16 @@ func rewriteValueAMD64_OpAMD64SHRW(v *Value, config *Config) bool { break } c := v_1.AuxInt + if !(c&31 < 16) { + break + } v.reset(OpAMD64SHRWconst) v.AuxInt = c & 31 v.AddArg(x) return true } // match: (SHRW x (MOVLconst [c])) - // cond: + // cond: c&31 < 16 // result: (SHRWconst [c&31] x) for { x := v.Args[0] @@ -13981,11 +14600,64 @@ func rewriteValueAMD64_OpAMD64SHRW(v *Value, config *Config) bool { break } c := v_1.AuxInt + if !(c&31 < 16) { + break + } v.reset(OpAMD64SHRWconst) v.AuxInt = c & 31 v.AddArg(x) return true } + // match: (SHRW _ (MOVQconst [c])) + // cond: c&31 >= 16 + // result: (MOVLconst [0]) + for { + v_1 := v.Args[1] + if v_1.Op != OpAMD64MOVQconst { + break + } + c := v_1.AuxInt + if !(c&31 >= 16) { + break + } + v.reset(OpAMD64MOVLconst) + v.AuxInt = 0 + return true + } + // match: (SHRW _ (MOVLconst [c])) + // cond: c&31 >= 16 + // result: (MOVLconst [0]) + for { + v_1 := v.Args[1] + if v_1.Op != OpAMD64MOVLconst { + break + } + c := v_1.AuxInt + if !(c&31 >= 16) { + break + } + v.reset(OpAMD64MOVLconst) + v.AuxInt = 0 + return true + } + return false +} +func rewriteValueAMD64_OpAMD64SHRWconst(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (SHRWconst x [0]) + // cond: + // result: x + for { + if v.AuxInt != 0 { + break + } + x := v.Args[0] + v.reset(OpCopy) + v.Type = x.Type + v.AddArg(x) + return true + } return false } func rewriteValueAMD64_OpAMD64SUBL(v *Value, config *Config) bool { @@ -14391,6 +15063,172 @@ func rewriteValueAMD64_OpAMD64XORL(v *Value, config *Config) bool { v.AddArg(x) return true } + // match: (XORL (SHLLconst x [c]) (SHRLconst x [32-c])) + // cond: + // result: (ROLLconst x [ c]) + for { + v_0 := v.Args[0] + if v_0.Op != OpAMD64SHLLconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpAMD64SHRLconst { + break + } + if v_1.AuxInt != 32-c { + break + } + if x != v_1.Args[0] { + break + } + v.reset(OpAMD64ROLLconst) + v.AuxInt = c + v.AddArg(x) + return true + } + // match: (XORL (SHRLconst x [c]) (SHLLconst x [32-c])) + // cond: + // result: (ROLLconst x [32-c]) + for { + v_0 := v.Args[0] + if v_0.Op != OpAMD64SHRLconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpAMD64SHLLconst { + break + } + if v_1.AuxInt != 32-c { + break + } + if x != v_1.Args[0] { + break + } + v.reset(OpAMD64ROLLconst) + v.AuxInt = 32 - c + v.AddArg(x) + return true + } + // match: (XORL (SHLLconst x [c]) (SHRWconst x [16-c])) + // cond: c < 16 && t.Size() == 2 + // result: (ROLWconst x [ c]) + for { + t := v.Type + v_0 := v.Args[0] + if v_0.Op != OpAMD64SHLLconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpAMD64SHRWconst { + break + } + if v_1.AuxInt != 16-c { + break + } + if x != v_1.Args[0] { + break + } + if !(c < 16 && t.Size() == 2) { + break + } + v.reset(OpAMD64ROLWconst) + v.AuxInt = c + v.AddArg(x) + return true + } + // match: (XORL (SHRWconst x [c]) (SHLLconst x [16-c])) + // cond: c > 0 && t.Size() == 2 + // result: (ROLWconst x [16-c]) + for { + t := v.Type + v_0 := v.Args[0] + if v_0.Op != OpAMD64SHRWconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpAMD64SHLLconst { + break + } + if v_1.AuxInt != 16-c { + break + } + if x != v_1.Args[0] { + break + } + if !(c > 0 && t.Size() == 2) { + break + } + v.reset(OpAMD64ROLWconst) + v.AuxInt = 16 - c + v.AddArg(x) + return true + } + // match: (XORL (SHLLconst x [c]) (SHRBconst x [ 8-c])) + // cond: c < 8 && t.Size() == 1 + // result: (ROLBconst x [ c]) + for { + t := v.Type + v_0 := v.Args[0] + if v_0.Op != OpAMD64SHLLconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpAMD64SHRBconst { + break + } + if v_1.AuxInt != 8-c { + break + } + if x != v_1.Args[0] { + break + } + if !(c < 8 && t.Size() == 1) { + break + } + v.reset(OpAMD64ROLBconst) + v.AuxInt = c + v.AddArg(x) + return true + } + // match: (XORL (SHRBconst x [c]) (SHLLconst x [ 8-c])) + // cond: c > 0 && t.Size() == 1 + // result: (ROLBconst x [ 8-c]) + for { + t := v.Type + v_0 := v.Args[0] + if v_0.Op != OpAMD64SHRBconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpAMD64SHLLconst { + break + } + if v_1.AuxInt != 8-c { + break + } + if x != v_1.Args[0] { + break + } + if !(c > 0 && t.Size() == 1) { + break + } + v.reset(OpAMD64ROLBconst) + v.AuxInt = 8 - c + v.AddArg(x) + return true + } // match: (XORL x x) // cond: // result: (MOVLconst [0]) @@ -14493,6 +15331,56 @@ func rewriteValueAMD64_OpAMD64XORQ(v *Value, config *Config) bool { v.AddArg(x) return true } + // match: (XORQ (SHLQconst x [c]) (SHRQconst x [64-c])) + // cond: + // result: (ROLQconst x [ c]) + for { + v_0 := v.Args[0] + if v_0.Op != OpAMD64SHLQconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpAMD64SHRQconst { + break + } + if v_1.AuxInt != 64-c { + break + } + if x != v_1.Args[0] { + break + } + v.reset(OpAMD64ROLQconst) + v.AuxInt = c + v.AddArg(x) + return true + } + // match: (XORQ (SHRQconst x [c]) (SHLQconst x [64-c])) + // cond: + // result: (ROLQconst x [64-c]) + for { + v_0 := v.Args[0] + if v_0.Op != OpAMD64SHRQconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpAMD64SHLQconst { + break + } + if v_1.AuxInt != 64-c { + break + } + if x != v_1.Args[0] { + break + } + v.reset(OpAMD64ROLQconst) + v.AuxInt = 64 - c + v.AddArg(x) + return true + } // match: (XORQ x x) // cond: // result: (MOVQconst [0]) @@ -16919,74 +17807,6 @@ func rewriteValueAMD64_OpLoad(v *Value, config *Config) bool { } return false } -func rewriteValueAMD64_OpLrot16(v *Value, config *Config) bool { - b := v.Block - _ = b - // match: (Lrot16 x [c]) - // cond: - // result: (ROLWconst [c&15] x) - for { - t := v.Type - c := v.AuxInt - x := v.Args[0] - v.reset(OpAMD64ROLWconst) - v.Type = t - v.AuxInt = c & 15 - v.AddArg(x) - return true - } -} -func rewriteValueAMD64_OpLrot32(v *Value, config *Config) bool { - b := v.Block - _ = b - // match: (Lrot32 x [c]) - // cond: - // result: (ROLLconst [c&31] x) - for { - t := v.Type - c := v.AuxInt - x := v.Args[0] - v.reset(OpAMD64ROLLconst) - v.Type = t - v.AuxInt = c & 31 - v.AddArg(x) - return true - } -} -func rewriteValueAMD64_OpLrot64(v *Value, config *Config) bool { - b := v.Block - _ = b - // match: (Lrot64 x [c]) - // cond: - // result: (ROLQconst [c&63] x) - for { - t := v.Type - c := v.AuxInt - x := v.Args[0] - v.reset(OpAMD64ROLQconst) - v.Type = t - v.AuxInt = c & 63 - v.AddArg(x) - return true - } -} -func rewriteValueAMD64_OpLrot8(v *Value, config *Config) bool { - b := v.Block - _ = b - // match: (Lrot8 x [c]) - // cond: - // result: (ROLBconst [c&7] x) - for { - t := v.Type - c := v.AuxInt - x := v.Args[0] - v.reset(OpAMD64ROLBconst) - v.Type = t - v.AuxInt = c & 7 - v.AddArg(x) - return true - } -} func rewriteValueAMD64_OpLsh16x16(v *Value, config *Config) bool { b := v.Block _ = b diff --git a/src/cmd/compile/internal/ssa/rewriteARM.go b/src/cmd/compile/internal/ssa/rewriteARM.go index edfd9ac9c31..f1cd0d5f5d4 100644 --- a/src/cmd/compile/internal/ssa/rewriteARM.go +++ b/src/cmd/compile/internal/ssa/rewriteARM.go @@ -530,12 +530,6 @@ func rewriteValueARM(v *Value, config *Config) bool { return rewriteValueARM_OpLess8U(v, config) case OpLoad: return rewriteValueARM_OpLoad(v, config) - case OpLrot16: - return rewriteValueARM_OpLrot16(v, config) - case OpLrot32: - return rewriteValueARM_OpLrot32(v, config) - case OpLrot8: - return rewriteValueARM_OpLrot8(v, config) case OpLsh16x16: return rewriteValueARM_OpLsh16x16(v, config) case OpLsh16x32: @@ -2235,6 +2229,27 @@ func rewriteValueARM_OpARMADDshiftLL(v *Value, config *Config) bool { v.AddArg(x) return true } + // match: (ADDshiftLL [c] (SRLconst x [32-c]) x) + // cond: + // result: (SRRconst [32-c] x) + for { + c := v.AuxInt + v_0 := v.Args[0] + if v_0.Op != OpARMSRLconst { + break + } + if v_0.AuxInt != 32-c { + break + } + x := v_0.Args[0] + if x != v.Args[1] { + break + } + v.reset(OpARMSRRconst) + v.AuxInt = 32 - c + v.AddArg(x) + return true + } return false } func rewriteValueARM_OpARMADDshiftLLreg(v *Value, config *Config) bool { @@ -2397,6 +2412,27 @@ func rewriteValueARM_OpARMADDshiftRL(v *Value, config *Config) bool { v.AddArg(x) return true } + // match: (ADDshiftRL [c] (SLLconst x [32-c]) x) + // cond: + // result: (SRRconst [ c] x) + for { + c := v.AuxInt + v_0 := v.Args[0] + if v_0.Op != OpARMSLLconst { + break + } + if v_0.AuxInt != 32-c { + break + } + x := v_0.Args[0] + if x != v.Args[1] { + break + } + v.reset(OpARMSRRconst) + v.AuxInt = c + v.AddArg(x) + return true + } return false } func rewriteValueARM_OpARMADDshiftRLreg(v *Value, config *Config) bool { @@ -8688,6 +8724,27 @@ func rewriteValueARM_OpARMORshiftLL(v *Value, config *Config) bool { v.AddArg(x) return true } + // match: ( ORshiftLL [c] (SRLconst x [32-c]) x) + // cond: + // result: (SRRconst [32-c] x) + for { + c := v.AuxInt + v_0 := v.Args[0] + if v_0.Op != OpARMSRLconst { + break + } + if v_0.AuxInt != 32-c { + break + } + x := v_0.Args[0] + if x != v.Args[1] { + break + } + v.reset(OpARMSRRconst) + v.AuxInt = 32 - c + v.AddArg(x) + return true + } // match: (ORshiftLL x y:(SLLconst x [c]) [d]) // cond: c==d // result: y @@ -8894,6 +8951,27 @@ func rewriteValueARM_OpARMORshiftRL(v *Value, config *Config) bool { v.AddArg(x) return true } + // match: ( ORshiftRL [c] (SLLconst x [32-c]) x) + // cond: + // result: (SRRconst [ c] x) + for { + c := v.AuxInt + v_0 := v.Args[0] + if v_0.Op != OpARMSLLconst { + break + } + if v_0.AuxInt != 32-c { + break + } + x := v_0.Args[0] + if x != v.Args[1] { + break + } + v.reset(OpARMSRRconst) + v.AuxInt = c + v.AddArg(x) + return true + } // match: (ORshiftRL x y:(SRLconst x [c]) [d]) // cond: c==d // result: y @@ -12393,6 +12471,27 @@ func rewriteValueARM_OpARMXORshiftLL(v *Value, config *Config) bool { v.AddArg(x) return true } + // match: (XORshiftLL [c] (SRLconst x [32-c]) x) + // cond: + // result: (SRRconst [32-c] x) + for { + c := v.AuxInt + v_0 := v.Args[0] + if v_0.Op != OpARMSRLconst { + break + } + if v_0.AuxInt != 32-c { + break + } + x := v_0.Args[0] + if x != v.Args[1] { + break + } + v.reset(OpARMSRRconst) + v.AuxInt = 32 - c + v.AddArg(x) + return true + } // match: (XORshiftLL x (SLLconst x [c]) [d]) // cond: c==d // result: (MOVWconst [0]) @@ -12597,6 +12696,27 @@ func rewriteValueARM_OpARMXORshiftRL(v *Value, config *Config) bool { v.AddArg(x) return true } + // match: (XORshiftRL [c] (SLLconst x [32-c]) x) + // cond: + // result: (SRRconst [ c] x) + for { + c := v.AuxInt + v_0 := v.Args[0] + if v_0.Op != OpARMSLLconst { + break + } + if v_0.AuxInt != 32-c { + break + } + x := v_0.Args[0] + if x != v.Args[1] { + break + } + v.reset(OpARMSRRconst) + v.AuxInt = c + v.AddArg(x) + return true + } // match: (XORshiftRL x (SRLconst x [c]) [d]) // cond: c==d // result: (MOVWconst [0]) @@ -14512,65 +14632,6 @@ func rewriteValueARM_OpLoad(v *Value, config *Config) bool { } return false } -func rewriteValueARM_OpLrot16(v *Value, config *Config) bool { - b := v.Block - _ = b - // match: (Lrot16 x [c]) - // cond: - // result: (OR (SLLconst x [c&15]) (SRLconst x [16-c&15])) - for { - t := v.Type - c := v.AuxInt - x := v.Args[0] - v.reset(OpARMOR) - v0 := b.NewValue0(v.Pos, OpARMSLLconst, t) - v0.AuxInt = c & 15 - v0.AddArg(x) - v.AddArg(v0) - v1 := b.NewValue0(v.Pos, OpARMSRLconst, t) - v1.AuxInt = 16 - c&15 - v1.AddArg(x) - v.AddArg(v1) - return true - } -} -func rewriteValueARM_OpLrot32(v *Value, config *Config) bool { - b := v.Block - _ = b - // match: (Lrot32 x [c]) - // cond: - // result: (SRRconst x [32-c&31]) - for { - c := v.AuxInt - x := v.Args[0] - v.reset(OpARMSRRconst) - v.AuxInt = 32 - c&31 - v.AddArg(x) - return true - } -} -func rewriteValueARM_OpLrot8(v *Value, config *Config) bool { - b := v.Block - _ = b - // match: (Lrot8 x [c]) - // cond: - // result: (OR (SLLconst x [c&7]) (SRLconst x [8-c&7])) - for { - t := v.Type - c := v.AuxInt - x := v.Args[0] - v.reset(OpARMOR) - v0 := b.NewValue0(v.Pos, OpARMSLLconst, t) - v0.AuxInt = c & 7 - v0.AddArg(x) - v.AddArg(v0) - v1 := b.NewValue0(v.Pos, OpARMSRLconst, t) - v1.AuxInt = 8 - c&7 - v1.AddArg(x) - v.AddArg(v1) - return true - } -} func rewriteValueARM_OpLsh16x16(v *Value, config *Config) bool { b := v.Block _ = b diff --git a/src/cmd/compile/internal/ssa/rewriteARM64.go b/src/cmd/compile/internal/ssa/rewriteARM64.go index 76f9a105d00..92664b188a4 100644 --- a/src/cmd/compile/internal/ssa/rewriteARM64.go +++ b/src/cmd/compile/internal/ssa/rewriteARM64.go @@ -470,14 +470,6 @@ func rewriteValueARM64(v *Value, config *Config) bool { return rewriteValueARM64_OpLess8U(v, config) case OpLoad: return rewriteValueARM64_OpLoad(v, config) - case OpLrot16: - return rewriteValueARM64_OpLrot16(v, config) - case OpLrot32: - return rewriteValueARM64_OpLrot32(v, config) - case OpLrot64: - return rewriteValueARM64_OpLrot64(v, config) - case OpLrot8: - return rewriteValueARM64_OpLrot8(v, config) case OpLsh16x16: return rewriteValueARM64_OpLsh16x16(v, config) case OpLsh16x32: @@ -1006,6 +998,56 @@ func rewriteValueARM64_OpARM64ADDshiftLL(v *Value, config *Config) bool { v.AddArg(x) return true } + // match: (ADDshiftLL [c] (SRLconst x [64-c]) x) + // cond: + // result: (RORconst [64-c] x) + for { + c := v.AuxInt + v_0 := v.Args[0] + if v_0.Op != OpARM64SRLconst { + break + } + if v_0.AuxInt != 64-c { + break + } + x := v_0.Args[0] + if x != v.Args[1] { + break + } + v.reset(OpARM64RORconst) + v.AuxInt = 64 - c + v.AddArg(x) + return true + } + // match: (ADDshiftLL [c] (SRLconst (MOVWUreg x) [32-c]) x) + // cond: c < 32 && t.Size() == 4 + // result: (RORWconst [32-c] x) + for { + t := v.Type + c := v.AuxInt + v_0 := v.Args[0] + if v_0.Op != OpARM64SRLconst { + break + } + if v_0.AuxInt != 32-c { + break + } + v_0_0 := v_0.Args[0] + if v_0_0.Op != OpARM64MOVWUreg { + break + } + x := v_0_0.Args[0] + if x != v.Args[1] { + break + } + if !(c < 32 && t.Size() == 4) { + break + } + v.reset(OpARM64RORWconst) + v.AuxInt = 32 - c + v.AddArg(x) + return true + } return false } func rewriteValueARM64_OpARM64ADDshiftRA(v *Value, config *Config) bool { @@ -1086,6 +1128,56 @@ func rewriteValueARM64_OpARM64ADDshiftRL(v *Value, config *Config) bool { v.AddArg(x) return true } + // match: (ADDshiftRL [c] (SLLconst x [64-c]) x) + // cond: + // result: (RORconst [ c] x) + for { + c := v.AuxInt + v_0 := v.Args[0] + if v_0.Op != OpARM64SLLconst { + break + } + if v_0.AuxInt != 64-c { + break + } + x := v_0.Args[0] + if x != v.Args[1] { + break + } + v.reset(OpARM64RORconst) + v.AuxInt = c + v.AddArg(x) + return true + } + // match: (ADDshiftRL [c] (SLLconst x [32-c]) (MOVWUreg x)) + // cond: c < 32 && t.Size() == 4 + // result: (RORWconst [ c] x) + for { + t := v.Type + c := v.AuxInt + v_0 := v.Args[0] + if v_0.Op != OpARM64SLLconst { + break + } + if v_0.AuxInt != 32-c { + break + } + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARM64MOVWUreg { + break + } + if x != v_1.Args[0] { + break + } + if !(c < 32 && t.Size() == 4) { + break + } + v.reset(OpARM64RORWconst) + v.AuxInt = c + v.AddArg(x) + return true + } return false } func rewriteValueARM64_OpARM64AND(v *Value, config *Config) bool { @@ -7227,6 +7319,56 @@ func rewriteValueARM64_OpARM64ORshiftLL(v *Value, config *Config) bool { v.AddArg(y) return true } + // match: ( ORshiftLL [c] (SRLconst x [64-c]) x) + // cond: + // result: (RORconst [64-c] x) + for { + c := v.AuxInt + v_0 := v.Args[0] + if v_0.Op != OpARM64SRLconst { + break + } + if v_0.AuxInt != 64-c { + break + } + x := v_0.Args[0] + if x != v.Args[1] { + break + } + v.reset(OpARM64RORconst) + v.AuxInt = 64 - c + v.AddArg(x) + return true + } + // match: ( ORshiftLL [c] (SRLconst (MOVWUreg x) [32-c]) x) + // cond: c < 32 && t.Size() == 4 + // result: (RORWconst [32-c] x) + for { + t := v.Type + c := v.AuxInt + v_0 := v.Args[0] + if v_0.Op != OpARM64SRLconst { + break + } + if v_0.AuxInt != 32-c { + break + } + v_0_0 := v_0.Args[0] + if v_0_0.Op != OpARM64MOVWUreg { + break + } + x := v_0_0.Args[0] + if x != v.Args[1] { + break + } + if !(c < 32 && t.Size() == 4) { + break + } + v.reset(OpARM64RORWconst) + v.AuxInt = 32 - c + v.AddArg(x) + return true + } // match: (ORshiftLL [8] y0:(MOVDnop x0:(MOVBUload [i] {s} p mem)) y1:(MOVDnop x1:(MOVBUload [i+1] {s} p mem))) // cond: x0.Uses == 1 && x1.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && mergePoint(b,x0,x1) != nil && clobber(x0) && clobber(x1) && clobber(y0) && clobber(y1) // result: @mergePoint(b,x0,x1) (MOVHUload {s} (OffPtr [i] p) mem) @@ -7893,6 +8035,56 @@ func rewriteValueARM64_OpARM64ORshiftRL(v *Value, config *Config) bool { v.AddArg(y) return true } + // match: ( ORshiftRL [c] (SLLconst x [64-c]) x) + // cond: + // result: (RORconst [ c] x) + for { + c := v.AuxInt + v_0 := v.Args[0] + if v_0.Op != OpARM64SLLconst { + break + } + if v_0.AuxInt != 64-c { + break + } + x := v_0.Args[0] + if x != v.Args[1] { + break + } + v.reset(OpARM64RORconst) + v.AuxInt = c + v.AddArg(x) + return true + } + // match: ( ORshiftRL [c] (SLLconst x [32-c]) (MOVWUreg x)) + // cond: c < 32 && t.Size() == 4 + // result: (RORWconst [ c] x) + for { + t := v.Type + c := v.AuxInt + v_0 := v.Args[0] + if v_0.Op != OpARM64SLLconst { + break + } + if v_0.AuxInt != 32-c { + break + } + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARM64MOVWUreg { + break + } + if x != v_1.Args[0] { + break + } + if !(c < 32 && t.Size() == 4) { + break + } + v.reset(OpARM64RORWconst) + v.AuxInt = c + v.AddArg(x) + return true + } return false } func rewriteValueARM64_OpARM64SLL(v *Value, config *Config) bool { @@ -8783,6 +8975,56 @@ func rewriteValueARM64_OpARM64XORshiftLL(v *Value, config *Config) bool { v.AuxInt = 0 return true } + // match: (XORshiftLL [c] (SRLconst x [64-c]) x) + // cond: + // result: (RORconst [64-c] x) + for { + c := v.AuxInt + v_0 := v.Args[0] + if v_0.Op != OpARM64SRLconst { + break + } + if v_0.AuxInt != 64-c { + break + } + x := v_0.Args[0] + if x != v.Args[1] { + break + } + v.reset(OpARM64RORconst) + v.AuxInt = 64 - c + v.AddArg(x) + return true + } + // match: (XORshiftLL [c] (SRLconst (MOVWUreg x) [32-c]) x) + // cond: c < 32 && t.Size() == 4 + // result: (RORWconst [32-c] x) + for { + t := v.Type + c := v.AuxInt + v_0 := v.Args[0] + if v_0.Op != OpARM64SRLconst { + break + } + if v_0.AuxInt != 32-c { + break + } + v_0_0 := v_0.Args[0] + if v_0_0.Op != OpARM64MOVWUreg { + break + } + x := v_0_0.Args[0] + if x != v.Args[1] { + break + } + if !(c < 32 && t.Size() == 4) { + break + } + v.reset(OpARM64RORWconst) + v.AuxInt = 32 - c + v.AddArg(x) + return true + } return false } func rewriteValueARM64_OpARM64XORshiftRA(v *Value, config *Config) bool { @@ -8905,6 +9147,56 @@ func rewriteValueARM64_OpARM64XORshiftRL(v *Value, config *Config) bool { v.AuxInt = 0 return true } + // match: (XORshiftRL [c] (SLLconst x [64-c]) x) + // cond: + // result: (RORconst [ c] x) + for { + c := v.AuxInt + v_0 := v.Args[0] + if v_0.Op != OpARM64SLLconst { + break + } + if v_0.AuxInt != 64-c { + break + } + x := v_0.Args[0] + if x != v.Args[1] { + break + } + v.reset(OpARM64RORconst) + v.AuxInt = c + v.AddArg(x) + return true + } + // match: (XORshiftRL [c] (SLLconst x [32-c]) (MOVWUreg x)) + // cond: c < 32 && t.Size() == 4 + // result: (RORWconst [ c] x) + for { + t := v.Type + c := v.AuxInt + v_0 := v.Args[0] + if v_0.Op != OpARM64SLLconst { + break + } + if v_0.AuxInt != 32-c { + break + } + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARM64MOVWUreg { + break + } + if x != v_1.Args[0] { + break + } + if !(c < 32 && t.Size() == 4) { + break + } + v.reset(OpARM64RORWconst) + v.AuxInt = c + v.AddArg(x) + return true + } return false } func rewriteValueARM64_OpAdd16(v *Value, config *Config) bool { @@ -11326,84 +11618,6 @@ func rewriteValueARM64_OpLoad(v *Value, config *Config) bool { } return false } -func rewriteValueARM64_OpLrot16(v *Value, config *Config) bool { - b := v.Block - _ = b - // match: (Lrot16 x [c]) - // cond: - // result: (OR (SLLconst x [c&15]) (SRLconst (ZeroExt16to64 x) [16-c&15])) - for { - t := v.Type - c := v.AuxInt - x := v.Args[0] - v.reset(OpARM64OR) - v0 := b.NewValue0(v.Pos, OpARM64SLLconst, t) - v0.AuxInt = c & 15 - v0.AddArg(x) - v.AddArg(v0) - v1 := b.NewValue0(v.Pos, OpARM64SRLconst, t) - v1.AuxInt = 16 - c&15 - v2 := b.NewValue0(v.Pos, OpZeroExt16to64, config.fe.TypeUInt64()) - v2.AddArg(x) - v1.AddArg(v2) - v.AddArg(v1) - return true - } -} -func rewriteValueARM64_OpLrot32(v *Value, config *Config) bool { - b := v.Block - _ = b - // match: (Lrot32 x [c]) - // cond: - // result: (RORWconst x [32-c&31]) - for { - c := v.AuxInt - x := v.Args[0] - v.reset(OpARM64RORWconst) - v.AuxInt = 32 - c&31 - v.AddArg(x) - return true - } -} -func rewriteValueARM64_OpLrot64(v *Value, config *Config) bool { - b := v.Block - _ = b - // match: (Lrot64 x [c]) - // cond: - // result: (RORconst x [64-c&63]) - for { - c := v.AuxInt - x := v.Args[0] - v.reset(OpARM64RORconst) - v.AuxInt = 64 - c&63 - v.AddArg(x) - return true - } -} -func rewriteValueARM64_OpLrot8(v *Value, config *Config) bool { - b := v.Block - _ = b - // match: (Lrot8 x [c]) - // cond: - // result: (OR (SLLconst x [c&7]) (SRLconst (ZeroExt8to64 x) [8-c&7])) - for { - t := v.Type - c := v.AuxInt - x := v.Args[0] - v.reset(OpARM64OR) - v0 := b.NewValue0(v.Pos, OpARM64SLLconst, t) - v0.AuxInt = c & 7 - v0.AddArg(x) - v.AddArg(v0) - v1 := b.NewValue0(v.Pos, OpARM64SRLconst, t) - v1.AuxInt = 8 - c&7 - v2 := b.NewValue0(v.Pos, OpZeroExt8to64, config.fe.TypeUInt64()) - v2.AddArg(x) - v1.AddArg(v2) - v.AddArg(v1) - return true - } -} func rewriteValueARM64_OpLsh16x16(v *Value, config *Config) bool { b := v.Block _ = b diff --git a/src/cmd/compile/internal/ssa/rewriteS390X.go b/src/cmd/compile/internal/ssa/rewriteS390X.go index 07350014cfe..f689d70161d 100644 --- a/src/cmd/compile/internal/ssa/rewriteS390X.go +++ b/src/cmd/compile/internal/ssa/rewriteS390X.go @@ -268,10 +268,6 @@ func rewriteValueS390X(v *Value, config *Config) bool { return rewriteValueS390X_OpLess8U(v, config) case OpLoad: return rewriteValueS390X_OpLoad(v, config) - case OpLrot32: - return rewriteValueS390X_OpLrot32(v, config) - case OpLrot64: - return rewriteValueS390X_OpLrot64(v, config) case OpLsh16x16: return rewriteValueS390X_OpLsh16x16(v, config) case OpLsh16x32: @@ -3312,40 +3308,6 @@ func rewriteValueS390X_OpLoad(v *Value, config *Config) bool { } return false } -func rewriteValueS390X_OpLrot32(v *Value, config *Config) bool { - b := v.Block - _ = b - // match: (Lrot32 x [c]) - // cond: - // result: (RLLconst [c&31] x) - for { - t := v.Type - c := v.AuxInt - x := v.Args[0] - v.reset(OpS390XRLLconst) - v.Type = t - v.AuxInt = c & 31 - v.AddArg(x) - return true - } -} -func rewriteValueS390X_OpLrot64(v *Value, config *Config) bool { - b := v.Block - _ = b - // match: (Lrot64 x [c]) - // cond: - // result: (RLLGconst [c&63] x) - for { - t := v.Type - c := v.AuxInt - x := v.Args[0] - v.reset(OpS390XRLLGconst) - v.Type = t - v.AuxInt = c & 63 - v.AddArg(x) - return true - } -} func rewriteValueS390X_OpLsh16x16(v *Value, config *Config) bool { b := v.Block _ = b @@ -5737,6 +5699,56 @@ func rewriteValueS390X_OpS390XADD(v *Value, config *Config) bool { v.AddArg(x) return true } + // match: (ADD (SLDconst x [c]) (SRDconst x [64-c])) + // cond: + // result: (RLLGconst [ c] x) + for { + v_0 := v.Args[0] + if v_0.Op != OpS390XSLDconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpS390XSRDconst { + break + } + if v_1.AuxInt != 64-c { + break + } + if x != v_1.Args[0] { + break + } + v.reset(OpS390XRLLGconst) + v.AuxInt = c + v.AddArg(x) + return true + } + // match: (ADD (SRDconst x [c]) (SLDconst x [64-c])) + // cond: + // result: (RLLGconst [64-c] x) + for { + v_0 := v.Args[0] + if v_0.Op != OpS390XSRDconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpS390XSLDconst { + break + } + if v_1.AuxInt != 64-c { + break + } + if x != v_1.Args[0] { + break + } + v.reset(OpS390XRLLGconst) + v.AuxInt = 64 - c + v.AddArg(x) + return true + } // match: (ADD x (MOVDaddr [c] {s} y)) // cond: x.Op != OpSB && y.Op != OpSB // result: (MOVDaddridx [c] {s} x y) @@ -5883,6 +5895,56 @@ func rewriteValueS390X_OpS390XADDW(v *Value, config *Config) bool { v.AddArg(x) return true } + // match: (ADDW (SLWconst x [c]) (SRWconst x [32-c])) + // cond: + // result: (RLLconst [ c] x) + for { + v_0 := v.Args[0] + if v_0.Op != OpS390XSLWconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpS390XSRWconst { + break + } + if v_1.AuxInt != 32-c { + break + } + if x != v_1.Args[0] { + break + } + v.reset(OpS390XRLLconst) + v.AuxInt = c + v.AddArg(x) + return true + } + // match: (ADDW (SRWconst x [c]) (SLWconst x [32-c])) + // cond: + // result: (RLLconst [32-c] x) + for { + v_0 := v.Args[0] + if v_0.Op != OpS390XSRWconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpS390XSLWconst { + break + } + if v_1.AuxInt != 32-c { + break + } + if x != v_1.Args[0] { + break + } + v.reset(OpS390XRLLconst) + v.AuxInt = 32 - c + v.AddArg(x) + return true + } // match: (ADDW x (NEGW y)) // cond: // result: (SUBW x y) @@ -14052,6 +14114,56 @@ func rewriteValueS390X_OpS390XOR(v *Value, config *Config) bool { v.AddArg(x) return true } + // match: ( OR (SLDconst x [c]) (SRDconst x [64-c])) + // cond: + // result: (RLLGconst [ c] x) + for { + v_0 := v.Args[0] + if v_0.Op != OpS390XSLDconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpS390XSRDconst { + break + } + if v_1.AuxInt != 64-c { + break + } + if x != v_1.Args[0] { + break + } + v.reset(OpS390XRLLGconst) + v.AuxInt = c + v.AddArg(x) + return true + } + // match: ( OR (SRDconst x [c]) (SLDconst x [64-c])) + // cond: + // result: (RLLGconst [64-c] x) + for { + v_0 := v.Args[0] + if v_0.Op != OpS390XSRDconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpS390XSLDconst { + break + } + if v_1.AuxInt != 64-c { + break + } + if x != v_1.Args[0] { + break + } + v.reset(OpS390XRLLGconst) + v.AuxInt = 64 - c + v.AddArg(x) + return true + } // match: (OR (MOVDconst [c]) (MOVDconst [d])) // cond: // result: (MOVDconst [c|d]) @@ -15056,6 +15168,56 @@ func rewriteValueS390X_OpS390XORW(v *Value, config *Config) bool { v.AddArg(x) return true } + // match: ( ORW (SLWconst x [c]) (SRWconst x [32-c])) + // cond: + // result: (RLLconst [ c] x) + for { + v_0 := v.Args[0] + if v_0.Op != OpS390XSLWconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpS390XSRWconst { + break + } + if v_1.AuxInt != 32-c { + break + } + if x != v_1.Args[0] { + break + } + v.reset(OpS390XRLLconst) + v.AuxInt = c + v.AddArg(x) + return true + } + // match: ( ORW (SRWconst x [c]) (SLWconst x [32-c])) + // cond: + // result: (RLLconst [32-c] x) + for { + v_0 := v.Args[0] + if v_0.Op != OpS390XSRWconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpS390XSLWconst { + break + } + if v_1.AuxInt != 32-c { + break + } + if x != v_1.Args[0] { + break + } + v.reset(OpS390XRLLconst) + v.AuxInt = 32 - c + v.AddArg(x) + return true + } // match: (ORW x x) // cond: // result: x @@ -16573,6 +16735,56 @@ func rewriteValueS390X_OpS390XXOR(v *Value, config *Config) bool { v.AddArg(x) return true } + // match: (XOR (SLDconst x [c]) (SRDconst x [64-c])) + // cond: + // result: (RLLGconst [ c] x) + for { + v_0 := v.Args[0] + if v_0.Op != OpS390XSLDconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpS390XSRDconst { + break + } + if v_1.AuxInt != 64-c { + break + } + if x != v_1.Args[0] { + break + } + v.reset(OpS390XRLLGconst) + v.AuxInt = c + v.AddArg(x) + return true + } + // match: (XOR (SRDconst x [c]) (SLDconst x [64-c])) + // cond: + // result: (RLLGconst [64-c] x) + for { + v_0 := v.Args[0] + if v_0.Op != OpS390XSRDconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpS390XSLDconst { + break + } + if v_1.AuxInt != 64-c { + break + } + if x != v_1.Args[0] { + break + } + v.reset(OpS390XRLLGconst) + v.AuxInt = 64 - c + v.AddArg(x) + return true + } // match: (XOR (MOVDconst [c]) (MOVDconst [d])) // cond: // result: (MOVDconst [c^d]) @@ -16690,6 +16902,56 @@ func rewriteValueS390X_OpS390XXORW(v *Value, config *Config) bool { v.AddArg(x) return true } + // match: (XORW (SLWconst x [c]) (SRWconst x [32-c])) + // cond: + // result: (RLLconst [ c] x) + for { + v_0 := v.Args[0] + if v_0.Op != OpS390XSLWconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpS390XSRWconst { + break + } + if v_1.AuxInt != 32-c { + break + } + if x != v_1.Args[0] { + break + } + v.reset(OpS390XRLLconst) + v.AuxInt = c + v.AddArg(x) + return true + } + // match: (XORW (SRWconst x [c]) (SLWconst x [32-c])) + // cond: + // result: (RLLconst [32-c] x) + for { + v_0 := v.Args[0] + if v_0.Op != OpS390XSRWconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpS390XSLWconst { + break + } + if v_1.AuxInt != 32-c { + break + } + if x != v_1.Args[0] { + break + } + v.reset(OpS390XRLLconst) + v.AuxInt = 32 - c + v.AddArg(x) + return true + } // match: (XORW x x) // cond: // result: (MOVDconst [0]) diff --git a/src/cmd/compile/internal/ssa/rewritedec64.go b/src/cmd/compile/internal/ssa/rewritedec64.go index ff45a5dd881..8d2f0d60ad5 100644 --- a/src/cmd/compile/internal/ssa/rewritedec64.go +++ b/src/cmd/compile/internal/ssa/rewritedec64.go @@ -46,8 +46,6 @@ func rewriteValuedec64(v *Value, config *Config) bool { return rewriteValuedec64_OpLess64U(v, config) case OpLoad: return rewriteValuedec64_OpLoad(v, config) - case OpLrot64: - return rewriteValuedec64_OpLrot64(v, config) case OpLsh16x64: return rewriteValuedec64_OpLsh16x64(v, config) case OpLsh32x64: @@ -881,78 +879,6 @@ func rewriteValuedec64_OpLoad(v *Value, config *Config) bool { } return false } -func rewriteValuedec64_OpLrot64(v *Value, config *Config) bool { - b := v.Block - _ = b - // match: (Lrot64 (Int64Make hi lo) [c]) - // cond: c <= 32 - // result: (Int64Make (Or32 (Lsh32x32 hi (Const32 [c])) (Rsh32Ux32 lo (Const32 [32-c]))) (Or32 (Lsh32x32 lo (Const32 [c])) (Rsh32Ux32 hi (Const32 [32-c])))) - for { - c := v.AuxInt - v_0 := v.Args[0] - if v_0.Op != OpInt64Make { - break - } - hi := v_0.Args[0] - lo := v_0.Args[1] - if !(c <= 32) { - break - } - v.reset(OpInt64Make) - v0 := b.NewValue0(v.Pos, OpOr32, config.fe.TypeUInt32()) - v1 := b.NewValue0(v.Pos, OpLsh32x32, config.fe.TypeUInt32()) - v1.AddArg(hi) - v2 := b.NewValue0(v.Pos, OpConst32, config.fe.TypeUInt32()) - v2.AuxInt = c - v1.AddArg(v2) - v0.AddArg(v1) - v3 := b.NewValue0(v.Pos, OpRsh32Ux32, config.fe.TypeUInt32()) - v3.AddArg(lo) - v4 := b.NewValue0(v.Pos, OpConst32, config.fe.TypeUInt32()) - v4.AuxInt = 32 - c - v3.AddArg(v4) - v0.AddArg(v3) - v.AddArg(v0) - v5 := b.NewValue0(v.Pos, OpOr32, config.fe.TypeUInt32()) - v6 := b.NewValue0(v.Pos, OpLsh32x32, config.fe.TypeUInt32()) - v6.AddArg(lo) - v7 := b.NewValue0(v.Pos, OpConst32, config.fe.TypeUInt32()) - v7.AuxInt = c - v6.AddArg(v7) - v5.AddArg(v6) - v8 := b.NewValue0(v.Pos, OpRsh32Ux32, config.fe.TypeUInt32()) - v8.AddArg(hi) - v9 := b.NewValue0(v.Pos, OpConst32, config.fe.TypeUInt32()) - v9.AuxInt = 32 - c - v8.AddArg(v9) - v5.AddArg(v8) - v.AddArg(v5) - return true - } - // match: (Lrot64 (Int64Make hi lo) [c]) - // cond: c > 32 - // result: (Lrot64 (Int64Make lo hi) [c-32]) - for { - c := v.AuxInt - v_0 := v.Args[0] - if v_0.Op != OpInt64Make { - break - } - hi := v_0.Args[0] - lo := v_0.Args[1] - if !(c > 32) { - break - } - v.reset(OpLrot64) - v.AuxInt = c - 32 - v0 := b.NewValue0(v.Pos, OpInt64Make, config.fe.TypeUInt64()) - v0.AddArg(lo) - v0.AddArg(hi) - v.AddArg(v0) - return true - } - return false -} func rewriteValuedec64_OpLsh16x64(v *Value, config *Config) bool { b := v.Block _ = b