Hi All,

When expanding logical operations with constant operands, GCC currently
splits >= 16-bit constants into 16-bit pieces during expand, every time
the constant appears. This results in repeated immediate synthesis and
later passes not being able to see that the same constant was used
multiple times.

This patch adjusts the costing so that if the constant is wider than
16-bits, operations  such as  IOR, XOR, PLUS, and  MINUS treat the
constant operand as COSTS_N_INSNS (2) instead of (1).  As a result,
the constants >= 16-bits will materialized every time into a reg.

By forcing larger constants into registers, later RTL optimizations can
see the common value and generate shorter sequences.  The final reload
pass handles splitting the constant into lis/ori as needed, but only
once, rather than repeatedly during expansion.

2025-09-23  Kishan Parmar  <[email protected]>

Bootstrapped and tested on powerpc64le-linux-gnu with no regressions.

gcc/ChangeLog:

        PR target/86106
        * config/rs6000/rs6000.cc (rs6000_rtx_costs): Adjust costs for logical
        and arithmetic rtx expressions with constant operands.
---
 gcc/config/rs6000/rs6000.cc | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index 1049c446c40..d3f31b5cf81 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -22288,13 +22288,11 @@ rs6000_rtx_costs (rtx x, machine_mode mode, int 
outer_code,
          *total = 0;
          return true;
        }
-      else if ((outer_code == PLUS
-               && reg_or_add_cint_operand (x, mode))
-              || (outer_code == MINUS
-                  && reg_or_sub_cint_operand (x, mode))
-              || ((outer_code == SET
-                   || outer_code == IOR
-                   || outer_code == XOR)
+      else if ((((outer_code == PLUS && reg_or_add_cint_operand (x, mode))
+                || (outer_code == MINUS && reg_or_sub_cint_operand (x, mode))
+                || ((outer_code == XOR || outer_code == IOR)))
+               && ((INTVAL (x) & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0))
+              || (outer_code == SET
                   && (INTVAL (x)
                       & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
        {
-- 
2.47.3

Reply via email to