From: Cherry Zhang Date: Sun, 19 Feb 2017 02:03:15 +0000 (-0500) Subject: [release-branch.go1.8] cmd/compile: do not fold offset into load/store for args on... X-Git-Tag: go1.8.1~30 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=2327d696c12155c6b94b3e1e74cbf059d2e07f37;p=gostls13.git [release-branch.go1.8] cmd/compile: do not fold offset into load/store for args on ARM64 Args may be not at 8-byte aligned offset to SP. When the stack frame is large, folding the offset of args may cause large unaligned offsets that does not fit in a machine instruction on ARM64. Therefore disable folding offsets for args. This has small performance impact (see below). A better fix would be letting the assembler backend fix up the offset by loading it into a register if it doesn't fit into an instruction. And the compiler can simply generate large load/stores with offset. Since in most of the cases the offset is aligned or the stack frame is small, it can fit in an instruction and no fixup is needed. But this is too complicated for Go 1.8. name old time/op new time/op delta BinaryTree17-8 8.30s ± 0% 8.31s ± 0% ~ (p=0.579 n=10+10) Fannkuch11-8 6.14s ± 0% 6.18s ± 0% +0.53% (p=0.000 n=9+10) FmtFprintfEmpty-8 117ns ± 0% 117ns ± 0% ~ (all equal) FmtFprintfString-8 196ns ± 0% 197ns ± 0% +0.72% (p=0.000 n=10+10) FmtFprintfInt-8 204ns ± 0% 205ns ± 0% +0.49% (p=0.000 n=9+10) FmtFprintfIntInt-8 302ns ± 0% 307ns ± 1% +1.46% (p=0.000 n=10+10) FmtFprintfPrefixedInt-8 329ns ± 2% 326ns ± 0% ~ (p=0.083 n=10+10) FmtFprintfFloat-8 540ns ± 0% 542ns ± 0% +0.46% (p=0.000 n=8+7) FmtManyArgs-8 1.20µs ± 1% 1.19µs ± 1% -1.02% (p=0.000 n=10+10) GobDecode-8 17.3ms ± 1% 17.8ms ± 0% +2.75% (p=0.000 n=10+7) GobEncode-8 15.3ms ± 1% 15.4ms ± 0% +0.57% (p=0.004 n=9+10) Gzip-8 789ms ± 0% 803ms ± 0% +1.78% (p=0.000 n=9+10) Gunzip-8 128ms ± 0% 130ms ± 0% +1.73% (p=0.000 n=10+9) HTTPClientServer-8 202µs ± 6% 201µs ±10% ~ (p=0.739 n=10+10) JSONEncode-8 42.0ms ± 0% 42.1ms ± 0% +0.19% (p=0.028 n=10+9) JSONDecode-8 159ms ± 0% 161ms ± 0% +1.05% (p=0.000 n=9+10) Mandelbrot200-8 10.1ms ± 0% 10.1ms ± 0% -0.07% (p=0.000 n=10+9) GoParse-8 8.46ms ± 1% 8.61ms ± 1% +1.77% (p=0.000 n=10+10) RegexpMatchEasy0_32-8 227ns ± 1% 226ns ± 0% -0.35% (p=0.001 n=10+9) RegexpMatchEasy0_1K-8 1.63µs ± 0% 1.63µs ± 0% -0.13% (p=0.000 n=10+9) RegexpMatchEasy1_32-8 250ns ± 0% 249ns ± 0% -0.40% (p=0.001 n=8+9) RegexpMatchEasy1_1K-8 2.07µs ± 0% 2.08µs ± 0% +0.05% (p=0.027 n=9+9) RegexpMatchMedium_32-8 350ns ± 0% 350ns ± 0% ~ (p=0.412 n=9+8) RegexpMatchMedium_1K-8 104µs ± 0% 104µs ± 0% +0.31% (p=0.000 n=10+7) RegexpMatchHard_32-8 5.82µs ± 0% 5.82µs ± 0% ~ (p=0.937 n=9+9) RegexpMatchHard_1K-8 176µs ± 0% 176µs ± 0% +0.03% (p=0.000 n=9+8) Revcomp-8 1.36s ± 1% 1.37s ± 1% ~ (p=0.218 n=10+10) Template-8 151ms ± 1% 156ms ± 1% +3.21% (p=0.000 n=10+10) TimeParse-8 737ns ± 0% 758ns ± 2% +2.74% (p=0.000 n=10+10) TimeFormat-8 801ns ± 2% 789ns ± 1% -1.51% (p=0.000 n=10+10) [Geo mean] 142µs 143µs +0.50% Fixes #19137. Change-Id: Ib8a21ea98c0ffb2d282a586535b213cc163e1b67 Reviewed-on: https://go-review.googlesource.com/37251 Run-TryBot: Cherry Zhang TryBot-Result: Gobot Gobot Reviewed-by: David Chase (cherry picked from commit 6464e5dc4b84a4348e6698f97c5bfc462a0e3a5e) Reviewed-on: https://go-review.googlesource.com/37719 Reviewed-by: Brad Fitzpatrick --- diff --git a/src/cmd/compile/internal/ssa/gen/ARM64.rules b/src/cmd/compile/internal/ssa/gen/ARM64.rules index 530d9fde8a..bc58a1f5f5 100644 --- a/src/cmd/compile/internal/ssa/gen/ARM64.rules +++ b/src/cmd/compile/internal/ssa/gen/ARM64.rules @@ -534,69 +534,69 @@ (MOVBUload [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(off1+off2) -> (MOVBUload [off1+off2] {sym} ptr mem) (MOVHload [off1] {sym} (ADDconst [off2] ptr) mem) - && is32Bit(off1+off2) - && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)) -> + && is32Bit(off1+off2) && !isArg(sym) + && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym)) -> (MOVHload [off1+off2] {sym} ptr mem) (MOVHUload [off1] {sym} (ADDconst [off2] ptr) mem) - && is32Bit(off1+off2) - && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)) -> + && is32Bit(off1+off2) && !isArg(sym) + && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym)) -> (MOVHUload [off1+off2] {sym} ptr mem) (MOVWload [off1] {sym} (ADDconst [off2] ptr) mem) - && is32Bit(off1+off2) - && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)) -> + && is32Bit(off1+off2) && !isArg(sym) + && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym)) -> (MOVWload [off1+off2] {sym} ptr mem) (MOVWUload [off1] {sym} (ADDconst [off2] ptr) mem) - && is32Bit(off1+off2) - && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)) -> + && is32Bit(off1+off2) && !isArg(sym) + && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym)) -> (MOVWUload [off1+off2] {sym} ptr mem) (MOVDload [off1] {sym} (ADDconst [off2] ptr) mem) - && is32Bit(off1+off2) - && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)) -> + && is32Bit(off1+off2) && !isArg(sym) + && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym)) -> (MOVDload [off1+off2] {sym} ptr mem) (FMOVSload [off1] {sym} (ADDconst [off2] ptr) mem) - && is32Bit(off1+off2) - && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)) -> + && is32Bit(off1+off2) && !isArg(sym) + && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym)) -> (FMOVSload [off1+off2] {sym} ptr mem) (FMOVDload [off1] {sym} (ADDconst [off2] ptr) mem) - && is32Bit(off1+off2) - && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)) -> + && is32Bit(off1+off2) && !isArg(sym) + && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym)) -> (FMOVDload [off1+off2] {sym} ptr mem) (MOVBstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is32Bit(off1+off2) -> (MOVBstore [off1+off2] {sym} ptr val mem) (MOVHstore [off1] {sym} (ADDconst [off2] ptr) val mem) - && is32Bit(off1+off2) - && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)) -> + && is32Bit(off1+off2) && !isArg(sym) + && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym)) -> (MOVHstore [off1+off2] {sym} ptr val mem) (MOVWstore [off1] {sym} (ADDconst [off2] ptr) val mem) - && is32Bit(off1+off2) - && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)) -> + && is32Bit(off1+off2) && !isArg(sym) + && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym)) -> (MOVWstore [off1+off2] {sym} ptr val mem) (MOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem) - && is32Bit(off1+off2) - && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)) -> + && is32Bit(off1+off2) && !isArg(sym) + && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym)) -> (MOVDstore [off1+off2] {sym} ptr val mem) (FMOVSstore [off1] {sym} (ADDconst [off2] ptr) val mem) - && is32Bit(off1+off2) - && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)) -> + && is32Bit(off1+off2) && !isArg(sym) + && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym)) -> (FMOVSstore [off1+off2] {sym} ptr val mem) (FMOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem) - && is32Bit(off1+off2) - && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)) -> + && is32Bit(off1+off2) && !isArg(sym) + && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym)) -> (FMOVDstore [off1+off2] {sym} ptr val mem) (MOVBstorezero [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(off1+off2) -> (MOVBstorezero [off1+off2] {sym} ptr mem) (MOVHstorezero [off1] {sym} (ADDconst [off2] ptr) mem) - && is32Bit(off1+off2) - && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)) -> + && is32Bit(off1+off2) && !isArg(sym) + && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym)) -> (MOVHstorezero [off1+off2] {sym} ptr mem) (MOVWstorezero [off1] {sym} (ADDconst [off2] ptr) mem) - && is32Bit(off1+off2) - && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)) -> + && is32Bit(off1+off2) && !isArg(sym) + && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym)) -> (MOVWstorezero [off1+off2] {sym} ptr mem) (MOVDstorezero [off1] {sym} (ADDconst [off2] ptr) mem) - && is32Bit(off1+off2) - && ((off1+off2)%2==8 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)) -> + && is32Bit(off1+off2) && !isArg(sym) + && ((off1+off2)%2==8 || off1+off2<256 && off1+off2>-256 && !isAuto(sym)) -> (MOVDstorezero [off1+off2] {sym} ptr mem) (MOVBload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) @@ -606,71 +606,71 @@ && is32Bit(off1+off2) -> (MOVBUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) (MOVHload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) - && is32Bit(off1+off2) - && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(mergeSym(sym1,sym2)) && !isAuto(mergeSym(sym1,sym2))) -> + && is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2)) + && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2))) -> (MOVHload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) (MOVHUload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) - && is32Bit(off1+off2) - && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(mergeSym(sym1,sym2)) && !isAuto(mergeSym(sym1,sym2))) -> + && is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2)) + && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2))) -> (MOVHUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) (MOVWload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) - && is32Bit(off1+off2) - && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(mergeSym(sym1,sym2)) && !isAuto(mergeSym(sym1,sym2))) -> + && is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2)) + && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2))) -> (MOVWload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) (MOVWUload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) - && is32Bit(off1+off2) - && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(mergeSym(sym1,sym2)) && !isAuto(mergeSym(sym1,sym2))) -> + && is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2)) + && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2))) -> (MOVWUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) (MOVDload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) - && is32Bit(off1+off2) - && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(mergeSym(sym1,sym2)) && !isAuto(mergeSym(sym1,sym2))) -> + && is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2)) + && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2))) -> (MOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) (FMOVSload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) - && is32Bit(off1+off2) - && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(mergeSym(sym1,sym2)) && !isAuto(mergeSym(sym1,sym2))) -> + && is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2)) + && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2))) -> (FMOVSload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) (FMOVDload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) - && is32Bit(off1+off2) - && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(mergeSym(sym1,sym2)) && !isAuto(mergeSym(sym1,sym2))) -> + && is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2)) + && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2))) -> (FMOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) (MOVBstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is32Bit(off1+off2) -> (MOVBstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) (MOVHstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) - && is32Bit(off1+off2) - && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(mergeSym(sym1,sym2)) && !isAuto(mergeSym(sym1,sym2))) -> + && is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2)) + && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2))) -> (MOVHstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) (MOVWstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) - && is32Bit(off1+off2) - && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(mergeSym(sym1,sym2)) && !isAuto(mergeSym(sym1,sym2))) -> + && is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2)) + && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2))) -> (MOVWstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) (MOVDstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) - && is32Bit(off1+off2) - && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(mergeSym(sym1,sym2)) && !isAuto(mergeSym(sym1,sym2))) -> + && is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2)) + && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2))) -> (MOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) (FMOVSstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) - && is32Bit(off1+off2) - && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(mergeSym(sym1,sym2)) && !isAuto(mergeSym(sym1,sym2))) -> + && is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2)) + && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2))) -> (FMOVSstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) (FMOVDstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) - && is32Bit(off1+off2) - && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(mergeSym(sym1,sym2)) && !isAuto(mergeSym(sym1,sym2))) -> + && is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2)) + && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2))) -> (FMOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) (MOVBstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(off1+off2) -> (MOVBstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem) (MOVHstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) - && is32Bit(off1+off2) - && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(mergeSym(sym1,sym2)) && !isAuto(mergeSym(sym1,sym2))) -> + && is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2)) + && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2))) -> (MOVHstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem) (MOVWstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) - && is32Bit(off1+off2) - && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(mergeSym(sym1,sym2)) && !isAuto(mergeSym(sym1,sym2))) -> + && is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2)) + && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2))) -> (MOVWstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem) (MOVDstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) - && is32Bit(off1+off2) - && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(mergeSym(sym1,sym2)) && !isAuto(mergeSym(sym1,sym2))) -> + && is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2)) + && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2))) -> (MOVDstorezero [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 890f60a85c..5c49636a36 100644 --- a/src/cmd/compile/internal/ssa/rewriteARM64.go +++ b/src/cmd/compile/internal/ssa/rewriteARM64.go @@ -2625,7 +2625,7 @@ func rewriteValueARM64_OpARM64FMOVDload(v *Value, config *Config) bool { b := v.Block _ = b // match: (FMOVDload [off1] {sym} (ADDconst [off2] ptr) mem) - // cond: is32Bit(off1+off2) && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)) + // cond: is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym)) // result: (FMOVDload [off1+off2] {sym} ptr mem) for { off1 := v.AuxInt @@ -2637,7 +2637,7 @@ func rewriteValueARM64_OpARM64FMOVDload(v *Value, config *Config) bool { off2 := v_0.AuxInt ptr := v_0.Args[0] mem := v.Args[1] - if !(is32Bit(off1+off2) && ((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym))) { + if !(is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(sym))) { break } v.reset(OpARM64FMOVDload) @@ -2648,7 +2648,7 @@ func rewriteValueARM64_OpARM64FMOVDload(v *Value, config *Config) bool { return true } // match: (FMOVDload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) - // cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(mergeSym(sym1,sym2)) && !isAuto(mergeSym(sym1,sym2))) + // cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2)) && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2))) // result: (FMOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { off1 := v.AuxInt @@ -2661,7 +2661,7 @@ func rewriteValueARM64_OpARM64FMOVDload(v *Value, config *Config) bool { sym2 := v_0.Aux ptr := v_0.Args[0] mem := v.Args[1] - if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && ((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(mergeSym(sym1, sym2)) && !isAuto(mergeSym(sym1, sym2)))) { + if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1, sym2)) && ((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(mergeSym(sym1, sym2)))) { break } v.reset(OpARM64FMOVDload) @@ -2677,7 +2677,7 @@ func rewriteValueARM64_OpARM64FMOVDstore(v *Value, config *Config) bool { b := v.Block _ = b // match: (FMOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem) - // cond: is32Bit(off1+off2) && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)) + // cond: is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym)) // result: (FMOVDstore [off1+off2] {sym} ptr val mem) for { off1 := v.AuxInt @@ -2690,7 +2690,7 @@ func rewriteValueARM64_OpARM64FMOVDstore(v *Value, config *Config) bool { ptr := v_0.Args[0] val := v.Args[1] mem := v.Args[2] - if !(is32Bit(off1+off2) && ((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym))) { + if !(is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(sym))) { break } v.reset(OpARM64FMOVDstore) @@ -2702,7 +2702,7 @@ func rewriteValueARM64_OpARM64FMOVDstore(v *Value, config *Config) bool { return true } // match: (FMOVDstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem) - // cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(mergeSym(sym1,sym2)) && !isAuto(mergeSym(sym1,sym2))) + // cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2)) && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2))) // result: (FMOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) for { off1 := v.AuxInt @@ -2716,7 +2716,7 @@ func rewriteValueARM64_OpARM64FMOVDstore(v *Value, config *Config) bool { ptr := v_0.Args[0] val := v.Args[1] mem := v.Args[2] - if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && ((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(mergeSym(sym1, sym2)) && !isAuto(mergeSym(sym1, sym2)))) { + if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1, sym2)) && ((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(mergeSym(sym1, sym2)))) { break } v.reset(OpARM64FMOVDstore) @@ -2733,7 +2733,7 @@ func rewriteValueARM64_OpARM64FMOVSload(v *Value, config *Config) bool { b := v.Block _ = b // match: (FMOVSload [off1] {sym} (ADDconst [off2] ptr) mem) - // cond: is32Bit(off1+off2) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)) + // cond: is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym)) // result: (FMOVSload [off1+off2] {sym} ptr mem) for { off1 := v.AuxInt @@ -2745,7 +2745,7 @@ func rewriteValueARM64_OpARM64FMOVSload(v *Value, config *Config) bool { off2 := v_0.AuxInt ptr := v_0.Args[0] mem := v.Args[1] - if !(is32Bit(off1+off2) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym))) { + if !(is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(sym))) { break } v.reset(OpARM64FMOVSload) @@ -2756,7 +2756,7 @@ func rewriteValueARM64_OpARM64FMOVSload(v *Value, config *Config) bool { return true } // match: (FMOVSload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) - // cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(mergeSym(sym1,sym2)) && !isAuto(mergeSym(sym1,sym2))) + // cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2)) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2))) // result: (FMOVSload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { off1 := v.AuxInt @@ -2769,7 +2769,7 @@ func rewriteValueARM64_OpARM64FMOVSload(v *Value, config *Config) bool { sym2 := v_0.Aux ptr := v_0.Args[0] mem := v.Args[1] - if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(mergeSym(sym1, sym2)) && !isAuto(mergeSym(sym1, sym2)))) { + if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1, sym2)) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(mergeSym(sym1, sym2)))) { break } v.reset(OpARM64FMOVSload) @@ -2785,7 +2785,7 @@ func rewriteValueARM64_OpARM64FMOVSstore(v *Value, config *Config) bool { b := v.Block _ = b // match: (FMOVSstore [off1] {sym} (ADDconst [off2] ptr) val mem) - // cond: is32Bit(off1+off2) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)) + // cond: is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym)) // result: (FMOVSstore [off1+off2] {sym} ptr val mem) for { off1 := v.AuxInt @@ -2798,7 +2798,7 @@ func rewriteValueARM64_OpARM64FMOVSstore(v *Value, config *Config) bool { ptr := v_0.Args[0] val := v.Args[1] mem := v.Args[2] - if !(is32Bit(off1+off2) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym))) { + if !(is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(sym))) { break } v.reset(OpARM64FMOVSstore) @@ -2810,7 +2810,7 @@ func rewriteValueARM64_OpARM64FMOVSstore(v *Value, config *Config) bool { return true } // match: (FMOVSstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem) - // cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(mergeSym(sym1,sym2)) && !isAuto(mergeSym(sym1,sym2))) + // cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2)) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2))) // result: (FMOVSstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) for { off1 := v.AuxInt @@ -2824,7 +2824,7 @@ func rewriteValueARM64_OpARM64FMOVSstore(v *Value, config *Config) bool { ptr := v_0.Args[0] val := v.Args[1] mem := v.Args[2] - if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(mergeSym(sym1, sym2)) && !isAuto(mergeSym(sym1, sym2)))) { + if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1, sym2)) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(mergeSym(sym1, sym2)))) { break } v.reset(OpARM64FMOVSstore) @@ -3997,7 +3997,7 @@ func rewriteValueARM64_OpARM64MOVDload(v *Value, config *Config) bool { b := v.Block _ = b // match: (MOVDload [off1] {sym} (ADDconst [off2] ptr) mem) - // cond: is32Bit(off1+off2) && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)) + // cond: is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym)) // result: (MOVDload [off1+off2] {sym} ptr mem) for { off1 := v.AuxInt @@ -4009,7 +4009,7 @@ func rewriteValueARM64_OpARM64MOVDload(v *Value, config *Config) bool { off2 := v_0.AuxInt ptr := v_0.Args[0] mem := v.Args[1] - if !(is32Bit(off1+off2) && ((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym))) { + if !(is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(sym))) { break } v.reset(OpARM64MOVDload) @@ -4020,7 +4020,7 @@ func rewriteValueARM64_OpARM64MOVDload(v *Value, config *Config) bool { return true } // match: (MOVDload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) - // cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(mergeSym(sym1,sym2)) && !isAuto(mergeSym(sym1,sym2))) + // cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2)) && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2))) // result: (MOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { off1 := v.AuxInt @@ -4033,7 +4033,7 @@ func rewriteValueARM64_OpARM64MOVDload(v *Value, config *Config) bool { sym2 := v_0.Aux ptr := v_0.Args[0] mem := v.Args[1] - if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && ((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(mergeSym(sym1, sym2)) && !isAuto(mergeSym(sym1, sym2)))) { + if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1, sym2)) && ((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(mergeSym(sym1, sym2)))) { break } v.reset(OpARM64MOVDload) @@ -4100,7 +4100,7 @@ func rewriteValueARM64_OpARM64MOVDstore(v *Value, config *Config) bool { b := v.Block _ = b // match: (MOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem) - // cond: is32Bit(off1+off2) && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)) + // cond: is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym)) // result: (MOVDstore [off1+off2] {sym} ptr val mem) for { off1 := v.AuxInt @@ -4113,7 +4113,7 @@ func rewriteValueARM64_OpARM64MOVDstore(v *Value, config *Config) bool { ptr := v_0.Args[0] val := v.Args[1] mem := v.Args[2] - if !(is32Bit(off1+off2) && ((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym))) { + if !(is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(sym))) { break } v.reset(OpARM64MOVDstore) @@ -4125,7 +4125,7 @@ func rewriteValueARM64_OpARM64MOVDstore(v *Value, config *Config) bool { return true } // match: (MOVDstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem) - // cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(mergeSym(sym1,sym2)) && !isAuto(mergeSym(sym1,sym2))) + // cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2)) && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2))) // result: (MOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) for { off1 := v.AuxInt @@ -4139,7 +4139,7 @@ func rewriteValueARM64_OpARM64MOVDstore(v *Value, config *Config) bool { ptr := v_0.Args[0] val := v.Args[1] mem := v.Args[2] - if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && ((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(mergeSym(sym1, sym2)) && !isAuto(mergeSym(sym1, sym2)))) { + if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1, sym2)) && ((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(mergeSym(sym1, sym2)))) { break } v.reset(OpARM64MOVDstore) @@ -4178,7 +4178,7 @@ func rewriteValueARM64_OpARM64MOVDstorezero(v *Value, config *Config) bool { b := v.Block _ = b // match: (MOVDstorezero [off1] {sym} (ADDconst [off2] ptr) mem) - // cond: is32Bit(off1+off2) && ((off1+off2)%2==8 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)) + // cond: is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%2==8 || off1+off2<256 && off1+off2>-256 && !isAuto(sym)) // result: (MOVDstorezero [off1+off2] {sym} ptr mem) for { off1 := v.AuxInt @@ -4190,7 +4190,7 @@ func rewriteValueARM64_OpARM64MOVDstorezero(v *Value, config *Config) bool { off2 := v_0.AuxInt ptr := v_0.Args[0] mem := v.Args[1] - if !(is32Bit(off1+off2) && ((off1+off2)%2 == 8 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym))) { + if !(is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%2 == 8 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(sym))) { break } v.reset(OpARM64MOVDstorezero) @@ -4201,7 +4201,7 @@ func rewriteValueARM64_OpARM64MOVDstorezero(v *Value, config *Config) bool { return true } // match: (MOVDstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) - // cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isArg(mergeSym(sym1,sym2)) && !isAuto(mergeSym(sym1,sym2))) + // cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2)) && ((off1+off2)%8==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2))) // result: (MOVDstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { off1 := v.AuxInt @@ -4214,7 +4214,7 @@ func rewriteValueARM64_OpARM64MOVDstorezero(v *Value, config *Config) bool { sym2 := v_0.Aux ptr := v_0.Args[0] mem := v.Args[1] - if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && ((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(mergeSym(sym1, sym2)) && !isAuto(mergeSym(sym1, sym2)))) { + if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1, sym2)) && ((off1+off2)%8 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(mergeSym(sym1, sym2)))) { break } v.reset(OpARM64MOVDstorezero) @@ -4230,7 +4230,7 @@ func rewriteValueARM64_OpARM64MOVHUload(v *Value, config *Config) bool { b := v.Block _ = b // match: (MOVHUload [off1] {sym} (ADDconst [off2] ptr) mem) - // cond: is32Bit(off1+off2) && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)) + // cond: is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym)) // result: (MOVHUload [off1+off2] {sym} ptr mem) for { off1 := v.AuxInt @@ -4242,7 +4242,7 @@ func rewriteValueARM64_OpARM64MOVHUload(v *Value, config *Config) bool { off2 := v_0.AuxInt ptr := v_0.Args[0] mem := v.Args[1] - if !(is32Bit(off1+off2) && ((off1+off2)%2 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym))) { + if !(is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%2 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(sym))) { break } v.reset(OpARM64MOVHUload) @@ -4253,7 +4253,7 @@ func rewriteValueARM64_OpARM64MOVHUload(v *Value, config *Config) bool { return true } // match: (MOVHUload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) - // cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(mergeSym(sym1,sym2)) && !isAuto(mergeSym(sym1,sym2))) + // cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2)) && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2))) // result: (MOVHUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { off1 := v.AuxInt @@ -4266,7 +4266,7 @@ func rewriteValueARM64_OpARM64MOVHUload(v *Value, config *Config) bool { sym2 := v_0.Aux ptr := v_0.Args[0] mem := v.Args[1] - if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && ((off1+off2)%2 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(mergeSym(sym1, sym2)) && !isAuto(mergeSym(sym1, sym2)))) { + if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1, sym2)) && ((off1+off2)%2 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(mergeSym(sym1, sym2)))) { break } v.reset(OpARM64MOVHUload) @@ -4369,7 +4369,7 @@ func rewriteValueARM64_OpARM64MOVHload(v *Value, config *Config) bool { b := v.Block _ = b // match: (MOVHload [off1] {sym} (ADDconst [off2] ptr) mem) - // cond: is32Bit(off1+off2) && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)) + // cond: is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym)) // result: (MOVHload [off1+off2] {sym} ptr mem) for { off1 := v.AuxInt @@ -4381,7 +4381,7 @@ func rewriteValueARM64_OpARM64MOVHload(v *Value, config *Config) bool { off2 := v_0.AuxInt ptr := v_0.Args[0] mem := v.Args[1] - if !(is32Bit(off1+off2) && ((off1+off2)%2 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym))) { + if !(is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%2 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(sym))) { break } v.reset(OpARM64MOVHload) @@ -4392,7 +4392,7 @@ func rewriteValueARM64_OpARM64MOVHload(v *Value, config *Config) bool { return true } // match: (MOVHload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) - // cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(mergeSym(sym1,sym2)) && !isAuto(mergeSym(sym1,sym2))) + // cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2)) && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2))) // result: (MOVHload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { off1 := v.AuxInt @@ -4405,7 +4405,7 @@ func rewriteValueARM64_OpARM64MOVHload(v *Value, config *Config) bool { sym2 := v_0.Aux ptr := v_0.Args[0] mem := v.Args[1] - if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && ((off1+off2)%2 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(mergeSym(sym1, sym2)) && !isAuto(mergeSym(sym1, sym2)))) { + if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1, sym2)) && ((off1+off2)%2 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(mergeSym(sym1, sym2)))) { break } v.reset(OpARM64MOVHload) @@ -4532,7 +4532,7 @@ func rewriteValueARM64_OpARM64MOVHstore(v *Value, config *Config) bool { b := v.Block _ = b // match: (MOVHstore [off1] {sym} (ADDconst [off2] ptr) val mem) - // cond: is32Bit(off1+off2) && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)) + // cond: is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym)) // result: (MOVHstore [off1+off2] {sym} ptr val mem) for { off1 := v.AuxInt @@ -4545,7 +4545,7 @@ func rewriteValueARM64_OpARM64MOVHstore(v *Value, config *Config) bool { ptr := v_0.Args[0] val := v.Args[1] mem := v.Args[2] - if !(is32Bit(off1+off2) && ((off1+off2)%2 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym))) { + if !(is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%2 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(sym))) { break } v.reset(OpARM64MOVHstore) @@ -4557,7 +4557,7 @@ func rewriteValueARM64_OpARM64MOVHstore(v *Value, config *Config) bool { return true } // match: (MOVHstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem) - // cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(mergeSym(sym1,sym2)) && !isAuto(mergeSym(sym1,sym2))) + // cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2)) && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2))) // result: (MOVHstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) for { off1 := v.AuxInt @@ -4571,7 +4571,7 @@ func rewriteValueARM64_OpARM64MOVHstore(v *Value, config *Config) bool { ptr := v_0.Args[0] val := v.Args[1] mem := v.Args[2] - if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && ((off1+off2)%2 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(mergeSym(sym1, sym2)) && !isAuto(mergeSym(sym1, sym2)))) { + if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1, sym2)) && ((off1+off2)%2 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(mergeSym(sym1, sym2)))) { break } v.reset(OpARM64MOVHstore) @@ -4694,7 +4694,7 @@ func rewriteValueARM64_OpARM64MOVHstorezero(v *Value, config *Config) bool { b := v.Block _ = b // match: (MOVHstorezero [off1] {sym} (ADDconst [off2] ptr) mem) - // cond: is32Bit(off1+off2) && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)) + // cond: is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym)) // result: (MOVHstorezero [off1+off2] {sym} ptr mem) for { off1 := v.AuxInt @@ -4706,7 +4706,7 @@ func rewriteValueARM64_OpARM64MOVHstorezero(v *Value, config *Config) bool { off2 := v_0.AuxInt ptr := v_0.Args[0] mem := v.Args[1] - if !(is32Bit(off1+off2) && ((off1+off2)%2 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym))) { + if !(is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%2 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(sym))) { break } v.reset(OpARM64MOVHstorezero) @@ -4717,7 +4717,7 @@ func rewriteValueARM64_OpARM64MOVHstorezero(v *Value, config *Config) bool { return true } // match: (MOVHstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) - // cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isArg(mergeSym(sym1,sym2)) && !isAuto(mergeSym(sym1,sym2))) + // cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2)) && ((off1+off2)%2==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2))) // result: (MOVHstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { off1 := v.AuxInt @@ -4730,7 +4730,7 @@ func rewriteValueARM64_OpARM64MOVHstorezero(v *Value, config *Config) bool { sym2 := v_0.Aux ptr := v_0.Args[0] mem := v.Args[1] - if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && ((off1+off2)%2 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(mergeSym(sym1, sym2)) && !isAuto(mergeSym(sym1, sym2)))) { + if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1, sym2)) && ((off1+off2)%2 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(mergeSym(sym1, sym2)))) { break } v.reset(OpARM64MOVHstorezero) @@ -4746,7 +4746,7 @@ func rewriteValueARM64_OpARM64MOVWUload(v *Value, config *Config) bool { b := v.Block _ = b // match: (MOVWUload [off1] {sym} (ADDconst [off2] ptr) mem) - // cond: is32Bit(off1+off2) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)) + // cond: is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym)) // result: (MOVWUload [off1+off2] {sym} ptr mem) for { off1 := v.AuxInt @@ -4758,7 +4758,7 @@ func rewriteValueARM64_OpARM64MOVWUload(v *Value, config *Config) bool { off2 := v_0.AuxInt ptr := v_0.Args[0] mem := v.Args[1] - if !(is32Bit(off1+off2) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym))) { + if !(is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(sym))) { break } v.reset(OpARM64MOVWUload) @@ -4769,7 +4769,7 @@ func rewriteValueARM64_OpARM64MOVWUload(v *Value, config *Config) bool { return true } // match: (MOVWUload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) - // cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(mergeSym(sym1,sym2)) && !isAuto(mergeSym(sym1,sym2))) + // cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2)) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2))) // result: (MOVWUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { off1 := v.AuxInt @@ -4782,7 +4782,7 @@ func rewriteValueARM64_OpARM64MOVWUload(v *Value, config *Config) bool { sym2 := v_0.Aux ptr := v_0.Args[0] mem := v.Args[1] - if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(mergeSym(sym1, sym2)) && !isAuto(mergeSym(sym1, sym2)))) { + if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1, sym2)) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(mergeSym(sym1, sym2)))) { break } v.reset(OpARM64MOVWUload) @@ -4909,7 +4909,7 @@ func rewriteValueARM64_OpARM64MOVWload(v *Value, config *Config) bool { b := v.Block _ = b // match: (MOVWload [off1] {sym} (ADDconst [off2] ptr) mem) - // cond: is32Bit(off1+off2) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)) + // cond: is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym)) // result: (MOVWload [off1+off2] {sym} ptr mem) for { off1 := v.AuxInt @@ -4921,7 +4921,7 @@ func rewriteValueARM64_OpARM64MOVWload(v *Value, config *Config) bool { off2 := v_0.AuxInt ptr := v_0.Args[0] mem := v.Args[1] - if !(is32Bit(off1+off2) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym))) { + if !(is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(sym))) { break } v.reset(OpARM64MOVWload) @@ -4932,7 +4932,7 @@ func rewriteValueARM64_OpARM64MOVWload(v *Value, config *Config) bool { return true } // match: (MOVWload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) - // cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(mergeSym(sym1,sym2)) && !isAuto(mergeSym(sym1,sym2))) + // cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2)) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2))) // result: (MOVWload [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { off1 := v.AuxInt @@ -4945,7 +4945,7 @@ func rewriteValueARM64_OpARM64MOVWload(v *Value, config *Config) bool { sym2 := v_0.Aux ptr := v_0.Args[0] mem := v.Args[1] - if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(mergeSym(sym1, sym2)) && !isAuto(mergeSym(sym1, sym2)))) { + if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1, sym2)) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(mergeSym(sym1, sym2)))) { break } v.reset(OpARM64MOVWload) @@ -5120,7 +5120,7 @@ func rewriteValueARM64_OpARM64MOVWstore(v *Value, config *Config) bool { b := v.Block _ = b // match: (MOVWstore [off1] {sym} (ADDconst [off2] ptr) val mem) - // cond: is32Bit(off1+off2) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)) + // cond: is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym)) // result: (MOVWstore [off1+off2] {sym} ptr val mem) for { off1 := v.AuxInt @@ -5133,7 +5133,7 @@ func rewriteValueARM64_OpARM64MOVWstore(v *Value, config *Config) bool { ptr := v_0.Args[0] val := v.Args[1] mem := v.Args[2] - if !(is32Bit(off1+off2) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym))) { + if !(is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(sym))) { break } v.reset(OpARM64MOVWstore) @@ -5145,7 +5145,7 @@ func rewriteValueARM64_OpARM64MOVWstore(v *Value, config *Config) bool { return true } // match: (MOVWstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem) - // cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(mergeSym(sym1,sym2)) && !isAuto(mergeSym(sym1,sym2))) + // cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2)) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2))) // result: (MOVWstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem) for { off1 := v.AuxInt @@ -5159,7 +5159,7 @@ func rewriteValueARM64_OpARM64MOVWstore(v *Value, config *Config) bool { ptr := v_0.Args[0] val := v.Args[1] mem := v.Args[2] - if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(mergeSym(sym1, sym2)) && !isAuto(mergeSym(sym1, sym2)))) { + if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1, sym2)) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(mergeSym(sym1, sym2)))) { break } v.reset(OpARM64MOVWstore) @@ -5240,7 +5240,7 @@ func rewriteValueARM64_OpARM64MOVWstorezero(v *Value, config *Config) bool { b := v.Block _ = b // match: (MOVWstorezero [off1] {sym} (ADDconst [off2] ptr) mem) - // cond: is32Bit(off1+off2) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(sym) && !isAuto(sym)) + // cond: is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isAuto(sym)) // result: (MOVWstorezero [off1+off2] {sym} ptr mem) for { off1 := v.AuxInt @@ -5252,7 +5252,7 @@ func rewriteValueARM64_OpARM64MOVWstorezero(v *Value, config *Config) bool { off2 := v_0.AuxInt ptr := v_0.Args[0] mem := v.Args[1] - if !(is32Bit(off1+off2) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(sym) && !isAuto(sym))) { + if !(is32Bit(off1+off2) && !isArg(sym) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(sym))) { break } v.reset(OpARM64MOVWstorezero) @@ -5263,7 +5263,7 @@ func rewriteValueARM64_OpARM64MOVWstorezero(v *Value, config *Config) bool { return true } // match: (MOVWstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) - // cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isArg(mergeSym(sym1,sym2)) && !isAuto(mergeSym(sym1,sym2))) + // cond: canMergeSym(sym1,sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1,sym2)) && ((off1+off2)%4==0 || off1+off2<256 && off1+off2>-256 && !isAuto(mergeSym(sym1,sym2))) // result: (MOVWstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem) for { off1 := v.AuxInt @@ -5276,7 +5276,7 @@ func rewriteValueARM64_OpARM64MOVWstorezero(v *Value, config *Config) bool { sym2 := v_0.Aux ptr := v_0.Args[0] mem := v.Args[1] - if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isArg(mergeSym(sym1, sym2)) && !isAuto(mergeSym(sym1, sym2)))) { + if !(canMergeSym(sym1, sym2) && is32Bit(off1+off2) && !isArg(mergeSym(sym1, sym2)) && ((off1+off2)%4 == 0 || off1+off2 < 256 && off1+off2 > -256 && !isAuto(mergeSym(sym1, sym2)))) { break } v.reset(OpARM64MOVWstorezero) diff --git a/test/fixedbugs/issue19137.go b/test/fixedbugs/issue19137.go index b107c2b5b3..946f029be1 100644 --- a/test/fixedbugs/issue19137.go +++ b/test/fixedbugs/issue19137.go @@ -20,3 +20,16 @@ func f(b [6]byte) T { _ = x return T{b: b} } + +// Arg symbol's base address may be not at an aligned offset to +// SP. Folding arg's address into load/store may cause odd offset. +func move(a, b [20]byte) [20]byte { + var x [1000]int // a large stack frame + _ = x + return b // b is not 8-byte aligned to SP +} +func zero() ([20]byte, [20]byte) { + var x [1000]int // a large stack frame + _ = x + return [20]byte{}, [20]byte{} // the second return value is not 8-byte aligned to SP +}