Created attachment 25164 [details] Preprocessed source Compiling u-boot with gcc 4.6.1 with the fix from http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50116 applied results in clocks.c: In function 'enable_basic_clocks': clocks.c:657:13: internal compiler error: in decode_addr_const, at varasm.c:2638 (this is the same error as 50116, except the ICE moved by the 6 lines that were inserted in the patch for 50116. I don't have permissions to reopen 50116.) Attaching preprocessed source.
Created attachment 25165 [details] Reduced test case Reduced test case: struct a { unsigned int a; unsigned int b; }; struct a *const p = (struct a *)0x4A004100; void bug50116(void) { unsigned int i = 0; unsigned int *const x[] = { &p->a, &p->b, 0 }; (*(volatile unsigned int *)((x[i])) = (unsigned int)((unsigned int)((*(volatile unsigned int *)(x[i]))))); }
Confirmed on x86_64-linux with -Os on 4.6 and trunk. (gdb) call debug_tree (exp) <addr_expr 0x2aaaaceb3fc0 type <pointer_type 0x2aaaaab5d150 type <integer_type 0x2aaaaab47540 unsigned int sizes-gimplified public unsigned SI size <integer_cst 0x2aaaaab35988 constant 32> unit size <integer_cst 0x2aaaaab35690 constant 4> align 32 symtab 0 alias set -1 canonical type 0x2aaaaab47540 precision 32 min <integer_cst 0x2aaaaab359b0 0> max <integer_cst 0x2aaaaab35960 4294967295> pointer_to_this <pointer_type 0x2aaaaab5d150>> sizes-gimplified public unsigned DI size <integer_cst 0x2aaaaab35a50 constant 64> unit size <integer_cst 0x2aaaaab35a78 constant 8> align 64 symtab 0 alias set -1 canonical type 0x2aaaaab5d150 pointer_to_this <pointer_type 0x2aaaace99738>> constant arg 0 <component_ref 0x2aaaaceb7040 type <integer_type 0x2aaaaab47540 unsigned int> arg 0 <indirect_ref 0x2aaaaceb3f90 type <record_type 0x2aaaace993f0 a> arg 0 <integer_cst 0x2aaaace94938 constant 1241530624> t.i:12:9> arg 1 <field_decl 0x2aaaaab42720 a type <integer_type 0x2aaaaab47540 unsigned int> unsigned SI file t.i line 2 col 18 size <integer_cst 0x2aaaaab35988 32> unit size <integer_cst 0x2aaaaab35690 4> align 32 offset_align 128 offset <integer_cst 0x2aaaaab356b8 constant 0> bit offset <integer_cst 0x2aaaaab35dc0 constant 0> context <record_type 0x2aaaace993f0 a> chain <field_decl 0x2aaaaab427b8 b>> t.i:12:9> t.i:12:7> There is an INDIRECT_REF in the expression, that shouldn't happen. It is from a CTOR that looks like (gdb) call debug_generic_expr (ctor) {&1241530624B->a, &1241530624B->b, 0B} and we have a CTOR and not individual initializations because of Erics const-pool changes I believe. &p->a is folded to &1241530624B->a even before gimplification (but &1241530624B->a is "unfolded" - it's an obfuscated constant). We ICE from #0 fancy_abort ( file=0x1252a70 "/space/rguenther/src/svn/gcc-4_6-branch/gcc/varasm.c", line=2638, function=0x1253700 "decode_addr_const") at /space/rguenther/src/svn/gcc-4_6-branch/gcc/diagnostic.c:893 #1 0x0000000000ca9016 in decode_addr_const (exp=0x2aaaaceb3fc0, value=0x7fffffff9b30) at /space/rguenther/src/svn/gcc-4_6-branch/gcc/varasm.c:2638 #2 0x0000000000ca97f0 in const_hash_1 (exp=0x2aaaaceb3fc0) at /space/rguenther/src/svn/gcc-4_6-branch/gcc/varasm.c:2734 #3 0x0000000000ca95db in const_hash_1 (exp=0x2aaaacea54e0) at /space/rguenther/src/svn/gcc-4_6-branch/gcc/varasm.c:2724 #4 0x0000000000cace7a in tree_output_constant_def (exp=0x2aaaacea54e0) at /space/rguenther/src/svn/gcc-4_6-branch/gcc/varasm.c:3302 #5 0x000000000083a5f4 in gimplify_init_constructor (expr_p=0x7fffffffb3a8, pre_p=0x7fffffffccf8, post_p=0x7fffffffa928, want_value=0 '\000', notify_temp_creation=0 '\000') at /space/rguenther/src/svn/gcc-4_6-branch/gcc/gimplify.c:3833 and fold &p->a via c_fully_fold_internal. Either the ADDR_EXPR case handling of this function or the COMPONENT_REF case should be adjusted to fold it down to a constant. Maybe there is a middle-end function somewhere to legitimize const constructor elements though that I missed (and that the gimplifcation misses).
I don't think there's any particular reason this initializer should need to be folded in a particular way by the front end; I'd think the front end's job is to produce a valid GENERIC initializer, whether or not folded, with folding to something visibly constant only required if the object initialized is of static storage duration. If you make x static then it builds OK (although it's not required to) but in C99 an aggregate initializer of automatic storage duration can have non-constant elements even if the type of the aggregate is a const-qualified type (that is, x is initialized once and constant after that). In fact you get the same ICE when x isn't marked const at all. (And in general the middle-end ought to be prepared to see aggregate initializers that become constant after constant propagation but aren't known by the front end to be constant.)
Looking into it.
> and we have a CTOR and not individual initializations because of Erics > const-pool changes I believe. No, we have the constructor with GCC 4.5 as well, my patch only makes it go through tree_output_constant_def. > &p->a is folded to &1241530624B->a even before gimplification (but > &1241530624B->a is "unfolded" - it's an obfuscated constant). > > We ICE from > > #0 fancy_abort ( > file=0x1252a70 "/space/rguenther/src/svn/gcc-4_6-branch/gcc/varasm.c", > line=2638, function=0x1253700 "decode_addr_const") > at /space/rguenther/src/svn/gcc-4_6-branch/gcc/diagnostic.c:893 > #1 0x0000000000ca9016 in decode_addr_const (exp=0x2aaaaceb3fc0, > value=0x7fffffff9b30) > at /space/rguenther/src/svn/gcc-4_6-branch/gcc/varasm.c:2638 > #2 0x0000000000ca97f0 in const_hash_1 (exp=0x2aaaaceb3fc0) > at /space/rguenther/src/svn/gcc-4_6-branch/gcc/varasm.c:2734 > #3 0x0000000000ca95db in const_hash_1 (exp=0x2aaaacea54e0) > at /space/rguenther/src/svn/gcc-4_6-branch/gcc/varasm.c:2724 > #4 0x0000000000cace7a in tree_output_constant_def (exp=0x2aaaacea54e0) > at /space/rguenther/src/svn/gcc-4_6-branch/gcc/varasm.c:3302 > #5 0x000000000083a5f4 in gimplify_init_constructor (expr_p=0x7fffffffb3a8, > pre_p=0x7fffffffccf8, post_p=0x7fffffffa928, want_value=0 '\000', > notify_temp_creation=0 '\000') > at /space/rguenther/src/svn/gcc-4_6-branch/gcc/gimplify.c:3833 > > and fold &p->a via c_fully_fold_internal. This is a known issue, namely that tree_output_constant_def rejects offsetof computations. See PR middle-end/44100 for an example with the C++ compiler. I think this should be folded in the front-end - c_fully_fold is kind of a misnomer if it can only partially fold &p->a. It's just a matter of copying the chunk of code present in build_unary_op, no big deal IMO. And this compiles fine in C++ because the folding is done: Starting program: /home/eric/build/gcc/native/gcc/cc1plus -quiet pr50266.c -quiet -mtune=generic -march=x86-64 -Os Breakpoint 1, tree_output_constant_def (exp=0x7ffff6edbdf8) at /home/eric/svn/gcc/gcc/varasm.c:3295 3295 key.value = exp; (gdb) p debug_generic_expr(exp) {1241530624B, 1241530628B, 0B}
Author: ebotcazou Date: Tue Sep 6 21:17:46 2011 New Revision: 178611 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=178611 Log: PR middle-end/50266 * c-common.c (c_fully_fold_internal) <ADDR_EXPR>: Fold offsetof-like computations. Added: trunk/gcc/testsuite/gcc.c-torture/compile/20110906-1.c Modified: trunk/gcc/c-family/ChangeLog trunk/gcc/c-family/c-common.c trunk/gcc/testsuite/ChangeLog
Author: ebotcazou Date: Tue Sep 6 21:23:53 2011 New Revision: 178613 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=178613 Log: PR middle-end/50266 * c-common.c (c_fully_fold_internal) <ADDR_EXPR>: Fold offsetof-like computations. Added: branches/gcc-4_6-branch/gcc/testsuite/gcc.c-torture/compile/20110906-1.c - copied unchanged from r178611, trunk/gcc/testsuite/gcc.c-torture/compile/20110906-1.c Modified: branches/gcc-4_6-branch/gcc/c-family/ChangeLog branches/gcc-4_6-branch/gcc/c-family/c-common.c branches/gcc-4_6-branch/gcc/testsuite/ChangeLog
This should compile again.