PR middle-end/95126: Expand small const structs as immediate constants.
This patch resolves PR middle-end/95126 which is a code quality regression,
by teaching the RTL expander to emit small const structs/unions as integer
immediate constants.
The motivating example from the bugzilla PR is:
struct small{ short a,b; signed char c; };
extern int func(struct small X);
void call_func(void)
{
static struct small const s = { 1, 2, 0 };
func(s);
}
which on x86_64 is currently compiled to:
call_func:
movzwl s.0+2(%rip), %eax
movzwl s.0(%rip), %edx
movzwl s.0+4(%rip), %edi
salq $16, %rax
orq %rdx, %rax
salq $32, %rdi
orq %rax, %rdi
jmp func
but with this patch is now optimized to:
call_func:
movl $131073, %edi
jmp func
2022-06-04 Roger Sayle <roger@nextmovesoftware.com>
gcc/ChangeLog
PR middle-end/95126
* calls.cc (load_register_parameters): When loading a suitable
immediate_const_ctor_p VAR_DECL into a single word_mode register,
construct it directly in a pseudo rather than read it (by parts)
from memory.
* expr.cc (int_expr_size): Make tree argument a const_tree.
(immediate_const_ctor_p): Helper predicate. Return true for
simple constructors that may be materialized in a register.
(expand_expr_real_1) [VAR_DECL]: When expanding a constant
VAR_DECL with a suitable immediate_const_ctor_p constructor
use store_constructor to materialize it directly in a pseudo.
* expr.h (immediate_const_ctor_p): Prototype here.
* varasm.cc (initializer_constant_valid_for_bitfield_p): Change
VALUE argument from tree to const_tree.
* varasm.h (initializer_constant_valid_for_bitfield_p): Update
prototype.
gcc/testsuite/ChangeLog
PR middle-end/95126
* gcc.target/i386/pr95126-m32-1.c: New test case.
* gcc.target/i386/pr95126-m32-2.c: New test case.
* gcc.target/i386/pr95126-m32-3.c: New test case.
* gcc.target/i386/pr95126-m32-4.c: New test case.
* gcc.target/i386/pr95126-m64-1.c: New test case.
* gcc.target/i386/pr95126-m64-2.c: New test case.
* gcc.target/i386/pr95126-m64-3.c: New test case.
* gcc.target/i386/pr95126-m64-4.c: New test case.
13 files changed: