Source file src/cmd/compile/internal/test/logic_test.go

     1  // Copyright 2016 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 test
     6  
     7  import "testing"
     8  
     9  // Tests to make sure logic simplification rules are correct.
    10  
    11  func TestLogic64(t *testing.T) {
    12  	// test values to determine function equality
    13  	values := [...]int64{-1 << 63, 1<<63 - 1, -4, -3, -2, -1, 0, 1, 2, 3, 4}
    14  
    15  	// golden functions we use repeatedly
    16  	zero := func(x int64) int64 { return 0 }
    17  	id := func(x int64) int64 { return x }
    18  	or := func(x, y int64) int64 { return x | y }
    19  	and := func(x, y int64) int64 { return x & y }
    20  	y := func(x, y int64) int64 { return y }
    21  
    22  	for _, test := range [...]struct {
    23  		name   string
    24  		f      func(int64) int64
    25  		golden func(int64) int64
    26  	}{
    27  		{"x|x", func(x int64) int64 { return x | x }, id},
    28  		{"x|0", func(x int64) int64 { return x | 0 }, id},
    29  		{"x|-1", func(x int64) int64 { return x | -1 }, func(x int64) int64 { return -1 }},
    30  		{"x&x", func(x int64) int64 { return x & x }, id},
    31  		{"x&0", func(x int64) int64 { return x & 0 }, zero},
    32  		{"x&-1", func(x int64) int64 { return x & -1 }, id},
    33  		{"x^x", func(x int64) int64 { return x ^ x }, zero},
    34  		{"x^0", func(x int64) int64 { return x ^ 0 }, id},
    35  		{"x^-1", func(x int64) int64 { return x ^ -1 }, func(x int64) int64 { return ^x }},
    36  		{"x+0", func(x int64) int64 { return x + 0 }, id},
    37  		{"x-x", func(x int64) int64 { return x - x }, zero},
    38  		{"x*0", func(x int64) int64 { return x * 0 }, zero},
    39  		{"^^x", func(x int64) int64 { return ^^x }, id},
    40  	} {
    41  		for _, v := range values {
    42  			got := test.f(v)
    43  			want := test.golden(v)
    44  			if want != got {
    45  				t.Errorf("[%s](%d)=%d, want %d", test.name, v, got, want)
    46  			}
    47  		}
    48  	}
    49  	for _, test := range [...]struct {
    50  		name   string
    51  		f      func(int64, int64) int64
    52  		golden func(int64, int64) int64
    53  	}{
    54  		{"x|(x|y)", func(x, y int64) int64 { return x | (x | y) }, or},
    55  		{"x|(y|x)", func(x, y int64) int64 { return x | (y | x) }, or},
    56  		{"(x|y)|x", func(x, y int64) int64 { return (x | y) | x }, or},
    57  		{"(y|x)|x", func(x, y int64) int64 { return (y | x) | x }, or},
    58  		{"x&(x&y)", func(x, y int64) int64 { return x & (x & y) }, and},
    59  		{"x&(y&x)", func(x, y int64) int64 { return x & (y & x) }, and},
    60  		{"(x&y)&x", func(x, y int64) int64 { return (x & y) & x }, and},
    61  		{"(y&x)&x", func(x, y int64) int64 { return (y & x) & x }, and},
    62  		{"x^(x^y)", func(x, y int64) int64 { return x ^ (x ^ y) }, y},
    63  		{"x^(y^x)", func(x, y int64) int64 { return x ^ (y ^ x) }, y},
    64  		{"(x^y)^x", func(x, y int64) int64 { return (x ^ y) ^ x }, y},
    65  		{"(y^x)^x", func(x, y int64) int64 { return (y ^ x) ^ x }, y},
    66  		{"-(y-x)", func(x, y int64) int64 { return -(y - x) }, func(x, y int64) int64 { return x - y }},
    67  		{"(x+y)-x", func(x, y int64) int64 { return (x + y) - x }, y},
    68  		{"(y+x)-x", func(x, y int64) int64 { return (y + x) - x }, y},
    69  	} {
    70  		for _, v := range values {
    71  			for _, w := range values {
    72  				got := test.f(v, w)
    73  				want := test.golden(v, w)
    74  				if want != got {
    75  					t.Errorf("[%s](%d,%d)=%d, want %d", test.name, v, w, got, want)
    76  				}
    77  			}
    78  		}
    79  	}
    80  }
    81  
    82  func TestLogic32(t *testing.T) {
    83  	// test values to determine function equality
    84  	values := [...]int32{-1 << 31, 1<<31 - 1, -4, -3, -2, -1, 0, 1, 2, 3, 4}
    85  
    86  	// golden functions we use repeatedly
    87  	zero := func(x int32) int32 { return 0 }
    88  	id := func(x int32) int32 { return x }
    89  	or := func(x, y int32) int32 { return x | y }
    90  	and := func(x, y int32) int32 { return x & y }
    91  	y := func(x, y int32) int32 { return y }
    92  
    93  	for _, test := range [...]struct {
    94  		name   string
    95  		f      func(int32) int32
    96  		golden func(int32) int32
    97  	}{
    98  		{"x|x", func(x int32) int32 { return x | x }, id},
    99  		{"x|0", func(x int32) int32 { return x | 0 }, id},
   100  		{"x|-1", func(x int32) int32 { return x | -1 }, func(x int32) int32 { return -1 }},
   101  		{"x&x", func(x int32) int32 { return x & x }, id},
   102  		{"x&0", func(x int32) int32 { return x & 0 }, zero},
   103  		{"x&-1", func(x int32) int32 { return x & -1 }, id},
   104  		{"x^x", func(x int32) int32 { return x ^ x }, zero},
   105  		{"x^0", func(x int32) int32 { return x ^ 0 }, id},
   106  		{"x^-1", func(x int32) int32 { return x ^ -1 }, func(x int32) int32 { return ^x }},
   107  		{"x+0", func(x int32) int32 { return x + 0 }, id},
   108  		{"x-x", func(x int32) int32 { return x - x }, zero},
   109  		{"x*0", func(x int32) int32 { return x * 0 }, zero},
   110  		{"^^x", func(x int32) int32 { return ^^x }, id},
   111  	} {
   112  		for _, v := range values {
   113  			got := test.f(v)
   114  			want := test.golden(v)
   115  			if want != got {
   116  				t.Errorf("[%s](%d)=%d, want %d", test.name, v, got, want)
   117  			}
   118  		}
   119  	}
   120  	for _, test := range [...]struct {
   121  		name   string
   122  		f      func(int32, int32) int32
   123  		golden func(int32, int32) int32
   124  	}{
   125  		{"x|(x|y)", func(x, y int32) int32 { return x | (x | y) }, or},
   126  		{"x|(y|x)", func(x, y int32) int32 { return x | (y | x) }, or},
   127  		{"(x|y)|x", func(x, y int32) int32 { return (x | y) | x }, or},
   128  		{"(y|x)|x", func(x, y int32) int32 { return (y | x) | x }, or},
   129  		{"x&(x&y)", func(x, y int32) int32 { return x & (x & y) }, and},
   130  		{"x&(y&x)", func(x, y int32) int32 { return x & (y & x) }, and},
   131  		{"(x&y)&x", func(x, y int32) int32 { return (x & y) & x }, and},
   132  		{"(y&x)&x", func(x, y int32) int32 { return (y & x) & x }, and},
   133  		{"x^(x^y)", func(x, y int32) int32 { return x ^ (x ^ y) }, y},
   134  		{"x^(y^x)", func(x, y int32) int32 { return x ^ (y ^ x) }, y},
   135  		{"(x^y)^x", func(x, y int32) int32 { return (x ^ y) ^ x }, y},
   136  		{"(y^x)^x", func(x, y int32) int32 { return (y ^ x) ^ x }, y},
   137  		{"-(y-x)", func(x, y int32) int32 { return -(y - x) }, func(x, y int32) int32 { return x - y }},
   138  		{"(x+y)-x", func(x, y int32) int32 { return (x + y) - x }, y},
   139  		{"(y+x)-x", func(x, y int32) int32 { return (y + x) - x }, y},
   140  	} {
   141  		for _, v := range values {
   142  			for _, w := range values {
   143  				got := test.f(v, w)
   144  				want := test.golden(v, w)
   145  				if want != got {
   146  					t.Errorf("[%s](%d,%d)=%d, want %d", test.name, v, w, got, want)
   147  				}
   148  			}
   149  		}
   150  	}
   151  }
   152  
   153  func TestLogic16(t *testing.T) {
   154  	// test values to determine function equality
   155  	values := [...]int16{-1 << 15, 1<<15 - 1, -4, -3, -2, -1, 0, 1, 2, 3, 4}
   156  
   157  	// golden functions we use repeatedly
   158  	zero := func(x int16) int16 { return 0 }
   159  	id := func(x int16) int16 { return x }
   160  	or := func(x, y int16) int16 { return x | y }
   161  	and := func(x, y int16) int16 { return x & y }
   162  	y := func(x, y int16) int16 { return y }
   163  
   164  	for _, test := range [...]struct {
   165  		name   string
   166  		f      func(int16) int16
   167  		golden func(int16) int16
   168  	}{
   169  		{"x|x", func(x int16) int16 { return x | x }, id},
   170  		{"x|0", func(x int16) int16 { return x | 0 }, id},
   171  		{"x|-1", func(x int16) int16 { return x | -1 }, func(x int16) int16 { return -1 }},
   172  		{"x&x", func(x int16) int16 { return x & x }, id},
   173  		{"x&0", func(x int16) int16 { return x & 0 }, zero},
   174  		{"x&-1", func(x int16) int16 { return x & -1 }, id},
   175  		{"x^x", func(x int16) int16 { return x ^ x }, zero},
   176  		{"x^0", func(x int16) int16 { return x ^ 0 }, id},
   177  		{"x^-1", func(x int16) int16 { return x ^ -1 }, func(x int16) int16 { return ^x }},
   178  		{"x+0", func(x int16) int16 { return x + 0 }, id},
   179  		{"x-x", func(x int16) int16 { return x - x }, zero},
   180  		{"x*0", func(x int16) int16 { return x * 0 }, zero},
   181  		{"^^x", func(x int16) int16 { return ^^x }, id},
   182  	} {
   183  		for _, v := range values {
   184  			got := test.f(v)
   185  			want := test.golden(v)
   186  			if want != got {
   187  				t.Errorf("[%s](%d)=%d, want %d", test.name, v, got, want)
   188  			}
   189  		}
   190  	}
   191  	for _, test := range [...]struct {
   192  		name   string
   193  		f      func(int16, int16) int16
   194  		golden func(int16, int16) int16
   195  	}{
   196  		{"x|(x|y)", func(x, y int16) int16 { return x | (x | y) }, or},
   197  		{"x|(y|x)", func(x, y int16) int16 { return x | (y | x) }, or},
   198  		{"(x|y)|x", func(x, y int16) int16 { return (x | y) | x }, or},
   199  		{"(y|x)|x", func(x, y int16) int16 { return (y | x) | x }, or},
   200  		{"x&(x&y)", func(x, y int16) int16 { return x & (x & y) }, and},
   201  		{"x&(y&x)", func(x, y int16) int16 { return x & (y & x) }, and},
   202  		{"(x&y)&x", func(x, y int16) int16 { return (x & y) & x }, and},
   203  		{"(y&x)&x", func(x, y int16) int16 { return (y & x) & x }, and},
   204  		{"x^(x^y)", func(x, y int16) int16 { return x ^ (x ^ y) }, y},
   205  		{"x^(y^x)", func(x, y int16) int16 { return x ^ (y ^ x) }, y},
   206  		{"(x^y)^x", func(x, y int16) int16 { return (x ^ y) ^ x }, y},
   207  		{"(y^x)^x", func(x, y int16) int16 { return (y ^ x) ^ x }, y},
   208  		{"-(y-x)", func(x, y int16) int16 { return -(y - x) }, func(x, y int16) int16 { return x - y }},
   209  		{"(x+y)-x", func(x, y int16) int16 { return (x + y) - x }, y},
   210  		{"(y+x)-x", func(x, y int16) int16 { return (y + x) - x }, y},
   211  	} {
   212  		for _, v := range values {
   213  			for _, w := range values {
   214  				got := test.f(v, w)
   215  				want := test.golden(v, w)
   216  				if want != got {
   217  					t.Errorf("[%s](%d,%d)=%d, want %d", test.name, v, w, got, want)
   218  				}
   219  			}
   220  		}
   221  	}
   222  }
   223  
   224  func TestLogic8(t *testing.T) {
   225  	// test values to determine function equality
   226  	values := [...]int8{-1 << 7, 1<<7 - 1, -4, -3, -2, -1, 0, 1, 2, 3, 4}
   227  
   228  	// golden functions we use repeatedly
   229  	zero := func(x int8) int8 { return 0 }
   230  	id := func(x int8) int8 { return x }
   231  	or := func(x, y int8) int8 { return x | y }
   232  	and := func(x, y int8) int8 { return x & y }
   233  	y := func(x, y int8) int8 { return y }
   234  
   235  	for _, test := range [...]struct {
   236  		name   string
   237  		f      func(int8) int8
   238  		golden func(int8) int8
   239  	}{
   240  		{"x|x", func(x int8) int8 { return x | x }, id},
   241  		{"x|0", func(x int8) int8 { return x | 0 }, id},
   242  		{"x|-1", func(x int8) int8 { return x | -1 }, func(x int8) int8 { return -1 }},
   243  		{"x&x", func(x int8) int8 { return x & x }, id},
   244  		{"x&0", func(x int8) int8 { return x & 0 }, zero},
   245  		{"x&-1", func(x int8) int8 { return x & -1 }, id},
   246  		{"x^x", func(x int8) int8 { return x ^ x }, zero},
   247  		{"x^0", func(x int8) int8 { return x ^ 0 }, id},
   248  		{"x^-1", func(x int8) int8 { return x ^ -1 }, func(x int8) int8 { return ^x }},
   249  		{"x+0", func(x int8) int8 { return x + 0 }, id},
   250  		{"x-x", func(x int8) int8 { return x - x }, zero},
   251  		{"x*0", func(x int8) int8 { return x * 0 }, zero},
   252  		{"^^x", func(x int8) int8 { return ^^x }, id},
   253  	} {
   254  		for _, v := range values {
   255  			got := test.f(v)
   256  			want := test.golden(v)
   257  			if want != got {
   258  				t.Errorf("[%s](%d)=%d, want %d", test.name, v, got, want)
   259  			}
   260  		}
   261  	}
   262  	for _, test := range [...]struct {
   263  		name   string
   264  		f      func(int8, int8) int8
   265  		golden func(int8, int8) int8
   266  	}{
   267  		{"x|(x|y)", func(x, y int8) int8 { return x | (x | y) }, or},
   268  		{"x|(y|x)", func(x, y int8) int8 { return x | (y | x) }, or},
   269  		{"(x|y)|x", func(x, y int8) int8 { return (x | y) | x }, or},
   270  		{"(y|x)|x", func(x, y int8) int8 { return (y | x) | x }, or},
   271  		{"x&(x&y)", func(x, y int8) int8 { return x & (x & y) }, and},
   272  		{"x&(y&x)", func(x, y int8) int8 { return x & (y & x) }, and},
   273  		{"(x&y)&x", func(x, y int8) int8 { return (x & y) & x }, and},
   274  		{"(y&x)&x", func(x, y int8) int8 { return (y & x) & x }, and},
   275  		{"x^(x^y)", func(x, y int8) int8 { return x ^ (x ^ y) }, y},
   276  		{"x^(y^x)", func(x, y int8) int8 { return x ^ (y ^ x) }, y},
   277  		{"(x^y)^x", func(x, y int8) int8 { return (x ^ y) ^ x }, y},
   278  		{"(y^x)^x", func(x, y int8) int8 { return (y ^ x) ^ x }, y},
   279  		{"-(y-x)", func(x, y int8) int8 { return -(y - x) }, func(x, y int8) int8 { return x - y }},
   280  		{"(x+y)-x", func(x, y int8) int8 { return (x + y) - x }, y},
   281  		{"(y+x)-x", func(x, y int8) int8 { return (y + x) - x }, y},
   282  	} {
   283  		for _, v := range values {
   284  			for _, w := range values {
   285  				got := test.f(v, w)
   286  				want := test.golden(v, w)
   287  				if want != got {
   288  					t.Errorf("[%s](%d,%d)=%d, want %d", test.name, v, w, got, want)
   289  				}
   290  			}
   291  		}
   292  	}
   293  }
   294  

View as plain text