[dev.ssa] cmd/compile/ssa: add comparison ops

Increase SSA coverage of functions in the
standard library from 20.79% to 27.81%.

The most significant unimplemented items are now:

 10.16%  2597 SSA unimplemented: zero for type error not implemented
  8.44%  2157 SSA unimplemented: addr: bad op DOTPTR
  7.98%  2039 SSA unimplemented: unhandled OLITERAL 7
  6.29%  1607 SSA unimplemented: unhandled expr OROR
  4.73%  1209 SSA unimplemented: unhandled expr LEN
  4.55%  1163 SSA unimplemented: unhandled expr LROT
  3.42%   874 SSA unimplemented: unhandled OLITERAL 6
  2.46%   629 SSA unimplemented: unhandled expr DOT
  2.41%   615 SSA unimplemented: zero for type []byte not implemented
  2.02%   516 SSA unimplemented: unhandled stmt CALLMETH
  1.90%   486 SSA unimplemented: unhandled expr ANDAND
  1.79%   458 SSA unimplemented: unhandled expr CALLINTER
  1.69%   433 SSA unimplemented: unhandled stmt SWITCH
  1.67%   428 SSA unimplemented: unhandled expr CALLMETH
  1.67%   426 SSA unimplemented: unhandled expr CLOSUREVAR

Change-Id: I40959b22993c4f70784b4eca472cae752347879c
Reviewed-on: https://go-review.googlesource.com/11452
Reviewed-by: Keith Randall <khr@golang.org>
diff --git a/src/cmd/compile/internal/gc/ssa.go b/src/cmd/compile/internal/gc/ssa.go
index 51e4735..f9c8c9b 100644
--- a/src/cmd/compile/internal/gc/ssa.go
+++ b/src/cmd/compile/internal/gc/ssa.go
@@ -392,7 +392,9 @@
 		// generate body
 		s.startBlock(bBody)
 		s.stmtList(n.Nbody)
-		s.stmt(n.Right)
+		if n.Right != nil {
+			s.stmt(n.Right)
+		}
 		b = s.endBlock()
 		addEdge(b, bCond)
 
@@ -409,6 +411,21 @@
 	}
 }
 
+var binOpToSSA = [...]ssa.Op{
+	// Comparisons
+	OEQ: ssa.OpEq,
+	ONE: ssa.OpNeq,
+	OLT: ssa.OpLess,
+	OLE: ssa.OpLeq,
+	OGT: ssa.OpGreater,
+	OGE: ssa.OpGeq,
+	// Arithmetic
+	OADD: ssa.OpAdd,
+	OSUB: ssa.OpSub,
+	OLSH: ssa.OpLsh,
+	ORSH: ssa.OpRsh,
+}
+
 // expr converts the expression n to ssa, adds it to s and returns the ssa result.
 func (s *state) expr(n *Node) *ssa.Value {
 	s.pushLine(n.Lineno)
@@ -444,28 +461,15 @@
 		x := s.expr(n.Left)
 		return s.newValue1(ssa.OpConvert, n.Type, x)
 
-		// binary ops
-	case OLT:
+	// binary ops
+	case OLT, OEQ, ONE, OLE, OGE, OGT:
 		a := s.expr(n.Left)
 		b := s.expr(n.Right)
-		return s.newValue2(ssa.OpLess, ssa.TypeBool, a, b)
-	case OADD:
+		return s.newValue2(binOpToSSA[n.Op], ssa.TypeBool, a, b)
+	case OADD, OSUB, OLSH, ORSH:
 		a := s.expr(n.Left)
 		b := s.expr(n.Right)
-		return s.newValue2(ssa.OpAdd, a.Type, a, b)
-	case OSUB:
-		// TODO:(khr) fold code for all binary ops together somehow
-		a := s.expr(n.Left)
-		b := s.expr(n.Right)
-		return s.newValue2(ssa.OpSub, a.Type, a, b)
-	case OLSH:
-		a := s.expr(n.Left)
-		b := s.expr(n.Right)
-		return s.newValue2(ssa.OpLsh, a.Type, a, b)
-	case ORSH:
-		a := s.expr(n.Left)
-		b := s.expr(n.Right)
-		return s.newValue2(ssa.OpRsh, a.Type, a, b)
+		return s.newValue2(binOpToSSA[n.Op], a.Type, a, b)
 
 	case OADDR:
 		return s.addr(n.Left)