]> Cypherpunks.ru repositories - gostls13.git/blobdiff - test/checkbce.go
cmd/compile/internal/inline: score call sites exposed by inlines
[gostls13.git] / test / checkbce.go
index a3b0100db8efdc1e40384675e6c58c460d88192e..71acfb71ac17d46ec08acde3f0d878f40c8cec65 100644 (file)
@@ -1,8 +1,18 @@
-// +build amd64
 // errorcheck -0 -d=ssa/check_bce/debug=3
 
+//go:build amd64 && !gcflags_noopt
+
+// Copyright 2016 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 the compiler does bounds check elimination as expected.
+// This avoids accidental regressions.
+
 package main
 
+import "encoding/binary"
+
 func f0(a []int) {
        a[0] = 1 // ERROR "Found IsInBounds$"
        a[0] = 1
@@ -13,23 +23,54 @@ func f0(a []int) {
 }
 
 func f1(a [256]int, i int) {
-       useInt(a[i])     // ERROR "Found IsInBounds$"
-       useInt(a[i%256]) // ERROR "Found IsInBounds$"
-       useInt(a[i&255])
-       useInt(a[i&17])
+       var j int
+       useInt(a[i]) // ERROR "Found IsInBounds$"
+       j = i % 256
+       useInt(a[j]) // ERROR "Found IsInBounds$"
+       j = i & 255
+       useInt(a[j])
+       j = i & 17
+       useInt(a[j])
 
        if 4 <= i && i < len(a) {
                useInt(a[i])
-               useInt(a[i-1]) // ERROR "Found IsInBounds$"
-               useInt(a[i-4]) // ERROR "Found IsInBounds$"
+               useInt(a[i-1])
+               useInt(a[i-4])
        }
 }
 
 func f2(a [256]int, i uint) {
        useInt(a[i]) // ERROR "Found IsInBounds$"
-       useInt(a[i%256])
-       useInt(a[i&255])
-       useInt(a[i&17])
+       j := i % 256
+       useInt(a[j])
+       j = i & 255
+       useInt(a[j])
+       j = i & 17
+       useInt(a[j])
+}
+
+func f2a(a [35]int, i uint8) {
+       useInt(a[i]) // ERROR "Found IsInBounds$"
+       j := i & 34
+       useInt(a[j])
+       j = i & 17
+       useInt(a[j])
+}
+
+func f2b(a [35]int, i uint16) {
+       useInt(a[i]) // ERROR "Found IsInBounds$"
+       j := i & 34
+       useInt(a[j])
+       j = i & 17
+       useInt(a[j])
+}
+
+func f2c(a [35]int, i uint32) {
+       useInt(a[i]) // ERROR "Found IsInBounds$"
+       j := i & 34
+       useInt(a[j])
+       j = i & 17
+       useInt(a[j])
 }
 
 func f3(a [256]int, i uint8) {
@@ -48,10 +89,22 @@ func f5(a []int) {
        if len(a) > 5 {
                useInt(a[5])
                useSlice(a[6:])
-               useSlice(a[:6]) // ERROR "Found IsSliceInBounds$"
+               useSlice(a[:6])
        }
 }
 
+func f6(a [32]int, b [64]int, i int) {
+       useInt(a[uint32(i*0x07C4ACDD)>>27])
+       useInt(b[uint64(i*0x07C4ACDD)>>58])
+       useInt(a[uint(i*0x07C4ACDD)>>59])
+
+       // The following bounds should not be removed because they can overflow.
+       useInt(a[uint32(i*0x106297f105d0cc86)>>26]) // ERROR "Found IsInBounds$"
+       useInt(b[uint64(i*0x106297f105d0cc86)>>57]) // ERROR "Found IsInBounds$"
+       useInt(a[int32(i*0x106297f105d0cc86)>>26])  // ERROR "Found IsInBounds$"
+       useInt(b[int64(i*0x106297f105d0cc86)>>57])  // ERROR "Found IsInBounds$"
+}
+
 func g1(a []int) {
        for i := range a {
                a[i] = i
@@ -77,6 +130,50 @@ func g3(a []int) {
        }
 }
 
+func g4(a [100]int) {
+       for i := 10; i < 50; i++ {
+               useInt(a[i-10])
+               useInt(a[i])
+               useInt(a[i+25])
+               useInt(a[i+50])
+
+               // The following are out of bounds.
+               if a[0] == 0xdeadbeef {
+                       // This is a trick to prohibit sccp to optimize out the following out of bound check
+                       continue
+               }
+               useInt(a[i-11]) // ERROR "Found IsInBounds$"
+               useInt(a[i+51]) // ERROR "Found IsInBounds$"
+       }
+}
+
+func decode1(data []byte) (x uint64) {
+       for len(data) >= 32 {
+               x += binary.BigEndian.Uint64(data[:8])
+               x += binary.BigEndian.Uint64(data[8:16])
+               x += binary.BigEndian.Uint64(data[16:24])
+               x += binary.BigEndian.Uint64(data[24:32])
+               data = data[32:]
+       }
+       return x
+}
+
+func decode2(data []byte) (x uint64) {
+       // TODO(rasky): this should behave like decode1 and compile to no
+       // boundchecks. We're currently not able to remove all of them.
+       for len(data) >= 32 {
+               x += binary.BigEndian.Uint64(data)
+               data = data[8:]
+               x += binary.BigEndian.Uint64(data) // ERROR "Found IsInBounds$"
+               data = data[8:]
+               x += binary.BigEndian.Uint64(data) // ERROR "Found IsInBounds$"
+               data = data[8:]
+               x += binary.BigEndian.Uint64(data) // ERROR "Found IsInBounds$"
+               data = data[8:]
+       }
+       return x
+}
+
 //go:noinline
 func useInt(a int) {
 }