[dev.ssa] cmd/compile: make zero-divide panic from div/mod explicit

Added an explicit compare-zero and branch-to-panic for
integer division and mod so that other optimizations will
not be fooled by their implicit panics.

Change-Id: Ibf96f636b541c0088861907c537a6beb4b99fa4c
Reviewed-on: https://go-review.googlesource.com/16450
Reviewed-by: Keith Randall <khr@golang.org>
diff --git a/src/cmd/compile/internal/gc/go.go b/src/cmd/compile/internal/gc/go.go
index dcc16d0..7b73380 100644
--- a/src/cmd/compile/internal/gc/go.go
+++ b/src/cmd/compile/internal/gc/go.go
@@ -858,6 +858,8 @@
 
 var panicslice *Node
 
+var panicdivide *Node
+
 var throwreturn *Node
 
 var growslice *Node
diff --git a/src/cmd/compile/internal/gc/pgen.go b/src/cmd/compile/internal/gc/pgen.go
index b3ba2fb..87e99df 100644
--- a/src/cmd/compile/internal/gc/pgen.go
+++ b/src/cmd/compile/internal/gc/pgen.go
@@ -339,6 +339,7 @@
 		Deferreturn = Sysfunc("deferreturn")
 		Panicindex = Sysfunc("panicindex")
 		panicslice = Sysfunc("panicslice")
+		panicdivide = Sysfunc("panicdivide")
 		throwreturn = Sysfunc("throwreturn")
 		growslice = Sysfunc("growslice")
 		typedmemmove_nostore = Sysfunc("typedmemmove_nostore")
diff --git a/src/cmd/compile/internal/gc/ssa.go b/src/cmd/compile/internal/gc/ssa.go
index c988465..4b4dc09 100644
--- a/src/cmd/compile/internal/gc/ssa.go
+++ b/src/cmd/compile/internal/gc/ssa.go
@@ -1655,9 +1655,22 @@
 				xreal = s.newValue1(ssa.OpCvt64Fto32F, pt, xreal)
 				ximag = s.newValue1(ssa.OpCvt64Fto32F, pt, ximag)
 			}
-
 			return s.newValue2(ssa.OpComplexMake, n.Type, xreal, ximag)
 		}
+		if n.Type.IsFloat() {
+			return s.newValue2(s.ssaOp(n.Op, n.Type), a.Type, a, b)
+		} else {
+			// do a size-appropriate check for zero
+			cmp := s.newValue2(s.ssaOp(ONE, n.Type), Types[TBOOL], b, s.zeroVal(n.Type))
+			s.check(cmp, panicdivide)
+			return s.newValue2(s.ssaOp(n.Op, n.Type), a.Type, a, b)
+		}
+	case OMOD:
+		a := s.expr(n.Left)
+		b := s.expr(n.Right)
+		// do a size-appropriate check for zero
+		cmp := s.newValue2(s.ssaOp(ONE, n.Type), Types[TBOOL], b, s.zeroVal(n.Type))
+		s.check(cmp, panicdivide)
 		return s.newValue2(s.ssaOp(n.Op, n.Type), a.Type, a, b)
 	case OADD, OSUB:
 		a := s.expr(n.Left)
@@ -1670,7 +1683,7 @@
 				s.newValue2(op, pt, s.newValue1(ssa.OpComplexImag, pt, a), s.newValue1(ssa.OpComplexImag, pt, b)))
 		}
 		return s.newValue2(s.ssaOp(n.Op, n.Type), a.Type, a, b)
-	case OAND, OOR, OMOD, OHMUL, OXOR:
+	case OAND, OOR, OHMUL, OXOR:
 		a := s.expr(n.Left)
 		b := s.expr(n.Right)
 		return s.newValue2(s.ssaOp(n.Op, n.Type), a.Type, a, b)