diff options
author | Keith Randall <khr@golang.org> | 2016-05-31 13:48:29 -0700 |
---|---|---|
committer | Keith Randall <khr@golang.org> | 2016-06-01 00:06:00 +0000 |
commit | e106122200032cdf4f0a993cdd89c7531aaf8d75 (patch) | |
tree | a5712cd8f5e3d59497fffdc5232b10dba100d55e | |
parent | 3d81d4adc9419e2fcba5888ab074d3f17eb5eb03 (diff) | |
download | go-git-e106122200032cdf4f0a993cdd89c7531aaf8d75.tar.gz |
cmd/compile: test non-constant shifts
Test all the weird shifts, like int8 shifted right by uint16.
Increases coverage for shift lowerings in AMD64.rules.
Change-Id: I066fe6ad6bfc05253a8d6a2ee17ff244d3a7652e
Reviewed-on: https://go-review.googlesource.com/23585
Run-TryBot: Todd Neal <todd@tneal.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Todd Neal <todd@tneal.org>
-rw-r--r-- | src/cmd/compile/internal/gc/shift_test.go | 126 |
1 files changed, 125 insertions, 1 deletions
diff --git a/src/cmd/compile/internal/gc/shift_test.go b/src/cmd/compile/internal/gc/shift_test.go index cb6be777a7..ce2eedf152 100644 --- a/src/cmd/compile/internal/gc/shift_test.go +++ b/src/cmd/compile/internal/gc/shift_test.go @@ -4,7 +4,10 @@ package gc -import "testing" +import ( + "reflect" + "testing" +) // Tests shifts of zero. @@ -905,3 +908,124 @@ func TestShiftLargeCombine3(t *testing.T) { t.Errorf("shift overflow mishandled") } } + +func TestShiftGeneric(t *testing.T) { + for _, test := range [...]struct { + valueWidth int + signed bool + shiftWidth int + left bool + f interface{} + }{ + {64, true, 64, true, func(n int64, s uint64) int64 { return n << s }}, + {64, true, 64, false, func(n int64, s uint64) int64 { return n >> s }}, + {64, false, 64, false, func(n uint64, s uint64) uint64 { return n >> s }}, + {64, true, 32, true, func(n int64, s uint32) int64 { return n << s }}, + {64, true, 32, false, func(n int64, s uint32) int64 { return n >> s }}, + {64, false, 32, false, func(n uint64, s uint32) uint64 { return n >> s }}, + {64, true, 16, true, func(n int64, s uint16) int64 { return n << s }}, + {64, true, 16, false, func(n int64, s uint16) int64 { return n >> s }}, + {64, false, 16, false, func(n uint64, s uint16) uint64 { return n >> s }}, + {64, true, 8, true, func(n int64, s uint8) int64 { return n << s }}, + {64, true, 8, false, func(n int64, s uint8) int64 { return n >> s }}, + {64, false, 8, false, func(n uint64, s uint8) uint64 { return n >> s }}, + + {32, true, 64, true, func(n int32, s uint64) int32 { return n << s }}, + {32, true, 64, false, func(n int32, s uint64) int32 { return n >> s }}, + {32, false, 64, false, func(n uint32, s uint64) uint32 { return n >> s }}, + {32, true, 32, true, func(n int32, s uint32) int32 { return n << s }}, + {32, true, 32, false, func(n int32, s uint32) int32 { return n >> s }}, + {32, false, 32, false, func(n uint32, s uint32) uint32 { return n >> s }}, + {32, true, 16, true, func(n int32, s uint16) int32 { return n << s }}, + {32, true, 16, false, func(n int32, s uint16) int32 { return n >> s }}, + {32, false, 16, false, func(n uint32, s uint16) uint32 { return n >> s }}, + {32, true, 8, true, func(n int32, s uint8) int32 { return n << s }}, + {32, true, 8, false, func(n int32, s uint8) int32 { return n >> s }}, + {32, false, 8, false, func(n uint32, s uint8) uint32 { return n >> s }}, + + {16, true, 64, true, func(n int16, s uint64) int16 { return n << s }}, + {16, true, 64, false, func(n int16, s uint64) int16 { return n >> s }}, + {16, false, 64, false, func(n uint16, s uint64) uint16 { return n >> s }}, + {16, true, 32, true, func(n int16, s uint32) int16 { return n << s }}, + {16, true, 32, false, func(n int16, s uint32) int16 { return n >> s }}, + {16, false, 32, false, func(n uint16, s uint32) uint16 { return n >> s }}, + {16, true, 16, true, func(n int16, s uint16) int16 { return n << s }}, + {16, true, 16, false, func(n int16, s uint16) int16 { return n >> s }}, + {16, false, 16, false, func(n uint16, s uint16) uint16 { return n >> s }}, + {16, true, 8, true, func(n int16, s uint8) int16 { return n << s }}, + {16, true, 8, false, func(n int16, s uint8) int16 { return n >> s }}, + {16, false, 8, false, func(n uint16, s uint8) uint16 { return n >> s }}, + + {8, true, 64, true, func(n int8, s uint64) int8 { return n << s }}, + {8, true, 64, false, func(n int8, s uint64) int8 { return n >> s }}, + {8, false, 64, false, func(n uint8, s uint64) uint8 { return n >> s }}, + {8, true, 32, true, func(n int8, s uint32) int8 { return n << s }}, + {8, true, 32, false, func(n int8, s uint32) int8 { return n >> s }}, + {8, false, 32, false, func(n uint8, s uint32) uint8 { return n >> s }}, + {8, true, 16, true, func(n int8, s uint16) int8 { return n << s }}, + {8, true, 16, false, func(n int8, s uint16) int8 { return n >> s }}, + {8, false, 16, false, func(n uint8, s uint16) uint8 { return n >> s }}, + {8, true, 8, true, func(n int8, s uint8) int8 { return n << s }}, + {8, true, 8, false, func(n int8, s uint8) int8 { return n >> s }}, + {8, false, 8, false, func(n uint8, s uint8) uint8 { return n >> s }}, + } { + fv := reflect.ValueOf(test.f) + var args [2]reflect.Value + for i := 0; i < test.valueWidth; i++ { + // Build value to be shifted. + var n int64 = 1 + for j := 0; j < i; j++ { + n <<= 1 + } + args[0] = reflect.ValueOf(n).Convert(fv.Type().In(0)) + for s := 0; s <= test.shiftWidth; s++ { + args[1] = reflect.ValueOf(s).Convert(fv.Type().In(1)) + + // Compute desired result. We're testing variable shifts + // assuming constant shifts are correct. + r := n + var op string + switch { + case test.left: + op = "<<" + for j := 0; j < s; j++ { + r <<= 1 + } + switch test.valueWidth { + case 32: + r = int64(int32(r)) + case 16: + r = int64(int16(r)) + case 8: + r = int64(int8(r)) + } + case test.signed: + op = ">>" + switch test.valueWidth { + case 32: + r = int64(int32(r)) + case 16: + r = int64(int16(r)) + case 8: + r = int64(int8(r)) + } + for j := 0; j < s; j++ { + r >>= 1 + } + default: + op = ">>>" + for j := 0; j < s; j++ { + r = int64(uint64(r) >> 1) + } + } + + // Call function. + res := fv.Call(args[:])[0].Convert(reflect.ValueOf(r).Type()) + + if res.Int() != r { + t.Errorf("%s%dx%d(%x,%x)=%x, want %x", op, test.valueWidth, test.shiftWidth, n, s, res.Int(), r) + } + } + } + } +} |