From 25ea4e579f44fa28189422b9951c375a5ff36a4e Mon Sep 17 00:00:00 2001 From: Keith Randall Date: Tue, 31 Jul 2018 15:26:58 -0700 Subject: cmd/compile: move more compiler tests to new test infrastructure Update #26469 Change-Id: I1188e49cde1bda11506afef6b6e3f34c6ff45ea5 Reviewed-on: https://go-review.googlesource.com/127115 Run-TryBot: Keith Randall TryBot-Result: Gobot Gobot Reviewed-by: David Chase --- src/cmd/compile/internal/gc/ssa_test.go | 20 -- src/cmd/compile/internal/gc/testdata/chan.go | 73 ------- src/cmd/compile/internal/gc/testdata/chan_test.go | 63 ++++++ src/cmd/compile/internal/gc/testdata/compound.go | 143 ------------- .../compile/internal/gc/testdata/compound_test.go | 128 ++++++++++++ src/cmd/compile/internal/gc/testdata/ctl.go | 160 --------------- src/cmd/compile/internal/gc/testdata/ctl_test.go | 149 ++++++++++++++ .../compile/internal/gc/testdata/deferNoReturn.go | 17 -- .../internal/gc/testdata/deferNoReturn_test.go | 21 ++ src/cmd/compile/internal/gc/testdata/loadstore.go | 223 -------------------- .../compile/internal/gc/testdata/loadstore_test.go | 204 +++++++++++++++++++ src/cmd/compile/internal/gc/testdata/map.go | 45 ----- src/cmd/compile/internal/gc/testdata/map_test.go | 37 ++++ src/cmd/compile/internal/gc/testdata/novet.go | 9 + src/cmd/compile/internal/gc/testdata/regalloc.go | 57 ------ .../compile/internal/gc/testdata/regalloc_test.go | 50 +++++ src/cmd/compile/internal/gc/testdata/string.go | 224 --------------------- .../compile/internal/gc/testdata/string_test.go | 207 +++++++++++++++++++ 18 files changed, 868 insertions(+), 962 deletions(-) delete mode 100644 src/cmd/compile/internal/gc/testdata/chan.go create mode 100644 src/cmd/compile/internal/gc/testdata/chan_test.go delete mode 100644 src/cmd/compile/internal/gc/testdata/compound.go create mode 100644 src/cmd/compile/internal/gc/testdata/compound_test.go delete mode 100644 src/cmd/compile/internal/gc/testdata/ctl.go create mode 100644 src/cmd/compile/internal/gc/testdata/ctl_test.go delete mode 100644 src/cmd/compile/internal/gc/testdata/deferNoReturn.go create mode 100644 src/cmd/compile/internal/gc/testdata/deferNoReturn_test.go delete mode 100644 src/cmd/compile/internal/gc/testdata/loadstore.go create mode 100644 src/cmd/compile/internal/gc/testdata/loadstore_test.go delete mode 100644 src/cmd/compile/internal/gc/testdata/map.go create mode 100644 src/cmd/compile/internal/gc/testdata/map_test.go create mode 100644 src/cmd/compile/internal/gc/testdata/novet.go delete mode 100644 src/cmd/compile/internal/gc/testdata/regalloc.go create mode 100644 src/cmd/compile/internal/gc/testdata/regalloc_test.go delete mode 100644 src/cmd/compile/internal/gc/testdata/string.go create mode 100644 src/cmd/compile/internal/gc/testdata/string_test.go (limited to 'src') diff --git a/src/cmd/compile/internal/gc/ssa_test.go b/src/cmd/compile/internal/gc/ssa_test.go index 4f7bab9fc5..98230a15c6 100644 --- a/src/cmd/compile/internal/gc/ssa_test.go +++ b/src/cmd/compile/internal/gc/ssa_test.go @@ -26,10 +26,6 @@ func runTest(t *testing.T, filename string, flags ...string) { t.Parallel() doTest(t, filename, "run", flags...) } -func buildTest(t *testing.T, filename string, flags ...string) { - t.Parallel() - doTest(t, filename, "build", flags...) -} func doTest(t *testing.T, filename string, kind string, flags ...string) { testenv.MustHaveGoBuild(t) gotool := testenv.GoToolPath(t) @@ -227,22 +223,6 @@ func TestCode(t *testing.T) { } } -func TestChan(t *testing.T) { runTest(t, "chan.go") } - -func TestCompound(t *testing.T) { runTest(t, "compound.go") } - -func TestCtl(t *testing.T) { runTest(t, "ctl.go") } - -func TestLoadStore(t *testing.T) { runTest(t, "loadstore.go") } - -func TestMap(t *testing.T) { runTest(t, "map.go") } - -func TestRegalloc(t *testing.T) { runTest(t, "regalloc.go") } - -func TestString(t *testing.T) { runTest(t, "string.go") } - -func TestDeferNoReturn(t *testing.T) { buildTest(t, "deferNoReturn.go") } - // TestClosure tests closure related behavior. func TestClosure(t *testing.T) { runTest(t, "closure.go") } diff --git a/src/cmd/compile/internal/gc/testdata/chan.go b/src/cmd/compile/internal/gc/testdata/chan.go deleted file mode 100644 index 0766fcda5b..0000000000 --- a/src/cmd/compile/internal/gc/testdata/chan.go +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// chan_ssa.go tests chan operations. -package main - -import "fmt" - -var failed = false - -//go:noinline -func lenChan_ssa(v chan int) int { - return len(v) -} - -//go:noinline -func capChan_ssa(v chan int) int { - return cap(v) -} - -func testLenChan() { - - v := make(chan int, 10) - v <- 1 - v <- 1 - v <- 1 - - if want, got := 3, lenChan_ssa(v); got != want { - fmt.Printf("expected len(chan) = %d, got %d", want, got) - failed = true - } -} - -func testLenNilChan() { - - var v chan int - if want, got := 0, lenChan_ssa(v); got != want { - fmt.Printf("expected len(nil) = %d, got %d", want, got) - failed = true - } -} - -func testCapChan() { - - v := make(chan int, 25) - - if want, got := 25, capChan_ssa(v); got != want { - fmt.Printf("expected cap(chan) = %d, got %d", want, got) - failed = true - } -} - -func testCapNilChan() { - - var v chan int - if want, got := 0, capChan_ssa(v); got != want { - fmt.Printf("expected cap(nil) = %d, got %d", want, got) - failed = true - } -} - -func main() { - testLenChan() - testLenNilChan() - - testCapChan() - testCapNilChan() - - if failed { - panic("failed") - } -} diff --git a/src/cmd/compile/internal/gc/testdata/chan_test.go b/src/cmd/compile/internal/gc/testdata/chan_test.go new file mode 100644 index 0000000000..628bd8f7f7 --- /dev/null +++ b/src/cmd/compile/internal/gc/testdata/chan_test.go @@ -0,0 +1,63 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// chan.go tests chan operations. +package main + +import "testing" + +//go:noinline +func lenChan_ssa(v chan int) int { + return len(v) +} + +//go:noinline +func capChan_ssa(v chan int) int { + return cap(v) +} + +func testLenChan(t *testing.T) { + + v := make(chan int, 10) + v <- 1 + v <- 1 + v <- 1 + + if want, got := 3, lenChan_ssa(v); got != want { + t.Errorf("expected len(chan) = %d, got %d", want, got) + } +} + +func testLenNilChan(t *testing.T) { + + var v chan int + if want, got := 0, lenChan_ssa(v); got != want { + t.Errorf("expected len(nil) = %d, got %d", want, got) + } +} + +func testCapChan(t *testing.T) { + + v := make(chan int, 25) + + if want, got := 25, capChan_ssa(v); got != want { + t.Errorf("expected cap(chan) = %d, got %d", want, got) + } +} + +func testCapNilChan(t *testing.T) { + + var v chan int + if want, got := 0, capChan_ssa(v); got != want { + t.Errorf("expected cap(nil) = %d, got %d", want, got) + } +} + +func TestChan(t *testing.T) { + testLenChan(t) + testLenNilChan(t) + + testCapChan(t) + testCapNilChan(t) +} diff --git a/src/cmd/compile/internal/gc/testdata/compound.go b/src/cmd/compile/internal/gc/testdata/compound.go deleted file mode 100644 index de10cdc779..0000000000 --- a/src/cmd/compile/internal/gc/testdata/compound.go +++ /dev/null @@ -1,143 +0,0 @@ -// run - -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Test compound objects - -package main - -import "fmt" - -func string_ssa(a, b string, x bool) string { - s := "" - if x { - s = a - } else { - s = b - } - return s -} - -func testString() { - a := "foo" - b := "barz" - if want, got := a, string_ssa(a, b, true); got != want { - fmt.Printf("string_ssa(%v, %v, true) = %v, want %v\n", a, b, got, want) - failed = true - } - if want, got := b, string_ssa(a, b, false); got != want { - fmt.Printf("string_ssa(%v, %v, false) = %v, want %v\n", a, b, got, want) - failed = true - } -} - -//go:noinline -func complex64_ssa(a, b complex64, x bool) complex64 { - var c complex64 - if x { - c = a - } else { - c = b - } - return c -} - -//go:noinline -func complex128_ssa(a, b complex128, x bool) complex128 { - var c complex128 - if x { - c = a - } else { - c = b - } - return c -} - -func testComplex64() { - var a complex64 = 1 + 2i - var b complex64 = 3 + 4i - - if want, got := a, complex64_ssa(a, b, true); got != want { - fmt.Printf("complex64_ssa(%v, %v, true) = %v, want %v\n", a, b, got, want) - failed = true - } - if want, got := b, complex64_ssa(a, b, false); got != want { - fmt.Printf("complex64_ssa(%v, %v, true) = %v, want %v\n", a, b, got, want) - failed = true - } -} - -func testComplex128() { - var a complex128 = 1 + 2i - var b complex128 = 3 + 4i - - if want, got := a, complex128_ssa(a, b, true); got != want { - fmt.Printf("complex128_ssa(%v, %v, true) = %v, want %v\n", a, b, got, want) - failed = true - } - if want, got := b, complex128_ssa(a, b, false); got != want { - fmt.Printf("complex128_ssa(%v, %v, true) = %v, want %v\n", a, b, got, want) - failed = true - } -} - -func slice_ssa(a, b []byte, x bool) []byte { - var s []byte - if x { - s = a - } else { - s = b - } - return s -} - -func testSlice() { - a := []byte{3, 4, 5} - b := []byte{7, 8, 9} - if want, got := byte(3), slice_ssa(a, b, true)[0]; got != want { - fmt.Printf("slice_ssa(%v, %v, true) = %v, want %v\n", a, b, got, want) - failed = true - } - if want, got := byte(7), slice_ssa(a, b, false)[0]; got != want { - fmt.Printf("slice_ssa(%v, %v, false) = %v, want %v\n", a, b, got, want) - failed = true - } -} - -func interface_ssa(a, b interface{}, x bool) interface{} { - var s interface{} - if x { - s = a - } else { - s = b - } - return s -} - -func testInterface() { - a := interface{}(3) - b := interface{}(4) - if want, got := 3, interface_ssa(a, b, true).(int); got != want { - fmt.Printf("interface_ssa(%v, %v, true) = %v, want %v\n", a, b, got, want) - failed = true - } - if want, got := 4, interface_ssa(a, b, false).(int); got != want { - fmt.Printf("interface_ssa(%v, %v, false) = %v, want %v\n", a, b, got, want) - failed = true - } -} - -var failed = false - -func main() { - testString() - testSlice() - testInterface() - testComplex64() - testComplex128() - if failed { - panic("failed") - } -} diff --git a/src/cmd/compile/internal/gc/testdata/compound_test.go b/src/cmd/compile/internal/gc/testdata/compound_test.go new file mode 100644 index 0000000000..4ae464dbe3 --- /dev/null +++ b/src/cmd/compile/internal/gc/testdata/compound_test.go @@ -0,0 +1,128 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Test compound objects + +package main + +import ( + "testing" +) + +func string_ssa(a, b string, x bool) string { + s := "" + if x { + s = a + } else { + s = b + } + return s +} + +func testString(t *testing.T) { + a := "foo" + b := "barz" + if want, got := a, string_ssa(a, b, true); got != want { + t.Errorf("string_ssa(%v, %v, true) = %v, want %v\n", a, b, got, want) + } + if want, got := b, string_ssa(a, b, false); got != want { + t.Errorf("string_ssa(%v, %v, false) = %v, want %v\n", a, b, got, want) + } +} + +//go:noinline +func complex64_ssa(a, b complex64, x bool) complex64 { + var c complex64 + if x { + c = a + } else { + c = b + } + return c +} + +//go:noinline +func complex128_ssa(a, b complex128, x bool) complex128 { + var c complex128 + if x { + c = a + } else { + c = b + } + return c +} + +func testComplex64(t *testing.T) { + var a complex64 = 1 + 2i + var b complex64 = 3 + 4i + + if want, got := a, complex64_ssa(a, b, true); got != want { + t.Errorf("complex64_ssa(%v, %v, true) = %v, want %v\n", a, b, got, want) + } + if want, got := b, complex64_ssa(a, b, false); got != want { + t.Errorf("complex64_ssa(%v, %v, true) = %v, want %v\n", a, b, got, want) + } +} + +func testComplex128(t *testing.T) { + var a complex128 = 1 + 2i + var b complex128 = 3 + 4i + + if want, got := a, complex128_ssa(a, b, true); got != want { + t.Errorf("complex128_ssa(%v, %v, true) = %v, want %v\n", a, b, got, want) + } + if want, got := b, complex128_ssa(a, b, false); got != want { + t.Errorf("complex128_ssa(%v, %v, true) = %v, want %v\n", a, b, got, want) + } +} + +func slice_ssa(a, b []byte, x bool) []byte { + var s []byte + if x { + s = a + } else { + s = b + } + return s +} + +func testSlice(t *testing.T) { + a := []byte{3, 4, 5} + b := []byte{7, 8, 9} + if want, got := byte(3), slice_ssa(a, b, true)[0]; got != want { + t.Errorf("slice_ssa(%v, %v, true) = %v, want %v\n", a, b, got, want) + } + if want, got := byte(7), slice_ssa(a, b, false)[0]; got != want { + t.Errorf("slice_ssa(%v, %v, false) = %v, want %v\n", a, b, got, want) + } +} + +func interface_ssa(a, b interface{}, x bool) interface{} { + var s interface{} + if x { + s = a + } else { + s = b + } + return s +} + +func testInterface(t *testing.T) { + a := interface{}(3) + b := interface{}(4) + if want, got := 3, interface_ssa(a, b, true).(int); got != want { + t.Errorf("interface_ssa(%v, %v, true) = %v, want %v\n", a, b, got, want) + } + if want, got := 4, interface_ssa(a, b, false).(int); got != want { + t.Errorf("interface_ssa(%v, %v, false) = %v, want %v\n", a, b, got, want) + } +} + +func TestCompound(t *testing.T) { + testString(t) + testSlice(t) + testInterface(t) + testComplex64(t) + testComplex128(t) +} diff --git a/src/cmd/compile/internal/gc/testdata/ctl.go b/src/cmd/compile/internal/gc/testdata/ctl.go deleted file mode 100644 index 0656cb4ddb..0000000000 --- a/src/cmd/compile/internal/gc/testdata/ctl.go +++ /dev/null @@ -1,160 +0,0 @@ -// run - -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Test control flow - -package main - -// nor_ssa calculates NOR(a, b). -// It is implemented in a way that generates -// phi control values. -func nor_ssa(a, b bool) bool { - var c bool - if a { - c = true - } - if b { - c = true - } - if c { - return false - } - return true -} - -func testPhiControl() { - tests := [...][3]bool{ // a, b, want - {false, false, true}, - {true, false, false}, - {false, true, false}, - {true, true, false}, - } - for _, test := range tests { - a, b := test[0], test[1] - got := nor_ssa(a, b) - want := test[2] - if want != got { - print("nor(", a, ", ", b, ")=", want, " got ", got, "\n") - failed = true - } - } -} - -func emptyRange_ssa(b []byte) bool { - for _, x := range b { - _ = x - } - return true -} - -func testEmptyRange() { - if !emptyRange_ssa([]byte{}) { - println("emptyRange_ssa([]byte{})=false, want true") - failed = true - } -} - -func switch_ssa(a int) int { - ret := 0 - switch a { - case 5: - ret += 5 - case 4: - ret += 4 - case 3: - ret += 3 - case 2: - ret += 2 - case 1: - ret += 1 - } - return ret - -} - -func fallthrough_ssa(a int) int { - ret := 0 - switch a { - case 5: - ret++ - fallthrough - case 4: - ret++ - fallthrough - case 3: - ret++ - fallthrough - case 2: - ret++ - fallthrough - case 1: - ret++ - } - return ret - -} - -func testFallthrough() { - for i := 0; i < 6; i++ { - if got := fallthrough_ssa(i); got != i { - println("fallthrough_ssa(i) =", got, "wanted", i) - failed = true - } - } -} - -func testSwitch() { - for i := 0; i < 6; i++ { - if got := switch_ssa(i); got != i { - println("switch_ssa(i) =", got, "wanted", i) - failed = true - } - } -} - -type junk struct { - step int -} - -// flagOverwrite_ssa is intended to reproduce an issue seen where a XOR -// was scheduled between a compare and branch, clearing flags. -//go:noinline -func flagOverwrite_ssa(s *junk, c int) int { - if '0' <= c && c <= '9' { - s.step = 0 - return 1 - } - if c == 'e' || c == 'E' { - s.step = 0 - return 2 - } - s.step = 0 - return 3 -} - -func testFlagOverwrite() { - j := junk{} - if got := flagOverwrite_ssa(&j, ' '); got != 3 { - println("flagOverwrite_ssa =", got, "wanted 3") - failed = true - } -} - -var failed = false - -func main() { - testPhiControl() - testEmptyRange() - - testSwitch() - testFallthrough() - - testFlagOverwrite() - - if failed { - panic("failed") - } -} diff --git a/src/cmd/compile/internal/gc/testdata/ctl_test.go b/src/cmd/compile/internal/gc/testdata/ctl_test.go new file mode 100644 index 0000000000..16d571ce2c --- /dev/null +++ b/src/cmd/compile/internal/gc/testdata/ctl_test.go @@ -0,0 +1,149 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Test control flow + +package main + +import "testing" + +// nor_ssa calculates NOR(a, b). +// It is implemented in a way that generates +// phi control values. +func nor_ssa(a, b bool) bool { + var c bool + if a { + c = true + } + if b { + c = true + } + if c { + return false + } + return true +} + +func testPhiControl(t *testing.T) { + tests := [...][3]bool{ // a, b, want + {false, false, true}, + {true, false, false}, + {false, true, false}, + {true, true, false}, + } + for _, test := range tests { + a, b := test[0], test[1] + got := nor_ssa(a, b) + want := test[2] + if want != got { + t.Errorf("nor(%t, %t)=%t got %t", a, b, want, got) + } + } +} + +func emptyRange_ssa(b []byte) bool { + for _, x := range b { + _ = x + } + return true +} + +func testEmptyRange(t *testing.T) { + if !emptyRange_ssa([]byte{}) { + t.Errorf("emptyRange_ssa([]byte{})=false, want true") + } +} + +func switch_ssa(a int) int { + ret := 0 + switch a { + case 5: + ret += 5 + case 4: + ret += 4 + case 3: + ret += 3 + case 2: + ret += 2 + case 1: + ret += 1 + } + return ret + +} + +func fallthrough_ssa(a int) int { + ret := 0 + switch a { + case 5: + ret++ + fallthrough + case 4: + ret++ + fallthrough + case 3: + ret++ + fallthrough + case 2: + ret++ + fallthrough + case 1: + ret++ + } + return ret + +} + +func testFallthrough(t *testing.T) { + for i := 0; i < 6; i++ { + if got := fallthrough_ssa(i); got != i { + t.Errorf("fallthrough_ssa(i) = %d, wanted %d", got, i) + } + } +} + +func testSwitch(t *testing.T) { + for i := 0; i < 6; i++ { + if got := switch_ssa(i); got != i { + t.Errorf("switch_ssa(i) = %d, wanted %d", got, i) + } + } +} + +type junk struct { + step int +} + +// flagOverwrite_ssa is intended to reproduce an issue seen where a XOR +// was scheduled between a compare and branch, clearing flags. +//go:noinline +func flagOverwrite_ssa(s *junk, c int) int { + if '0' <= c && c <= '9' { + s.step = 0 + return 1 + } + if c == 'e' || c == 'E' { + s.step = 0 + return 2 + } + s.step = 0 + return 3 +} + +func testFlagOverwrite(t *testing.T) { + j := junk{} + if got := flagOverwrite_ssa(&j, ' '); got != 3 { + t.Errorf("flagOverwrite_ssa = %d, wanted 3", got) + } +} + +func TestCtl(t *testing.T) { + testPhiControl(t) + testEmptyRange(t) + + testSwitch(t) + testFallthrough(t) + + testFlagOverwrite(t) +} diff --git a/src/cmd/compile/internal/gc/testdata/deferNoReturn.go b/src/cmd/compile/internal/gc/testdata/deferNoReturn.go deleted file mode 100644 index 7578dd56f2..0000000000 --- a/src/cmd/compile/internal/gc/testdata/deferNoReturn.go +++ /dev/null @@ -1,17 +0,0 @@ -// compile - -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Test that a defer in a function with no return -// statement will compile correctly. - -package foo - -func deferNoReturn_ssa() { - defer func() { println("returned") }() - for { - println("loop") - } -} diff --git a/src/cmd/compile/internal/gc/testdata/deferNoReturn_test.go b/src/cmd/compile/internal/gc/testdata/deferNoReturn_test.go new file mode 100644 index 0000000000..308e897607 --- /dev/null +++ b/src/cmd/compile/internal/gc/testdata/deferNoReturn_test.go @@ -0,0 +1,21 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Test that a defer in a function with no return +// statement will compile correctly. + +package main + +import "testing" + +func deferNoReturn_ssa() { + defer func() { println("returned") }() + for { + println("loop") + } +} + +func TestDeferNoReturn(t *testing.T) { + // This is a compile-time test, no runtime testing required. +} diff --git a/src/cmd/compile/internal/gc/testdata/loadstore.go b/src/cmd/compile/internal/gc/testdata/loadstore.go deleted file mode 100644 index dcb61d4b7e..0000000000 --- a/src/cmd/compile/internal/gc/testdata/loadstore.go +++ /dev/null @@ -1,223 +0,0 @@ -// run - -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Tests load/store ordering - -package main - -import "fmt" - -// testLoadStoreOrder tests for reordering of stores/loads. -func testLoadStoreOrder() { - z := uint32(1000) - if testLoadStoreOrder_ssa(&z, 100) == 0 { - println("testLoadStoreOrder failed") - failed = true - } -} - -//go:noinline -func testLoadStoreOrder_ssa(z *uint32, prec uint) int { - old := *z // load - *z = uint32(prec) // store - if *z < old { // load - return 1 - } - return 0 -} - -func testStoreSize() { - a := [4]uint16{11, 22, 33, 44} - testStoreSize_ssa(&a[0], &a[2], 77) - want := [4]uint16{77, 22, 33, 44} - if a != want { - fmt.Println("testStoreSize failed. want =", want, ", got =", a) - failed = true - } -} - -//go:noinline -func testStoreSize_ssa(p *uint16, q *uint16, v uint32) { - // Test to make sure that (Store ptr (Trunc32to16 val) mem) - // does not end up as a 32-bit store. It must stay a 16 bit store - // even when Trunc32to16 is rewritten to be a nop. - // To ensure that we get rewrite the Trunc32to16 before - // we rewrite the Store, we force the truncate into an - // earlier basic block by using it on both branches. - w := uint16(v) - if p != nil { - *p = w - } else { - *q = w - } -} - -var failed = false - -//go:noinline -func testExtStore_ssa(p *byte, b bool) int { - x := *p - *p = 7 - if b { - return int(x) - } - return 0 -} - -func testExtStore() { - const start = 8 - var b byte = start - if got := testExtStore_ssa(&b, true); got != start { - fmt.Println("testExtStore failed. want =", start, ", got =", got) - failed = true - } -} - -var b int - -// testDeadStorePanic_ssa ensures that we don't optimize away stores -// that could be read by after recover(). Modeled after fixedbugs/issue1304. -//go:noinline -func testDeadStorePanic_ssa(a int) (r int) { - defer func() { - recover() - r = a - }() - a = 2 // store - b := a - a // optimized to zero - c := 4 - a = c / b // store, but panics - a = 3 // store - r = a - return -} - -func testDeadStorePanic() { - if want, got := 2, testDeadStorePanic_ssa(1); want != got { - fmt.Println("testDeadStorePanic failed. want =", want, ", got =", got) - failed = true - } -} - -//go:noinline -func loadHitStore8(x int8, p *int8) int32 { - x *= x // try to trash high bits (arch-dependent) - *p = x // store - return int32(*p) // load and cast -} - -//go:noinline -func loadHitStoreU8(x uint8, p *uint8) uint32 { - x *= x // try to trash high bits (arch-dependent) - *p = x // store - return uint32(*p) // load and cast -} - -//go:noinline -func loadHitStore16(x int16, p *int16) int32 { - x *= x // try to trash high bits (arch-dependent) - *p = x // store - return int32(*p) // load and cast -} - -//go:noinline -func loadHitStoreU16(x uint16, p *uint16) uint32 { - x *= x // try to trash high bits (arch-dependent) - *p = x // store - return uint32(*p) // load and cast -} - -//go:noinline -func loadHitStore32(x int32, p *int32) int64 { - x *= x // try to trash high bits (arch-dependent) - *p = x // store - return int64(*p) // load and cast -} - -//go:noinline -func loadHitStoreU32(x uint32, p *uint32) uint64 { - x *= x // try to trash high bits (arch-dependent) - *p = x // store - return uint64(*p) // load and cast -} - -func testLoadHitStore() { - // Test that sign/zero extensions are kept when a load-hit-store - // is replaced by a register-register move. - { - var in int8 = (1 << 6) + 1 - var p int8 - got := loadHitStore8(in, &p) - want := int32(in * in) - if got != want { - fmt.Println("testLoadHitStore (int8) failed. want =", want, ", got =", got) - failed = true - } - } - { - var in uint8 = (1 << 6) + 1 - var p uint8 - got := loadHitStoreU8(in, &p) - want := uint32(in * in) - if got != want { - fmt.Println("testLoadHitStore (uint8) failed. want =", want, ", got =", got) - failed = true - } - } - { - var in int16 = (1 << 10) + 1 - var p int16 - got := loadHitStore16(in, &p) - want := int32(in * in) - if got != want { - fmt.Println("testLoadHitStore (int16) failed. want =", want, ", got =", got) - failed = true - } - } - { - var in uint16 = (1 << 10) + 1 - var p uint16 - got := loadHitStoreU16(in, &p) - want := uint32(in * in) - if got != want { - fmt.Println("testLoadHitStore (uint16) failed. want =", want, ", got =", got) - failed = true - } - } - { - var in int32 = (1 << 30) + 1 - var p int32 - got := loadHitStore32(in, &p) - want := int64(in * in) - if got != want { - fmt.Println("testLoadHitStore (int32) failed. want =", want, ", got =", got) - failed = true - } - } - { - var in uint32 = (1 << 30) + 1 - var p uint32 - got := loadHitStoreU32(in, &p) - want := uint64(in * in) - if got != want { - fmt.Println("testLoadHitStore (uint32) failed. want =", want, ", got =", got) - failed = true - } - } -} - -func main() { - - testLoadStoreOrder() - testStoreSize() - testExtStore() - testDeadStorePanic() - testLoadHitStore() - - if failed { - panic("failed") - } -} diff --git a/src/cmd/compile/internal/gc/testdata/loadstore_test.go b/src/cmd/compile/internal/gc/testdata/loadstore_test.go new file mode 100644 index 0000000000..57571f5d17 --- /dev/null +++ b/src/cmd/compile/internal/gc/testdata/loadstore_test.go @@ -0,0 +1,204 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Tests load/store ordering + +package main + +import "testing" + +// testLoadStoreOrder tests for reordering of stores/loads. +func testLoadStoreOrder(t *testing.T) { + z := uint32(1000) + if testLoadStoreOrder_ssa(&z, 100) == 0 { + t.Errorf("testLoadStoreOrder failed") + } +} + +//go:noinline +func testLoadStoreOrder_ssa(z *uint32, prec uint) int { + old := *z // load + *z = uint32(prec) // store + if *z < old { // load + return 1 + } + return 0 +} + +func testStoreSize(t *testing.T) { + a := [4]uint16{11, 22, 33, 44} + testStoreSize_ssa(&a[0], &a[2], 77) + want := [4]uint16{77, 22, 33, 44} + if a != want { + t.Errorf("testStoreSize failed. want = %d, got = %d", want, a) + } +} + +//go:noinline +func testStoreSize_ssa(p *uint16, q *uint16, v uint32) { + // Test to make sure that (Store ptr (Trunc32to16 val) mem) + // does not end up as a 32-bit store. It must stay a 16 bit store + // even when Trunc32to16 is rewritten to be a nop. + // To ensure that we get rewrite the Trunc32to16 before + // we rewrite the Store, we force the truncate into an + // earlier basic block by using it on both branches. + w := uint16(v) + if p != nil { + *p = w + } else { + *q = w + } +} + +//go:noinline +func testExtStore_ssa(p *byte, b bool) int { + x := *p + *p = 7 + if b { + return int(x) + } + return 0 +} + +func testExtStore(t *testing.T) { + const start = 8 + var b byte = start + if got := testExtStore_ssa(&b, true); got != start { + t.Errorf("testExtStore failed. want = %d, got = %d", start, got) + } +} + +var b int + +// testDeadStorePanic_ssa ensures that we don't optimize away stores +// that could be read by after recover(). Modeled after fixedbugs/issue1304. +//go:noinline +func testDeadStorePanic_ssa(a int) (r int) { + defer func() { + recover() + r = a + }() + a = 2 // store + b := a - a // optimized to zero + c := 4 + a = c / b // store, but panics + a = 3 // store + r = a + return +} + +func testDeadStorePanic(t *testing.T) { + if want, got := 2, testDeadStorePanic_ssa(1); want != got { + t.Errorf("testDeadStorePanic failed. want = %d, got = %d", want, got) + } +} + +//go:noinline +func loadHitStore8(x int8, p *int8) int32 { + x *= x // try to trash high bits (arch-dependent) + *p = x // store + return int32(*p) // load and cast +} + +//go:noinline +func loadHitStoreU8(x uint8, p *uint8) uint32 { + x *= x // try to trash high bits (arch-dependent) + *p = x // store + return uint32(*p) // load and cast +} + +//go:noinline +func loadHitStore16(x int16, p *int16) int32 { + x *= x // try to trash high bits (arch-dependent) + *p = x // store + return int32(*p) // load and cast +} + +//go:noinline +func loadHitStoreU16(x uint16, p *uint16) uint32 { + x *= x // try to trash high bits (arch-dependent) + *p = x // store + return uint32(*p) // load and cast +} + +//go:noinline +func loadHitStore32(x int32, p *int32) int64 { + x *= x // try to trash high bits (arch-dependent) + *p = x // store + return int64(*p) // load and cast +} + +//go:noinline +func loadHitStoreU32(x uint32, p *uint32) uint64 { + x *= x // try to trash high bits (arch-dependent) + *p = x // store + return uint64(*p) // load and cast +} + +func testLoadHitStore(t *testing.T) { + // Test that sign/zero extensions are kept when a load-hit-store + // is replaced by a register-register move. + { + var in int8 = (1 << 6) + 1 + var p int8 + got := loadHitStore8(in, &p) + want := int32(in * in) + if got != want { + t.Errorf("testLoadHitStore (int8) failed. want = %d, got = %d", want, got) + } + } + { + var in uint8 = (1 << 6) + 1 + var p uint8 + got := loadHitStoreU8(in, &p) + want := uint32(in * in) + if got != want { + t.Errorf("testLoadHitStore (uint8) failed. want = %d, got = %d", want, got) + } + } + { + var in int16 = (1 << 10) + 1 + var p int16 + got := loadHitStore16(in, &p) + want := int32(in * in) + if got != want { + t.Errorf("testLoadHitStore (int16) failed. want = %d, got = %d", want, got) + } + } + { + var in uint16 = (1 << 10) + 1 + var p uint16 + got := loadHitStoreU16(in, &p) + want := uint32(in * in) + if got != want { + t.Errorf("testLoadHitStore (uint16) failed. want = %d, got = %d", want, got) + } + } + { + var in int32 = (1 << 30) + 1 + var p int32 + got := loadHitStore32(in, &p) + want := int64(in * in) + if got != want { + t.Errorf("testLoadHitStore (int32) failed. want = %d, got = %d", want, got) + } + } + { + var in uint32 = (1 << 30) + 1 + var p uint32 + got := loadHitStoreU32(in, &p) + want := uint64(in * in) + if got != want { + t.Errorf("testLoadHitStore (uint32) failed. want = %d, got = %d", want, got) + } + } +} + +func TestLoadStore(t *testing.T) { + testLoadStoreOrder(t) + testStoreSize(t) + testExtStore(t) + testDeadStorePanic(t) + testLoadHitStore(t) +} diff --git a/src/cmd/compile/internal/gc/testdata/map.go b/src/cmd/compile/internal/gc/testdata/map.go deleted file mode 100644 index 4a466003c7..0000000000 --- a/src/cmd/compile/internal/gc/testdata/map.go +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// map_ssa.go tests map operations. -package main - -import "fmt" - -var failed = false - -//go:noinline -func lenMap_ssa(v map[int]int) int { - return len(v) -} - -func testLenMap() { - - v := make(map[int]int) - v[0] = 0 - v[1] = 0 - v[2] = 0 - - if want, got := 3, lenMap_ssa(v); got != want { - fmt.Printf("expected len(map) = %d, got %d", want, got) - failed = true - } -} - -func testLenNilMap() { - - var v map[int]int - if want, got := 0, lenMap_ssa(v); got != want { - fmt.Printf("expected len(nil) = %d, got %d", want, got) - failed = true - } -} -func main() { - testLenMap() - testLenNilMap() - - if failed { - panic("failed") - } -} diff --git a/src/cmd/compile/internal/gc/testdata/map_test.go b/src/cmd/compile/internal/gc/testdata/map_test.go new file mode 100644 index 0000000000..71dc820c1c --- /dev/null +++ b/src/cmd/compile/internal/gc/testdata/map_test.go @@ -0,0 +1,37 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// map.go tests map operations. +package main + +import "testing" + +//go:noinline +func lenMap_ssa(v map[int]int) int { + return len(v) +} + +func testLenMap(t *testing.T) { + + v := make(map[int]int) + v[0] = 0 + v[1] = 0 + v[2] = 0 + + if want, got := 3, lenMap_ssa(v); got != want { + t.Errorf("expected len(map) = %d, got %d", want, got) + } +} + +func testLenNilMap(t *testing.T) { + + var v map[int]int + if want, got := 0, lenMap_ssa(v); got != want { + t.Errorf("expected len(nil) = %d, got %d", want, got) + } +} +func TestMap(t *testing.T) { + testLenMap(t) + testLenNilMap(t) +} diff --git a/src/cmd/compile/internal/gc/testdata/novet.go b/src/cmd/compile/internal/gc/testdata/novet.go new file mode 100644 index 0000000000..0fcbba290c --- /dev/null +++ b/src/cmd/compile/internal/gc/testdata/novet.go @@ -0,0 +1,9 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file exists just to convince vet not to check this directory. +// (vet will not check a directory with two different packages in it.) +// TODO: remove this hack & add failing tests to the whitelist. + +package foo diff --git a/src/cmd/compile/internal/gc/testdata/regalloc.go b/src/cmd/compile/internal/gc/testdata/regalloc.go deleted file mode 100644 index f752692952..0000000000 --- a/src/cmd/compile/internal/gc/testdata/regalloc.go +++ /dev/null @@ -1,57 +0,0 @@ -// run - -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Tests phi implementation - -package main - -func phiOverwrite_ssa() int { - var n int - for i := 0; i < 10; i++ { - if i == 6 { - break - } - n = i - } - return n -} - -func phiOverwrite() { - want := 5 - got := phiOverwrite_ssa() - if got != want { - println("phiOverwrite_ssa()=", want, ", got", got) - failed = true - } -} - -func phiOverwriteBig_ssa() int { - var a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z int - a = 1 - for idx := 0; idx < 26; idx++ { - a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z = b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a - } - return a*1 + b*2 + c*3 + d*4 + e*5 + f*6 + g*7 + h*8 + i*9 + j*10 + k*11 + l*12 + m*13 + n*14 + o*15 + p*16 + q*17 + r*18 + s*19 + t*20 + u*21 + v*22 + w*23 + x*24 + y*25 + z*26 -} - -func phiOverwriteBig() { - want := 1 - got := phiOverwriteBig_ssa() - if got != want { - println("phiOverwriteBig_ssa()=", want, ", got", got) - failed = true - } -} - -var failed = false - -func main() { - phiOverwrite() - phiOverwriteBig() - if failed { - panic("failed") - } -} diff --git a/src/cmd/compile/internal/gc/testdata/regalloc_test.go b/src/cmd/compile/internal/gc/testdata/regalloc_test.go new file mode 100644 index 0000000000..577f8e7684 --- /dev/null +++ b/src/cmd/compile/internal/gc/testdata/regalloc_test.go @@ -0,0 +1,50 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Tests phi implementation + +package main + +import "testing" + +func phiOverwrite_ssa() int { + var n int + for i := 0; i < 10; i++ { + if i == 6 { + break + } + n = i + } + return n +} + +func phiOverwrite(t *testing.T) { + want := 5 + got := phiOverwrite_ssa() + if got != want { + t.Errorf("phiOverwrite_ssa()= %d, got %d", want, got) + } +} + +func phiOverwriteBig_ssa() int { + var a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z int + a = 1 + for idx := 0; idx < 26; idx++ { + a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z = b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a + } + return a*1 + b*2 + c*3 + d*4 + e*5 + f*6 + g*7 + h*8 + i*9 + j*10 + k*11 + l*12 + m*13 + n*14 + o*15 + p*16 + q*17 + r*18 + s*19 + t*20 + u*21 + v*22 + w*23 + x*24 + y*25 + z*26 +} + +func phiOverwriteBig(t *testing.T) { + want := 1 + got := phiOverwriteBig_ssa() + if got != want { + t.Errorf("phiOverwriteBig_ssa()= %d, got %d", want, got) + } +} + +func TestRegalloc(t *testing.T) { + phiOverwrite(t) + phiOverwriteBig(t) +} diff --git a/src/cmd/compile/internal/gc/testdata/string.go b/src/cmd/compile/internal/gc/testdata/string.go deleted file mode 100644 index 03053a6134..0000000000 --- a/src/cmd/compile/internal/gc/testdata/string.go +++ /dev/null @@ -1,224 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// string_ssa.go tests string operations. -package main - -var failed = false - -//go:noinline -func testStringSlice1_ssa(a string, i, j int) string { - return a[i:] -} - -//go:noinline -func testStringSlice2_ssa(a string, i, j int) string { - return a[:j] -} - -//go:noinline -func testStringSlice12_ssa(a string, i, j int) string { - return a[i:j] -} - -func testStringSlice() { - tests := [...]struct { - fn func(string, int, int) string - s string - low, high int - want string - }{ - // -1 means the value is not used. - {testStringSlice1_ssa, "foobar", 0, -1, "foobar"}, - {testStringSlice1_ssa, "foobar", 3, -1, "bar"}, - {testStringSlice1_ssa, "foobar", 6, -1, ""}, - {testStringSlice2_ssa, "foobar", -1, 0, ""}, - {testStringSlice2_ssa, "foobar", -1, 3, "foo"}, - {testStringSlice2_ssa, "foobar", -1, 6, "foobar"}, - {testStringSlice12_ssa, "foobar", 0, 6, "foobar"}, - {testStringSlice12_ssa, "foobar", 0, 0, ""}, - {testStringSlice12_ssa, "foobar", 6, 6, ""}, - {testStringSlice12_ssa, "foobar", 1, 5, "ooba"}, - {testStringSlice12_ssa, "foobar", 3, 3, ""}, - {testStringSlice12_ssa, "", 0, 0, ""}, - } - - for i, t := range tests { - if got := t.fn(t.s, t.low, t.high); t.want != got { - println("#", i, " ", t.s, "[", t.low, ":", t.high, "] = ", got, " want ", t.want) - failed = true - } - } -} - -type prefix struct { - prefix string -} - -func (p *prefix) slice_ssa() { - p.prefix = p.prefix[:3] -} - -//go:noinline -func testStructSlice() { - p := &prefix{"prefix"} - p.slice_ssa() - if "pre" != p.prefix { - println("wrong field slice: wanted %s got %s", "pre", p.prefix) - failed = true - } -} - -func testStringSlicePanic() { - defer func() { - if r := recover(); r != nil { - println("panicked as expected") - } - }() - - str := "foobar" - println("got ", testStringSlice12_ssa(str, 3, 9)) - println("expected to panic, but didn't") - failed = true -} - -const _Accuracy_name = "BelowExactAbove" - -var _Accuracy_index = [...]uint8{0, 5, 10, 15} - -//go:noinline -func testSmallIndexType_ssa(i int) string { - return _Accuracy_name[_Accuracy_index[i]:_Accuracy_index[i+1]] -} - -func testSmallIndexType() { - tests := []struct { - i int - want string - }{ - {0, "Below"}, - {1, "Exact"}, - {2, "Above"}, - } - - for i, t := range tests { - if got := testSmallIndexType_ssa(t.i); got != t.want { - println("#", i, "got ", got, ", wanted", t.want) - failed = true - } - } -} - -//go:noinline -func testInt64Index_ssa(s string, i int64) byte { - return s[i] -} - -//go:noinline -func testInt64Slice_ssa(s string, i, j int64) string { - return s[i:j] -} - -func testInt64Index() { - tests := []struct { - i int64 - j int64 - b byte - s string - }{ - {0, 5, 'B', "Below"}, - {5, 10, 'E', "Exact"}, - {10, 15, 'A', "Above"}, - } - - str := "BelowExactAbove" - for i, t := range tests { - if got := testInt64Index_ssa(str, t.i); got != t.b { - println("#", i, "got ", got, ", wanted", t.b) - failed = true - } - if got := testInt64Slice_ssa(str, t.i, t.j); got != t.s { - println("#", i, "got ", got, ", wanted", t.s) - failed = true - } - } -} - -func testInt64IndexPanic() { - defer func() { - if r := recover(); r != nil { - println("panicked as expected") - } - }() - - str := "foobar" - println("got ", testInt64Index_ssa(str, 1<<32+1)) - println("expected to panic, but didn't") - failed = true -} - -func testInt64SlicePanic() { - defer func() { - if r := recover(); r != nil { - println("panicked as expected") - } - }() - - str := "foobar" - println("got ", testInt64Slice_ssa(str, 1<<32, 1<<32+1)) - println("expected to panic, but didn't") - failed = true -} - -//go:noinline -func testStringElem_ssa(s string, i int) byte { - return s[i] -} - -func testStringElem() { - tests := []struct { - s string - i int - n byte - }{ - {"foobar", 3, 98}, - {"foobar", 0, 102}, - {"foobar", 5, 114}, - } - for _, t := range tests { - if got := testStringElem_ssa(t.s, t.i); got != t.n { - print("testStringElem \"", t.s, "\"[", t.i, "]=", got, ", wanted ", t.n, "\n") - failed = true - } - } -} - -//go:noinline -func testStringElemConst_ssa(i int) byte { - s := "foobar" - return s[i] -} - -func testStringElemConst() { - if got := testStringElemConst_ssa(3); got != 98 { - println("testStringElemConst=", got, ", wanted 98") - failed = true - } -} - -func main() { - testStringSlice() - testStringSlicePanic() - testStructSlice() - testSmallIndexType() - testStringElem() - testStringElemConst() - testInt64Index() - testInt64IndexPanic() - testInt64SlicePanic() - - if failed { - panic("failed") - } -} diff --git a/src/cmd/compile/internal/gc/testdata/string_test.go b/src/cmd/compile/internal/gc/testdata/string_test.go new file mode 100644 index 0000000000..5d086f0147 --- /dev/null +++ b/src/cmd/compile/internal/gc/testdata/string_test.go @@ -0,0 +1,207 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// string_ssa.go tests string operations. +package main + +import "testing" + +//go:noinline +func testStringSlice1_ssa(a string, i, j int) string { + return a[i:] +} + +//go:noinline +func testStringSlice2_ssa(a string, i, j int) string { + return a[:j] +} + +//go:noinline +func testStringSlice12_ssa(a string, i, j int) string { + return a[i:j] +} + +func testStringSlice(t *testing.T) { + tests := [...]struct { + fn func(string, int, int) string + s string + low, high int + want string + }{ + // -1 means the value is not used. + {testStringSlice1_ssa, "foobar", 0, -1, "foobar"}, + {testStringSlice1_ssa, "foobar", 3, -1, "bar"}, + {testStringSlice1_ssa, "foobar", 6, -1, ""}, + {testStringSlice2_ssa, "foobar", -1, 0, ""}, + {testStringSlice2_ssa, "foobar", -1, 3, "foo"}, + {testStringSlice2_ssa, "foobar", -1, 6, "foobar"}, + {testStringSlice12_ssa, "foobar", 0, 6, "foobar"}, + {testStringSlice12_ssa, "foobar", 0, 0, ""}, + {testStringSlice12_ssa, "foobar", 6, 6, ""}, + {testStringSlice12_ssa, "foobar", 1, 5, "ooba"}, + {testStringSlice12_ssa, "foobar", 3, 3, ""}, + {testStringSlice12_ssa, "", 0, 0, ""}, + } + + for i, test := range tests { + if got := test.fn(test.s, test.low, test.high); test.want != got { + t.Errorf("#%d %s[%d,%d] = %s, want %s", i, test.s, test.low, test.high, got, test.want) + } + } +} + +type prefix struct { + prefix string +} + +func (p *prefix) slice_ssa() { + p.prefix = p.prefix[:3] +} + +//go:noinline +func testStructSlice(t *testing.T) { + p := &prefix{"prefix"} + p.slice_ssa() + if "pre" != p.prefix { + t.Errorf("wrong field slice: wanted %s got %s", "pre", p.prefix) + } +} + +func testStringSlicePanic(t *testing.T) { + defer func() { + if r := recover(); r != nil { + //println("panicked as expected") + } + }() + + str := "foobar" + t.Errorf("got %s and expected to panic, but didn't", testStringSlice12_ssa(str, 3, 9)) +} + +const _Accuracy_name = "BelowExactAbove" + +var _Accuracy_index = [...]uint8{0, 5, 10, 15} + +//go:noinline +func testSmallIndexType_ssa(i int) string { + return _Accuracy_name[_Accuracy_index[i]:_Accuracy_index[i+1]] +} + +func testSmallIndexType(t *testing.T) { + tests := []struct { + i int + want string + }{ + {0, "Below"}, + {1, "Exact"}, + {2, "Above"}, + } + + for i, test := range tests { + if got := testSmallIndexType_ssa(test.i); got != test.want { + t.Errorf("#%d got %s wanted %s", i, got, test.want) + } + } +} + +//go:noinline +func testInt64Index_ssa(s string, i int64) byte { + return s[i] +} + +//go:noinline +func testInt64Slice_ssa(s string, i, j int64) string { + return s[i:j] +} + +func testInt64Index(t *testing.T) { + tests := []struct { + i int64 + j int64 + b byte + s string + }{ + {0, 5, 'B', "Below"}, + {5, 10, 'E', "Exact"}, + {10, 15, 'A', "Above"}, + } + + str := "BelowExactAbove" + for i, test := range tests { + if got := testInt64Index_ssa(str, test.i); got != test.b { + t.Errorf("#%d got %d wanted %d", i, got, test.b) + } + if got := testInt64Slice_ssa(str, test.i, test.j); got != test.s { + t.Errorf("#%d got %s wanted %s", i, got, test.s) + } + } +} + +func testInt64IndexPanic(t *testing.T) { + defer func() { + if r := recover(); r != nil { + //println("panicked as expected") + } + }() + + str := "foobar" + t.Errorf("got %d and expected to panic, but didn't", testInt64Index_ssa(str, 1<<32+1)) +} + +func testInt64SlicePanic(t *testing.T) { + defer func() { + if r := recover(); r != nil { + //println("panicked as expected") + } + }() + + str := "foobar" + t.Errorf("got %s and expected to panic, but didn't", testInt64Slice_ssa(str, 1<<32, 1<<32+1)) +} + +//go:noinline +func testStringElem_ssa(s string, i int) byte { + return s[i] +} + +func testStringElem(t *testing.T) { + tests := []struct { + s string + i int + n byte + }{ + {"foobar", 3, 98}, + {"foobar", 0, 102}, + {"foobar", 5, 114}, + } + for _, test := range tests { + if got := testStringElem_ssa(test.s, test.i); got != test.n { + t.Errorf("testStringElem \"%s\"[%d] = %d, wanted %d", test.s, test.i, got, test.n) + } + } +} + +//go:noinline +func testStringElemConst_ssa(i int) byte { + s := "foobar" + return s[i] +} + +func testStringElemConst(t *testing.T) { + if got := testStringElemConst_ssa(3); got != 98 { + t.Errorf("testStringElemConst= %d, wanted 98", got) + } +} + +func TestString(t *testing.T) { + testStringSlice(t) + testStringSlicePanic(t) + testStructSlice(t) + testSmallIndexType(t) + testStringElem(t) + testStringElemConst(t) + testInt64Index(t) + testInt64IndexPanic(t) + testInt64SlicePanic(t) +} -- cgit v1.3-5-g9baa