Source file test/simd.go

     1  // errorcheck -0 -d=ssa/cpufeatures/debug=1,ssa/rewrite_tern/debug=1
     2  
     3  //go:build goexperiment.simd && amd64
     4  
     5  // Copyright 2025 The Go Authors. All rights reserved.
     6  // Use of this source code is governed by a BSD-style
     7  // license that can be found in the LICENSE file.
     8  
     9  package foo
    10  
    11  import (
    12  	"fmt"
    13  	"simd/archsimd"
    14  )
    15  
    16  func f1(x archsimd.Int8x16) {
    17  	return // ERROR "has features avx"
    18  }
    19  
    20  func g1() archsimd.Int8x16 {
    21  	var x archsimd.Int8x16
    22  	return x // ERROR "has features avx$"
    23  }
    24  
    25  type T1 archsimd.Int8x16
    26  
    27  func (x T1) h() {
    28  	return // ERROR "has features avx$"
    29  }
    30  
    31  func f2(x archsimd.Int8x64) {
    32  	return // ERROR "has features avx[+]avx2[+]avx512$"
    33  }
    34  
    35  func g2() archsimd.Int8x64 {
    36  	var x archsimd.Int8x64
    37  	return x // ERROR "has features avx[+]avx2[+]avx512$"
    38  }
    39  
    40  type T2 archsimd.Int8x64
    41  
    42  func (x T2) h() {
    43  	return // ERROR "has features avx[+]avx2[+]avx512$"
    44  }
    45  
    46  var a int
    47  
    48  func f() {
    49  	if a == 0 {
    50  		if !archsimd.X86.AVX512() {
    51  			return
    52  		}
    53  		println("has avx512") // ERROR "has features avx[+]avx2[+]avx512$"
    54  	} else {
    55  		if !archsimd.X86.AVX2() {
    56  			return
    57  		}
    58  		println("has avx2") // ERROR "has features avx[+]avx2$"
    59  	}
    60  	println("has something")
    61  } // ERROR "has features avx[+]avx2$"
    62  
    63  func g() {
    64  	if archsimd.X86.AVX2() { // ERROR "has features avx[+]avx2$"
    65  		for range 5 { // ERROR "has features avx[+]avx2$"
    66  			if a < 0 { // ERROR "has features avx[+]avx2$"
    67  				a++ // ERROR "has features avx[+]avx2$"
    68  			}
    69  		}
    70  	}
    71  	println("ahoy!") // ERROR "has features avx[+]avx2$" // this is an artifact of flaky block numbering and why isn't it fused?
    72  	if a > 0 {
    73  		a--
    74  	}
    75  }
    76  
    77  //go:noinline
    78  func p() bool {
    79  	return true
    80  }
    81  
    82  func hasIrreducibleLoop() {
    83  	if archsimd.X86.AVX2() {
    84  		goto a // ERROR "has features avx[+]avx2$"
    85  	} else {
    86  		goto b
    87  	}
    88  a:
    89  	println("a")
    90  	if p() {
    91  		goto c
    92  	}
    93  b:
    94  	println("b")
    95  	if p() {
    96  		goto a
    97  	}
    98  c:
    99  	println("c")
   100  }
   101  
   102  func ternRewrite(m, w, x, y, z archsimd.Int32x16) (t0, t1, t2 archsimd.Int32x16) {
   103  	if !archsimd.X86.AVX512() { // ERROR "has features avx[+]avx2[+]avx512$"
   104  		return // ERROR "has features avx[+]avx2[+]avx512$" // all blocks have it because of the vector size
   105  	}
   106  	t0 = w.Xor(y).Xor(z)                            // ERROR "Rewriting.*ternInt"
   107  	t1 = m.And(w.Xor(y).Xor(z.Not()))               // ERROR "Rewriting.*ternInt"
   108  	t2 = x.Xor(y).Xor(z).And(x.Xor(y).Xor(z.Not())) // ERROR "Rewriting.*ternInt"
   109  	return                                          // ERROR "has features avx[+]avx2[+]avx512$"
   110  }
   111  
   112  func ternTricky1(x, y, z archsimd.Int32x8) archsimd.Int32x8 {
   113  	// Int32x8 is a 256-bit vector and does not guarantee AVX-512
   114  	// a is a 3-variable logical expression occurring outside AVX-512 feature check
   115  	a := x.Xor(y).Xor(z)
   116  	var w archsimd.Int32x8
   117  	if !archsimd.X86.AVX512() { // ERROR "has features avx$"
   118  		// do nothing
   119  	} else {
   120  		w = y.AndNot(a) // ERROR "has features avx[+]avx2[+]avx512" "Rewriting.*ternInt"
   121  	}
   122  	// a is a common subexpression
   123  	return a.Or(w) // ERROR "has features avx$"
   124  }
   125  
   126  func ternTricky2(x, y, z archsimd.Int32x8) archsimd.Int32x8 {
   127  	// Int32x8 is a 256-bit vector and does not guarantee AVX-512
   128  	var a, w archsimd.Int32x8
   129  	if !archsimd.X86.AVX512() { // ERROR "has features avx$"
   130  		// do nothing
   131  	} else {
   132  		a = x.Xor(y).Xor(z)
   133  		w = y.AndNot(a) // ERROR "has features avx[+]avx2[+]avx512" "Rewriting.*ternInt"
   134  	}
   135  	// a is a common subexpression
   136  	return a.Or(w) // ERROR "has features avx$"
   137  }
   138  
   139  func ternTricky3(x, y, z archsimd.Int32x8) archsimd.Int32x8 {
   140  	// Int32x8 is a 256-bit vector and does not guarantee AVX-512
   141  	a := x.Xor(y).Xor(z)
   142  	w := y.AndNot(a)
   143  	if !archsimd.X86.AVX512() { // ERROR "has features avx$"
   144  		return a // ERROR "has features avx$"
   145  	}
   146  	// a is a common subexpression
   147  	return a.Or(w) // ERROR "has features avx[+]avx2[+]avx512"  // This does not rewrite, do we want it to?
   148  }
   149  
   150  func vpternlogdPanic() {
   151  	resultsMask := archsimd.Mask64x8{}
   152  
   153  	for { // ERROR "has features avx[+]avx2[+]avx512"
   154  		resultsMask = archsimd.Mask64x8FromBits(0).Or( // ERROR "has features avx[+]avx2[+]avx512"
   155  			archsimd.Float64x8{}.Less(
   156  				archsimd.BroadcastFloat64x8(0))).Or(resultsMask) // ERROR "Rewriting.*ternInt" "Skipping rewrite"
   157  		fmt.Print(resultsMask.And(resultsMask.And(archsimd.Mask64x8{})))
   158  	}
   159  }
   160  

View as plain text