]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: generate commutative rules when a condition is present
authorJosh Bleecher Snyder <josharian@gmail.com>
Tue, 7 Jan 2020 07:45:57 +0000 (23:45 -0800)
committerJosh Bleecher Snyder <josharian@gmail.com>
Thu, 20 Feb 2020 14:59:27 +0000 (14:59 +0000)
The commutative rule generator has an optimization
where given (Add x y) with no other uses of x and y in the matching rule,
it doesn't generate the commutative match (Add y x).

However, if there is also a condition referring to x or y,
such as (Add x y) && isFoo(x), then we should generate the commutative rule.
This change parses the condition, extracts all idents, and takes them
into consideration.

This doesn't yield any new optimizations now.
However, it is the right thing to do;
otherwise we'll have to track it down and fix it again later.

It is also expensive now, in terms of additional generated code.
However, it will be much, much less expensive soon,
once our generated code for commutative ops gets smaller.

Change-Id: I52c2016c884bbc7789bf8dfe9b9c56061bc028ad
Reviewed-on: https://go-review.googlesource.com/c/go/+/213702
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
Reviewed-by: Keith Randall <khr@golang.org>
src/cmd/compile/internal/ssa/gen/rulegen.go
src/cmd/compile/internal/ssa/rewrite386.go
src/cmd/compile/internal/ssa/rewriteAMD64.go
src/cmd/compile/internal/ssa/rewriteARM64.go
src/cmd/compile/internal/ssa/rewritePPC64.go
src/cmd/compile/internal/ssa/rewriteS390X.go

index fa0b7c8a6b7be6da4ec858a69c865bc47c17da64..46d4eee72cfde97e95b0e16ab86e65daab81b549 100644 (file)
@@ -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
 }
 
index d1ea5c5a4d6caed20cd15b76981030fe0b3bff09..dba61cf3476aed4906c547ff58529412689f8571 100644 (file)
@@ -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)
index b29b1cc0d4384e30ef445d087b8f7eef48e61653..98619943d75719ef3a19b2828fc6d6af543eeb03 100644 (file)
@@ -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 <w.Type> [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.Type> 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.Type> 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)
index a62ac8a6fcdcddf65544891ba8e4fb21be7b77d4..485aee546a8adc116757596e1aead406dbb57db5 100644 (file)
@@ -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,29 +9657,80 @@ func rewriteValueARM64_OpARM64MOVBstore_20(v *Value) bool {
                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.Type> w) mem)
+       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 {
-               i := v.AuxInt
+               if v.AuxInt != 1 {
+                       break
+               }
                s := v.Aux
                _ = v.Args[2]
-               ptr := v.Args[0]
-               w := v.Args[1]
-               x0 := v.Args[2]
-               if x0.Op != OpARM64MOVBstore || x0.AuxInt != i-1 || x0.Aux != s {
+               v_0 := v.Args[0]
+               if v_0.Op != OpARM64ADD {
                        break
                }
-               _ = x0.Args[2]
-               if ptr != x0.Args[0] {
+               ptr0 := v_0.Args[1]
+               idx0 := v_0.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpARM64SRLconst {
                        break
                }
-               x0_1 := x0.Args[1]
-               if x0_1.Op != OpARM64SRLconst || x0_1.AuxInt != 8 || w != x0_1.Args[0] {
+               j := v_1.AuxInt
+               v_1_0 := v_1.Args[0]
+               if v_1_0.Op != OpARM64MOVDreg {
                        break
                }
-               x1 := x0.Args[2]
-               if x1.Op != OpARM64MOVBstore || x1.AuxInt != i-2 || x1.Aux != s {
+               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.Type> w) mem)
+       for {
+               i := v.AuxInt
+               s := v.Aux
+               _ = v.Args[2]
+               ptr := v.Args[0]
+               w := v.Args[1]
+               x0 := v.Args[2]
+               if x0.Op != OpARM64MOVBstore || x0.AuxInt != i-1 || x0.Aux != s {
+                       break
+               }
+               _ = x0.Args[2]
+               if ptr != 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 != i-2 || x1.Aux != s {
                        break
                }
                _ = x1.Args[2]
@@ -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.Type> 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.Type> 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.Type> 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.Type> w) mem)
@@ -9883,61 +10331,131 @@ 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 [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)
-       // result: (MOVWstore [i-3] {s} ptr (REVW <w.Type> w) mem)
+       // 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.Type> w) mem)
        for {
-               i := v.AuxInt
+               if v.AuxInt != 3 {
+                       break
+               }
                s := v.Aux
                _ = v.Args[2]
-               ptr := v.Args[0]
+               p := v.Args[0]
                w := v.Args[1]
                x0 := v.Args[2]
-               if x0.Op != OpARM64MOVBstore || x0.AuxInt != i-1 || x0.Aux != s {
+               if x0.Op != OpARM64MOVBstore || x0.AuxInt != 2 || x0.Aux != s {
                        break
                }
                _ = x0.Args[2]
-               if ptr != x0.Args[0] {
+               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] {
+               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 != i-2 || x1.Aux != s {
+               if x1.Op != OpARM64MOVBstore || x1.AuxInt != 1 || x1.Aux != s {
                        break
                }
                _ = x1.Args[2]
-               if ptr != x1.Args[0] {
+               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] {
+               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 != OpARM64MOVBstore || x2.AuxInt != i-3 || x2.Aux != s {
+               if x2.Op != OpARM64MOVBstoreidx {
                        break
                }
-               mem := x2.Args[2]
-               if ptr != x2.Args[0] {
+               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_1 := x2.Args[1]
-               if x2_1.Op != OpARM64SRLconst || x2_1.AuxInt != 24 || w != x2_1.Args[0] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && clobber(x0) && clobber(x1) && clobber(x2)) {
+               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(OpARM64MOVWstore)
-               v.AuxInt = i - 3
-               v.Aux = s
-               v.AddArg(ptr)
-               v0 := b.NewValue0(x2.Pos, OpARM64REVW, w.Type)
-               v0.AddArg(w)
+               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_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)
+       // result: (MOVWstore [i-3] {s} ptr (REVW <w.Type> w) mem)
+       for {
+               i := v.AuxInt
+               s := v.Aux
+               _ = v.Args[2]
+               ptr := v.Args[0]
+               w := v.Args[1]
+               x0 := v.Args[2]
+               if x0.Op != OpARM64MOVBstore || x0.AuxInt != i-1 || x0.Aux != s {
+                       break
+               }
+               _ = x0.Args[2]
+               if ptr != 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 != i-2 || x1.Aux != s {
+                       break
+               }
+               _ = x1.Args[2]
+               if ptr != 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 != i-3 || x2.Aux != s {
+                       break
+               }
+               mem := x2.Args[2]
+               if ptr != x2.Args[0] {
+                       break
+               }
+               x2_1 := x2.Args[1]
+               if x2_1.Op != OpARM64SRLconst || x2_1.AuxInt != 24 || w != x2_1.Args[0] || !(x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && clobber(x0) && clobber(x1) && clobber(x2)) {
+                       break
+               }
+               v.reset(OpARM64MOVWstore)
+               v.AuxInt = i - 3
+               v.Aux = s
+               v.AddArg(ptr)
+               v0 := b.NewValue0(x2.Pos, OpARM64REVW, w.Type)
+               v0.AddArg(w)
                v.AddArg(v0)
                v.AddArg(mem)
                return true
@@ -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.Type> 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.Type> 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.Type> 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.Type> 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.Type> 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.Type> 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.Type> 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.Type> 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.Type> w) mem)
@@ -10276,38 +10968,74 @@ func rewriteValueARM64_OpARM64MOVBstore_30(v *Value) bool {
                v.AddArg(mem)
                return true
        }
-       return false
-}
-func rewriteValueARM64_OpARM64MOVBstoreidx_0(v *Value) bool {
-       // match: (MOVBstoreidx ptr (MOVDconst [c]) val mem)
-       // result: (MOVBstore [c] ptr val mem)
+       // 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.Type> w) mem)
        for {
-               mem := v.Args[3]
-               ptr := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARM64MOVDconst {
+               if v.AuxInt != 1 {
                        break
                }
-               c := v_1.AuxInt
-               val := v.Args[2]
-               v.reset(OpARM64MOVBstore)
-               v.AuxInt = c
-               v.AddArg(ptr)
-               v.AddArg(val)
-               v.AddArg(mem)
-               return true
-       }
-       // match: (MOVBstoreidx (MOVDconst [c]) idx val mem)
-       // result: (MOVBstore [c] idx val mem)
-       for {
-               mem := v.Args[3]
+               s := v.Aux
+               _ = v.Args[2]
                v_0 := v.Args[0]
-               if v_0.Op != OpARM64MOVDconst {
+               if v_0.Op != OpARM64ADD {
                        break
                }
-               c := v_0.AuxInt
-               idx := v.Args[1]
-               val := v.Args[2]
+               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 {
+       // match: (MOVBstoreidx ptr (MOVDconst [c]) val mem)
+       // result: (MOVBstore [c] ptr val mem)
+       for {
+               mem := v.Args[3]
+               ptr := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpARM64MOVDconst {
+                       break
+               }
+               c := v_1.AuxInt
+               val := v.Args[2]
+               v.reset(OpARM64MOVBstore)
+               v.AuxInt = c
+               v.AddArg(ptr)
+               v.AddArg(val)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (MOVBstoreidx (MOVDconst [c]) idx val mem)
+       // result: (MOVBstore [c] idx val mem)
+       for {
+               mem := v.Args[3]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARM64MOVDconst {
+                       break
+               }
+               c := v_0.AuxInt
+               idx := v.Args[1]
+               val := v.Args[2]
                v.reset(OpARM64MOVBstore)
                v.AuxInt = c
                v.AddArg(idx)
@@ -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 <idx1.Type> [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 <idx1.Type> [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 <idx1.Type> [1] idx1) w mem)
@@ -13178,13 +14088,9 @@ 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} (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 <idx1.Type> [1] idx1) w0 mem)
+       // 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
@@ -13192,11 +14098,11 @@ func rewriteValueARM64_OpARM64MOVHstore_20(v *Value) bool {
                s := v.Aux
                _ = v.Args[2]
                v_0 := v.Args[0]
-               if v_0.Op != OpARM64ADDshiftLL || v_0.AuxInt != 1 {
+               if v_0.Op != OpARM64ADD {
                        break
                }
-               idx0 := v_0.Args[1]
-               ptr0 := v_0.Args[0]
+               ptr0 := v_0.Args[1]
+               idx0 := v_0.Args[0]
                v_1 := v.Args[1]
                if v_1.Op != OpARM64SRLconst {
                        break
@@ -13204,39 +14110,78 @@ func rewriteValueARM64_OpARM64MOVHstore_20(v *Value) bool {
                j := v_1.AuxInt
                w := v_1.Args[0]
                x := v.Args[2]
-               if x.Op != OpARM64MOVHstoreidx2 {
+               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) && clobber(x)) {
+               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)
-               v0 := b.NewValue0(v.Pos, OpARM64SLLconst, idx1.Type)
-               v0.AuxInt = 1
-               v0.AddArg(idx1)
-               v.AddArg(v0)
+               v.AddArg(idx1)
                v.AddArg(w0)
                v.AddArg(mem)
                return true
        }
-       return false
-}
-func rewriteValueARM64_OpARM64MOVHstoreidx_0(v *Value) bool {
-       // match: (MOVHstoreidx ptr (MOVDconst [c]) val mem)
-       // result: (MOVHstore [c] ptr val mem)
+       // 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 <idx1.Type> [1] idx1) w0 mem)
        for {
-               mem := v.Args[3]
-               ptr := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARM64MOVDconst {
+               if v.AuxInt != 2 {
                        break
                }
-               c := v_1.AuxInt
+               s := v.Aux
+               _ = v.Args[2]
+               v_0 := v.Args[0]
+               if v_0.Op != OpARM64ADDshiftLL || v_0.AuxInt != 1 {
+                       break
+               }
+               idx0 := v_0.Args[1]
+               ptr0 := 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 != OpARM64MOVHstoreidx2 {
+                       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) && clobber(x)) {
+                       break
+               }
+               v.reset(OpARM64MOVWstoreidx)
+               v.AddArg(ptr1)
+               v0 := b.NewValue0(v.Pos, OpARM64SLLconst, idx1.Type)
+               v0.AuxInt = 1
+               v0.AddArg(idx1)
+               v.AddArg(v0)
+               v.AddArg(w0)
+               v.AddArg(mem)
+               return true
+       }
+       return false
+}
+func rewriteValueARM64_OpARM64MOVHstoreidx_0(v *Value) bool {
+       // match: (MOVHstoreidx ptr (MOVDconst [c]) val mem)
+       // result: (MOVHstore [c] ptr val mem)
+       for {
+               mem := v.Args[3]
+               ptr := v.Args[0]
+               v_1 := v.Args[1]
+               if v_1.Op != OpARM64MOVDconst {
+                       break
+               }
+               c := v_1.AuxInt
                val := v.Args[2]
                v.reset(OpARM64MOVHstore)
                v.AuxInt = c
@@ -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 <idx1.Type> [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 <idx1.Type> [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 <idx1.Type> [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 <idx1.Type> [2] idx1) mem)
@@ -19232,24 +20315,13 @@ func rewriteValueARM64_OpARM64OR_20(v *Value) bool {
                v0.AddArg(mem)
                return true
        }
-       // match: (OR <t> 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))))
+       // match: (OR <t> 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 <t> 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]
+               o0 := v.Args[0]
                if o0.Op != OpARM64ORshiftLL || o0.AuxInt != 8 {
                        break
                }
@@ -19272,11 +20344,8 @@ func rewriteValueARM64_OpARM64OR_20(v *Value) bool {
                        break
                }
                s := x0.Aux
-               = x0.Args[1]
+               mem := x0.Args[1]
                p := x0.Args[0]
-               if mem != x0.Args[1] {
-                       break
-               }
                y1 := o1.Args[1]
                if y1.Op != OpARM64MOVDnop {
                        break
@@ -19302,9 +20371,23 @@ func rewriteValueARM64_OpARM64OR_20(v *Value) bool {
                if p1.Op != OpARM64ADD {
                        break
                }
-               idx1 := p1.Args[1]
-               ptr1 := 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)) {
+               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)
@@ -19316,13 +20399,24 @@ func rewriteValueARM64_OpARM64OR_20(v *Value) bool {
                v0.AddArg(mem)
                return true
        }
-       // match: (OR <t> 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 <t> ptr idx mem)
+       // match: (OR <t> 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 <t> ptr0 idx0 mem)
        for {
                t := v.Type
                _ = v.Args[1]
-               o0 := v.Args[0]
+               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
                }
@@ -19341,30 +20435,25 @@ func rewriteValueARM64_OpARM64OR_20(v *Value) bool {
                        break
                }
                x0 := y0.Args[0]
-               if x0.Op != OpARM64MOVBUloadidx {
+               if x0.Op != OpARM64MOVBUload || x0.AuxInt != 3 {
                        break
                }
-               mem := x0.Args[2]
-               ptr := x0.Args[0]
-               x0_1 := x0.Args[1]
-               if x0_1.Op != OpARM64ADDconst || x0_1.AuxInt != 3 {
+               s := x0.Aux
+               _ = x0.Args[1]
+               p := x0.Args[0]
+               if mem != x0.Args[1] {
                        break
                }
-               idx := x0_1.Args[0]
                y1 := o1.Args[1]
                if y1.Op != OpARM64MOVDnop {
                        break
                }
                x1 := y1.Args[0]
-               if x1.Op != OpARM64MOVBUloadidx {
-                       break
-               }
-               _ = x1.Args[2]
-               if ptr != x1.Args[0] {
+               if x1.Op != OpARM64MOVBUload || x1.AuxInt != 2 || x1.Aux != s {
                        break
                }
-               x1_1 := x1.Args[1]
-               if x1_1.Op != OpARM64ADDconst || x1_1.AuxInt != 2 || idx != x1_1.Args[0] || mem != x1.Args[2] {
+               = x1.Args[1]
+               if p != x1.Args[0] || mem != x1.Args[1] {
                        break
                }
                y2 := o0.Args[1]
@@ -19372,12 +20461,174 @@ func rewriteValueARM64_OpARM64OR_20(v *Value) bool {
                        break
                }
                x2 := y2.Args[0]
-               if x2.Op != OpARM64MOVBUloadidx {
+               if x2.Op != OpARM64MOVBUload || x2.AuxInt != 1 || x2.Aux != s {
                        break
                }
-               _ = x2.Args[2]
-               if ptr != x2.Args[0] {
-                       break
+               _ = x2.Args[1]
+               p1 := x2.Args[0]
+               if p1.Op != OpARM64ADD {
+                       break
+               }
+               idx1 := p1.Args[1]
+               ptr1 := 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 <t> 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 <t> 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 <t> 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 <t> ptr idx 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]
+               ptr := x0.Args[0]
+               x0_1 := x0.Args[1]
+               if x0_1.Op != OpARM64ADDconst || x0_1.AuxInt != 3 {
+                       break
+               }
+               idx := x0_1.Args[0]
+               y1 := o1.Args[1]
+               if y1.Op != OpARM64MOVDnop {
+                       break
+               }
+               x1 := y1.Args[0]
+               if x1.Op != OpARM64MOVBUloadidx {
+                       break
+               }
+               _ = x1.Args[2]
+               if ptr != x1.Args[0] {
+                       break
+               }
+               x1_1 := x1.Args[1]
+               if x1_1.Op != OpARM64ADDconst || x1_1.AuxInt != 2 || idx != x1_1.Args[0] || mem != x1.Args[2] {
+                       break
+               }
+               y2 := o0.Args[1]
+               if y2.Op != OpARM64MOVDnop {
+                       break
+               }
+               x2 := y2.Args[0]
+               if x2.Op != OpARM64MOVBUloadidx {
+                       break
+               }
+               _ = x2.Args[2]
+               if ptr != x2.Args[0] {
+                       break
                }
                x2_1 := x2.Args[1]
                if x2_1.Op != OpARM64ADDconst || x2_1.AuxInt != 1 || idx != x2_1.Args[0] || mem != x2.Args[2] {
@@ -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 <t> 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 <t> 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 <t> 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 <t> {s} (OffPtr <p.Type> [i0] p) mem)
@@ -20000,24 +21251,13 @@ func rewriteValueARM64_OpARM64OR_30(v *Value) bool {
                v0.AddArg(mem)
                return true
        }
-       // match: (OR <t> 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))))
+       // match: (OR <t> 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 <t> 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]
+               o0 := v.Args[0]
                if o0.Op != OpARM64ORshiftLL || o0.AuxInt != 8 {
                        break
                }
@@ -20060,11 +21300,8 @@ func rewriteValueARM64_OpARM64OR_30(v *Value) bool {
                        break
                }
                s := x0.Aux
-               = x0.Args[1]
+               mem := x0.Args[1]
                p := x0.Args[0]
-               if mem != x0.Args[1] {
-                       break
-               }
                y1 := o5.Args[1]
                if y1.Op != OpARM64MOVDnop {
                        break
@@ -20138,9 +21375,23 @@ func rewriteValueARM64_OpARM64OR_30(v *Value) bool {
                if p1.Op != OpARM64ADD {
                        break
                }
-               idx1 := p1.Args[1]
-               ptr1 := 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)) {
+               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)
@@ -20152,13 +21403,24 @@ func rewriteValueARM64_OpARM64OR_30(v *Value) bool {
                v0.AddArg(mem)
                return true
        }
-       // match: (OR <t> 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 <t> ptr idx mem)
+       // match: (OR <t> 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 <t> ptr0 idx0 mem)
        for {
                t := v.Type
                _ = v.Args[1]
-               o0 := v.Args[0]
+               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
                }
@@ -20197,30 +21459,25 @@ func rewriteValueARM64_OpARM64OR_30(v *Value) bool {
                        break
                }
                x0 := y0.Args[0]
-               if x0.Op != OpARM64MOVBUloadidx {
+               if x0.Op != OpARM64MOVBUload || x0.AuxInt != 7 {
                        break
                }
-               mem := x0.Args[2]
-               ptr := x0.Args[0]
-               x0_1 := x0.Args[1]
-               if x0_1.Op != OpARM64ADDconst || x0_1.AuxInt != 7 {
+               s := x0.Aux
+               _ = x0.Args[1]
+               p := x0.Args[0]
+               if mem != x0.Args[1] {
                        break
                }
-               idx := x0_1.Args[0]
                y1 := o5.Args[1]
                if y1.Op != OpARM64MOVDnop {
                        break
                }
                x1 := y1.Args[0]
-               if x1.Op != OpARM64MOVBUloadidx {
-                       break
-               }
-               _ = x1.Args[2]
-               if ptr != x1.Args[0] {
+               if x1.Op != OpARM64MOVBUload || x1.AuxInt != 6 || x1.Aux != s {
                        break
                }
-               x1_1 := x1.Args[1]
-               if x1_1.Op != OpARM64ADDconst || x1_1.AuxInt != 6 || idx != x1_1.Args[0] || mem != x1.Args[2] {
+               = x1.Args[1]
+               if p != x1.Args[0] || mem != x1.Args[1] {
                        break
                }
                y2 := o4.Args[1]
@@ -20228,15 +21485,11 @@ func rewriteValueARM64_OpARM64OR_30(v *Value) bool {
                        break
                }
                x2 := y2.Args[0]
-               if x2.Op != OpARM64MOVBUloadidx {
+               if x2.Op != OpARM64MOVBUload || x2.AuxInt != 5 || x2.Aux != s {
                        break
                }
-               _ = x2.Args[2]
-               if ptr != x2.Args[0] {
-                       break
-               }
-               x2_1 := x2.Args[1]
-               if x2_1.Op != OpARM64ADDconst || x2_1.AuxInt != 5 || idx != x2_1.Args[0] || mem != x2.Args[2] {
+               _ = x2.Args[1]
+               if p != x2.Args[0] || mem != x2.Args[1] {
                        break
                }
                y3 := o3.Args[1]
@@ -20244,15 +21497,11 @@ func rewriteValueARM64_OpARM64OR_30(v *Value) bool {
                        break
                }
                x3 := y3.Args[0]
-               if x3.Op != OpARM64MOVBUloadidx {
-                       break
-               }
-               _ = x3.Args[2]
-               if ptr != x3.Args[0] {
+               if x3.Op != OpARM64MOVBUload || x3.AuxInt != 4 || x3.Aux != s {
                        break
                }
-               x3_1 := x3.Args[1]
-               if x3_1.Op != OpARM64ADDconst || x3_1.AuxInt != 4 || idx != x3_1.Args[0] || mem != x3.Args[2] {
+               = x3.Args[1]
+               if p != x3.Args[0] || mem != x3.Args[1] {
                        break
                }
                y4 := o2.Args[1]
@@ -20260,15 +21509,11 @@ func rewriteValueARM64_OpARM64OR_30(v *Value) bool {
                        break
                }
                x4 := y4.Args[0]
-               if x4.Op != OpARM64MOVBUloadidx {
-                       break
-               }
-               _ = x4.Args[2]
-               if ptr != x4.Args[0] {
+               if x4.Op != OpARM64MOVBUload || x4.AuxInt != 3 || x4.Aux != s {
                        break
                }
-               x4_1 := x4.Args[1]
-               if x4_1.Op != OpARM64ADDconst || x4_1.AuxInt != 3 || idx != x4_1.Args[0] || mem != x4.Args[2] {
+               = x4.Args[1]
+               if p != x4.Args[0] || mem != x4.Args[1] {
                        break
                }
                y5 := o1.Args[1]
@@ -20276,15 +21521,11 @@ func rewriteValueARM64_OpARM64OR_30(v *Value) bool {
                        break
                }
                x5 := y5.Args[0]
-               if x5.Op != OpARM64MOVBUloadidx {
-                       break
-               }
-               _ = x5.Args[2]
-               if ptr != x5.Args[0] {
+               if x5.Op != OpARM64MOVBUload || x5.AuxInt != 2 || x5.Aux != s {
                        break
                }
-               x5_1 := x5.Args[1]
-               if x5_1.Op != OpARM64ADDconst || x5_1.AuxInt != 2 || idx != x5_1.Args[0] || mem != x5.Args[2] {
+               = x5.Args[1]
+               if p != x5.Args[0] || mem != x5.Args[1] {
                        break
                }
                y6 := o0.Args[1]
@@ -20292,41 +21533,31 @@ func rewriteValueARM64_OpARM64OR_30(v *Value) bool {
                        break
                }
                x6 := y6.Args[0]
-               if x6.Op != OpARM64MOVBUloadidx {
-                       break
-               }
-               _ = x6.Args[2]
-               if ptr != x6.Args[0] {
-                       break
-               }
-               x6_1 := x6.Args[1]
-               if x6_1.Op != OpARM64ADDconst || x6_1.AuxInt != 1 || idx != x6_1.Args[0] || mem != x6.Args[2] {
-                       break
-               }
-               y7 := v.Args[1]
-               if y7.Op != OpARM64MOVDnop {
+               if x6.Op != OpARM64MOVBUload || x6.AuxInt != 1 || x6.Aux != s {
                        break
                }
-               x7 := y7.Args[0]
-               if x7.Op != OpARM64MOVBUloadidx {
+               _ = x6.Args[1]
+               p1 := x6.Args[0]
+               if p1.Op != OpARM64ADD {
                        break
                }
-               _ = x7.Args[2]
-               if ptr != x7.Args[0] || idx != x7.Args[1] || mem != x7.Args[2] || !(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)) {
+               idx1 := p1.Args[1]
+               ptr1 := 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(v.Pos, OpARM64MOVDloadidx, t)
+               v0 := b.NewValue0(x6.Pos, OpARM64MOVDloadidx, t)
                v.reset(OpCopy)
                v.AddArg(v0)
-               v0.AddArg(ptr)
-               v0.AddArg(idx)
+               v0.AddArg(ptr0)
+               v0.AddArg(idx0)
                v0.AddArg(mem)
                return true
        }
-       // match: (OR <t> y7:(MOVDnop x7:(MOVBUloadidx ptr idx 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 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))))
-       // 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 <t> ptr idx mem)
+       // match: (OR <t> 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 <t> ptr0 idx0 mem)
        for {
                t := v.Type
                _ = v.Args[1]
@@ -20339,8 +21570,8 @@ func rewriteValueARM64_OpARM64OR_30(v *Value) bool {
                        break
                }
                mem := x7.Args[2]
-               ptr := x7.Args[0]
-               idx := x7.Args[1]
+               ptr0 := x7.Args[0]
+               idx0 := x7.Args[1]
                o0 := v.Args[1]
                if o0.Op != OpARM64ORshiftLL || o0.AuxInt != 8 {
                        break
@@ -20380,17 +21611,157 @@ func rewriteValueARM64_OpARM64OR_30(v *Value) bool {
                        break
                }
                x0 := y0.Args[0]
-               if x0.Op != OpARM64MOVBUloadidx {
+               if x0.Op != OpARM64MOVBUload || x0.AuxInt != 7 {
                        break
                }
-               _ = x0.Args[2]
-               if ptr != x0.Args[0] {
+               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 <t> 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 <t> ptr idx 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]
+               ptr := x0.Args[0]
                x0_1 := x0.Args[1]
-               if x0_1.Op != OpARM64ADDconst || x0_1.AuxInt != 7 || idx != x0_1.Args[0] || mem != x0.Args[2] {
+               if x0_1.Op != OpARM64ADDconst || x0_1.AuxInt != 7 {
                        break
                }
+               idx := x0_1.Args[0]
                y1 := o5.Args[1]
                if y1.Op != OpARM64MOVDnop {
                        break
@@ -20484,7 +21855,19 @@ func rewriteValueARM64_OpARM64OR_30(v *Value) bool {
                        break
                }
                x6_1 := x6.Args[1]
-               if x6_1.Op != OpARM64ADDconst || x6_1.AuxInt != 1 || idx != x6_1.Args[0] || mem != x6.Args[2] || !(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)) {
+               if x6_1.Op != OpARM64ADDconst || x6_1.AuxInt != 1 || idx != x6_1.Args[0] || mem != x6.Args[2] {
+                       break
+               }
+               y7 := v.Args[1]
+               if y7.Op != OpARM64MOVDnop {
+                       break
+               }
+               x7 := y7.Args[0]
+               if x7.Op != OpARM64MOVBUloadidx {
+                       break
+               }
+               _ = x7.Args[2]
+               if ptr != x7.Args[0] || idx != x7.Args[1] || mem != x7.Args[2] || !(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)) {
                        break
                }
                b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
@@ -20496,13 +21879,24 @@ func rewriteValueARM64_OpARM64OR_30(v *Value) bool {
                v0.AddArg(mem)
                return true
        }
-       // match: (OR <t> 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))) y3:(MOVDnop x3:(MOVBUload [i3] {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 <t> (MOVWUload <t> {s} (OffPtr <p.Type> [i0] p) mem))
+       // match: (OR <t> y7:(MOVDnop x7:(MOVBUloadidx ptr idx 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 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))))
+       // 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 <t> ptr idx mem)
        for {
                t := v.Type
                _ = v.Args[1]
-               o0 := v.Args[0]
+               y7 := v.Args[0]
+               if y7.Op != OpARM64MOVDnop {
+                       break
+               }
+               x7 := y7.Args[0]
+               if x7.Op != OpARM64MOVBUloadidx {
+                       break
+               }
+               mem := x7.Args[2]
+               ptr := x7.Args[0]
+               idx := x7.Args[1]
+               o0 := v.Args[1]
                if o0.Op != OpARM64ORshiftLL || o0.AuxInt != 8 {
                        break
                }
@@ -20512,13 +21906,174 @@ func rewriteValueARM64_OpARM64OR_30(v *Value) bool {
                        break
                }
                _ = o1.Args[1]
-               s0 := o1.Args[0]
-               if s0.Op != OpARM64SLLconst || s0.AuxInt != 24 {
+               o2 := o1.Args[0]
+               if o2.Op != OpARM64ORshiftLL || o2.AuxInt != 24 {
                        break
                }
-               y0 := s0.Args[0]
-               if y0.Op != OpARM64MOVDnop {
-                       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]
+               if ptr != x0.Args[0] {
+                       break
+               }
+               x0_1 := x0.Args[1]
+               if x0_1.Op != OpARM64ADDconst || x0_1.AuxInt != 7 || idx != x0_1.Args[0] || mem != x0.Args[2] {
+                       break
+               }
+               y1 := o5.Args[1]
+               if y1.Op != OpARM64MOVDnop {
+                       break
+               }
+               x1 := y1.Args[0]
+               if x1.Op != OpARM64MOVBUloadidx {
+                       break
+               }
+               _ = x1.Args[2]
+               if ptr != x1.Args[0] {
+                       break
+               }
+               x1_1 := x1.Args[1]
+               if x1_1.Op != OpARM64ADDconst || x1_1.AuxInt != 6 || idx != x1_1.Args[0] || mem != x1.Args[2] {
+                       break
+               }
+               y2 := o4.Args[1]
+               if y2.Op != OpARM64MOVDnop {
+                       break
+               }
+               x2 := y2.Args[0]
+               if x2.Op != OpARM64MOVBUloadidx {
+                       break
+               }
+               _ = x2.Args[2]
+               if ptr != x2.Args[0] {
+                       break
+               }
+               x2_1 := x2.Args[1]
+               if x2_1.Op != OpARM64ADDconst || x2_1.AuxInt != 5 || idx != x2_1.Args[0] || mem != x2.Args[2] {
+                       break
+               }
+               y3 := o3.Args[1]
+               if y3.Op != OpARM64MOVDnop {
+                       break
+               }
+               x3 := y3.Args[0]
+               if x3.Op != OpARM64MOVBUloadidx {
+                       break
+               }
+               _ = x3.Args[2]
+               if ptr != x3.Args[0] {
+                       break
+               }
+               x3_1 := x3.Args[1]
+               if x3_1.Op != OpARM64ADDconst || x3_1.AuxInt != 4 || idx != x3_1.Args[0] || mem != x3.Args[2] {
+                       break
+               }
+               y4 := o2.Args[1]
+               if y4.Op != OpARM64MOVDnop {
+                       break
+               }
+               x4 := y4.Args[0]
+               if x4.Op != OpARM64MOVBUloadidx {
+                       break
+               }
+               _ = x4.Args[2]
+               if ptr != x4.Args[0] {
+                       break
+               }
+               x4_1 := x4.Args[1]
+               if x4_1.Op != OpARM64ADDconst || x4_1.AuxInt != 3 || idx != x4_1.Args[0] || mem != x4.Args[2] {
+                       break
+               }
+               y5 := o1.Args[1]
+               if y5.Op != OpARM64MOVDnop {
+                       break
+               }
+               x5 := y5.Args[0]
+               if x5.Op != OpARM64MOVBUloadidx {
+                       break
+               }
+               _ = x5.Args[2]
+               if ptr != x5.Args[0] {
+                       break
+               }
+               x5_1 := x5.Args[1]
+               if x5_1.Op != OpARM64ADDconst || x5_1.AuxInt != 2 || idx != x5_1.Args[0] || mem != x5.Args[2] {
+                       break
+               }
+               y6 := o0.Args[1]
+               if y6.Op != OpARM64MOVDnop {
+                       break
+               }
+               x6 := y6.Args[0]
+               if x6.Op != OpARM64MOVBUloadidx {
+                       break
+               }
+               _ = x6.Args[2]
+               if ptr != x6.Args[0] {
+                       break
+               }
+               x6_1 := x6.Args[1]
+               if x6_1.Op != OpARM64ADDconst || x6_1.AuxInt != 1 || idx != x6_1.Args[0] || mem != x6.Args[2] || !(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)) {
+                       break
+               }
+               b = mergePoint(b, x0, x1, x2, x3, x4, x5, x6, x7)
+               v0 := b.NewValue0(v.Pos, OpARM64MOVDloadidx, t)
+               v.reset(OpCopy)
+               v.AddArg(v0)
+               v0.AddArg(ptr)
+               v0.AddArg(idx)
+               v0.AddArg(mem)
+               return true
+       }
+       // match: (OR <t> 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))) y3:(MOVDnop x3:(MOVBUload [i3] {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 <t> (MOVWUload <t> {s} (OffPtr <p.Type> [i0] p) 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 {
@@ -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 <t> 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 <t> (MOVWUload <t> {s} (OffPtr <p.Type> [i0] p) mem))
@@ -20770,24 +22329,13 @@ func rewriteValueARM64_OpARM64OR_30(v *Value) bool {
                v0.AddArg(v1)
                return true
        }
-       // match: (OR <t> 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))))
+       // match: (OR <t> 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 <t> (MOVWUloadidx <t> 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]
+               o0 := v.Args[0]
                if o0.Op != OpARM64ORshiftLL || o0.AuxInt != 8 {
                        break
                }
@@ -20809,27 +22357,25 @@ func rewriteValueARM64_OpARM64OR_30(v *Value) bool {
                if x0.Op != OpARM64MOVBUloadidx {
                        break
                }
-               = x0.Args[2]
+               mem := 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 {
+               if x1.Op != OpARM64MOVBUload || x1.AuxInt != 1 {
                        break
                }
+               s := x1.Aux
                _ = x1.Args[1]
                p1 := x1.Args[0]
                if p1.Op != OpARM64ADD {
                        break
                }
-               idx1 := p1.Args[1]
-               ptr1 := p1.Args[0]
+               ptr1 := p1.Args[1]
+               idx1 := p1.Args[0]
                if mem != x1.Args[1] {
                        break
                }
@@ -20842,27 +22388,51 @@ func rewriteValueARM64_OpARM64OR_30(v *Value) bool {
                        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)) {
+               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(x2.Pos, OpARM64REVW, t)
+               v0 := b.NewValue0(x3.Pos, OpARM64REVW, t)
                v.reset(OpCopy)
                v.AddArg(v0)
-               v1 := b.NewValue0(x2.Pos, OpARM64MOVWUloadidx, t)
+               v1 := b.NewValue0(x3.Pos, OpARM64MOVWUloadidx, t)
                v1.AddArg(ptr0)
                v1.AddArg(idx0)
                v1.AddArg(mem)
                v0.AddArg(v1)
                return true
        }
-       // match: (OR <t> 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 <t> (MOVWUloadidx <t> ptr idx mem))
+       // match: (OR <t> 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 <t> (MOVWUloadidx <t> ptr0 idx0 mem))
        for {
                t := v.Type
                _ = v.Args[1]
-               o0 := v.Args[0]
+               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
                }
@@ -20884,23 +22454,28 @@ func rewriteValueARM64_OpARM64OR_30(v *Value) bool {
                if x0.Op != OpARM64MOVBUloadidx {
                        break
                }
-               mem := x0.Args[2]
-               ptr := x0.Args[0]
-               idx := x0.Args[1]
+               _ = 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 != OpARM64MOVBUloadidx {
+               if x1.Op != OpARM64MOVBUload || x1.AuxInt != 1 || x1.Aux != s {
                        break
                }
-               _ = x1.Args[2]
-               if ptr != x1.Args[0] {
+               _ = x1.Args[1]
+               p1 := x1.Args[0]
+               if p1.Op != OpARM64ADD {
                        break
                }
-               x1_1 := x1.Args[1]
-               if x1_1.Op != OpARM64ADDconst || x1_1.AuxInt != 1 || idx != x1_1.Args[0] || mem != x1.Args[2] {
+               idx1 := p1.Args[1]
+               ptr1 := p1.Args[0]
+               if mem != x1.Args[1] {
                        break
                }
                y2 := o0.Args[1]
@@ -20908,12 +22483,168 @@ func rewriteValueARM64_OpARM64OR_30(v *Value) bool {
                        break
                }
                x2 := y2.Args[0]
-               if x2.Op != OpARM64MOVBUloadidx {
+               if x2.Op != OpARM64MOVBUload || x2.AuxInt != 2 || x2.Aux != s {
                        break
                }
-               _ = x2.Args[2]
-               if ptr != x2.Args[0] {
-                       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 <t> 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 <t> (MOVWUloadidx <t> 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 <t> 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 <t> (MOVWUloadidx <t> ptr idx 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]
+               ptr := x0.Args[0]
+               idx := x0.Args[1]
+               y1 := o1.Args[1]
+               if y1.Op != OpARM64MOVDnop {
+                       break
+               }
+               x1 := y1.Args[0]
+               if x1.Op != OpARM64MOVBUloadidx {
+                       break
+               }
+               _ = x1.Args[2]
+               if ptr != x1.Args[0] {
+                       break
+               }
+               x1_1 := x1.Args[1]
+               if x1_1.Op != OpARM64ADDconst || x1_1.AuxInt != 1 || idx != x1_1.Args[0] || mem != x1.Args[2] {
+                       break
+               }
+               y2 := o0.Args[1]
+               if y2.Op != OpARM64MOVDnop {
+                       break
+               }
+               x2 := y2.Args[0]
+               if x2.Op != OpARM64MOVBUloadidx {
+                       break
+               }
+               _ = x2.Args[2]
+               if ptr != x2.Args[0] {
+                       break
                }
                x2_1 := x2.Args[1]
                if x2_1.Op != OpARM64ADDconst || x2_1.AuxInt != 2 || idx != x2_1.Args[0] || mem != x2.Args[2] {
@@ -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 <t> 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 <t> (MOVWUloadidx <t> ptr idx mem))
@@ -20970,79 +22697,435 @@ func rewriteValueARM64_OpARM64OR_40(v *Value) bool {
                if x3_1.Op != OpARM64ADDconst || x3_1.AuxInt != 3 {
                        break
                }
-               idx := x3_1.Args[0]
-               o0 := v.Args[1]
-               if o0.Op != OpARM64ORshiftLL || o0.AuxInt != 8 {
+               idx := x3_1.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]
+               if ptr != x0.Args[0] || idx != x0.Args[1] || mem != x0.Args[2] {
+                       break
+               }
+               y1 := o1.Args[1]
+               if y1.Op != OpARM64MOVDnop {
+                       break
+               }
+               x1 := y1.Args[0]
+               if x1.Op != OpARM64MOVBUloadidx {
+                       break
+               }
+               _ = x1.Args[2]
+               if ptr != x1.Args[0] {
+                       break
+               }
+               x1_1 := x1.Args[1]
+               if x1_1.Op != OpARM64ADDconst || x1_1.AuxInt != 1 || idx != x1_1.Args[0] || mem != x1.Args[2] {
+                       break
+               }
+               y2 := o0.Args[1]
+               if y2.Op != OpARM64MOVDnop {
+                       break
+               }
+               x2 := y2.Args[0]
+               if x2.Op != OpARM64MOVBUloadidx {
+                       break
+               }
+               _ = x2.Args[2]
+               if ptr != x2.Args[0] {
+                       break
+               }
+               x2_1 := x2.Args[1]
+               if x2_1.Op != OpARM64ADDconst || x2_1.AuxInt != 2 || idx != x2_1.Args[0] || mem != x2.Args[2] || !(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)) {
+                       break
+               }
+               b = mergePoint(b, x0, x1, x2, x3)
+               v0 := b.NewValue0(v.Pos, OpARM64REVW, t)
+               v.reset(OpCopy)
+               v.AddArg(v0)
+               v1 := b.NewValue0(v.Pos, OpARM64MOVWUloadidx, t)
+               v1.AddArg(ptr)
+               v1.AddArg(idx)
+               v1.AddArg(mem)
+               v0.AddArg(v1)
+               return true
+       }
+       // match: (OR <t> 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 [i0] {s} p mem))) y1:(MOVDnop x1:(MOVBUload [i1] {s} p mem))) y2:(MOVDnop x2:(MOVBUload [i2] {s} p mem))) y3:(MOVDnop x3:(MOVBUload [i3] {s} p mem))) y4:(MOVDnop x4:(MOVBUload [i4] {s} p mem))) y5:(MOVDnop x5:(MOVBUload [i5] {s} p mem))) y6:(MOVDnop x6:(MOVBUload [i6] {s} p mem))) y7:(MOVDnop x7:(MOVBUload [i7] {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) (REV <t> (MOVDload <t> {s} (OffPtr <p.Type> [i0] p) 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 {
+                       break
+               }
+               i0 := x0.AuxInt
+               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 {
+                       break
+               }
+               i1 := x1.AuxInt
+               if 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 {
+                       break
+               }
+               i2 := x2.AuxInt
+               if 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 {
+                       break
+               }
+               i3 := x3.AuxInt
+               if 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 {
+                       break
+               }
+               i4 := x4.AuxInt
+               if 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 {
+                       break
+               }
+               i5 := x5.AuxInt
+               if 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 {
+                       break
+               }
+               i6 := x6.AuxInt
+               if 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 {
+                       break
+               }
+               i7 := x7.AuxInt
+               if x7.Aux != s {
+                       break
+               }
+               _ = x7.Args[1]
+               if p != x7.Args[0] || mem != x7.Args[1] || !(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)) {
+                       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, OpARM64MOVDload, t)
+               v1.Aux = s
+               v2 := b.NewValue0(x7.Pos, OpOffPtr, p.Type)
+               v2.AuxInt = i0
+               v2.AddArg(p)
+               v1.AddArg(v2)
+               v1.AddArg(mem)
+               v0.AddArg(v1)
+               return true
+       }
+       // match: (OR <t> y7:(MOVDnop x7:(MOVBUload [i7] {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 [i0] {s} p mem))) y1:(MOVDnop x1:(MOVBUload [i1] {s} p mem))) y2:(MOVDnop x2:(MOVBUload [i2] {s} p mem))) y3:(MOVDnop x3:(MOVBUload [i3] {s} p mem))) y4:(MOVDnop x4:(MOVBUload [i4] {s} p mem))) y5:(MOVDnop x5:(MOVBUload [i5] {s} p mem))) y6:(MOVDnop x6:(MOVBUload [i6] {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) (REV <t> (MOVDload <t> {s} (OffPtr <p.Type> [i0] p) 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 {
+                       break
+               }
+               i7 := x7.AuxInt
+               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 != OpARM64MOVBUload {
+                       break
+               }
+               i0 := x0.AuxInt
+               if x0.Aux != s {
+                       break
+               }
+               _ = x0.Args[1]
+               if p != x0.Args[0] || mem != x0.Args[1] {
+                       break
+               }
+               y1 := o5.Args[1]
+               if y1.Op != OpARM64MOVDnop {
+                       break
+               }
+               x1 := y1.Args[0]
+               if x1.Op != OpARM64MOVBUload {
+                       break
+               }
+               i1 := x1.AuxInt
+               if 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 {
+                       break
+               }
+               i2 := x2.AuxInt
+               if 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 {
                        break
                }
-               _ = o0.Args[1]
-               o1 := o0.Args[0]
-               if o1.Op != OpARM64ORshiftLL || o1.AuxInt != 16 {
+               i3 := x3.AuxInt
+               if x3.Aux != s {
                        break
                }
-               _ = o1.Args[1]
-               s0 := o1.Args[0]
-               if s0.Op != OpARM64SLLconst || s0.AuxInt != 24 {
+               _ = x3.Args[1]
+               if p != x3.Args[0] || mem != x3.Args[1] {
                        break
                }
-               y0 := s0.Args[0]
-               if y0.Op != OpARM64MOVDnop {
+               y4 := o2.Args[1]
+               if y4.Op != OpARM64MOVDnop {
                        break
                }
-               x0 := y0.Args[0]
-               if x0.Op != OpARM64MOVBUloadidx {
+               x4 := y4.Args[0]
+               if x4.Op != OpARM64MOVBUload {
                        break
                }
-               _ = x0.Args[2]
-               if ptr != x0.Args[0] || idx != x0.Args[1] || mem != x0.Args[2] {
+               i4 := x4.AuxInt
+               if x4.Aux != s {
                        break
                }
-               y1 := o1.Args[1]
-               if y1.Op != OpARM64MOVDnop {
+               _ = x4.Args[1]
+               if p != x4.Args[0] || mem != x4.Args[1] {
                        break
                }
-               x1 := y1.Args[0]
-               if x1.Op != OpARM64MOVBUloadidx {
+               y5 := o1.Args[1]
+               if y5.Op != OpARM64MOVDnop {
                        break
                }
-               _ = x1.Args[2]
-               if ptr != x1.Args[0] {
+               x5 := y5.Args[0]
+               if x5.Op != OpARM64MOVBUload {
                        break
                }
-               x1_1 := x1.Args[1]
-               if x1_1.Op != OpARM64ADDconst || x1_1.AuxInt != 1 || idx != x1_1.Args[0] || mem != x1.Args[2] {
+               i5 := x5.AuxInt
+               if x5.Aux != s {
                        break
                }
-               y2 := o0.Args[1]
-               if y2.Op != OpARM64MOVDnop {
+               _ = x5.Args[1]
+               if p != x5.Args[0] || mem != x5.Args[1] {
                        break
                }
-               x2 := y2.Args[0]
-               if x2.Op != OpARM64MOVBUloadidx {
+               y6 := o0.Args[1]
+               if y6.Op != OpARM64MOVDnop {
                        break
                }
-               _ = x2.Args[2]
-               if ptr != x2.Args[0] {
+               x6 := y6.Args[0]
+               if x6.Op != OpARM64MOVBUload {
                        break
                }
-               x2_1 := x2.Args[1]
-               if x2_1.Op != OpARM64ADDconst || x2_1.AuxInt != 2 || idx != x2_1.Args[0] || mem != x2.Args[2] || !(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)) {
+               i6 := x6.AuxInt
+               if x6.Aux != s {
                        break
                }
-               b = mergePoint(b, x0, x1, x2, x3)
-               v0 := b.NewValue0(v.Pos, OpARM64REVW, t)
+               _ = x6.Args[1]
+               if p != x6.Args[0] || mem != x6.Args[1] || !(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)) {
+                       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(v.Pos, OpARM64MOVWUloadidx, t)
-               v1.AddArg(ptr)
-               v1.AddArg(idx)
+               v1 := b.NewValue0(x6.Pos, OpARM64MOVDload, t)
+               v1.Aux = s
+               v2 := b.NewValue0(x6.Pos, OpOffPtr, p.Type)
+               v2.AuxInt = i0
+               v2.AddArg(p)
+               v1.AddArg(v2)
                v1.AddArg(mem)
                v0.AddArg(v1)
                return true
        }
-       // match: (OR <t> 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 [i0] {s} p mem))) y1:(MOVDnop x1:(MOVBUload [i1] {s} p mem))) y2:(MOVDnop x2:(MOVBUload [i2] {s} p mem))) y3:(MOVDnop x3:(MOVBUload [i3] {s} p mem))) y4:(MOVDnop x4:(MOVBUload [i4] {s} p mem))) y5:(MOVDnop x5:(MOVBUload [i5] {s} p mem))) y6:(MOVDnop x6:(MOVBUload [i6] {s} p mem))) y7:(MOVDnop x7:(MOVBUload [i7] {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) (REV <t> (MOVDload <t> {s} (OffPtr <p.Type> [i0] p) mem))
+       // match: (OR <t> 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))) 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 <t> (MOVDloadidx <t> ptr0 idx0 mem))
        for {
                t := v.Type
                _ = v.Args[1]
@@ -21085,27 +23168,29 @@ func rewriteValueARM64_OpARM64OR_40(v *Value) bool {
                        break
                }
                x0 := y0.Args[0]
-               if x0.Op != OpARM64MOVBUload {
+               if x0.Op != OpARM64MOVBUloadidx {
                        break
                }
-               i0 := x0.AuxInt
-               s := x0.Aux
-               mem := x0.Args[1]
-               p := x0.Args[0]
+               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 {
+               if x1.Op != OpARM64MOVBUload || x1.AuxInt != 1 {
                        break
                }
-               i1 := x1.AuxInt
-               if x1.Aux != s {
+               s := x1.Aux
+               _ = x1.Args[1]
+               p1 := x1.Args[0]
+               if p1.Op != OpARM64ADD {
                        break
                }
-               _ = x1.Args[1]
-               if p != x1.Args[0] || mem != x1.Args[1] {
+               idx1 := p1.Args[1]
+               ptr1 := p1.Args[0]
+               if mem != x1.Args[1] {
                        break
                }
                y2 := o4.Args[1]
@@ -21113,15 +23198,12 @@ func rewriteValueARM64_OpARM64OR_40(v *Value) bool {
                        break
                }
                x2 := y2.Args[0]
-               if x2.Op != OpARM64MOVBUload {
-                       break
-               }
-               i2 := x2.AuxInt
-               if x2.Aux != s {
+               if x2.Op != OpARM64MOVBUload || x2.AuxInt != 2 || x2.Aux != s {
                        break
                }
                _ = x2.Args[1]
-               if p != x2.Args[0] || mem != x2.Args[1] {
+               p := x2.Args[0]
+               if mem != x2.Args[1] {
                        break
                }
                y3 := o3.Args[1]
@@ -21129,11 +23211,7 @@ func rewriteValueARM64_OpARM64OR_40(v *Value) bool {
                        break
                }
                x3 := y3.Args[0]
-               if x3.Op != OpARM64MOVBUload {
-                       break
-               }
-               i3 := x3.AuxInt
-               if x3.Aux != s {
+               if x3.Op != OpARM64MOVBUload || x3.AuxInt != 3 || x3.Aux != s {
                        break
                }
                _ = x3.Args[1]
@@ -21145,11 +23223,7 @@ func rewriteValueARM64_OpARM64OR_40(v *Value) bool {
                        break
                }
                x4 := y4.Args[0]
-               if x4.Op != OpARM64MOVBUload {
-                       break
-               }
-               i4 := x4.AuxInt
-               if x4.Aux != s {
+               if x4.Op != OpARM64MOVBUload || x4.AuxInt != 4 || x4.Aux != s {
                        break
                }
                _ = x4.Args[1]
@@ -21161,11 +23235,7 @@ func rewriteValueARM64_OpARM64OR_40(v *Value) bool {
                        break
                }
                x5 := y5.Args[0]
-               if x5.Op != OpARM64MOVBUload {
-                       break
-               }
-               i5 := x5.AuxInt
-               if x5.Aux != s {
+               if x5.Op != OpARM64MOVBUload || x5.AuxInt != 5 || x5.Aux != s {
                        break
                }
                _ = x5.Args[1]
@@ -21177,11 +23247,7 @@ func rewriteValueARM64_OpARM64OR_40(v *Value) bool {
                        break
                }
                x6 := y6.Args[0]
-               if x6.Op != OpARM64MOVBUload {
-                       break
-               }
-               i6 := x6.AuxInt
-               if x6.Aux != s {
+               if x6.Op != OpARM64MOVBUload || x6.AuxInt != 6 || x6.Aux != s {
                        break
                }
                _ = x6.Args[1]
@@ -21193,50 +23259,35 @@ func rewriteValueARM64_OpARM64OR_40(v *Value) bool {
                        break
                }
                x7 := y7.Args[0]
-               if x7.Op != OpARM64MOVBUload {
-                       break
-               }
-               i7 := x7.AuxInt
-               if x7.Aux != s {
+               if x7.Op != OpARM64MOVBUload || x7.AuxInt != 7 || x7.Aux != s {
                        break
                }
                _ = x7.Args[1]
-               if p != x7.Args[0] || mem != x7.Args[1] || !(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)) {
+               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, OpARM64MOVDload, t)
-               v1.Aux = s
-               v2 := b.NewValue0(x7.Pos, OpOffPtr, p.Type)
-               v2.AuxInt = i0
-               v2.AddArg(p)
-               v1.AddArg(v2)
+               v1 := b.NewValue0(x7.Pos, OpARM64MOVDloadidx, t)
+               v1.AddArg(ptr0)
+               v1.AddArg(idx0)
                v1.AddArg(mem)
                v0.AddArg(v1)
                return true
        }
-       // match: (OR <t> y7:(MOVDnop x7:(MOVBUload [i7] {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 [i0] {s} p mem))) y1:(MOVDnop x1:(MOVBUload [i1] {s} p mem))) y2:(MOVDnop x2:(MOVBUload [i2] {s} p mem))) y3:(MOVDnop x3:(MOVBUload [i3] {s} p mem))) y4:(MOVDnop x4:(MOVBUload [i4] {s} p mem))) y5:(MOVDnop x5:(MOVBUload [i5] {s} p mem))) y6:(MOVDnop x6:(MOVBUload [i6] {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) (REV <t> (MOVDload <t> {s} (OffPtr <p.Type> [i0] p) mem))
+       return false
+}
+func rewriteValueARM64_OpARM64OR_50(v *Value) bool {
+       b := v.Block
+       // match: (OR <t> 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 <t> (MOVDloadidx <t> 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 {
-                       break
-               }
-               i7 := x7.AuxInt
-               s := x7.Aux
-               mem := x7.Args[1]
-               p := x7.Args[0]
-               o0 := v.Args[1]
+               o0 := v.Args[0]
                if o0.Op != OpARM64ORshiftLL || o0.AuxInt != 8 {
                        break
                }
@@ -21275,31 +23326,29 @@ func rewriteValueARM64_OpARM64OR_40(v *Value) bool {
                        break
                }
                x0 := y0.Args[0]
-               if x0.Op != OpARM64MOVBUload {
-                       break
-               }
-               i0 := x0.AuxInt
-               if x0.Aux != s {
-                       break
-               }
-               _ = x0.Args[1]
-               if p != x0.Args[0] || mem != x0.Args[1] {
+               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 {
+               if x1.Op != OpARM64MOVBUload || x1.AuxInt != 1 {
                        break
                }
-               i1 := x1.AuxInt
-               if x1.Aux != s {
+               s := x1.Aux
+               _ = x1.Args[1]
+               p1 := x1.Args[0]
+               if p1.Op != OpARM64ADD {
                        break
                }
-               _ = x1.Args[1]
-               if p != x1.Args[0] || mem != x1.Args[1] {
+               ptr1 := p1.Args[1]
+               idx1 := p1.Args[0]
+               if mem != x1.Args[1] {
                        break
                }
                y2 := o4.Args[1]
@@ -21307,15 +23356,12 @@ func rewriteValueARM64_OpARM64OR_40(v *Value) bool {
                        break
                }
                x2 := y2.Args[0]
-               if x2.Op != OpARM64MOVBUload {
-                       break
-               }
-               i2 := x2.AuxInt
-               if x2.Aux != s {
+               if x2.Op != OpARM64MOVBUload || x2.AuxInt != 2 || x2.Aux != s {
                        break
                }
                _ = x2.Args[1]
-               if p != x2.Args[0] || mem != x2.Args[1] {
+               p := x2.Args[0]
+               if mem != x2.Args[1] {
                        break
                }
                y3 := o3.Args[1]
@@ -21323,11 +23369,7 @@ func rewriteValueARM64_OpARM64OR_40(v *Value) bool {
                        break
                }
                x3 := y3.Args[0]
-               if x3.Op != OpARM64MOVBUload {
-                       break
-               }
-               i3 := x3.AuxInt
-               if x3.Aux != s {
+               if x3.Op != OpARM64MOVBUload || x3.AuxInt != 3 || x3.Aux != s {
                        break
                }
                _ = x3.Args[1]
@@ -21339,11 +23381,7 @@ func rewriteValueARM64_OpARM64OR_40(v *Value) bool {
                        break
                }
                x4 := y4.Args[0]
-               if x4.Op != OpARM64MOVBUload {
-                       break
-               }
-               i4 := x4.AuxInt
-               if x4.Aux != s {
+               if x4.Op != OpARM64MOVBUload || x4.AuxInt != 4 || x4.Aux != s {
                        break
                }
                _ = x4.Args[1]
@@ -21355,11 +23393,7 @@ func rewriteValueARM64_OpARM64OR_40(v *Value) bool {
                        break
                }
                x5 := y5.Args[0]
-               if x5.Op != OpARM64MOVBUload {
-                       break
-               }
-               i5 := x5.AuxInt
-               if x5.Aux != s {
+               if x5.Op != OpARM64MOVBUload || x5.AuxInt != 5 || x5.Aux != s {
                        break
                }
                _ = x5.Args[1]
@@ -21371,38 +23405,54 @@ func rewriteValueARM64_OpARM64OR_40(v *Value) bool {
                        break
                }
                x6 := y6.Args[0]
-               if x6.Op != OpARM64MOVBUload {
+               if x6.Op != OpARM64MOVBUload || x6.AuxInt != 6 || x6.Aux != s {
                        break
                }
-               i6 := x6.AuxInt
-               if x6.Aux != s {
+               _ = x6.Args[1]
+               if p != x6.Args[0] || mem != x6.Args[1] {
                        break
                }
-               _ = x6.Args[1]
-               if p != x6.Args[0] || mem != x6.Args[1] || !(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)) {
+               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(x6.Pos, OpARM64REV, t)
+               v0 := b.NewValue0(x7.Pos, OpARM64REV, t)
                v.reset(OpCopy)
                v.AddArg(v0)
-               v1 := b.NewValue0(x6.Pos, OpARM64MOVDload, t)
-               v1.Aux = s
-               v2 := b.NewValue0(x6.Pos, OpOffPtr, p.Type)
-               v2.AuxInt = i0
-               v2.AddArg(p)
-               v1.AddArg(v2)
+               v1 := b.NewValue0(x7.Pos, OpARM64MOVDloadidx, t)
+               v1.AddArg(ptr0)
+               v1.AddArg(idx0)
                v1.AddArg(mem)
                v0.AddArg(v1)
                return true
        }
-       // match: (OR <t> 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))) y7:(MOVDnop x7:(MOVBUload [7] {s} p mem)))
+       // match: (OR <t> 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 <t> (MOVDloadidx <t> ptr0 idx0 mem))
        for {
                t := v.Type
                _ = v.Args[1]
-               o0 := v.Args[0]
+               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
                }
@@ -21444,18 +23494,20 @@ func rewriteValueARM64_OpARM64OR_40(v *Value) bool {
                if x0.Op != OpARM64MOVBUloadidx {
                        break
                }
-               mem := x0.Args[2]
+               = 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 {
+               if x1.Op != OpARM64MOVBUload || x1.AuxInt != 1 || x1.Aux != s {
                        break
                }
-               s := x1.Aux
                _ = x1.Args[1]
                p1 := x1.Args[0]
                if p1.Op != OpARM64ADD {
@@ -21475,8 +23527,7 @@ func rewriteValueARM64_OpARM64OR_40(v *Value) bool {
                        break
                }
                _ = x2.Args[1]
-               p := x2.Args[0]
-               if mem != x2.Args[1] {
+               if p != x2.Args[0] || mem != x2.Args[1] {
                        break
                }
                y3 := o3.Args[1]
@@ -21524,33 +23575,21 @@ func rewriteValueARM64_OpARM64OR_40(v *Value) bool {
                        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)) {
+               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(x7.Pos, OpARM64REV, t)
+               v0 := b.NewValue0(x6.Pos, OpARM64REV, t)
                v.reset(OpCopy)
                v.AddArg(v0)
-               v1 := b.NewValue0(x7.Pos, OpARM64MOVDloadidx, t)
+               v1 := b.NewValue0(x6.Pos, OpARM64MOVDloadidx, t)
                v1.AddArg(ptr0)
                v1.AddArg(idx0)
                v1.AddArg(mem)
                v0.AddArg(v1)
                return true
        }
-       // match: (OR <t> 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))))
+       // match: (OR <t> 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 <t> (MOVDloadidx <t> ptr0 idx0 mem))
        for {
@@ -21628,8 +23667,8 @@ func rewriteValueARM64_OpARM64OR_40(v *Value) bool {
                if p1.Op != OpARM64ADD {
                        break
                }
-               idx1 := p1.Args[1]
-               ptr1 := p1.Args[0]
+               ptr1 := p1.Args[1]
+               idx1 := p1.Args[0]
                if mem != x1.Args[1] {
                        break
                }
@@ -22603,6 +24642,54 @@ func rewriteValueARM64_OpARM64ORshiftLL_10(v *Value) bool {
                v0.AddArg(mem)
                return true
        }
+       // match: (ORshiftLL <t> [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 <t> 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 <t> [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 <t> ptr idx mem)
@@ -22776,6 +24863,68 @@ func rewriteValueARM64_OpARM64ORshiftLL_10(v *Value) bool {
                v0.AddArg(mem)
                return true
        }
+       // match: (ORshiftLL <t> [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 <t> 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 <t> [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 <t> ptr idx mem)
@@ -22959,12 +25108,119 @@ func rewriteValueARM64_OpARM64ORshiftLL_10(v *Value) bool {
                if x2.Op != OpARM64MOVBUload {
                        break
                }
-               i5 := x2.AuxInt
-               if x2.Aux != s {
+               i5 := x2.AuxInt
+               if 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 {
+                       break
+               }
+               i6 := x3.AuxInt
+               if 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 {
+                       break
+               }
+               i7 := x4.AuxInt
+               if x4.Aux != s {
+                       break
+               }
+               _ = x4.Args[1]
+               if p != x4.Args[0] || mem != x4.Args[1] || !(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 && 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(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, OpARM64MOVDload, t)
+               v.reset(OpCopy)
+               v.AddArg(v0)
+               v0.Aux = s
+               v1 := b.NewValue0(x4.Pos, OpOffPtr, p.Type)
+               v1.AuxInt = i0
+               v1.AddArg(p)
+               v0.AddArg(v1)
+               v0.AddArg(mem)
+               return true
+       }
+       // match: (ORshiftLL <t> [56] o0:(ORshiftLL [48] o1:(ORshiftLL [40] o2:(ORshiftLL [32] x0:(MOVWUloadidx ptr0 idx0 mem) y1:(MOVDnop x1:(MOVBUload [4] {s} p1:(ADD 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(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 <t> 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
+               }
+               idx1 := p1.Args[1]
+               ptr1 := 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]
-               if p != x2.Args[0] || mem != x2.Args[1] {
+               p := x2.Args[0]
+               if mem != x2.Args[1] {
                        break
                }
                y3 := o0.Args[1]
@@ -22972,11 +25228,7 @@ func rewriteValueARM64_OpARM64ORshiftLL_10(v *Value) bool {
                        break
                }
                x3 := y3.Args[0]
-               if x3.Op != OpARM64MOVBUload {
-                       break
-               }
-               i6 := x3.AuxInt
-               if x3.Aux != s {
+               if x3.Op != OpARM64MOVBUload || x3.AuxInt != 6 || x3.Aux != s {
                        break
                }
                _ = x3.Args[1]
@@ -22988,30 +25240,27 @@ func rewriteValueARM64_OpARM64ORshiftLL_10(v *Value) bool {
                        break
                }
                x4 := y4.Args[0]
-               if x4.Op != OpARM64MOVBUload {
-                       break
-               }
-               i7 := x4.AuxInt
-               if x4.Aux != s {
+               if x4.Op != OpARM64MOVBUload || x4.AuxInt != 7 || x4.Aux != s {
                        break
                }
                _ = x4.Args[1]
-               if p != x4.Args[0] || mem != x4.Args[1] || !(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 && 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(y1) && clobber(y2) && clobber(y3) && clobber(y4) && clobber(o0) && clobber(o1) && clobber(o2)) {
+               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, OpARM64MOVDload, t)
+               v0 := b.NewValue0(x4.Pos, OpARM64MOVDloadidx, t)
                v.reset(OpCopy)
                v.AddArg(v0)
-               v0.Aux = s
-               v1 := b.NewValue0(x4.Pos, OpOffPtr, p.Type)
-               v1.AuxInt = i0
-               v1.AddArg(p)
-               v0.AddArg(v1)
+               v0.AddArg(ptr0)
+               v0.AddArg(idx0)
                v0.AddArg(mem)
                return true
        }
-       // match: (ORshiftLL <t> [56] o0:(ORshiftLL [48] o1:(ORshiftLL [40] o2:(ORshiftLL [32] x0:(MOVWUloadidx ptr0 idx0 mem) y1:(MOVDnop x1:(MOVBUload [4] {s} p1:(ADD 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)))
+       return false
+}
+func rewriteValueARM64_OpARM64ORshiftLL_20(v *Value) bool {
+       b := v.Block
+       // match: (ORshiftLL <t> [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 <t> ptr0 idx0 mem)
        for {
@@ -23056,8 +25305,8 @@ func rewriteValueARM64_OpARM64ORshiftLL_10(v *Value) bool {
                if p1.Op != OpARM64ADD {
                        break
                }
-               idx1 := p1.Args[1]
-               ptr1 := p1.Args[0]
+               ptr1 := p1.Args[1]
+               idx1 := p1.Args[0]
                if mem != x1.Args[1] {
                        break
                }
@@ -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 <t> [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 <t> (MOVHUload <t> [i0] {s} p mem))
@@ -23413,6 +25658,56 @@ func rewriteValueARM64_OpARM64ORshiftLL_20(v *Value) bool {
                v0.AddArg(v1)
                return true
        }
+       // match: (ORshiftLL <t> [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 <t> (MOVHUloadidx <t> 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 <t> [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 <t> (MOVHUloadidx <t> ptr idx mem))
@@ -23600,6 +25895,78 @@ func rewriteValueARM64_OpARM64ORshiftLL_20(v *Value) bool {
                v0.AddArg(v1)
                return true
        }
+       // match: (ORshiftLL <t> [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 <t> (MOVWUloadidx <t> 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 <t> [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 <t> (MOVWUloadidx <t> ptr idx mem))
@@ -23884,6 +26251,108 @@ func rewriteValueARM64_OpARM64ORshiftLL_20(v *Value) bool {
                v0.AddArg(v1)
                return true
        }
+       // match: (ORshiftLL <t> [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 <t> (MOVDloadidx <t> 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 <t> [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 <t> (MOVDloadidx <t> ptr idx mem))
index 2a9e0aa8b59db161678836837af4ce99054f3038..a8641ce1a4b1cc17a79d9ea83cc6b47b5e0ddee7 100644 (file)
@@ -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 {
index e93b3f6b956eeb3ce584869f0665123f7a58d9d5..e7c8120ea0562d8e57e001cbd2b428fa07b964c2 100644 (file)
@@ -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)