cmd/compile: special-case const comparisons against zero

Constant comparisons against 0 are reasonably common.
Special-case and avoid allocating a new zero value each time.

Change-Id: I6c526c8ab30ef7f0fef59110133c764b7b90ba05
Reviewed-on: https://go-review.googlesource.com/20956
Reviewed-by: Alan Donovan <adonovan@google.com>
diff --git a/src/cmd/compile/internal/gc/mpfloat.go b/src/cmd/compile/internal/gc/mpfloat.go
index ca290d7..72cc540 100644
--- a/src/cmd/compile/internal/gc/mpfloat.go
+++ b/src/cmd/compile/internal/gc/mpfloat.go
@@ -116,11 +116,11 @@
 	return a.Val.Cmp(&b.Val)
 }
 
-func (b *Mpflt) CmpFloat64(c float64) int {
-	var a Mpflt
-
-	a.SetFloat64(c)
-	return b.Cmp(&a)
+func (a *Mpflt) CmpFloat64(c float64) int {
+	if c == 0 {
+		return a.Val.Sign() // common case shortcut
+	}
+	return a.Val.Cmp(big.NewFloat(c))
 }
 
 func (a *Mpflt) Float64() float64 {
diff --git a/src/cmd/compile/internal/gc/mpint.go b/src/cmd/compile/internal/gc/mpint.go
index 1ab060e..d0f87de 100644
--- a/src/cmd/compile/internal/gc/mpint.go
+++ b/src/cmd/compile/internal/gc/mpint.go
@@ -262,8 +262,11 @@
 	return a.Val.Cmp(&b.Val)
 }
 
-func (b *Mpint) CmpInt64(c int64) int {
-	return b.Val.Cmp(big.NewInt(c))
+func (a *Mpint) CmpInt64(c int64) int {
+	if c == 0 {
+		return a.Val.Sign() // common case shortcut
+	}
+	return a.Val.Cmp(big.NewInt(c))
 }
 
 func (a *Mpint) Neg() {
diff --git a/src/cmd/compile/internal/gc/walk.go b/src/cmd/compile/internal/gc/walk.go
index 428d309..7a82a80 100644
--- a/src/cmd/compile/internal/gc/walk.go
+++ b/src/cmd/compile/internal/gc/walk.go
@@ -10,8 +10,6 @@
 	"strings"
 )
 
-var mpzero Mpint
-
 // The constant is known to runtime.
 const (
 	tmpstringbufsize = 32
@@ -1229,7 +1227,7 @@
 		}
 
 		if Isconst(n.Right, CTINT) {
-			if n.Right.Val().U.(*Mpint).Cmp(&mpzero) < 0 || n.Right.Val().U.(*Mpint).Cmp(Maxintval[TINT]) > 0 {
+			if n.Right.Val().U.(*Mpint).CmpInt64(0) < 0 || n.Right.Val().U.(*Mpint).Cmp(Maxintval[TINT]) > 0 {
 				Yyerror("index out of bounds")
 			}
 		}