Hi! The following testcase ICEs in 4.8/4.9. The problem is that we don't fold NON_LVALUE_EXPR of INTEGER_CST into the INTEGER_CST, but it seems huge amount of fold-const.c code has the assumption that if argN = opN; ... STRIP_NOPS (argN); ... if (TREE_CODE (argN) == INTEGER_CST)
then argN == opN, so passes e.g. argN instead of opN, assuming that argN must have type already. Eric has fixed this for 5+ already by dropping the NON_LVALUE_EXPR if the argument is isn't a possible lvalue. Bootstrapped/regtested on x86_64-linux and i686-linux on both 4.9 and 4.8 branches with --enable-checking=yes,rtl, ok for those branches? Is the testcase alone ok for 5.2/trunk? A safer alternative would be just to fold NON_LVALUE_EXPR of INTEGER_CST into the INTEGER_CST. 2015-06-12 Jakub Jelinek <ja...@redhat.com> PR middle-end/63608 * gcc.c-torture/compile/pr63608.c: New test. Backported from mainline 2014-05-16 Eric Botcazou <ebotca...@adacore.com> * fold-const (fold_unary_loc) <NON_LVALUE_EXPR>: New case. <CASE_CONVERT>: Pass arg0 instead of op0 to fold_convert_const. --- gcc/fold-const.c (revision 210517) +++ gcc/fold-const.c (revision 210518) @@ -7850,6 +7850,11 @@ fold_unary_loc (location_t loc, enum tre return fold_convert_loc (loc, type, op0); return NULL_TREE; + case NON_LVALUE_EXPR: + if (!maybe_lvalue_p (op0)) + return fold_convert_loc (loc, type, op0); + return NULL_TREE; + CASE_CONVERT: case FLOAT_EXPR: case FIX_TRUNC_EXPR: @@ -8113,7 +8118,7 @@ fold_unary_loc (location_t loc, enum tre } } - tem = fold_convert_const (code, type, op0); + tem = fold_convert_const (code, type, arg0); return tem ? tem : NULL_TREE; case ADDR_SPACE_CONVERT_EXPR: --- gcc/testsuite/gcc.c-torture/compile/pr63608.c.jj 2015-06-12 10:55:16.484746890 +0200 +++ gcc/testsuite/gcc.c-torture/compile/pr63608.c 2015-06-12 10:53:58.000000000 +0200 @@ -0,0 +1,14 @@ +/* PR middle-end/63608 */ + +typedef long T; +typedef unsigned long U; +unsigned long a; + +unsigned long +foo (int b) +{ + T c = 0; + const U d = 2248593032UL; + a = (c = +d) | (~4L & ~b); + return c; +} Jakub