go/ssa: fix miscompilation of <<= and >>= statements

Unlike other binary operations, the RHS operand of a shift operation
does not need to have the same type as the LHS operand. In particular,
for "x <<= y" and "x >>= y" statements, coercing y to have the same
type as x can lead to miscompilation.

Fixes golang/go#52342.

Change-Id: I3ff139afa18f5637d527bd4a0b10d6b40ce53ab4
Reviewed-on: https://go-review.googlesource.com/c/tools/+/400394
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Zvonimir Pavlinovic <zpavlinovic@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Tim King <taking@google.com>
diff --git a/go/ssa/builder.go b/go/ssa/builder.go
index 45a8376..4a3eed9 100644
--- a/go/ssa/builder.go
+++ b/go/ssa/builder.go
@@ -1026,8 +1026,7 @@
 
 // assignOp emits to fn code to perform loc <op>= val.
 func (b *builder) assignOp(fn *Function, loc lvalue, val Value, op token.Token, pos token.Pos) {
-	oldv := loc.load(fn)
-	loc.store(fn, emitArith(fn, op, oldv, emitConv(fn, val, oldv.Type()), loc.typ(), pos))
+	loc.store(fn, emitArith(fn, op, loc.load(fn), val, loc.typ(), pos))
 }
 
 // localValueSpec emits to fn code to define all of the vars in the
diff --git a/go/ssa/interp/interp_test.go b/go/ssa/interp/interp_test.go
index c78d0d2..91ecb97 100644
--- a/go/ssa/interp/interp_test.go
+++ b/go/ssa/interp/interp_test.go
@@ -124,6 +124,8 @@
 	"reflect.go",
 	"static.go",
 	"width32.go",
+
+	"fixedbugs/issue52342.go",
 }
 
 // Specific GOARCH to use for a test case in go.tools/go/ssa/interp/testdata/.
diff --git a/go/ssa/interp/testdata/fixedbugs/issue52342.go b/go/ssa/interp/testdata/fixedbugs/issue52342.go
new file mode 100644
index 0000000..2e1cc63
--- /dev/null
+++ b/go/ssa/interp/testdata/fixedbugs/issue52342.go
@@ -0,0 +1,17 @@
+package main
+
+func main() {
+	var d byte
+
+	d = 1
+	d <<= 256
+	if d != 0 {
+		panic(d)
+	}
+
+	d = 1
+	d >>= 256
+	if d != 0 {
+		panic(d)
+	}
+}