http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53922
--- Comment #3 from amker.cheng <amker.cheng at gmail dot com> 2012-07-11 10:12:24 UTC --- vrp processes PHI node " # cstore.6_9 = PHI <x(3), y(2)>" in calling sequence: vrp_visit_phi_node -> vrp_meet When gcc gives up in function vrp_meet, it executes following code to derive an anti-range against zero: give_up: /* Failed to find an efficient meet. Before giving up and setting the result to VARYING, see if we can at least derive a useful anti-range. FIXME, all this nonsense about distinguishing anti-ranges from ranges is necessary because of the odd semantics of range_includes_zero_p and friends. */ if (!symbolic_range_p (vr0) && ((vr0->type == VR_RANGE && !range_includes_zero_p (vr0)) || (vr0->type == VR_ANTI_RANGE && range_includes_zero_p (vr0))) && !symbolic_range_p (vr1) && ((vr1->type == VR_RANGE && !range_includes_zero_p (vr1)) || (vr1->type == VR_ANTI_RANGE && range_includes_zero_p (vr1)))) { set_value_range_to_nonnull (vr0, TREE_TYPE (vr0->min)); /* Since this meet operation did not result from the meeting of two equivalent names, VR0 cannot have any equivalences. */ if (vr0->equiv) bitmap_clear (vr0->equiv); } Here vr0 is for "x" in source code, while vr1 for "y" in source code, which is a weak symbol. function range_includes_zero_p check whether vr1 includes zero by calling value_inside_range. The value_inside_range works well by returning -2, because of the WEAK symbol. After that, range_includes_zero_p checks whether return value of value_inside_range equals 1. Finally in vrp_meet, condition "((vr1->type == VR_RANGE && !range_includes_zero_p (vr1))" holds, resulting in gcc asserting cstore.6_9 non-zero. Am I missing something?