https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78681
--- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Yeah: --- gcc/ipa-prop.c.jj 2016-11-25 18:11:05.000000000 +0100 +++ gcc/ipa-prop.c 2016-12-05 18:48:48.853882864 +0100 @@ -5709,8 +5709,23 @@ ipcp_update_vr (struct cgraph_node *node { tree type = TREE_TYPE (ddef); unsigned prec = TYPE_PRECISION (type); + unsigned mprec = wi::get_precision (vr[i].min); + gcc_assert (mprec == wi::get_precision (vr[i].max)); if (INTEGRAL_TYPE_P (TREE_TYPE (ddef))) { + if (prec < mprec) + { + /* If there is a disagreement between callers and callee + on the argument type, e.g. when using K&R function + definitions, punt if vr[i].min or vr[i].max are outside + of type's precision. */ + wide_int m = wi::ext (vr[i].min, prec, TYPE_SIGN (type)); + if (m != vr[i].min) + continue; + m = wi::ext (vr[i].max, prec, TYPE_SIGN (type)); + if (m != vr[i].max) + continue; + } if (dump_file) { fprintf (dump_file, "Setting value range of param %u ", i); @@ -5729,6 +5744,7 @@ ipcp_update_vr (struct cgraph_node *node } else if (POINTER_TYPE_P (TREE_TYPE (ddef)) && vr[i].type == VR_ANTI_RANGE + && mprec <= prec && wi::eq_p (vr[i].min, 0) && wi::eq_p (vr[i].max, 0)) { works for me (i.e. if the callers expect higher precision and the range doesn't fit into the smaller type, punt). Not sure if one can construct a testcase where prec == mprec, but the signedness differ (either vr[i].min/vr[i].max is from signed type and type is unsigned, or vice versa). Tried: static void foo (int, unsigned int); static int foo (x, y) unsigned int x; int y; { return x + y; } void bar (int x, unsigned int y) { if (x < - __INT_MAX__ + 3 || x >= __INT_MAX__ - 19) return; if (y < 5 || y >= ~19U) return; x++; y++; foo (x, y); x++; y++; foo (x, y); } but that is rejected.