Skip to content

Commit eff27e8

Browse files
committed
cmd/compile: ensure constant shift amounts are in range for arm
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 #48476 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>
1 parent 9ebe7c8 commit eff27e8

File tree

5 files changed

+318
-68
lines changed

5 files changed

+318
-68
lines changed

src/cmd/compile/internal/ssa/gen/ARM.rules

Lines changed: 57 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -498,9 +498,9 @@
498498
(XOR x (MOVWconst [c])) => (XORconst [c] x)
499499
(BIC x (MOVWconst [c])) => (BICconst [c] x)
500500

501-
(SLL x (MOVWconst [c])) => (SLLconst x [c&31]) // Note: I don't think we ever generate bad constant shifts (i.e. c>=32)
502-
(SRL x (MOVWconst [c])) => (SRLconst x [c&31])
503-
(SRA x (MOVWconst [c])) => (SRAconst x [c&31])
501+
(SLL x (MOVWconst [c])) && 0 <= c && c < 32 => (SLLconst x [c])
502+
(SRL x (MOVWconst [c])) && 0 <= c && c < 32 => (SRLconst x [c])
503+
(SRA x (MOVWconst [c])) && 0 <= c && c < 32 => (SRAconst x [c])
504504

505505
(CMP x (MOVWconst [c])) => (CMPconst [c] x)
506506
(CMP (MOVWconst [c]) x) => (InvertFlags (CMPconst [c] x))
@@ -1075,60 +1075,60 @@
10751075
(CMNshiftRL x (MOVWconst [c]) [d]) => (CMNconst x [int32(uint32(c)>>uint64(d))])
10761076
(CMNshiftRA x (MOVWconst [c]) [d]) => (CMNconst x [c>>uint64(d)])
10771077

1078-
(ADDshiftLLreg x y (MOVWconst [c])) => (ADDshiftLL x y [c])
1079-
(ADDshiftRLreg x y (MOVWconst [c])) => (ADDshiftRL x y [c])
1080-
(ADDshiftRAreg x y (MOVWconst [c])) => (ADDshiftRA x y [c])
1081-
(ADCshiftLLreg x y (MOVWconst [c]) flags) => (ADCshiftLL x y [c] flags)
1082-
(ADCshiftRLreg x y (MOVWconst [c]) flags) => (ADCshiftRL x y [c] flags)
1083-
(ADCshiftRAreg x y (MOVWconst [c]) flags) => (ADCshiftRA x y [c] flags)
1084-
(ADDSshiftLLreg x y (MOVWconst [c])) => (ADDSshiftLL x y [c])
1085-
(ADDSshiftRLreg x y (MOVWconst [c])) => (ADDSshiftRL x y [c])
1086-
(ADDSshiftRAreg x y (MOVWconst [c])) => (ADDSshiftRA x y [c])
1087-
(SUBshiftLLreg x y (MOVWconst [c])) => (SUBshiftLL x y [c])
1088-
(SUBshiftRLreg x y (MOVWconst [c])) => (SUBshiftRL x y [c])
1089-
(SUBshiftRAreg x y (MOVWconst [c])) => (SUBshiftRA x y [c])
1090-
(SBCshiftLLreg x y (MOVWconst [c]) flags) => (SBCshiftLL x y [c] flags)
1091-
(SBCshiftRLreg x y (MOVWconst [c]) flags) => (SBCshiftRL x y [c] flags)
1092-
(SBCshiftRAreg x y (MOVWconst [c]) flags) => (SBCshiftRA x y [c] flags)
1093-
(SUBSshiftLLreg x y (MOVWconst [c])) => (SUBSshiftLL x y [c])
1094-
(SUBSshiftRLreg x y (MOVWconst [c])) => (SUBSshiftRL x y [c])
1095-
(SUBSshiftRAreg x y (MOVWconst [c])) => (SUBSshiftRA x y [c])
1096-
(RSBshiftLLreg x y (MOVWconst [c])) => (RSBshiftLL x y [c])
1097-
(RSBshiftRLreg x y (MOVWconst [c])) => (RSBshiftRL x y [c])
1098-
(RSBshiftRAreg x y (MOVWconst [c])) => (RSBshiftRA x y [c])
1099-
(RSCshiftLLreg x y (MOVWconst [c]) flags) => (RSCshiftLL x y [c] flags)
1100-
(RSCshiftRLreg x y (MOVWconst [c]) flags) => (RSCshiftRL x y [c] flags)
1101-
(RSCshiftRAreg x y (MOVWconst [c]) flags) => (RSCshiftRA x y [c] flags)
1102-
(RSBSshiftLLreg x y (MOVWconst [c])) => (RSBSshiftLL x y [c])
1103-
(RSBSshiftRLreg x y (MOVWconst [c])) => (RSBSshiftRL x y [c])
1104-
(RSBSshiftRAreg x y (MOVWconst [c])) => (RSBSshiftRA x y [c])
1105-
(ANDshiftLLreg x y (MOVWconst [c])) => (ANDshiftLL x y [c])
1106-
(ANDshiftRLreg x y (MOVWconst [c])) => (ANDshiftRL x y [c])
1107-
(ANDshiftRAreg x y (MOVWconst [c])) => (ANDshiftRA x y [c])
1108-
(ORshiftLLreg x y (MOVWconst [c])) => (ORshiftLL x y [c])
1109-
(ORshiftRLreg x y (MOVWconst [c])) => (ORshiftRL x y [c])
1110-
(ORshiftRAreg x y (MOVWconst [c])) => (ORshiftRA x y [c])
1111-
(XORshiftLLreg x y (MOVWconst [c])) => (XORshiftLL x y [c])
1112-
(XORshiftRLreg x y (MOVWconst [c])) => (XORshiftRL x y [c])
1113-
(XORshiftRAreg x y (MOVWconst [c])) => (XORshiftRA x y [c])
1114-
(BICshiftLLreg x y (MOVWconst [c])) => (BICshiftLL x y [c])
1115-
(BICshiftRLreg x y (MOVWconst [c])) => (BICshiftRL x y [c])
1116-
(BICshiftRAreg x y (MOVWconst [c])) => (BICshiftRA x y [c])
1117-
(MVNshiftLLreg x (MOVWconst [c])) => (MVNshiftLL x [c])
1118-
(MVNshiftRLreg x (MOVWconst [c])) => (MVNshiftRL x [c])
1119-
(MVNshiftRAreg x (MOVWconst [c])) => (MVNshiftRA x [c])
1120-
(CMPshiftLLreg x y (MOVWconst [c])) => (CMPshiftLL x y [c])
1121-
(CMPshiftRLreg x y (MOVWconst [c])) => (CMPshiftRL x y [c])
1122-
(CMPshiftRAreg x y (MOVWconst [c])) => (CMPshiftRA x y [c])
1123-
(TSTshiftLLreg x y (MOVWconst [c])) => (TSTshiftLL x y [c])
1124-
(TSTshiftRLreg x y (MOVWconst [c])) => (TSTshiftRL x y [c])
1125-
(TSTshiftRAreg x y (MOVWconst [c])) => (TSTshiftRA x y [c])
1126-
(TEQshiftLLreg x y (MOVWconst [c])) => (TEQshiftLL x y [c])
1127-
(TEQshiftRLreg x y (MOVWconst [c])) => (TEQshiftRL x y [c])
1128-
(TEQshiftRAreg x y (MOVWconst [c])) => (TEQshiftRA x y [c])
1129-
(CMNshiftLLreg x y (MOVWconst [c])) => (CMNshiftLL x y [c])
1130-
(CMNshiftRLreg x y (MOVWconst [c])) => (CMNshiftRL x y [c])
1131-
(CMNshiftRAreg x y (MOVWconst [c])) => (CMNshiftRA x y [c])
1078+
(ADDshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ADDshiftLL x y [c])
1079+
(ADDshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ADDshiftRL x y [c])
1080+
(ADDshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ADDshiftRA x y [c])
1081+
(ADCshiftLLreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (ADCshiftLL x y [c] flags)
1082+
(ADCshiftRLreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (ADCshiftRL x y [c] flags)
1083+
(ADCshiftRAreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (ADCshiftRA x y [c] flags)
1084+
(ADDSshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ADDSshiftLL x y [c])
1085+
(ADDSshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ADDSshiftRL x y [c])
1086+
(ADDSshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ADDSshiftRA x y [c])
1087+
(SUBshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (SUBshiftLL x y [c])
1088+
(SUBshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (SUBshiftRL x y [c])
1089+
(SUBshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (SUBshiftRA x y [c])
1090+
(SBCshiftLLreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (SBCshiftLL x y [c] flags)
1091+
(SBCshiftRLreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (SBCshiftRL x y [c] flags)
1092+
(SBCshiftRAreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (SBCshiftRA x y [c] flags)
1093+
(SUBSshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (SUBSshiftLL x y [c])
1094+
(SUBSshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (SUBSshiftRL x y [c])
1095+
(SUBSshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (SUBSshiftRA x y [c])
1096+
(RSBshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (RSBshiftLL x y [c])
1097+
(RSBshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (RSBshiftRL x y [c])
1098+
(RSBshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (RSBshiftRA x y [c])
1099+
(RSCshiftLLreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (RSCshiftLL x y [c] flags)
1100+
(RSCshiftRLreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (RSCshiftRL x y [c] flags)
1101+
(RSCshiftRAreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (RSCshiftRA x y [c] flags)
1102+
(RSBSshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (RSBSshiftLL x y [c])
1103+
(RSBSshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (RSBSshiftRL x y [c])
1104+
(RSBSshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (RSBSshiftRA x y [c])
1105+
(ANDshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ANDshiftLL x y [c])
1106+
(ANDshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ANDshiftRL x y [c])
1107+
(ANDshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ANDshiftRA x y [c])
1108+
(ORshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ORshiftLL x y [c])
1109+
(ORshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ORshiftRL x y [c])
1110+
(ORshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ORshiftRA x y [c])
1111+
(XORshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (XORshiftLL x y [c])
1112+
(XORshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (XORshiftRL x y [c])
1113+
(XORshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (XORshiftRA x y [c])
1114+
(BICshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (BICshiftLL x y [c])
1115+
(BICshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (BICshiftRL x y [c])
1116+
(BICshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (BICshiftRA x y [c])
1117+
(MVNshiftLLreg x (MOVWconst [c])) && 0 <= c && c < 32 => (MVNshiftLL x [c])
1118+
(MVNshiftRLreg x (MOVWconst [c])) && 0 <= c && c < 32 => (MVNshiftRL x [c])
1119+
(MVNshiftRAreg x (MOVWconst [c])) && 0 <= c && c < 32 => (MVNshiftRA x [c])
1120+
(CMPshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (CMPshiftLL x y [c])
1121+
(CMPshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (CMPshiftRL x y [c])
1122+
(CMPshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (CMPshiftRA x y [c])
1123+
(TSTshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (TSTshiftLL x y [c])
1124+
(TSTshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (TSTshiftRL x y [c])
1125+
(TSTshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (TSTshiftRA x y [c])
1126+
(TEQshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (TEQshiftLL x y [c])
1127+
(TEQshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (TEQshiftRL x y [c])
1128+
(TEQshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (TEQshiftRA x y [c])
1129+
(CMNshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (CMNshiftLL x y [c])
1130+
(CMNshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (CMNshiftRL x y [c])
1131+
(CMNshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (CMNshiftRA x y [c])
11321132

11331133
// Generate rotates
11341134
(ADDshiftLL [c] (SRLconst x [32-c]) x) => (SRRconst [32-c] x)

src/cmd/compile/internal/ssa/gen/ARMOps.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -228,14 +228,15 @@ func init() {
228228

229229
// shifts
230230
{name: "SLL", argLength: 2, reg: gp21, asm: "SLL"}, // arg0 << arg1, shift amount is mod 256
231-
{name: "SLLconst", argLength: 1, reg: gp11, asm: "SLL", aux: "Int32"}, // arg0 << auxInt
231+
{name: "SLLconst", argLength: 1, reg: gp11, asm: "SLL", aux: "Int32"}, // arg0 << auxInt, 0 <= auxInt < 32
232232
{name: "SRL", argLength: 2, reg: gp21, asm: "SRL"}, // arg0 >> arg1, unsigned, shift amount is mod 256
233-
{name: "SRLconst", argLength: 1, reg: gp11, asm: "SRL", aux: "Int32"}, // arg0 >> auxInt, unsigned
233+
{name: "SRLconst", argLength: 1, reg: gp11, asm: "SRL", aux: "Int32"}, // arg0 >> auxInt, unsigned, 0 <= auxInt < 32
234234
{name: "SRA", argLength: 2, reg: gp21, asm: "SRA"}, // arg0 >> arg1, signed, shift amount is mod 256
235-
{name: "SRAconst", argLength: 1, reg: gp11, asm: "SRA", aux: "Int32"}, // arg0 >> auxInt, signed
235+
{name: "SRAconst", argLength: 1, reg: gp11, asm: "SRA", aux: "Int32"}, // arg0 >> auxInt, signed, 0 <= auxInt < 32
236236
{name: "SRR", argLength: 2, reg: gp21}, // arg0 right rotate by arg1 bits
237-
{name: "SRRconst", argLength: 1, reg: gp11, aux: "Int32"}, // arg0 right rotate by auxInt bits
237+
{name: "SRRconst", argLength: 1, reg: gp11, aux: "Int32"}, // arg0 right rotate by auxInt bits, 0 <= auxInt < 32
238238

239+
// auxInt for all of these satisfy 0 <= auxInt < 32
239240
{name: "ADDshiftLL", argLength: 2, reg: gp21, asm: "ADD", aux: "Int32"}, // arg0 + arg1<<auxInt
240241
{name: "ADDshiftRL", argLength: 2, reg: gp21, asm: "ADD", aux: "Int32"}, // arg0 + arg1>>auxInt, unsigned shift
241242
{name: "ADDshiftRA", argLength: 2, reg: gp21, asm: "ADD", aux: "Int32"}, // arg0 + arg1>>auxInt, signed shift

src/cmd/compile/internal/ssa/gen/genericOps.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ var genericOps = []opData{
106106

107107
// For shifts, AxB means the shifted value has A bits and the shift amount has B bits.
108108
// Shift amounts are considered unsigned.
109-
// If arg1 is known to be less than the number of bits in arg0,
109+
// If arg1 is known to be nonnegative and less than the number of bits in arg0,
110110
// then auxInt may be set to 1.
111111
// This enables better code generation on some platforms.
112112
{name: "Lsh8x8", argLength: 2, aux: "Bool"}, // arg0 << arg1

0 commit comments

Comments
 (0)