Source file src/simd/archsimd/internal/simd_test/convert_sve_arm64_test.go

     1  // Copyright 2026 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:build goexperiment.simd && arm64
     6  
     7  package simd_test
     8  
     9  import (
    10  	"math"
    11  	"simd/archsimd"
    12  	"testing"
    13  )
    14  
    15  // fcvtzs32 is FCVTZS on one float32: truncate toward zero, saturate out of
    16  // range values, and convert NaN to 0.
    17  func fcvtzs32(x float32) int32 {
    18  	switch {
    19  	case x != x:
    20  		return 0
    21  	case x >= math.MaxInt32:
    22  		return math.MaxInt32
    23  	case x <= math.MinInt32:
    24  		return math.MinInt32
    25  	}
    26  	return int32(x)
    27  }
    28  
    29  func TestConvertToInt32SVE(t *testing.T) {
    30  	if !archsimd.ARM64.SVE() {
    31  		t.Skip("no SVE")
    32  	}
    33  	n := archsimd.Float32s{}.Len()
    34  	vals := []float32{0, 0.5, -0.5, 1.5, -1.5, 2.999, -2.999, 1e9, -1e9, 3e9, -3e9,
    35  		float32(math.Inf(1)), float32(math.Inf(-1)), float32(math.NaN()), float32(math.Copysign(0, -1))}
    36  	xs := make([]float32, n)
    37  	got := make([]int32, n)
    38  	for start := 0; start < len(vals); start += n {
    39  		for i := range xs {
    40  			xs[i] = vals[(start+i)%len(vals)]
    41  		}
    42  		archsimd.LoadFloat32s(xs).ConvertToInt32().Store(got)
    43  		for i, x := range xs {
    44  			if want := fcvtzs32(x); got[i] != want {
    45  				t.Errorf("ConvertToInt32(%v) = %d, want %d", x, got[i], want)
    46  			}
    47  		}
    48  	}
    49  
    50  	// A select over the conversion folds into its merging form.
    51  	ys := make([]int32, n)
    52  	for i := range xs {
    53  		xs[i] = float32(i) + 0.75
    54  		ys[i] = -int32(i) - 100
    55  	}
    56  	m := archsimd.LoadFloat32s(xs).Greater(archsimd.BroadcastFloat32s(float32(n) / 2))
    57  	archsimd.LoadFloat32s(xs).ConvertToInt32().IfElse(m, archsimd.LoadInt32s(ys)).Store(got)
    58  	for i, x := range xs {
    59  		want := ys[i]
    60  		if x > float32(n)/2 {
    61  			want = int32(i)
    62  		}
    63  		if got[i] != want {
    64  			t.Errorf("ConvertToInt32 under IfElse: lane %d = %d, want %d", i, got[i], want)
    65  		}
    66  	}
    67  }
    68  

View as plain text