From b675a75c3d7c221d8f5734203e25bd690a9a1f83 Mon Sep 17 00:00:00 2001 From: Cherry Mui Date: Tue, 7 Mar 2023 15:32:30 -0500 Subject: [PATCH] cmd/compile: enable address folding for globals on ARM64, just not -dynlink mode 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 Reviewed-by: Keith Randall Reviewed-by: Keith Randall TryBot-Result: Gopher Robot --- src/cmd/compile/internal/ssa/_gen/ARM64.rules | 93 ++++----- src/cmd/compile/internal/ssa/rewriteARM64.go | 176 +++++++++--------- test/fixedbugs/issue58826.go | 23 +++ 3 files changed, 159 insertions(+), 133 deletions(-) create mode 100644 test/fixedbugs/issue58826.go diff --git a/src/cmd/compile/internal/ssa/_gen/ARM64.rules b/src/cmd/compile/internal/ssa/_gen/ARM64.rules index 53d4129906..a896e7c8bd 100644 --- a/src/cmd/compile/internal/ssa/_gen/ARM64.rules +++ b/src/cmd/compile/internal/ssa/_gen/ARM64.rules @@ -837,36 +837,39 @@ (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 @@ -932,40 +935,40 @@ (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 @@ -1015,92 +1018,92 @@ (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 diff --git a/src/cmd/compile/internal/ssa/rewriteARM64.go b/src/cmd/compile/internal/ssa/rewriteARM64.go index 0deb9b1510..f84d7b3c19 100644 --- a/src/cmd/compile/internal/ssa/rewriteARM64.go +++ b/src/cmd/compile/internal/ssa/rewriteARM64.go @@ -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 index 0000000000..de92002ed7 --- /dev/null +++ b/test/fixedbugs/issue58826.go @@ -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) -- 2.50.0