[release-branch.go1.14] cmd/compile: sign extend constant folding properly

MOVLconst must have a properly sign-extended auxint constant.
The bit operations in these rules don't enforce that invariant.

Fixes #42755

Change-Id: I729afcad18752d9b7739e49709020e3be7b3653e
Reviewed-on: https://go-review.googlesource.com/c/go/+/272030
Trust: Keith Randall <khr@golang.org>
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
diff --git a/src/cmd/compile/internal/ssa/gen/AMD64.rules b/src/cmd/compile/internal/ssa/gen/AMD64.rules
index 2d662d5a..f819aef 100644
--- a/src/cmd/compile/internal/ssa/gen/AMD64.rules
+++ b/src/cmd/compile/internal/ssa/gen/AMD64.rules
@@ -1465,11 +1465,11 @@
 (NOTQ (MOVQconst [c])) -> (MOVQconst [^c])
 (NOTL (MOVLconst [c])) -> (MOVLconst [^c])
 (BTSQconst [c] (MOVQconst [d])) -> (MOVQconst [d|(1<<uint32(c))])
-(BTSLconst [c] (MOVLconst [d])) -> (MOVLconst [d|(1<<uint32(c))])
+(BTSLconst [c] (MOVLconst [d])) -> (MOVLconst [int64(int32(d|(1<<uint32(c))))])
 (BTRQconst [c] (MOVQconst [d])) -> (MOVQconst [d&^(1<<uint32(c))])
-(BTRLconst [c] (MOVLconst [d])) -> (MOVLconst [d&^(1<<uint32(c))])
+(BTRLconst [c] (MOVLconst [d])) -> (MOVLconst [int64(int32(d&^(1<<uint32(c))))])
 (BTCQconst [c] (MOVQconst [d])) -> (MOVQconst [d^(1<<uint32(c))])
-(BTCLconst [c] (MOVLconst [d])) -> (MOVLconst [d^(1<<uint32(c))])
+(BTCLconst [c] (MOVLconst [d])) -> (MOVLconst [int64(int32(d^(1<<uint32(c))))])
 
 // generic simplifications
 // TODO: more of this
diff --git a/src/cmd/compile/internal/ssa/rewriteAMD64.go b/src/cmd/compile/internal/ssa/rewriteAMD64.go
index c104157..366eac0 100644
--- a/src/cmd/compile/internal/ssa/rewriteAMD64.go
+++ b/src/cmd/compile/internal/ssa/rewriteAMD64.go
@@ -4326,7 +4326,7 @@
 		return true
 	}
 	// match: (BTCLconst [c] (MOVLconst [d]))
-	// result: (MOVLconst [d^(1<<uint32(c))])
+	// result: (MOVLconst [int64(int32(d^(1<<uint32(c))))])
 	for {
 		c := v.AuxInt
 		v_0 := v.Args[0]
@@ -4335,7 +4335,7 @@
 		}
 		d := v_0.AuxInt
 		v.reset(OpAMD64MOVLconst)
-		v.AuxInt = d ^ (1 << uint32(c))
+		v.AuxInt = int64(int32(d ^ (1 << uint32(c))))
 		return true
 	}
 	return false
@@ -4825,7 +4825,7 @@
 		return true
 	}
 	// match: (BTRLconst [c] (MOVLconst [d]))
-	// result: (MOVLconst [d&^(1<<uint32(c))])
+	// result: (MOVLconst [int64(int32(d&^(1<<uint32(c))))])
 	for {
 		c := v.AuxInt
 		v_0 := v.Args[0]
@@ -4834,7 +4834,7 @@
 		}
 		d := v_0.AuxInt
 		v.reset(OpAMD64MOVLconst)
-		v.AuxInt = d &^ (1 << uint32(c))
+		v.AuxInt = int64(int32(d &^ (1 << uint32(c))))
 		return true
 	}
 	return false
@@ -5181,7 +5181,7 @@
 		return true
 	}
 	// match: (BTSLconst [c] (MOVLconst [d]))
-	// result: (MOVLconst [d|(1<<uint32(c))])
+	// result: (MOVLconst [int64(int32(d|(1<<uint32(c))))])
 	for {
 		c := v.AuxInt
 		v_0 := v.Args[0]
@@ -5190,7 +5190,7 @@
 		}
 		d := v_0.AuxInt
 		v.reset(OpAMD64MOVLconst)
-		v.AuxInt = d | (1 << uint32(c))
+		v.AuxInt = int64(int32(d | (1 << uint32(c))))
 		return true
 	}
 	return false
diff --git a/test/fixedbugs/issue42753.go b/test/fixedbugs/issue42753.go
new file mode 100644
index 0000000..a998d1d
--- /dev/null
+++ b/test/fixedbugs/issue42753.go
@@ -0,0 +1,13 @@
+// compile -d=ssa/check/on
+
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+func f() uint32 {
+	s := "\x01"
+	x := -int32(s[0])
+	return uint32(x) & 0x7fffffff
+}