]> git.ipfire.org Git - thirdparty/gcc.git/commit - gcc/calls.cc
PR middle-end/95126: Expand small const structs as immediate constants.
authorRoger Sayle <roger@nextmovesoftware.com>
Sat, 4 Jun 2022 11:21:51 +0000 (12:21 +0100)
committerRoger Sayle <roger@nextmovesoftware.com>
Sat, 4 Jun 2022 11:21:51 +0000 (12:21 +0100)
commited6fd2aed58f2cca99f15331bf68999c0e6df370
treef45d2ecac85e6636ee9ec5ce1ecbe7b3fc771e5c
parent53718316afa45eb0d1c236fbbf2fc0959b08510f
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:
gcc/calls.cc
gcc/expr.cc
gcc/expr.h
gcc/testsuite/gcc.target/i386/pr95126-m32-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr95126-m32-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr95126-m32-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr95126-m32-4.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr95126-m64-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr95126-m64-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr95126-m64-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr95126-m64-4.c [new file with mode: 0644]
gcc/varasm.cc
gcc/varasm.h