diff --git a/src/simd/archsimd/_gen/tmplgen/main.go b/src/simd/archsimd/_gen/tmplgen/main.go
index d6708eb..bee3cd4 100644
--- a/src/simd/archsimd/_gen/tmplgen/main.go
+++ b/src/simd/archsimd/_gen/tmplgen/main.go
@@ -832,7 +832,18 @@
// Merge returns x but with elements set to y where mask is false.
//
// Emulated, CPU Feature: {{.CPUfeature}}
+//
+// Deprecated
+//
+//go:fix inline
func (x {{.VType}}) Merge(y {{.VType}}, mask Mask{{.WxC}}) {{.VType}} {
+ return x.IfElse(mask, y)
+}
+
+// IfElse returns x but with elements set to y where mask is false.
+//
+// Emulated, CPU Feature: {{.CPUfeature}}
+func (x {{.VType}}) IfElse(mask Mask{{.WxC}}, y {{.VType}}) {{.VType}} {
{{- if eq .BxC .WxC -}}
im := mask.ToInt{{.BxC}}()
{{- else}}
@@ -865,7 +876,15 @@
// Merge returns x but with elements set to y where mask is false.
//
// Emulated, CPU Feature: AVX512
+//
+// Deprecated
+//
+//go:fix inline
func (x {{.VType}}) Merge(y {{.VType}}, mask Mask{{.WxC}}) {{.VType}} {
+ return x.IfElse(mask, y)
+}
+
+func (x {{.VType}}) IfElse(mask Mask{{.WxC}}, y {{.VType}}) {{.VType}} {
{{- if eq .Base "Int" }}
return y.blendMasked(x, mask)
{{- else}}
diff --git a/src/simd/archsimd/internal/simd_test/simd_test.go b/src/simd/archsimd/internal/simd_test/simd_test.go
index cdf9499..eee7413 100644
--- a/src/simd/archsimd/internal/simd_test/simd_test.go
+++ b/src/simd/archsimd/internal/simd_test/simd_test.go
@@ -470,6 +470,26 @@
checkSlices[float64](t, s, []float64{4, 2, 3, 4})
}
+func TestIfElseFloat(t *testing.T) {
+ if !archsimd.X86.AVX2() {
+ t.Skip("Test requires X86.AVX2, not available on this hardware")
+ return
+ }
+ k := make([]int64, 4, 4)
+ s := make([]float64, 4, 4)
+
+ a := archsimd.LoadFloat64x4([]float64{1, 2, 3, 4})
+ b := archsimd.LoadFloat64x4([]float64{4, 2, 3, 1})
+ g := a.Greater(b)
+ g.ToInt64x4().Store(k)
+ c := a.IfElse(g, b)
+
+ c.Store(s)
+
+ checkSlices[int64](t, k, []int64{0, 0, 0, -1})
+ checkSlices[float64](t, s, []float64{4, 2, 3, 4})
+}
+
func TestMergeFloat512(t *testing.T) {
if !archsimd.X86.AVX512() {
t.Skip("Test requires X86.AVX512, not available on this hardware")
@@ -495,6 +515,31 @@
checkSlices[float64](t, s, []float64{0, 0, 0, 0, 5, 6, 7, 8})
}
+func TestIfElseFloat512(t *testing.T) {
+ if !archsimd.X86.AVX512() {
+ t.Skip("Test requires X86.AVX512, not available on this hardware")
+ return
+ }
+
+ k := make([]int64, 8, 8)
+ s := make([]float64, 8, 8)
+
+ a := archsimd.LoadFloat64x8([]float64{1, 2, 3, 4, 5, 6, 7, 8})
+ b := archsimd.LoadFloat64x8([]float64{8, 7, 6, 5, 4, 2, 3, 1})
+ g := a.Greater(b)
+ g.ToInt64x8().Store(k)
+ c := a.IfElse(g, b)
+ d := a.Masked(g)
+
+ checkSlices[int64](t, k, []int64{0, 0, 0, 0, -1, -1, -1, -1})
+
+ c.Store(s)
+ checkSlices[float64](t, s, []float64{8, 7, 6, 5, 5, 6, 7, 8})
+
+ d.Store(s)
+ checkSlices[float64](t, s, []float64{0, 0, 0, 0, 5, 6, 7, 8})
+}
+
var ro uint8 = 2
func TestRotateAllVariable(t *testing.T) {
@@ -1214,6 +1259,29 @@
}
}
+func TestMaskedIfElse(t *testing.T) {
+ if !archsimd.X86.AVX2() {
+ t.Skip("Test requires X86.AVX2, not available on this hardware")
+ return
+ }
+ x := archsimd.LoadInt64x4([]int64{1, 2, 3, 4})
+ y := archsimd.LoadInt64x4([]int64{5, 6, 1, 1})
+ z := archsimd.LoadInt64x4([]int64{-1, -2, -3, -4})
+ res := make([]int64, 4)
+ expected := []int64{6, 8, -3, -4}
+ mask := x.Less(y)
+ if archsimd.X86.AVX512() {
+ x.Add(y).IfElse(mask, z).Store(res)
+ } else {
+ x.Add(y).IfElse(mask, z).Store(res)
+ }
+ for i := range 4 {
+ if res[i] != expected[i] {
+ t.Errorf("got %d wanted %d", res[i], expected[i])
+ }
+ }
+}
+
func TestPermuteScalars(t *testing.T) {
x := []int32{11, 12, 13, 14}
want := []int32{12, 13, 14, 11}
diff --git a/src/simd/archsimd/maskmerge_gen_amd64.go b/src/simd/archsimd/maskmerge_gen_amd64.go
index 593ad2d..e5b58a0 100644
--- a/src/simd/archsimd/maskmerge_gen_amd64.go
+++ b/src/simd/archsimd/maskmerge_gen_amd64.go
@@ -15,7 +15,18 @@
// Merge returns x but with elements set to y where mask is false.
//
// Emulated, CPU Feature: AVX
+//
+// Deprecated
+//
+//go:fix inline
func (x Int8x16) Merge(y Int8x16, mask Mask8x16) Int8x16 {
+ return x.IfElse(mask, y)
+}
+
+// IfElse returns x but with elements set to y where mask is false.
+//
+// Emulated, CPU Feature: AVX
+func (x Int8x16) IfElse(mask Mask8x16, y Int8x16) Int8x16 {
im := mask.ToInt8x16()
return y.blend(x, im)
}
@@ -31,7 +42,18 @@
// Merge returns x but with elements set to y where mask is false.
//
// Emulated, CPU Feature: AVX
+//
+// Deprecated
+//
+//go:fix inline
func (x Int16x8) Merge(y Int16x8, mask Mask16x8) Int16x8 {
+ return x.IfElse(mask, y)
+}
+
+// IfElse returns x but with elements set to y where mask is false.
+//
+// Emulated, CPU Feature: AVX
+func (x Int16x8) IfElse(mask Mask16x8, y Int16x8) Int16x8 {
im := mask.ToInt16x8().AsInt8x16()
ix := x.AsInt8x16()
iy := y.AsInt8x16()
@@ -49,7 +71,18 @@
// Merge returns x but with elements set to y where mask is false.
//
// Emulated, CPU Feature: AVX
+//
+// Deprecated
+//
+//go:fix inline
func (x Int32x4) Merge(y Int32x4, mask Mask32x4) Int32x4 {
+ return x.IfElse(mask, y)
+}
+
+// IfElse returns x but with elements set to y where mask is false.
+//
+// Emulated, CPU Feature: AVX
+func (x Int32x4) IfElse(mask Mask32x4, y Int32x4) Int32x4 {
im := mask.ToInt32x4().AsInt8x16()
ix := x.AsInt8x16()
iy := y.AsInt8x16()
@@ -67,7 +100,18 @@
// Merge returns x but with elements set to y where mask is false.
//
// Emulated, CPU Feature: AVX
+//
+// Deprecated
+//
+//go:fix inline
func (x Int64x2) Merge(y Int64x2, mask Mask64x2) Int64x2 {
+ return x.IfElse(mask, y)
+}
+
+// IfElse returns x but with elements set to y where mask is false.
+//
+// Emulated, CPU Feature: AVX
+func (x Int64x2) IfElse(mask Mask64x2, y Int64x2) Int64x2 {
im := mask.ToInt64x2().AsInt8x16()
ix := x.AsInt8x16()
iy := y.AsInt8x16()
@@ -85,7 +129,18 @@
// Merge returns x but with elements set to y where mask is false.
//
// Emulated, CPU Feature: AVX
+//
+// Deprecated
+//
+//go:fix inline
func (x Uint8x16) Merge(y Uint8x16, mask Mask8x16) Uint8x16 {
+ return x.IfElse(mask, y)
+}
+
+// IfElse returns x but with elements set to y where mask is false.
+//
+// Emulated, CPU Feature: AVX
+func (x Uint8x16) IfElse(mask Mask8x16, y Uint8x16) Uint8x16 {
im := mask.ToInt8x16()
ix := x.AsInt8x16()
iy := y.AsInt8x16()
@@ -103,7 +158,18 @@
// Merge returns x but with elements set to y where mask is false.
//
// Emulated, CPU Feature: AVX
+//
+// Deprecated
+//
+//go:fix inline
func (x Uint16x8) Merge(y Uint16x8, mask Mask16x8) Uint16x8 {
+ return x.IfElse(mask, y)
+}
+
+// IfElse returns x but with elements set to y where mask is false.
+//
+// Emulated, CPU Feature: AVX
+func (x Uint16x8) IfElse(mask Mask16x8, y Uint16x8) Uint16x8 {
im := mask.ToInt16x8().AsInt8x16()
ix := x.AsInt8x16()
iy := y.AsInt8x16()
@@ -121,7 +187,18 @@
// Merge returns x but with elements set to y where mask is false.
//
// Emulated, CPU Feature: AVX
+//
+// Deprecated
+//
+//go:fix inline
func (x Uint32x4) Merge(y Uint32x4, mask Mask32x4) Uint32x4 {
+ return x.IfElse(mask, y)
+}
+
+// IfElse returns x but with elements set to y where mask is false.
+//
+// Emulated, CPU Feature: AVX
+func (x Uint32x4) IfElse(mask Mask32x4, y Uint32x4) Uint32x4 {
im := mask.ToInt32x4().AsInt8x16()
ix := x.AsInt8x16()
iy := y.AsInt8x16()
@@ -139,7 +216,18 @@
// Merge returns x but with elements set to y where mask is false.
//
// Emulated, CPU Feature: AVX
+//
+// Deprecated
+//
+//go:fix inline
func (x Uint64x2) Merge(y Uint64x2, mask Mask64x2) Uint64x2 {
+ return x.IfElse(mask, y)
+}
+
+// IfElse returns x but with elements set to y where mask is false.
+//
+// Emulated, CPU Feature: AVX
+func (x Uint64x2) IfElse(mask Mask64x2, y Uint64x2) Uint64x2 {
im := mask.ToInt64x2().AsInt8x16()
ix := x.AsInt8x16()
iy := y.AsInt8x16()
@@ -157,7 +245,18 @@
// Merge returns x but with elements set to y where mask is false.
//
// Emulated, CPU Feature: AVX
+//
+// Deprecated
+//
+//go:fix inline
func (x Float32x4) Merge(y Float32x4, mask Mask32x4) Float32x4 {
+ return x.IfElse(mask, y)
+}
+
+// IfElse returns x but with elements set to y where mask is false.
+//
+// Emulated, CPU Feature: AVX
+func (x Float32x4) IfElse(mask Mask32x4, y Float32x4) Float32x4 {
im := mask.ToInt32x4().AsInt8x16()
ix := x.AsInt8x16()
iy := y.AsInt8x16()
@@ -175,7 +274,18 @@
// Merge returns x but with elements set to y where mask is false.
//
// Emulated, CPU Feature: AVX
+//
+// Deprecated
+//
+//go:fix inline
func (x Float64x2) Merge(y Float64x2, mask Mask64x2) Float64x2 {
+ return x.IfElse(mask, y)
+}
+
+// IfElse returns x but with elements set to y where mask is false.
+//
+// Emulated, CPU Feature: AVX
+func (x Float64x2) IfElse(mask Mask64x2, y Float64x2) Float64x2 {
im := mask.ToInt64x2().AsInt8x16()
ix := x.AsInt8x16()
iy := y.AsInt8x16()
@@ -193,7 +303,18 @@
// Merge returns x but with elements set to y where mask is false.
//
// Emulated, CPU Feature: AVX2
+//
+// Deprecated
+//
+//go:fix inline
func (x Int8x32) Merge(y Int8x32, mask Mask8x32) Int8x32 {
+ return x.IfElse(mask, y)
+}
+
+// IfElse returns x but with elements set to y where mask is false.
+//
+// Emulated, CPU Feature: AVX2
+func (x Int8x32) IfElse(mask Mask8x32, y Int8x32) Int8x32 {
im := mask.ToInt8x32()
return y.blend(x, im)
}
@@ -209,7 +330,18 @@
// Merge returns x but with elements set to y where mask is false.
//
// Emulated, CPU Feature: AVX2
+//
+// Deprecated
+//
+//go:fix inline
func (x Int16x16) Merge(y Int16x16, mask Mask16x16) Int16x16 {
+ return x.IfElse(mask, y)
+}
+
+// IfElse returns x but with elements set to y where mask is false.
+//
+// Emulated, CPU Feature: AVX2
+func (x Int16x16) IfElse(mask Mask16x16, y Int16x16) Int16x16 {
im := mask.ToInt16x16().AsInt8x32()
ix := x.AsInt8x32()
iy := y.AsInt8x32()
@@ -227,7 +359,18 @@
// Merge returns x but with elements set to y where mask is false.
//
// Emulated, CPU Feature: AVX2
+//
+// Deprecated
+//
+//go:fix inline
func (x Int32x8) Merge(y Int32x8, mask Mask32x8) Int32x8 {
+ return x.IfElse(mask, y)
+}
+
+// IfElse returns x but with elements set to y where mask is false.
+//
+// Emulated, CPU Feature: AVX2
+func (x Int32x8) IfElse(mask Mask32x8, y Int32x8) Int32x8 {
im := mask.ToInt32x8().AsInt8x32()
ix := x.AsInt8x32()
iy := y.AsInt8x32()
@@ -245,7 +388,18 @@
// Merge returns x but with elements set to y where mask is false.
//
// Emulated, CPU Feature: AVX2
+//
+// Deprecated
+//
+//go:fix inline
func (x Int64x4) Merge(y Int64x4, mask Mask64x4) Int64x4 {
+ return x.IfElse(mask, y)
+}
+
+// IfElse returns x but with elements set to y where mask is false.
+//
+// Emulated, CPU Feature: AVX2
+func (x Int64x4) IfElse(mask Mask64x4, y Int64x4) Int64x4 {
im := mask.ToInt64x4().AsInt8x32()
ix := x.AsInt8x32()
iy := y.AsInt8x32()
@@ -263,7 +417,18 @@
// Merge returns x but with elements set to y where mask is false.
//
// Emulated, CPU Feature: AVX2
+//
+// Deprecated
+//
+//go:fix inline
func (x Uint8x32) Merge(y Uint8x32, mask Mask8x32) Uint8x32 {
+ return x.IfElse(mask, y)
+}
+
+// IfElse returns x but with elements set to y where mask is false.
+//
+// Emulated, CPU Feature: AVX2
+func (x Uint8x32) IfElse(mask Mask8x32, y Uint8x32) Uint8x32 {
im := mask.ToInt8x32()
ix := x.AsInt8x32()
iy := y.AsInt8x32()
@@ -281,7 +446,18 @@
// Merge returns x but with elements set to y where mask is false.
//
// Emulated, CPU Feature: AVX2
+//
+// Deprecated
+//
+//go:fix inline
func (x Uint16x16) Merge(y Uint16x16, mask Mask16x16) Uint16x16 {
+ return x.IfElse(mask, y)
+}
+
+// IfElse returns x but with elements set to y where mask is false.
+//
+// Emulated, CPU Feature: AVX2
+func (x Uint16x16) IfElse(mask Mask16x16, y Uint16x16) Uint16x16 {
im := mask.ToInt16x16().AsInt8x32()
ix := x.AsInt8x32()
iy := y.AsInt8x32()
@@ -299,7 +475,18 @@
// Merge returns x but with elements set to y where mask is false.
//
// Emulated, CPU Feature: AVX2
+//
+// Deprecated
+//
+//go:fix inline
func (x Uint32x8) Merge(y Uint32x8, mask Mask32x8) Uint32x8 {
+ return x.IfElse(mask, y)
+}
+
+// IfElse returns x but with elements set to y where mask is false.
+//
+// Emulated, CPU Feature: AVX2
+func (x Uint32x8) IfElse(mask Mask32x8, y Uint32x8) Uint32x8 {
im := mask.ToInt32x8().AsInt8x32()
ix := x.AsInt8x32()
iy := y.AsInt8x32()
@@ -317,7 +504,18 @@
// Merge returns x but with elements set to y where mask is false.
//
// Emulated, CPU Feature: AVX2
+//
+// Deprecated
+//
+//go:fix inline
func (x Uint64x4) Merge(y Uint64x4, mask Mask64x4) Uint64x4 {
+ return x.IfElse(mask, y)
+}
+
+// IfElse returns x but with elements set to y where mask is false.
+//
+// Emulated, CPU Feature: AVX2
+func (x Uint64x4) IfElse(mask Mask64x4, y Uint64x4) Uint64x4 {
im := mask.ToInt64x4().AsInt8x32()
ix := x.AsInt8x32()
iy := y.AsInt8x32()
@@ -335,7 +533,18 @@
// Merge returns x but with elements set to y where mask is false.
//
// Emulated, CPU Feature: AVX2
+//
+// Deprecated
+//
+//go:fix inline
func (x Float32x8) Merge(y Float32x8, mask Mask32x8) Float32x8 {
+ return x.IfElse(mask, y)
+}
+
+// IfElse returns x but with elements set to y where mask is false.
+//
+// Emulated, CPU Feature: AVX2
+func (x Float32x8) IfElse(mask Mask32x8, y Float32x8) Float32x8 {
im := mask.ToInt32x8().AsInt8x32()
ix := x.AsInt8x32()
iy := y.AsInt8x32()
@@ -353,7 +562,18 @@
// Merge returns x but with elements set to y where mask is false.
//
// Emulated, CPU Feature: AVX2
+//
+// Deprecated
+//
+//go:fix inline
func (x Float64x4) Merge(y Float64x4, mask Mask64x4) Float64x4 {
+ return x.IfElse(mask, y)
+}
+
+// IfElse returns x but with elements set to y where mask is false.
+//
+// Emulated, CPU Feature: AVX2
+func (x Float64x4) IfElse(mask Mask64x4, y Float64x4) Float64x4 {
im := mask.ToInt64x4().AsInt8x32()
ix := x.AsInt8x32()
iy := y.AsInt8x32()
@@ -371,7 +591,15 @@
// Merge returns x but with elements set to y where mask is false.
//
// Emulated, CPU Feature: AVX512
+//
+// Deprecated
+//
+//go:fix inline
func (x Int8x64) Merge(y Int8x64, mask Mask8x64) Int8x64 {
+ return x.IfElse(mask, y)
+}
+
+func (x Int8x64) IfElse(mask Mask8x64, y Int8x64) Int8x64 {
return y.blendMasked(x, mask)
}
@@ -386,7 +614,15 @@
// Merge returns x but with elements set to y where mask is false.
//
// Emulated, CPU Feature: AVX512
+//
+// Deprecated
+//
+//go:fix inline
func (x Int16x32) Merge(y Int16x32, mask Mask16x32) Int16x32 {
+ return x.IfElse(mask, y)
+}
+
+func (x Int16x32) IfElse(mask Mask16x32, y Int16x32) Int16x32 {
return y.blendMasked(x, mask)
}
@@ -401,7 +637,15 @@
// Merge returns x but with elements set to y where mask is false.
//
// Emulated, CPU Feature: AVX512
+//
+// Deprecated
+//
+//go:fix inline
func (x Int32x16) Merge(y Int32x16, mask Mask32x16) Int32x16 {
+ return x.IfElse(mask, y)
+}
+
+func (x Int32x16) IfElse(mask Mask32x16, y Int32x16) Int32x16 {
return y.blendMasked(x, mask)
}
@@ -416,7 +660,15 @@
// Merge returns x but with elements set to y where mask is false.
//
// Emulated, CPU Feature: AVX512
+//
+// Deprecated
+//
+//go:fix inline
func (x Int64x8) Merge(y Int64x8, mask Mask64x8) Int64x8 {
+ return x.IfElse(mask, y)
+}
+
+func (x Int64x8) IfElse(mask Mask64x8, y Int64x8) Int64x8 {
return y.blendMasked(x, mask)
}
@@ -431,7 +683,15 @@
// Merge returns x but with elements set to y where mask is false.
//
// Emulated, CPU Feature: AVX512
+//
+// Deprecated
+//
+//go:fix inline
func (x Uint8x64) Merge(y Uint8x64, mask Mask8x64) Uint8x64 {
+ return x.IfElse(mask, y)
+}
+
+func (x Uint8x64) IfElse(mask Mask8x64, y Uint8x64) Uint8x64 {
ix := x.AsInt8x64()
iy := y.AsInt8x64()
return iy.blendMasked(ix, mask).AsUint8x64()
@@ -448,7 +708,15 @@
// Merge returns x but with elements set to y where mask is false.
//
// Emulated, CPU Feature: AVX512
+//
+// Deprecated
+//
+//go:fix inline
func (x Uint16x32) Merge(y Uint16x32, mask Mask16x32) Uint16x32 {
+ return x.IfElse(mask, y)
+}
+
+func (x Uint16x32) IfElse(mask Mask16x32, y Uint16x32) Uint16x32 {
ix := x.AsInt16x32()
iy := y.AsInt16x32()
return iy.blendMasked(ix, mask).AsUint16x32()
@@ -465,7 +733,15 @@
// Merge returns x but with elements set to y where mask is false.
//
// Emulated, CPU Feature: AVX512
+//
+// Deprecated
+//
+//go:fix inline
func (x Uint32x16) Merge(y Uint32x16, mask Mask32x16) Uint32x16 {
+ return x.IfElse(mask, y)
+}
+
+func (x Uint32x16) IfElse(mask Mask32x16, y Uint32x16) Uint32x16 {
ix := x.AsInt32x16()
iy := y.AsInt32x16()
return iy.blendMasked(ix, mask).AsUint32x16()
@@ -482,7 +758,15 @@
// Merge returns x but with elements set to y where mask is false.
//
// Emulated, CPU Feature: AVX512
+//
+// Deprecated
+//
+//go:fix inline
func (x Uint64x8) Merge(y Uint64x8, mask Mask64x8) Uint64x8 {
+ return x.IfElse(mask, y)
+}
+
+func (x Uint64x8) IfElse(mask Mask64x8, y Uint64x8) Uint64x8 {
ix := x.AsInt64x8()
iy := y.AsInt64x8()
return iy.blendMasked(ix, mask).AsUint64x8()
@@ -499,7 +783,15 @@
// Merge returns x but with elements set to y where mask is false.
//
// Emulated, CPU Feature: AVX512
+//
+// Deprecated
+//
+//go:fix inline
func (x Float32x16) Merge(y Float32x16, mask Mask32x16) Float32x16 {
+ return x.IfElse(mask, y)
+}
+
+func (x Float32x16) IfElse(mask Mask32x16, y Float32x16) Float32x16 {
ix := x.AsInt32x16()
iy := y.AsInt32x16()
return iy.blendMasked(ix, mask).AsFloat32x16()
@@ -516,7 +808,15 @@
// Merge returns x but with elements set to y where mask is false.
//
// Emulated, CPU Feature: AVX512
+//
+// Deprecated
+//
+//go:fix inline
func (x Float64x8) Merge(y Float64x8, mask Mask64x8) Float64x8 {
+ return x.IfElse(mask, y)
+}
+
+func (x Float64x8) IfElse(mask Mask64x8, y Float64x8) Float64x8 {
ix := x.AsInt64x8()
iy := y.AsInt64x8()
return iy.blendMasked(ix, mask).AsFloat64x8()