Source file src/cmd/compile/internal/ssa/prove_test.go

     1  // Copyright 2025 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  package ssa
     6  
     7  import (
     8  	"math"
     9  	"math/bits"
    10  	"testing"
    11  )
    12  
    13  func testLimitUnaryOpSigned8(t *testing.T, opName string, initLimit limit, op func(l limit, bitsize uint) limit, opImpl func(int8) int8) {
    14  	for min := math.MinInt8; min <= math.MaxInt8; min++ {
    15  		for max := min; max <= math.MaxInt8; max++ {
    16  			realSmallest, realBiggest := int8(math.MaxInt8), int8(math.MinInt8)
    17  			for i := min; i <= max; i++ {
    18  				result := opImpl(int8(i))
    19  				if result < realSmallest {
    20  					realSmallest = result
    21  				}
    22  				if result > realBiggest {
    23  					realBiggest = result
    24  				}
    25  			}
    26  
    27  			l := limit{int64(min), int64(max), 0, math.MaxUint64}
    28  			l = op(l, 8)
    29  			l = l.intersect(initLimit) // We assume this is gonna be used by newLimit which is seeded by the op size already.
    30  
    31  			if l.min != int64(realSmallest) || l.max != int64(realBiggest) {
    32  				t.Errorf("%s(%d..%d) = %d..%d; want %d..%d", opName, min, max, l.min, l.max, realSmallest, realBiggest)
    33  			}
    34  		}
    35  	}
    36  }
    37  
    38  func testLimitUnaryOpUnsigned8(t *testing.T, opName string, initLimit limit, op func(l limit, bitsize uint) limit, opImpl func(uint8) uint8) {
    39  	for min := 0; min <= math.MaxUint8; min++ {
    40  		for max := min; max <= math.MaxUint8; max++ {
    41  			realSmallest, realBiggest := uint8(math.MaxUint8), uint8(0)
    42  			for i := min; i <= max; i++ {
    43  				result := opImpl(uint8(i))
    44  				if result < realSmallest {
    45  					realSmallest = result
    46  				}
    47  				if result > realBiggest {
    48  					realBiggest = result
    49  				}
    50  			}
    51  
    52  			l := limit{math.MinInt64, math.MaxInt64, uint64(min), uint64(max)}
    53  			l = op(l, 8)
    54  			l = l.intersect(initLimit) // We assume this is gonna be used by newLimit which is seeded by the op size already.
    55  
    56  			if l.umin != uint64(realSmallest) || l.umax != uint64(realBiggest) {
    57  				t.Errorf("%s(%d..%d) = %d..%d; want %d..%d", opName, min, max, l.umin, l.umax, realSmallest, realBiggest)
    58  			}
    59  		}
    60  	}
    61  }
    62  
    63  func TestLimitNegSigned(t *testing.T) {
    64  	testLimitUnaryOpSigned8(t, "neg", noLimitForBitsize(8), limit.neg, func(x int8) int8 { return -x })
    65  }
    66  func TestLimitNegUnsigned(t *testing.T) {
    67  	testLimitUnaryOpUnsigned8(t, "neg", noLimitForBitsize(8), limit.neg, func(x uint8) uint8 { return -x })
    68  }
    69  
    70  func TestLimitComSigned(t *testing.T) {
    71  	testLimitUnaryOpSigned8(t, "com", noLimitForBitsize(8), limit.com, func(x int8) int8 { return ^x })
    72  }
    73  func TestLimitComUnsigned(t *testing.T) {
    74  	testLimitUnaryOpUnsigned8(t, "com", noLimitForBitsize(8), limit.com, func(x uint8) uint8 { return ^x })
    75  }
    76  
    77  func TestLimitCtzUnsigned(t *testing.T) {
    78  	testLimitUnaryOpUnsigned8(t, "ctz", limit{-128, 127, 0, 8}, limit.ctz, func(x uint8) uint8 { return uint8(bits.TrailingZeros8(x)) })
    79  }
    80  
    81  func TestLimitBitlenUnsigned(t *testing.T) {
    82  	testLimitUnaryOpUnsigned8(t, "bitlen", limit{-128, 127, 0, 8}, limit.bitlen, func(x uint8) uint8 { return uint8(bits.Len8(x)) })
    83  }
    84  
    85  func TestLimitPopcountUnsigned(t *testing.T) {
    86  	testLimitUnaryOpUnsigned8(t, "popcount", limit{-128, 127, 0, 8}, limit.popcount, func(x uint8) uint8 { return uint8(bits.OnesCount8(x)) })
    87  }
    88  

View as plain text