cmd/compile: fix the issue of shift amount exceeding the valid range

Fixes #75479

Change-Id: I362d3e49090e94f91a840dd5a475978b59222a00
Reviewed-on: https://go-review.googlesource.com/c/go/+/704135
Reviewed-by: Mark Freeman <markfreeman@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Meidan Li <limeidan@loongson.cn>
Reviewed-by: abner chenc <chenguoqi@loongson.cn>
This commit is contained in:
Xiaolin Zhao 2025-09-16 15:27:42 +08:00 committed by abner chenc
parent 77aac7bb75
commit 78ef487a6f
4 changed files with 47 additions and 6 deletions

View file

@ -717,7 +717,8 @@
(SRLVconst [rc] (MOVBUreg x)) && rc >= 8 => (MOVVconst [0]) (SRLVconst [rc] (MOVBUreg x)) && rc >= 8 => (MOVVconst [0])
// (x + x) << c -> x << c+1 // (x + x) << c -> x << c+1
((SLLV|SLL)const [c] (ADDV x x)) => ((SLLV|SLL)const [c+1] x) ((SLLV|SLL)const <t> [c] (ADDV x x)) && c < t.Size() * 8 - 1 => ((SLLV|SLL)const [c+1] x)
((SLLV|SLL)const <t> [c] (ADDV x x)) && c >= t.Size() * 8 - 1 => (MOVVconst [0])
// mul by constant // mul by constant
(MULV _ (MOVVconst [0])) => (MOVVconst [0]) (MULV _ (MOVVconst [0])) => (MOVVconst [0])

View file

@ -247,7 +247,7 @@ func init() {
{name: "SLL", argLength: 2, reg: gp21, asm: "SLL"}, // arg0 << arg1, shift amount is mod 32 {name: "SLL", argLength: 2, reg: gp21, asm: "SLL"}, // arg0 << arg1, shift amount is mod 32
{name: "SLLV", argLength: 2, reg: gp21, asm: "SLLV"}, // arg0 << arg1, shift amount is mod 64 {name: "SLLV", argLength: 2, reg: gp21, asm: "SLLV"}, // arg0 << arg1, shift amount is mod 64
{name: "SLLconst", argLength: 1, reg: gp11, asm: "SLL", aux: "Int64"}, // arg0 << auxInt, auxInt should be in the range 0 to 31. {name: "SLLconst", argLength: 1, reg: gp11, asm: "SLL", aux: "Int64"}, // arg0 << auxInt, auxInt should be in the range 0 to 31.
{name: "SLLVconst", argLength: 1, reg: gp11, asm: "SLLV", aux: "Int64"}, // arg0 << auxInt {name: "SLLVconst", argLength: 1, reg: gp11, asm: "SLLV", aux: "Int64"}, // arg0 << auxInt, auxInt should be in the range 0 to 63.
{name: "SRL", argLength: 2, reg: gp21, asm: "SRL"}, // arg0 >> arg1, shift amount is mod 32 {name: "SRL", argLength: 2, reg: gp21, asm: "SRL"}, // arg0 >> arg1, shift amount is mod 32
{name: "SRLV", argLength: 2, reg: gp21, asm: "SRLV"}, // arg0 >> arg1, unsigned, shift amount is mod 64 {name: "SRLV", argLength: 2, reg: gp21, asm: "SRLV"}, // arg0 >> arg1, unsigned, shift amount is mod 64
{name: "SRLconst", argLength: 1, reg: gp11, asm: "SRL", aux: "Int64"}, // arg0 >> auxInt, auxInt should be in the range 0 to 31. {name: "SRLconst", argLength: 1, reg: gp11, asm: "SRL", aux: "Int64"}, // arg0 >> auxInt, auxInt should be in the range 0 to 31.

View file

@ -6561,15 +6561,17 @@ func rewriteValueLOONG64_OpLOONG64SLLV(v *Value) bool {
} }
func rewriteValueLOONG64_OpLOONG64SLLVconst(v *Value) bool { func rewriteValueLOONG64_OpLOONG64SLLVconst(v *Value) bool {
v_0 := v.Args[0] v_0 := v.Args[0]
// match: (SLLVconst [c] (ADDV x x)) // match: (SLLVconst <t> [c] (ADDV x x))
// cond: c < t.Size() * 8 - 1
// result: (SLLVconst [c+1] x) // result: (SLLVconst [c+1] x)
for { for {
t := v.Type
c := auxIntToInt64(v.AuxInt) c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpLOONG64ADDV { if v_0.Op != OpLOONG64ADDV {
break break
} }
x := v_0.Args[1] x := v_0.Args[1]
if x != v_0.Args[0] { if x != v_0.Args[0] || !(c < t.Size()*8-1) {
break break
} }
v.reset(OpLOONG64SLLVconst) v.reset(OpLOONG64SLLVconst)
@ -6577,6 +6579,23 @@ func rewriteValueLOONG64_OpLOONG64SLLVconst(v *Value) bool {
v.AddArg(x) v.AddArg(x)
return true return true
} }
// match: (SLLVconst <t> [c] (ADDV x x))
// cond: c >= t.Size() * 8 - 1
// result: (MOVVconst [0])
for {
t := v.Type
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpLOONG64ADDV {
break
}
x := v_0.Args[1]
if x != v_0.Args[0] || !(c >= t.Size()*8-1) {
break
}
v.reset(OpLOONG64MOVVconst)
v.AuxInt = int64ToAuxInt(0)
return true
}
// match: (SLLVconst [c] (MOVVconst [d])) // match: (SLLVconst [c] (MOVVconst [d]))
// result: (MOVVconst [d<<uint64(c)]) // result: (MOVVconst [d<<uint64(c)])
for { for {
@ -6593,15 +6612,17 @@ func rewriteValueLOONG64_OpLOONG64SLLVconst(v *Value) bool {
} }
func rewriteValueLOONG64_OpLOONG64SLLconst(v *Value) bool { func rewriteValueLOONG64_OpLOONG64SLLconst(v *Value) bool {
v_0 := v.Args[0] v_0 := v.Args[0]
// match: (SLLconst [c] (ADDV x x)) // match: (SLLconst <t> [c] (ADDV x x))
// cond: c < t.Size() * 8 - 1
// result: (SLLconst [c+1] x) // result: (SLLconst [c+1] x)
for { for {
t := v.Type
c := auxIntToInt64(v.AuxInt) c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpLOONG64ADDV { if v_0.Op != OpLOONG64ADDV {
break break
} }
x := v_0.Args[1] x := v_0.Args[1]
if x != v_0.Args[0] { if x != v_0.Args[0] || !(c < t.Size()*8-1) {
break break
} }
v.reset(OpLOONG64SLLconst) v.reset(OpLOONG64SLLconst)
@ -6609,6 +6630,23 @@ func rewriteValueLOONG64_OpLOONG64SLLconst(v *Value) bool {
v.AddArg(x) v.AddArg(x)
return true return true
} }
// match: (SLLconst <t> [c] (ADDV x x))
// cond: c >= t.Size() * 8 - 1
// result: (MOVVconst [0])
for {
t := v.Type
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpLOONG64ADDV {
break
}
x := v_0.Args[1]
if x != v_0.Args[0] || !(c >= t.Size()*8-1) {
break
}
v.reset(OpLOONG64MOVVconst)
v.AuxInt = int64ToAuxInt(0)
return true
}
return false return false
} }
func rewriteValueLOONG64_OpLOONG64SRA(v *Value) bool { func rewriteValueLOONG64_OpLOONG64SRA(v *Value) bool {

View file

@ -148,11 +148,13 @@ func lshConst64x2Add(x int64) int64 {
} }
func lshConst32x31Add(x int32) int32 { func lshConst32x31Add(x int32) int32 {
// loong64:-"SLL\t","MOVV\tR0"
// riscv64:-"SLLI","MOV\t[$]0" // riscv64:-"SLLI","MOV\t[$]0"
return (x + x) << 31 return (x + x) << 31
} }
func lshConst64x63Add(x int64) int64 { func lshConst64x63Add(x int64) int64 {
// loong64:-"SLLV","MOVV\tR0"
// riscv64:-"SLLI","MOV\t[$]0" // riscv64:-"SLLI","MOV\t[$]0"
return (x + x) << 63 return (x + x) << 63
} }