The following testcase: extern int f1 (void **); extern void f2 (void *);
struct s { unsigned char field1; int field2; }; static inline struct s * get_globals (void) { struct s * r; void * rr; if (f1 (&rr)) return 0; r = rr; if (! r) { extern struct s t; r = &t; } r->field1 = 1; return r; } void atexit_common (const void *dso) { struct s *g = get_globals (); if (! g) return; if (g->field1) { g->field2 = 0; f2 (g); } else f2 (g); } when compiled with ./xgcc -B./ -O2 crt3.c -S ICEs with: crt3.c: In function 'atexit_common': crt3.c:30: error: definition in block 7 follows the use for SSA_NAME: rr_11 in statement: # rr_23 = V_MAY_DEF <rr_11>; # SFT.1_24 = V_MAY_DEF <SFT.1_22>; # SFT.2_25 = V_MAY_DEF <SFT.2_26>; f2 (g_1); It appears that the problem is that phicprop1 makes a fairly harmless modification to this: # rr_11 = V_MAY_DEF <rr_16>; # SFT.1_22 = V_MAY_DEF <SFT.1_17>; g_2->field2 = 0 but since it's modified it, it calls update_operands, which turns it into: # SFT.1_22 = V_MAY_DEF <SFT.1_17>; g_1->field2 = 0 deleting the rr_11 set. That of course leaves no rr_11 sets at all, and produces the error. Now, in this particular case I believe the change is correct, in that 'rr' really can't be modified by this instruction, but then of course you shouldn't have had an rr_11 at all. The 036t.forwprop1 dump file says # SFT.1_22 = V_MAY_DEF <SFT.1_17>; g_5->field2 = 0; then 037t.copyprop1 adds rr_11 and says # rr_11 = V_MAY_DEF <rr_16>; # SFT.1_22 = V_MAY_DEF <SFT.1_17>; g_2->field2 = 0; so it's possible that this is the original problem. -- Summary: escaping global variables cause 'definition follows use' error. Product: gcc Version: 4.2.0 Status: UNCONFIRMED Severity: major Priority: P3 Component: middle-end AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: geoffk at gcc dot gnu dot org GCC build triplet: powerpc-apple-darwin GCC host triplet: powerpc-apple-darwin GCC target triplet: powerpc-apple-darwin http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26840