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 "simd"
    12  
    13  func f1(x simd.Int8x16) {
    14  	return // ERROR "has features avx"
    15  }
    16  
    17  func g1() simd.Int8x16 {
    18  	var x simd.Int8x16
    19  	return x // ERROR "has features avx$"
    20  }
    21  
    22  type T1 simd.Int8x16
    23  
    24  func (x T1) h() {
    25  	return // ERROR "has features avx$"
    26  }
    27  
    28  func f2(x simd.Int8x64) {
    29  	return // ERROR "has features avx[+]avx2[+]avx512$"
    30  }
    31  
    32  func g2() simd.Int8x64 {
    33  	var x simd.Int8x64
    34  	return x // ERROR "has features avx[+]avx2[+]avx512$"
    35  }
    36  
    37  type T2 simd.Int8x64
    38  
    39  func (x T2) h() {
    40  	return // ERROR "has features avx[+]avx2[+]avx512$"
    41  }
    42  
    43  var a int
    44  
    45  func f() {
    46  	if a == 0 {
    47  		if !simd.X86.AVX512() {
    48  			return
    49  		}
    50  		println("has avx512") // ERROR "has features avx[+]avx2[+]avx512$"
    51  	} else {
    52  		if !simd.X86.AVX2() {
    53  			return
    54  		}
    55  		println("has avx2") // ERROR "has features avx[+]avx2$"
    56  	}
    57  	println("has something")
    58  } // ERROR "has features avx[+]avx2$"
    59  
    60  func g() {
    61  	if simd.X86.AVX2() { // ERROR "has features avx[+]avx2$"
    62  		for range 5 { // ERROR "has features avx[+]avx2$"
    63  			if a < 0 { // ERROR "has features avx[+]avx2$"
    64  				a++ // ERROR "has features avx[+]avx2$"
    65  			}
    66  		}
    67  	}
    68  	println("ahoy!") // ERROR "has features avx[+]avx2$" // this is an artifact of flaky block numbering and why isn't it fused?
    69  	if a > 0 {
    70  		a--
    71  	}
    72  }
    73  
    74  //go:noinline
    75  func p() bool {
    76  	return true
    77  }
    78  
    79  func hasIrreducibleLoop() {
    80  	if simd.X86.AVX2() {
    81  		goto a // ERROR "has features avx[+]avx2$"
    82  	} else {
    83  		goto b
    84  	}
    85  a:
    86  	println("a")
    87  	if p() {
    88  		goto c
    89  	}
    90  b:
    91  	println("b")
    92  	if p() {
    93  		goto a
    94  	}
    95  c:
    96  	println("c")
    97  }
    98  
    99  func ternRewrite(m, w, x, y, z simd.Int32x16) (t0, t1, t2 simd.Int32x16) {
   100  	if !simd.X86.AVX512() { // ERROR "has features avx[+]avx2[+]avx512$"
   101  		return // ERROR "has features avx[+]avx2[+]avx512$" // all blocks have it because of the vector size
   102  	}
   103  	t0 = w.Xor(y).Xor(z)                            // ERROR "Rewriting.*ternInt"
   104  	t1 = m.And(w.Xor(y).Xor(z.Not()))               // ERROR "Rewriting.*ternInt"
   105  	t2 = x.Xor(y).Xor(z).And(x.Xor(y).Xor(z.Not())) // ERROR "Rewriting.*ternInt"
   106  	return                                          // ERROR "has features avx[+]avx2[+]avx512$"
   107  }
   108  
   109  func ternTricky1(x, y, z simd.Int32x8) simd.Int32x8 {
   110  	// Int32x8 is a 256-bit vector and does not guarantee AVX-512
   111  	// a is a 3-variable logical expression occurring outside AVX-512 feature check
   112  	a := x.Xor(y).Xor(z)
   113  	var w simd.Int32x8
   114  	if !simd.X86.AVX512() { // ERROR "has features avx$"
   115  		// do nothing
   116  	} else {
   117  		w = y.AndNot(a) // ERROR "has features avx[+]avx2[+]avx512" "Rewriting.*ternInt"
   118  	}
   119  	// a is a common subexpression
   120  	return a.Or(w) // ERROR "has features avx$"
   121  }
   122  
   123  func ternTricky2(x, y, z simd.Int32x8) simd.Int32x8 {
   124  	// Int32x8 is a 256-bit vector and does not guarantee AVX-512
   125  	var a, w simd.Int32x8
   126  	if !simd.X86.AVX512() { // ERROR "has features avx$"
   127  		// do nothing
   128  	} else {
   129  		a = x.Xor(y).Xor(z)
   130  		w = y.AndNot(a) // ERROR "has features avx[+]avx2[+]avx512" "Rewriting.*ternInt"
   131  	}
   132  	// a is a common subexpression
   133  	return a.Or(w) // ERROR "has features avx$"
   134  }
   135  
   136  func ternTricky3(x, y, z simd.Int32x8) simd.Int32x8 {
   137  	// Int32x8 is a 256-bit vector and does not guarantee AVX-512
   138  	a := x.Xor(y).Xor(z)
   139  	w := y.AndNot(a)
   140  	if !simd.X86.AVX512() { // ERROR "has features avx$"
   141  		return a // ERROR "has features avx$"
   142  	}
   143  	// a is a common subexpression
   144  	return a.Or(w) // ERROR "has features avx[+]avx2[+]avx512"  // This does not rewrite, do we want it to?
   145  }
   146  

View as plain text