simd/archsimd: deduplicate ternary test helpers

Change-Id: Ica79417b43af8004dc15e4f1e114640b954247af
Reviewed-on: https://go-review.googlesource.com/c/go/+/794000
Reviewed-by: David Chase <drchase@google.com>
LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
diff --git a/src/simd/archsimd/_gen/tmplgen/main.go b/src/simd/archsimd/_gen/tmplgen/main.go
index 28c850e..10ad081 100644
--- a/src/simd/archsimd/_gen/tmplgen/main.go
+++ b/src/simd/archsimd/_gen/tmplgen/main.go
@@ -231,7 +231,7 @@
 
 var ternaryFlaky = &shapes{ // for tests that support flaky equality
 	vecs:   []int{128, 256, 512},
-	floats: []int{32},
+	floats: []int{32, 64},
 }
 
 var avx2SignedComparisons = &shapes{
@@ -674,8 +674,6 @@
 
 var ternaryTemplate = templateOf("ternary_helpers", ternaryTestTemplateText)
 var ternaryFlakyTemplate = shapedTemplateOf(ternaryFlaky, "ternary_helpers", ternaryFlakyTestTemplateText)
-var ternaryTemplateArm64 = shapedTemplateOf(arm64Shapes, "ternary_arm64_helpers", ternaryTestTemplateText)
-var ternaryFlakyTemplateArm64 = shapedTemplateOf(arm64Shapes, "ternary_arm64_helpers", ternaryFlakyTestTemplateText)
 
 const reduceTestTemplateText = `
 func test{{.VType}}Reduce(t *testing.T, f func(_ archsimd.{{.VType}}) {{.Etype}}, want func(_ []{{.Etype}}) {{.Etype}}) {
@@ -1391,7 +1389,7 @@
 	bh := flag.String("bh", TD+"binary_helpers_%W_test.go", "file name for binary test helpers")
 	uh := flag.String("uh", TD+"unary_helpers_%W_test.go", "file name for unary test helpers")
 	cvh := flag.String("cvh", TD+"convert_helpers_%W_test.go", "file name for conversion test helpers")
-	th := flag.String("th", TD+"ternary_helpers_test.go", "file name for ternary test helpers")
+	th := flag.String("th", TD+"ternary_helpers_%W_test.go", "file name for ternary test helpers")
 	ch := flag.String("ch", TD+"compare_helpers_%W_test.go", "file name for compare test helpers")
 	cmh := flag.String("cmh", TD+"comparemasked_helpers_test.go", "file name for compare-masked test helpers")
 	sh := flag.String("sh", TD+"shift_helpers_%W_test.go", "file name for shift test helpers")
@@ -1401,7 +1399,6 @@
 	shArm64 := flag.String("shArm64", TD+"arm64_shift_helpers_test.go", "file name for ARM64 shift test helpers")
 	cmArm64 := flag.String("cmArm64", SIMD+"compare_gen_arm64.go", "file name for ARM64 comparison operations")
 	mmArm64 := flag.String("mmArm64", SIMD+"maskmerge_gen_arm64.go", "file name for ARM64 mask/merge operations")
-	thArm64 := flag.String("thArm64", TD+"ternary_arm64_helpers_test.go", "file name for ARM64 ternary test helpers")
 	rhArm64 := flag.String("rhArm64", TD+"reduce_arm64_helpers_test.go", "file name for ARM64 reduce test helpers")
 	flag.Parse()
 
@@ -1508,9 +1505,6 @@
 			arm64MaskToString,
 		)
 	}
-	if *thArm64 != "" {
-		oneArch(*thArm64, "arm64", curryTestPrologue("ternary simd methods"), filterAll, ternaryTemplateArm64, ternaryFlakyTemplateArm64)
-	}
 	if *rhArm64 != "" {
 		oneArch(*rhArm64, "arm64", reduceTestPrologue, filterAll, reduceTestTemplateArm64)
 	}
diff --git a/src/simd/archsimd/internal/simd_test/ternary_arm64_helpers_test.go b/src/simd/archsimd/internal/simd_test/ternary_arm64_helpers_test.go
deleted file mode 100644
index de5e6ce..0000000
--- a/src/simd/archsimd/internal/simd_test/ternary_arm64_helpers_test.go
+++ /dev/null
@@ -1,344 +0,0 @@
-// Code generated by 'tmplgen'; DO NOT EDIT.
-
-//go:build goexperiment.simd && arm64
-
-// This file contains functions testing ternary simd methods.
-// Each function in this file is specialized for a
-// particular simd type <BaseType><Width>x<Count>.
-
-package simd_test
-
-import (
-	"simd/archsimd"
-	"testing"
-)
-
-// testInt8x16Ternary tests the simd ternary method f against the expected behavior generated by want
-func testInt8x16Ternary(t *testing.T, f func(_, _, _ archsimd.Int8x16) archsimd.Int8x16, want func(_, _, _ []int8) []int8) {
-	n := 16
-	t.Helper()
-	forSliceTriple(t, int8s, n, func(x, y, z []int8) bool {
-		t.Helper()
-		a := archsimd.LoadInt8x16(x)
-		b := archsimd.LoadInt8x16(y)
-		c := archsimd.LoadInt8x16(z)
-		g := make([]int8, n)
-		f(a, b, c).Store(g)
-		w := want(x, y, z)
-		return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
-	})
-}
-
-// testInt16x8Ternary tests the simd ternary method f against the expected behavior generated by want
-func testInt16x8Ternary(t *testing.T, f func(_, _, _ archsimd.Int16x8) archsimd.Int16x8, want func(_, _, _ []int16) []int16) {
-	n := 8
-	t.Helper()
-	forSliceTriple(t, int16s, n, func(x, y, z []int16) bool {
-		t.Helper()
-		a := archsimd.LoadInt16x8(x)
-		b := archsimd.LoadInt16x8(y)
-		c := archsimd.LoadInt16x8(z)
-		g := make([]int16, n)
-		f(a, b, c).Store(g)
-		w := want(x, y, z)
-		return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
-	})
-}
-
-// testInt32x4Ternary tests the simd ternary method f against the expected behavior generated by want
-func testInt32x4Ternary(t *testing.T, f func(_, _, _ archsimd.Int32x4) archsimd.Int32x4, want func(_, _, _ []int32) []int32) {
-	n := 4
-	t.Helper()
-	forSliceTriple(t, int32s, n, func(x, y, z []int32) bool {
-		t.Helper()
-		a := archsimd.LoadInt32x4(x)
-		b := archsimd.LoadInt32x4(y)
-		c := archsimd.LoadInt32x4(z)
-		g := make([]int32, n)
-		f(a, b, c).Store(g)
-		w := want(x, y, z)
-		return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
-	})
-}
-
-// testInt64x2Ternary tests the simd ternary method f against the expected behavior generated by want
-func testInt64x2Ternary(t *testing.T, f func(_, _, _ archsimd.Int64x2) archsimd.Int64x2, want func(_, _, _ []int64) []int64) {
-	n := 2
-	t.Helper()
-	forSliceTriple(t, int64s, n, func(x, y, z []int64) bool {
-		t.Helper()
-		a := archsimd.LoadInt64x2(x)
-		b := archsimd.LoadInt64x2(y)
-		c := archsimd.LoadInt64x2(z)
-		g := make([]int64, n)
-		f(a, b, c).Store(g)
-		w := want(x, y, z)
-		return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
-	})
-}
-
-// testUint8x16Ternary tests the simd ternary method f against the expected behavior generated by want
-func testUint8x16Ternary(t *testing.T, f func(_, _, _ archsimd.Uint8x16) archsimd.Uint8x16, want func(_, _, _ []uint8) []uint8) {
-	n := 16
-	t.Helper()
-	forSliceTriple(t, uint8s, n, func(x, y, z []uint8) bool {
-		t.Helper()
-		a := archsimd.LoadUint8x16(x)
-		b := archsimd.LoadUint8x16(y)
-		c := archsimd.LoadUint8x16(z)
-		g := make([]uint8, n)
-		f(a, b, c).Store(g)
-		w := want(x, y, z)
-		return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
-	})
-}
-
-// testUint16x8Ternary tests the simd ternary method f against the expected behavior generated by want
-func testUint16x8Ternary(t *testing.T, f func(_, _, _ archsimd.Uint16x8) archsimd.Uint16x8, want func(_, _, _ []uint16) []uint16) {
-	n := 8
-	t.Helper()
-	forSliceTriple(t, uint16s, n, func(x, y, z []uint16) bool {
-		t.Helper()
-		a := archsimd.LoadUint16x8(x)
-		b := archsimd.LoadUint16x8(y)
-		c := archsimd.LoadUint16x8(z)
-		g := make([]uint16, n)
-		f(a, b, c).Store(g)
-		w := want(x, y, z)
-		return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
-	})
-}
-
-// testUint32x4Ternary tests the simd ternary method f against the expected behavior generated by want
-func testUint32x4Ternary(t *testing.T, f func(_, _, _ archsimd.Uint32x4) archsimd.Uint32x4, want func(_, _, _ []uint32) []uint32) {
-	n := 4
-	t.Helper()
-	forSliceTriple(t, uint32s, n, func(x, y, z []uint32) bool {
-		t.Helper()
-		a := archsimd.LoadUint32x4(x)
-		b := archsimd.LoadUint32x4(y)
-		c := archsimd.LoadUint32x4(z)
-		g := make([]uint32, n)
-		f(a, b, c).Store(g)
-		w := want(x, y, z)
-		return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
-	})
-}
-
-// testUint64x2Ternary tests the simd ternary method f against the expected behavior generated by want
-func testUint64x2Ternary(t *testing.T, f func(_, _, _ archsimd.Uint64x2) archsimd.Uint64x2, want func(_, _, _ []uint64) []uint64) {
-	n := 2
-	t.Helper()
-	forSliceTriple(t, uint64s, n, func(x, y, z []uint64) bool {
-		t.Helper()
-		a := archsimd.LoadUint64x2(x)
-		b := archsimd.LoadUint64x2(y)
-		c := archsimd.LoadUint64x2(z)
-		g := make([]uint64, n)
-		f(a, b, c).Store(g)
-		w := want(x, y, z)
-		return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
-	})
-}
-
-// testFloat32x4Ternary tests the simd ternary method f against the expected behavior generated by want
-func testFloat32x4Ternary(t *testing.T, f func(_, _, _ archsimd.Float32x4) archsimd.Float32x4, want func(_, _, _ []float32) []float32) {
-	n := 4
-	t.Helper()
-	forSliceTriple(t, float32s, n, func(x, y, z []float32) bool {
-		t.Helper()
-		a := archsimd.LoadFloat32x4(x)
-		b := archsimd.LoadFloat32x4(y)
-		c := archsimd.LoadFloat32x4(z)
-		g := make([]float32, n)
-		f(a, b, c).Store(g)
-		w := want(x, y, z)
-		return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
-	})
-}
-
-// testFloat64x2Ternary tests the simd ternary method f against the expected behavior generated by want
-func testFloat64x2Ternary(t *testing.T, f func(_, _, _ archsimd.Float64x2) archsimd.Float64x2, want func(_, _, _ []float64) []float64) {
-	n := 2
-	t.Helper()
-	forSliceTriple(t, float64s, n, func(x, y, z []float64) bool {
-		t.Helper()
-		a := archsimd.LoadFloat64x2(x)
-		b := archsimd.LoadFloat64x2(y)
-		c := archsimd.LoadFloat64x2(z)
-		g := make([]float64, n)
-		f(a, b, c).Store(g)
-		w := want(x, y, z)
-		return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
-	})
-}
-
-// testInt8x16TernaryFlaky tests the simd ternary method f against the expected behavior generated by want,
-// but using a flakiness parameter because we haven't exactly figured out how simd floating point works
-func testInt8x16TernaryFlaky(t *testing.T, f func(x, y, z archsimd.Int8x16) archsimd.Int8x16, want func(x, y, z []int8) []int8, flakiness float64) {
-	n := 16
-	t.Helper()
-	forSliceTriple(t, int8s, n, func(x, y, z []int8) bool {
-		t.Helper()
-		a := archsimd.LoadInt8x16(x)
-		b := archsimd.LoadInt8x16(y)
-		c := archsimd.LoadInt8x16(z)
-		g := make([]int8, n)
-		f(a, b, c).Store(g)
-		w := want(x, y, z)
-		return checkSlicesLogInput(t, g, w, flakiness, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
-	})
-}
-
-// testInt16x8TernaryFlaky tests the simd ternary method f against the expected behavior generated by want,
-// but using a flakiness parameter because we haven't exactly figured out how simd floating point works
-func testInt16x8TernaryFlaky(t *testing.T, f func(x, y, z archsimd.Int16x8) archsimd.Int16x8, want func(x, y, z []int16) []int16, flakiness float64) {
-	n := 8
-	t.Helper()
-	forSliceTriple(t, int16s, n, func(x, y, z []int16) bool {
-		t.Helper()
-		a := archsimd.LoadInt16x8(x)
-		b := archsimd.LoadInt16x8(y)
-		c := archsimd.LoadInt16x8(z)
-		g := make([]int16, n)
-		f(a, b, c).Store(g)
-		w := want(x, y, z)
-		return checkSlicesLogInput(t, g, w, flakiness, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
-	})
-}
-
-// testInt32x4TernaryFlaky tests the simd ternary method f against the expected behavior generated by want,
-// but using a flakiness parameter because we haven't exactly figured out how simd floating point works
-func testInt32x4TernaryFlaky(t *testing.T, f func(x, y, z archsimd.Int32x4) archsimd.Int32x4, want func(x, y, z []int32) []int32, flakiness float64) {
-	n := 4
-	t.Helper()
-	forSliceTriple(t, int32s, n, func(x, y, z []int32) bool {
-		t.Helper()
-		a := archsimd.LoadInt32x4(x)
-		b := archsimd.LoadInt32x4(y)
-		c := archsimd.LoadInt32x4(z)
-		g := make([]int32, n)
-		f(a, b, c).Store(g)
-		w := want(x, y, z)
-		return checkSlicesLogInput(t, g, w, flakiness, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
-	})
-}
-
-// testInt64x2TernaryFlaky tests the simd ternary method f against the expected behavior generated by want,
-// but using a flakiness parameter because we haven't exactly figured out how simd floating point works
-func testInt64x2TernaryFlaky(t *testing.T, f func(x, y, z archsimd.Int64x2) archsimd.Int64x2, want func(x, y, z []int64) []int64, flakiness float64) {
-	n := 2
-	t.Helper()
-	forSliceTriple(t, int64s, n, func(x, y, z []int64) bool {
-		t.Helper()
-		a := archsimd.LoadInt64x2(x)
-		b := archsimd.LoadInt64x2(y)
-		c := archsimd.LoadInt64x2(z)
-		g := make([]int64, n)
-		f(a, b, c).Store(g)
-		w := want(x, y, z)
-		return checkSlicesLogInput(t, g, w, flakiness, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
-	})
-}
-
-// testUint8x16TernaryFlaky tests the simd ternary method f against the expected behavior generated by want,
-// but using a flakiness parameter because we haven't exactly figured out how simd floating point works
-func testUint8x16TernaryFlaky(t *testing.T, f func(x, y, z archsimd.Uint8x16) archsimd.Uint8x16, want func(x, y, z []uint8) []uint8, flakiness float64) {
-	n := 16
-	t.Helper()
-	forSliceTriple(t, uint8s, n, func(x, y, z []uint8) bool {
-		t.Helper()
-		a := archsimd.LoadUint8x16(x)
-		b := archsimd.LoadUint8x16(y)
-		c := archsimd.LoadUint8x16(z)
-		g := make([]uint8, n)
-		f(a, b, c).Store(g)
-		w := want(x, y, z)
-		return checkSlicesLogInput(t, g, w, flakiness, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
-	})
-}
-
-// testUint16x8TernaryFlaky tests the simd ternary method f against the expected behavior generated by want,
-// but using a flakiness parameter because we haven't exactly figured out how simd floating point works
-func testUint16x8TernaryFlaky(t *testing.T, f func(x, y, z archsimd.Uint16x8) archsimd.Uint16x8, want func(x, y, z []uint16) []uint16, flakiness float64) {
-	n := 8
-	t.Helper()
-	forSliceTriple(t, uint16s, n, func(x, y, z []uint16) bool {
-		t.Helper()
-		a := archsimd.LoadUint16x8(x)
-		b := archsimd.LoadUint16x8(y)
-		c := archsimd.LoadUint16x8(z)
-		g := make([]uint16, n)
-		f(a, b, c).Store(g)
-		w := want(x, y, z)
-		return checkSlicesLogInput(t, g, w, flakiness, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
-	})
-}
-
-// testUint32x4TernaryFlaky tests the simd ternary method f against the expected behavior generated by want,
-// but using a flakiness parameter because we haven't exactly figured out how simd floating point works
-func testUint32x4TernaryFlaky(t *testing.T, f func(x, y, z archsimd.Uint32x4) archsimd.Uint32x4, want func(x, y, z []uint32) []uint32, flakiness float64) {
-	n := 4
-	t.Helper()
-	forSliceTriple(t, uint32s, n, func(x, y, z []uint32) bool {
-		t.Helper()
-		a := archsimd.LoadUint32x4(x)
-		b := archsimd.LoadUint32x4(y)
-		c := archsimd.LoadUint32x4(z)
-		g := make([]uint32, n)
-		f(a, b, c).Store(g)
-		w := want(x, y, z)
-		return checkSlicesLogInput(t, g, w, flakiness, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
-	})
-}
-
-// testUint64x2TernaryFlaky tests the simd ternary method f against the expected behavior generated by want,
-// but using a flakiness parameter because we haven't exactly figured out how simd floating point works
-func testUint64x2TernaryFlaky(t *testing.T, f func(x, y, z archsimd.Uint64x2) archsimd.Uint64x2, want func(x, y, z []uint64) []uint64, flakiness float64) {
-	n := 2
-	t.Helper()
-	forSliceTriple(t, uint64s, n, func(x, y, z []uint64) bool {
-		t.Helper()
-		a := archsimd.LoadUint64x2(x)
-		b := archsimd.LoadUint64x2(y)
-		c := archsimd.LoadUint64x2(z)
-		g := make([]uint64, n)
-		f(a, b, c).Store(g)
-		w := want(x, y, z)
-		return checkSlicesLogInput(t, g, w, flakiness, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
-	})
-}
-
-// testFloat32x4TernaryFlaky tests the simd ternary method f against the expected behavior generated by want,
-// but using a flakiness parameter because we haven't exactly figured out how simd floating point works
-func testFloat32x4TernaryFlaky(t *testing.T, f func(x, y, z archsimd.Float32x4) archsimd.Float32x4, want func(x, y, z []float32) []float32, flakiness float64) {
-	n := 4
-	t.Helper()
-	forSliceTriple(t, float32s, n, func(x, y, z []float32) bool {
-		t.Helper()
-		a := archsimd.LoadFloat32x4(x)
-		b := archsimd.LoadFloat32x4(y)
-		c := archsimd.LoadFloat32x4(z)
-		g := make([]float32, n)
-		f(a, b, c).Store(g)
-		w := want(x, y, z)
-		return checkSlicesLogInput(t, g, w, flakiness, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
-	})
-}
-
-// testFloat64x2TernaryFlaky tests the simd ternary method f against the expected behavior generated by want,
-// but using a flakiness parameter because we haven't exactly figured out how simd floating point works
-func testFloat64x2TernaryFlaky(t *testing.T, f func(x, y, z archsimd.Float64x2) archsimd.Float64x2, want func(x, y, z []float64) []float64, flakiness float64) {
-	n := 2
-	t.Helper()
-	forSliceTriple(t, float64s, n, func(x, y, z []float64) bool {
-		t.Helper()
-		a := archsimd.LoadFloat64x2(x)
-		b := archsimd.LoadFloat64x2(y)
-		c := archsimd.LoadFloat64x2(z)
-		g := make([]float64, n)
-		f(a, b, c).Store(g)
-		w := want(x, y, z)
-		return checkSlicesLogInput(t, g, w, flakiness, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
-	})
-}
diff --git a/src/simd/archsimd/internal/simd_test/ternary_helpers_128_test.go b/src/simd/archsimd/internal/simd_test/ternary_helpers_128_test.go
new file mode 100644
index 0000000..76722d9
--- /dev/null
+++ b/src/simd/archsimd/internal/simd_test/ternary_helpers_128_test.go
@@ -0,0 +1,208 @@
+// Code generated by 'tmplgen'; DO NOT EDIT.
+
+//go:build goexperiment.simd && (amd64 || wasm || arm64)
+
+// This file contains functions testing ternary simd methods.
+// Each function in this file is specialized for a
+// particular simd type <BaseType><Width>x<Count>.
+
+package simd_test
+
+import (
+	"simd/archsimd"
+	"testing"
+)
+
+// testInt8x16Ternary tests the simd ternary method f against the expected behavior generated by want
+func testInt8x16Ternary(t *testing.T, f func(_, _, _ archsimd.Int8x16) archsimd.Int8x16, want func(_, _, _ []int8) []int8) {
+	n := 16
+	t.Helper()
+	forSliceTriple(t, int8s, n, func(x, y, z []int8) bool {
+		t.Helper()
+		a := archsimd.LoadInt8x16(x)
+		b := archsimd.LoadInt8x16(y)
+		c := archsimd.LoadInt8x16(z)
+		g := make([]int8, n)
+		f(a, b, c).Store(g)
+		w := want(x, y, z)
+		return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
+	})
+}
+
+// testInt16x8Ternary tests the simd ternary method f against the expected behavior generated by want
+func testInt16x8Ternary(t *testing.T, f func(_, _, _ archsimd.Int16x8) archsimd.Int16x8, want func(_, _, _ []int16) []int16) {
+	n := 8
+	t.Helper()
+	forSliceTriple(t, int16s, n, func(x, y, z []int16) bool {
+		t.Helper()
+		a := archsimd.LoadInt16x8(x)
+		b := archsimd.LoadInt16x8(y)
+		c := archsimd.LoadInt16x8(z)
+		g := make([]int16, n)
+		f(a, b, c).Store(g)
+		w := want(x, y, z)
+		return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
+	})
+}
+
+// testInt32x4Ternary tests the simd ternary method f against the expected behavior generated by want
+func testInt32x4Ternary(t *testing.T, f func(_, _, _ archsimd.Int32x4) archsimd.Int32x4, want func(_, _, _ []int32) []int32) {
+	n := 4
+	t.Helper()
+	forSliceTriple(t, int32s, n, func(x, y, z []int32) bool {
+		t.Helper()
+		a := archsimd.LoadInt32x4(x)
+		b := archsimd.LoadInt32x4(y)
+		c := archsimd.LoadInt32x4(z)
+		g := make([]int32, n)
+		f(a, b, c).Store(g)
+		w := want(x, y, z)
+		return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
+	})
+}
+
+// testInt64x2Ternary tests the simd ternary method f against the expected behavior generated by want
+func testInt64x2Ternary(t *testing.T, f func(_, _, _ archsimd.Int64x2) archsimd.Int64x2, want func(_, _, _ []int64) []int64) {
+	n := 2
+	t.Helper()
+	forSliceTriple(t, int64s, n, func(x, y, z []int64) bool {
+		t.Helper()
+		a := archsimd.LoadInt64x2(x)
+		b := archsimd.LoadInt64x2(y)
+		c := archsimd.LoadInt64x2(z)
+		g := make([]int64, n)
+		f(a, b, c).Store(g)
+		w := want(x, y, z)
+		return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
+	})
+}
+
+// testUint8x16Ternary tests the simd ternary method f against the expected behavior generated by want
+func testUint8x16Ternary(t *testing.T, f func(_, _, _ archsimd.Uint8x16) archsimd.Uint8x16, want func(_, _, _ []uint8) []uint8) {
+	n := 16
+	t.Helper()
+	forSliceTriple(t, uint8s, n, func(x, y, z []uint8) bool {
+		t.Helper()
+		a := archsimd.LoadUint8x16(x)
+		b := archsimd.LoadUint8x16(y)
+		c := archsimd.LoadUint8x16(z)
+		g := make([]uint8, n)
+		f(a, b, c).Store(g)
+		w := want(x, y, z)
+		return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
+	})
+}
+
+// testUint16x8Ternary tests the simd ternary method f against the expected behavior generated by want
+func testUint16x8Ternary(t *testing.T, f func(_, _, _ archsimd.Uint16x8) archsimd.Uint16x8, want func(_, _, _ []uint16) []uint16) {
+	n := 8
+	t.Helper()
+	forSliceTriple(t, uint16s, n, func(x, y, z []uint16) bool {
+		t.Helper()
+		a := archsimd.LoadUint16x8(x)
+		b := archsimd.LoadUint16x8(y)
+		c := archsimd.LoadUint16x8(z)
+		g := make([]uint16, n)
+		f(a, b, c).Store(g)
+		w := want(x, y, z)
+		return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
+	})
+}
+
+// testUint32x4Ternary tests the simd ternary method f against the expected behavior generated by want
+func testUint32x4Ternary(t *testing.T, f func(_, _, _ archsimd.Uint32x4) archsimd.Uint32x4, want func(_, _, _ []uint32) []uint32) {
+	n := 4
+	t.Helper()
+	forSliceTriple(t, uint32s, n, func(x, y, z []uint32) bool {
+		t.Helper()
+		a := archsimd.LoadUint32x4(x)
+		b := archsimd.LoadUint32x4(y)
+		c := archsimd.LoadUint32x4(z)
+		g := make([]uint32, n)
+		f(a, b, c).Store(g)
+		w := want(x, y, z)
+		return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
+	})
+}
+
+// testUint64x2Ternary tests the simd ternary method f against the expected behavior generated by want
+func testUint64x2Ternary(t *testing.T, f func(_, _, _ archsimd.Uint64x2) archsimd.Uint64x2, want func(_, _, _ []uint64) []uint64) {
+	n := 2
+	t.Helper()
+	forSliceTriple(t, uint64s, n, func(x, y, z []uint64) bool {
+		t.Helper()
+		a := archsimd.LoadUint64x2(x)
+		b := archsimd.LoadUint64x2(y)
+		c := archsimd.LoadUint64x2(z)
+		g := make([]uint64, n)
+		f(a, b, c).Store(g)
+		w := want(x, y, z)
+		return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
+	})
+}
+
+// testFloat32x4Ternary tests the simd ternary method f against the expected behavior generated by want
+func testFloat32x4Ternary(t *testing.T, f func(_, _, _ archsimd.Float32x4) archsimd.Float32x4, want func(_, _, _ []float32) []float32) {
+	n := 4
+	t.Helper()
+	forSliceTriple(t, float32s, n, func(x, y, z []float32) bool {
+		t.Helper()
+		a := archsimd.LoadFloat32x4(x)
+		b := archsimd.LoadFloat32x4(y)
+		c := archsimd.LoadFloat32x4(z)
+		g := make([]float32, n)
+		f(a, b, c).Store(g)
+		w := want(x, y, z)
+		return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
+	})
+}
+
+// testFloat64x2Ternary tests the simd ternary method f against the expected behavior generated by want
+func testFloat64x2Ternary(t *testing.T, f func(_, _, _ archsimd.Float64x2) archsimd.Float64x2, want func(_, _, _ []float64) []float64) {
+	n := 2
+	t.Helper()
+	forSliceTriple(t, float64s, n, func(x, y, z []float64) bool {
+		t.Helper()
+		a := archsimd.LoadFloat64x2(x)
+		b := archsimd.LoadFloat64x2(y)
+		c := archsimd.LoadFloat64x2(z)
+		g := make([]float64, n)
+		f(a, b, c).Store(g)
+		w := want(x, y, z)
+		return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
+	})
+}
+
+// testFloat32x4TernaryFlaky tests the simd ternary method f against the expected behavior generated by want,
+// but using a flakiness parameter because we haven't exactly figured out how simd floating point works
+func testFloat32x4TernaryFlaky(t *testing.T, f func(x, y, z archsimd.Float32x4) archsimd.Float32x4, want func(x, y, z []float32) []float32, flakiness float64) {
+	n := 4
+	t.Helper()
+	forSliceTriple(t, float32s, n, func(x, y, z []float32) bool {
+		t.Helper()
+		a := archsimd.LoadFloat32x4(x)
+		b := archsimd.LoadFloat32x4(y)
+		c := archsimd.LoadFloat32x4(z)
+		g := make([]float32, n)
+		f(a, b, c).Store(g)
+		w := want(x, y, z)
+		return checkSlicesLogInput(t, g, w, flakiness, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
+	})
+}
+
+// testFloat64x2TernaryFlaky tests the simd ternary method f against the expected behavior generated by want,
+// but using a flakiness parameter because we haven't exactly figured out how simd floating point works
+func testFloat64x2TernaryFlaky(t *testing.T, f func(x, y, z archsimd.Float64x2) archsimd.Float64x2, want func(x, y, z []float64) []float64, flakiness float64) {
+	n := 2
+	t.Helper()
+	forSliceTriple(t, float64s, n, func(x, y, z []float64) bool {
+		t.Helper()
+		a := archsimd.LoadFloat64x2(x)
+		b := archsimd.LoadFloat64x2(y)
+		c := archsimd.LoadFloat64x2(z)
+		g := make([]float64, n)
+		f(a, b, c).Store(g)
+		w := want(x, y, z)
+		return checkSlicesLogInput(t, g, w, flakiness, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
+	})
+}
diff --git a/src/simd/archsimd/internal/simd_test/ternary_helpers_test.go b/src/simd/archsimd/internal/simd_test/ternary_helpers_wider_test.go
similarity index 69%
rename from src/simd/archsimd/internal/simd_test/ternary_helpers_test.go
rename to src/simd/archsimd/internal/simd_test/ternary_helpers_wider_test.go
index 03ab918..74b4f03 100644
--- a/src/simd/archsimd/internal/simd_test/ternary_helpers_test.go
+++ b/src/simd/archsimd/internal/simd_test/ternary_helpers_wider_test.go
@@ -13,166 +13,6 @@
 	"testing"
 )
 
-// testInt8x16Ternary tests the simd ternary method f against the expected behavior generated by want
-func testInt8x16Ternary(t *testing.T, f func(_, _, _ archsimd.Int8x16) archsimd.Int8x16, want func(_, _, _ []int8) []int8) {
-	n := 16
-	t.Helper()
-	forSliceTriple(t, int8s, n, func(x, y, z []int8) bool {
-		t.Helper()
-		a := archsimd.LoadInt8x16(x)
-		b := archsimd.LoadInt8x16(y)
-		c := archsimd.LoadInt8x16(z)
-		g := make([]int8, n)
-		f(a, b, c).Store(g)
-		w := want(x, y, z)
-		return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
-	})
-}
-
-// testInt16x8Ternary tests the simd ternary method f against the expected behavior generated by want
-func testInt16x8Ternary(t *testing.T, f func(_, _, _ archsimd.Int16x8) archsimd.Int16x8, want func(_, _, _ []int16) []int16) {
-	n := 8
-	t.Helper()
-	forSliceTriple(t, int16s, n, func(x, y, z []int16) bool {
-		t.Helper()
-		a := archsimd.LoadInt16x8(x)
-		b := archsimd.LoadInt16x8(y)
-		c := archsimd.LoadInt16x8(z)
-		g := make([]int16, n)
-		f(a, b, c).Store(g)
-		w := want(x, y, z)
-		return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
-	})
-}
-
-// testInt32x4Ternary tests the simd ternary method f against the expected behavior generated by want
-func testInt32x4Ternary(t *testing.T, f func(_, _, _ archsimd.Int32x4) archsimd.Int32x4, want func(_, _, _ []int32) []int32) {
-	n := 4
-	t.Helper()
-	forSliceTriple(t, int32s, n, func(x, y, z []int32) bool {
-		t.Helper()
-		a := archsimd.LoadInt32x4(x)
-		b := archsimd.LoadInt32x4(y)
-		c := archsimd.LoadInt32x4(z)
-		g := make([]int32, n)
-		f(a, b, c).Store(g)
-		w := want(x, y, z)
-		return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
-	})
-}
-
-// testInt64x2Ternary tests the simd ternary method f against the expected behavior generated by want
-func testInt64x2Ternary(t *testing.T, f func(_, _, _ archsimd.Int64x2) archsimd.Int64x2, want func(_, _, _ []int64) []int64) {
-	n := 2
-	t.Helper()
-	forSliceTriple(t, int64s, n, func(x, y, z []int64) bool {
-		t.Helper()
-		a := archsimd.LoadInt64x2(x)
-		b := archsimd.LoadInt64x2(y)
-		c := archsimd.LoadInt64x2(z)
-		g := make([]int64, n)
-		f(a, b, c).Store(g)
-		w := want(x, y, z)
-		return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
-	})
-}
-
-// testUint8x16Ternary tests the simd ternary method f against the expected behavior generated by want
-func testUint8x16Ternary(t *testing.T, f func(_, _, _ archsimd.Uint8x16) archsimd.Uint8x16, want func(_, _, _ []uint8) []uint8) {
-	n := 16
-	t.Helper()
-	forSliceTriple(t, uint8s, n, func(x, y, z []uint8) bool {
-		t.Helper()
-		a := archsimd.LoadUint8x16(x)
-		b := archsimd.LoadUint8x16(y)
-		c := archsimd.LoadUint8x16(z)
-		g := make([]uint8, n)
-		f(a, b, c).Store(g)
-		w := want(x, y, z)
-		return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
-	})
-}
-
-// testUint16x8Ternary tests the simd ternary method f against the expected behavior generated by want
-func testUint16x8Ternary(t *testing.T, f func(_, _, _ archsimd.Uint16x8) archsimd.Uint16x8, want func(_, _, _ []uint16) []uint16) {
-	n := 8
-	t.Helper()
-	forSliceTriple(t, uint16s, n, func(x, y, z []uint16) bool {
-		t.Helper()
-		a := archsimd.LoadUint16x8(x)
-		b := archsimd.LoadUint16x8(y)
-		c := archsimd.LoadUint16x8(z)
-		g := make([]uint16, n)
-		f(a, b, c).Store(g)
-		w := want(x, y, z)
-		return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
-	})
-}
-
-// testUint32x4Ternary tests the simd ternary method f against the expected behavior generated by want
-func testUint32x4Ternary(t *testing.T, f func(_, _, _ archsimd.Uint32x4) archsimd.Uint32x4, want func(_, _, _ []uint32) []uint32) {
-	n := 4
-	t.Helper()
-	forSliceTriple(t, uint32s, n, func(x, y, z []uint32) bool {
-		t.Helper()
-		a := archsimd.LoadUint32x4(x)
-		b := archsimd.LoadUint32x4(y)
-		c := archsimd.LoadUint32x4(z)
-		g := make([]uint32, n)
-		f(a, b, c).Store(g)
-		w := want(x, y, z)
-		return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
-	})
-}
-
-// testUint64x2Ternary tests the simd ternary method f against the expected behavior generated by want
-func testUint64x2Ternary(t *testing.T, f func(_, _, _ archsimd.Uint64x2) archsimd.Uint64x2, want func(_, _, _ []uint64) []uint64) {
-	n := 2
-	t.Helper()
-	forSliceTriple(t, uint64s, n, func(x, y, z []uint64) bool {
-		t.Helper()
-		a := archsimd.LoadUint64x2(x)
-		b := archsimd.LoadUint64x2(y)
-		c := archsimd.LoadUint64x2(z)
-		g := make([]uint64, n)
-		f(a, b, c).Store(g)
-		w := want(x, y, z)
-		return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
-	})
-}
-
-// testFloat32x4Ternary tests the simd ternary method f against the expected behavior generated by want
-func testFloat32x4Ternary(t *testing.T, f func(_, _, _ archsimd.Float32x4) archsimd.Float32x4, want func(_, _, _ []float32) []float32) {
-	n := 4
-	t.Helper()
-	forSliceTriple(t, float32s, n, func(x, y, z []float32) bool {
-		t.Helper()
-		a := archsimd.LoadFloat32x4(x)
-		b := archsimd.LoadFloat32x4(y)
-		c := archsimd.LoadFloat32x4(z)
-		g := make([]float32, n)
-		f(a, b, c).Store(g)
-		w := want(x, y, z)
-		return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
-	})
-}
-
-// testFloat64x2Ternary tests the simd ternary method f against the expected behavior generated by want
-func testFloat64x2Ternary(t *testing.T, f func(_, _, _ archsimd.Float64x2) archsimd.Float64x2, want func(_, _, _ []float64) []float64) {
-	n := 2
-	t.Helper()
-	forSliceTriple(t, float64s, n, func(x, y, z []float64) bool {
-		t.Helper()
-		a := archsimd.LoadFloat64x2(x)
-		b := archsimd.LoadFloat64x2(y)
-		c := archsimd.LoadFloat64x2(z)
-		g := make([]float64, n)
-		f(a, b, c).Store(g)
-		w := want(x, y, z)
-		return checkSlicesLogInput(t, g, w, 0.0, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
-	})
-}
-
 // testInt8x32Ternary tests the simd ternary method f against the expected behavior generated by want
 func testInt8x32Ternary(t *testing.T, f func(_, _, _ archsimd.Int8x32) archsimd.Int8x32, want func(_, _, _ []int8) []int8) {
 	n := 32
@@ -493,23 +333,6 @@
 	})
 }
 
-// testFloat32x4TernaryFlaky tests the simd ternary method f against the expected behavior generated by want,
-// but using a flakiness parameter because we haven't exactly figured out how simd floating point works
-func testFloat32x4TernaryFlaky(t *testing.T, f func(x, y, z archsimd.Float32x4) archsimd.Float32x4, want func(x, y, z []float32) []float32, flakiness float64) {
-	n := 4
-	t.Helper()
-	forSliceTriple(t, float32s, n, func(x, y, z []float32) bool {
-		t.Helper()
-		a := archsimd.LoadFloat32x4(x)
-		b := archsimd.LoadFloat32x4(y)
-		c := archsimd.LoadFloat32x4(z)
-		g := make([]float32, n)
-		f(a, b, c).Store(g)
-		w := want(x, y, z)
-		return checkSlicesLogInput(t, g, w, flakiness, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
-	})
-}
-
 // testFloat32x8TernaryFlaky tests the simd ternary method f against the expected behavior generated by want,
 // but using a flakiness parameter because we haven't exactly figured out how simd floating point works
 func testFloat32x8TernaryFlaky(t *testing.T, f func(x, y, z archsimd.Float32x8) archsimd.Float32x8, want func(x, y, z []float32) []float32, flakiness float64) {
@@ -527,6 +350,23 @@
 	})
 }
 
+// testFloat64x4TernaryFlaky tests the simd ternary method f against the expected behavior generated by want,
+// but using a flakiness parameter because we haven't exactly figured out how simd floating point works
+func testFloat64x4TernaryFlaky(t *testing.T, f func(x, y, z archsimd.Float64x4) archsimd.Float64x4, want func(x, y, z []float64) []float64, flakiness float64) {
+	n := 4
+	t.Helper()
+	forSliceTriple(t, float64s, n, func(x, y, z []float64) bool {
+		t.Helper()
+		a := archsimd.LoadFloat64x4(x)
+		b := archsimd.LoadFloat64x4(y)
+		c := archsimd.LoadFloat64x4(z)
+		g := make([]float64, n)
+		f(a, b, c).Store(g)
+		w := want(x, y, z)
+		return checkSlicesLogInput(t, g, w, flakiness, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
+	})
+}
+
 // testFloat32x16TernaryFlaky tests the simd ternary method f against the expected behavior generated by want,
 // but using a flakiness parameter because we haven't exactly figured out how simd floating point works
 func testFloat32x16TernaryFlaky(t *testing.T, f func(x, y, z archsimd.Float32x16) archsimd.Float32x16, want func(x, y, z []float32) []float32, flakiness float64) {
@@ -543,3 +383,20 @@
 		return checkSlicesLogInput(t, g, w, flakiness, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
 	})
 }
+
+// testFloat64x8TernaryFlaky tests the simd ternary method f against the expected behavior generated by want,
+// but using a flakiness parameter because we haven't exactly figured out how simd floating point works
+func testFloat64x8TernaryFlaky(t *testing.T, f func(x, y, z archsimd.Float64x8) archsimd.Float64x8, want func(x, y, z []float64) []float64, flakiness float64) {
+	n := 8
+	t.Helper()
+	forSliceTriple(t, float64s, n, func(x, y, z []float64) bool {
+		t.Helper()
+		a := archsimd.LoadFloat64x8(x)
+		b := archsimd.LoadFloat64x8(y)
+		c := archsimd.LoadFloat64x8(z)
+		g := make([]float64, n)
+		f(a, b, c).Store(g)
+		w := want(x, y, z)
+		return checkSlicesLogInput(t, g, w, flakiness, func() { t.Helper(); t.Logf("x=%v", x); t.Logf("y=%v", y); t.Logf("z=%v", z) })
+	})
+}