cmd/compile/internal/ssa: combine more shift and masking on PPC64

Investigating binaries, these patterns seem to show up frequently.

Change-Id: I987251e4070e35c25e98da321e444ccaa1526912
Reviewed-on: https://go-review.googlesource.com/c/go/+/583302
Reviewed-by: Cherry Mui <cherryyz@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Lynn Boger <laboger@linux.vnet.ibm.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
This commit is contained in:
Paul E. Murphy 2024-05-01 15:03:34 -05:00 committed by Paul Murphy
parent bbdad50c09
commit 0222a028f1
4 changed files with 261 additions and 1 deletions

View file

@ -1653,6 +1653,56 @@ func mergePPC64ClrlsldiRlwinm(sld int32, rlw int64) int64 {
return encodePPC64RotateMask(r_3, int64(mask_3), 32)
}
// Test if RLWINM feeding into an ANDconst can be merged. Return the encoded RLWINM constant,
// or 0 if they cannot be merged.
func mergePPC64AndRlwinm(mask uint32, rlw int64) int64 {
r, _, _, mask_rlw := DecodePPC64RotateMask(rlw)
mask_out := (mask_rlw & uint64(mask))
// Verify the result is still a valid bitmask of <= 32 bits.
if !isPPC64WordRotateMask(int64(mask_out)) {
return 0
}
return encodePPC64RotateMask(r, int64(mask_out), 32)
}
// Test if AND feeding into an ANDconst can be merged. Return the encoded RLWINM constant,
// or 0 if they cannot be merged.
func mergePPC64RlwinmAnd(rlw int64, mask uint32) int64 {
r, _, _, mask_rlw := DecodePPC64RotateMask(rlw)
// Rotate the input mask, combine with the rlwnm mask, and test if it is still a valid rlwinm mask.
r_mask := bits.RotateLeft32(mask, int(r))
mask_out := (mask_rlw & uint64(r_mask))
// Verify the result is still a valid bitmask of <= 32 bits.
if !isPPC64WordRotateMask(int64(mask_out)) {
return 0
}
return encodePPC64RotateMask(r, int64(mask_out), 32)
}
// Test if RLWINM feeding into SRDconst can be merged. Return the encoded RLIWNM constant,
// or 0 if they cannot be merged.
func mergePPC64SldiRlwinm(sldi, rlw int64) int64 {
r_1, mb, me, mask_1 := DecodePPC64RotateMask(rlw)
if mb > me || mb < sldi {
// Wrapping masks cannot be merged as the upper 32 bits are effectively undefined in this case.
// Likewise, if mb is less than the shift amount, it cannot be merged.
return 0
}
// combine the masks, and adjust for the final left shift.
mask_3 := mask_1 << sldi
r_3 := (r_1 + sldi) & 31 // This can wrap.
// Verify the result is still a valid bitmask of <= 32 bits.
if uint64(uint32(mask_3)) != mask_3 {
return 0
}
return encodePPC64RotateMask(r_3, int64(mask_3), 32)
}
// Compute the encoded RLWINM constant from combining (SLDconst [sld] (SRWconst [srw] x)),
// or return 0 if they cannot be combined.
func mergePPC64SldiSrw(sld, srw int64) int64 {