diff --git a/src/cmd/compile/internal/ssa/gen/rulegen.go b/src/cmd/compile/internal/ssa/gen/rulegen.go index fa0b7c8a6b..46d4eee72c 100644 --- a/src/cmd/compile/internal/ssa/gen/rulegen.go +++ b/src/cmd/compile/internal/ssa/gen/rulegen.go @@ -1339,7 +1339,7 @@ func expandOr(r string) []string { // Potentially exponential, be careful. func commute(r string, arch arch) []string { match, cond, result := Rule{rule: r}.parse() - a := commute1(match, varCount(match), arch) + a := commute1(match, varCount(match, cond), arch) for i, m := range a { if cond != "" { m += " && " + cond @@ -1428,10 +1428,22 @@ func commute1(m string, cnt map[string]int, arch arch) []string { } // varCount returns a map which counts the number of occurrences of -// Value variables in m. -func varCount(m string) map[string]int { +// Value variables in the s-expression "match" and the Go expression "cond". +func varCount(match, cond string) map[string]int { cnt := map[string]int{} - varCount1(m, cnt) + varCount1(match, cnt) + if cond != "" { + expr, err := parser.ParseExpr(cond) + if err != nil { + log.Fatalf("failed to parse cond %q: %v", cond, err) + } + ast.Inspect(expr, func(n ast.Node) bool { + if id, ok := n.(*ast.Ident); ok { + cnt[id.Name]++ + } + return true + }) + } return cnt } diff --git a/src/cmd/compile/internal/ssa/rewrite386.go b/src/cmd/compile/internal/ssa/rewrite386.go index d1ea5c5a4d..dba61cf347 100644 --- a/src/cmd/compile/internal/ssa/rewrite386.go +++ b/src/cmd/compile/internal/ssa/rewrite386.go @@ -165,7 +165,7 @@ func rewriteValue386(v *Value) bool { case Op386MOVWloadidx2: return rewriteValue386_Op386MOVWloadidx2_0(v) case Op386MOVWstore: - return rewriteValue386_Op386MOVWstore_0(v) + return rewriteValue386_Op386MOVWstore_0(v) || rewriteValue386_Op386MOVWstore_10(v) case Op386MOVWstoreconst: return rewriteValue386_Op386MOVWstoreconst_0(v) case Op386MOVWstoreconstidx1: @@ -4015,6 +4015,28 @@ func rewriteValue386_Op386LEAL_0(v *Value) bool { v.AddArg(y) return true } + // match: (LEAL [c] {s} (ADDL y x)) + // cond: x.Op != OpSB && y.Op != OpSB + // result: (LEAL1 [c] {s} x y) + for { + c := v.AuxInt + s := v.Aux + v_0 := v.Args[0] + if v_0.Op != Op386ADDL { + break + } + x := v_0.Args[1] + y := v_0.Args[0] + if !(x.Op != OpSB && y.Op != OpSB) { + break + } + v.reset(Op386LEAL1) + v.AuxInt = c + v.Aux = s + v.AddArg(x) + v.AddArg(y) + return true + } // match: (LEAL [off1] {sym1} (LEAL [off2] {sym2} x)) // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) // result: (LEAL [off1+off2] {mergeSym(sym1,sym2)} x) @@ -4918,6 +4940,30 @@ func rewriteValue386_Op386MOVBload_0(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVBload [off] {sym} (ADDL idx ptr) mem) + // cond: ptr.Op != OpSB + // result: (MOVBloadidx1 [off] {sym} ptr idx mem) + for { + off := v.AuxInt + sym := v.Aux + mem := v.Args[1] + v_0 := v.Args[0] + if v_0.Op != Op386ADDL { + break + } + ptr := v_0.Args[1] + idx := v_0.Args[0] + if !(ptr.Op != OpSB) { + break + } + v.reset(Op386MOVBloadidx1) + v.AuxInt = off + v.Aux = sym + v.AddArg(ptr) + v.AddArg(idx) + v.AddArg(mem) + return true + } // match: (MOVBload [off] {sym} (SB) _) // cond: symIsRO(sym) // result: (MOVLconst [int64(read8(sym, off))]) @@ -5193,6 +5239,32 @@ func rewriteValue386_Op386MOVBstore_0(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVBstore [off] {sym} (ADDL idx ptr) val mem) + // cond: ptr.Op != OpSB + // result: (MOVBstoreidx1 [off] {sym} ptr idx val mem) + for { + off := v.AuxInt + sym := v.Aux + mem := v.Args[2] + v_0 := v.Args[0] + if v_0.Op != Op386ADDL { + break + } + ptr := v_0.Args[1] + idx := v_0.Args[0] + val := v.Args[1] + if !(ptr.Op != OpSB) { + break + } + v.reset(Op386MOVBstoreidx1) + v.AuxInt = off + v.Aux = sym + v.AddArg(ptr) + v.AddArg(idx) + v.AddArg(val) + v.AddArg(mem) + return true + } // match: (MOVBstore [i] {s} p (SHRWconst [8] w) x:(MOVBstore [i-1] {s} p w mem)) // cond: x.Uses == 1 && clobber(x) // result: (MOVWstore [i-1] {s} p w mem) @@ -5251,6 +5323,9 @@ func rewriteValue386_Op386MOVBstore_0(v *Value) bool { v.AddArg(mem) return true } + return false +} +func rewriteValue386_Op386MOVBstore_10(v *Value) bool { // match: (MOVBstore [i] {s} p w x:(MOVBstore {s} [i+1] p (SHRWconst [8] w) mem)) // cond: x.Uses == 1 && clobber(x) // result: (MOVWstore [i] {s} p w mem) @@ -5280,9 +5355,6 @@ func rewriteValue386_Op386MOVBstore_0(v *Value) bool { v.AddArg(mem) return true } - return false -} -func rewriteValue386_Op386MOVBstore_10(v *Value) bool { // match: (MOVBstore [i] {s} p w x:(MOVBstore {s} [i+1] p (SHRLconst [8] w) mem)) // cond: x.Uses == 1 && clobber(x) // result: (MOVWstore [i] {s} p w mem) @@ -6466,6 +6538,30 @@ func rewriteValue386_Op386MOVLload_0(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVLload [off] {sym} (ADDL idx ptr) mem) + // cond: ptr.Op != OpSB + // result: (MOVLloadidx1 [off] {sym} ptr idx mem) + for { + off := v.AuxInt + sym := v.Aux + mem := v.Args[1] + v_0 := v.Args[0] + if v_0.Op != Op386ADDL { + break + } + ptr := v_0.Args[1] + idx := v_0.Args[0] + if !(ptr.Op != OpSB) { + break + } + v.reset(Op386MOVLloadidx1) + v.AuxInt = off + v.Aux = sym + v.AddArg(ptr) + v.AddArg(idx) + v.AddArg(mem) + return true + } // match: (MOVLload [off] {sym} (SB) _) // cond: symIsRO(sym) // result: (MOVLconst [int64(int32(read32(sym, off, config.BigEndian)))]) @@ -6814,6 +6910,32 @@ func rewriteValue386_Op386MOVLstore_0(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVLstore [off] {sym} (ADDL idx ptr) val mem) + // cond: ptr.Op != OpSB + // result: (MOVLstoreidx1 [off] {sym} ptr idx val mem) + for { + off := v.AuxInt + sym := v.Aux + mem := v.Args[2] + v_0 := v.Args[0] + if v_0.Op != Op386ADDL { + break + } + ptr := v_0.Args[1] + idx := v_0.Args[0] + val := v.Args[1] + if !(ptr.Op != OpSB) { + break + } + v.reset(Op386MOVLstoreidx1) + v.AuxInt = off + v.Aux = sym + v.AddArg(ptr) + v.AddArg(idx) + v.AddArg(val) + v.AddArg(mem) + return true + } // match: (MOVLstore {sym} [off] ptr y:(ADDLload x [off] {sym} ptr mem) mem) // cond: y.Uses==1 && clobber(y) // result: (ADDLmodify [off] {sym} ptr x mem) @@ -6889,6 +7011,9 @@ func rewriteValue386_Op386MOVLstore_0(v *Value) bool { v.AddArg(mem) return true } + return false +} +func rewriteValue386_Op386MOVLstore_10(v *Value) bool { // match: (MOVLstore {sym} [off] ptr y:(XORLload x [off] {sym} ptr mem) mem) // cond: y.Uses==1 && clobber(y) // result: (XORLmodify [off] {sym} ptr x mem) @@ -6914,9 +7039,6 @@ func rewriteValue386_Op386MOVLstore_0(v *Value) bool { v.AddArg(mem) return true } - return false -} -func rewriteValue386_Op386MOVLstore_10(v *Value) bool { // match: (MOVLstore {sym} [off] ptr y:(ADDL l:(MOVLload [off] {sym} ptr mem) x) mem) // cond: y.Uses==1 && l.Uses==1 && clobber(y) && clobber(l) // result: (ADDLmodify [off] {sym} ptr x mem) @@ -7182,6 +7304,9 @@ func rewriteValue386_Op386MOVLstore_10(v *Value) bool { v.AddArg(mem) return true } + return false +} +func rewriteValue386_Op386MOVLstore_20(v *Value) bool { // match: (MOVLstore {sym} [off] ptr y:(ADDLconst [c] l:(MOVLload [off] {sym} ptr mem)) mem) // cond: y.Uses==1 && l.Uses==1 && clobber(y) && clobber(l) && validValAndOff(c,off) // result: (ADDLconstmodify [makeValAndOff(c,off)] {sym} ptr mem) @@ -7210,9 +7335,6 @@ func rewriteValue386_Op386MOVLstore_10(v *Value) bool { v.AddArg(mem) return true } - return false -} -func rewriteValue386_Op386MOVLstore_20(v *Value) bool { // match: (MOVLstore {sym} [off] ptr y:(ANDLconst [c] l:(MOVLload [off] {sym} ptr mem)) mem) // cond: y.Uses==1 && l.Uses==1 && clobber(y) && clobber(l) && validValAndOff(c,off) // result: (ANDLconstmodify [makeValAndOff(c,off)] {sym} ptr mem) @@ -8381,6 +8503,30 @@ func rewriteValue386_Op386MOVSDload_0(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVSDload [off] {sym} (ADDL idx ptr) mem) + // cond: ptr.Op != OpSB + // result: (MOVSDloadidx1 [off] {sym} ptr idx mem) + for { + off := v.AuxInt + sym := v.Aux + mem := v.Args[1] + v_0 := v.Args[0] + if v_0.Op != Op386ADDL { + break + } + ptr := v_0.Args[1] + idx := v_0.Args[0] + if !(ptr.Op != OpSB) { + break + } + v.reset(Op386MOVSDloadidx1) + v.AuxInt = off + v.Aux = sym + v.AddArg(ptr) + v.AddArg(idx) + v.AddArg(mem) + return true + } return false } func rewriteValue386_Op386MOVSDloadidx1_0(v *Value) bool { @@ -8609,6 +8755,32 @@ func rewriteValue386_Op386MOVSDstore_0(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVSDstore [off] {sym} (ADDL idx ptr) val mem) + // cond: ptr.Op != OpSB + // result: (MOVSDstoreidx1 [off] {sym} ptr idx val mem) + for { + off := v.AuxInt + sym := v.Aux + mem := v.Args[2] + v_0 := v.Args[0] + if v_0.Op != Op386ADDL { + break + } + ptr := v_0.Args[1] + idx := v_0.Args[0] + val := v.Args[1] + if !(ptr.Op != OpSB) { + break + } + v.reset(Op386MOVSDstoreidx1) + v.AuxInt = off + v.Aux = sym + v.AddArg(ptr) + v.AddArg(idx) + v.AddArg(val) + v.AddArg(mem) + return true + } return false } func rewriteValue386_Op386MOVSDstoreidx1_0(v *Value) bool { @@ -8855,6 +9027,30 @@ func rewriteValue386_Op386MOVSSload_0(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVSSload [off] {sym} (ADDL idx ptr) mem) + // cond: ptr.Op != OpSB + // result: (MOVSSloadidx1 [off] {sym} ptr idx mem) + for { + off := v.AuxInt + sym := v.Aux + mem := v.Args[1] + v_0 := v.Args[0] + if v_0.Op != Op386ADDL { + break + } + ptr := v_0.Args[1] + idx := v_0.Args[0] + if !(ptr.Op != OpSB) { + break + } + v.reset(Op386MOVSSloadidx1) + v.AuxInt = off + v.Aux = sym + v.AddArg(ptr) + v.AddArg(idx) + v.AddArg(mem) + return true + } return false } func rewriteValue386_Op386MOVSSloadidx1_0(v *Value) bool { @@ -9083,6 +9279,32 @@ func rewriteValue386_Op386MOVSSstore_0(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVSSstore [off] {sym} (ADDL idx ptr) val mem) + // cond: ptr.Op != OpSB + // result: (MOVSSstoreidx1 [off] {sym} ptr idx val mem) + for { + off := v.AuxInt + sym := v.Aux + mem := v.Args[2] + v_0 := v.Args[0] + if v_0.Op != Op386ADDL { + break + } + ptr := v_0.Args[1] + idx := v_0.Args[0] + val := v.Args[1] + if !(ptr.Op != OpSB) { + break + } + v.reset(Op386MOVSSstoreidx1) + v.AuxInt = off + v.Aux = sym + v.AddArg(ptr) + v.AddArg(idx) + v.AddArg(val) + v.AddArg(mem) + return true + } return false } func rewriteValue386_Op386MOVSSstoreidx1_0(v *Value) bool { @@ -9530,6 +9752,30 @@ func rewriteValue386_Op386MOVWload_0(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVWload [off] {sym} (ADDL idx ptr) mem) + // cond: ptr.Op != OpSB + // result: (MOVWloadidx1 [off] {sym} ptr idx mem) + for { + off := v.AuxInt + sym := v.Aux + mem := v.Args[1] + v_0 := v.Args[0] + if v_0.Op != Op386ADDL { + break + } + ptr := v_0.Args[1] + idx := v_0.Args[0] + if !(ptr.Op != OpSB) { + break + } + v.reset(Op386MOVWloadidx1) + v.AuxInt = off + v.Aux = sym + v.AddArg(ptr) + v.AddArg(idx) + v.AddArg(mem) + return true + } // match: (MOVWload [off] {sym} (SB) _) // cond: symIsRO(sym) // result: (MOVLconst [int64(read16(sym, off, config.BigEndian))]) @@ -9918,6 +10164,32 @@ func rewriteValue386_Op386MOVWstore_0(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVWstore [off] {sym} (ADDL idx ptr) val mem) + // cond: ptr.Op != OpSB + // result: (MOVWstoreidx1 [off] {sym} ptr idx val mem) + for { + off := v.AuxInt + sym := v.Aux + mem := v.Args[2] + v_0 := v.Args[0] + if v_0.Op != Op386ADDL { + break + } + ptr := v_0.Args[1] + idx := v_0.Args[0] + val := v.Args[1] + if !(ptr.Op != OpSB) { + break + } + v.reset(Op386MOVWstoreidx1) + v.AuxInt = off + v.Aux = sym + v.AddArg(ptr) + v.AddArg(idx) + v.AddArg(val) + v.AddArg(mem) + return true + } // match: (MOVWstore [i] {s} p (SHRLconst [16] w) x:(MOVWstore [i-2] {s} p w mem)) // cond: x.Uses == 1 && clobber(x) // result: (MOVLstore [i-2] {s} p w mem) @@ -9947,6 +10219,9 @@ func rewriteValue386_Op386MOVWstore_0(v *Value) bool { v.AddArg(mem) return true } + return false +} +func rewriteValue386_Op386MOVWstore_10(v *Value) bool { // match: (MOVWstore [i] {s} p (SHRLconst [j] w) x:(MOVWstore [i-2] {s} p w0:(SHRLconst [j-16] w) mem)) // cond: x.Uses == 1 && clobber(x) // result: (MOVLstore [i-2] {s} p w0 mem) diff --git a/src/cmd/compile/internal/ssa/rewriteAMD64.go b/src/cmd/compile/internal/ssa/rewriteAMD64.go index b29b1cc0d4..98619943d7 100644 --- a/src/cmd/compile/internal/ssa/rewriteAMD64.go +++ b/src/cmd/compile/internal/ssa/rewriteAMD64.go @@ -301,7 +301,7 @@ func rewriteValueAMD64(v *Value) bool { case OpAMD64MOVQi2f: return rewriteValueAMD64_OpAMD64MOVQi2f_0(v) case OpAMD64MOVQload: - return rewriteValueAMD64_OpAMD64MOVQload_0(v) + return rewriteValueAMD64_OpAMD64MOVQload_0(v) || rewriteValueAMD64_OpAMD64MOVQload_10(v) case OpAMD64MOVQloadidx1: return rewriteValueAMD64_OpAMD64MOVQloadidx1_0(v) case OpAMD64MOVQloadidx8: @@ -10220,6 +10220,28 @@ func rewriteValueAMD64_OpAMD64LEAL_0(v *Value) bool { v.AddArg(y) return true } + // match: (LEAL [c] {s} (ADDL y x)) + // cond: x.Op != OpSB && y.Op != OpSB + // result: (LEAL1 [c] {s} x y) + for { + c := v.AuxInt + s := v.Aux + v_0 := v.Args[0] + if v_0.Op != OpAMD64ADDL { + break + } + x := v_0.Args[1] + y := v_0.Args[0] + if !(x.Op != OpSB && y.Op != OpSB) { + break + } + v.reset(OpAMD64LEAL1) + v.AuxInt = c + v.Aux = s + v.AddArg(x) + v.AddArg(y) + return true + } return false } func rewriteValueAMD64_OpAMD64LEAL1_0(v *Value) bool { @@ -10634,6 +10656,28 @@ func rewriteValueAMD64_OpAMD64LEAQ_0(v *Value) bool { v.AddArg(y) return true } + // match: (LEAQ [c] {s} (ADDQ y x)) + // cond: x.Op != OpSB && y.Op != OpSB + // result: (LEAQ1 [c] {s} x y) + for { + c := v.AuxInt + s := v.Aux + v_0 := v.Args[0] + if v_0.Op != OpAMD64ADDQ { + break + } + x := v_0.Args[1] + y := v_0.Args[0] + if !(x.Op != OpSB && y.Op != OpSB) { + break + } + v.reset(OpAMD64LEAQ1) + v.AuxInt = c + v.Aux = s + v.AddArg(x) + v.AddArg(y) + return true + } // match: (LEAQ [off1] {sym1} (LEAQ [off2] {sym2} x)) // cond: is32Bit(off1+off2) && canMergeSym(sym1, sym2) // result: (LEAQ [off1+off2] {mergeSym(sym1,sym2)} x) @@ -11770,6 +11814,30 @@ func rewriteValueAMD64_OpAMD64MOVBload_0(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVBload [off] {sym} (ADDQ idx ptr) mem) + // cond: ptr.Op != OpSB + // result: (MOVBloadidx1 [off] {sym} ptr idx mem) + for { + off := v.AuxInt + sym := v.Aux + mem := v.Args[1] + v_0 := v.Args[0] + if v_0.Op != OpAMD64ADDQ { + break + } + ptr := v_0.Args[1] + idx := v_0.Args[0] + if !(ptr.Op != OpSB) { + break + } + v.reset(OpAMD64MOVBloadidx1) + v.AuxInt = off + v.Aux = sym + v.AddArg(ptr) + v.AddArg(idx) + v.AddArg(mem) + return true + } // match: (MOVBload [off1] {sym1} (LEAL [off2] {sym2} base) mem) // cond: canMergeSym(sym1, sym2) && is32Bit(off1+off2) // result: (MOVBload [off1+off2] {mergeSym(sym1,sym2)} base mem) @@ -12419,6 +12487,32 @@ func rewriteValueAMD64_OpAMD64MOVBstore_10(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVBstore [off] {sym} (ADDQ idx ptr) val mem) + // cond: ptr.Op != OpSB + // result: (MOVBstoreidx1 [off] {sym} ptr idx val mem) + for { + off := v.AuxInt + sym := v.Aux + mem := v.Args[2] + v_0 := v.Args[0] + if v_0.Op != OpAMD64ADDQ { + break + } + ptr := v_0.Args[1] + idx := v_0.Args[0] + val := v.Args[1] + if !(ptr.Op != OpSB) { + break + } + v.reset(OpAMD64MOVBstoreidx1) + v.AuxInt = off + v.Aux = sym + v.AddArg(ptr) + v.AddArg(idx) + v.AddArg(val) + v.AddArg(mem) + return true + } // match: (MOVBstore [i] {s} p w x0:(MOVBstore [i-1] {s} p (SHRWconst [8] w) mem)) // cond: x0.Uses == 1 && clobber(x0) // result: (MOVWstore [i-1] {s} p (ROLWconst [8] w) mem) @@ -12451,6 +12545,10 @@ func rewriteValueAMD64_OpAMD64MOVBstore_10(v *Value) bool { v.AddArg(mem) return true } + return false +} +func rewriteValueAMD64_OpAMD64MOVBstore_20(v *Value) bool { + b := v.Block // match: (MOVBstore [i] {s} p w x2:(MOVBstore [i-1] {s} p (SHRLconst [8] w) x1:(MOVBstore [i-2] {s} p (SHRLconst [16] w) x0:(MOVBstore [i-3] {s} p (SHRLconst [24] w) mem)))) // cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && clobber(x0) && clobber(x1) && clobber(x2) // result: (MOVLstore [i-3] {s} p (BSWAPL w) mem) @@ -12506,11 +12604,6 @@ func rewriteValueAMD64_OpAMD64MOVBstore_10(v *Value) bool { v.AddArg(mem) return true } - return false -} -func rewriteValueAMD64_OpAMD64MOVBstore_20(v *Value) bool { - b := v.Block - typ := &b.Func.Config.Types // match: (MOVBstore [i] {s} p w x6:(MOVBstore [i-1] {s} p (SHRQconst [8] w) x5:(MOVBstore [i-2] {s} p (SHRQconst [16] w) x4:(MOVBstore [i-3] {s} p (SHRQconst [24] w) x3:(MOVBstore [i-4] {s} p (SHRQconst [32] w) x2:(MOVBstore [i-5] {s} p (SHRQconst [40] w) x1:(MOVBstore [i-6] {s} p (SHRQconst [48] w) x0:(MOVBstore [i-7] {s} p (SHRQconst [56] w) mem)))))))) // cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) // result: (MOVQstore [i-7] {s} p (BSWAPQ w) mem) @@ -12856,6 +12949,11 @@ func rewriteValueAMD64_OpAMD64MOVBstore_20(v *Value) bool { v.AddArg(mem) return true } + return false +} +func rewriteValueAMD64_OpAMD64MOVBstore_30(v *Value) bool { + b := v.Block + typ := &b.Func.Config.Types // match: (MOVBstore [i] {s} p x1:(MOVBload [j] {s2} p2 mem) mem2:(MOVBstore [i-1] {s} p x2:(MOVBload [j-1] {s2} p2 mem) mem)) // cond: x1.Uses == 1 && x2.Uses == 1 && mem2.Uses == 1 && clobber(x1) && clobber(x2) && clobber(mem2) // result: (MOVWstore [i-1] {s} p (MOVWload [j-1] {s2} p2 mem) mem) @@ -12901,9 +12999,6 @@ func rewriteValueAMD64_OpAMD64MOVBstore_20(v *Value) bool { v.AddArg(mem) return true } - return false -} -func rewriteValueAMD64_OpAMD64MOVBstore_30(v *Value) bool { // match: (MOVBstore [off1] {sym1} (LEAL [off2] {sym2} base) val mem) // cond: canMergeSym(sym1, sym2) && is32Bit(off1+off2) // result: (MOVBstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) @@ -14291,6 +14386,30 @@ func rewriteValueAMD64_OpAMD64MOVLload_0(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVLload [off] {sym} (ADDQ idx ptr) mem) + // cond: ptr.Op != OpSB + // result: (MOVLloadidx1 [off] {sym} ptr idx mem) + for { + off := v.AuxInt + sym := v.Aux + mem := v.Args[1] + v_0 := v.Args[0] + if v_0.Op != OpAMD64ADDQ { + break + } + ptr := v_0.Args[1] + idx := v_0.Args[0] + if !(ptr.Op != OpSB) { + break + } + v.reset(OpAMD64MOVLloadidx1) + v.AuxInt = off + v.Aux = sym + v.AddArg(ptr) + v.AddArg(idx) + v.AddArg(mem) + return true + } // match: (MOVLload [off1] {sym1} (LEAL [off2] {sym2} base) mem) // cond: canMergeSym(sym1, sym2) && is32Bit(off1+off2) // result: (MOVLload [off1+off2] {mergeSym(sym1,sym2)} base mem) @@ -14338,6 +14457,11 @@ func rewriteValueAMD64_OpAMD64MOVLload_0(v *Value) bool { v.AddArg(mem) return true } + return false +} +func rewriteValueAMD64_OpAMD64MOVLload_10(v *Value) bool { + b := v.Block + config := b.Func.Config // match: (MOVLload [off] {sym} ptr (MOVSSstore [off] {sym} ptr val _)) // result: (MOVLf2i val) for { @@ -14358,11 +14482,6 @@ func rewriteValueAMD64_OpAMD64MOVLload_0(v *Value) bool { v.AddArg(val) return true } - return false -} -func rewriteValueAMD64_OpAMD64MOVLload_10(v *Value) bool { - b := v.Block - config := b.Func.Config // match: (MOVLload [off] {sym} (SB) _) // cond: symIsRO(sym) // result: (MOVQconst [int64(read32(sym, off, config.BigEndian))]) @@ -15014,6 +15133,32 @@ func rewriteValueAMD64_OpAMD64MOVLstore_0(v *Value) bool { func rewriteValueAMD64_OpAMD64MOVLstore_10(v *Value) bool { b := v.Block typ := &b.Func.Config.Types + // match: (MOVLstore [off] {sym} (ADDQ idx ptr) val mem) + // cond: ptr.Op != OpSB + // result: (MOVLstoreidx1 [off] {sym} ptr idx val mem) + for { + off := v.AuxInt + sym := v.Aux + mem := v.Args[2] + v_0 := v.Args[0] + if v_0.Op != OpAMD64ADDQ { + break + } + ptr := v_0.Args[1] + idx := v_0.Args[0] + val := v.Args[1] + if !(ptr.Op != OpSB) { + break + } + v.reset(OpAMD64MOVLstoreidx1) + v.AuxInt = off + v.Aux = sym + v.AddArg(ptr) + v.AddArg(idx) + v.AddArg(val) + v.AddArg(mem) + return true + } // match: (MOVLstore [i] {s} p (SHRQconst [32] w) x:(MOVLstore [i-4] {s} p w mem)) // cond: x.Uses == 1 && clobber(x) // result: (MOVQstore [i-4] {s} p w mem) @@ -15273,6 +15418,9 @@ func rewriteValueAMD64_OpAMD64MOVLstore_10(v *Value) bool { v.AddArg(mem) return true } + return false +} +func rewriteValueAMD64_OpAMD64MOVLstore_20(v *Value) bool { // match: (MOVLstore {sym} [off] ptr y:(ADDL l:(MOVLload [off] {sym} ptr mem) x) mem) // cond: y.Uses==1 && l.Uses==1 && clobber(y) && clobber(l) // result: (ADDLmodify [off] {sym} ptr x mem) @@ -15302,9 +15450,6 @@ func rewriteValueAMD64_OpAMD64MOVLstore_10(v *Value) bool { v.AddArg(mem) return true } - return false -} -func rewriteValueAMD64_OpAMD64MOVLstore_20(v *Value) bool { // match: (MOVLstore {sym} [off] ptr y:(ADDL x l:(MOVLload [off] {sym} ptr mem)) mem) // cond: y.Uses==1 && l.Uses==1 && clobber(y) && clobber(l) // result: (ADDLmodify [off] {sym} ptr x mem) @@ -15570,6 +15715,9 @@ func rewriteValueAMD64_OpAMD64MOVLstore_20(v *Value) bool { v.AddArg(mem) return true } + return false +} +func rewriteValueAMD64_OpAMD64MOVLstore_30(v *Value) bool { // match: (MOVLstore {sym} [off] ptr y:(BTRL l:(MOVLload [off] {sym} ptr mem) x) mem) // cond: y.Uses==1 && l.Uses==1 && clobber(y) && clobber(l) // result: (BTRLmodify [off] {sym} ptr x mem) @@ -15599,9 +15747,6 @@ func rewriteValueAMD64_OpAMD64MOVLstore_20(v *Value) bool { v.AddArg(mem) return true } - return false -} -func rewriteValueAMD64_OpAMD64MOVLstore_30(v *Value) bool { // match: (MOVLstore {sym} [off] ptr y:(BTSL l:(MOVLload [off] {sym} ptr mem) x) mem) // cond: y.Uses==1 && l.Uses==1 && clobber(y) && clobber(l) // result: (BTSLmodify [off] {sym} ptr x mem) @@ -16924,8 +17069,6 @@ func rewriteValueAMD64_OpAMD64MOVQi2f_0(v *Value) bool { return false } func rewriteValueAMD64_OpAMD64MOVQload_0(v *Value) bool { - b := v.Block - config := b.Func.Config // match: (MOVQload [off] {sym} ptr (MOVQstore [off2] {sym2} ptr2 x _)) // cond: sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) // result: x @@ -17074,6 +17217,30 @@ func rewriteValueAMD64_OpAMD64MOVQload_0(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVQload [off] {sym} (ADDQ idx ptr) mem) + // cond: ptr.Op != OpSB + // result: (MOVQloadidx1 [off] {sym} ptr idx mem) + for { + off := v.AuxInt + sym := v.Aux + mem := v.Args[1] + v_0 := v.Args[0] + if v_0.Op != OpAMD64ADDQ { + break + } + ptr := v_0.Args[1] + idx := v_0.Args[0] + if !(ptr.Op != OpSB) { + break + } + v.reset(OpAMD64MOVQloadidx1) + v.AuxInt = off + v.Aux = sym + v.AddArg(ptr) + v.AddArg(idx) + v.AddArg(mem) + return true + } // match: (MOVQload [off1] {sym1} (LEAL [off2] {sym2} base) mem) // cond: canMergeSym(sym1, sym2) && is32Bit(off1+off2) // result: (MOVQload [off1+off2] {mergeSym(sym1,sym2)} base mem) @@ -17141,6 +17308,11 @@ func rewriteValueAMD64_OpAMD64MOVQload_0(v *Value) bool { v.AddArg(val) return true } + return false +} +func rewriteValueAMD64_OpAMD64MOVQload_10(v *Value) bool { + b := v.Block + config := b.Func.Config // match: (MOVQload [off] {sym} (SB) _) // cond: symIsRO(sym) // result: (MOVQconst [int64(read64(sym, off, config.BigEndian))]) @@ -17580,6 +17752,32 @@ func rewriteValueAMD64_OpAMD64MOVQstore_0(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVQstore [off] {sym} (ADDQ idx ptr) val mem) + // cond: ptr.Op != OpSB + // result: (MOVQstoreidx1 [off] {sym} ptr idx val mem) + for { + off := v.AuxInt + sym := v.Aux + mem := v.Args[2] + v_0 := v.Args[0] + if v_0.Op != OpAMD64ADDQ { + break + } + ptr := v_0.Args[1] + idx := v_0.Args[0] + val := v.Args[1] + if !(ptr.Op != OpSB) { + break + } + v.reset(OpAMD64MOVQstoreidx1) + v.AuxInt = off + v.Aux = sym + v.AddArg(ptr) + v.AddArg(idx) + v.AddArg(val) + v.AddArg(mem) + return true + } // match: (MOVQstore [off1] {sym1} (LEAL [off2] {sym2} base) val mem) // cond: canMergeSym(sym1, sym2) && is32Bit(off1+off2) // result: (MOVQstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) @@ -17656,6 +17854,9 @@ func rewriteValueAMD64_OpAMD64MOVQstore_0(v *Value) bool { v.AddArg(mem) return true } + return false +} +func rewriteValueAMD64_OpAMD64MOVQstore_10(v *Value) bool { // match: (MOVQstore {sym} [off] ptr y:(ANDQload x [off] {sym} ptr mem) mem) // cond: y.Uses==1 && clobber(y) // result: (ANDQmodify [off] {sym} ptr x mem) @@ -17681,9 +17882,6 @@ func rewriteValueAMD64_OpAMD64MOVQstore_0(v *Value) bool { v.AddArg(mem) return true } - return false -} -func rewriteValueAMD64_OpAMD64MOVQstore_10(v *Value) bool { // match: (MOVQstore {sym} [off] ptr y:(ORQload x [off] {sym} ptr mem) mem) // cond: y.Uses==1 && clobber(y) // result: (ORQmodify [off] {sym} ptr x mem) @@ -17940,6 +18138,9 @@ func rewriteValueAMD64_OpAMD64MOVQstore_10(v *Value) bool { v.AddArg(mem) return true } + return false +} +func rewriteValueAMD64_OpAMD64MOVQstore_20(v *Value) bool { // match: (MOVQstore {sym} [off] ptr y:(XORQ l:(MOVQload [off] {sym} ptr mem) x) mem) // cond: y.Uses==1 && l.Uses==1 && clobber(y) && clobber(l) // result: (XORQmodify [off] {sym} ptr x mem) @@ -17969,9 +18170,6 @@ func rewriteValueAMD64_OpAMD64MOVQstore_10(v *Value) bool { v.AddArg(mem) return true } - return false -} -func rewriteValueAMD64_OpAMD64MOVQstore_20(v *Value) bool { // match: (MOVQstore {sym} [off] ptr y:(XORQ x l:(MOVQload [off] {sym} ptr mem)) mem) // cond: y.Uses==1 && l.Uses==1 && clobber(y) && clobber(l) // result: (XORQmodify [off] {sym} ptr x mem) @@ -18234,6 +18432,9 @@ func rewriteValueAMD64_OpAMD64MOVQstore_20(v *Value) bool { v.AddArg(mem) return true } + return false +} +func rewriteValueAMD64_OpAMD64MOVQstore_30(v *Value) bool { // match: (MOVQstore [off] {sym} ptr a:(BTRQconst [c] l:(MOVQload [off] {sym} ptr2 mem)) mem) // cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(c,off) && clobber(l) && clobber(a) // result: (BTRQconstmodify {sym} [makeValAndOff(c,off)] ptr mem) @@ -18263,9 +18464,6 @@ func rewriteValueAMD64_OpAMD64MOVQstore_20(v *Value) bool { v.AddArg(mem) return true } - return false -} -func rewriteValueAMD64_OpAMD64MOVQstore_30(v *Value) bool { // match: (MOVQstore [off] {sym} ptr a:(BTSQconst [c] l:(MOVQload [off] {sym} ptr2 mem)) mem) // cond: isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && validValAndOff(c,off) && clobber(l) && clobber(a) // result: (BTSQconstmodify {sym} [makeValAndOff(c,off)] ptr mem) @@ -18954,6 +19152,30 @@ func rewriteValueAMD64_OpAMD64MOVSDload_0(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVSDload [off] {sym} (ADDQ idx ptr) mem) + // cond: ptr.Op != OpSB + // result: (MOVSDloadidx1 [off] {sym} ptr idx mem) + for { + off := v.AuxInt + sym := v.Aux + mem := v.Args[1] + v_0 := v.Args[0] + if v_0.Op != OpAMD64ADDQ { + break + } + ptr := v_0.Args[1] + idx := v_0.Args[0] + if !(ptr.Op != OpSB) { + break + } + v.reset(OpAMD64MOVSDloadidx1) + v.AuxInt = off + v.Aux = sym + v.AddArg(ptr) + v.AddArg(idx) + v.AddArg(mem) + return true + } // match: (MOVSDload [off] {sym} ptr (MOVQstore [off] {sym} ptr val _)) // result: (MOVQi2f val) for { @@ -19282,6 +19504,32 @@ func rewriteValueAMD64_OpAMD64MOVSDstore_0(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVSDstore [off] {sym} (ADDQ idx ptr) val mem) + // cond: ptr.Op != OpSB + // result: (MOVSDstoreidx1 [off] {sym} ptr idx val mem) + for { + off := v.AuxInt + sym := v.Aux + mem := v.Args[2] + v_0 := v.Args[0] + if v_0.Op != OpAMD64ADDQ { + break + } + ptr := v_0.Args[1] + idx := v_0.Args[0] + val := v.Args[1] + if !(ptr.Op != OpSB) { + break + } + v.reset(OpAMD64MOVSDstoreidx1) + v.AuxInt = off + v.Aux = sym + v.AddArg(ptr) + v.AddArg(idx) + v.AddArg(val) + v.AddArg(mem) + return true + } // match: (MOVSDstore [off] {sym} ptr (MOVQi2f val) mem) // result: (MOVQstore [off] {sym} ptr val mem) for { @@ -19614,6 +19862,30 @@ func rewriteValueAMD64_OpAMD64MOVSSload_0(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVSSload [off] {sym} (ADDQ idx ptr) mem) + // cond: ptr.Op != OpSB + // result: (MOVSSloadidx1 [off] {sym} ptr idx mem) + for { + off := v.AuxInt + sym := v.Aux + mem := v.Args[1] + v_0 := v.Args[0] + if v_0.Op != OpAMD64ADDQ { + break + } + ptr := v_0.Args[1] + idx := v_0.Args[0] + if !(ptr.Op != OpSB) { + break + } + v.reset(OpAMD64MOVSSloadidx1) + v.AuxInt = off + v.Aux = sym + v.AddArg(ptr) + v.AddArg(idx) + v.AddArg(mem) + return true + } // match: (MOVSSload [off] {sym} ptr (MOVLstore [off] {sym} ptr val _)) // result: (MOVLi2f val) for { @@ -19942,6 +20214,32 @@ func rewriteValueAMD64_OpAMD64MOVSSstore_0(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVSSstore [off] {sym} (ADDQ idx ptr) val mem) + // cond: ptr.Op != OpSB + // result: (MOVSSstoreidx1 [off] {sym} ptr idx val mem) + for { + off := v.AuxInt + sym := v.Aux + mem := v.Args[2] + v_0 := v.Args[0] + if v_0.Op != OpAMD64ADDQ { + break + } + ptr := v_0.Args[1] + idx := v_0.Args[0] + val := v.Args[1] + if !(ptr.Op != OpSB) { + break + } + v.reset(OpAMD64MOVSSstoreidx1) + v.AuxInt = off + v.Aux = sym + v.AddArg(ptr) + v.AddArg(idx) + v.AddArg(val) + v.AddArg(mem) + return true + } // match: (MOVSSstore [off] {sym} ptr (MOVLi2f val) mem) // result: (MOVLstore [off] {sym} ptr val mem) for { @@ -20656,6 +20954,30 @@ func rewriteValueAMD64_OpAMD64MOVWload_0(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVWload [off] {sym} (ADDQ idx ptr) mem) + // cond: ptr.Op != OpSB + // result: (MOVWloadidx1 [off] {sym} ptr idx mem) + for { + off := v.AuxInt + sym := v.Aux + mem := v.Args[1] + v_0 := v.Args[0] + if v_0.Op != OpAMD64ADDQ { + break + } + ptr := v_0.Args[1] + idx := v_0.Args[0] + if !(ptr.Op != OpSB) { + break + } + v.reset(OpAMD64MOVWloadidx1) + v.AuxInt = off + v.Aux = sym + v.AddArg(ptr) + v.AddArg(idx) + v.AddArg(mem) + return true + } // match: (MOVWload [off1] {sym1} (LEAL [off2] {sym2} base) mem) // cond: canMergeSym(sym1, sym2) && is32Bit(off1+off2) // result: (MOVWload [off1+off2] {mergeSym(sym1,sym2)} base mem) @@ -21205,6 +21527,37 @@ func rewriteValueAMD64_OpAMD64MOVWstore_0(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVWstore [off] {sym} (ADDQ idx ptr) val mem) + // cond: ptr.Op != OpSB + // result: (MOVWstoreidx1 [off] {sym} ptr idx val mem) + for { + off := v.AuxInt + sym := v.Aux + mem := v.Args[2] + v_0 := v.Args[0] + if v_0.Op != OpAMD64ADDQ { + break + } + ptr := v_0.Args[1] + idx := v_0.Args[0] + val := v.Args[1] + if !(ptr.Op != OpSB) { + break + } + v.reset(OpAMD64MOVWstoreidx1) + v.AuxInt = off + v.Aux = sym + v.AddArg(ptr) + v.AddArg(idx) + v.AddArg(val) + v.AddArg(mem) + return true + } + return false +} +func rewriteValueAMD64_OpAMD64MOVWstore_10(v *Value) bool { + b := v.Block + typ := &b.Func.Config.Types // match: (MOVWstore [i] {s} p (SHRLconst [16] w) x:(MOVWstore [i-2] {s} p w mem)) // cond: x.Uses == 1 && clobber(x) // result: (MOVLstore [i-2] {s} p w mem) @@ -21234,11 +21587,6 @@ func rewriteValueAMD64_OpAMD64MOVWstore_0(v *Value) bool { v.AddArg(mem) return true } - return false -} -func rewriteValueAMD64_OpAMD64MOVWstore_10(v *Value) bool { - b := v.Block - typ := &b.Func.Config.Types // match: (MOVWstore [i] {s} p (SHRQconst [16] w) x:(MOVWstore [i-2] {s} p w mem)) // cond: x.Uses == 1 && clobber(x) // result: (MOVLstore [i-2] {s} p w mem) diff --git a/src/cmd/compile/internal/ssa/rewriteARM64.go b/src/cmd/compile/internal/ssa/rewriteARM64.go index a62ac8a6fc..485aee546a 100644 --- a/src/cmd/compile/internal/ssa/rewriteARM64.go +++ b/src/cmd/compile/internal/ssa/rewriteARM64.go @@ -176,7 +176,7 @@ func rewriteValueARM64(v *Value) bool { case OpARM64MOVBreg: return rewriteValueARM64_OpARM64MOVBreg_0(v) case OpARM64MOVBstore: - return rewriteValueARM64_OpARM64MOVBstore_0(v) || rewriteValueARM64_OpARM64MOVBstore_10(v) || rewriteValueARM64_OpARM64MOVBstore_20(v) || rewriteValueARM64_OpARM64MOVBstore_30(v) + return rewriteValueARM64_OpARM64MOVBstore_0(v) || rewriteValueARM64_OpARM64MOVBstore_10(v) || rewriteValueARM64_OpARM64MOVBstore_20(v) || rewriteValueARM64_OpARM64MOVBstore_30(v) || rewriteValueARM64_OpARM64MOVBstore_40(v) || rewriteValueARM64_OpARM64MOVBstore_50(v) case OpARM64MOVBstoreidx: return rewriteValueARM64_OpARM64MOVBstoreidx_0(v) || rewriteValueARM64_OpARM64MOVBstoreidx_10(v) case OpARM64MOVBstorezero: @@ -288,7 +288,7 @@ func rewriteValueARM64(v *Value) bool { case OpARM64NotEqual: return rewriteValueARM64_OpARM64NotEqual_0(v) case OpARM64OR: - return rewriteValueARM64_OpARM64OR_0(v) || rewriteValueARM64_OpARM64OR_10(v) || rewriteValueARM64_OpARM64OR_20(v) || rewriteValueARM64_OpARM64OR_30(v) || rewriteValueARM64_OpARM64OR_40(v) + return rewriteValueARM64_OpARM64OR_0(v) || rewriteValueARM64_OpARM64OR_10(v) || rewriteValueARM64_OpARM64OR_20(v) || rewriteValueARM64_OpARM64OR_30(v) || rewriteValueARM64_OpARM64OR_40(v) || rewriteValueARM64_OpARM64OR_50(v) case OpARM64ORN: return rewriteValueARM64_OpARM64ORN_0(v) case OpARM64ORNshiftLL: @@ -300,7 +300,7 @@ func rewriteValueARM64(v *Value) bool { case OpARM64ORconst: return rewriteValueARM64_OpARM64ORconst_0(v) case OpARM64ORshiftLL: - return rewriteValueARM64_OpARM64ORshiftLL_0(v) || rewriteValueARM64_OpARM64ORshiftLL_10(v) || rewriteValueARM64_OpARM64ORshiftLL_20(v) + return rewriteValueARM64_OpARM64ORshiftLL_0(v) || rewriteValueARM64_OpARM64ORshiftLL_10(v) || rewriteValueARM64_OpARM64ORshiftLL_20(v) || rewriteValueARM64_OpARM64ORshiftLL_30(v) case OpARM64ORshiftRA: return rewriteValueARM64_OpARM64ORshiftRA_0(v) case OpARM64ORshiftRL: @@ -8974,6 +8974,43 @@ func rewriteValueARM64_OpARM64MOVBstore_10(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVBstore [1] {s} (ADD idx0 ptr0) (SRLconst [8] w) x:(MOVBstoreidx ptr1 idx1 w mem)) + // cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x) + // result: (MOVHstoreidx ptr1 idx1 w mem) + for { + if v.AuxInt != 1 { + break + } + s := v.Aux + _ = v.Args[2] + v_0 := v.Args[0] + if v_0.Op != OpARM64ADD { + break + } + ptr0 := v_0.Args[1] + idx0 := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARM64SRLconst || v_1.AuxInt != 8 { + break + } + w := v_1.Args[0] + x := v.Args[2] + if x.Op != OpARM64MOVBstoreidx { + break + } + mem := x.Args[3] + ptr1 := x.Args[0] + idx1 := x.Args[1] + if w != x.Args[2] || !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) { + break + } + v.reset(OpARM64MOVHstoreidx) + v.AddArg(ptr1) + v.AddArg(idx1) + v.AddArg(w) + v.AddArg(mem) + return true + } // match: (MOVBstore [i] {s} ptr0 (UBFX [armBFAuxInt(8, 8)] w) x:(MOVBstore [i-1] {s} ptr1 w mem)) // cond: x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x) // result: (MOVHstore [i-1] {s} ptr0 w mem) @@ -9041,6 +9078,43 @@ func rewriteValueARM64_OpARM64MOVBstore_10(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVBstore [1] {s} (ADD idx0 ptr0) (UBFX [armBFAuxInt(8, 8)] w) x:(MOVBstoreidx ptr1 idx1 w mem)) + // cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x) + // result: (MOVHstoreidx ptr1 idx1 w mem) + for { + if v.AuxInt != 1 { + break + } + s := v.Aux + _ = v.Args[2] + v_0 := v.Args[0] + if v_0.Op != OpARM64ADD { + break + } + ptr0 := v_0.Args[1] + idx0 := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARM64UBFX || v_1.AuxInt != armBFAuxInt(8, 8) { + break + } + w := v_1.Args[0] + x := v.Args[2] + if x.Op != OpARM64MOVBstoreidx { + break + } + mem := x.Args[3] + ptr1 := x.Args[0] + idx1 := x.Args[1] + if w != x.Args[2] || !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) { + break + } + v.reset(OpARM64MOVHstoreidx) + v.AddArg(ptr1) + v.AddArg(idx1) + v.AddArg(w) + v.AddArg(mem) + return true + } // match: (MOVBstore [i] {s} ptr0 (UBFX [armBFAuxInt(8, 24)] w) x:(MOVBstore [i-1] {s} ptr1 w mem)) // cond: x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x) // result: (MOVHstore [i-1] {s} ptr0 w mem) @@ -9108,6 +9182,43 @@ func rewriteValueARM64_OpARM64MOVBstore_10(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVBstore [1] {s} (ADD idx0 ptr0) (UBFX [armBFAuxInt(8, 24)] w) x:(MOVBstoreidx ptr1 idx1 w mem)) + // cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x) + // result: (MOVHstoreidx ptr1 idx1 w mem) + for { + if v.AuxInt != 1 { + break + } + s := v.Aux + _ = v.Args[2] + v_0 := v.Args[0] + if v_0.Op != OpARM64ADD { + break + } + ptr0 := v_0.Args[1] + idx0 := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARM64UBFX || v_1.AuxInt != armBFAuxInt(8, 24) { + break + } + w := v_1.Args[0] + x := v.Args[2] + if x.Op != OpARM64MOVBstoreidx { + break + } + mem := x.Args[3] + ptr1 := x.Args[0] + idx1 := x.Args[1] + if w != x.Args[2] || !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) { + break + } + v.reset(OpARM64MOVHstoreidx) + v.AddArg(ptr1) + v.AddArg(idx1) + v.AddArg(w) + v.AddArg(mem) + return true + } // match: (MOVBstore [i] {s} ptr0 (SRLconst [8] (MOVDreg w)) x:(MOVBstore [i-1] {s} ptr1 w mem)) // cond: x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x) // result: (MOVHstore [i-1] {s} ptr0 w mem) @@ -9142,6 +9253,9 @@ func rewriteValueARM64_OpARM64MOVBstore_10(v *Value) bool { v.AddArg(mem) return true } + return false +} +func rewriteValueARM64_OpARM64MOVBstore_20(v *Value) bool { // match: (MOVBstore [1] {s} (ADD ptr0 idx0) (SRLconst [8] (MOVDreg w)) x:(MOVBstoreidx ptr1 idx1 w mem)) // cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x) // result: (MOVHstoreidx ptr1 idx1 w mem) @@ -9183,6 +9297,47 @@ func rewriteValueARM64_OpARM64MOVBstore_10(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVBstore [1] {s} (ADD idx0 ptr0) (SRLconst [8] (MOVDreg w)) x:(MOVBstoreidx ptr1 idx1 w mem)) + // cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x) + // result: (MOVHstoreidx ptr1 idx1 w mem) + for { + if v.AuxInt != 1 { + break + } + s := v.Aux + _ = v.Args[2] + v_0 := v.Args[0] + if v_0.Op != OpARM64ADD { + break + } + ptr0 := v_0.Args[1] + idx0 := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARM64SRLconst || v_1.AuxInt != 8 { + break + } + v_1_0 := v_1.Args[0] + if v_1_0.Op != OpARM64MOVDreg { + break + } + w := v_1_0.Args[0] + x := v.Args[2] + if x.Op != OpARM64MOVBstoreidx { + break + } + mem := x.Args[3] + ptr1 := x.Args[0] + idx1 := x.Args[1] + if w != x.Args[2] || !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) { + break + } + v.reset(OpARM64MOVHstoreidx) + v.AddArg(ptr1) + v.AddArg(idx1) + v.AddArg(w) + v.AddArg(mem) + return true + } // match: (MOVBstore [i] {s} ptr0 (SRLconst [j] w) x:(MOVBstore [i-1] {s} ptr1 w0:(SRLconst [j-8] w) mem)) // cond: x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x) // result: (MOVHstore [i-1] {s} ptr0 w0 mem) @@ -9254,10 +9409,45 @@ func rewriteValueARM64_OpARM64MOVBstore_10(v *Value) bool { v.AddArg(mem) return true } - return false -} -func rewriteValueARM64_OpARM64MOVBstore_20(v *Value) bool { - b := v.Block + // match: (MOVBstore [1] {s} (ADD idx0 ptr0) (SRLconst [j] w) x:(MOVBstoreidx ptr1 idx1 w0:(SRLconst [j-8] w) mem)) + // cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x) + // result: (MOVHstoreidx ptr1 idx1 w0 mem) + for { + if v.AuxInt != 1 { + break + } + s := v.Aux + _ = v.Args[2] + v_0 := v.Args[0] + if v_0.Op != OpARM64ADD { + break + } + ptr0 := v_0.Args[1] + idx0 := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARM64SRLconst { + break + } + j := v_1.AuxInt + w := v_1.Args[0] + x := v.Args[2] + if x.Op != OpARM64MOVBstoreidx { + break + } + mem := x.Args[3] + ptr1 := x.Args[0] + idx1 := x.Args[1] + w0 := x.Args[2] + if w0.Op != OpARM64SRLconst || w0.AuxInt != j-8 || w != w0.Args[0] || !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) { + break + } + v.reset(OpARM64MOVHstoreidx) + v.AddArg(ptr1) + v.AddArg(idx1) + v.AddArg(w0) + v.AddArg(mem) + return true + } // match: (MOVBstore [i] {s} ptr0 (UBFX [bfc] w) x:(MOVBstore [i-1] {s} ptr1 w0:(UBFX [bfc2] w) mem)) // cond: x.Uses == 1 && isSamePtr(ptr0, ptr1) && getARM64BFwidth(bfc) == 32 - getARM64BFlsb(bfc) && getARM64BFwidth(bfc2) == 32 - getARM64BFlsb(bfc2) && getARM64BFlsb(bfc2) == getARM64BFlsb(bfc) - 8 && clobber(x) // result: (MOVHstore [i-1] {s} ptr0 w0 mem) @@ -9337,6 +9527,49 @@ func rewriteValueARM64_OpARM64MOVBstore_20(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVBstore [1] {s} (ADD idx0 ptr0) (UBFX [bfc] w) x:(MOVBstoreidx ptr1 idx1 w0:(UBFX [bfc2] w) mem)) + // cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && getARM64BFwidth(bfc) == 32 - getARM64BFlsb(bfc) && getARM64BFwidth(bfc2) == 32 - getARM64BFlsb(bfc2) && getARM64BFlsb(bfc2) == getARM64BFlsb(bfc) - 8 && clobber(x) + // result: (MOVHstoreidx ptr1 idx1 w0 mem) + for { + if v.AuxInt != 1 { + break + } + s := v.Aux + _ = v.Args[2] + v_0 := v.Args[0] + if v_0.Op != OpARM64ADD { + break + } + ptr0 := v_0.Args[1] + idx0 := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARM64UBFX { + break + } + bfc := v_1.AuxInt + w := v_1.Args[0] + x := v.Args[2] + if x.Op != OpARM64MOVBstoreidx { + break + } + mem := x.Args[3] + ptr1 := x.Args[0] + idx1 := x.Args[1] + w0 := x.Args[2] + if w0.Op != OpARM64UBFX { + break + } + bfc2 := w0.AuxInt + if w != w0.Args[0] || !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && getARM64BFwidth(bfc) == 32-getARM64BFlsb(bfc) && getARM64BFwidth(bfc2) == 32-getARM64BFlsb(bfc2) && getARM64BFlsb(bfc2) == getARM64BFlsb(bfc)-8 && clobber(x)) { + break + } + v.reset(OpARM64MOVHstoreidx) + v.AddArg(ptr1) + v.AddArg(idx1) + v.AddArg(w0) + v.AddArg(mem) + return true + } // match: (MOVBstore [i] {s} ptr0 (SRLconst [j] (MOVDreg w)) x:(MOVBstore [i-1] {s} ptr1 w0:(SRLconst [j-8] (MOVDreg w)) mem)) // cond: x.Uses == 1 && isSamePtr(ptr0, ptr1) && clobber(x) // result: (MOVHstore [i-1] {s} ptr0 w0 mem) @@ -9424,6 +9657,57 @@ func rewriteValueARM64_OpARM64MOVBstore_20(v *Value) bool { v.AddArg(mem) return true } + return false +} +func rewriteValueARM64_OpARM64MOVBstore_30(v *Value) bool { + b := v.Block + // match: (MOVBstore [1] {s} (ADD idx0 ptr0) (SRLconst [j] (MOVDreg w)) x:(MOVBstoreidx ptr1 idx1 w0:(SRLconst [j-8] (MOVDreg w)) mem)) + // cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x) + // result: (MOVHstoreidx ptr1 idx1 w0 mem) + for { + if v.AuxInt != 1 { + break + } + s := v.Aux + _ = v.Args[2] + v_0 := v.Args[0] + if v_0.Op != OpARM64ADD { + break + } + ptr0 := v_0.Args[1] + idx0 := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARM64SRLconst { + break + } + j := v_1.AuxInt + v_1_0 := v_1.Args[0] + if v_1_0.Op != OpARM64MOVDreg { + break + } + w := v_1_0.Args[0] + x := v.Args[2] + if x.Op != OpARM64MOVBstoreidx { + break + } + mem := x.Args[3] + ptr1 := x.Args[0] + idx1 := x.Args[1] + w0 := x.Args[2] + if w0.Op != OpARM64SRLconst || w0.AuxInt != j-8 { + break + } + w0_0 := w0.Args[0] + if w0_0.Op != OpARM64MOVDreg || w != w0_0.Args[0] || !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) { + break + } + v.reset(OpARM64MOVHstoreidx) + v.AddArg(ptr1) + v.AddArg(idx1) + v.AddArg(w0) + v.AddArg(mem) + return true + } // match: (MOVBstore [i] {s} ptr w x0:(MOVBstore [i-1] {s} ptr (SRLconst [8] w) x1:(MOVBstore [i-2] {s} ptr (SRLconst [16] w) x2:(MOVBstore [i-3] {s} ptr (SRLconst [24] w) x3:(MOVBstore [i-4] {s} ptr (SRLconst [32] w) x4:(MOVBstore [i-5] {s} ptr (SRLconst [40] w) x5:(MOVBstore [i-6] {s} ptr (SRLconst [48] w) x6:(MOVBstore [i-7] {s} ptr (SRLconst [56] w) mem)))))))) // cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) // result: (MOVDstore [i-7] {s} ptr (REV w) mem) @@ -9633,6 +9917,112 @@ func rewriteValueARM64_OpARM64MOVBstore_20(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVBstore [7] {s} p w x0:(MOVBstore [6] {s} p (SRLconst [8] w) x1:(MOVBstore [5] {s} p (SRLconst [16] w) x2:(MOVBstore [4] {s} p (SRLconst [24] w) x3:(MOVBstore [3] {s} p (SRLconst [32] w) x4:(MOVBstore [2] {s} p (SRLconst [40] w) x5:(MOVBstore [1] {s} p1:(ADD idx1 ptr1) (SRLconst [48] w) x6:(MOVBstoreidx ptr0 idx0 (SRLconst [56] w) mem)))))))) + // cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) + // result: (MOVDstoreidx ptr0 idx0 (REV w) mem) + for { + if v.AuxInt != 7 { + break + } + s := v.Aux + _ = v.Args[2] + p := v.Args[0] + w := v.Args[1] + x0 := v.Args[2] + if x0.Op != OpARM64MOVBstore || x0.AuxInt != 6 || x0.Aux != s { + break + } + _ = x0.Args[2] + if p != x0.Args[0] { + break + } + x0_1 := x0.Args[1] + if x0_1.Op != OpARM64SRLconst || x0_1.AuxInt != 8 || w != x0_1.Args[0] { + break + } + x1 := x0.Args[2] + if x1.Op != OpARM64MOVBstore || x1.AuxInt != 5 || x1.Aux != s { + break + } + _ = x1.Args[2] + if p != x1.Args[0] { + break + } + x1_1 := x1.Args[1] + if x1_1.Op != OpARM64SRLconst || x1_1.AuxInt != 16 || w != x1_1.Args[0] { + break + } + x2 := x1.Args[2] + if x2.Op != OpARM64MOVBstore || x2.AuxInt != 4 || x2.Aux != s { + break + } + _ = x2.Args[2] + if p != x2.Args[0] { + break + } + x2_1 := x2.Args[1] + if x2_1.Op != OpARM64SRLconst || x2_1.AuxInt != 24 || w != x2_1.Args[0] { + break + } + x3 := x2.Args[2] + if x3.Op != OpARM64MOVBstore || x3.AuxInt != 3 || x3.Aux != s { + break + } + _ = x3.Args[2] + if p != x3.Args[0] { + break + } + x3_1 := x3.Args[1] + if x3_1.Op != OpARM64SRLconst || x3_1.AuxInt != 32 || w != x3_1.Args[0] { + break + } + x4 := x3.Args[2] + if x4.Op != OpARM64MOVBstore || x4.AuxInt != 2 || x4.Aux != s { + break + } + _ = x4.Args[2] + if p != x4.Args[0] { + break + } + x4_1 := x4.Args[1] + if x4_1.Op != OpARM64SRLconst || x4_1.AuxInt != 40 || w != x4_1.Args[0] { + break + } + x5 := x4.Args[2] + if x5.Op != OpARM64MOVBstore || x5.AuxInt != 1 || x5.Aux != s { + break + } + _ = x5.Args[2] + p1 := x5.Args[0] + if p1.Op != OpARM64ADD { + break + } + ptr1 := p1.Args[1] + idx1 := p1.Args[0] + x5_1 := x5.Args[1] + if x5_1.Op != OpARM64SRLconst || x5_1.AuxInt != 48 || w != x5_1.Args[0] { + break + } + x6 := x5.Args[2] + if x6.Op != OpARM64MOVBstoreidx { + break + } + mem := x6.Args[3] + ptr0 := x6.Args[0] + idx0 := x6.Args[1] + x6_2 := x6.Args[2] + if x6_2.Op != OpARM64SRLconst || x6_2.AuxInt != 56 || w != x6_2.Args[0] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6)) { + break + } + v.reset(OpARM64MOVDstoreidx) + v.AddArg(ptr0) + v.AddArg(idx0) + v0 := b.NewValue0(x5.Pos, OpARM64REV, w.Type) + v0.AddArg(w) + v.AddArg(v0) + v.AddArg(mem) + return true + } // match: (MOVBstore [i] {s} ptr w x0:(MOVBstore [i-1] {s} ptr (UBFX [armBFAuxInt(8, 24)] w) x1:(MOVBstore [i-2] {s} ptr (UBFX [armBFAuxInt(16, 16)] w) x2:(MOVBstore [i-3] {s} ptr (UBFX [armBFAuxInt(24, 8)] w) mem)))) // cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && clobber(x0) && clobber(x1) && clobber(x2) // result: (MOVWstore [i-3] {s} ptr (REVW w) mem) @@ -9746,6 +10136,64 @@ func rewriteValueARM64_OpARM64MOVBstore_20(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVBstore [3] {s} p w x0:(MOVBstore [2] {s} p (UBFX [armBFAuxInt(8, 24)] w) x1:(MOVBstore [1] {s} p1:(ADD idx1 ptr1) (UBFX [armBFAuxInt(16, 16)] w) x2:(MOVBstoreidx ptr0 idx0 (UBFX [armBFAuxInt(24, 8)] w) mem)))) + // cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0) && clobber(x1) && clobber(x2) + // result: (MOVWstoreidx ptr0 idx0 (REVW w) mem) + for { + if v.AuxInt != 3 { + break + } + s := v.Aux + _ = v.Args[2] + p := v.Args[0] + w := v.Args[1] + x0 := v.Args[2] + if x0.Op != OpARM64MOVBstore || x0.AuxInt != 2 || x0.Aux != s { + break + } + _ = x0.Args[2] + if p != x0.Args[0] { + break + } + x0_1 := x0.Args[1] + if x0_1.Op != OpARM64UBFX || x0_1.AuxInt != armBFAuxInt(8, 24) || w != x0_1.Args[0] { + break + } + x1 := x0.Args[2] + if x1.Op != OpARM64MOVBstore || x1.AuxInt != 1 || x1.Aux != s { + break + } + _ = x1.Args[2] + p1 := x1.Args[0] + if p1.Op != OpARM64ADD { + break + } + ptr1 := p1.Args[1] + idx1 := p1.Args[0] + x1_1 := x1.Args[1] + if x1_1.Op != OpARM64UBFX || x1_1.AuxInt != armBFAuxInt(16, 16) || w != x1_1.Args[0] { + break + } + x2 := x1.Args[2] + if x2.Op != OpARM64MOVBstoreidx { + break + } + mem := x2.Args[3] + ptr0 := x2.Args[0] + idx0 := x2.Args[1] + x2_2 := x2.Args[2] + if x2_2.Op != OpARM64UBFX || x2_2.AuxInt != armBFAuxInt(24, 8) || w != x2_2.Args[0] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0) && clobber(x1) && clobber(x2)) { + break + } + v.reset(OpARM64MOVWstoreidx) + v.AddArg(ptr0) + v.AddArg(idx0) + v0 := b.NewValue0(x1.Pos, OpARM64REVW, w.Type) + v0.AddArg(w) + v.AddArg(v0) + v.AddArg(mem) + return true + } // match: (MOVBstore [i] {s} ptr w x0:(MOVBstore [i-1] {s} ptr (SRLconst [8] (MOVDreg w)) x1:(MOVBstore [i-2] {s} ptr (SRLconst [16] (MOVDreg w)) x2:(MOVBstore [i-3] {s} ptr (SRLconst [24] (MOVDreg w)) mem)))) // cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && clobber(x0) && clobber(x1) && clobber(x2) // result: (MOVWstore [i-3] {s} ptr (REVW w) mem) @@ -9883,9 +10331,79 @@ func rewriteValueARM64_OpARM64MOVBstore_20(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVBstore [3] {s} p w x0:(MOVBstore [2] {s} p (SRLconst [8] (MOVDreg w)) x1:(MOVBstore [1] {s} p1:(ADD idx1 ptr1) (SRLconst [16] (MOVDreg w)) x2:(MOVBstoreidx ptr0 idx0 (SRLconst [24] (MOVDreg w)) mem)))) + // cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0) && clobber(x1) && clobber(x2) + // result: (MOVWstoreidx ptr0 idx0 (REVW w) mem) + for { + if v.AuxInt != 3 { + break + } + s := v.Aux + _ = v.Args[2] + p := v.Args[0] + w := v.Args[1] + x0 := v.Args[2] + if x0.Op != OpARM64MOVBstore || x0.AuxInt != 2 || x0.Aux != s { + break + } + _ = x0.Args[2] + if p != x0.Args[0] { + break + } + x0_1 := x0.Args[1] + if x0_1.Op != OpARM64SRLconst || x0_1.AuxInt != 8 { + break + } + x0_1_0 := x0_1.Args[0] + if x0_1_0.Op != OpARM64MOVDreg || w != x0_1_0.Args[0] { + break + } + x1 := x0.Args[2] + if x1.Op != OpARM64MOVBstore || x1.AuxInt != 1 || x1.Aux != s { + break + } + _ = x1.Args[2] + p1 := x1.Args[0] + if p1.Op != OpARM64ADD { + break + } + ptr1 := p1.Args[1] + idx1 := p1.Args[0] + x1_1 := x1.Args[1] + if x1_1.Op != OpARM64SRLconst || x1_1.AuxInt != 16 { + break + } + x1_1_0 := x1_1.Args[0] + if x1_1_0.Op != OpARM64MOVDreg || w != x1_1_0.Args[0] { + break + } + x2 := x1.Args[2] + if x2.Op != OpARM64MOVBstoreidx { + break + } + mem := x2.Args[3] + ptr0 := x2.Args[0] + idx0 := x2.Args[1] + x2_2 := x2.Args[2] + if x2_2.Op != OpARM64SRLconst || x2_2.AuxInt != 24 { + break + } + x2_2_0 := x2_2.Args[0] + if x2_2_0.Op != OpARM64MOVDreg || w != x2_2_0.Args[0] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0) && clobber(x1) && clobber(x2)) { + break + } + v.reset(OpARM64MOVWstoreidx) + v.AddArg(ptr0) + v.AddArg(idx0) + v0 := b.NewValue0(x1.Pos, OpARM64REVW, w.Type) + v0.AddArg(w) + v.AddArg(v0) + v.AddArg(mem) + return true + } return false } -func rewriteValueARM64_OpARM64MOVBstore_30(v *Value) bool { +func rewriteValueARM64_OpARM64MOVBstore_40(v *Value) bool { b := v.Block // match: (MOVBstore [i] {s} ptr w x0:(MOVBstore [i-1] {s} ptr (SRLconst [8] w) x1:(MOVBstore [i-2] {s} ptr (SRLconst [16] w) x2:(MOVBstore [i-3] {s} ptr (SRLconst [24] w) mem)))) // cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && clobber(x0) && clobber(x1) && clobber(x2) @@ -10000,6 +10518,64 @@ func rewriteValueARM64_OpARM64MOVBstore_30(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVBstore [3] {s} p w x0:(MOVBstore [2] {s} p (SRLconst [8] w) x1:(MOVBstore [1] {s} p1:(ADD idx1 ptr1) (SRLconst [16] w) x2:(MOVBstoreidx ptr0 idx0 (SRLconst [24] w) mem)))) + // cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0) && clobber(x1) && clobber(x2) + // result: (MOVWstoreidx ptr0 idx0 (REVW w) mem) + for { + if v.AuxInt != 3 { + break + } + s := v.Aux + _ = v.Args[2] + p := v.Args[0] + w := v.Args[1] + x0 := v.Args[2] + if x0.Op != OpARM64MOVBstore || x0.AuxInt != 2 || x0.Aux != s { + break + } + _ = x0.Args[2] + if p != x0.Args[0] { + break + } + x0_1 := x0.Args[1] + if x0_1.Op != OpARM64SRLconst || x0_1.AuxInt != 8 || w != x0_1.Args[0] { + break + } + x1 := x0.Args[2] + if x1.Op != OpARM64MOVBstore || x1.AuxInt != 1 || x1.Aux != s { + break + } + _ = x1.Args[2] + p1 := x1.Args[0] + if p1.Op != OpARM64ADD { + break + } + ptr1 := p1.Args[1] + idx1 := p1.Args[0] + x1_1 := x1.Args[1] + if x1_1.Op != OpARM64SRLconst || x1_1.AuxInt != 16 || w != x1_1.Args[0] { + break + } + x2 := x1.Args[2] + if x2.Op != OpARM64MOVBstoreidx { + break + } + mem := x2.Args[3] + ptr0 := x2.Args[0] + idx0 := x2.Args[1] + x2_2 := x2.Args[2] + if x2_2.Op != OpARM64SRLconst || x2_2.AuxInt != 24 || w != x2_2.Args[0] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0) && clobber(x1) && clobber(x2)) { + break + } + v.reset(OpARM64MOVWstoreidx) + v.AddArg(ptr0) + v.AddArg(idx0) + v0 := b.NewValue0(x1.Pos, OpARM64REVW, w.Type) + v0.AddArg(w) + v.AddArg(v0) + v.AddArg(mem) + return true + } // match: (MOVBstore [i] {s} ptr w x:(MOVBstore [i-1] {s} ptr (SRLconst [8] w) mem)) // cond: x.Uses == 1 && clobber(x) // result: (MOVHstore [i-1] {s} ptr (REV16W w) mem) @@ -10067,6 +10643,42 @@ func rewriteValueARM64_OpARM64MOVBstore_30(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVBstore [1] {s} (ADD idx1 ptr1) w x:(MOVBstoreidx ptr0 idx0 (SRLconst [8] w) mem)) + // cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x) + // result: (MOVHstoreidx ptr0 idx0 (REV16W w) mem) + for { + if v.AuxInt != 1 { + break + } + s := v.Aux + _ = v.Args[2] + v_0 := v.Args[0] + if v_0.Op != OpARM64ADD { + break + } + ptr1 := v_0.Args[1] + idx1 := v_0.Args[0] + w := v.Args[1] + x := v.Args[2] + if x.Op != OpARM64MOVBstoreidx { + break + } + mem := x.Args[3] + ptr0 := x.Args[0] + idx0 := x.Args[1] + x_2 := x.Args[2] + if x_2.Op != OpARM64SRLconst || x_2.AuxInt != 8 || w != x_2.Args[0] || !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) { + break + } + v.reset(OpARM64MOVHstoreidx) + v.AddArg(ptr0) + v.AddArg(idx0) + v0 := b.NewValue0(v.Pos, OpARM64REV16W, w.Type) + v0.AddArg(w) + v.AddArg(v0) + v.AddArg(mem) + return true + } // match: (MOVBstore [i] {s} ptr w x:(MOVBstore [i-1] {s} ptr (UBFX [armBFAuxInt(8, 8)] w) mem)) // cond: x.Uses == 1 && clobber(x) // result: (MOVHstore [i-1] {s} ptr (REV16W w) mem) @@ -10134,6 +10746,42 @@ func rewriteValueARM64_OpARM64MOVBstore_30(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVBstore [1] {s} (ADD idx1 ptr1) w x:(MOVBstoreidx ptr0 idx0 (UBFX [armBFAuxInt(8, 8)] w) mem)) + // cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x) + // result: (MOVHstoreidx ptr0 idx0 (REV16W w) mem) + for { + if v.AuxInt != 1 { + break + } + s := v.Aux + _ = v.Args[2] + v_0 := v.Args[0] + if v_0.Op != OpARM64ADD { + break + } + ptr1 := v_0.Args[1] + idx1 := v_0.Args[0] + w := v.Args[1] + x := v.Args[2] + if x.Op != OpARM64MOVBstoreidx { + break + } + mem := x.Args[3] + ptr0 := x.Args[0] + idx0 := x.Args[1] + x_2 := x.Args[2] + if x_2.Op != OpARM64UBFX || x_2.AuxInt != armBFAuxInt(8, 8) || w != x_2.Args[0] || !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) { + break + } + v.reset(OpARM64MOVHstoreidx) + v.AddArg(ptr0) + v.AddArg(idx0) + v0 := b.NewValue0(v.Pos, OpARM64REV16W, w.Type) + v0.AddArg(w) + v.AddArg(v0) + v.AddArg(mem) + return true + } // match: (MOVBstore [i] {s} ptr w x:(MOVBstore [i-1] {s} ptr (SRLconst [8] (MOVDreg w)) mem)) // cond: x.Uses == 1 && clobber(x) // result: (MOVHstore [i-1] {s} ptr (REV16W w) mem) @@ -10169,6 +10817,10 @@ func rewriteValueARM64_OpARM64MOVBstore_30(v *Value) bool { v.AddArg(mem) return true } + return false +} +func rewriteValueARM64_OpARM64MOVBstore_50(v *Value) bool { + b := v.Block // match: (MOVBstore [1] {s} (ADD ptr1 idx1) w x:(MOVBstoreidx ptr0 idx0 (SRLconst [8] (MOVDreg w)) mem)) // cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x) // result: (MOVHstoreidx ptr0 idx0 (REV16W w) mem) @@ -10209,6 +10861,46 @@ func rewriteValueARM64_OpARM64MOVBstore_30(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVBstore [1] {s} (ADD idx1 ptr1) w x:(MOVBstoreidx ptr0 idx0 (SRLconst [8] (MOVDreg w)) mem)) + // cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x) + // result: (MOVHstoreidx ptr0 idx0 (REV16W w) mem) + for { + if v.AuxInt != 1 { + break + } + s := v.Aux + _ = v.Args[2] + v_0 := v.Args[0] + if v_0.Op != OpARM64ADD { + break + } + ptr1 := v_0.Args[1] + idx1 := v_0.Args[0] + w := v.Args[1] + x := v.Args[2] + if x.Op != OpARM64MOVBstoreidx { + break + } + mem := x.Args[3] + ptr0 := x.Args[0] + idx0 := x.Args[1] + x_2 := x.Args[2] + if x_2.Op != OpARM64SRLconst || x_2.AuxInt != 8 { + break + } + x_2_0 := x_2.Args[0] + if x_2_0.Op != OpARM64MOVDreg || w != x_2_0.Args[0] || !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) { + break + } + v.reset(OpARM64MOVHstoreidx) + v.AddArg(ptr0) + v.AddArg(idx0) + v0 := b.NewValue0(v.Pos, OpARM64REV16W, w.Type) + v0.AddArg(w) + v.AddArg(v0) + v.AddArg(mem) + return true + } // match: (MOVBstore [i] {s} ptr w x:(MOVBstore [i-1] {s} ptr (UBFX [armBFAuxInt(8, 24)] w) mem)) // cond: x.Uses == 1 && clobber(x) // result: (MOVHstore [i-1] {s} ptr (REV16W w) mem) @@ -10276,6 +10968,42 @@ func rewriteValueARM64_OpARM64MOVBstore_30(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVBstore [1] {s} (ADD idx1 ptr1) w x:(MOVBstoreidx ptr0 idx0 (UBFX [armBFAuxInt(8, 24)] w) mem)) + // cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x) + // result: (MOVHstoreidx ptr0 idx0 (REV16W w) mem) + for { + if v.AuxInt != 1 { + break + } + s := v.Aux + _ = v.Args[2] + v_0 := v.Args[0] + if v_0.Op != OpARM64ADD { + break + } + ptr1 := v_0.Args[1] + idx1 := v_0.Args[0] + w := v.Args[1] + x := v.Args[2] + if x.Op != OpARM64MOVBstoreidx { + break + } + mem := x.Args[3] + ptr0 := x.Args[0] + idx0 := x.Args[1] + x_2 := x.Args[2] + if x_2.Op != OpARM64UBFX || x_2.AuxInt != armBFAuxInt(8, 24) || w != x_2.Args[0] || !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) { + break + } + v.reset(OpARM64MOVHstoreidx) + v.AddArg(ptr0) + v.AddArg(idx0) + v0 := b.NewValue0(v.Pos, OpARM64REV16W, w.Type) + v0.AddArg(w) + v.AddArg(v0) + v.AddArg(mem) + return true + } return false } func rewriteValueARM64_OpARM64MOVBstoreidx_0(v *Value) bool { @@ -10799,6 +11527,37 @@ func rewriteValueARM64_OpARM64MOVBstorezero_0(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVBstorezero [1] {s} (ADD idx0 ptr0) x:(MOVBstorezeroidx ptr1 idx1 mem)) + // cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x) + // result: (MOVHstorezeroidx ptr1 idx1 mem) + for { + if v.AuxInt != 1 { + break + } + s := v.Aux + _ = v.Args[1] + v_0 := v.Args[0] + if v_0.Op != OpARM64ADD { + break + } + ptr0 := v_0.Args[1] + idx0 := v_0.Args[0] + x := v.Args[1] + if x.Op != OpARM64MOVBstorezeroidx { + break + } + mem := x.Args[2] + ptr1 := x.Args[0] + idx1 := x.Args[1] + if !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) { + break + } + v.reset(OpARM64MOVHstorezeroidx) + v.AddArg(ptr1) + v.AddArg(idx1) + v.AddArg(mem) + return true + } return false } func rewriteValueARM64_OpARM64MOVBstorezeroidx_0(v *Value) bool { @@ -11594,6 +12353,38 @@ func rewriteValueARM64_OpARM64MOVDstorezero_0(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVDstorezero [8] {s} p0:(ADD idx0 ptr0) x:(MOVDstorezeroidx ptr1 idx1 mem)) + // cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x) + // result: (MOVQstorezero [0] {s} p0 mem) + for { + if v.AuxInt != 8 { + break + } + s := v.Aux + _ = v.Args[1] + p0 := v.Args[0] + if p0.Op != OpARM64ADD { + break + } + ptr0 := p0.Args[1] + idx0 := p0.Args[0] + x := v.Args[1] + if x.Op != OpARM64MOVDstorezeroidx { + break + } + mem := x.Args[2] + ptr1 := x.Args[0] + idx1 := x.Args[1] + if !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) { + break + } + v.reset(OpARM64MOVQstorezero) + v.AuxInt = 0 + v.Aux = s + v.AddArg(p0) + v.AddArg(mem) + return true + } // match: (MOVDstorezero [8] {s} p0:(ADDshiftLL [3] ptr0 idx0) x:(MOVDstorezeroidx8 ptr1 idx1 mem)) // cond: x.Uses == 1 && s == nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && clobber(x) // result: (MOVQstorezero [0] {s} p0 mem) @@ -12841,6 +13632,43 @@ func rewriteValueARM64_OpARM64MOVHstore_10(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVHstore [2] {s} (ADD idx0 ptr0) (SRLconst [16] w) x:(MOVHstoreidx ptr1 idx1 w mem)) + // cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x) + // result: (MOVWstoreidx ptr1 idx1 w mem) + for { + if v.AuxInt != 2 { + break + } + s := v.Aux + _ = v.Args[2] + v_0 := v.Args[0] + if v_0.Op != OpARM64ADD { + break + } + ptr0 := v_0.Args[1] + idx0 := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARM64SRLconst || v_1.AuxInt != 16 { + break + } + w := v_1.Args[0] + x := v.Args[2] + if x.Op != OpARM64MOVHstoreidx { + break + } + mem := x.Args[3] + ptr1 := x.Args[0] + idx1 := x.Args[1] + if w != x.Args[2] || !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) { + break + } + v.reset(OpARM64MOVWstoreidx) + v.AddArg(ptr1) + v.AddArg(idx1) + v.AddArg(w) + v.AddArg(mem) + return true + } // match: (MOVHstore [2] {s} (ADDshiftLL [1] ptr0 idx0) (SRLconst [16] w) x:(MOVHstoreidx2 ptr1 idx1 w mem)) // cond: x.Uses == 1 && s == nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && clobber(x) // result: (MOVWstoreidx ptr1 (SLLconst [1] idx1) w mem) @@ -12948,6 +13776,43 @@ func rewriteValueARM64_OpARM64MOVHstore_10(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVHstore [2] {s} (ADD idx0 ptr0) (UBFX [armBFAuxInt(16, 16)] w) x:(MOVHstoreidx ptr1 idx1 w mem)) + // cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x) + // result: (MOVWstoreidx ptr1 idx1 w mem) + for { + if v.AuxInt != 2 { + break + } + s := v.Aux + _ = v.Args[2] + v_0 := v.Args[0] + if v_0.Op != OpARM64ADD { + break + } + ptr0 := v_0.Args[1] + idx0 := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARM64UBFX || v_1.AuxInt != armBFAuxInt(16, 16) { + break + } + w := v_1.Args[0] + x := v.Args[2] + if x.Op != OpARM64MOVHstoreidx { + break + } + mem := x.Args[3] + ptr1 := x.Args[0] + idx1 := x.Args[1] + if w != x.Args[2] || !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) { + break + } + v.reset(OpARM64MOVWstoreidx) + v.AddArg(ptr1) + v.AddArg(idx1) + v.AddArg(w) + v.AddArg(mem) + return true + } // match: (MOVHstore [2] {s} (ADDshiftLL [1] ptr0 idx0) (UBFX [armBFAuxInt(16, 16)] w) x:(MOVHstoreidx2 ptr1 idx1 w mem)) // cond: x.Uses == 1 && s == nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && clobber(x) // result: (MOVWstoreidx ptr1 (SLLconst [1] idx1) w mem) @@ -13063,6 +13928,51 @@ func rewriteValueARM64_OpARM64MOVHstore_10(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVHstore [2] {s} (ADD idx0 ptr0) (SRLconst [16] (MOVDreg w)) x:(MOVHstoreidx ptr1 idx1 w mem)) + // cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x) + // result: (MOVWstoreidx ptr1 idx1 w mem) + for { + if v.AuxInt != 2 { + break + } + s := v.Aux + _ = v.Args[2] + v_0 := v.Args[0] + if v_0.Op != OpARM64ADD { + break + } + ptr0 := v_0.Args[1] + idx0 := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARM64SRLconst || v_1.AuxInt != 16 { + break + } + v_1_0 := v_1.Args[0] + if v_1_0.Op != OpARM64MOVDreg { + break + } + w := v_1_0.Args[0] + x := v.Args[2] + if x.Op != OpARM64MOVHstoreidx { + break + } + mem := x.Args[3] + ptr1 := x.Args[0] + idx1 := x.Args[1] + if w != x.Args[2] || !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) { + break + } + v.reset(OpARM64MOVWstoreidx) + v.AddArg(ptr1) + v.AddArg(idx1) + v.AddArg(w) + v.AddArg(mem) + return true + } + return false +} +func rewriteValueARM64_OpARM64MOVHstore_20(v *Value) bool { + b := v.Block // match: (MOVHstore [2] {s} (ADDshiftLL [1] ptr0 idx0) (SRLconst [16] (MOVDreg w)) x:(MOVHstoreidx2 ptr1 idx1 w mem)) // cond: x.Uses == 1 && s == nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && clobber(x) // result: (MOVWstoreidx ptr1 (SLLconst [1] idx1) w mem) @@ -13178,10 +14088,45 @@ func rewriteValueARM64_OpARM64MOVHstore_10(v *Value) bool { v.AddArg(mem) return true } - return false -} -func rewriteValueARM64_OpARM64MOVHstore_20(v *Value) bool { - b := v.Block + // match: (MOVHstore [2] {s} (ADD idx0 ptr0) (SRLconst [j] w) x:(MOVHstoreidx ptr1 idx1 w0:(SRLconst [j-16] w) mem)) + // cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x) + // result: (MOVWstoreidx ptr1 idx1 w0 mem) + for { + if v.AuxInt != 2 { + break + } + s := v.Aux + _ = v.Args[2] + v_0 := v.Args[0] + if v_0.Op != OpARM64ADD { + break + } + ptr0 := v_0.Args[1] + idx0 := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARM64SRLconst { + break + } + j := v_1.AuxInt + w := v_1.Args[0] + x := v.Args[2] + if x.Op != OpARM64MOVHstoreidx { + break + } + mem := x.Args[3] + ptr1 := x.Args[0] + idx1 := x.Args[1] + w0 := x.Args[2] + if w0.Op != OpARM64SRLconst || w0.AuxInt != j-16 || w != w0.Args[0] || !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) { + break + } + v.reset(OpARM64MOVWstoreidx) + v.AddArg(ptr1) + v.AddArg(idx1) + v.AddArg(w0) + v.AddArg(mem) + return true + } // match: (MOVHstore [2] {s} (ADDshiftLL [1] ptr0 idx0) (SRLconst [j] w) x:(MOVHstoreidx2 ptr1 idx1 w0:(SRLconst [j-16] w) mem)) // cond: x.Uses == 1 && s == nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && clobber(x) // result: (MOVWstoreidx ptr1 (SLLconst [1] idx1) w0 mem) @@ -13727,6 +14672,37 @@ func rewriteValueARM64_OpARM64MOVHstorezero_0(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVHstorezero [2] {s} (ADD idx0 ptr0) x:(MOVHstorezeroidx ptr1 idx1 mem)) + // cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x) + // result: (MOVWstorezeroidx ptr1 idx1 mem) + for { + if v.AuxInt != 2 { + break + } + s := v.Aux + _ = v.Args[1] + v_0 := v.Args[0] + if v_0.Op != OpARM64ADD { + break + } + ptr0 := v_0.Args[1] + idx0 := v_0.Args[0] + x := v.Args[1] + if x.Op != OpARM64MOVHstorezeroidx { + break + } + mem := x.Args[2] + ptr1 := x.Args[0] + idx1 := x.Args[1] + if !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) { + break + } + v.reset(OpARM64MOVWstorezeroidx) + v.AddArg(ptr1) + v.AddArg(idx1) + v.AddArg(mem) + return true + } // match: (MOVHstorezero [2] {s} (ADDshiftLL [1] ptr0 idx0) x:(MOVHstorezeroidx2 ptr1 idx1 mem)) // cond: x.Uses == 1 && s == nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && clobber(x) // result: (MOVWstorezeroidx ptr1 (SLLconst [1] idx1) mem) @@ -15177,6 +16153,43 @@ func rewriteValueARM64_OpARM64MOVWstore_0(v *Value) bool { } func rewriteValueARM64_OpARM64MOVWstore_10(v *Value) bool { b := v.Block + // match: (MOVWstore [4] {s} (ADD idx0 ptr0) (SRLconst [32] w) x:(MOVWstoreidx ptr1 idx1 w mem)) + // cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x) + // result: (MOVDstoreidx ptr1 idx1 w mem) + for { + if v.AuxInt != 4 { + break + } + s := v.Aux + _ = v.Args[2] + v_0 := v.Args[0] + if v_0.Op != OpARM64ADD { + break + } + ptr0 := v_0.Args[1] + idx0 := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARM64SRLconst || v_1.AuxInt != 32 { + break + } + w := v_1.Args[0] + x := v.Args[2] + if x.Op != OpARM64MOVWstoreidx { + break + } + mem := x.Args[3] + ptr1 := x.Args[0] + idx1 := x.Args[1] + if w != x.Args[2] || !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) { + break + } + v.reset(OpARM64MOVDstoreidx) + v.AddArg(ptr1) + v.AddArg(idx1) + v.AddArg(w) + v.AddArg(mem) + return true + } // match: (MOVWstore [4] {s} (ADDshiftLL [2] ptr0 idx0) (SRLconst [32] w) x:(MOVWstoreidx4 ptr1 idx1 w mem)) // cond: x.Uses == 1 && s == nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && clobber(x) // result: (MOVDstoreidx ptr1 (SLLconst [2] idx1) w mem) @@ -15288,6 +16301,45 @@ func rewriteValueARM64_OpARM64MOVWstore_10(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVWstore [4] {s} (ADD idx0 ptr0) (SRLconst [j] w) x:(MOVWstoreidx ptr1 idx1 w0:(SRLconst [j-32] w) mem)) + // cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x) + // result: (MOVDstoreidx ptr1 idx1 w0 mem) + for { + if v.AuxInt != 4 { + break + } + s := v.Aux + _ = v.Args[2] + v_0 := v.Args[0] + if v_0.Op != OpARM64ADD { + break + } + ptr0 := v_0.Args[1] + idx0 := v_0.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpARM64SRLconst { + break + } + j := v_1.AuxInt + w := v_1.Args[0] + x := v.Args[2] + if x.Op != OpARM64MOVWstoreidx { + break + } + mem := x.Args[3] + ptr1 := x.Args[0] + idx1 := x.Args[1] + w0 := x.Args[2] + if w0.Op != OpARM64SRLconst || w0.AuxInt != j-32 || w != w0.Args[0] || !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) { + break + } + v.reset(OpARM64MOVDstoreidx) + v.AddArg(ptr1) + v.AddArg(idx1) + v.AddArg(w0) + v.AddArg(mem) + return true + } // match: (MOVWstore [4] {s} (ADDshiftLL [2] ptr0 idx0) (SRLconst [j] w) x:(MOVWstoreidx4 ptr1 idx1 w0:(SRLconst [j-32] w) mem)) // cond: x.Uses == 1 && s == nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && clobber(x) // result: (MOVDstoreidx ptr1 (SLLconst [2] idx1) w0 mem) @@ -15716,6 +16768,37 @@ func rewriteValueARM64_OpARM64MOVWstorezero_0(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVWstorezero [4] {s} (ADD idx0 ptr0) x:(MOVWstorezeroidx ptr1 idx1 mem)) + // cond: x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x) + // result: (MOVDstorezeroidx ptr1 idx1 mem) + for { + if v.AuxInt != 4 { + break + } + s := v.Aux + _ = v.Args[1] + v_0 := v.Args[0] + if v_0.Op != OpARM64ADD { + break + } + ptr0 := v_0.Args[1] + idx0 := v_0.Args[0] + x := v.Args[1] + if x.Op != OpARM64MOVWstorezeroidx { + break + } + mem := x.Args[2] + ptr1 := x.Args[0] + idx1 := x.Args[1] + if !(x.Uses == 1 && s == nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x)) { + break + } + v.reset(OpARM64MOVDstorezeroidx) + v.AddArg(ptr1) + v.AddArg(idx1) + v.AddArg(mem) + return true + } // match: (MOVWstorezero [4] {s} (ADDshiftLL [2] ptr0 idx0) x:(MOVWstorezeroidx4 ptr1 idx1 mem)) // cond: x.Uses == 1 && s == nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && clobber(x) // result: (MOVDstorezeroidx ptr1 (SLLconst [2] idx1) mem) @@ -19232,6 +20315,90 @@ func rewriteValueARM64_OpARM64OR_20(v *Value) bool { v0.AddArg(mem) return true } + // match: (OR o0:(ORshiftLL [8] o1:(ORshiftLL [16] s0:(SLLconst [24] y0:(MOVDnop x0:(MOVBUload [3] {s} p mem))) y1:(MOVDnop x1:(MOVBUload [2] {s} p mem))) y2:(MOVDnop x2:(MOVBUload [1] {s} p1:(ADD idx1 ptr1) mem))) y3:(MOVDnop x3:(MOVBUloadidx ptr0 idx0 mem))) + // cond: s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1 && mergePoint(b,x0,x1,x2,x3) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(y0) && clobber(y1) && clobber(y2) && clobber(y3) && clobber(o0) && clobber(o1) && clobber(s0) + // result: @mergePoint(b,x0,x1,x2,x3) (MOVWUloadidx ptr0 idx0 mem) + for { + t := v.Type + _ = v.Args[1] + o0 := v.Args[0] + if o0.Op != OpARM64ORshiftLL || o0.AuxInt != 8 { + break + } + _ = o0.Args[1] + o1 := o0.Args[0] + if o1.Op != OpARM64ORshiftLL || o1.AuxInt != 16 { + break + } + _ = o1.Args[1] + s0 := o1.Args[0] + if s0.Op != OpARM64SLLconst || s0.AuxInt != 24 { + break + } + y0 := s0.Args[0] + if y0.Op != OpARM64MOVDnop { + break + } + x0 := y0.Args[0] + if x0.Op != OpARM64MOVBUload || x0.AuxInt != 3 { + break + } + s := x0.Aux + mem := x0.Args[1] + p := x0.Args[0] + y1 := o1.Args[1] + if y1.Op != OpARM64MOVDnop { + break + } + x1 := y1.Args[0] + if x1.Op != OpARM64MOVBUload || x1.AuxInt != 2 || x1.Aux != s { + break + } + _ = x1.Args[1] + if p != x1.Args[0] || mem != x1.Args[1] { + break + } + y2 := o0.Args[1] + if y2.Op != OpARM64MOVDnop { + break + } + x2 := y2.Args[0] + if x2.Op != OpARM64MOVBUload || x2.AuxInt != 1 || x2.Aux != s { + break + } + _ = x2.Args[1] + p1 := x2.Args[0] + if p1.Op != OpARM64ADD { + break + } + ptr1 := p1.Args[1] + idx1 := p1.Args[0] + if mem != x2.Args[1] { + break + } + y3 := v.Args[1] + if y3.Op != OpARM64MOVDnop { + break + } + x3 := y3.Args[0] + if x3.Op != OpARM64MOVBUloadidx { + break + } + _ = x3.Args[2] + ptr0 := x3.Args[0] + idx0 := x3.Args[1] + if mem != x3.Args[2] || !(s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1 && mergePoint(b, x0, x1, x2, x3) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(y0) && clobber(y1) && clobber(y2) && clobber(y3) && clobber(o0) && clobber(o1) && clobber(s0)) { + break + } + b = mergePoint(b, x0, x1, x2, x3) + v0 := b.NewValue0(x2.Pos, OpARM64MOVWUloadidx, t) + v.reset(OpCopy) + v.AddArg(v0) + v0.AddArg(ptr0) + v0.AddArg(idx0) + v0.AddArg(mem) + return true + } // match: (OR y3:(MOVDnop x3:(MOVBUloadidx ptr0 idx0 mem)) o0:(ORshiftLL [8] o1:(ORshiftLL [16] s0:(SLLconst [24] y0:(MOVDnop x0:(MOVBUload [3] {s} p mem))) y1:(MOVDnop x1:(MOVBUload [2] {s} p mem))) y2:(MOVDnop x2:(MOVBUload [1] {s} p1:(ADD ptr1 idx1) mem)))) // cond: s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1 && mergePoint(b,x0,x1,x2,x3) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(y0) && clobber(y1) && clobber(y2) && clobber(y3) && clobber(o0) && clobber(o1) && clobber(s0) // result: @mergePoint(b,x0,x1,x2,x3) (MOVWUloadidx ptr0 idx0 mem) @@ -19316,6 +20483,90 @@ func rewriteValueARM64_OpARM64OR_20(v *Value) bool { v0.AddArg(mem) return true } + // match: (OR y3:(MOVDnop x3:(MOVBUloadidx ptr0 idx0 mem)) o0:(ORshiftLL [8] o1:(ORshiftLL [16] s0:(SLLconst [24] y0:(MOVDnop x0:(MOVBUload [3] {s} p mem))) y1:(MOVDnop x1:(MOVBUload [2] {s} p mem))) y2:(MOVDnop x2:(MOVBUload [1] {s} p1:(ADD idx1 ptr1) mem)))) + // cond: s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1 && mergePoint(b,x0,x1,x2,x3) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(y0) && clobber(y1) && clobber(y2) && clobber(y3) && clobber(o0) && clobber(o1) && clobber(s0) + // result: @mergePoint(b,x0,x1,x2,x3) (MOVWUloadidx ptr0 idx0 mem) + for { + t := v.Type + _ = v.Args[1] + y3 := v.Args[0] + if y3.Op != OpARM64MOVDnop { + break + } + x3 := y3.Args[0] + if x3.Op != OpARM64MOVBUloadidx { + break + } + mem := x3.Args[2] + ptr0 := x3.Args[0] + idx0 := x3.Args[1] + o0 := v.Args[1] + if o0.Op != OpARM64ORshiftLL || o0.AuxInt != 8 { + break + } + _ = o0.Args[1] + o1 := o0.Args[0] + if o1.Op != OpARM64ORshiftLL || o1.AuxInt != 16 { + break + } + _ = o1.Args[1] + s0 := o1.Args[0] + if s0.Op != OpARM64SLLconst || s0.AuxInt != 24 { + break + } + y0 := s0.Args[0] + if y0.Op != OpARM64MOVDnop { + break + } + x0 := y0.Args[0] + if x0.Op != OpARM64MOVBUload || x0.AuxInt != 3 { + break + } + s := x0.Aux + _ = x0.Args[1] + p := x0.Args[0] + if mem != x0.Args[1] { + break + } + y1 := o1.Args[1] + if y1.Op != OpARM64MOVDnop { + break + } + x1 := y1.Args[0] + if x1.Op != OpARM64MOVBUload || x1.AuxInt != 2 || x1.Aux != s { + break + } + _ = x1.Args[1] + if p != x1.Args[0] || mem != x1.Args[1] { + break + } + y2 := o0.Args[1] + if y2.Op != OpARM64MOVDnop { + break + } + x2 := y2.Args[0] + if x2.Op != OpARM64MOVBUload || x2.AuxInt != 1 || x2.Aux != s { + break + } + _ = x2.Args[1] + p1 := x2.Args[0] + if p1.Op != OpARM64ADD { + break + } + ptr1 := p1.Args[1] + idx1 := p1.Args[0] + if mem != x2.Args[1] || !(s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1 && mergePoint(b, x0, x1, x2, x3) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(y0) && clobber(y1) && clobber(y2) && clobber(y3) && clobber(o0) && clobber(o1) && clobber(s0)) { + break + } + b = mergePoint(b, x0, x1, x2, x3) + v0 := b.NewValue0(x2.Pos, OpARM64MOVWUloadidx, t) + v.reset(OpCopy) + v.AddArg(v0) + v0.AddArg(ptr0) + v0.AddArg(idx0) + v0.AddArg(mem) + return true + } // match: (OR o0:(ORshiftLL [8] o1:(ORshiftLL [16] s0:(SLLconst [24] y0:(MOVDnop x0:(MOVBUloadidx ptr (ADDconst [3] idx) mem))) y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [2] idx) mem))) y2:(MOVDnop x2:(MOVBUloadidx ptr (ADDconst [1] idx) mem))) y3:(MOVDnop x3:(MOVBUloadidx ptr idx mem))) // cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1 && mergePoint(b,x0,x1,x2,x3) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(y0) && clobber(y1) && clobber(y2) && clobber(y3) && clobber(o0) && clobber(o1) && clobber(s0) // result: @mergePoint(b,x0,x1,x2,x3) (MOVWUloadidx ptr idx mem) @@ -19404,6 +20655,10 @@ func rewriteValueARM64_OpARM64OR_20(v *Value) bool { v0.AddArg(mem) return true } + return false +} +func rewriteValueARM64_OpARM64OR_30(v *Value) bool { + b := v.Block // match: (OR y3:(MOVDnop x3:(MOVBUloadidx ptr idx mem)) o0:(ORshiftLL [8] o1:(ORshiftLL [16] s0:(SLLconst [24] y0:(MOVDnop x0:(MOVBUloadidx ptr (ADDconst [3] idx) mem))) y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [2] idx) mem))) y2:(MOVDnop x2:(MOVBUloadidx ptr (ADDconst [1] idx) mem)))) // cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1 && mergePoint(b,x0,x1,x2,x3) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(y0) && clobber(y1) && clobber(y2) && clobber(y3) && clobber(o0) && clobber(o1) && clobber(s0) // result: @mergePoint(b,x0,x1,x2,x3) (MOVWUloadidx ptr idx mem) @@ -19668,10 +20923,6 @@ func rewriteValueARM64_OpARM64OR_20(v *Value) bool { v0.AddArg(mem) return true } - return false -} -func rewriteValueARM64_OpARM64OR_30(v *Value) bool { - b := v.Block // match: (OR y7:(MOVDnop x7:(MOVBUload [i0] {s} p mem)) o0:(ORshiftLL [8] o1:(ORshiftLL [16] o2:(ORshiftLL [24] o3:(ORshiftLL [32] o4:(ORshiftLL [40] o5:(ORshiftLL [48] s0:(SLLconst [56] y0:(MOVDnop x0:(MOVBUload [i7] {s} p mem))) y1:(MOVDnop x1:(MOVBUload [i6] {s} p mem))) y2:(MOVDnop x2:(MOVBUload [i5] {s} p mem))) y3:(MOVDnop x3:(MOVBUload [i4] {s} p mem))) y4:(MOVDnop x4:(MOVBUload [i3] {s} p mem))) y5:(MOVDnop x5:(MOVBUload [i2] {s} p mem))) y6:(MOVDnop x6:(MOVBUload [i1] {s} p mem)))) // cond: i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(y0) && clobber(y1) && clobber(y2) && clobber(y3) && clobber(y4) && clobber(y5) && clobber(y6) && clobber(y7) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5) && clobber(s0) // result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload {s} (OffPtr [i0] p) mem) @@ -20000,6 +21251,158 @@ func rewriteValueARM64_OpARM64OR_30(v *Value) bool { v0.AddArg(mem) return true } + // match: (OR o0:(ORshiftLL [8] o1:(ORshiftLL [16] o2:(ORshiftLL [24] o3:(ORshiftLL [32] o4:(ORshiftLL [40] o5:(ORshiftLL [48] s0:(SLLconst [56] y0:(MOVDnop x0:(MOVBUload [7] {s} p mem))) y1:(MOVDnop x1:(MOVBUload [6] {s} p mem))) y2:(MOVDnop x2:(MOVBUload [5] {s} p mem))) y3:(MOVDnop x3:(MOVBUload [4] {s} p mem))) y4:(MOVDnop x4:(MOVBUload [3] {s} p mem))) y5:(MOVDnop x5:(MOVBUload [2] {s} p mem))) y6:(MOVDnop x6:(MOVBUload [1] {s} p1:(ADD idx1 ptr1) mem))) y7:(MOVDnop x7:(MOVBUloadidx ptr0 idx0 mem))) + // cond: s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(y0) && clobber(y1) && clobber(y2) && clobber(y3) && clobber(y4) && clobber(y5) && clobber(y6) && clobber(y7) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5) && clobber(s0) + // result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDloadidx ptr0 idx0 mem) + for { + t := v.Type + _ = v.Args[1] + o0 := v.Args[0] + if o0.Op != OpARM64ORshiftLL || o0.AuxInt != 8 { + break + } + _ = o0.Args[1] + o1 := o0.Args[0] + if o1.Op != OpARM64ORshiftLL || o1.AuxInt != 16 { + break + } + _ = o1.Args[1] + o2 := o1.Args[0] + if o2.Op != OpARM64ORshiftLL || o2.AuxInt != 24 { + break + } + _ = o2.Args[1] + o3 := o2.Args[0] + if o3.Op != OpARM64ORshiftLL || o3.AuxInt != 32 { + break + } + _ = o3.Args[1] + o4 := o3.Args[0] + if o4.Op != OpARM64ORshiftLL || o4.AuxInt != 40 { + break + } + _ = o4.Args[1] + o5 := o4.Args[0] + if o5.Op != OpARM64ORshiftLL || o5.AuxInt != 48 { + break + } + _ = o5.Args[1] + s0 := o5.Args[0] + if s0.Op != OpARM64SLLconst || s0.AuxInt != 56 { + break + } + y0 := s0.Args[0] + if y0.Op != OpARM64MOVDnop { + break + } + x0 := y0.Args[0] + if x0.Op != OpARM64MOVBUload || x0.AuxInt != 7 { + break + } + s := x0.Aux + mem := x0.Args[1] + p := x0.Args[0] + y1 := o5.Args[1] + if y1.Op != OpARM64MOVDnop { + break + } + x1 := y1.Args[0] + if x1.Op != OpARM64MOVBUload || x1.AuxInt != 6 || x1.Aux != s { + break + } + _ = x1.Args[1] + if p != x1.Args[0] || mem != x1.Args[1] { + break + } + y2 := o4.Args[1] + if y2.Op != OpARM64MOVDnop { + break + } + x2 := y2.Args[0] + if x2.Op != OpARM64MOVBUload || x2.AuxInt != 5 || x2.Aux != s { + break + } + _ = x2.Args[1] + if p != x2.Args[0] || mem != x2.Args[1] { + break + } + y3 := o3.Args[1] + if y3.Op != OpARM64MOVDnop { + break + } + x3 := y3.Args[0] + if x3.Op != OpARM64MOVBUload || x3.AuxInt != 4 || x3.Aux != s { + break + } + _ = x3.Args[1] + if p != x3.Args[0] || mem != x3.Args[1] { + break + } + y4 := o2.Args[1] + if y4.Op != OpARM64MOVDnop { + break + } + x4 := y4.Args[0] + if x4.Op != OpARM64MOVBUload || x4.AuxInt != 3 || x4.Aux != s { + break + } + _ = x4.Args[1] + if p != x4.Args[0] || mem != x4.Args[1] { + break + } + y5 := o1.Args[1] + if y5.Op != OpARM64MOVDnop { + break + } + x5 := y5.Args[0] + if x5.Op != OpARM64MOVBUload || x5.AuxInt != 2 || x5.Aux != s { + break + } + _ = x5.Args[1] + if p != x5.Args[0] || mem != x5.Args[1] { + break + } + y6 := o0.Args[1] + if y6.Op != OpARM64MOVDnop { + break + } + x6 := y6.Args[0] + if x6.Op != OpARM64MOVBUload || x6.AuxInt != 1 || x6.Aux != s { + break + } + _ = x6.Args[1] + p1 := x6.Args[0] + if p1.Op != OpARM64ADD { + break + } + ptr1 := p1.Args[1] + idx1 := p1.Args[0] + if mem != x6.Args[1] { + break + } + y7 := v.Args[1] + if y7.Op != OpARM64MOVDnop { + break + } + x7 := y7.Args[0] + if x7.Op != OpARM64MOVBUloadidx { + break + } + _ = x7.Args[2] + ptr0 := x7.Args[0] + idx0 := x7.Args[1] + if mem != x7.Args[2] || !(s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(y0) && clobber(y1) && clobber(y2) && clobber(y3) && clobber(y4) && clobber(y5) && clobber(y6) && clobber(y7) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5) && clobber(s0)) { + break + } + b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) + v0 := b.NewValue0(x6.Pos, OpARM64MOVDloadidx, t) + v.reset(OpCopy) + v.AddArg(v0) + v0.AddArg(ptr0) + v0.AddArg(idx0) + v0.AddArg(mem) + return true + } // match: (OR y7:(MOVDnop x7:(MOVBUloadidx ptr0 idx0 mem)) o0:(ORshiftLL [8] o1:(ORshiftLL [16] o2:(ORshiftLL [24] o3:(ORshiftLL [32] o4:(ORshiftLL [40] o5:(ORshiftLL [48] s0:(SLLconst [56] y0:(MOVDnop x0:(MOVBUload [7] {s} p mem))) y1:(MOVDnop x1:(MOVBUload [6] {s} p mem))) y2:(MOVDnop x2:(MOVBUload [5] {s} p mem))) y3:(MOVDnop x3:(MOVBUload [4] {s} p mem))) y4:(MOVDnop x4:(MOVBUload [3] {s} p mem))) y5:(MOVDnop x5:(MOVBUload [2] {s} p mem))) y6:(MOVDnop x6:(MOVBUload [1] {s} p1:(ADD ptr1 idx1) mem)))) // cond: s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(y0) && clobber(y1) && clobber(y2) && clobber(y3) && clobber(y4) && clobber(y5) && clobber(y6) && clobber(y7) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5) && clobber(s0) // result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDloadidx ptr0 idx0 mem) @@ -20152,6 +21555,158 @@ func rewriteValueARM64_OpARM64OR_30(v *Value) bool { v0.AddArg(mem) return true } + // match: (OR y7:(MOVDnop x7:(MOVBUloadidx ptr0 idx0 mem)) o0:(ORshiftLL [8] o1:(ORshiftLL [16] o2:(ORshiftLL [24] o3:(ORshiftLL [32] o4:(ORshiftLL [40] o5:(ORshiftLL [48] s0:(SLLconst [56] y0:(MOVDnop x0:(MOVBUload [7] {s} p mem))) y1:(MOVDnop x1:(MOVBUload [6] {s} p mem))) y2:(MOVDnop x2:(MOVBUload [5] {s} p mem))) y3:(MOVDnop x3:(MOVBUload [4] {s} p mem))) y4:(MOVDnop x4:(MOVBUload [3] {s} p mem))) y5:(MOVDnop x5:(MOVBUload [2] {s} p mem))) y6:(MOVDnop x6:(MOVBUload [1] {s} p1:(ADD idx1 ptr1) mem)))) + // cond: s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(y0) && clobber(y1) && clobber(y2) && clobber(y3) && clobber(y4) && clobber(y5) && clobber(y6) && clobber(y7) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5) && clobber(s0) + // result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDloadidx ptr0 idx0 mem) + for { + t := v.Type + _ = v.Args[1] + y7 := v.Args[0] + if y7.Op != OpARM64MOVDnop { + break + } + x7 := y7.Args[0] + if x7.Op != OpARM64MOVBUloadidx { + break + } + mem := x7.Args[2] + ptr0 := x7.Args[0] + idx0 := x7.Args[1] + o0 := v.Args[1] + if o0.Op != OpARM64ORshiftLL || o0.AuxInt != 8 { + break + } + _ = o0.Args[1] + o1 := o0.Args[0] + if o1.Op != OpARM64ORshiftLL || o1.AuxInt != 16 { + break + } + _ = o1.Args[1] + o2 := o1.Args[0] + if o2.Op != OpARM64ORshiftLL || o2.AuxInt != 24 { + break + } + _ = o2.Args[1] + o3 := o2.Args[0] + if o3.Op != OpARM64ORshiftLL || o3.AuxInt != 32 { + break + } + _ = o3.Args[1] + o4 := o3.Args[0] + if o4.Op != OpARM64ORshiftLL || o4.AuxInt != 40 { + break + } + _ = o4.Args[1] + o5 := o4.Args[0] + if o5.Op != OpARM64ORshiftLL || o5.AuxInt != 48 { + break + } + _ = o5.Args[1] + s0 := o5.Args[0] + if s0.Op != OpARM64SLLconst || s0.AuxInt != 56 { + break + } + y0 := s0.Args[0] + if y0.Op != OpARM64MOVDnop { + break + } + x0 := y0.Args[0] + if x0.Op != OpARM64MOVBUload || x0.AuxInt != 7 { + break + } + s := x0.Aux + _ = x0.Args[1] + p := x0.Args[0] + if mem != x0.Args[1] { + break + } + y1 := o5.Args[1] + if y1.Op != OpARM64MOVDnop { + break + } + x1 := y1.Args[0] + if x1.Op != OpARM64MOVBUload || x1.AuxInt != 6 || x1.Aux != s { + break + } + _ = x1.Args[1] + if p != x1.Args[0] || mem != x1.Args[1] { + break + } + y2 := o4.Args[1] + if y2.Op != OpARM64MOVDnop { + break + } + x2 := y2.Args[0] + if x2.Op != OpARM64MOVBUload || x2.AuxInt != 5 || x2.Aux != s { + break + } + _ = x2.Args[1] + if p != x2.Args[0] || mem != x2.Args[1] { + break + } + y3 := o3.Args[1] + if y3.Op != OpARM64MOVDnop { + break + } + x3 := y3.Args[0] + if x3.Op != OpARM64MOVBUload || x3.AuxInt != 4 || x3.Aux != s { + break + } + _ = x3.Args[1] + if p != x3.Args[0] || mem != x3.Args[1] { + break + } + y4 := o2.Args[1] + if y4.Op != OpARM64MOVDnop { + break + } + x4 := y4.Args[0] + if x4.Op != OpARM64MOVBUload || x4.AuxInt != 3 || x4.Aux != s { + break + } + _ = x4.Args[1] + if p != x4.Args[0] || mem != x4.Args[1] { + break + } + y5 := o1.Args[1] + if y5.Op != OpARM64MOVDnop { + break + } + x5 := y5.Args[0] + if x5.Op != OpARM64MOVBUload || x5.AuxInt != 2 || x5.Aux != s { + break + } + _ = x5.Args[1] + if p != x5.Args[0] || mem != x5.Args[1] { + break + } + y6 := o0.Args[1] + if y6.Op != OpARM64MOVDnop { + break + } + x6 := y6.Args[0] + if x6.Op != OpARM64MOVBUload || x6.AuxInt != 1 || x6.Aux != s { + break + } + _ = x6.Args[1] + p1 := x6.Args[0] + if p1.Op != OpARM64ADD { + break + } + ptr1 := p1.Args[1] + idx1 := p1.Args[0] + if mem != x6.Args[1] || !(s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(y0) && clobber(y1) && clobber(y2) && clobber(y3) && clobber(y4) && clobber(y5) && clobber(y6) && clobber(y7) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5) && clobber(s0)) { + break + } + b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) + v0 := b.NewValue0(x6.Pos, OpARM64MOVDloadidx, t) + v.reset(OpCopy) + v.AddArg(v0) + v0.AddArg(ptr0) + v0.AddArg(idx0) + v0.AddArg(mem) + return true + } // match: (OR o0:(ORshiftLL [8] o1:(ORshiftLL [16] o2:(ORshiftLL [24] o3:(ORshiftLL [32] o4:(ORshiftLL [40] o5:(ORshiftLL [48] s0:(SLLconst [56] y0:(MOVDnop x0:(MOVBUloadidx ptr (ADDconst [7] idx) mem))) y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [6] idx) mem))) y2:(MOVDnop x2:(MOVBUloadidx ptr (ADDconst [5] idx) mem))) y3:(MOVDnop x3:(MOVBUloadidx ptr (ADDconst [4] idx) mem))) y4:(MOVDnop x4:(MOVBUloadidx ptr (ADDconst [3] idx) mem))) y5:(MOVDnop x5:(MOVBUloadidx ptr (ADDconst [2] idx) mem))) y6:(MOVDnop x6:(MOVBUloadidx ptr (ADDconst [1] idx) mem))) y7:(MOVDnop x7:(MOVBUloadidx ptr idx mem))) // cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(y0) && clobber(y1) && clobber(y2) && clobber(y3) && clobber(y4) && clobber(y5) && clobber(y6) && clobber(y7) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5) && clobber(s0) // result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDloadidx ptr idx mem) @@ -20590,6 +22145,10 @@ func rewriteValueARM64_OpARM64OR_30(v *Value) bool { v0.AddArg(v1) return true } + return false +} +func rewriteValueARM64_OpARM64OR_40(v *Value) bool { + b := v.Block // match: (OR y3:(MOVDnop x3:(MOVBUload [i3] {s} p mem)) o0:(ORshiftLL [8] o1:(ORshiftLL [16] s0:(SLLconst [24] y0:(MOVDnop x0:(MOVBUload [i0] {s} p mem))) y1:(MOVDnop x1:(MOVBUload [i1] {s} p mem))) y2:(MOVDnop x2:(MOVBUload [i2] {s} p mem)))) // cond: i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1 && mergePoint(b,x0,x1,x2,x3) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(y0) && clobber(y1) && clobber(y2) && clobber(y3) && clobber(o0) && clobber(o1) && clobber(s0) // result: @mergePoint(b,x0,x1,x2,x3) (REVW (MOVWUload {s} (OffPtr [i0] p) mem)) @@ -20770,6 +22329,92 @@ func rewriteValueARM64_OpARM64OR_30(v *Value) bool { v0.AddArg(v1) return true } + // match: (OR o0:(ORshiftLL [8] o1:(ORshiftLL [16] s0:(SLLconst [24] y0:(MOVDnop x0:(MOVBUloadidx ptr0 idx0 mem))) y1:(MOVDnop x1:(MOVBUload [1] {s} p1:(ADD idx1 ptr1) mem))) y2:(MOVDnop x2:(MOVBUload [2] {s} p mem))) y3:(MOVDnop x3:(MOVBUload [3] {s} p mem))) + // cond: s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1 && mergePoint(b,x0,x1,x2,x3) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(y0) && clobber(y1) && clobber(y2) && clobber(y3) && clobber(o0) && clobber(o1) && clobber(s0) + // result: @mergePoint(b,x0,x1,x2,x3) (REVW (MOVWUloadidx ptr0 idx0 mem)) + for { + t := v.Type + _ = v.Args[1] + o0 := v.Args[0] + if o0.Op != OpARM64ORshiftLL || o0.AuxInt != 8 { + break + } + _ = o0.Args[1] + o1 := o0.Args[0] + if o1.Op != OpARM64ORshiftLL || o1.AuxInt != 16 { + break + } + _ = o1.Args[1] + s0 := o1.Args[0] + if s0.Op != OpARM64SLLconst || s0.AuxInt != 24 { + break + } + y0 := s0.Args[0] + if y0.Op != OpARM64MOVDnop { + break + } + x0 := y0.Args[0] + if x0.Op != OpARM64MOVBUloadidx { + break + } + mem := x0.Args[2] + ptr0 := x0.Args[0] + idx0 := x0.Args[1] + y1 := o1.Args[1] + if y1.Op != OpARM64MOVDnop { + break + } + x1 := y1.Args[0] + if x1.Op != OpARM64MOVBUload || x1.AuxInt != 1 { + break + } + s := x1.Aux + _ = x1.Args[1] + p1 := x1.Args[0] + if p1.Op != OpARM64ADD { + break + } + ptr1 := p1.Args[1] + idx1 := p1.Args[0] + if mem != x1.Args[1] { + break + } + y2 := o0.Args[1] + if y2.Op != OpARM64MOVDnop { + break + } + x2 := y2.Args[0] + if x2.Op != OpARM64MOVBUload || x2.AuxInt != 2 || x2.Aux != s { + break + } + _ = x2.Args[1] + p := x2.Args[0] + if mem != x2.Args[1] { + break + } + y3 := v.Args[1] + if y3.Op != OpARM64MOVDnop { + break + } + x3 := y3.Args[0] + if x3.Op != OpARM64MOVBUload || x3.AuxInt != 3 || x3.Aux != s { + break + } + _ = x3.Args[1] + if p != x3.Args[0] || mem != x3.Args[1] || !(s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1 && mergePoint(b, x0, x1, x2, x3) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(y0) && clobber(y1) && clobber(y2) && clobber(y3) && clobber(o0) && clobber(o1) && clobber(s0)) { + break + } + b = mergePoint(b, x0, x1, x2, x3) + v0 := b.NewValue0(x3.Pos, OpARM64REVW, t) + v.reset(OpCopy) + v.AddArg(v0) + v1 := b.NewValue0(x3.Pos, OpARM64MOVWUloadidx, t) + v1.AddArg(ptr0) + v1.AddArg(idx0) + v1.AddArg(mem) + v0.AddArg(v1) + return true + } // match: (OR y3:(MOVDnop x3:(MOVBUload [3] {s} p mem)) o0:(ORshiftLL [8] o1:(ORshiftLL [16] s0:(SLLconst [24] y0:(MOVDnop x0:(MOVBUloadidx ptr0 idx0 mem))) y1:(MOVDnop x1:(MOVBUload [1] {s} p1:(ADD ptr1 idx1) mem))) y2:(MOVDnop x2:(MOVBUload [2] {s} p mem)))) // cond: s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1 && mergePoint(b,x0,x1,x2,x3) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(y0) && clobber(y1) && clobber(y2) && clobber(y3) && clobber(o0) && clobber(o1) && clobber(s0) // result: @mergePoint(b,x0,x1,x2,x3) (REVW (MOVWUloadidx ptr0 idx0 mem)) @@ -20856,6 +22501,92 @@ func rewriteValueARM64_OpARM64OR_30(v *Value) bool { v0.AddArg(v1) return true } + // match: (OR y3:(MOVDnop x3:(MOVBUload [3] {s} p mem)) o0:(ORshiftLL [8] o1:(ORshiftLL [16] s0:(SLLconst [24] y0:(MOVDnop x0:(MOVBUloadidx ptr0 idx0 mem))) y1:(MOVDnop x1:(MOVBUload [1] {s} p1:(ADD idx1 ptr1) mem))) y2:(MOVDnop x2:(MOVBUload [2] {s} p mem)))) + // cond: s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1 && mergePoint(b,x0,x1,x2,x3) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(y0) && clobber(y1) && clobber(y2) && clobber(y3) && clobber(o0) && clobber(o1) && clobber(s0) + // result: @mergePoint(b,x0,x1,x2,x3) (REVW (MOVWUloadidx ptr0 idx0 mem)) + for { + t := v.Type + _ = v.Args[1] + y3 := v.Args[0] + if y3.Op != OpARM64MOVDnop { + break + } + x3 := y3.Args[0] + if x3.Op != OpARM64MOVBUload || x3.AuxInt != 3 { + break + } + s := x3.Aux + mem := x3.Args[1] + p := x3.Args[0] + o0 := v.Args[1] + if o0.Op != OpARM64ORshiftLL || o0.AuxInt != 8 { + break + } + _ = o0.Args[1] + o1 := o0.Args[0] + if o1.Op != OpARM64ORshiftLL || o1.AuxInt != 16 { + break + } + _ = o1.Args[1] + s0 := o1.Args[0] + if s0.Op != OpARM64SLLconst || s0.AuxInt != 24 { + break + } + y0 := s0.Args[0] + if y0.Op != OpARM64MOVDnop { + break + } + x0 := y0.Args[0] + if x0.Op != OpARM64MOVBUloadidx { + break + } + _ = x0.Args[2] + ptr0 := x0.Args[0] + idx0 := x0.Args[1] + if mem != x0.Args[2] { + break + } + y1 := o1.Args[1] + if y1.Op != OpARM64MOVDnop { + break + } + x1 := y1.Args[0] + if x1.Op != OpARM64MOVBUload || x1.AuxInt != 1 || x1.Aux != s { + break + } + _ = x1.Args[1] + p1 := x1.Args[0] + if p1.Op != OpARM64ADD { + break + } + ptr1 := p1.Args[1] + idx1 := p1.Args[0] + if mem != x1.Args[1] { + break + } + y2 := o0.Args[1] + if y2.Op != OpARM64MOVDnop { + break + } + x2 := y2.Args[0] + if x2.Op != OpARM64MOVBUload || x2.AuxInt != 2 || x2.Aux != s { + break + } + _ = x2.Args[1] + if p != x2.Args[0] || mem != x2.Args[1] || !(s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1 && mergePoint(b, x0, x1, x2, x3) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(y0) && clobber(y1) && clobber(y2) && clobber(y3) && clobber(o0) && clobber(o1) && clobber(s0)) { + break + } + b = mergePoint(b, x0, x1, x2, x3) + v0 := b.NewValue0(x2.Pos, OpARM64REVW, t) + v.reset(OpCopy) + v.AddArg(v0) + v1 := b.NewValue0(x2.Pos, OpARM64MOVWUloadidx, t) + v1.AddArg(ptr0) + v1.AddArg(idx0) + v1.AddArg(mem) + v0.AddArg(v1) + return true + } // match: (OR o0:(ORshiftLL [8] o1:(ORshiftLL [16] s0:(SLLconst [24] y0:(MOVDnop x0:(MOVBUloadidx ptr idx mem))) y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [1] idx) mem))) y2:(MOVDnop x2:(MOVBUloadidx ptr (ADDconst [2] idx) mem))) y3:(MOVDnop x3:(MOVBUloadidx ptr (ADDconst [3] idx) mem))) // cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1 && mergePoint(b,x0,x1,x2,x3) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(y0) && clobber(y1) && clobber(y2) && clobber(y3) && clobber(o0) && clobber(o1) && clobber(s0) // result: @mergePoint(b,x0,x1,x2,x3) (REVW (MOVWUloadidx ptr idx mem)) @@ -20946,10 +22677,6 @@ func rewriteValueARM64_OpARM64OR_30(v *Value) bool { v0.AddArg(v1) return true } - return false -} -func rewriteValueARM64_OpARM64OR_40(v *Value) bool { - b := v.Block // match: (OR y3:(MOVDnop x3:(MOVBUloadidx ptr (ADDconst [3] idx) mem)) o0:(ORshiftLL [8] o1:(ORshiftLL [16] s0:(SLLconst [24] y0:(MOVDnop x0:(MOVBUloadidx ptr idx mem))) y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [1] idx) mem))) y2:(MOVDnop x2:(MOVBUloadidx ptr (ADDconst [2] idx) mem)))) // cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1 && mergePoint(b,x0,x1,x2,x3) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(y0) && clobber(y1) && clobber(y2) && clobber(y3) && clobber(o0) && clobber(o1) && clobber(s0) // result: @mergePoint(b,x0,x1,x2,x3) (REVW (MOVWUloadidx ptr idx mem)) @@ -21550,6 +23277,164 @@ func rewriteValueARM64_OpARM64OR_40(v *Value) bool { v0.AddArg(v1) return true } + return false +} +func rewriteValueARM64_OpARM64OR_50(v *Value) bool { + b := v.Block + // match: (OR o0:(ORshiftLL [8] o1:(ORshiftLL [16] o2:(ORshiftLL [24] o3:(ORshiftLL [32] o4:(ORshiftLL [40] o5:(ORshiftLL [48] s0:(SLLconst [56] y0:(MOVDnop x0:(MOVBUloadidx ptr0 idx0 mem))) y1:(MOVDnop x1:(MOVBUload [1] {s} p1:(ADD idx1 ptr1) mem))) y2:(MOVDnop x2:(MOVBUload [2] {s} p mem))) y3:(MOVDnop x3:(MOVBUload [3] {s} p mem))) y4:(MOVDnop x4:(MOVBUload [4] {s} p mem))) y5:(MOVDnop x5:(MOVBUload [5] {s} p mem))) y6:(MOVDnop x6:(MOVBUload [6] {s} p mem))) y7:(MOVDnop x7:(MOVBUload [7] {s} p mem))) + // cond: s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(y0) && clobber(y1) && clobber(y2) && clobber(y3) && clobber(y4) && clobber(y5) && clobber(y6) && clobber(y7) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5) && clobber(s0) + // result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (REV (MOVDloadidx ptr0 idx0 mem)) + for { + t := v.Type + _ = v.Args[1] + o0 := v.Args[0] + if o0.Op != OpARM64ORshiftLL || o0.AuxInt != 8 { + break + } + _ = o0.Args[1] + o1 := o0.Args[0] + if o1.Op != OpARM64ORshiftLL || o1.AuxInt != 16 { + break + } + _ = o1.Args[1] + o2 := o1.Args[0] + if o2.Op != OpARM64ORshiftLL || o2.AuxInt != 24 { + break + } + _ = o2.Args[1] + o3 := o2.Args[0] + if o3.Op != OpARM64ORshiftLL || o3.AuxInt != 32 { + break + } + _ = o3.Args[1] + o4 := o3.Args[0] + if o4.Op != OpARM64ORshiftLL || o4.AuxInt != 40 { + break + } + _ = o4.Args[1] + o5 := o4.Args[0] + if o5.Op != OpARM64ORshiftLL || o5.AuxInt != 48 { + break + } + _ = o5.Args[1] + s0 := o5.Args[0] + if s0.Op != OpARM64SLLconst || s0.AuxInt != 56 { + break + } + y0 := s0.Args[0] + if y0.Op != OpARM64MOVDnop { + break + } + x0 := y0.Args[0] + if x0.Op != OpARM64MOVBUloadidx { + break + } + mem := x0.Args[2] + ptr0 := x0.Args[0] + idx0 := x0.Args[1] + y1 := o5.Args[1] + if y1.Op != OpARM64MOVDnop { + break + } + x1 := y1.Args[0] + if x1.Op != OpARM64MOVBUload || x1.AuxInt != 1 { + break + } + s := x1.Aux + _ = x1.Args[1] + p1 := x1.Args[0] + if p1.Op != OpARM64ADD { + break + } + ptr1 := p1.Args[1] + idx1 := p1.Args[0] + if mem != x1.Args[1] { + break + } + y2 := o4.Args[1] + if y2.Op != OpARM64MOVDnop { + break + } + x2 := y2.Args[0] + if x2.Op != OpARM64MOVBUload || x2.AuxInt != 2 || x2.Aux != s { + break + } + _ = x2.Args[1] + p := x2.Args[0] + if mem != x2.Args[1] { + break + } + y3 := o3.Args[1] + if y3.Op != OpARM64MOVDnop { + break + } + x3 := y3.Args[0] + if x3.Op != OpARM64MOVBUload || x3.AuxInt != 3 || x3.Aux != s { + break + } + _ = x3.Args[1] + if p != x3.Args[0] || mem != x3.Args[1] { + break + } + y4 := o2.Args[1] + if y4.Op != OpARM64MOVDnop { + break + } + x4 := y4.Args[0] + if x4.Op != OpARM64MOVBUload || x4.AuxInt != 4 || x4.Aux != s { + break + } + _ = x4.Args[1] + if p != x4.Args[0] || mem != x4.Args[1] { + break + } + y5 := o1.Args[1] + if y5.Op != OpARM64MOVDnop { + break + } + x5 := y5.Args[0] + if x5.Op != OpARM64MOVBUload || x5.AuxInt != 5 || x5.Aux != s { + break + } + _ = x5.Args[1] + if p != x5.Args[0] || mem != x5.Args[1] { + break + } + y6 := o0.Args[1] + if y6.Op != OpARM64MOVDnop { + break + } + x6 := y6.Args[0] + if x6.Op != OpARM64MOVBUload || x6.AuxInt != 6 || x6.Aux != s { + break + } + _ = x6.Args[1] + if p != x6.Args[0] || mem != x6.Args[1] { + break + } + y7 := v.Args[1] + if y7.Op != OpARM64MOVDnop { + break + } + x7 := y7.Args[0] + if x7.Op != OpARM64MOVBUload || x7.AuxInt != 7 || x7.Aux != s { + break + } + _ = x7.Args[1] + if p != x7.Args[0] || mem != x7.Args[1] || !(s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(y0) && clobber(y1) && clobber(y2) && clobber(y3) && clobber(y4) && clobber(y5) && clobber(y6) && clobber(y7) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5) && clobber(s0)) { + break + } + b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) + v0 := b.NewValue0(x7.Pos, OpARM64REV, t) + v.reset(OpCopy) + v.AddArg(v0) + v1 := b.NewValue0(x7.Pos, OpARM64MOVDloadidx, t) + v1.AddArg(ptr0) + v1.AddArg(idx0) + v1.AddArg(mem) + v0.AddArg(v1) + return true + } // match: (OR y7:(MOVDnop x7:(MOVBUload [7] {s} p mem)) o0:(ORshiftLL [8] o1:(ORshiftLL [16] o2:(ORshiftLL [24] o3:(ORshiftLL [32] o4:(ORshiftLL [40] o5:(ORshiftLL [48] s0:(SLLconst [56] y0:(MOVDnop x0:(MOVBUloadidx ptr0 idx0 mem))) y1:(MOVDnop x1:(MOVBUload [1] {s} p1:(ADD ptr1 idx1) mem))) y2:(MOVDnop x2:(MOVBUload [2] {s} p mem))) y3:(MOVDnop x3:(MOVBUload [3] {s} p mem))) y4:(MOVDnop x4:(MOVBUload [4] {s} p mem))) y5:(MOVDnop x5:(MOVBUload [5] {s} p mem))) y6:(MOVDnop x6:(MOVBUload [6] {s} p mem)))) // cond: s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(y0) && clobber(y1) && clobber(y2) && clobber(y3) && clobber(y4) && clobber(y5) && clobber(y6) && clobber(y7) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5) && clobber(s0) // result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (REV (MOVDloadidx ptr0 idx0 mem)) @@ -21704,6 +23589,160 @@ func rewriteValueARM64_OpARM64OR_40(v *Value) bool { v0.AddArg(v1) return true } + // match: (OR y7:(MOVDnop x7:(MOVBUload [7] {s} p mem)) o0:(ORshiftLL [8] o1:(ORshiftLL [16] o2:(ORshiftLL [24] o3:(ORshiftLL [32] o4:(ORshiftLL [40] o5:(ORshiftLL [48] s0:(SLLconst [56] y0:(MOVDnop x0:(MOVBUloadidx ptr0 idx0 mem))) y1:(MOVDnop x1:(MOVBUload [1] {s} p1:(ADD idx1 ptr1) mem))) y2:(MOVDnop x2:(MOVBUload [2] {s} p mem))) y3:(MOVDnop x3:(MOVBUload [3] {s} p mem))) y4:(MOVDnop x4:(MOVBUload [4] {s} p mem))) y5:(MOVDnop x5:(MOVBUload [5] {s} p mem))) y6:(MOVDnop x6:(MOVBUload [6] {s} p mem)))) + // cond: s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(y0) && clobber(y1) && clobber(y2) && clobber(y3) && clobber(y4) && clobber(y5) && clobber(y6) && clobber(y7) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5) && clobber(s0) + // result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (REV (MOVDloadidx ptr0 idx0 mem)) + for { + t := v.Type + _ = v.Args[1] + y7 := v.Args[0] + if y7.Op != OpARM64MOVDnop { + break + } + x7 := y7.Args[0] + if x7.Op != OpARM64MOVBUload || x7.AuxInt != 7 { + break + } + s := x7.Aux + mem := x7.Args[1] + p := x7.Args[0] + o0 := v.Args[1] + if o0.Op != OpARM64ORshiftLL || o0.AuxInt != 8 { + break + } + _ = o0.Args[1] + o1 := o0.Args[0] + if o1.Op != OpARM64ORshiftLL || o1.AuxInt != 16 { + break + } + _ = o1.Args[1] + o2 := o1.Args[0] + if o2.Op != OpARM64ORshiftLL || o2.AuxInt != 24 { + break + } + _ = o2.Args[1] + o3 := o2.Args[0] + if o3.Op != OpARM64ORshiftLL || o3.AuxInt != 32 { + break + } + _ = o3.Args[1] + o4 := o3.Args[0] + if o4.Op != OpARM64ORshiftLL || o4.AuxInt != 40 { + break + } + _ = o4.Args[1] + o5 := o4.Args[0] + if o5.Op != OpARM64ORshiftLL || o5.AuxInt != 48 { + break + } + _ = o5.Args[1] + s0 := o5.Args[0] + if s0.Op != OpARM64SLLconst || s0.AuxInt != 56 { + break + } + y0 := s0.Args[0] + if y0.Op != OpARM64MOVDnop { + break + } + x0 := y0.Args[0] + if x0.Op != OpARM64MOVBUloadidx { + break + } + _ = x0.Args[2] + ptr0 := x0.Args[0] + idx0 := x0.Args[1] + if mem != x0.Args[2] { + break + } + y1 := o5.Args[1] + if y1.Op != OpARM64MOVDnop { + break + } + x1 := y1.Args[0] + if x1.Op != OpARM64MOVBUload || x1.AuxInt != 1 || x1.Aux != s { + break + } + _ = x1.Args[1] + p1 := x1.Args[0] + if p1.Op != OpARM64ADD { + break + } + ptr1 := p1.Args[1] + idx1 := p1.Args[0] + if mem != x1.Args[1] { + break + } + y2 := o4.Args[1] + if y2.Op != OpARM64MOVDnop { + break + } + x2 := y2.Args[0] + if x2.Op != OpARM64MOVBUload || x2.AuxInt != 2 || x2.Aux != s { + break + } + _ = x2.Args[1] + if p != x2.Args[0] || mem != x2.Args[1] { + break + } + y3 := o3.Args[1] + if y3.Op != OpARM64MOVDnop { + break + } + x3 := y3.Args[0] + if x3.Op != OpARM64MOVBUload || x3.AuxInt != 3 || x3.Aux != s { + break + } + _ = x3.Args[1] + if p != x3.Args[0] || mem != x3.Args[1] { + break + } + y4 := o2.Args[1] + if y4.Op != OpARM64MOVDnop { + break + } + x4 := y4.Args[0] + if x4.Op != OpARM64MOVBUload || x4.AuxInt != 4 || x4.Aux != s { + break + } + _ = x4.Args[1] + if p != x4.Args[0] || mem != x4.Args[1] { + break + } + y5 := o1.Args[1] + if y5.Op != OpARM64MOVDnop { + break + } + x5 := y5.Args[0] + if x5.Op != OpARM64MOVBUload || x5.AuxInt != 5 || x5.Aux != s { + break + } + _ = x5.Args[1] + if p != x5.Args[0] || mem != x5.Args[1] { + break + } + y6 := o0.Args[1] + if y6.Op != OpARM64MOVDnop { + break + } + x6 := y6.Args[0] + if x6.Op != OpARM64MOVBUload || x6.AuxInt != 6 || x6.Aux != s { + break + } + _ = x6.Args[1] + if p != x6.Args[0] || mem != x6.Args[1] || !(s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(y0) && clobber(y1) && clobber(y2) && clobber(y3) && clobber(y4) && clobber(y5) && clobber(y6) && clobber(y7) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5) && clobber(s0)) { + break + } + b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7) + v0 := b.NewValue0(x6.Pos, OpARM64REV, t) + v.reset(OpCopy) + v.AddArg(v0) + v1 := b.NewValue0(x6.Pos, OpARM64MOVDloadidx, t) + v1.AddArg(ptr0) + v1.AddArg(idx0) + v1.AddArg(mem) + v0.AddArg(v1) + return true + } // match: (OR o0:(ORshiftLL [8] o1:(ORshiftLL [16] o2:(ORshiftLL [24] o3:(ORshiftLL [32] o4:(ORshiftLL [40] o5:(ORshiftLL [48] s0:(SLLconst [56] y0:(MOVDnop x0:(MOVBUloadidx ptr idx mem))) y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [1] idx) mem))) y2:(MOVDnop x2:(MOVBUloadidx ptr (ADDconst [2] idx) mem))) y3:(MOVDnop x3:(MOVBUloadidx ptr (ADDconst [3] idx) mem))) y4:(MOVDnop x4:(MOVBUloadidx ptr (ADDconst [4] idx) mem))) y5:(MOVDnop x5:(MOVBUloadidx ptr (ADDconst [5] idx) mem))) y6:(MOVDnop x6:(MOVBUloadidx ptr (ADDconst [6] idx) mem))) y7:(MOVDnop x7:(MOVBUloadidx ptr (ADDconst [7] idx) mem))) // cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1 && mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(x5) && clobber(x6) && clobber(x7) && clobber(y0) && clobber(y1) && clobber(y2) && clobber(y3) && clobber(y4) && clobber(y5) && clobber(y6) && clobber(y7) && clobber(o0) && clobber(o1) && clobber(o2) && clobber(o3) && clobber(o4) && clobber(o5) && clobber(s0) // result: @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (REV (MOVDloadidx ptr idx mem)) @@ -22603,6 +24642,54 @@ func rewriteValueARM64_OpARM64ORshiftLL_10(v *Value) bool { v0.AddArg(mem) return true } + // match: (ORshiftLL [8] y0:(MOVDnop x0:(MOVBUloadidx ptr0 idx0 mem)) y1:(MOVDnop x1:(MOVBUload [1] {s} p1:(ADD idx1 ptr1) mem))) + // cond: s == nil && x0.Uses == 1 && x1.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && mergePoint(b,x0,x1) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x0) && clobber(x1) && clobber(y0) && clobber(y1) + // result: @mergePoint(b,x0,x1) (MOVHUloadidx ptr0 idx0 mem) + for { + t := v.Type + if v.AuxInt != 8 { + break + } + _ = v.Args[1] + y0 := v.Args[0] + if y0.Op != OpARM64MOVDnop { + break + } + x0 := y0.Args[0] + if x0.Op != OpARM64MOVBUloadidx { + break + } + mem := x0.Args[2] + ptr0 := x0.Args[0] + idx0 := x0.Args[1] + y1 := v.Args[1] + if y1.Op != OpARM64MOVDnop { + break + } + x1 := y1.Args[0] + if x1.Op != OpARM64MOVBUload || x1.AuxInt != 1 { + break + } + s := x1.Aux + _ = x1.Args[1] + p1 := x1.Args[0] + if p1.Op != OpARM64ADD { + break + } + ptr1 := p1.Args[1] + idx1 := p1.Args[0] + if mem != x1.Args[1] || !(s == nil && x0.Uses == 1 && x1.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && mergePoint(b, x0, x1) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x0) && clobber(x1) && clobber(y0) && clobber(y1)) { + break + } + b = mergePoint(b, x0, x1) + v0 := b.NewValue0(x1.Pos, OpARM64MOVHUloadidx, t) + v.reset(OpCopy) + v.AddArg(v0) + v0.AddArg(ptr0) + v0.AddArg(idx0) + v0.AddArg(mem) + return true + } // match: (ORshiftLL [8] y0:(MOVDnop x0:(MOVBUloadidx ptr idx mem)) y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [1] idx) 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) (MOVHUloadidx ptr idx mem) @@ -22776,6 +24863,68 @@ func rewriteValueARM64_OpARM64ORshiftLL_10(v *Value) bool { v0.AddArg(mem) return true } + // match: (ORshiftLL [24] o0:(ORshiftLL [16] x0:(MOVHUloadidx ptr0 idx0 mem) y1:(MOVDnop x1:(MOVBUload [2] {s} p1:(ADD idx1 ptr1) mem))) y2:(MOVDnop x2:(MOVBUload [3] {s} p mem))) + // cond: s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && o0.Uses == 1 && mergePoint(b,x0,x1,x2) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0) && clobber(x1) && clobber(x2) && clobber(y1) && clobber(y2) && clobber(o0) + // result: @mergePoint(b,x0,x1,x2) (MOVWUloadidx ptr0 idx0 mem) + for { + t := v.Type + if v.AuxInt != 24 { + break + } + _ = v.Args[1] + o0 := v.Args[0] + if o0.Op != OpARM64ORshiftLL || o0.AuxInt != 16 { + break + } + _ = o0.Args[1] + x0 := o0.Args[0] + if x0.Op != OpARM64MOVHUloadidx { + break + } + mem := x0.Args[2] + ptr0 := x0.Args[0] + idx0 := x0.Args[1] + y1 := o0.Args[1] + if y1.Op != OpARM64MOVDnop { + break + } + x1 := y1.Args[0] + if x1.Op != OpARM64MOVBUload || x1.AuxInt != 2 { + break + } + s := x1.Aux + _ = x1.Args[1] + p1 := x1.Args[0] + if p1.Op != OpARM64ADD { + break + } + ptr1 := p1.Args[1] + idx1 := p1.Args[0] + if mem != x1.Args[1] { + break + } + y2 := v.Args[1] + if y2.Op != OpARM64MOVDnop { + break + } + x2 := y2.Args[0] + if x2.Op != OpARM64MOVBUload || x2.AuxInt != 3 || x2.Aux != s { + break + } + _ = x2.Args[1] + p := x2.Args[0] + if mem != x2.Args[1] || !(s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && o0.Uses == 1 && mergePoint(b, x0, x1, x2) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0) && clobber(x1) && clobber(x2) && clobber(y1) && clobber(y2) && clobber(o0)) { + break + } + b = mergePoint(b, x0, x1, x2) + v0 := b.NewValue0(x2.Pos, OpARM64MOVWUloadidx, t) + v.reset(OpCopy) + v.AddArg(v0) + v0.AddArg(ptr0) + v0.AddArg(idx0) + v0.AddArg(mem) + return true + } // match: (ORshiftLL [24] o0:(ORshiftLL [16] x0:(MOVHUloadidx ptr idx mem) y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [2] idx) mem))) y2:(MOVDnop x2:(MOVBUloadidx ptr (ADDconst [3] idx) mem))) // cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && o0.Uses == 1 && mergePoint(b,x0,x1,x2) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(y1) && clobber(y2) && clobber(o0) // result: @mergePoint(b,x0,x1,x2) (MOVWUloadidx ptr idx mem) @@ -23107,6 +25256,106 @@ func rewriteValueARM64_OpARM64ORshiftLL_10(v *Value) bool { v0.AddArg(mem) return true } + return false +} +func rewriteValueARM64_OpARM64ORshiftLL_20(v *Value) bool { + b := v.Block + // match: (ORshiftLL [56] o0:(ORshiftLL [48] o1:(ORshiftLL [40] o2:(ORshiftLL [32] x0:(MOVWUloadidx ptr0 idx0 mem) y1:(MOVDnop x1:(MOVBUload [4] {s} p1:(ADD idx1 ptr1) mem))) y2:(MOVDnop x2:(MOVBUload [5] {s} p mem))) y3:(MOVDnop x3:(MOVBUload [6] {s} p mem))) y4:(MOVDnop x4:(MOVBUload [7] {s} p mem))) + // cond: s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && mergePoint(b,x0,x1,x2,x3,x4) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(y1) && clobber(y2) && clobber(y3) && clobber(y4) && clobber(o0) && clobber(o1) && clobber(o2) + // result: @mergePoint(b,x0,x1,x2,x3,x4) (MOVDloadidx ptr0 idx0 mem) + for { + t := v.Type + if v.AuxInt != 56 { + break + } + _ = v.Args[1] + o0 := v.Args[0] + if o0.Op != OpARM64ORshiftLL || o0.AuxInt != 48 { + break + } + _ = o0.Args[1] + o1 := o0.Args[0] + if o1.Op != OpARM64ORshiftLL || o1.AuxInt != 40 { + break + } + _ = o1.Args[1] + o2 := o1.Args[0] + if o2.Op != OpARM64ORshiftLL || o2.AuxInt != 32 { + break + } + _ = o2.Args[1] + x0 := o2.Args[0] + if x0.Op != OpARM64MOVWUloadidx { + break + } + mem := x0.Args[2] + ptr0 := x0.Args[0] + idx0 := x0.Args[1] + y1 := o2.Args[1] + if y1.Op != OpARM64MOVDnop { + break + } + x1 := y1.Args[0] + if x1.Op != OpARM64MOVBUload || x1.AuxInt != 4 { + break + } + s := x1.Aux + _ = x1.Args[1] + p1 := x1.Args[0] + if p1.Op != OpARM64ADD { + break + } + ptr1 := p1.Args[1] + idx1 := p1.Args[0] + if mem != x1.Args[1] { + break + } + y2 := o1.Args[1] + if y2.Op != OpARM64MOVDnop { + break + } + x2 := y2.Args[0] + if x2.Op != OpARM64MOVBUload || x2.AuxInt != 5 || x2.Aux != s { + break + } + _ = x2.Args[1] + p := x2.Args[0] + if mem != x2.Args[1] { + break + } + y3 := o0.Args[1] + if y3.Op != OpARM64MOVDnop { + break + } + x3 := y3.Args[0] + if x3.Op != OpARM64MOVBUload || x3.AuxInt != 6 || x3.Aux != s { + break + } + _ = x3.Args[1] + if p != x3.Args[0] || mem != x3.Args[1] { + break + } + y4 := v.Args[1] + if y4.Op != OpARM64MOVDnop { + break + } + x4 := y4.Args[0] + if x4.Op != OpARM64MOVBUload || x4.AuxInt != 7 || x4.Aux != s { + break + } + _ = x4.Args[1] + if p != x4.Args[0] || mem != x4.Args[1] || !(s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(y1) && clobber(y2) && clobber(y3) && clobber(y4) && clobber(o0) && clobber(o1) && clobber(o2)) { + break + } + b = mergePoint(b, x0, x1, x2, x3, x4) + v0 := b.NewValue0(x4.Pos, OpARM64MOVDloadidx, t) + v.reset(OpCopy) + v.AddArg(v0) + v0.AddArg(ptr0) + v0.AddArg(idx0) + v0.AddArg(mem) + return true + } // match: (ORshiftLL [56] o0:(ORshiftLL [48] o1:(ORshiftLL [40] o2:(ORshiftLL [32] x0:(MOVWUloadidx4 ptr0 idx0 mem) y1:(MOVDnop x1:(MOVBUload [4] {s} p1:(ADDshiftLL [2] ptr1 idx1) mem))) y2:(MOVDnop x2:(MOVBUload [5] {s} p mem))) y3:(MOVDnop x3:(MOVBUload [6] {s} p mem))) y4:(MOVDnop x4:(MOVBUload [7] {s} p mem))) // cond: s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && mergePoint(b,x0,x1,x2,x3,x4) != nil && isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) && isSamePtr(p1, p) && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(y1) && clobber(y2) && clobber(y3) && clobber(y4) && clobber(o0) && clobber(o1) && clobber(o2) // result: @mergePoint(b,x0,x1,x2,x3,x4) (MOVDloadidx ptr0 (SLLconst [2] idx0) mem) @@ -23310,10 +25559,6 @@ func rewriteValueARM64_OpARM64ORshiftLL_10(v *Value) bool { v0.AddArg(mem) return true } - return false -} -func rewriteValueARM64_OpARM64ORshiftLL_20(v *Value) bool { - b := v.Block // match: (ORshiftLL [8] y0:(MOVDnop x0:(MOVBUload [i1] {s} p mem)) y1:(MOVDnop x1:(MOVBUload [i0] {s} p mem))) // cond: i1 == i0+1 && 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) (REV16W (MOVHUload [i0] {s} p mem)) @@ -23413,6 +25658,56 @@ func rewriteValueARM64_OpARM64ORshiftLL_20(v *Value) bool { v0.AddArg(v1) return true } + // match: (ORshiftLL [8] y0:(MOVDnop x0:(MOVBUload [1] {s} p1:(ADD idx1 ptr1) mem)) y1:(MOVDnop x1:(MOVBUloadidx ptr0 idx0 mem))) + // cond: s == nil && x0.Uses == 1 && x1.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && mergePoint(b,x0,x1) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x0) && clobber(x1) && clobber(y0) && clobber(y1) + // result: @mergePoint(b,x0,x1) (REV16W (MOVHUloadidx ptr0 idx0 mem)) + for { + t := v.Type + if v.AuxInt != 8 { + break + } + _ = v.Args[1] + y0 := v.Args[0] + if y0.Op != OpARM64MOVDnop { + break + } + x0 := y0.Args[0] + if x0.Op != OpARM64MOVBUload || x0.AuxInt != 1 { + break + } + s := x0.Aux + mem := x0.Args[1] + p1 := x0.Args[0] + if p1.Op != OpARM64ADD { + break + } + ptr1 := p1.Args[1] + idx1 := p1.Args[0] + y1 := v.Args[1] + if y1.Op != OpARM64MOVDnop { + break + } + x1 := y1.Args[0] + if x1.Op != OpARM64MOVBUloadidx { + break + } + _ = x1.Args[2] + ptr0 := x1.Args[0] + idx0 := x1.Args[1] + if mem != x1.Args[2] || !(s == nil && x0.Uses == 1 && x1.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && mergePoint(b, x0, x1) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && clobber(x0) && clobber(x1) && clobber(y0) && clobber(y1)) { + break + } + b = mergePoint(b, x0, x1) + v0 := b.NewValue0(x0.Pos, OpARM64REV16W, t) + v.reset(OpCopy) + v.AddArg(v0) + v1 := b.NewValue0(x0.Pos, OpARM64MOVHUloadidx, t) + v1.AddArg(ptr0) + v1.AddArg(idx0) + v1.AddArg(mem) + v0.AddArg(v1) + return true + } // match: (ORshiftLL [8] y0:(MOVDnop x0:(MOVBUloadidx ptr (ADDconst [1] idx) mem)) y1:(MOVDnop x1:(MOVBUloadidx ptr idx 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) (REV16W (MOVHUloadidx ptr idx mem)) @@ -23600,6 +25895,78 @@ func rewriteValueARM64_OpARM64ORshiftLL_20(v *Value) bool { v0.AddArg(v1) return true } + // match: (ORshiftLL [24] o0:(ORshiftLL [16] y0:(REV16W x0:(MOVHUload [2] {s} p mem)) y1:(MOVDnop x1:(MOVBUload [1] {s} p1:(ADD idx1 ptr1) mem))) y2:(MOVDnop x2:(MOVBUloadidx ptr0 idx0 mem))) + // cond: s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && o0.Uses == 1 && mergePoint(b,x0,x1,x2) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0) && clobber(x1) && clobber(x2) && clobber(y0) && clobber(y1) && clobber(y2) && clobber(o0) + // result: @mergePoint(b,x0,x1,x2) (REVW (MOVWUloadidx ptr0 idx0 mem)) + for { + t := v.Type + if v.AuxInt != 24 { + break + } + _ = v.Args[1] + o0 := v.Args[0] + if o0.Op != OpARM64ORshiftLL || o0.AuxInt != 16 { + break + } + _ = o0.Args[1] + y0 := o0.Args[0] + if y0.Op != OpARM64REV16W { + break + } + x0 := y0.Args[0] + if x0.Op != OpARM64MOVHUload || x0.AuxInt != 2 { + break + } + s := x0.Aux + mem := x0.Args[1] + p := x0.Args[0] + y1 := o0.Args[1] + if y1.Op != OpARM64MOVDnop { + break + } + x1 := y1.Args[0] + if x1.Op != OpARM64MOVBUload || x1.AuxInt != 1 || x1.Aux != s { + break + } + _ = x1.Args[1] + p1 := x1.Args[0] + if p1.Op != OpARM64ADD { + break + } + ptr1 := p1.Args[1] + idx1 := p1.Args[0] + if mem != x1.Args[1] { + break + } + y2 := v.Args[1] + if y2.Op != OpARM64MOVDnop { + break + } + x2 := y2.Args[0] + if x2.Op != OpARM64MOVBUloadidx { + break + } + _ = x2.Args[2] + ptr0 := x2.Args[0] + idx0 := x2.Args[1] + if mem != x2.Args[2] || !(s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && o0.Uses == 1 && mergePoint(b, x0, x1, x2) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0) && clobber(x1) && clobber(x2) && clobber(y0) && clobber(y1) && clobber(y2) && clobber(o0)) { + break + } + b = mergePoint(b, x0, x1, x2) + v0 := b.NewValue0(x1.Pos, OpARM64REVW, t) + v.reset(OpCopy) + v.AddArg(v0) + v1 := b.NewValue0(x1.Pos, OpARM64MOVWUloadidx, t) + v1.AddArg(ptr0) + v1.AddArg(idx0) + v1.AddArg(mem) + v0.AddArg(v1) + return true + } + return false +} +func rewriteValueARM64_OpARM64ORshiftLL_30(v *Value) bool { + b := v.Block // match: (ORshiftLL [24] o0:(ORshiftLL [16] y0:(REV16W x0:(MOVHUloadidx ptr (ADDconst [2] idx) mem)) y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [1] idx) mem))) y2:(MOVDnop x2:(MOVBUloadidx ptr idx mem))) // cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && o0.Uses == 1 && mergePoint(b,x0,x1,x2) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(y0) && clobber(y1) && clobber(y2) && clobber(o0) // result: @mergePoint(b,x0,x1,x2) (REVW (MOVWUloadidx ptr idx mem)) @@ -23884,6 +26251,108 @@ func rewriteValueARM64_OpARM64ORshiftLL_20(v *Value) bool { v0.AddArg(v1) return true } + // match: (ORshiftLL [56] o0:(ORshiftLL [48] o1:(ORshiftLL [40] o2:(ORshiftLL [32] y0:(REVW x0:(MOVWUload [4] {s} p mem)) y1:(MOVDnop x1:(MOVBUload [3] {s} p mem))) y2:(MOVDnop x2:(MOVBUload [2] {s} p mem))) y3:(MOVDnop x3:(MOVBUload [1] {s} p1:(ADD idx1 ptr1) mem))) y4:(MOVDnop x4:(MOVBUloadidx ptr0 idx0 mem))) + // cond: s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && mergePoint(b,x0,x1,x2,x3,x4) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(y0) && clobber(y1) && clobber(y2) && clobber(y3) && clobber(y4) && clobber(o0) && clobber(o1) && clobber(o2) + // result: @mergePoint(b,x0,x1,x2,x3,x4) (REV (MOVDloadidx ptr0 idx0 mem)) + for { + t := v.Type + if v.AuxInt != 56 { + break + } + _ = v.Args[1] + o0 := v.Args[0] + if o0.Op != OpARM64ORshiftLL || o0.AuxInt != 48 { + break + } + _ = o0.Args[1] + o1 := o0.Args[0] + if o1.Op != OpARM64ORshiftLL || o1.AuxInt != 40 { + break + } + _ = o1.Args[1] + o2 := o1.Args[0] + if o2.Op != OpARM64ORshiftLL || o2.AuxInt != 32 { + break + } + _ = o2.Args[1] + y0 := o2.Args[0] + if y0.Op != OpARM64REVW { + break + } + x0 := y0.Args[0] + if x0.Op != OpARM64MOVWUload || x0.AuxInt != 4 { + break + } + s := x0.Aux + mem := x0.Args[1] + p := x0.Args[0] + y1 := o2.Args[1] + if y1.Op != OpARM64MOVDnop { + break + } + x1 := y1.Args[0] + if x1.Op != OpARM64MOVBUload || x1.AuxInt != 3 || x1.Aux != s { + break + } + _ = x1.Args[1] + if p != x1.Args[0] || mem != x1.Args[1] { + break + } + y2 := o1.Args[1] + if y2.Op != OpARM64MOVDnop { + break + } + x2 := y2.Args[0] + if x2.Op != OpARM64MOVBUload || x2.AuxInt != 2 || x2.Aux != s { + break + } + _ = x2.Args[1] + if p != x2.Args[0] || mem != x2.Args[1] { + break + } + y3 := o0.Args[1] + if y3.Op != OpARM64MOVDnop { + break + } + x3 := y3.Args[0] + if x3.Op != OpARM64MOVBUload || x3.AuxInt != 1 || x3.Aux != s { + break + } + _ = x3.Args[1] + p1 := x3.Args[0] + if p1.Op != OpARM64ADD { + break + } + ptr1 := p1.Args[1] + idx1 := p1.Args[0] + if mem != x3.Args[1] { + break + } + y4 := v.Args[1] + if y4.Op != OpARM64MOVDnop { + break + } + x4 := y4.Args[0] + if x4.Op != OpARM64MOVBUloadidx { + break + } + _ = x4.Args[2] + ptr0 := x4.Args[0] + idx0 := x4.Args[1] + if mem != x4.Args[2] || !(s == nil && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && mergePoint(b, x0, x1, x2, x3, x4) != nil && (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1)) && isSamePtr(p1, p) && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(y0) && clobber(y1) && clobber(y2) && clobber(y3) && clobber(y4) && clobber(o0) && clobber(o1) && clobber(o2)) { + break + } + b = mergePoint(b, x0, x1, x2, x3, x4) + v0 := b.NewValue0(x3.Pos, OpARM64REV, t) + v.reset(OpCopy) + v.AddArg(v0) + v1 := b.NewValue0(x3.Pos, OpARM64MOVDloadidx, t) + v1.AddArg(ptr0) + v1.AddArg(idx0) + v1.AddArg(mem) + v0.AddArg(v1) + return true + } // match: (ORshiftLL [56] o0:(ORshiftLL [48] o1:(ORshiftLL [40] o2:(ORshiftLL [32] y0:(REVW x0:(MOVWUloadidx ptr (ADDconst [4] idx) mem)) y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [3] idx) mem))) y2:(MOVDnop x2:(MOVBUloadidx ptr (ADDconst [2] idx) mem))) y3:(MOVDnop x3:(MOVBUloadidx ptr (ADDconst [1] idx) mem))) y4:(MOVDnop x4:(MOVBUloadidx ptr idx mem))) // cond: x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1 && o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && mergePoint(b,x0,x1,x2,x3,x4) != nil && clobber(x0) && clobber(x1) && clobber(x2) && clobber(x3) && clobber(x4) && clobber(y0) && clobber(y1) && clobber(y2) && clobber(y3) && clobber(y4) && clobber(o0) && clobber(o1) && clobber(o2) // result: @mergePoint(b,x0,x1,x2,x3,x4) (REV (MOVDloadidx ptr idx mem)) diff --git a/src/cmd/compile/internal/ssa/rewritePPC64.go b/src/cmd/compile/internal/ssa/rewritePPC64.go index 2a9e0aa8b5..a8641ce1a4 100644 --- a/src/cmd/compile/internal/ssa/rewritePPC64.go +++ b/src/cmd/compile/internal/ssa/rewritePPC64.go @@ -1848,6 +1848,26 @@ func rewriteValuePPC64_OpEq16_0(v *Value) bool { v.AddArg(v0) return true } + // match: (Eq16 y x) + // cond: isSigned(x.Type) && isSigned(y.Type) + // result: (Equal (CMPW (SignExt16to32 x) (SignExt16to32 y))) + for { + x := v.Args[1] + y := v.Args[0] + if !(isSigned(x.Type) && isSigned(y.Type)) { + break + } + v.reset(OpPPC64Equal) + v0 := b.NewValue0(v.Pos, OpPPC64CMPW, types.TypeFlags) + v1 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32) + v1.AddArg(x) + v0.AddArg(v1) + v2 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32) + v2.AddArg(y) + v0.AddArg(v2) + v.AddArg(v0) + return true + } // match: (Eq16 x y) // result: (Equal (CMPW (ZeroExt16to32 x) (ZeroExt16to32 y))) for { @@ -1948,6 +1968,26 @@ func rewriteValuePPC64_OpEq8_0(v *Value) bool { v.AddArg(v0) return true } + // match: (Eq8 y x) + // cond: isSigned(x.Type) && isSigned(y.Type) + // result: (Equal (CMPW (SignExt8to32 x) (SignExt8to32 y))) + for { + x := v.Args[1] + y := v.Args[0] + if !(isSigned(x.Type) && isSigned(y.Type)) { + break + } + v.reset(OpPPC64Equal) + v0 := b.NewValue0(v.Pos, OpPPC64CMPW, types.TypeFlags) + v1 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32) + v1.AddArg(x) + v0.AddArg(v1) + v2 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32) + v2.AddArg(y) + v0.AddArg(v2) + v.AddArg(v0) + return true + } // match: (Eq8 x y) // result: (Equal (CMPW (ZeroExt8to32 x) (ZeroExt8to32 y))) for { @@ -4677,6 +4717,26 @@ func rewriteValuePPC64_OpNeq16_0(v *Value) bool { v.AddArg(v0) return true } + // match: (Neq16 y x) + // cond: isSigned(x.Type) && isSigned(y.Type) + // result: (NotEqual (CMPW (SignExt16to32 x) (SignExt16to32 y))) + for { + x := v.Args[1] + y := v.Args[0] + if !(isSigned(x.Type) && isSigned(y.Type)) { + break + } + v.reset(OpPPC64NotEqual) + v0 := b.NewValue0(v.Pos, OpPPC64CMPW, types.TypeFlags) + v1 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32) + v1.AddArg(x) + v0.AddArg(v1) + v2 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32) + v2.AddArg(y) + v0.AddArg(v2) + v.AddArg(v0) + return true + } // match: (Neq16 x y) // result: (NotEqual (CMPW (ZeroExt16to32 x) (ZeroExt16to32 y))) for { @@ -4777,6 +4837,26 @@ func rewriteValuePPC64_OpNeq8_0(v *Value) bool { v.AddArg(v0) return true } + // match: (Neq8 y x) + // cond: isSigned(x.Type) && isSigned(y.Type) + // result: (NotEqual (CMPW (SignExt8to32 x) (SignExt8to32 y))) + for { + x := v.Args[1] + y := v.Args[0] + if !(isSigned(x.Type) && isSigned(y.Type)) { + break + } + v.reset(OpPPC64NotEqual) + v0 := b.NewValue0(v.Pos, OpPPC64CMPW, types.TypeFlags) + v1 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32) + v1.AddArg(x) + v0.AddArg(v1) + v2 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32) + v2.AddArg(y) + v0.AddArg(v2) + v.AddArg(v0) + return true + } // match: (Neq8 x y) // result: (NotEqual (CMPW (ZeroExt8to32 x) (ZeroExt8to32 y))) for { diff --git a/src/cmd/compile/internal/ssa/rewriteS390X.go b/src/cmd/compile/internal/ssa/rewriteS390X.go index e93b3f6b95..e7c8120ea0 100644 --- a/src/cmd/compile/internal/ssa/rewriteS390X.go +++ b/src/cmd/compile/internal/ssa/rewriteS390X.go @@ -9331,6 +9331,30 @@ func rewriteValueS390X_OpS390XFMOVDload_0(v *Value) bool { v.AddArg(mem) return true } + // match: (FMOVDload [off] {sym} (ADD idx ptr) mem) + // cond: ptr.Op != OpSB + // result: (FMOVDloadidx [off] {sym} ptr idx mem) + for { + off := v.AuxInt + sym := v.Aux + mem := v.Args[1] + v_0 := v.Args[0] + if v_0.Op != OpS390XADD { + break + } + ptr := v_0.Args[1] + idx := v_0.Args[0] + if !(ptr.Op != OpSB) { + break + } + v.reset(OpS390XFMOVDloadidx) + v.AuxInt = off + v.Aux = sym + v.AddArg(ptr) + v.AddArg(idx) + v.AddArg(mem) + return true + } return false } func rewriteValueS390X_OpS390XFMOVDloadidx_0(v *Value) bool { @@ -9492,6 +9516,32 @@ func rewriteValueS390X_OpS390XFMOVDstore_0(v *Value) bool { v.AddArg(mem) return true } + // match: (FMOVDstore [off] {sym} (ADD idx ptr) val mem) + // cond: ptr.Op != OpSB + // result: (FMOVDstoreidx [off] {sym} ptr idx val mem) + for { + off := v.AuxInt + sym := v.Aux + mem := v.Args[2] + v_0 := v.Args[0] + if v_0.Op != OpS390XADD { + break + } + ptr := v_0.Args[1] + idx := v_0.Args[0] + val := v.Args[1] + if !(ptr.Op != OpSB) { + break + } + v.reset(OpS390XFMOVDstoreidx) + v.AuxInt = off + v.Aux = sym + v.AddArg(ptr) + v.AddArg(idx) + v.AddArg(val) + v.AddArg(mem) + return true + } return false } func rewriteValueS390X_OpS390XFMOVDstoreidx_0(v *Value) bool { @@ -9672,6 +9722,30 @@ func rewriteValueS390X_OpS390XFMOVSload_0(v *Value) bool { v.AddArg(mem) return true } + // match: (FMOVSload [off] {sym} (ADD idx ptr) mem) + // cond: ptr.Op != OpSB + // result: (FMOVSloadidx [off] {sym} ptr idx mem) + for { + off := v.AuxInt + sym := v.Aux + mem := v.Args[1] + v_0 := v.Args[0] + if v_0.Op != OpS390XADD { + break + } + ptr := v_0.Args[1] + idx := v_0.Args[0] + if !(ptr.Op != OpSB) { + break + } + v.reset(OpS390XFMOVSloadidx) + v.AuxInt = off + v.Aux = sym + v.AddArg(ptr) + v.AddArg(idx) + v.AddArg(mem) + return true + } return false } func rewriteValueS390X_OpS390XFMOVSloadidx_0(v *Value) bool { @@ -9833,6 +9907,32 @@ func rewriteValueS390X_OpS390XFMOVSstore_0(v *Value) bool { v.AddArg(mem) return true } + // match: (FMOVSstore [off] {sym} (ADD idx ptr) val mem) + // cond: ptr.Op != OpSB + // result: (FMOVSstoreidx [off] {sym} ptr idx val mem) + for { + off := v.AuxInt + sym := v.Aux + mem := v.Args[2] + v_0 := v.Args[0] + if v_0.Op != OpS390XADD { + break + } + ptr := v_0.Args[1] + idx := v_0.Args[0] + val := v.Args[1] + if !(ptr.Op != OpSB) { + break + } + v.reset(OpS390XFMOVSstoreidx) + v.AuxInt = off + v.Aux = sym + v.AddArg(ptr) + v.AddArg(idx) + v.AddArg(val) + v.AddArg(mem) + return true + } return false } func rewriteValueS390X_OpS390XFMOVSstoreidx_0(v *Value) bool { @@ -10484,6 +10584,30 @@ func rewriteValueS390X_OpS390XMOVBZload_0(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVBZload [off] {sym} (ADD idx ptr) mem) + // cond: ptr.Op != OpSB + // result: (MOVBZloadidx [off] {sym} ptr idx mem) + for { + off := v.AuxInt + sym := v.Aux + mem := v.Args[1] + v_0 := v.Args[0] + if v_0.Op != OpS390XADD { + break + } + ptr := v_0.Args[1] + idx := v_0.Args[0] + if !(ptr.Op != OpSB) { + break + } + v.reset(OpS390XMOVBZloadidx) + v.AuxInt = off + v.Aux = sym + v.AddArg(ptr) + v.AddArg(idx) + v.AddArg(mem) + return true + } return false } func rewriteValueS390X_OpS390XMOVBZloadidx_0(v *Value) bool { @@ -10974,6 +11098,30 @@ func rewriteValueS390X_OpS390XMOVBload_0(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVBload [off] {sym} (ADD idx ptr) mem) + // cond: ptr.Op != OpSB + // result: (MOVBloadidx [off] {sym} ptr idx mem) + for { + off := v.AuxInt + sym := v.Aux + mem := v.Args[1] + v_0 := v.Args[0] + if v_0.Op != OpS390XADD { + break + } + ptr := v_0.Args[1] + idx := v_0.Args[0] + if !(ptr.Op != OpSB) { + break + } + v.reset(OpS390XMOVBloadidx) + v.AuxInt = off + v.Aux = sym + v.AddArg(ptr) + v.AddArg(idx) + v.AddArg(mem) + return true + } return false } func rewriteValueS390X_OpS390XMOVBloadidx_0(v *Value) bool { @@ -11490,6 +11638,32 @@ func rewriteValueS390X_OpS390XMOVBstore_0(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVBstore [off] {sym} (ADD idx ptr) val mem) + // cond: ptr.Op != OpSB + // result: (MOVBstoreidx [off] {sym} ptr idx val mem) + for { + off := v.AuxInt + sym := v.Aux + mem := v.Args[2] + v_0 := v.Args[0] + if v_0.Op != OpS390XADD { + break + } + ptr := v_0.Args[1] + idx := v_0.Args[0] + val := v.Args[1] + if !(ptr.Op != OpSB) { + break + } + v.reset(OpS390XMOVBstoreidx) + v.AuxInt = off + v.Aux = sym + v.AddArg(ptr) + v.AddArg(idx) + v.AddArg(val) + v.AddArg(mem) + return true + } // match: (MOVBstore [i] {s} p w x:(MOVBstore [i-1] {s} p (SRDconst [8] w) mem)) // cond: p.Op != OpSB && x.Uses == 1 && clobber(x) // result: (MOVHstore [i-1] {s} p w mem) @@ -11553,6 +11727,9 @@ func rewriteValueS390X_OpS390XMOVBstore_0(v *Value) bool { v.AddArg(mem) return true } + return false +} +func rewriteValueS390X_OpS390XMOVBstore_10(v *Value) bool { // match: (MOVBstore [i] {s} p w x:(MOVBstore [i-1] {s} p (SRWconst [8] w) mem)) // cond: p.Op != OpSB && x.Uses == 1 && clobber(x) // result: (MOVHstore [i-1] {s} p w mem) @@ -11582,9 +11759,6 @@ func rewriteValueS390X_OpS390XMOVBstore_0(v *Value) bool { v.AddArg(mem) return true } - return false -} -func rewriteValueS390X_OpS390XMOVBstore_10(v *Value) bool { // match: (MOVBstore [i] {s} p w0:(SRWconst [j] w) x:(MOVBstore [i-1] {s} p (SRWconst [j+8] w) mem)) // cond: p.Op != OpSB && x.Uses == 1 && clobber(x) // result: (MOVHstore [i-1] {s} p w0 mem) @@ -13259,6 +13433,30 @@ func rewriteValueS390X_OpS390XMOVDload_0(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVDload [off] {sym} (ADD idx ptr) mem) + // cond: ptr.Op != OpSB + // result: (MOVDloadidx [off] {sym} ptr idx mem) + for { + off := v.AuxInt + sym := v.Aux + mem := v.Args[1] + v_0 := v.Args[0] + if v_0.Op != OpS390XADD { + break + } + ptr := v_0.Args[1] + idx := v_0.Args[0] + if !(ptr.Op != OpSB) { + break + } + v.reset(OpS390XMOVDloadidx) + v.AuxInt = off + v.Aux = sym + v.AddArg(ptr) + v.AddArg(idx) + v.AddArg(mem) + return true + } return false } func rewriteValueS390X_OpS390XMOVDloadidx_0(v *Value) bool { @@ -13494,6 +13692,32 @@ func rewriteValueS390X_OpS390XMOVDstore_0(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVDstore [off] {sym} (ADD idx ptr) val mem) + // cond: ptr.Op != OpSB + // result: (MOVDstoreidx [off] {sym} ptr idx val mem) + for { + off := v.AuxInt + sym := v.Aux + mem := v.Args[2] + v_0 := v.Args[0] + if v_0.Op != OpS390XADD { + break + } + ptr := v_0.Args[1] + idx := v_0.Args[0] + val := v.Args[1] + if !(ptr.Op != OpSB) { + break + } + v.reset(OpS390XMOVDstoreidx) + v.AuxInt = off + v.Aux = sym + v.AddArg(ptr) + v.AddArg(idx) + v.AddArg(val) + v.AddArg(mem) + return true + } // match: (MOVDstore [i] {s} p w1 x:(MOVDstore [i-8] {s} p w0 mem)) // cond: p.Op != OpSB && x.Uses == 1 && is20Bit(i-8) && clobber(x) // result: (STMG2 [i-8] {s} p w0 w1 mem) @@ -14545,6 +14769,30 @@ func rewriteValueS390X_OpS390XMOVHZload_0(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVHZload [off] {sym} (ADD idx ptr) mem) + // cond: ptr.Op != OpSB + // result: (MOVHZloadidx [off] {sym} ptr idx mem) + for { + off := v.AuxInt + sym := v.Aux + mem := v.Args[1] + v_0 := v.Args[0] + if v_0.Op != OpS390XADD { + break + } + ptr := v_0.Args[1] + idx := v_0.Args[0] + if !(ptr.Op != OpSB) { + break + } + v.reset(OpS390XMOVHZloadidx) + v.AuxInt = off + v.Aux = sym + v.AddArg(ptr) + v.AddArg(idx) + v.AddArg(mem) + return true + } return false } func rewriteValueS390X_OpS390XMOVHZloadidx_0(v *Value) bool { @@ -15027,6 +15275,30 @@ func rewriteValueS390X_OpS390XMOVHload_0(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVHload [off] {sym} (ADD idx ptr) mem) + // cond: ptr.Op != OpSB + // result: (MOVHloadidx [off] {sym} ptr idx mem) + for { + off := v.AuxInt + sym := v.Aux + mem := v.Args[1] + v_0 := v.Args[0] + if v_0.Op != OpS390XADD { + break + } + ptr := v_0.Args[1] + idx := v_0.Args[0] + if !(ptr.Op != OpSB) { + break + } + v.reset(OpS390XMOVHloadidx) + v.AuxInt = off + v.Aux = sym + v.AddArg(ptr) + v.AddArg(idx) + v.AddArg(mem) + return true + } return false } func rewriteValueS390X_OpS390XMOVHloadidx_0(v *Value) bool { @@ -15595,6 +15867,32 @@ func rewriteValueS390X_OpS390XMOVHstore_0(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVHstore [off] {sym} (ADD idx ptr) val mem) + // cond: ptr.Op != OpSB + // result: (MOVHstoreidx [off] {sym} ptr idx val mem) + for { + off := v.AuxInt + sym := v.Aux + mem := v.Args[2] + v_0 := v.Args[0] + if v_0.Op != OpS390XADD { + break + } + ptr := v_0.Args[1] + idx := v_0.Args[0] + val := v.Args[1] + if !(ptr.Op != OpSB) { + break + } + v.reset(OpS390XMOVHstoreidx) + v.AuxInt = off + v.Aux = sym + v.AddArg(ptr) + v.AddArg(idx) + v.AddArg(val) + v.AddArg(mem) + return true + } // match: (MOVHstore [i] {s} p w x:(MOVHstore [i-2] {s} p (SRDconst [16] w) mem)) // cond: p.Op != OpSB && x.Uses == 1 && clobber(x) // result: (MOVWstore [i-2] {s} p w mem) @@ -15658,6 +15956,9 @@ func rewriteValueS390X_OpS390XMOVHstore_0(v *Value) bool { v.AddArg(mem) return true } + return false +} +func rewriteValueS390X_OpS390XMOVHstore_10(v *Value) bool { // match: (MOVHstore [i] {s} p w x:(MOVHstore [i-2] {s} p (SRWconst [16] w) mem)) // cond: p.Op != OpSB && x.Uses == 1 && clobber(x) // result: (MOVWstore [i-2] {s} p w mem) @@ -15687,9 +15988,6 @@ func rewriteValueS390X_OpS390XMOVHstore_0(v *Value) bool { v.AddArg(mem) return true } - return false -} -func rewriteValueS390X_OpS390XMOVHstore_10(v *Value) bool { // match: (MOVHstore [i] {s} p w0:(SRWconst [j] w) x:(MOVHstore [i-2] {s} p (SRWconst [j+16] w) mem)) // cond: p.Op != OpSB && x.Uses == 1 && clobber(x) // result: (MOVWstore [i-2] {s} p w0 mem) @@ -16916,6 +17214,30 @@ func rewriteValueS390X_OpS390XMOVWZload_0(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVWZload [off] {sym} (ADD idx ptr) mem) + // cond: ptr.Op != OpSB + // result: (MOVWZloadidx [off] {sym} ptr idx mem) + for { + off := v.AuxInt + sym := v.Aux + mem := v.Args[1] + v_0 := v.Args[0] + if v_0.Op != OpS390XADD { + break + } + ptr := v_0.Args[1] + idx := v_0.Args[0] + if !(ptr.Op != OpSB) { + break + } + v.reset(OpS390XMOVWZloadidx) + v.AuxInt = off + v.Aux = sym + v.AddArg(ptr) + v.AddArg(idx) + v.AddArg(mem) + return true + } return false } func rewriteValueS390X_OpS390XMOVWZloadidx_0(v *Value) bool { @@ -17398,6 +17720,30 @@ func rewriteValueS390X_OpS390XMOVWload_0(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVWload [off] {sym} (ADD idx ptr) mem) + // cond: ptr.Op != OpSB + // result: (MOVWloadidx [off] {sym} ptr idx mem) + for { + off := v.AuxInt + sym := v.Aux + mem := v.Args[1] + v_0 := v.Args[0] + if v_0.Op != OpS390XADD { + break + } + ptr := v_0.Args[1] + idx := v_0.Args[0] + if !(ptr.Op != OpSB) { + break + } + v.reset(OpS390XMOVWloadidx) + v.AuxInt = off + v.Aux = sym + v.AddArg(ptr) + v.AddArg(idx) + v.AddArg(mem) + return true + } return false } func rewriteValueS390X_OpS390XMOVWloadidx_0(v *Value) bool { @@ -17997,6 +18343,32 @@ func rewriteValueS390X_OpS390XMOVWstore_0(v *Value) bool { v.AddArg(mem) return true } + // match: (MOVWstore [off] {sym} (ADD idx ptr) val mem) + // cond: ptr.Op != OpSB + // result: (MOVWstoreidx [off] {sym} ptr idx val mem) + for { + off := v.AuxInt + sym := v.Aux + mem := v.Args[2] + v_0 := v.Args[0] + if v_0.Op != OpS390XADD { + break + } + ptr := v_0.Args[1] + idx := v_0.Args[0] + val := v.Args[1] + if !(ptr.Op != OpSB) { + break + } + v.reset(OpS390XMOVWstoreidx) + v.AuxInt = off + v.Aux = sym + v.AddArg(ptr) + v.AddArg(idx) + v.AddArg(val) + v.AddArg(mem) + return true + } // match: (MOVWstore [i] {s} p (SRDconst [32] w) x:(MOVWstore [i-4] {s} p w mem)) // cond: p.Op != OpSB && x.Uses == 1 && clobber(x) // result: (MOVDstore [i-4] {s} p w mem) @@ -18060,6 +18432,9 @@ func rewriteValueS390X_OpS390XMOVWstore_0(v *Value) bool { v.AddArg(mem) return true } + return false +} +func rewriteValueS390X_OpS390XMOVWstore_10(v *Value) bool { // match: (MOVWstore [i] {s} p w1 x:(MOVWstore [i-4] {s} p w0 mem)) // cond: p.Op != OpSB && x.Uses == 1 && is20Bit(i-4) && clobber(x) // result: (STM2 [i-4] {s} p w0 w1 mem) @@ -18090,9 +18465,6 @@ func rewriteValueS390X_OpS390XMOVWstore_0(v *Value) bool { v.AddArg(mem) return true } - return false -} -func rewriteValueS390X_OpS390XMOVWstore_10(v *Value) bool { // match: (MOVWstore [i] {s} p w2 x:(STM2 [i-8] {s} p w0 w1 mem)) // cond: x.Uses == 1 && is20Bit(i-8) && clobber(x) // result: (STM3 [i-8] {s} p w0 w1 w2 mem)