This C code: #pragma pack(1) struct { unsigned f0; } static g_251 = {6}; void g_329_3() { func_19(g_251); } when compiled with -O2 on a arm-32 compiler natively or cross, does this: during RTL pass: expand bug819.c: In function ‘g_329_3’: bug819.c:5:18: internal compiler error: in emit_move_insn, at expr.cc:4011 5 | void g_329_3() { func_19(g_251); } | ^~~~~~~~~~~~~~ 0x67dcba emit_move_insn(rtx_def*, rtx_def*) /home/dcb/gcc/trunk.git/gcc/expr.cc:4011 0xa2940d load_register_parameters /home/dcb/gcc/trunk.git/gcc/calls.cc:2192 0xa2c59b expand_call(tree_node*, rtx_def*, int) /home/dcb/gcc/trunk.git/gcc/calls.cc:3593 0xba77d0 expand_expr_real_1(tree_node*, rtx_def*, machine_mode, expand_modifier, rtx_def**, bool) /home/dcb/gcc/trunk.git/gcc/expr.cc:11621 The bug appears sometime in the week before git hash aec868578d851576.
The bug first appears sometime after git hash de57440858591a88.
Mine. Sorry for the breakage. I've a fix that avoids the ICE on ARM, and allows GCC to generate the following code for this testcase: g_329_3: mov r0, #6 b func_19 [i.e. the same code as without the #pragma pack(1)]. This is a big improvement on GCC v12 which generates (both with and without #pragma pack(1)): g_329_3: movw r3, #:lower16:.LANCHOR0 movt r3, #:upper16:.LANCHOR0 ldr r0, [r3] b func_19 I'm bootstrapping and regression testing on x86_64 now.
Patch proposed: https://gcc.gnu.org/pipermail/gcc-patches/2022-June/596242.html
Roger makes an interesting comment about test case coverage in the C and C++ testsuite. There are about 45,000 C test cases and about 19,000 C++ test cases. This gives pretty good coverage in practice, with only occasional problems failing to be found. The much stronger test of compiling an entire Linux distribution on x86_64, which I do most weeks, generates about 340,000 object modules, so it is a far bigger and more comprehensive testcase. It would be an obvious extension to compile a Linux distribution on a different architecture. Maybe ARM or PowerPC or another primary gcc target ?
The master branch has been updated by Roger Sayle <sayle@gcc.gnu.org>: https://gcc.gnu.org/g:c00e1e3aa5ae62a991d105d309061d12f6a8764f commit r13-1004-gc00e1e3aa5ae62a991d105d309061d12f6a8764f Author: Roger Sayle <roger@nextmovesoftware.com> Date: Tue Jun 7 10:09:49 2022 +0100 PR middle-end/105853: Call store_constructor directly from calls.cc. This patch fixes both ICE regressions PR middle-end/105853 and PR target/105856 caused by my recent patch to expand small const structs as immediate constants. That patch updated code generation in three places: two in expr.cc that call store_constructor directly, and the third in calls.cc's load_register_parameters that expands its CONSTRUCTOR via expand_expr, as store_constructor is local/static to expr.cc, and the "public" API, should usually simply forward the constructor to the appropriate store_constructor function. Alas, despite the clean regression testing on multiple targets, the above ICEs show that expand_expr isn't a suitable proxy for store_constructor, and things that (I'd assumed) shouldn't affect how/whether a struct is placed in a register [such as whether the struct is considered packed/ aligned or not] actually interfere with the optimization that is being attempted. The (proposed) solution is to export store_constructor (and it's helper function int_expr_size) from expr.cc, by removing their static qualifier and prototyping both functions in expr.h, so they can be called directly from load_register_parameters in calls.cc. This cures both ICEs, but almost as importantly improves code generation over GCC 12. For PR 105853, GCC 12 generates: compose_nd_na_ipv6_src: movzx eax, WORD PTR eth_addr_zero[rip+2] movzx edx, WORD PTR eth_addr_zero[rip] movzx edi, WORD PTR eth_addr_zero[rip+4] sal rax, 16 or rax, rdx sal rdi, 32 or rdi, rax xor eax, eax jmp packet_set_nd eth_addr_zero: .zero 6 where now (with this fix) GCC 13 generates: compose_nd_na_ipv6_src: xorl %edi, %edi xorl %eax, %eax jmp packet_set_nd Likewise, for PR 105856 on ARM, we'd previously generate: g_329_3: movw r3, #:lower16:.LANCHOR0 movt r3, #:upper16:.LANCHOR0 ldr r0, [r3] b func_19 but with this optimization we now generate: g_329_3: mov r0, #6 b func_19 2022-06-07 Roger Sayle <roger@nextmovesoftware.com> gcc/ChangeLog PR middle-end/105853 PR target/105856 * calls.cc (load_register_parameters): Call store_constructor and int_expr_size directly instead of expanding via expand_expr. * expr.cc (static void store_constructor): Don't prototype here. (static HOST_WIDE_INT int_expr_size): Likewise. (store_constructor): No longer static. (int_expr_size): Likewise, no longer static. * expr.h (store_constructor): Prototype here. (int_expr_size): Prototype here. gcc/testsuite/ChangeLog PR middle-end/105853 PR target/105856 * gcc.dg/pr105853.c: New test case. * gcc.dg/pr105856.c: New test case.
Hi David. Thanks again for all your help (building Linux distributions is a helpful/vital service to the GCC community). Can you confirm that this problem is now fixed on ARM?
(In reply to Roger Sayle from comment #6) > Hi David. Thanks again for all your help (building Linux distributions is a > helpful/vital service to the GCC community). Thanks. Good to know I am doing something useful. 820 bugs in 10+ years. >Can you confirm that this problem is now fixed on ARM? I just confirmed that today's gcc compiler (git hash 2fc6e3d55f6080da) has it fixed. Much thanks for your fast work on this bug report. Found & fixed in four days.
Thanks David.