go/analyis/passes/asmdecl: allow loading both parts of a complex with one instruction
Update golang/go#35264
Change-Id: I4317c75cc5acc592ab739b0aab4cd85280858219
Reviewed-on: https://go-review.googlesource.com/c/tools/+/204537
Reviewed-by: Alan Donovan <adonovan@google.com>
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
diff --git a/go/analysis/passes/asmdecl/asmdecl.go b/go/analysis/passes/asmdecl/asmdecl.go
index 6e7a76e..c2e89ee 100644
--- a/go/analysis/passes/asmdecl/asmdecl.go
+++ b/go/analysis/passes/asmdecl/asmdecl.go
@@ -661,6 +661,10 @@
src = 4
break
}
+ if op == "MOVO" || op == "MOVOU" {
+ src = 16
+ break
+ }
if strings.HasPrefix(op, "SET") {
// SETEQ, etc
src = 1
@@ -736,6 +740,11 @@
vk = v.inner[0].kind
vs = v.inner[0].size
vt = v.inner[0].typ
+ case asmComplex:
+ // Allow a single instruction to load both parts of a complex.
+ if int(kind) == vs {
+ kind = asmComplex
+ }
}
if addr {
vk = asmKind(archDef.ptrSize)
diff --git a/go/analysis/passes/asmdecl/testdata/src/a/asm1.s b/go/analysis/passes/asmdecl/testdata/src/a/asm1.s
index 9af8612..b39130f 100644
--- a/go/analysis/passes/asmdecl/testdata/src/a/asm1.s
+++ b/go/analysis/passes/asmdecl/testdata/src/a/asm1.s
@@ -228,7 +228,6 @@
TEXT ·argcomplex(SB),0,$24 // want `wrong argument size 0; expected \$\.\.\.-24`
MOVSS x+0(FP), X0 // want `invalid MOVSS of x\+0\(FP\); complex64 is 8-byte value containing x_real\+0\(FP\) and x_imag\+4\(FP\)`
- MOVSD x+0(FP), X0 // want `invalid MOVSD of x\+0\(FP\); complex64 is 8-byte value containing x_real\+0\(FP\) and x_imag\+4\(FP\)`
MOVSS x_real+0(FP), X0
MOVSD x_real+0(FP), X0 // want `invalid MOVSD of x_real\+0\(FP\); real\(complex64\) is 4-byte value`
MOVSS x_real+4(FP), X0 // want `invalid offset x_real\+4\(FP\); expected x_real\+0\(FP\)`
@@ -242,6 +241,13 @@
MOVSS y_imag+16(FP), X0 // want `invalid MOVSS of y_imag\+16\(FP\); imag\(complex128\) is 8-byte value`
MOVSD y_imag+16(FP), X0
MOVSS y_imag+24(FP), X0 // want `invalid offset y_imag\+24\(FP\); expected y_imag\+16\(FP\)`
+ // Loading both parts of a complex is ok: see issue 35264.
+ MOVSD x+0(FP), X0
+ MOVO y+8(FP), X0
+ MOVOU y+8(FP), X0
+ // These are not ok.
+ MOVO x+0(FP), X0 // want `invalid MOVO of x\+0\(FP\); complex64 is 8-byte value containing x_real\+0\(FP\) and x_imag\+4\(FP\)`
+ MOVOU x+0(FP), X0 // want `invalid MOVOU of x\+0\(FP\); complex64 is 8-byte value containing x_real\+0\(FP\) and x_imag\+4\(FP\)`
RET
TEXT ·argstruct(SB),0,$64 // want `wrong argument size 0; expected \$\.\.\.-24`