1
2
3
4
5 package ssacompile
6
7 import (
8 "math"
9 "math/bits"
10 "testing"
11
12 "cmd/compile/internal/ssa"
13 )
14
15 func testLimitUnaryOpSigned8(t *testing.T, opName string, initLimit ssa.Limit, op func(l ssa.Limit, bitsize uint) ssa.Limit, opImpl func(int8) int8) {
16 for min := math.MinInt8; min <= math.MaxInt8; min++ {
17 for max := min; max <= math.MaxInt8; max++ {
18 realSmallest, realBiggest := int8(math.MaxInt8), int8(math.MinInt8)
19 for i := min; i <= max; i++ {
20 result := opImpl(int8(i))
21 if result < realSmallest {
22 realSmallest = result
23 }
24 if result > realBiggest {
25 realBiggest = result
26 }
27 }
28
29 l := ssa.Limit{Min: int64(min), Max: int64(max), Umin: 0, Umax: math.MaxUint64}
30 l = op(l, 8)
31 l = l.Intersect(initLimit)
32
33 if l.Min != int64(realSmallest) || l.Max != int64(realBiggest) {
34 t.Errorf("%s(%d..%d) = %d..%d; want %d..%d", opName, min, max, l.Min, l.Max, realSmallest, realBiggest)
35 }
36 }
37 }
38 }
39
40 func testLimitUnaryOpUnsigned8(t *testing.T, opName string, initLimit ssa.Limit, op func(l ssa.Limit, bitsize uint) ssa.Limit, opImpl func(uint8) uint8) {
41 for min := 0; min <= math.MaxUint8; min++ {
42 for max := min; max <= math.MaxUint8; max++ {
43 realSmallest, realBiggest := uint8(math.MaxUint8), uint8(0)
44 for i := min; i <= max; i++ {
45 result := opImpl(uint8(i))
46 if result < realSmallest {
47 realSmallest = result
48 }
49 if result > realBiggest {
50 realBiggest = result
51 }
52 }
53
54 l := ssa.Limit{Min: math.MinInt64, Max: math.MaxInt64, Umin: uint64(min), Umax: uint64(max)}
55 l = op(l, 8)
56 l = l.Intersect(initLimit)
57
58 if l.Umin != uint64(realSmallest) || l.Umax != uint64(realBiggest) {
59 t.Errorf("%s(%d..%d) = %d..%d; want %d..%d", opName, min, max, l.Umin, l.Umax, realSmallest, realBiggest)
60 }
61 }
62 }
63 }
64
65 func TestLimitNegSigned(t *testing.T) {
66 testLimitUnaryOpSigned8(t, "neg", ssa.NoLimitForBitsize(8), ssa.Limit.Neg, func(x int8) int8 { return -x })
67 }
68 func TestLimitNegUnsigned(t *testing.T) {
69 testLimitUnaryOpUnsigned8(t, "neg", ssa.NoLimitForBitsize(8), ssa.Limit.Neg, func(x uint8) uint8 { return -x })
70 }
71
72 func TestLimitComSigned(t *testing.T) {
73 testLimitUnaryOpSigned8(t, "com", ssa.NoLimitForBitsize(8), ssa.Limit.Com, func(x int8) int8 { return ^x })
74 }
75 func TestLimitComUnsigned(t *testing.T) {
76 testLimitUnaryOpUnsigned8(t, "com", ssa.NoLimitForBitsize(8), ssa.Limit.Com, func(x uint8) uint8 { return ^x })
77 }
78
79 func TestLimitCtzUnsigned(t *testing.T) {
80 testLimitUnaryOpUnsigned8(t, "ctz", ssa.Limit{Min: -128, Max: 127, Umin: 0, Umax: 8}, ssa.Limit.Ctz, func(x uint8) uint8 { return uint8(bits.TrailingZeros8(x)) })
81 }
82
83 func TestLimitBitlenUnsigned(t *testing.T) {
84 testLimitUnaryOpUnsigned8(t, "bitlen", ssa.Limit{Min: -128, Max: 127, Umin: 0, Umax: 8}, ssa.Limit.Bitlen, func(x uint8) uint8 { return uint8(bits.Len8(x)) })
85 }
86
87 func TestLimitPopcountUnsigned(t *testing.T) {
88 testLimitUnaryOpUnsigned8(t, "popcount", ssa.Limit{Min: -128, Max: 127, Umin: 0, Umax: 8}, ssa.Limit.Popcount, func(x uint8) uint8 { return uint8(bits.OnesCount8(x)) })
89 }
90
91 func TestConvertIntWithBitsize(t *testing.T) {
92 if got := ssa.ConvertIntWithBitsize[int64, uint64](255, 8); got != -1 {
93 t.Errorf("convertIntWithBitsize(255, 8) = %d; want -1", got)
94 }
95 if got := ssa.ConvertIntWithBitsize[uint64, int64](-1, 8); got != 255 {
96 t.Errorf("convertIntWithBitsize(-1, 8) = %d; want 255", got)
97 }
98
99 if got := ssa.ConvertIntWithBitsize[int64, uint64](127, 8); got != 127 {
100 t.Errorf("convertIntWithBitsize(127, 8) = %d; want 127", got)
101 }
102 if got := ssa.ConvertIntWithBitsize[uint64, int64](127, 8); got != 127 {
103 t.Errorf("convertIntWithBitsize(127, 8) = %d; want 127", got)
104 }
105 }
106
View as plain text