Hi, this is C version static int (*p) (int a) = (int (*)(int))__builtin_unreachable; main() { return p(1); }
Here we get in CCP: Folding statement: return _4; Not folded Folding statement: _4 = p.0_2 (1); Folded into: _4 = __builtin_unreachable (1); Removing dead stmt p.0_2 = __builtin_unreachable; Removing basic block 3 <bb 3>: return _4; main () { <bb 2>: __builtin_unreachable (1); } So fold seems to do the same, but tree-ssa-propagate promptly fixes it up /* No point propagating into a stmt whose result is not used, but instead we might be able to remove a trivially dead stmt. Don't do this when called from VRP, since the SSA_NAME which is going to be released could be still referenced in VRP ranges. */ if (do_dce && gimple_get_lhs (stmt) && TREE_CODE (gimple_get_lhs (stmt)) == SSA_NAME && has_zero_uses (gimple_get_lhs (stmt)) && !stmt_could_throw_p (stmt) && !gimple_has_side_effects (stmt)) { gimple_stmt_iterator i2; if (dump_file && dump_flags & TDF_DETAILS) { fprintf (dump_file, "Removing dead stmt "); print_gimple_stmt (dump_file, stmt, 0, 0); fprintf (dump_file, "\n"); } so we do not trigger same ICE, but I think it is more luck than design? Honza