When using gimple_has_side_effects on a GIMPLE_LABEL with a LABEL_DECL with DECL_FORCED_LABEL set we ICE. That is because gimple_has_side_effects uses TREE_SIDE_EFFECTS on the LABEL_DECL which isn't valid. Fixed by (finally) cleaning up this predicate, removing all code that can only be executed if we eventually ICE and has no other side-effects.
Bootstrapped on x86_64-unknown-linux-gnu, testing in progress. Richard. 2011-11-10 Richard Guenther <rguent...@suse.de> PR middle-end/51071 * gimple.c (gimple_has_side_effects): Remove checking code that doesn't belong here. * gcc.dg/torture/pr51071.c: New testcase. Index: gcc/gimple.c =================================================================== *** gcc/gimple.c (revision 181206) --- gcc/gimple.c (working copy) *************** gimple_set_modified (gimple s, bool modi *** 2457,2464 **** bool gimple_has_side_effects (const_gimple s) { - unsigned i; - if (is_gimple_debug (s)) return false; --- 2457,2462 ---- *************** gimple_has_side_effects (const_gimple s) *** 2474,2520 **** if (is_gimple_call (s)) { ! unsigned nargs = gimple_call_num_args (s); ! tree fn; ! if (!(gimple_call_flags (s) & (ECF_CONST | ECF_PURE))) ! return true; ! else if (gimple_call_flags (s) & ECF_LOOPING_CONST_OR_PURE) ! /* An infinite loop is considered a side effect. */ return true; - if (gimple_call_lhs (s) - && TREE_SIDE_EFFECTS (gimple_call_lhs (s))) - { - gcc_checking_assert (gimple_has_volatile_ops (s)); - return true; - } - - fn = gimple_call_fn (s); - if (fn && TREE_SIDE_EFFECTS (fn)) - return true; - - for (i = 0; i < nargs; i++) - if (TREE_SIDE_EFFECTS (gimple_call_arg (s, i))) - { - gcc_checking_assert (gimple_has_volatile_ops (s)); - return true; - } - return false; } - else - { - for (i = 0; i < gimple_num_ops (s); i++) - { - tree op = gimple_op (s, i); - if (op && TREE_SIDE_EFFECTS (op)) - { - gcc_checking_assert (gimple_has_volatile_ops (s)); - return true; - } - } - } return false; } --- 2472,2486 ---- if (is_gimple_call (s)) { ! int flags = gimple_call_flags (s); ! /* An infinite loop is considered a side effect. */ ! if (!(flags & (ECF_CONST | ECF_PURE)) ! || (flags & ECF_LOOPING_CONST_OR_PURE)) return true; return false; } return false; } Index: gcc/testsuite/gcc.dg/torture/pr51071.c =================================================================== *** gcc/testsuite/gcc.dg/torture/pr51071.c (revision 0) --- gcc/testsuite/gcc.dg/torture/pr51071.c (revision 0) *************** *** 0 **** --- 1,33 ---- + /* { dg-do compile } */ + + void foo (void); + void bar (void *); + extern int t; + + static void kmalloc_large (int size, int flags) + { + (void) size; + (void) flags; + foo (); + bar (({__here:&&__here;})); + } + + static void kmalloc (int size, int flags) + { + if (size) + { + if ((unsigned long) size > 0x1000) + kmalloc_large (size, flags); + + if (flags) + bar (({__here:&&__here;})); + } + } + + void compress_file_range (int i, int j, int k) + { + int nr_pages = ({j < k;}); + + if (i || t) + kmalloc (0x1000UL * nr_pages, 0x40UL); + }