unsafe: optimize Slice bounds checking

This reduces the number of branches to bounds check non-empty slices
from 5 to 3. It does also increase the number of branches to handle
empty slices from 1 to 3; but for non-panicking calls, they should all
be predictable.

Updates #48798.

Change-Id: I3ffa66857096486f4dee417e1a66eb8fdf7a3777
Reviewed-on: https://go-review.googlesource.com/c/go/+/355490
Trust: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
diff --git a/src/runtime/slice.go b/src/runtime/slice.go
index 66bb7d9..aab8a59 100644
--- a/src/runtime/slice.go
+++ b/src/runtime/slice.go
@@ -115,16 +115,15 @@
 }
 
 func unsafeslice(et *_type, ptr unsafe.Pointer, len int) {
-	if len == 0 {
-		return
-	}
-
-	if ptr == nil {
-		panic(errorString("unsafe.Slice: ptr is nil and len is not zero"))
+	if len < 0 {
+		panicunsafeslicelen()
 	}
 
 	mem, overflow := math.MulUintptr(et.size, uintptr(len))
-	if overflow || mem > -uintptr(ptr) || len < 0 {
+	if overflow || mem > -uintptr(ptr) {
+		if ptr == nil {
+			panic(errorString("unsafe.Slice: ptr is nil and len is not zero"))
+		}
 		panicunsafeslicelen()
 	}
 }