aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile
diff options
context:
space:
mode:
authorJayanth Krishnamurthy jayanth.krishnamurthy@ibm.com <jayanth.krishnamurthy@ibm.com>2025-10-15 04:18:52 -0500
committerArchana Ravindar <aravinda@redhat.com>2026-03-25 03:52:03 -0700
commitcbc2d06c9ba8285bb60f1055b44d4d1e742ca734 (patch)
tree10c0fe04738b9da366a49f290a5173be1fd74f59 /src/cmd/compile
parentc52d784d0834d13b53e297dbcf7ebf057ba4eb8f (diff)
downloadgo-cbc2d06c9ba8285bb60f1055b44d4d1e742ca734.tar.xz
cmd/compile: ppc64 fold (x+x)<<c into x<<(c+1)
On ppc64/ppc64le, rewrite (x + x) << c to x << (c+1) for constant shifts. This removes an ADD, shortens the dependency chain, and reduces code size. Add rules for both 64-bit (SLDconst) and 32-bit (SLWconst), and extend test/codegen/shift.go with ppc64x checks to assert a single SLD/SLW and forbid ADD. Aligns ppc64 with other architectures that already assert similar codegen in shift.go. Change-Id: Ie564afbb029a5bd48887b82b0c455ca1dddd5508 Cq-Include-Trybots: luci.golang.try:gotip-linux-ppc64_power10,gotip-linux-ppc64_power8,gotip-linux-ppc64le_power8,gotip-linux-ppc64le_power9,gotip-linux-ppc64le_power10 Reviewed-on: https://go-review.googlesource.com/c/go/+/712000 Reviewed-by: Archana Ravindar <aravinda@redhat.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com> Reviewed-by: Carlos Amedee <carlos@golang.org>
Diffstat (limited to 'src/cmd/compile')
-rw-r--r--src/cmd/compile/internal/ssa/_gen/PPC64.rules4
-rw-r--r--src/cmd/compile/internal/ssa/rewritePPC64.go34
2 files changed, 38 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/ssa/_gen/PPC64.rules b/src/cmd/compile/internal/ssa/_gen/PPC64.rules
index 3678a7e941..6d40687264 100644
--- a/src/cmd/compile/internal/ssa/_gen/PPC64.rules
+++ b/src/cmd/compile/internal/ssa/_gen/PPC64.rules
@@ -869,10 +869,14 @@
(SLDconst [c] z:(ANDconst [d] x)) && z.Uses == 1 && isPPC64ValidShiftMask(d) && c <= (64-getPPC64ShiftMaskLength(d)) => (CLRLSLDI [newPPC64ShiftAuxInt(c,64-getPPC64ShiftMaskLength(d),63,64)] x)
(SLDconst [c] z:(AND (MOVDconst [d]) x)) && z.Uses == 1 && isPPC64ValidShiftMask(d) && c<=(64-getPPC64ShiftMaskLength(d)) => (CLRLSLDI [newPPC64ShiftAuxInt(c,64-getPPC64ShiftMaskLength(d),63,64)] x)
+// (x + x) << c → x << (c+1)
+(SLDconst [c] (ADD x x)) && c < 63 => (SLDconst [c+1] x)
(SLWconst [c] z:(MOVBZreg x)) && z.Uses == 1 && c < 8 => (CLRLSLWI [newPPC64ShiftAuxInt(c,24,31,32)] x)
(SLWconst [c] z:(MOVHZreg x)) && z.Uses == 1 && c < 16 => (CLRLSLWI [newPPC64ShiftAuxInt(c,16,31,32)] x)
(SLWconst [c] z:(ANDconst [d] x)) && z.Uses == 1 && isPPC64ValidShiftMask(d) && c<=(32-getPPC64ShiftMaskLength(d)) => (CLRLSLWI [newPPC64ShiftAuxInt(c,32-getPPC64ShiftMaskLength(d),31,32)] x)
(SLWconst [c] z:(AND (MOVDconst [d]) x)) && z.Uses == 1 && isPPC64ValidShiftMask(d) && c<=(32-getPPC64ShiftMaskLength(d)) => (CLRLSLWI [newPPC64ShiftAuxInt(c,32-getPPC64ShiftMaskLength(d),31,32)] x)
+// (x + x) << c → x << (c+1)
+(SLWconst [c] (ADD x x)) && c < 31 => (SLWconst [c+1] x)
// special case for power9
(SL(W|D)const [c] z:(MOVWreg x)) && c < 32 && buildcfg.GOPPC64 >= 9 => (EXTSWSLconst [c] x)
diff --git a/src/cmd/compile/internal/ssa/rewritePPC64.go b/src/cmd/compile/internal/ssa/rewritePPC64.go
index 17a5421ff8..6a7df42546 100644
--- a/src/cmd/compile/internal/ssa/rewritePPC64.go
+++ b/src/cmd/compile/internal/ssa/rewritePPC64.go
@@ -12614,6 +12614,23 @@ func rewriteValuePPC64_OpPPC64SLDconst(v *Value) bool {
}
break
}
+ // match: (SLDconst [c] (ADD x x))
+ // cond: c < 63
+ // result: (SLDconst [c+1] x)
+ for {
+ c := auxIntToInt64(v.AuxInt)
+ if v_0.Op != OpPPC64ADD {
+ break
+ }
+ x := v_0.Args[1]
+ if x != v_0.Args[0] || !(c < 63) {
+ break
+ }
+ v.reset(OpPPC64SLDconst)
+ v.AuxInt = int64ToAuxInt(c + 1)
+ v.AddArg(x)
+ return true
+ }
// match: (SLDconst [c] z:(MOVWreg x))
// cond: c < 32 && buildcfg.GOPPC64 >= 9
// result: (EXTSWSLconst [c] x)
@@ -12750,6 +12767,23 @@ func rewriteValuePPC64_OpPPC64SLWconst(v *Value) bool {
}
break
}
+ // match: (SLWconst [c] (ADD x x))
+ // cond: c < 31
+ // result: (SLWconst [c+1] x)
+ for {
+ c := auxIntToInt64(v.AuxInt)
+ if v_0.Op != OpPPC64ADD {
+ break
+ }
+ x := v_0.Args[1]
+ if x != v_0.Args[0] || !(c < 31) {
+ break
+ }
+ v.reset(OpPPC64SLWconst)
+ v.AuxInt = int64ToAuxInt(c + 1)
+ v.AddArg(x)
+ return true
+ }
// match: (SLWconst [c] z:(MOVWreg x))
// cond: c < 32 && buildcfg.GOPPC64 >= 9
// result: (EXTSWSLconst [c] x)