cmd/compile: mask SLL,SRL,SRAconst shift amount
mips SRA/SLL/SRL shift amounts are used mod 32; this change aligns the
XXXconst rules to mask the shift amount by &31.
Passes
$ GOARCH=mips go build -toolexec 'toolstash -cmp' -a std
$ GOARCH=mipsle go build -toolexec 'toolstash -cmp' -a std
Fixes #42587
Change-Id: I6003ebd0bc500fba4cf6fb10254e1b557bf8c48f
Reviewed-on: https://go-review.googlesource.com/c/go/+/270117
Trust: Alberto Donizetti <alb.donizetti@gmail.com>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
diff --git a/src/cmd/compile/internal/ssa/gen/MIPS.rules b/src/cmd/compile/internal/ssa/gen/MIPS.rules
index aff12b4..7dcac9c 100644
--- a/src/cmd/compile/internal/ssa/gen/MIPS.rules
+++ b/src/cmd/compile/internal/ssa/gen/MIPS.rules
@@ -567,10 +567,9 @@
(XOR x (MOVWconst [c])) => (XORconst [c] x)
(NOR x (MOVWconst [c])) => (NORconst [c] x)
-(SRA x (MOVWconst [c])) && c >= 32 => (SRAconst x [31])
-(SLL x (MOVWconst [c])) => (SLLconst x [c])
-(SRL x (MOVWconst [c])) => (SRLconst x [c])
-(SRA x (MOVWconst [c])) => (SRAconst x [c])
+(SLL x (MOVWconst [c])) => (SLLconst x [c&31])
+(SRL x (MOVWconst [c])) => (SRLconst x [c&31])
+(SRA x (MOVWconst [c])) => (SRAconst x [c&31])
(SGT (MOVWconst [c]) x) => (SGTconst [c] x)
(SGTU (MOVWconst [c]) x) => (SGTUconst [c] x)
diff --git a/src/cmd/compile/internal/ssa/gen/MIPSOps.go b/src/cmd/compile/internal/ssa/gen/MIPSOps.go
index cd7357f..75ab99e 100644
--- a/src/cmd/compile/internal/ssa/gen/MIPSOps.go
+++ b/src/cmd/compile/internal/ssa/gen/MIPSOps.go
@@ -185,11 +185,11 @@
// shifts
{name: "SLL", argLength: 2, reg: gp21, asm: "SLL"}, // arg0 << arg1, shift amount is mod 32
- {name: "SLLconst", argLength: 1, reg: gp11, asm: "SLL", aux: "Int32"}, // arg0 << auxInt
+ {name: "SLLconst", argLength: 1, reg: gp11, asm: "SLL", aux: "Int32"}, // arg0 << auxInt, shift amount must be 0 through 31 inclusive
{name: "SRL", argLength: 2, reg: gp21, asm: "SRL"}, // arg0 >> arg1, unsigned, shift amount is mod 32
- {name: "SRLconst", argLength: 1, reg: gp11, asm: "SRL", aux: "Int32"}, // arg0 >> auxInt, unsigned
+ {name: "SRLconst", argLength: 1, reg: gp11, asm: "SRL", aux: "Int32"}, // arg0 >> auxInt, shift amount must be 0 through 31 inclusive
{name: "SRA", argLength: 2, reg: gp21, asm: "SRA"}, // arg0 >> arg1, signed, shift amount is mod 32
- {name: "SRAconst", argLength: 1, reg: gp11, asm: "SRA", aux: "Int32"}, // arg0 >> auxInt, signed
+ {name: "SRAconst", argLength: 1, reg: gp11, asm: "SRA", aux: "Int32"}, // arg0 >> auxInt, signed, shift amount must be 0 through 31 inclusive
{name: "CLZ", argLength: 1, reg: gp11, asm: "CLZ"},
diff --git a/src/cmd/compile/internal/ssa/rewriteMIPS.go b/src/cmd/compile/internal/ssa/rewriteMIPS.go
index 970bd7b..cfe39d7 100644
--- a/src/cmd/compile/internal/ssa/rewriteMIPS.go
+++ b/src/cmd/compile/internal/ssa/rewriteMIPS.go
@@ -4431,7 +4431,7 @@
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (SLL x (MOVWconst [c]))
- // result: (SLLconst x [c])
+ // result: (SLLconst x [c&31])
for {
x := v_0
if v_1.Op != OpMIPSMOVWconst {
@@ -4439,7 +4439,7 @@
}
c := auxIntToInt32(v_1.AuxInt)
v.reset(OpMIPSSLLconst)
- v.AuxInt = int32ToAuxInt(c)
+ v.AuxInt = int32ToAuxInt(c & 31)
v.AddArg(x)
return true
}
@@ -4465,24 +4465,7 @@
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (SRA x (MOVWconst [c]))
- // cond: c >= 32
- // result: (SRAconst x [31])
- for {
- x := v_0
- if v_1.Op != OpMIPSMOVWconst {
- break
- }
- c := auxIntToInt32(v_1.AuxInt)
- if !(c >= 32) {
- break
- }
- v.reset(OpMIPSSRAconst)
- v.AuxInt = int32ToAuxInt(31)
- v.AddArg(x)
- return true
- }
- // match: (SRA x (MOVWconst [c]))
- // result: (SRAconst x [c])
+ // result: (SRAconst x [c&31])
for {
x := v_0
if v_1.Op != OpMIPSMOVWconst {
@@ -4490,7 +4473,7 @@
}
c := auxIntToInt32(v_1.AuxInt)
v.reset(OpMIPSSRAconst)
- v.AuxInt = int32ToAuxInt(c)
+ v.AuxInt = int32ToAuxInt(c & 31)
v.AddArg(x)
return true
}
@@ -4516,7 +4499,7 @@
v_1 := v.Args[1]
v_0 := v.Args[0]
// match: (SRL x (MOVWconst [c]))
- // result: (SRLconst x [c])
+ // result: (SRLconst x [c&31])
for {
x := v_0
if v_1.Op != OpMIPSMOVWconst {
@@ -4524,7 +4507,7 @@
}
c := auxIntToInt32(v_1.AuxInt)
v.reset(OpMIPSSRLconst)
- v.AuxInt = int32ToAuxInt(c)
+ v.AuxInt = int32ToAuxInt(c & 31)
v.AddArg(x)
return true
}
diff --git a/test/fixedbugs/issue42587.go b/test/fixedbugs/issue42587.go
new file mode 100644
index 0000000..d10ba97
--- /dev/null
+++ b/test/fixedbugs/issue42587.go
@@ -0,0 +1,15 @@
+// compile
+
+// 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 p
+
+func f() {
+ var i, j int
+ _ = func() {
+ i = 32
+ j = j>>i | len([]int{})
+ }
+}