https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63862
Bug ID: 63862 Summary: C frontend converts shift-count to int while standard wants integer promotions Product: gcc Version: 5.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: rguenth at gcc dot gnu.org CC: jsm28 at gcc dot gnu.org /* Convert the non vector shift-count to an integer, regardless of size of value being shifted. */ if (TREE_CODE (TREE_TYPE (op1)) != VECTOR_TYPE && TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node) op1 = convert (integer_type_node, op1); while C99 6.5.7 says "The integer promotions are performed on each of the operands". The above pessimizes gcc.c-torture/execute/shiftopt-1.c which does void utest (unsigned int x) { if (-1 >> x != -1) link_error (); } and thus expects us to know that the shift amount is nonnegative. But with the C frontend generating -1 >> (int)x we don't know that anymore (and thus if I fix the bogus fold-const.c code which strips sign-changing conversions on x before asking tree_expr_nonnegative_p it fails to optimize).