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
