]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: fix the issue of shift amount exceeding the valid range
authorXiaolin Zhao <zhaoxiaolin@loongson.cn>
Tue, 16 Sep 2025 07:27:42 +0000 (15:27 +0800)
committerabner chenc <chenguoqi@loongson.cn>
Thu, 18 Sep 2025 01:05:31 +0000 (18:05 -0700)
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>
src/cmd/compile/internal/ssa/_gen/LOONG64.rules
src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go
src/cmd/compile/internal/ssa/rewriteLOONG64.go
test/codegen/shift.go

index d0a64364d68852fa037ce6da580a69d9fb09ab60..0d2384143c483772f4ff07aef16c76fab5d6198e 100644 (file)
 (SRLVconst [rc] (MOVBUreg x)) && rc >= 8 => (MOVVconst [0])
 
 // (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
 (MULV _ (MOVVconst [0])) => (MOVVconst [0])
index 0d5e0eb76f8832ec6193eb31782f7874cc20fbe9..a3db4def569e9f9ecd4cedf98be619e0433760cc 100644 (file)
@@ -247,7 +247,7 @@ func init() {
                {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: "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: "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.
index 6a9b723c8c0d4d32a26c9eea4d222e016fa51f88..3990b2833b20298f51116140649629c9720766dc 100644 (file)
@@ -6561,15 +6561,17 @@ func rewriteValueLOONG64_OpLOONG64SLLV(v *Value) bool {
 }
 func rewriteValueLOONG64_OpLOONG64SLLVconst(v *Value) bool {
        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)
        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] {
+               if x != v_0.Args[0] || !(c < t.Size()*8-1) {
                        break
                }
                v.reset(OpLOONG64SLLVconst)
@@ -6577,6 +6579,23 @@ func rewriteValueLOONG64_OpLOONG64SLLVconst(v *Value) bool {
                v.AddArg(x)
                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]))
        // result: (MOVVconst [d<<uint64(c)])
        for {
@@ -6593,15 +6612,17 @@ func rewriteValueLOONG64_OpLOONG64SLLVconst(v *Value) bool {
 }
 func rewriteValueLOONG64_OpLOONG64SLLconst(v *Value) bool {
        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)
        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] {
+               if x != v_0.Args[0] || !(c < t.Size()*8-1) {
                        break
                }
                v.reset(OpLOONG64SLLconst)
@@ -6609,6 +6630,23 @@ func rewriteValueLOONG64_OpLOONG64SLLconst(v *Value) bool {
                v.AddArg(x)
                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
 }
 func rewriteValueLOONG64_OpLOONG64SRA(v *Value) bool {
index 738505872671dd81bc84be24f6bcf1c5783aa325..4b0885a4dddd7b06718a22968776f5fcd1c465a3 100644 (file)
@@ -148,11 +148,13 @@ func lshConst64x2Add(x int64) int64 {
 }
 
 func lshConst32x31Add(x int32) int32 {
+       // loong64:-"SLL\t","MOVV\tR0"
        // riscv64:-"SLLI","MOV\t[$]0"
        return (x + x) << 31
 }
 
 func lshConst64x63Add(x int64) int64 {
+       // loong64:-"SLLV","MOVV\tR0"
        // riscv64:-"SLLI","MOV\t[$]0"
        return (x + x) << 63
 }