internal/asm/f32,f64: AMD64 GER mishandles valid negative increments
Author: jamestjspCreated Sep 8, 2026Updated Sep 8, 2026
Upstream master 2b52c28fc756441b75b3af99cddc1649f4439ded; AMD64 ASM, no SIMD experiment.
Save as asm_ger_repro_test.go in the repository root. Run:
GOEXPERIMENT= go test -run '^TestUpstreamGER' -count=1 -timeout=5s .Add -tags noasm for the passing control.
package gonum_test
import (
"fmt"
blasgo "gonum.org/v1/gonum/blas/gonum"
"testing"
)
func TestUpstreamGER(t *testing.T) {
for _, steps := range [][2]int{{1, -1}, {-1, 1}, {-1, -1}} {
t.Run(fmt.Sprint(steps), func(t *testing.T) {
// Extra initialized backing keeps the known erroneous offsets mapped.
xd, yd := make([]float64, 128), make([]float64, 128)
xs, ys := make([]float32, 128), make([]float32, 128)
for i := range xd {
xd[i] = float64(i + 1)
yd[i] = float64(i + 2)
xs[i] = float32(i + 1)
ys[i] = float32(i + 2)
}
const m, n = 5, 3
ad, as := make([]float64, m*n), make([]float32, m*n)
blasgo.Implementation{}.Dger(m, n, 1, xd, steps[0], yd, steps[1], ad, n)
blasgo.Implementation{}.Sger(m, n, 1, xs, steps[0], ys, steps[1], as, n)
for i := 0; i < m; i++ {
for j := 0; j < n; j++ {
ix, iy := i, j
if steps[0] < 0 {
ix = m - 1 - i
}
if steps[1] < 0 {
iy = n - 1 - j
}
want := xd[ix] * yd[iy]
if ad[i*n+j] != want {
t.Errorf("Dger [%d,%d]: got %g want %g", i, j, ad[i*n+j], want)
}
if as[i*n+j] != float32(want) {
t.Errorf("Sger [%d,%d]: got %g want %g", i, j, as[i*n+j], want)
}
}
}
})
}
}Go 1.27.1/Rosetta: original gives incorrect matrices; repaired ASM and noasm controls pass. Native AMD64 pending.
Source: gonum/gonum