aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXiaolin Zhao <zhaoxiaolin@loongson.cn>2025-08-21 16:52:02 +0800
committerGopher Robot <gobot@golang.org>2025-08-21 11:16:49 -0700
commitfa706ea50fd0b9bf36d642d3bb8eeb732caafc7f (patch)
tree90116ccf17cc900044a65d837b6c236c28608bc8
parentffc85ee1f1c865c953920f966a8401d963b102ca (diff)
downloadgo-fa706ea50fd0b9bf36d642d3bb8eeb732caafc7f.tar.xz
cmd/compile: optimize rule (x + x) << c to x << c+1 on loong64
Change-Id: I782f93510bba92ba60b298c1c1cde456c8bcec38 Reviewed-on: https://go-review.googlesource.com/c/go/+/697956 Reviewed-by: Keith Randall <khr@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Keith Randall <khr@golang.org> Auto-Submit: Keith Randall <khr@golang.org> Reviewed-by: Carlos Amedee <carlos@golang.org>
-rw-r--r--src/cmd/compile/internal/ssa/_gen/LOONG64.rules3
-rw-r--r--src/cmd/compile/internal/ssa/rewriteLOONG64.go38
-rw-r--r--test/codegen/shift.go4
3 files changed, 45 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/ssa/_gen/LOONG64.rules b/src/cmd/compile/internal/ssa/_gen/LOONG64.rules
index efeeca652c..75b5e3806b 100644
--- a/src/cmd/compile/internal/ssa/_gen/LOONG64.rules
+++ b/src/cmd/compile/internal/ssa/_gen/LOONG64.rules
@@ -749,6 +749,9 @@
(SRLVconst [rc] (MOVHUreg x)) && rc >= 16 => (MOVVconst [0])
(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)
+
// mul by constant
(MULV _ (MOVVconst [0])) => (MOVVconst [0])
(MULV x (MOVVconst [1])) => x
diff --git a/src/cmd/compile/internal/ssa/rewriteLOONG64.go b/src/cmd/compile/internal/ssa/rewriteLOONG64.go
index 6f29588f9a..df4ac818dd 100644
--- a/src/cmd/compile/internal/ssa/rewriteLOONG64.go
+++ b/src/cmd/compile/internal/ssa/rewriteLOONG64.go
@@ -468,6 +468,8 @@ func rewriteValueLOONG64(v *Value) bool {
return rewriteValueLOONG64_OpLOONG64SLLV(v)
case OpLOONG64SLLVconst:
return rewriteValueLOONG64_OpLOONG64SLLVconst(v)
+ case OpLOONG64SLLconst:
+ return rewriteValueLOONG64_OpLOONG64SLLconst(v)
case OpLOONG64SRA:
return rewriteValueLOONG64_OpLOONG64SRA(v)
case OpLOONG64SRAV:
@@ -6457,6 +6459,22 @@ func rewriteValueLOONG64_OpLOONG64SLLV(v *Value) bool {
}
func rewriteValueLOONG64_OpLOONG64SLLVconst(v *Value) bool {
v_0 := v.Args[0]
+ // match: (SLLVconst [c] (ADDV x x))
+ // result: (SLLVconst [c+1] x)
+ for {
+ c := auxIntToInt64(v.AuxInt)
+ if v_0.Op != OpLOONG64ADDV {
+ break
+ }
+ x := v_0.Args[1]
+ if x != v_0.Args[0] {
+ break
+ }
+ v.reset(OpLOONG64SLLVconst)
+ v.AuxInt = int64ToAuxInt(c + 1)
+ v.AddArg(x)
+ return true
+ }
// match: (SLLVconst [c] (MOVVconst [d]))
// result: (MOVVconst [d<<uint64(c)])
for {
@@ -6471,6 +6489,26 @@ func rewriteValueLOONG64_OpLOONG64SLLVconst(v *Value) bool {
}
return false
}
+func rewriteValueLOONG64_OpLOONG64SLLconst(v *Value) bool {
+ v_0 := v.Args[0]
+ // match: (SLLconst [c] (ADDV x x))
+ // result: (SLLconst [c+1] x)
+ for {
+ c := auxIntToInt64(v.AuxInt)
+ if v_0.Op != OpLOONG64ADDV {
+ break
+ }
+ x := v_0.Args[1]
+ if x != v_0.Args[0] {
+ break
+ }
+ v.reset(OpLOONG64SLLconst)
+ v.AuxInt = int64ToAuxInt(c + 1)
+ v.AddArg(x)
+ return true
+ }
+ return false
+}
func rewriteValueLOONG64_OpLOONG64SRA(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
diff --git a/test/codegen/shift.go b/test/codegen/shift.go
index 0e4cf1ed8d..3ab0fcfabc 100644
--- a/test/codegen/shift.go
+++ b/test/codegen/shift.go
@@ -121,21 +121,25 @@ func rshConst64x32(v int64) int64 {
func lshConst32x1Add(x int32) int32 {
// amd64:"SHLL\t[$]2"
+ // loong64:"SLL\t[$]2"
return (x + x) << 1
}
func lshConst64x1Add(x int64) int64 {
// amd64:"SHLQ\t[$]2"
+ // loong64:"SLLV\t[$]2"
return (x + x) << 1
}
func lshConst32x2Add(x int32) int32 {
// amd64:"SHLL\t[$]3"
+ // loong64:"SLL\t[$]3"
return (x + x) << 2
}
func lshConst64x2Add(x int64) int64 {
// amd64:"SHLQ\t[$]3"
+ // loong64:"SLLV\t[$]3"
return (x + x) << 2
}