aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/test/testdata
diff options
context:
space:
mode:
authorJoel Sing <joel@sing.id.au>2023-11-26 02:48:05 +1100
committerCherry Mui <cherryyz@google.com>2023-12-01 19:30:59 +0000
commit70c7fb75e9768630ca23ff5cbf79c9b597bc068e (patch)
treef3abaad695dc42bce092b78fdc41c38aa70917f1 /src/cmd/compile/internal/test/testdata
parent5a2161ce9ec130271ec67566ecb5a842497e8742 (diff)
downloadgo-70c7fb75e9768630ca23ff5cbf79c9b597bc068e.tar.xz
cmd/compile: correct code generation for right shifts on riscv64
The code generation on riscv64 will currently result in incorrect assembly when a 32 bit integer is right shifted by an amount that exceeds the size of the type. In particular, this occurs when an int32 or uint32 is cast to a 64 bit type and right shifted by a value larger than 31. Fix this by moving the SRAW/SRLW conversion into the right shift rules and removing the SignExt32to64/ZeroExt32to64. Add additional rules that rewrite to SRAIW/SRLIW when the shift is less than the size of the type, or replace/eliminate the shift when it exceeds the size of the type. Add SSA tests that would have caught this issue. Also add additional codegen tests to ensure that the resulting assembly is what we expect in these overflow cases. Fixes #64285 Change-Id: Ie97b05668597cfcb91413afefaab18ee1aa145ec Reviewed-on: https://go-review.googlesource.com/c/go/+/545035 Reviewed-by: Russ Cox <rsc@golang.org> Reviewed-by: Cherry Mui <cherryyz@google.com> Reviewed-by: M Zhuo <mzh@golangcn.org> Reviewed-by: Mark Ryan <markdryan@rivosinc.com> Run-TryBot: Joel Sing <joel@sing.id.au> TryBot-Result: Gopher Robot <gobot@golang.org>
Diffstat (limited to 'src/cmd/compile/internal/test/testdata')
-rw-r--r--src/cmd/compile/internal/test/testdata/arith_test.go66
1 files changed, 66 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/test/testdata/arith_test.go b/src/cmd/compile/internal/test/testdata/arith_test.go
index 2b8cd9fad3..cd7b5bc2c4 100644
--- a/src/cmd/compile/internal/test/testdata/arith_test.go
+++ b/src/cmd/compile/internal/test/testdata/arith_test.go
@@ -268,6 +268,70 @@ func testOverflowConstShift(t *testing.T) {
}
}
+//go:noinline
+func rsh64x64ConstOverflow8(x int8) int64 {
+ return int64(x) >> 9
+}
+
+//go:noinline
+func rsh64x64ConstOverflow16(x int16) int64 {
+ return int64(x) >> 17
+}
+
+//go:noinline
+func rsh64x64ConstOverflow32(x int32) int64 {
+ return int64(x) >> 33
+}
+
+func testArithRightShiftConstOverflow(t *testing.T) {
+ allSet := int64(-1)
+ if got, want := rsh64x64ConstOverflow8(0x7f), int64(0); got != want {
+ t.Errorf("rsh64x64ConstOverflow8 failed: got %v, want %v", got, want)
+ }
+ if got, want := rsh64x64ConstOverflow16(0x7fff), int64(0); got != want {
+ t.Errorf("rsh64x64ConstOverflow16 failed: got %v, want %v", got, want)
+ }
+ if got, want := rsh64x64ConstOverflow32(0x7ffffff), int64(0); got != want {
+ t.Errorf("rsh64x64ConstOverflow32 failed: got %v, want %v", got, want)
+ }
+ if got, want := rsh64x64ConstOverflow8(int8(-1)), allSet; got != want {
+ t.Errorf("rsh64x64ConstOverflow8 failed: got %v, want %v", got, want)
+ }
+ if got, want := rsh64x64ConstOverflow16(int16(-1)), allSet; got != want {
+ t.Errorf("rsh64x64ConstOverflow16 failed: got %v, want %v", got, want)
+ }
+ if got, want := rsh64x64ConstOverflow32(int32(-1)), allSet; got != want {
+ t.Errorf("rsh64x64ConstOverflow32 failed: got %v, want %v", got, want)
+ }
+}
+
+//go:noinline
+func rsh64Ux64ConstOverflow8(x uint8) uint64 {
+ return uint64(x) >> 9
+}
+
+//go:noinline
+func rsh64Ux64ConstOverflow16(x uint16) uint64 {
+ return uint64(x) >> 17
+}
+
+//go:noinline
+func rsh64Ux64ConstOverflow32(x uint32) uint64 {
+ return uint64(x) >> 33
+}
+
+func testRightShiftConstOverflow(t *testing.T) {
+ if got, want := rsh64Ux64ConstOverflow8(0xff), uint64(0); got != want {
+ t.Errorf("rsh64Ux64ConstOverflow8 failed: got %v, want %v", got, want)
+ }
+ if got, want := rsh64Ux64ConstOverflow16(0xffff), uint64(0); got != want {
+ t.Errorf("rsh64Ux64ConstOverflow16 failed: got %v, want %v", got, want)
+ }
+ if got, want := rsh64Ux64ConstOverflow32(0xffffffff), uint64(0); got != want {
+ t.Errorf("rsh64Ux64ConstOverflow32 failed: got %v, want %v", got, want)
+ }
+}
+
// test64BitConstMult tests that rewrite rules don't fold 64 bit constants
// into multiply instructions.
func test64BitConstMult(t *testing.T) {
@@ -918,6 +982,8 @@ func TestArithmetic(t *testing.T) {
testShiftCX(t)
testSubConst(t)
testOverflowConstShift(t)
+ testArithRightShiftConstOverflow(t)
+ testRightShiftConstOverflow(t)
testArithConstShift(t)
testArithRshConst(t)
testLargeConst(t)