]> Cypherpunks.ru repositories - gostls13.git/commitdiff
cmd/compile: enable address folding for globals on ARM64, just not -dynlink mode
authorCherry Mui <cherryyz@google.com>
Tue, 7 Mar 2023 20:32:30 +0000 (15:32 -0500)
committerCherry Mui <cherryyz@google.com>
Tue, 7 Mar 2023 21:29:30 +0000 (21:29 +0000)
On ARM64, in -dynlink mode (building a shared library or a plugin),
accessing global variable is made using the GOT. Currently, the
GOT accessing instruction sequence our assembler generates doesn't
handle large offset well, so we don't fold the offset into loads
and stores in the compiler. Currently, the rewrite rules are
guarded with the -shared flag. However, the GOT access
instructions are only generated in the -dynlink mode (which
implies -shared, but not the other direction).

CL 445535 attempted to remove the guard althgether. But that
causes build failure for -dynlink mode for the reason above. This
CL changes it to guard specifically on -dynlink mode, allowing
the optimization in more cases (-shared but not -dynlink build
modes).

Updates #58826.

Change-Id: I1391db6a33e8d0455a304e7cae7fcfdeb49bfdab
Reviewed-on: https://go-review.googlesource.com/c/go/+/473999
Run-TryBot: Cherry Mui <cherryyz@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>

src/cmd/compile/internal/ssa/_gen/ARM64.rules
src/cmd/compile/internal/ssa/rewriteARM64.go
test/fixedbugs/issue58826.go [new file with mode: 0644]

index 53d4129906e0cd22ac9f4f321ddef733368ee7d8..a896e7c8bd7491511d2107f501fd9fe24612f515 100644 (file)
 (ADDconst [off1] (MOVDaddr [off2] {sym} ptr)) && is32Bit(off1+int64(off2)) =>
         (MOVDaddr [int32(off1)+off2] {sym} ptr)
 
-// fold address into load/store
+// fold address into load/store.
+// Do not fold global variable access in -dynlink mode, where it will
+// be rewritten to use the GOT via REGTMP, which currently cannot handle
+// large offset.
 (MOVBload [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2)
-       && (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
+       && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) =>
        (MOVBload [off1+int32(off2)] {sym} ptr mem)
 (MOVBUload [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2)
-       && (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
+       && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) =>
        (MOVBUload [off1+int32(off2)] {sym} ptr mem)
 (MOVHload [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2)
-       && (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
+       && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) =>
        (MOVHload [off1+int32(off2)] {sym} ptr mem)
 (MOVHUload [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2)
-       && (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
+       && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) =>
        (MOVHUload [off1+int32(off2)] {sym} ptr mem)
 (MOVWload [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2)
-       && (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
+       && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) =>
        (MOVWload [off1+int32(off2)] {sym} ptr mem)
 (MOVWUload [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2)
-       && (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
+       && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) =>
        (MOVWUload [off1+int32(off2)] {sym} ptr mem)
 (MOVDload [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2)
-       && (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
+       && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) =>
        (MOVDload [off1+int32(off2)] {sym} ptr mem)
 (LDP [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2)
-       && (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
+       && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) =>
        (LDP [off1+int32(off2)] {sym} ptr mem)
 (FMOVSload [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2)
-       && (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
+       && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) =>
        (FMOVSload [off1+int32(off2)] {sym} ptr mem)
 (FMOVDload [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2)
-       && (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
+       && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) =>
        (FMOVDload [off1+int32(off2)] {sym} ptr mem)
 
 // register indexed load
 (FMOVSloadidx4 ptr (MOVDconst [c]) mem) && is32Bit(c<<2) => (FMOVSload ptr [int32(c)<<2] mem)
 
 (MOVBstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2)
-       && (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
+       && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) =>
        (MOVBstore [off1+int32(off2)] {sym} ptr val mem)
 (MOVHstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2)
-       && (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
+       && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) =>
        (MOVHstore [off1+int32(off2)] {sym} ptr val mem)
 (MOVWstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2)
-       && (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
+       && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) =>
        (MOVWstore [off1+int32(off2)] {sym} ptr val mem)
 (MOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2)
-       && (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
+       && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) =>
        (MOVDstore [off1+int32(off2)] {sym} ptr val mem)
 (STP [off1] {sym} (ADDconst [off2] ptr) val1 val2 mem) && is32Bit(int64(off1)+off2)
-       && (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
+       && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) =>
        (STP [off1+int32(off2)] {sym} ptr val1 val2 mem)
 (FMOVSstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2)
-       && (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
+       && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) =>
        (FMOVSstore [off1+int32(off2)] {sym} ptr val mem)
 (FMOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2)
-       && (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
+       && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) =>
        (FMOVDstore [off1+int32(off2)] {sym} ptr val mem)
 (MOVBstorezero [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2)
-       && (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
+       && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) =>
        (MOVBstorezero [off1+int32(off2)] {sym} ptr mem)
 (MOVHstorezero [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2)
-       && (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
+       && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) =>
        (MOVHstorezero [off1+int32(off2)] {sym} ptr mem)
 (MOVWstorezero [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2)
-       && (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
+       && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) =>
        (MOVWstorezero [off1+int32(off2)] {sym} ptr mem)
 (MOVDstorezero [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2)
-       && (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
+       && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) =>
        (MOVDstorezero [off1+int32(off2)] {sym} ptr mem)
 (MOVQstorezero [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2)
-       && (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
+       && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) =>
        (MOVQstorezero [off1+int32(off2)] {sym} ptr mem)
 
 // register indexed store
 
 (MOVBload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
        && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
-       && (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
+       && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) =>
        (MOVBload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
 (MOVBUload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
        && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
-       && (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
+       && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) =>
        (MOVBUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
 (MOVHload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
        && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
-       && (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
+       && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) =>
        (MOVHload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
 (MOVHUload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
        && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
-       && (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
+       && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) =>
        (MOVHUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
 (MOVWload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
        && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
-       && (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
+       && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) =>
        (MOVWload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
 (MOVWUload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
        && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
-       && (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
+       && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) =>
        (MOVWUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
 (MOVDload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
        && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
-       && (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
+       && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) =>
        (MOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
 (LDP [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
        && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
-       && (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
+       && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) =>
        (LDP [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
 (FMOVSload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
        && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
-       && (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
+       && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) =>
        (FMOVSload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
 (FMOVDload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
        && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
-       && (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
+       && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) =>
        (FMOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
 
 (MOVBstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
        && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
-       && (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
+       && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) =>
        (MOVBstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
 (MOVHstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
        && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
-       && (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
+       && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) =>
        (MOVHstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
 (MOVWstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
        && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
-       && (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
+       && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) =>
        (MOVWstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
 (MOVDstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
        && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
-       && (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
+       && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) =>
        (MOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
 (STP [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val1 val2 mem)
        && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
-       && (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
+       && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) =>
        (STP [off1+off2] {mergeSym(sym1,sym2)} ptr val1 val2 mem)
 (FMOVSstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
        && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
-       && (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
+       && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) =>
        (FMOVSstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
 (FMOVDstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
        && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
-       && (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
+       && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) =>
        (FMOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
 (MOVBstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
        && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
-       && (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
+       && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) =>
        (MOVBstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
 (MOVHstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
        && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
-       && (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
+       && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) =>
        (MOVHstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
 (MOVWstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
        && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
-       && (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
+       && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) =>
        (MOVWstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
 (MOVDstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
        && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
-       && (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
+       && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) =>
        (MOVDstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
 (MOVQstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
        && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
-       && (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
+       && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink) =>
        (MOVQstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
 
 // store zero
index 0deb9b1510269f76d6f27aeccf950824efa27040..f84d7b3c198eb8abb9cb44bb01c345313ce0d9c6 100644 (file)
@@ -4557,7 +4557,7 @@ func rewriteValueARM64_OpARM64FMOVDload(v *Value) bool {
                return true
        }
        // match: (FMOVDload [off1] {sym} (ADDconst [off2] ptr) mem)
-       // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+       // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
        // result: (FMOVDload [off1+int32(off2)] {sym} ptr mem)
        for {
                off1 := auxIntToInt32(v.AuxInt)
@@ -4568,7 +4568,7 @@ func rewriteValueARM64_OpARM64FMOVDload(v *Value) bool {
                off2 := auxIntToInt64(v_0.AuxInt)
                ptr := v_0.Args[0]
                mem := v_1
-               if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+               if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
                        break
                }
                v.reset(OpARM64FMOVDload)
@@ -4616,7 +4616,7 @@ func rewriteValueARM64_OpARM64FMOVDload(v *Value) bool {
                return true
        }
        // match: (FMOVDload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
-       // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+       // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
        // result: (FMOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
        for {
                off1 := auxIntToInt32(v.AuxInt)
@@ -4628,7 +4628,7 @@ func rewriteValueARM64_OpARM64FMOVDload(v *Value) bool {
                sym2 := auxToSym(v_0.Aux)
                ptr := v_0.Args[0]
                mem := v_1
-               if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+               if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
                        break
                }
                v.reset(OpARM64FMOVDload)
@@ -4755,7 +4755,7 @@ func rewriteValueARM64_OpARM64FMOVDstore(v *Value) bool {
                return true
        }
        // match: (FMOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem)
-       // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+       // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
        // result: (FMOVDstore [off1+int32(off2)] {sym} ptr val mem)
        for {
                off1 := auxIntToInt32(v.AuxInt)
@@ -4767,7 +4767,7 @@ func rewriteValueARM64_OpARM64FMOVDstore(v *Value) bool {
                ptr := v_0.Args[0]
                val := v_1
                mem := v_2
-               if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+               if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
                        break
                }
                v.reset(OpARM64FMOVDstore)
@@ -4817,7 +4817,7 @@ func rewriteValueARM64_OpARM64FMOVDstore(v *Value) bool {
                return true
        }
        // match: (FMOVDstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
-       // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+       // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
        // result: (FMOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
        for {
                off1 := auxIntToInt32(v.AuxInt)
@@ -4830,7 +4830,7 @@ func rewriteValueARM64_OpARM64FMOVDstore(v *Value) bool {
                ptr := v_0.Args[0]
                val := v_1
                mem := v_2
-               if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+               if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
                        break
                }
                v.reset(OpARM64FMOVDstore)
@@ -4963,7 +4963,7 @@ func rewriteValueARM64_OpARM64FMOVSload(v *Value) bool {
                return true
        }
        // match: (FMOVSload [off1] {sym} (ADDconst [off2] ptr) mem)
-       // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+       // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
        // result: (FMOVSload [off1+int32(off2)] {sym} ptr mem)
        for {
                off1 := auxIntToInt32(v.AuxInt)
@@ -4974,7 +4974,7 @@ func rewriteValueARM64_OpARM64FMOVSload(v *Value) bool {
                off2 := auxIntToInt64(v_0.AuxInt)
                ptr := v_0.Args[0]
                mem := v_1
-               if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+               if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
                        break
                }
                v.reset(OpARM64FMOVSload)
@@ -5022,7 +5022,7 @@ func rewriteValueARM64_OpARM64FMOVSload(v *Value) bool {
                return true
        }
        // match: (FMOVSload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
-       // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+       // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
        // result: (FMOVSload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
        for {
                off1 := auxIntToInt32(v.AuxInt)
@@ -5034,7 +5034,7 @@ func rewriteValueARM64_OpARM64FMOVSload(v *Value) bool {
                sym2 := auxToSym(v_0.Aux)
                ptr := v_0.Args[0]
                mem := v_1
-               if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+               if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
                        break
                }
                v.reset(OpARM64FMOVSload)
@@ -5161,7 +5161,7 @@ func rewriteValueARM64_OpARM64FMOVSstore(v *Value) bool {
                return true
        }
        // match: (FMOVSstore [off1] {sym} (ADDconst [off2] ptr) val mem)
-       // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+       // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
        // result: (FMOVSstore [off1+int32(off2)] {sym} ptr val mem)
        for {
                off1 := auxIntToInt32(v.AuxInt)
@@ -5173,7 +5173,7 @@ func rewriteValueARM64_OpARM64FMOVSstore(v *Value) bool {
                ptr := v_0.Args[0]
                val := v_1
                mem := v_2
-               if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+               if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
                        break
                }
                v.reset(OpARM64FMOVSstore)
@@ -5223,7 +5223,7 @@ func rewriteValueARM64_OpARM64FMOVSstore(v *Value) bool {
                return true
        }
        // match: (FMOVSstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
-       // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+       // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
        // result: (FMOVSstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
        for {
                off1 := auxIntToInt32(v.AuxInt)
@@ -5236,7 +5236,7 @@ func rewriteValueARM64_OpARM64FMOVSstore(v *Value) bool {
                ptr := v_0.Args[0]
                val := v_1
                mem := v_2
-               if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+               if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
                        break
                }
                v.reset(OpARM64FMOVSstore)
@@ -5950,7 +5950,7 @@ func rewriteValueARM64_OpARM64LDP(v *Value) bool {
        b := v.Block
        config := b.Func.Config
        // match: (LDP [off1] {sym} (ADDconst [off2] ptr) mem)
-       // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+       // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
        // result: (LDP [off1+int32(off2)] {sym} ptr mem)
        for {
                off1 := auxIntToInt32(v.AuxInt)
@@ -5961,7 +5961,7 @@ func rewriteValueARM64_OpARM64LDP(v *Value) bool {
                off2 := auxIntToInt64(v_0.AuxInt)
                ptr := v_0.Args[0]
                mem := v_1
-               if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+               if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
                        break
                }
                v.reset(OpARM64LDP)
@@ -5971,7 +5971,7 @@ func rewriteValueARM64_OpARM64LDP(v *Value) bool {
                return true
        }
        // match: (LDP [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
-       // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+       // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
        // result: (LDP [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
        for {
                off1 := auxIntToInt32(v.AuxInt)
@@ -5983,7 +5983,7 @@ func rewriteValueARM64_OpARM64LDP(v *Value) bool {
                sym2 := auxToSym(v_0.Aux)
                ptr := v_0.Args[0]
                mem := v_1
-               if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+               if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
                        break
                }
                v.reset(OpARM64LDP)
@@ -7653,7 +7653,7 @@ func rewriteValueARM64_OpARM64MOVBUload(v *Value) bool {
        b := v.Block
        config := b.Func.Config
        // match: (MOVBUload [off1] {sym} (ADDconst [off2] ptr) mem)
-       // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+       // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
        // result: (MOVBUload [off1+int32(off2)] {sym} ptr mem)
        for {
                off1 := auxIntToInt32(v.AuxInt)
@@ -7664,7 +7664,7 @@ func rewriteValueARM64_OpARM64MOVBUload(v *Value) bool {
                off2 := auxIntToInt64(v_0.AuxInt)
                ptr := v_0.Args[0]
                mem := v_1
-               if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+               if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
                        break
                }
                v.reset(OpARM64MOVBUload)
@@ -7693,7 +7693,7 @@ func rewriteValueARM64_OpARM64MOVBUload(v *Value) bool {
                return true
        }
        // match: (MOVBUload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
-       // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+       // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
        // result: (MOVBUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
        for {
                off1 := auxIntToInt32(v.AuxInt)
@@ -7705,7 +7705,7 @@ func rewriteValueARM64_OpARM64MOVBUload(v *Value) bool {
                sym2 := auxToSym(v_0.Aux)
                ptr := v_0.Args[0]
                mem := v_1
-               if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+               if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
                        break
                }
                v.reset(OpARM64MOVBUload)
@@ -8096,7 +8096,7 @@ func rewriteValueARM64_OpARM64MOVBload(v *Value) bool {
        b := v.Block
        config := b.Func.Config
        // match: (MOVBload [off1] {sym} (ADDconst [off2] ptr) mem)
-       // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+       // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
        // result: (MOVBload [off1+int32(off2)] {sym} ptr mem)
        for {
                off1 := auxIntToInt32(v.AuxInt)
@@ -8107,7 +8107,7 @@ func rewriteValueARM64_OpARM64MOVBload(v *Value) bool {
                off2 := auxIntToInt64(v_0.AuxInt)
                ptr := v_0.Args[0]
                mem := v_1
-               if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+               if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
                        break
                }
                v.reset(OpARM64MOVBload)
@@ -8136,7 +8136,7 @@ func rewriteValueARM64_OpARM64MOVBload(v *Value) bool {
                return true
        }
        // match: (MOVBload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
-       // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+       // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
        // result: (MOVBload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
        for {
                off1 := auxIntToInt32(v.AuxInt)
@@ -8148,7 +8148,7 @@ func rewriteValueARM64_OpARM64MOVBload(v *Value) bool {
                sym2 := auxToSym(v_0.Aux)
                ptr := v_0.Args[0]
                mem := v_1
-               if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+               if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
                        break
                }
                v.reset(OpARM64MOVBload)
@@ -8347,7 +8347,7 @@ func rewriteValueARM64_OpARM64MOVBstore(v *Value) bool {
        b := v.Block
        config := b.Func.Config
        // match: (MOVBstore [off1] {sym} (ADDconst [off2] ptr) val mem)
-       // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+       // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
        // result: (MOVBstore [off1+int32(off2)] {sym} ptr val mem)
        for {
                off1 := auxIntToInt32(v.AuxInt)
@@ -8359,7 +8359,7 @@ func rewriteValueARM64_OpARM64MOVBstore(v *Value) bool {
                ptr := v_0.Args[0]
                val := v_1
                mem := v_2
-               if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+               if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
                        break
                }
                v.reset(OpARM64MOVBstore)
@@ -8389,7 +8389,7 @@ func rewriteValueARM64_OpARM64MOVBstore(v *Value) bool {
                return true
        }
        // match: (MOVBstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
-       // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+       // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
        // result: (MOVBstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
        for {
                off1 := auxIntToInt32(v.AuxInt)
@@ -8402,7 +8402,7 @@ func rewriteValueARM64_OpARM64MOVBstore(v *Value) bool {
                ptr := v_0.Args[0]
                val := v_1
                mem := v_2
-               if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+               if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
                        break
                }
                v.reset(OpARM64MOVBstore)
@@ -10200,7 +10200,7 @@ func rewriteValueARM64_OpARM64MOVBstorezero(v *Value) bool {
        b := v.Block
        config := b.Func.Config
        // match: (MOVBstorezero [off1] {sym} (ADDconst [off2] ptr) mem)
-       // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+       // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
        // result: (MOVBstorezero [off1+int32(off2)] {sym} ptr mem)
        for {
                off1 := auxIntToInt32(v.AuxInt)
@@ -10211,7 +10211,7 @@ func rewriteValueARM64_OpARM64MOVBstorezero(v *Value) bool {
                off2 := auxIntToInt64(v_0.AuxInt)
                ptr := v_0.Args[0]
                mem := v_1
-               if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+               if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
                        break
                }
                v.reset(OpARM64MOVBstorezero)
@@ -10221,7 +10221,7 @@ func rewriteValueARM64_OpARM64MOVBstorezero(v *Value) bool {
                return true
        }
        // match: (MOVBstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
-       // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+       // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
        // result: (MOVBstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
        for {
                off1 := auxIntToInt32(v.AuxInt)
@@ -10233,7 +10233,7 @@ func rewriteValueARM64_OpARM64MOVBstorezero(v *Value) bool {
                sym2 := auxToSym(v_0.Aux)
                ptr := v_0.Args[0]
                mem := v_1
-               if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+               if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
                        break
                }
                v.reset(OpARM64MOVBstorezero)
@@ -10408,7 +10408,7 @@ func rewriteValueARM64_OpARM64MOVDload(v *Value) bool {
                return true
        }
        // match: (MOVDload [off1] {sym} (ADDconst [off2] ptr) mem)
-       // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+       // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
        // result: (MOVDload [off1+int32(off2)] {sym} ptr mem)
        for {
                off1 := auxIntToInt32(v.AuxInt)
@@ -10419,7 +10419,7 @@ func rewriteValueARM64_OpARM64MOVDload(v *Value) bool {
                off2 := auxIntToInt64(v_0.AuxInt)
                ptr := v_0.Args[0]
                mem := v_1
-               if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+               if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
                        break
                }
                v.reset(OpARM64MOVDload)
@@ -10467,7 +10467,7 @@ func rewriteValueARM64_OpARM64MOVDload(v *Value) bool {
                return true
        }
        // match: (MOVDload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
-       // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+       // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
        // result: (MOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
        for {
                off1 := auxIntToInt32(v.AuxInt)
@@ -10479,7 +10479,7 @@ func rewriteValueARM64_OpARM64MOVDload(v *Value) bool {
                sym2 := auxToSym(v_0.Aux)
                ptr := v_0.Args[0]
                mem := v_1
-               if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+               if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
                        break
                }
                v.reset(OpARM64MOVDload)
@@ -10717,7 +10717,7 @@ func rewriteValueARM64_OpARM64MOVDstore(v *Value) bool {
                return true
        }
        // match: (MOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem)
-       // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+       // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
        // result: (MOVDstore [off1+int32(off2)] {sym} ptr val mem)
        for {
                off1 := auxIntToInt32(v.AuxInt)
@@ -10729,7 +10729,7 @@ func rewriteValueARM64_OpARM64MOVDstore(v *Value) bool {
                ptr := v_0.Args[0]
                val := v_1
                mem := v_2
-               if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+               if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
                        break
                }
                v.reset(OpARM64MOVDstore)
@@ -10779,7 +10779,7 @@ func rewriteValueARM64_OpARM64MOVDstore(v *Value) bool {
                return true
        }
        // match: (MOVDstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
-       // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+       // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
        // result: (MOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
        for {
                off1 := auxIntToInt32(v.AuxInt)
@@ -10792,7 +10792,7 @@ func rewriteValueARM64_OpARM64MOVDstore(v *Value) bool {
                ptr := v_0.Args[0]
                val := v_1
                mem := v_2
-               if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+               if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
                        break
                }
                v.reset(OpARM64MOVDstore)
@@ -10950,7 +10950,7 @@ func rewriteValueARM64_OpARM64MOVDstorezero(v *Value) bool {
        b := v.Block
        config := b.Func.Config
        // match: (MOVDstorezero [off1] {sym} (ADDconst [off2] ptr) mem)
-       // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+       // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
        // result: (MOVDstorezero [off1+int32(off2)] {sym} ptr mem)
        for {
                off1 := auxIntToInt32(v.AuxInt)
@@ -10961,7 +10961,7 @@ func rewriteValueARM64_OpARM64MOVDstorezero(v *Value) bool {
                off2 := auxIntToInt64(v_0.AuxInt)
                ptr := v_0.Args[0]
                mem := v_1
-               if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+               if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
                        break
                }
                v.reset(OpARM64MOVDstorezero)
@@ -10971,7 +10971,7 @@ func rewriteValueARM64_OpARM64MOVDstorezero(v *Value) bool {
                return true
        }
        // match: (MOVDstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
-       // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+       // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
        // result: (MOVDstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
        for {
                off1 := auxIntToInt32(v.AuxInt)
@@ -10983,7 +10983,7 @@ func rewriteValueARM64_OpARM64MOVDstorezero(v *Value) bool {
                sym2 := auxToSym(v_0.Aux)
                ptr := v_0.Args[0]
                mem := v_1
-               if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+               if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
                        break
                }
                v.reset(OpARM64MOVDstorezero)
@@ -11222,7 +11222,7 @@ func rewriteValueARM64_OpARM64MOVHUload(v *Value) bool {
        b := v.Block
        config := b.Func.Config
        // match: (MOVHUload [off1] {sym} (ADDconst [off2] ptr) mem)
-       // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+       // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
        // result: (MOVHUload [off1+int32(off2)] {sym} ptr mem)
        for {
                off1 := auxIntToInt32(v.AuxInt)
@@ -11233,7 +11233,7 @@ func rewriteValueARM64_OpARM64MOVHUload(v *Value) bool {
                off2 := auxIntToInt64(v_0.AuxInt)
                ptr := v_0.Args[0]
                mem := v_1
-               if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+               if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
                        break
                }
                v.reset(OpARM64MOVHUload)
@@ -11281,7 +11281,7 @@ func rewriteValueARM64_OpARM64MOVHUload(v *Value) bool {
                return true
        }
        // match: (MOVHUload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
-       // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+       // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
        // result: (MOVHUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
        for {
                off1 := auxIntToInt32(v.AuxInt)
@@ -11293,7 +11293,7 @@ func rewriteValueARM64_OpARM64MOVHUload(v *Value) bool {
                sym2 := auxToSym(v_0.Aux)
                ptr := v_0.Args[0]
                mem := v_1
-               if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+               if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
                        break
                }
                v.reset(OpARM64MOVHUload)
@@ -11661,7 +11661,7 @@ func rewriteValueARM64_OpARM64MOVHload(v *Value) bool {
        b := v.Block
        config := b.Func.Config
        // match: (MOVHload [off1] {sym} (ADDconst [off2] ptr) mem)
-       // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+       // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
        // result: (MOVHload [off1+int32(off2)] {sym} ptr mem)
        for {
                off1 := auxIntToInt32(v.AuxInt)
@@ -11672,7 +11672,7 @@ func rewriteValueARM64_OpARM64MOVHload(v *Value) bool {
                off2 := auxIntToInt64(v_0.AuxInt)
                ptr := v_0.Args[0]
                mem := v_1
-               if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+               if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
                        break
                }
                v.reset(OpARM64MOVHload)
@@ -11720,7 +11720,7 @@ func rewriteValueARM64_OpARM64MOVHload(v *Value) bool {
                return true
        }
        // match: (MOVHload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
-       // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+       // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
        // result: (MOVHload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
        for {
                off1 := auxIntToInt32(v.AuxInt)
@@ -11732,7 +11732,7 @@ func rewriteValueARM64_OpARM64MOVHload(v *Value) bool {
                sym2 := auxToSym(v_0.Aux)
                ptr := v_0.Args[0]
                mem := v_1
-               if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+               if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
                        break
                }
                v.reset(OpARM64MOVHload)
@@ -12095,7 +12095,7 @@ func rewriteValueARM64_OpARM64MOVHstore(v *Value) bool {
        b := v.Block
        config := b.Func.Config
        // match: (MOVHstore [off1] {sym} (ADDconst [off2] ptr) val mem)
-       // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+       // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
        // result: (MOVHstore [off1+int32(off2)] {sym} ptr val mem)
        for {
                off1 := auxIntToInt32(v.AuxInt)
@@ -12107,7 +12107,7 @@ func rewriteValueARM64_OpARM64MOVHstore(v *Value) bool {
                ptr := v_0.Args[0]
                val := v_1
                mem := v_2
-               if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+               if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
                        break
                }
                v.reset(OpARM64MOVHstore)
@@ -12157,7 +12157,7 @@ func rewriteValueARM64_OpARM64MOVHstore(v *Value) bool {
                return true
        }
        // match: (MOVHstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
-       // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+       // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
        // result: (MOVHstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
        for {
                off1 := auxIntToInt32(v.AuxInt)
@@ -12170,7 +12170,7 @@ func rewriteValueARM64_OpARM64MOVHstore(v *Value) bool {
                ptr := v_0.Args[0]
                val := v_1
                mem := v_2
-               if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+               if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
                        break
                }
                v.reset(OpARM64MOVHstore)
@@ -12973,7 +12973,7 @@ func rewriteValueARM64_OpARM64MOVHstorezero(v *Value) bool {
        b := v.Block
        config := b.Func.Config
        // match: (MOVHstorezero [off1] {sym} (ADDconst [off2] ptr) mem)
-       // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+       // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
        // result: (MOVHstorezero [off1+int32(off2)] {sym} ptr mem)
        for {
                off1 := auxIntToInt32(v.AuxInt)
@@ -12984,7 +12984,7 @@ func rewriteValueARM64_OpARM64MOVHstorezero(v *Value) bool {
                off2 := auxIntToInt64(v_0.AuxInt)
                ptr := v_0.Args[0]
                mem := v_1
-               if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+               if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
                        break
                }
                v.reset(OpARM64MOVHstorezero)
@@ -12994,7 +12994,7 @@ func rewriteValueARM64_OpARM64MOVHstorezero(v *Value) bool {
                return true
        }
        // match: (MOVHstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
-       // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+       // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
        // result: (MOVHstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
        for {
                off1 := auxIntToInt32(v.AuxInt)
@@ -13006,7 +13006,7 @@ func rewriteValueARM64_OpARM64MOVHstorezero(v *Value) bool {
                sym2 := auxToSym(v_0.Aux)
                ptr := v_0.Args[0]
                mem := v_1
-               if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+               if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
                        break
                }
                v.reset(OpARM64MOVHstorezero)
@@ -13295,7 +13295,7 @@ func rewriteValueARM64_OpARM64MOVQstorezero(v *Value) bool {
        b := v.Block
        config := b.Func.Config
        // match: (MOVQstorezero [off1] {sym} (ADDconst [off2] ptr) mem)
-       // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+       // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
        // result: (MOVQstorezero [off1+int32(off2)] {sym} ptr mem)
        for {
                off1 := auxIntToInt32(v.AuxInt)
@@ -13306,7 +13306,7 @@ func rewriteValueARM64_OpARM64MOVQstorezero(v *Value) bool {
                off2 := auxIntToInt64(v_0.AuxInt)
                ptr := v_0.Args[0]
                mem := v_1
-               if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+               if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
                        break
                }
                v.reset(OpARM64MOVQstorezero)
@@ -13316,7 +13316,7 @@ func rewriteValueARM64_OpARM64MOVQstorezero(v *Value) bool {
                return true
        }
        // match: (MOVQstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
-       // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+       // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
        // result: (MOVQstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
        for {
                off1 := auxIntToInt32(v.AuxInt)
@@ -13328,7 +13328,7 @@ func rewriteValueARM64_OpARM64MOVQstorezero(v *Value) bool {
                sym2 := auxToSym(v_0.Aux)
                ptr := v_0.Args[0]
                mem := v_1
-               if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+               if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
                        break
                }
                v.reset(OpARM64MOVQstorezero)
@@ -13362,7 +13362,7 @@ func rewriteValueARM64_OpARM64MOVWUload(v *Value) bool {
                return true
        }
        // match: (MOVWUload [off1] {sym} (ADDconst [off2] ptr) mem)
-       // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+       // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
        // result: (MOVWUload [off1+int32(off2)] {sym} ptr mem)
        for {
                off1 := auxIntToInt32(v.AuxInt)
@@ -13373,7 +13373,7 @@ func rewriteValueARM64_OpARM64MOVWUload(v *Value) bool {
                off2 := auxIntToInt64(v_0.AuxInt)
                ptr := v_0.Args[0]
                mem := v_1
-               if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+               if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
                        break
                }
                v.reset(OpARM64MOVWUload)
@@ -13421,7 +13421,7 @@ func rewriteValueARM64_OpARM64MOVWUload(v *Value) bool {
                return true
        }
        // match: (MOVWUload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
-       // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+       // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
        // result: (MOVWUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
        for {
                off1 := auxIntToInt32(v.AuxInt)
@@ -13433,7 +13433,7 @@ func rewriteValueARM64_OpARM64MOVWUload(v *Value) bool {
                sym2 := auxToSym(v_0.Aux)
                ptr := v_0.Args[0]
                mem := v_1
-               if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+               if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
                        break
                }
                v.reset(OpARM64MOVWUload)
@@ -13837,7 +13837,7 @@ func rewriteValueARM64_OpARM64MOVWload(v *Value) bool {
        b := v.Block
        config := b.Func.Config
        // match: (MOVWload [off1] {sym} (ADDconst [off2] ptr) mem)
-       // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+       // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
        // result: (MOVWload [off1+int32(off2)] {sym} ptr mem)
        for {
                off1 := auxIntToInt32(v.AuxInt)
@@ -13848,7 +13848,7 @@ func rewriteValueARM64_OpARM64MOVWload(v *Value) bool {
                off2 := auxIntToInt64(v_0.AuxInt)
                ptr := v_0.Args[0]
                mem := v_1
-               if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+               if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
                        break
                }
                v.reset(OpARM64MOVWload)
@@ -13896,7 +13896,7 @@ func rewriteValueARM64_OpARM64MOVWload(v *Value) bool {
                return true
        }
        // match: (MOVWload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
-       // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+       // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
        // result: (MOVWload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
        for {
                off1 := auxIntToInt32(v.AuxInt)
@@ -13908,7 +13908,7 @@ func rewriteValueARM64_OpARM64MOVWload(v *Value) bool {
                sym2 := auxToSym(v_0.Aux)
                ptr := v_0.Args[0]
                mem := v_1
-               if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+               if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
                        break
                }
                v.reset(OpARM64MOVWload)
@@ -14346,7 +14346,7 @@ func rewriteValueARM64_OpARM64MOVWstore(v *Value) bool {
                return true
        }
        // match: (MOVWstore [off1] {sym} (ADDconst [off2] ptr) val mem)
-       // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+       // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
        // result: (MOVWstore [off1+int32(off2)] {sym} ptr val mem)
        for {
                off1 := auxIntToInt32(v.AuxInt)
@@ -14358,7 +14358,7 @@ func rewriteValueARM64_OpARM64MOVWstore(v *Value) bool {
                ptr := v_0.Args[0]
                val := v_1
                mem := v_2
-               if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+               if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
                        break
                }
                v.reset(OpARM64MOVWstore)
@@ -14408,7 +14408,7 @@ func rewriteValueARM64_OpARM64MOVWstore(v *Value) bool {
                return true
        }
        // match: (MOVWstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
-       // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+       // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
        // result: (MOVWstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
        for {
                off1 := auxIntToInt32(v.AuxInt)
@@ -14421,7 +14421,7 @@ func rewriteValueARM64_OpARM64MOVWstore(v *Value) bool {
                ptr := v_0.Args[0]
                val := v_1
                mem := v_2
-               if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+               if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
                        break
                }
                v.reset(OpARM64MOVWstore)
@@ -14894,7 +14894,7 @@ func rewriteValueARM64_OpARM64MOVWstorezero(v *Value) bool {
        b := v.Block
        config := b.Func.Config
        // match: (MOVWstorezero [off1] {sym} (ADDconst [off2] ptr) mem)
-       // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+       // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
        // result: (MOVWstorezero [off1+int32(off2)] {sym} ptr mem)
        for {
                off1 := auxIntToInt32(v.AuxInt)
@@ -14905,7 +14905,7 @@ func rewriteValueARM64_OpARM64MOVWstorezero(v *Value) bool {
                off2 := auxIntToInt64(v_0.AuxInt)
                ptr := v_0.Args[0]
                mem := v_1
-               if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+               if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
                        break
                }
                v.reset(OpARM64MOVWstorezero)
@@ -14915,7 +14915,7 @@ func rewriteValueARM64_OpARM64MOVWstorezero(v *Value) bool {
                return true
        }
        // match: (MOVWstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
-       // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+       // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
        // result: (MOVWstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
        for {
                off1 := auxIntToInt32(v.AuxInt)
@@ -14927,7 +14927,7 @@ func rewriteValueARM64_OpARM64MOVWstorezero(v *Value) bool {
                sym2 := auxToSym(v_0.Aux)
                ptr := v_0.Args[0]
                mem := v_1
-               if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+               if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
                        break
                }
                v.reset(OpARM64MOVWstorezero)
@@ -21792,7 +21792,7 @@ func rewriteValueARM64_OpARM64STP(v *Value) bool {
        b := v.Block
        config := b.Func.Config
        // match: (STP [off1] {sym} (ADDconst [off2] ptr) val1 val2 mem)
-       // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+       // cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
        // result: (STP [off1+int32(off2)] {sym} ptr val1 val2 mem)
        for {
                off1 := auxIntToInt32(v.AuxInt)
@@ -21805,7 +21805,7 @@ func rewriteValueARM64_OpARM64STP(v *Value) bool {
                val1 := v_1
                val2 := v_2
                mem := v_3
-               if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+               if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
                        break
                }
                v.reset(OpARM64STP)
@@ -21815,7 +21815,7 @@ func rewriteValueARM64_OpARM64STP(v *Value) bool {
                return true
        }
        // match: (STP [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val1 val2 mem)
-       // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+       // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)
        // result: (STP [off1+off2] {mergeSym(sym1,sym2)} ptr val1 val2 mem)
        for {
                off1 := auxIntToInt32(v.AuxInt)
@@ -21829,7 +21829,7 @@ func rewriteValueARM64_OpARM64STP(v *Value) bool {
                val1 := v_1
                val2 := v_2
                mem := v_3
-               if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+               if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_dynlink)) {
                        break
                }
                v.reset(OpARM64STP)
diff --git a/test/fixedbugs/issue58826.go b/test/fixedbugs/issue58826.go
new file mode 100644 (file)
index 0000000..de92002
--- /dev/null
@@ -0,0 +1,23 @@
+// compile -dynlink
+
+//go:build 386 || amd64 || arm || arm64 || ppc64le || s390x
+// (platforms that support -dynlink flag)
+
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 58826: assembler cannot handle global access with large
+// offset in -dynlink mode on ARM64.
+
+package p
+
+var x [2197]uint8
+
+func F() {
+       for _, i := range x {
+               G(i)
+       }
+}
+
+func G(uint8)