]> Cypherpunks repositories - gostls13.git/commitdiff
[release-branch.go1.17] cmd/compile: ensure constant shift amounts are in range for arm
authorKeith Randall <khr@golang.org>
Mon, 20 Sep 2021 04:09:57 +0000 (21:09 -0700)
committerDmitri Shuralyov <dmitshur@golang.org>
Wed, 27 Oct 2021 21:13:34 +0000 (21:13 +0000)
Ensure constant shift amounts are in the range [0-31]. When shift amounts
are out of range, bad things happen. Shift amounts out of range occur
when lowering 64-bit shifts (we take an in-range shift s in [0-63] and
calculate s-32 and 32-s, both of which might be out of [0-31]).

The constant shift operations themselves still work, but their shift
amounts get copied unmolested to operations like ORshiftLL which use only
the low 5 bits. That changes an operation like <<100 which unconditionally
produces 0, to <<4, which doesn't.

Fixes #48479

Change-Id: I87363ef2b4ceaf3b2e316426064626efdfbb8ee3
Reviewed-on: https://go-review.googlesource.com/c/go/+/350969
Trust: Keith Randall <khr@golang.org>
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
(cherry picked from commit eff27e858b771bf5e0b5e7e836827c7d2941e6d4)
Reviewed-on: https://go-review.googlesource.com/c/go/+/351069
Reviewed-by: Austin Clements <austin@google.com>
src/cmd/compile/internal/ssa/gen/ARM.rules
src/cmd/compile/internal/ssa/gen/ARMOps.go
src/cmd/compile/internal/ssa/gen/genericOps.go
src/cmd/compile/internal/ssa/rewriteARM.go
test/fixedbugs/issue48476.go [new file with mode: 0644]

index d9a2e4ef87486a9c7151d21be9adfa09ea6d8629..3dd83ecab50ad6e15c4dc9c10572a075e90821cc 100644 (file)
 (XOR x (MOVWconst [c])) => (XORconst [c] x)
 (BIC x (MOVWconst [c])) => (BICconst [c] x)
 
-(SLL x (MOVWconst [c])) => (SLLconst x [c&31]) // Note: I don't think we ever generate bad constant shifts (i.e. c>=32)
-(SRL x (MOVWconst [c])) => (SRLconst x [c&31])
-(SRA x (MOVWconst [c])) => (SRAconst x [c&31])
+(SLL x (MOVWconst [c])) && 0 <= c && c < 32 => (SLLconst x [c])
+(SRL x (MOVWconst [c])) && 0 <= c && c < 32 => (SRLconst x [c])
+(SRA x (MOVWconst [c])) && 0 <= c && c < 32 => (SRAconst x [c])
 
 (CMP x (MOVWconst [c])) => (CMPconst [c] x)
 (CMP (MOVWconst [c]) x) => (InvertFlags (CMPconst [c] x))
 (CMNshiftRL x (MOVWconst [c]) [d]) => (CMNconst x [int32(uint32(c)>>uint64(d))])
 (CMNshiftRA x (MOVWconst [c]) [d]) => (CMNconst x [c>>uint64(d)])
 
-(ADDshiftLLreg x y (MOVWconst [c])) => (ADDshiftLL x y [c])
-(ADDshiftRLreg x y (MOVWconst [c])) => (ADDshiftRL x y [c])
-(ADDshiftRAreg x y (MOVWconst [c])) => (ADDshiftRA x y [c])
-(ADCshiftLLreg x y (MOVWconst [c]) flags) => (ADCshiftLL x y [c] flags)
-(ADCshiftRLreg x y (MOVWconst [c]) flags) => (ADCshiftRL x y [c] flags)
-(ADCshiftRAreg x y (MOVWconst [c]) flags) => (ADCshiftRA x y [c] flags)
-(ADDSshiftLLreg x y (MOVWconst [c])) => (ADDSshiftLL x y [c])
-(ADDSshiftRLreg x y (MOVWconst [c])) => (ADDSshiftRL x y [c])
-(ADDSshiftRAreg x y (MOVWconst [c])) => (ADDSshiftRA x y [c])
-(SUBshiftLLreg x y (MOVWconst [c])) => (SUBshiftLL x y [c])
-(SUBshiftRLreg x y (MOVWconst [c])) => (SUBshiftRL x y [c])
-(SUBshiftRAreg x y (MOVWconst [c])) => (SUBshiftRA x y [c])
-(SBCshiftLLreg x y (MOVWconst [c]) flags) => (SBCshiftLL x y [c] flags)
-(SBCshiftRLreg x y (MOVWconst [c]) flags) => (SBCshiftRL x y [c] flags)
-(SBCshiftRAreg x y (MOVWconst [c]) flags) => (SBCshiftRA x y [c] flags)
-(SUBSshiftLLreg x y (MOVWconst [c])) => (SUBSshiftLL x y [c])
-(SUBSshiftRLreg x y (MOVWconst [c])) => (SUBSshiftRL x y [c])
-(SUBSshiftRAreg x y (MOVWconst [c])) => (SUBSshiftRA x y [c])
-(RSBshiftLLreg x y (MOVWconst [c])) => (RSBshiftLL x y [c])
-(RSBshiftRLreg x y (MOVWconst [c])) => (RSBshiftRL x y [c])
-(RSBshiftRAreg x y (MOVWconst [c])) => (RSBshiftRA x y [c])
-(RSCshiftLLreg x y (MOVWconst [c]) flags) => (RSCshiftLL x y [c] flags)
-(RSCshiftRLreg x y (MOVWconst [c]) flags) => (RSCshiftRL x y [c] flags)
-(RSCshiftRAreg x y (MOVWconst [c]) flags) => (RSCshiftRA x y [c] flags)
-(RSBSshiftLLreg x y (MOVWconst [c])) => (RSBSshiftLL x y [c])
-(RSBSshiftRLreg x y (MOVWconst [c])) => (RSBSshiftRL x y [c])
-(RSBSshiftRAreg x y (MOVWconst [c])) => (RSBSshiftRA x y [c])
-(ANDshiftLLreg x y (MOVWconst [c])) => (ANDshiftLL x y [c])
-(ANDshiftRLreg x y (MOVWconst [c])) => (ANDshiftRL x y [c])
-(ANDshiftRAreg x y (MOVWconst [c])) => (ANDshiftRA x y [c])
-(ORshiftLLreg x y (MOVWconst [c])) => (ORshiftLL x y [c])
-(ORshiftRLreg x y (MOVWconst [c])) => (ORshiftRL x y [c])
-(ORshiftRAreg x y (MOVWconst [c])) => (ORshiftRA x y [c])
-(XORshiftLLreg x y (MOVWconst [c])) => (XORshiftLL x y [c])
-(XORshiftRLreg x y (MOVWconst [c])) => (XORshiftRL x y [c])
-(XORshiftRAreg x y (MOVWconst [c])) => (XORshiftRA x y [c])
-(BICshiftLLreg x y (MOVWconst [c])) => (BICshiftLL x y [c])
-(BICshiftRLreg x y (MOVWconst [c])) => (BICshiftRL x y [c])
-(BICshiftRAreg x y (MOVWconst [c])) => (BICshiftRA x y [c])
-(MVNshiftLLreg x (MOVWconst [c])) => (MVNshiftLL x [c])
-(MVNshiftRLreg x (MOVWconst [c])) => (MVNshiftRL x [c])
-(MVNshiftRAreg x (MOVWconst [c])) => (MVNshiftRA x [c])
-(CMPshiftLLreg x y (MOVWconst [c])) => (CMPshiftLL x y [c])
-(CMPshiftRLreg x y (MOVWconst [c])) => (CMPshiftRL x y [c])
-(CMPshiftRAreg x y (MOVWconst [c])) => (CMPshiftRA x y [c])
-(TSTshiftLLreg x y (MOVWconst [c])) => (TSTshiftLL x y [c])
-(TSTshiftRLreg x y (MOVWconst [c])) => (TSTshiftRL x y [c])
-(TSTshiftRAreg x y (MOVWconst [c])) => (TSTshiftRA x y [c])
-(TEQshiftLLreg x y (MOVWconst [c])) => (TEQshiftLL x y [c])
-(TEQshiftRLreg x y (MOVWconst [c])) => (TEQshiftRL x y [c])
-(TEQshiftRAreg x y (MOVWconst [c])) => (TEQshiftRA x y [c])
-(CMNshiftLLreg x y (MOVWconst [c])) => (CMNshiftLL x y [c])
-(CMNshiftRLreg x y (MOVWconst [c])) => (CMNshiftRL x y [c])
-(CMNshiftRAreg x y (MOVWconst [c])) => (CMNshiftRA x y [c])
+(ADDshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ADDshiftLL x y [c])
+(ADDshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ADDshiftRL x y [c])
+(ADDshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ADDshiftRA x y [c])
+(ADCshiftLLreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (ADCshiftLL x y [c] flags)
+(ADCshiftRLreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (ADCshiftRL x y [c] flags)
+(ADCshiftRAreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (ADCshiftRA x y [c] flags)
+(ADDSshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ADDSshiftLL x y [c])
+(ADDSshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ADDSshiftRL x y [c])
+(ADDSshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ADDSshiftRA x y [c])
+(SUBshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (SUBshiftLL x y [c])
+(SUBshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (SUBshiftRL x y [c])
+(SUBshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (SUBshiftRA x y [c])
+(SBCshiftLLreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (SBCshiftLL x y [c] flags)
+(SBCshiftRLreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (SBCshiftRL x y [c] flags)
+(SBCshiftRAreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (SBCshiftRA x y [c] flags)
+(SUBSshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (SUBSshiftLL x y [c])
+(SUBSshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (SUBSshiftRL x y [c])
+(SUBSshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (SUBSshiftRA x y [c])
+(RSBshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (RSBshiftLL x y [c])
+(RSBshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (RSBshiftRL x y [c])
+(RSBshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (RSBshiftRA x y [c])
+(RSCshiftLLreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (RSCshiftLL x y [c] flags)
+(RSCshiftRLreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (RSCshiftRL x y [c] flags)
+(RSCshiftRAreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (RSCshiftRA x y [c] flags)
+(RSBSshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (RSBSshiftLL x y [c])
+(RSBSshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (RSBSshiftRL x y [c])
+(RSBSshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (RSBSshiftRA x y [c])
+(ANDshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ANDshiftLL x y [c])
+(ANDshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ANDshiftRL x y [c])
+(ANDshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ANDshiftRA x y [c])
+(ORshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ORshiftLL x y [c])
+(ORshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ORshiftRL x y [c])
+(ORshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ORshiftRA x y [c])
+(XORshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (XORshiftLL x y [c])
+(XORshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (XORshiftRL x y [c])
+(XORshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (XORshiftRA x y [c])
+(BICshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (BICshiftLL x y [c])
+(BICshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (BICshiftRL x y [c])
+(BICshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (BICshiftRA x y [c])
+(MVNshiftLLreg x (MOVWconst [c])) && 0 <= c && c < 32 => (MVNshiftLL x [c])
+(MVNshiftRLreg x (MOVWconst [c])) && 0 <= c && c < 32 => (MVNshiftRL x [c])
+(MVNshiftRAreg x (MOVWconst [c])) && 0 <= c && c < 32 => (MVNshiftRA x [c])
+(CMPshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (CMPshiftLL x y [c])
+(CMPshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (CMPshiftRL x y [c])
+(CMPshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (CMPshiftRA x y [c])
+(TSTshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (TSTshiftLL x y [c])
+(TSTshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (TSTshiftRL x y [c])
+(TSTshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (TSTshiftRA x y [c])
+(TEQshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (TEQshiftLL x y [c])
+(TEQshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (TEQshiftRL x y [c])
+(TEQshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (TEQshiftRA x y [c])
+(CMNshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (CMNshiftLL x y [c])
+(CMNshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (CMNshiftRL x y [c])
+(CMNshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (CMNshiftRA x y [c])
 
 // Generate rotates
 (ADDshiftLL [c] (SRLconst x [32-c]) x) => (SRRconst [32-c] x)
index d1f86039a36e5c98ab7d6681928d67ea50e66302..74b044a9706a855ea0229c0867127d8d3cbf07b6 100644 (file)
@@ -228,14 +228,15 @@ func init() {
 
                // shifts
                {name: "SLL", argLength: 2, reg: gp21, asm: "SLL"},                    // arg0 << arg1, shift amount is mod 256
-               {name: "SLLconst", argLength: 1, reg: gp11, asm: "SLL", aux: "Int32"}, // arg0 << auxInt
+               {name: "SLLconst", argLength: 1, reg: gp11, asm: "SLL", aux: "Int32"}, // arg0 << auxInt, 0 <= auxInt < 32
                {name: "SRL", argLength: 2, reg: gp21, asm: "SRL"},                    // arg0 >> arg1, unsigned, shift amount is mod 256
-               {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, unsigned, 0 <= auxInt < 32
                {name: "SRA", argLength: 2, reg: gp21, asm: "SRA"},                    // arg0 >> arg1, signed, shift amount is mod 256
-               {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, 0 <= auxInt < 32
                {name: "SRR", argLength: 2, reg: gp21},                                // arg0 right rotate by arg1 bits
-               {name: "SRRconst", argLength: 1, reg: gp11, aux: "Int32"},             // arg0 right rotate by auxInt bits
+               {name: "SRRconst", argLength: 1, reg: gp11, aux: "Int32"},             // arg0 right rotate by auxInt bits, 0 <= auxInt < 32
 
+               // auxInt for all of these satisfy 0 <= auxInt < 32
                {name: "ADDshiftLL", argLength: 2, reg: gp21, asm: "ADD", aux: "Int32"}, // arg0 + arg1<<auxInt
                {name: "ADDshiftRL", argLength: 2, reg: gp21, asm: "ADD", aux: "Int32"}, // arg0 + arg1>>auxInt, unsigned shift
                {name: "ADDshiftRA", argLength: 2, reg: gp21, asm: "ADD", aux: "Int32"}, // arg0 + arg1>>auxInt, signed shift
index 9f6664386c9d1749e51c4d6bd3a29c6fecd7d37d..2a47c4268206b246de1dead1e20cf756e258e0db 100644 (file)
@@ -106,7 +106,7 @@ var genericOps = []opData{
 
        // For shifts, AxB means the shifted value has A bits and the shift amount has B bits.
        // Shift amounts are considered unsigned.
-       // If arg1 is known to be less than the number of bits in arg0,
+       // If arg1 is known to be nonnegative and less than the number of bits in arg0,
        // then auxInt may be set to 1.
        // This enables better code generation on some platforms.
        {name: "Lsh8x8", argLength: 2, aux: "Bool"}, // arg0 << arg1
index ffdee34070034ad2c7e44fc04e7cf08232906981..ec8d7125b60ab6a8197003e05f0962901c8c2aeb 100644 (file)
@@ -1119,6 +1119,7 @@ func rewriteValueARM_OpARMADCshiftLLreg(v *Value) bool {
                return true
        }
        // match: (ADCshiftLLreg x y (MOVWconst [c]) flags)
+       // cond: 0 <= c && c < 32
        // result: (ADCshiftLL x y [c] flags)
        for {
                x := v_0
@@ -1128,6 +1129,9 @@ func rewriteValueARM_OpARMADCshiftLLreg(v *Value) bool {
                }
                c := auxIntToInt32(v_2.AuxInt)
                flags := v_3
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMADCshiftLL)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg3(x, y, flags)
@@ -1199,6 +1203,7 @@ func rewriteValueARM_OpARMADCshiftRAreg(v *Value) bool {
                return true
        }
        // match: (ADCshiftRAreg x y (MOVWconst [c]) flags)
+       // cond: 0 <= c && c < 32
        // result: (ADCshiftRA x y [c] flags)
        for {
                x := v_0
@@ -1208,6 +1213,9 @@ func rewriteValueARM_OpARMADCshiftRAreg(v *Value) bool {
                }
                c := auxIntToInt32(v_2.AuxInt)
                flags := v_3
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMADCshiftRA)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg3(x, y, flags)
@@ -1279,6 +1287,7 @@ func rewriteValueARM_OpARMADCshiftRLreg(v *Value) bool {
                return true
        }
        // match: (ADCshiftRLreg x y (MOVWconst [c]) flags)
+       // cond: 0 <= c && c < 32
        // result: (ADCshiftRL x y [c] flags)
        for {
                x := v_0
@@ -1288,6 +1297,9 @@ func rewriteValueARM_OpARMADCshiftRLreg(v *Value) bool {
                }
                c := auxIntToInt32(v_2.AuxInt)
                flags := v_3
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMADCshiftRL)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg3(x, y, flags)
@@ -1740,6 +1752,7 @@ func rewriteValueARM_OpARMADDSshiftLLreg(v *Value) bool {
                return true
        }
        // match: (ADDSshiftLLreg x y (MOVWconst [c]))
+       // cond: 0 <= c && c < 32
        // result: (ADDSshiftLL x y [c])
        for {
                x := v_0
@@ -1748,6 +1761,9 @@ func rewriteValueARM_OpARMADDSshiftLLreg(v *Value) bool {
                        break
                }
                c := auxIntToInt32(v_2.AuxInt)
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMADDSshiftLL)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg2(x, y)
@@ -1814,6 +1830,7 @@ func rewriteValueARM_OpARMADDSshiftRAreg(v *Value) bool {
                return true
        }
        // match: (ADDSshiftRAreg x y (MOVWconst [c]))
+       // cond: 0 <= c && c < 32
        // result: (ADDSshiftRA x y [c])
        for {
                x := v_0
@@ -1822,6 +1839,9 @@ func rewriteValueARM_OpARMADDSshiftRAreg(v *Value) bool {
                        break
                }
                c := auxIntToInt32(v_2.AuxInt)
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMADDSshiftRA)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg2(x, y)
@@ -1888,6 +1908,7 @@ func rewriteValueARM_OpARMADDSshiftRLreg(v *Value) bool {
                return true
        }
        // match: (ADDSshiftRLreg x y (MOVWconst [c]))
+       // cond: 0 <= c && c < 32
        // result: (ADDSshiftRL x y [c])
        for {
                x := v_0
@@ -1896,6 +1917,9 @@ func rewriteValueARM_OpARMADDSshiftRLreg(v *Value) bool {
                        break
                }
                c := auxIntToInt32(v_2.AuxInt)
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMADDSshiftRL)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg2(x, y)
@@ -2124,6 +2148,7 @@ func rewriteValueARM_OpARMADDshiftLLreg(v *Value) bool {
                return true
        }
        // match: (ADDshiftLLreg x y (MOVWconst [c]))
+       // cond: 0 <= c && c < 32
        // result: (ADDshiftLL x y [c])
        for {
                x := v_0
@@ -2132,6 +2157,9 @@ func rewriteValueARM_OpARMADDshiftLLreg(v *Value) bool {
                        break
                }
                c := auxIntToInt32(v_2.AuxInt)
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMADDshiftLL)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg2(x, y)
@@ -2198,6 +2226,7 @@ func rewriteValueARM_OpARMADDshiftRAreg(v *Value) bool {
                return true
        }
        // match: (ADDshiftRAreg x y (MOVWconst [c]))
+       // cond: 0 <= c && c < 32
        // result: (ADDshiftRA x y [c])
        for {
                x := v_0
@@ -2206,6 +2235,9 @@ func rewriteValueARM_OpARMADDshiftRAreg(v *Value) bool {
                        break
                }
                c := auxIntToInt32(v_2.AuxInt)
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMADDshiftRA)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg2(x, y)
@@ -2288,6 +2320,7 @@ func rewriteValueARM_OpARMADDshiftRLreg(v *Value) bool {
                return true
        }
        // match: (ADDshiftRLreg x y (MOVWconst [c]))
+       // cond: 0 <= c && c < 32
        // result: (ADDshiftRL x y [c])
        for {
                x := v_0
@@ -2296,6 +2329,9 @@ func rewriteValueARM_OpARMADDshiftRLreg(v *Value) bool {
                        break
                }
                c := auxIntToInt32(v_2.AuxInt)
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMADDshiftRL)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg2(x, y)
@@ -2653,6 +2689,7 @@ func rewriteValueARM_OpARMANDshiftLLreg(v *Value) bool {
                return true
        }
        // match: (ANDshiftLLreg x y (MOVWconst [c]))
+       // cond: 0 <= c && c < 32
        // result: (ANDshiftLL x y [c])
        for {
                x := v_0
@@ -2661,6 +2698,9 @@ func rewriteValueARM_OpARMANDshiftLLreg(v *Value) bool {
                        break
                }
                c := auxIntToInt32(v_2.AuxInt)
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMANDshiftLL)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg2(x, y)
@@ -2742,6 +2782,7 @@ func rewriteValueARM_OpARMANDshiftRAreg(v *Value) bool {
                return true
        }
        // match: (ANDshiftRAreg x y (MOVWconst [c]))
+       // cond: 0 <= c && c < 32
        // result: (ANDshiftRA x y [c])
        for {
                x := v_0
@@ -2750,6 +2791,9 @@ func rewriteValueARM_OpARMANDshiftRAreg(v *Value) bool {
                        break
                }
                c := auxIntToInt32(v_2.AuxInt)
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMANDshiftRA)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg2(x, y)
@@ -2831,6 +2875,7 @@ func rewriteValueARM_OpARMANDshiftRLreg(v *Value) bool {
                return true
        }
        // match: (ANDshiftRLreg x y (MOVWconst [c]))
+       // cond: 0 <= c && c < 32
        // result: (ANDshiftRL x y [c])
        for {
                x := v_0
@@ -2839,6 +2884,9 @@ func rewriteValueARM_OpARMANDshiftRLreg(v *Value) bool {
                        break
                }
                c := auxIntToInt32(v_2.AuxInt)
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMANDshiftRL)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg2(x, y)
@@ -3107,6 +3155,7 @@ func rewriteValueARM_OpARMBICshiftLLreg(v *Value) bool {
        v_1 := v.Args[1]
        v_0 := v.Args[0]
        // match: (BICshiftLLreg x y (MOVWconst [c]))
+       // cond: 0 <= c && c < 32
        // result: (BICshiftLL x y [c])
        for {
                x := v_0
@@ -3115,6 +3164,9 @@ func rewriteValueARM_OpARMBICshiftLLreg(v *Value) bool {
                        break
                }
                c := auxIntToInt32(v_2.AuxInt)
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMBICshiftLL)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg2(x, y)
@@ -3161,6 +3213,7 @@ func rewriteValueARM_OpARMBICshiftRAreg(v *Value) bool {
        v_1 := v.Args[1]
        v_0 := v.Args[0]
        // match: (BICshiftRAreg x y (MOVWconst [c]))
+       // cond: 0 <= c && c < 32
        // result: (BICshiftRA x y [c])
        for {
                x := v_0
@@ -3169,6 +3222,9 @@ func rewriteValueARM_OpARMBICshiftRAreg(v *Value) bool {
                        break
                }
                c := auxIntToInt32(v_2.AuxInt)
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMBICshiftRA)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg2(x, y)
@@ -3215,6 +3271,7 @@ func rewriteValueARM_OpARMBICshiftRLreg(v *Value) bool {
        v_1 := v.Args[1]
        v_0 := v.Args[0]
        // match: (BICshiftRLreg x y (MOVWconst [c]))
+       // cond: 0 <= c && c < 32
        // result: (BICshiftRL x y [c])
        for {
                x := v_0
@@ -3223,6 +3280,9 @@ func rewriteValueARM_OpARMBICshiftRLreg(v *Value) bool {
                        break
                }
                c := auxIntToInt32(v_2.AuxInt)
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMBICshiftRL)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg2(x, y)
@@ -3425,6 +3485,7 @@ func rewriteValueARM_OpARMCMNshiftLLreg(v *Value) bool {
                return true
        }
        // match: (CMNshiftLLreg x y (MOVWconst [c]))
+       // cond: 0 <= c && c < 32
        // result: (CMNshiftLL x y [c])
        for {
                x := v_0
@@ -3433,6 +3494,9 @@ func rewriteValueARM_OpARMCMNshiftLLreg(v *Value) bool {
                        break
                }
                c := auxIntToInt32(v_2.AuxInt)
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMCMNshiftLL)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg2(x, y)
@@ -3499,6 +3563,7 @@ func rewriteValueARM_OpARMCMNshiftRAreg(v *Value) bool {
                return true
        }
        // match: (CMNshiftRAreg x y (MOVWconst [c]))
+       // cond: 0 <= c && c < 32
        // result: (CMNshiftRA x y [c])
        for {
                x := v_0
@@ -3507,6 +3572,9 @@ func rewriteValueARM_OpARMCMNshiftRAreg(v *Value) bool {
                        break
                }
                c := auxIntToInt32(v_2.AuxInt)
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMCMNshiftRA)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg2(x, y)
@@ -3573,6 +3641,7 @@ func rewriteValueARM_OpARMCMNshiftRLreg(v *Value) bool {
                return true
        }
        // match: (CMNshiftRLreg x y (MOVWconst [c]))
+       // cond: 0 <= c && c < 32
        // result: (CMNshiftRL x y [c])
        for {
                x := v_0
@@ -3581,6 +3650,9 @@ func rewriteValueARM_OpARMCMNshiftRLreg(v *Value) bool {
                        break
                }
                c := auxIntToInt32(v_2.AuxInt)
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMCMNshiftRL)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg2(x, y)
@@ -4078,6 +4150,7 @@ func rewriteValueARM_OpARMCMPshiftLLreg(v *Value) bool {
                return true
        }
        // match: (CMPshiftLLreg x y (MOVWconst [c]))
+       // cond: 0 <= c && c < 32
        // result: (CMPshiftLL x y [c])
        for {
                x := v_0
@@ -4086,6 +4159,9 @@ func rewriteValueARM_OpARMCMPshiftLLreg(v *Value) bool {
                        break
                }
                c := auxIntToInt32(v_2.AuxInt)
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMCMPshiftLL)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg2(x, y)
@@ -4156,6 +4232,7 @@ func rewriteValueARM_OpARMCMPshiftRAreg(v *Value) bool {
                return true
        }
        // match: (CMPshiftRAreg x y (MOVWconst [c]))
+       // cond: 0 <= c && c < 32
        // result: (CMPshiftRA x y [c])
        for {
                x := v_0
@@ -4164,6 +4241,9 @@ func rewriteValueARM_OpARMCMPshiftRAreg(v *Value) bool {
                        break
                }
                c := auxIntToInt32(v_2.AuxInt)
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMCMPshiftRA)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg2(x, y)
@@ -4234,6 +4314,7 @@ func rewriteValueARM_OpARMCMPshiftRLreg(v *Value) bool {
                return true
        }
        // match: (CMPshiftRLreg x y (MOVWconst [c]))
+       // cond: 0 <= c && c < 32
        // result: (CMPshiftRL x y [c])
        for {
                x := v_0
@@ -4242,6 +4323,9 @@ func rewriteValueARM_OpARMCMPshiftRLreg(v *Value) bool {
                        break
                }
                c := auxIntToInt32(v_2.AuxInt)
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMCMPshiftRL)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg2(x, y)
@@ -8089,6 +8173,7 @@ func rewriteValueARM_OpARMMVNshiftLLreg(v *Value) bool {
        v_1 := v.Args[1]
        v_0 := v.Args[0]
        // match: (MVNshiftLLreg x (MOVWconst [c]))
+       // cond: 0 <= c && c < 32
        // result: (MVNshiftLL x [c])
        for {
                x := v_0
@@ -8096,6 +8181,9 @@ func rewriteValueARM_OpARMMVNshiftLLreg(v *Value) bool {
                        break
                }
                c := auxIntToInt32(v_1.AuxInt)
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMMVNshiftLL)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg(x)
@@ -8123,6 +8211,7 @@ func rewriteValueARM_OpARMMVNshiftRAreg(v *Value) bool {
        v_1 := v.Args[1]
        v_0 := v.Args[0]
        // match: (MVNshiftRAreg x (MOVWconst [c]))
+       // cond: 0 <= c && c < 32
        // result: (MVNshiftRA x [c])
        for {
                x := v_0
@@ -8130,6 +8219,9 @@ func rewriteValueARM_OpARMMVNshiftRAreg(v *Value) bool {
                        break
                }
                c := auxIntToInt32(v_1.AuxInt)
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMMVNshiftRA)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg(x)
@@ -8157,6 +8249,7 @@ func rewriteValueARM_OpARMMVNshiftRLreg(v *Value) bool {
        v_1 := v.Args[1]
        v_0 := v.Args[0]
        // match: (MVNshiftRLreg x (MOVWconst [c]))
+       // cond: 0 <= c && c < 32
        // result: (MVNshiftRL x [c])
        for {
                x := v_0
@@ -8164,6 +8257,9 @@ func rewriteValueARM_OpARMMVNshiftRLreg(v *Value) bool {
                        break
                }
                c := auxIntToInt32(v_1.AuxInt)
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMMVNshiftRL)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg(x)
@@ -8583,6 +8679,7 @@ func rewriteValueARM_OpARMORshiftLLreg(v *Value) bool {
                return true
        }
        // match: (ORshiftLLreg x y (MOVWconst [c]))
+       // cond: 0 <= c && c < 32
        // result: (ORshiftLL x y [c])
        for {
                x := v_0
@@ -8591,6 +8688,9 @@ func rewriteValueARM_OpARMORshiftLLreg(v *Value) bool {
                        break
                }
                c := auxIntToInt32(v_2.AuxInt)
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMORshiftLL)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg2(x, y)
@@ -8672,6 +8772,7 @@ func rewriteValueARM_OpARMORshiftRAreg(v *Value) bool {
                return true
        }
        // match: (ORshiftRAreg x y (MOVWconst [c]))
+       // cond: 0 <= c && c < 32
        // result: (ORshiftRA x y [c])
        for {
                x := v_0
@@ -8680,6 +8781,9 @@ func rewriteValueARM_OpARMORshiftRAreg(v *Value) bool {
                        break
                }
                c := auxIntToInt32(v_2.AuxInt)
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMORshiftRA)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg2(x, y)
@@ -8777,6 +8881,7 @@ func rewriteValueARM_OpARMORshiftRLreg(v *Value) bool {
                return true
        }
        // match: (ORshiftRLreg x y (MOVWconst [c]))
+       // cond: 0 <= c && c < 32
        // result: (ORshiftRL x y [c])
        for {
                x := v_0
@@ -8785,6 +8890,9 @@ func rewriteValueARM_OpARMORshiftRLreg(v *Value) bool {
                        break
                }
                c := auxIntToInt32(v_2.AuxInt)
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMORshiftRL)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg2(x, y)
@@ -9072,6 +9180,7 @@ func rewriteValueARM_OpARMRSBSshiftLLreg(v *Value) bool {
                return true
        }
        // match: (RSBSshiftLLreg x y (MOVWconst [c]))
+       // cond: 0 <= c && c < 32
        // result: (RSBSshiftLL x y [c])
        for {
                x := v_0
@@ -9080,6 +9189,9 @@ func rewriteValueARM_OpARMRSBSshiftLLreg(v *Value) bool {
                        break
                }
                c := auxIntToInt32(v_2.AuxInt)
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMRSBSshiftLL)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg2(x, y)
@@ -9146,6 +9258,7 @@ func rewriteValueARM_OpARMRSBSshiftRAreg(v *Value) bool {
                return true
        }
        // match: (RSBSshiftRAreg x y (MOVWconst [c]))
+       // cond: 0 <= c && c < 32
        // result: (RSBSshiftRA x y [c])
        for {
                x := v_0
@@ -9154,6 +9267,9 @@ func rewriteValueARM_OpARMRSBSshiftRAreg(v *Value) bool {
                        break
                }
                c := auxIntToInt32(v_2.AuxInt)
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMRSBSshiftRA)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg2(x, y)
@@ -9220,6 +9336,7 @@ func rewriteValueARM_OpARMRSBSshiftRLreg(v *Value) bool {
                return true
        }
        // match: (RSBSshiftRLreg x y (MOVWconst [c]))
+       // cond: 0 <= c && c < 32
        // result: (RSBSshiftRL x y [c])
        for {
                x := v_0
@@ -9228,6 +9345,9 @@ func rewriteValueARM_OpARMRSBSshiftRLreg(v *Value) bool {
                        break
                }
                c := auxIntToInt32(v_2.AuxInt)
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMRSBSshiftRL)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg2(x, y)
@@ -9367,6 +9487,7 @@ func rewriteValueARM_OpARMRSBshiftLLreg(v *Value) bool {
                return true
        }
        // match: (RSBshiftLLreg x y (MOVWconst [c]))
+       // cond: 0 <= c && c < 32
        // result: (RSBshiftLL x y [c])
        for {
                x := v_0
@@ -9375,6 +9496,9 @@ func rewriteValueARM_OpARMRSBshiftLLreg(v *Value) bool {
                        break
                }
                c := auxIntToInt32(v_2.AuxInt)
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMRSBshiftLL)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg2(x, y)
@@ -9456,6 +9580,7 @@ func rewriteValueARM_OpARMRSBshiftRAreg(v *Value) bool {
                return true
        }
        // match: (RSBshiftRAreg x y (MOVWconst [c]))
+       // cond: 0 <= c && c < 32
        // result: (RSBshiftRA x y [c])
        for {
                x := v_0
@@ -9464,6 +9589,9 @@ func rewriteValueARM_OpARMRSBshiftRAreg(v *Value) bool {
                        break
                }
                c := auxIntToInt32(v_2.AuxInt)
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMRSBshiftRA)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg2(x, y)
@@ -9545,6 +9673,7 @@ func rewriteValueARM_OpARMRSBshiftRLreg(v *Value) bool {
                return true
        }
        // match: (RSBshiftRLreg x y (MOVWconst [c]))
+       // cond: 0 <= c && c < 32
        // result: (RSBshiftRL x y [c])
        for {
                x := v_0
@@ -9553,6 +9682,9 @@ func rewriteValueARM_OpARMRSBshiftRLreg(v *Value) bool {
                        break
                }
                c := auxIntToInt32(v_2.AuxInt)
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMRSBshiftRL)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg2(x, y)
@@ -9659,6 +9791,7 @@ func rewriteValueARM_OpARMRSCshiftLLreg(v *Value) bool {
                return true
        }
        // match: (RSCshiftLLreg x y (MOVWconst [c]) flags)
+       // cond: 0 <= c && c < 32
        // result: (RSCshiftLL x y [c] flags)
        for {
                x := v_0
@@ -9668,6 +9801,9 @@ func rewriteValueARM_OpARMRSCshiftLLreg(v *Value) bool {
                }
                c := auxIntToInt32(v_2.AuxInt)
                flags := v_3
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMRSCshiftLL)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg3(x, y, flags)
@@ -9739,6 +9875,7 @@ func rewriteValueARM_OpARMRSCshiftRAreg(v *Value) bool {
                return true
        }
        // match: (RSCshiftRAreg x y (MOVWconst [c]) flags)
+       // cond: 0 <= c && c < 32
        // result: (RSCshiftRA x y [c] flags)
        for {
                x := v_0
@@ -9748,6 +9885,9 @@ func rewriteValueARM_OpARMRSCshiftRAreg(v *Value) bool {
                }
                c := auxIntToInt32(v_2.AuxInt)
                flags := v_3
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMRSCshiftRA)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg3(x, y, flags)
@@ -9819,6 +9959,7 @@ func rewriteValueARM_OpARMRSCshiftRLreg(v *Value) bool {
                return true
        }
        // match: (RSCshiftRLreg x y (MOVWconst [c]) flags)
+       // cond: 0 <= c && c < 32
        // result: (RSCshiftRL x y [c] flags)
        for {
                x := v_0
@@ -9828,6 +9969,9 @@ func rewriteValueARM_OpARMRSCshiftRLreg(v *Value) bool {
                }
                c := auxIntToInt32(v_2.AuxInt)
                flags := v_3
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMRSCshiftRL)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg3(x, y, flags)
@@ -10142,6 +10286,7 @@ func rewriteValueARM_OpARMSBCshiftLLreg(v *Value) bool {
                return true
        }
        // match: (SBCshiftLLreg x y (MOVWconst [c]) flags)
+       // cond: 0 <= c && c < 32
        // result: (SBCshiftLL x y [c] flags)
        for {
                x := v_0
@@ -10151,6 +10296,9 @@ func rewriteValueARM_OpARMSBCshiftLLreg(v *Value) bool {
                }
                c := auxIntToInt32(v_2.AuxInt)
                flags := v_3
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMSBCshiftLL)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg3(x, y, flags)
@@ -10222,6 +10370,7 @@ func rewriteValueARM_OpARMSBCshiftRAreg(v *Value) bool {
                return true
        }
        // match: (SBCshiftRAreg x y (MOVWconst [c]) flags)
+       // cond: 0 <= c && c < 32
        // result: (SBCshiftRA x y [c] flags)
        for {
                x := v_0
@@ -10231,6 +10380,9 @@ func rewriteValueARM_OpARMSBCshiftRAreg(v *Value) bool {
                }
                c := auxIntToInt32(v_2.AuxInt)
                flags := v_3
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMSBCshiftRA)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg3(x, y, flags)
@@ -10302,6 +10454,7 @@ func rewriteValueARM_OpARMSBCshiftRLreg(v *Value) bool {
                return true
        }
        // match: (SBCshiftRLreg x y (MOVWconst [c]) flags)
+       // cond: 0 <= c && c < 32
        // result: (SBCshiftRL x y [c] flags)
        for {
                x := v_0
@@ -10311,6 +10464,9 @@ func rewriteValueARM_OpARMSBCshiftRLreg(v *Value) bool {
                }
                c := auxIntToInt32(v_2.AuxInt)
                flags := v_3
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMSBCshiftRL)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg3(x, y, flags)
@@ -10322,15 +10478,19 @@ func rewriteValueARM_OpARMSLL(v *Value) bool {
        v_1 := v.Args[1]
        v_0 := v.Args[0]
        // match: (SLL x (MOVWconst [c]))
-       // result: (SLLconst x [c&31])
+       // cond: 0 <= c && c < 32
+       // result: (SLLconst x [c])
        for {
                x := v_0
                if v_1.Op != OpARMMOVWconst {
                        break
                }
                c := auxIntToInt32(v_1.AuxInt)
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMSLLconst)
-               v.AuxInt = int32ToAuxInt(c & 31)
+               v.AuxInt = int32ToAuxInt(c)
                v.AddArg(x)
                return true
        }
@@ -10356,15 +10516,19 @@ func rewriteValueARM_OpARMSRA(v *Value) bool {
        v_1 := v.Args[1]
        v_0 := v.Args[0]
        // match: (SRA x (MOVWconst [c]))
-       // result: (SRAconst x [c&31])
+       // cond: 0 <= c && c < 32
+       // result: (SRAconst x [c])
        for {
                x := v_0
                if v_1.Op != OpARMMOVWconst {
                        break
                }
                c := auxIntToInt32(v_1.AuxInt)
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMSRAconst)
-               v.AuxInt = int32ToAuxInt(c & 31)
+               v.AuxInt = int32ToAuxInt(c)
                v.AddArg(x)
                return true
        }
@@ -10448,15 +10612,19 @@ func rewriteValueARM_OpARMSRL(v *Value) bool {
        v_1 := v.Args[1]
        v_0 := v.Args[0]
        // match: (SRL x (MOVWconst [c]))
-       // result: (SRLconst x [c&31])
+       // cond: 0 <= c && c < 32
+       // result: (SRLconst x [c])
        for {
                x := v_0
                if v_1.Op != OpARMMOVWconst {
                        break
                }
                c := auxIntToInt32(v_1.AuxInt)
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMSRLconst)
-               v.AuxInt = int32ToAuxInt(c & 31)
+               v.AuxInt = int32ToAuxInt(c)
                v.AddArg(x)
                return true
        }
@@ -11034,6 +11202,7 @@ func rewriteValueARM_OpARMSUBSshiftLLreg(v *Value) bool {
                return true
        }
        // match: (SUBSshiftLLreg x y (MOVWconst [c]))
+       // cond: 0 <= c && c < 32
        // result: (SUBSshiftLL x y [c])
        for {
                x := v_0
@@ -11042,6 +11211,9 @@ func rewriteValueARM_OpARMSUBSshiftLLreg(v *Value) bool {
                        break
                }
                c := auxIntToInt32(v_2.AuxInt)
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMSUBSshiftLL)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg2(x, y)
@@ -11108,6 +11280,7 @@ func rewriteValueARM_OpARMSUBSshiftRAreg(v *Value) bool {
                return true
        }
        // match: (SUBSshiftRAreg x y (MOVWconst [c]))
+       // cond: 0 <= c && c < 32
        // result: (SUBSshiftRA x y [c])
        for {
                x := v_0
@@ -11116,6 +11289,9 @@ func rewriteValueARM_OpARMSUBSshiftRAreg(v *Value) bool {
                        break
                }
                c := auxIntToInt32(v_2.AuxInt)
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMSUBSshiftRA)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg2(x, y)
@@ -11182,6 +11358,7 @@ func rewriteValueARM_OpARMSUBSshiftRLreg(v *Value) bool {
                return true
        }
        // match: (SUBSshiftRLreg x y (MOVWconst [c]))
+       // cond: 0 <= c && c < 32
        // result: (SUBSshiftRL x y [c])
        for {
                x := v_0
@@ -11190,6 +11367,9 @@ func rewriteValueARM_OpARMSUBSshiftRLreg(v *Value) bool {
                        break
                }
                c := auxIntToInt32(v_2.AuxInt)
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMSUBSshiftRL)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg2(x, y)
@@ -11383,6 +11563,7 @@ func rewriteValueARM_OpARMSUBshiftLLreg(v *Value) bool {
                return true
        }
        // match: (SUBshiftLLreg x y (MOVWconst [c]))
+       // cond: 0 <= c && c < 32
        // result: (SUBshiftLL x y [c])
        for {
                x := v_0
@@ -11391,6 +11572,9 @@ func rewriteValueARM_OpARMSUBshiftLLreg(v *Value) bool {
                        break
                }
                c := auxIntToInt32(v_2.AuxInt)
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMSUBshiftLL)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg2(x, y)
@@ -11472,6 +11656,7 @@ func rewriteValueARM_OpARMSUBshiftRAreg(v *Value) bool {
                return true
        }
        // match: (SUBshiftRAreg x y (MOVWconst [c]))
+       // cond: 0 <= c && c < 32
        // result: (SUBshiftRA x y [c])
        for {
                x := v_0
@@ -11480,6 +11665,9 @@ func rewriteValueARM_OpARMSUBshiftRAreg(v *Value) bool {
                        break
                }
                c := auxIntToInt32(v_2.AuxInt)
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMSUBshiftRA)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg2(x, y)
@@ -11561,6 +11749,7 @@ func rewriteValueARM_OpARMSUBshiftRLreg(v *Value) bool {
                return true
        }
        // match: (SUBshiftRLreg x y (MOVWconst [c]))
+       // cond: 0 <= c && c < 32
        // result: (SUBshiftRL x y [c])
        for {
                x := v_0
@@ -11569,6 +11758,9 @@ func rewriteValueARM_OpARMSUBshiftRLreg(v *Value) bool {
                        break
                }
                c := auxIntToInt32(v_2.AuxInt)
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMSUBshiftRL)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg2(x, y)
@@ -11771,6 +11963,7 @@ func rewriteValueARM_OpARMTEQshiftLLreg(v *Value) bool {
                return true
        }
        // match: (TEQshiftLLreg x y (MOVWconst [c]))
+       // cond: 0 <= c && c < 32
        // result: (TEQshiftLL x y [c])
        for {
                x := v_0
@@ -11779,6 +11972,9 @@ func rewriteValueARM_OpARMTEQshiftLLreg(v *Value) bool {
                        break
                }
                c := auxIntToInt32(v_2.AuxInt)
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMTEQshiftLL)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg2(x, y)
@@ -11845,6 +12041,7 @@ func rewriteValueARM_OpARMTEQshiftRAreg(v *Value) bool {
                return true
        }
        // match: (TEQshiftRAreg x y (MOVWconst [c]))
+       // cond: 0 <= c && c < 32
        // result: (TEQshiftRA x y [c])
        for {
                x := v_0
@@ -11853,6 +12050,9 @@ func rewriteValueARM_OpARMTEQshiftRAreg(v *Value) bool {
                        break
                }
                c := auxIntToInt32(v_2.AuxInt)
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMTEQshiftRA)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg2(x, y)
@@ -11919,6 +12119,7 @@ func rewriteValueARM_OpARMTEQshiftRLreg(v *Value) bool {
                return true
        }
        // match: (TEQshiftRLreg x y (MOVWconst [c]))
+       // cond: 0 <= c && c < 32
        // result: (TEQshiftRL x y [c])
        for {
                x := v_0
@@ -11927,6 +12128,9 @@ func rewriteValueARM_OpARMTEQshiftRLreg(v *Value) bool {
                        break
                }
                c := auxIntToInt32(v_2.AuxInt)
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMTEQshiftRL)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg2(x, y)
@@ -12129,6 +12333,7 @@ func rewriteValueARM_OpARMTSTshiftLLreg(v *Value) bool {
                return true
        }
        // match: (TSTshiftLLreg x y (MOVWconst [c]))
+       // cond: 0 <= c && c < 32
        // result: (TSTshiftLL x y [c])
        for {
                x := v_0
@@ -12137,6 +12342,9 @@ func rewriteValueARM_OpARMTSTshiftLLreg(v *Value) bool {
                        break
                }
                c := auxIntToInt32(v_2.AuxInt)
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMTSTshiftLL)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg2(x, y)
@@ -12203,6 +12411,7 @@ func rewriteValueARM_OpARMTSTshiftRAreg(v *Value) bool {
                return true
        }
        // match: (TSTshiftRAreg x y (MOVWconst [c]))
+       // cond: 0 <= c && c < 32
        // result: (TSTshiftRA x y [c])
        for {
                x := v_0
@@ -12211,6 +12420,9 @@ func rewriteValueARM_OpARMTSTshiftRAreg(v *Value) bool {
                        break
                }
                c := auxIntToInt32(v_2.AuxInt)
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMTSTshiftRA)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg2(x, y)
@@ -12277,6 +12489,7 @@ func rewriteValueARM_OpARMTSTshiftRLreg(v *Value) bool {
                return true
        }
        // match: (TSTshiftRLreg x y (MOVWconst [c]))
+       // cond: 0 <= c && c < 32
        // result: (TSTshiftRL x y [c])
        for {
                x := v_0
@@ -12285,6 +12498,9 @@ func rewriteValueARM_OpARMTSTshiftRLreg(v *Value) bool {
                        break
                }
                c := auxIntToInt32(v_2.AuxInt)
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMTSTshiftRL)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg2(x, y)
@@ -12604,6 +12820,7 @@ func rewriteValueARM_OpARMXORshiftLLreg(v *Value) bool {
                return true
        }
        // match: (XORshiftLLreg x y (MOVWconst [c]))
+       // cond: 0 <= c && c < 32
        // result: (XORshiftLL x y [c])
        for {
                x := v_0
@@ -12612,6 +12829,9 @@ func rewriteValueARM_OpARMXORshiftLLreg(v *Value) bool {
                        break
                }
                c := auxIntToInt32(v_2.AuxInt)
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMXORshiftLL)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg2(x, y)
@@ -12693,6 +12913,7 @@ func rewriteValueARM_OpARMXORshiftRAreg(v *Value) bool {
                return true
        }
        // match: (XORshiftRAreg x y (MOVWconst [c]))
+       // cond: 0 <= c && c < 32
        // result: (XORshiftRA x y [c])
        for {
                x := v_0
@@ -12701,6 +12922,9 @@ func rewriteValueARM_OpARMXORshiftRAreg(v *Value) bool {
                        break
                }
                c := auxIntToInt32(v_2.AuxInt)
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMXORshiftRA)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg2(x, y)
@@ -12798,6 +13022,7 @@ func rewriteValueARM_OpARMXORshiftRLreg(v *Value) bool {
                return true
        }
        // match: (XORshiftRLreg x y (MOVWconst [c]))
+       // cond: 0 <= c && c < 32
        // result: (XORshiftRL x y [c])
        for {
                x := v_0
@@ -12806,6 +13031,9 @@ func rewriteValueARM_OpARMXORshiftRLreg(v *Value) bool {
                        break
                }
                c := auxIntToInt32(v_2.AuxInt)
+               if !(0 <= c && c < 32) {
+                       break
+               }
                v.reset(OpARMXORshiftRL)
                v.AuxInt = int32ToAuxInt(c)
                v.AddArg2(x, y)
diff --git a/test/fixedbugs/issue48476.go b/test/fixedbugs/issue48476.go
new file mode 100644 (file)
index 0000000..6b77f7c
--- /dev/null
@@ -0,0 +1,21 @@
+// run
+
+// Copyright 2021 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
+
+import "fmt"
+
+//go:noinline
+func f(x uint64) uint64 {
+       s := "\x04"
+       c := s[0]
+       return x << c << 4
+}
+func main() {
+       if want, got := uint64(1<<8), f(1); want != got {
+               panic(fmt.Sprintf("want %x got %x", want, got))
+       }
+}