]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: mask SLL,SRL,SRAconst shift amount
authorAlberto Donizetti <alb.donizetti@gmail.com>
Sat, 14 Nov 2020 12:33:32 +0000 (13:33 +0100)
committerAlberto Donizetti <alb.donizetti@gmail.com>
Mon, 16 Nov 2020 08:22:10 +0000 (08:22 +0000)
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>
src/cmd/compile/internal/ssa/gen/MIPS.rules
src/cmd/compile/internal/ssa/gen/MIPSOps.go
src/cmd/compile/internal/ssa/rewriteMIPS.go
test/fixedbugs/issue42587.go [new file with mode: 0644]

index aff12b4e363746ed5980c6a21588fff5e716cb65..7dcac9cf5391ac5210dd2ad8cdcad20a38d09608 100644 (file)
 (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)
index cd7357f62bd1904150f3e61517b5e076539f4707..75ab99ea26c254be35710518fc14b280a64227d6 100644 (file)
@@ -185,11 +185,11 @@ func init() {
 
                // 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"},
 
index 970bd7b52e9d4e938e5c3eedc96c88eec49d77e4..cfe39d7842c0487d1d8cf79618da1437fe791b8b 100644 (file)
@@ -4431,7 +4431,7 @@ func rewriteValueMIPS_OpMIPSSLL(v *Value) bool {
        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 @@ func rewriteValueMIPS_OpMIPSSLL(v *Value) bool {
                }
                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 @@ func rewriteValueMIPS_OpMIPSSRA(v *Value) bool {
        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 @@ func rewriteValueMIPS_OpMIPSSRA(v *Value) bool {
                }
                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 @@ func rewriteValueMIPS_OpMIPSSRL(v *Value) bool {
        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 @@ func rewriteValueMIPS_OpMIPSSRL(v *Value) bool {
                }
                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 (file)
index 0000000..d10ba97
--- /dev/null
@@ -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{})
+       }
+}