#2103·gonum

internal/asm/c64,c128: AMD64 AXPY faults on valid alignment and overruns an exhausted alignment tail

Author: jamestjspCreated Sep 8, 2026Updated Sep 8, 2026

Upstream master 2b52c28fc756441b75b3af99cddc1649f4439ded; AMD64 ASM, no SIMD experiment.

Save as asm_axpy_repro_test.go in the repository root. Run:

bash
GOEXPERIMENT= go test -run '^TestUpstreamAXPY/c64_alignment

```go
package gonum_test

import (
	"gonum.org/v1/gonum/internal/asm/c128"
	"gonum.org/v1/gonum/internal/asm/c64"
	"testing"
	"unsafe"
)

func c64Aligned(t *testing.T, n int, mod uintptr) []complex64 {
	storage := new(struct {
		A   [32]complex64
		Pad float32
		B   [32]complex64
	})
	for _, v := range [][]complex64{storage.A[:], storage.B[:]} {
		for start := 0; start < 2; start++ {
			if uintptr(unsafe.Pointer(&v[start]))%16 == mod {
				return v[start : start+n]
			}
		}
	}
	t.Fatal("fixture alignment")
	return nil
}

func TestUpstreamAXPY(t *testing.T) {
	t.Run("c64_alignment", func(t *testing.T) {
		y := c64Aligned(t, 17, 4)
		x := make([]complex64, 17)
		for i := range x {
			x[i], y[i] = 1, 2
		}
		c64.AxpyUnitary(3, x, y)
		for _, v := range y {
			if v != 5 {
				t.Fatalf("got %v, want 5", v)
			}
		}
	})
	t.Run("c64_empty_tail", func(t *testing.T) {
		y := c64Aligned(t, 1, 8)
		y[0] = 2
		dst := make([]complex64, 1)
		c64.AxpyUnitaryTo(dst, 3, []complex64{1}, y)
		if dst[0] != 5 {
			t.Fatalf("got %v, want 5", dst)
		}
	})
	t.Run("c128_alignment", func(t *testing.T) {
		storage := new(struct {
			A   [8]complex128
			Pad uint64
			B   [8]complex128
		})
		y := storage.A[:]
		if uintptr(unsafe.Pointer(&y[0]))%16 == 0 {
			y = storage.B[:]
		}
		if uintptr(unsafe.Pointer(&y[0]))%16 != 8 {
			t.Fatal("fixture alignment")
		}
		y = y[:1]
		y[0] = 2
		c128.AxpyUnitary(3, []complex128{1}, y)
		if y[0] != 5 {
			t.Fatalf("got %v, want 5", y)
		}
	})
}

ASM may terminate the process; use ulimit -c 0. Go 1.27.1: noasm passes; Rosetta reproduces the exhausted tail but not alignment faults. Repaired ASM tests pass under Rosetta; native AMD64 pending. -count=1 -timeout=5s . GOEXPERIMENT= go test -run '^TestUpstreamAXPY/c64_empty_tail

go
package gonum_test

import (
	"gonum.org/v1/gonum/internal/asm/c128"
	"gonum.org/v1/gonum/internal/asm/c64"
	"testing"
	"unsafe"
)

func c64Aligned(t *testing.T, n int, mod uintptr) []complex64 {
	storage := new(struct {
		A   [32]complex64
		Pad float32
		B   [32]complex64
	})
	for _, v := range [][]complex64{storage.A[:], storage.B[:]} {
		for start := 0; start < 2; start++ {
			if uintptr(unsafe.Pointer(&v[start]))%16 == mod {
				return v[start : start+n]
			}
		}
	}
	t.Fatal("fixture alignment")
	return nil
}

func TestUpstreamAXPY(t *testing.T) {
	t.Run("c64_alignment", func(t *testing.T) {
		y := c64Aligned(t, 8, 4)
		x := make([]complex64, 8)
		for i := range x {
			x[i], y[i] = 1, 2
		}
		c64.AxpyUnitary(3, x, y)
		for _, v := range y {
			if v != 5 {
				t.Fatalf("got %v, want 5", v)
			}
		}
	})
	t.Run("c64_empty_tail", func(t *testing.T) {
		y := c64Aligned(t, 1, 8)
		y[0] = 2
		dst := make([]complex64, 1)
		c64.AxpyUnitaryTo(dst, 3, []complex64{1}, y)
		if dst[0] != 5 {
			t.Fatalf("got %v, want 5", dst)
		}
	})
	t.Run("c128_alignment", func(t *testing.T) {
		storage := new(struct {
			A   [8]complex128
			Pad uint64
			B   [8]complex128
		})
		y := storage.A[:]
		if uintptr(unsafe.Pointer(&y[0]))%16 == 0 {
			y = storage.B[:]
		}
		if uintptr(unsafe.Pointer(&y[0]))%16 != 8 {
			t.Fatal("fixture alignment")
		}
		y = y[:1]
		y[0] = 2
		c128.AxpyUnitary(3, []complex128{1}, y)
		if y[0] != 5 {
			t.Fatalf("got %v, want 5", y)
		}
	})
}

ASM may terminate the process; use ulimit -c 0. Verification: source audited; noasm control passed on darwin/arm64, Go 1.27.1. Fresh native AMD64 execution not yet verified. -count=1 -timeout=5s . GOEXPERIMENT= go test -run '^TestUpstreamAXPY/c128_alignment

go
package gonum_test

import (
	"gonum.org/v1/gonum/internal/asm/c128"
	"gonum.org/v1/gonum/internal/asm/c64"
	"testing"
	"unsafe"
)

func c64Aligned(t *testing.T, n int, mod uintptr) []complex64 {
	storage := new(struct {
		A   [32]complex64
		Pad float32
		B   [32]complex64
	})
	for _, v := range [][]complex64{storage.A[:], storage.B[:]} {
		for start := 0; start < 2; start++ {
			if uintptr(unsafe.Pointer(&v[start]))%16 == mod {
				return v[start : start+n]
			}
		}
	}
	t.Fatal("fixture alignment")
	return nil
}

func TestUpstreamAXPY(t *testing.T) {
	t.Run("c64_alignment", func(t *testing.T) {
		y := c64Aligned(t, 8, 4)
		x := make([]complex64, 8)
		for i := range x {
			x[i], y[i] = 1, 2
		}
		c64.AxpyUnitary(3, x, y)
		for _, v := range y {
			if v != 5 {
				t.Fatalf("got %v, want 5", v)
			}
		}
	})
	t.Run("c64_empty_tail", func(t *testing.T) {
		y := c64Aligned(t, 1, 8)
		y[0] = 2
		dst := make([]complex64, 1)
		c64.AxpyUnitaryTo(dst, 3, []complex64{1}, y)
		if dst[0] != 5 {
			t.Fatalf("got %v, want 5", dst)
		}
	})
	t.Run("c128_alignment", func(t *testing.T) {
		storage := new(struct {
			A   [8]complex128
			Pad uint64
			B   [8]complex128
		})
		y := storage.A[:]
		if uintptr(unsafe.Pointer(&y[0]))%16 == 0 {
			y = storage.B[:]
		}
		if uintptr(unsafe.Pointer(&y[0]))%16 != 8 {
			t.Fatal("fixture alignment")
		}
		y = y[:1]
		y[0] = 2
		c128.AxpyUnitary(3, []complex128{1}, y)
		if y[0] != 5 {
			t.Fatalf("got %v, want 5", y)
		}
	})
}

ASM may terminate the process; use ulimit -c 0. Verification: source audited; noasm control passed on darwin/arm64, Go 1.27.1. Fresh native AMD64 execution not yet verified. -count=1 -timeout=5s .


Add `-tags noasm` for the passing control.

```go
package gonum_test

import (
	"gonum.org/v1/gonum/internal/asm/c128"
	"gonum.org/v1/gonum/internal/asm/c64"
	"testing"
	"unsafe"
)

func c64Aligned(t *testing.T, n int, mod uintptr) []complex64 {
	storage := new(struct {
		A   [32]complex64
		Pad float32
		B   [32]complex64
	})
	for _, v := range [][]complex64{storage.A[:], storage.B[:]} {
		for start := 0; start < 2; start++ {
			if uintptr(unsafe.Pointer(&v[start]))%16 == mod {
				return v[start : start+n]
			}
		}
	}
	t.Fatal("fixture alignment")
	return nil
}

func TestUpstreamAXPY(t *testing.T) {
	t.Run("c64_alignment", func(t *testing.T) {
		y := c64Aligned(t, 8, 4)
		x := make([]complex64, 8)
		for i := range x {
			x[i], y[i] = 1, 2
		}
		c64.AxpyUnitary(3, x, y)
		for _, v := range y {
			if v != 5 {
				t.Fatalf("got %v, want 5", v)
			}
		}
	})
	t.Run("c64_empty_tail", func(t *testing.T) {
		y := c64Aligned(t, 1, 8)
		y[0] = 2
		dst := make([]complex64, 1)
		c64.AxpyUnitaryTo(dst, 3, []complex64{1}, y)
		if dst[0] != 5 {
			t.Fatalf("got %v, want 5", dst)
		}
	})
	t.Run("c128_alignment", func(t *testing.T) {
		storage := new(struct {
			A   [8]complex128
			Pad uint64
			B   [8]complex128
		})
		y := storage.A[:]
		if uintptr(unsafe.Pointer(&y[0]))%16 == 0 {
			y = storage.B[:]
		}
		if uintptr(unsafe.Pointer(&y[0]))%16 != 8 {
			t.Fatal("fixture alignment")
		}
		y = y[:1]
		y[0] = 2
		c128.AxpyUnitary(3, []complex128{1}, y)
		if y[0] != 5 {
			t.Fatalf("got %v, want 5", y)
		}
	})
}

ASM may terminate the process; use ulimit -c 0. Verification: source audited; noasm control passed on darwin/arm64, Go 1.27.1. Fresh native AMD64 execution not yet verified.