https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81082
--- Comment #7 from Richard Biener <rguenth at gcc dot gnu.org> --- FAIL: gcc.dg/tree-ssa/loop-15.c scan-tree-dump-times optimized " \\\\+ " 0 (found 2 times) the loop is gone but we end up with unfolded _1 = (unsigned int) n_5; _10 = _1 + 4294967295; _6 = (int) _10; _13 = n_5 * _6; j_2 = n_5 + _13; which is when you decipher, just (n * (n - 1)) + n == n * n FAIL: gcc.dg/tree-ssa/pr23294.c scan-tree-dump-not optimized "\\\\* 6" FAIL: gcc.dg/tree-ssa/pr23294.c scan-tree-dump-times optimized " \\\\* 2" 3 (found 4 times) FAIL: gcc.dg/tree-ssa/pr23294.c scan-tree-dump-times optimized "a_..D. \\\\* 5" 3 (found 0 times) my patterns are incomplete and don't for example handle _1 = a_2(D) * 6; _3 = _1 - a_2(D); where it isn't important whether a_2 is zero or -1. Leaving these cases to fold-const.c might be best at this point(?). FAIL: gcc.dg/tree-ssa/pr63586-2.c scan-tree-dump-times reassoc1 "\\\\* 6" 1 (found 0 times) Similar. FAIL: gcc.dg/tree-ssa/slsr-3.c scan-tree-dump-times optimized "\\\\* 4" 1 (found 4 times) FAIL: gcc.dg/tree-ssa/slsr-3.c scan-tree-dump-times optimized "\\\\+ 12|\\\\, 12>" 1 (found 0 times) FAIL: gcc.dg/tree-ssa/slsr-3.c scan-tree-dump-times optimized "\\\\+ 4|\\\\, 4>" 2 (found 1 times) FAIL: gcc.dg/tree-ssa/slsr-3.c scan-tree-dump-times optimized "\\\\+ 8|\\\\, 8>" 1 (found 0 times) FAIL: gcc.dg/tree-ssa/slsr-4.c scan-tree-dump-times optimized "\\\\* 40" 1 (found 2 times) FAIL: gcc.dg/tree-ssa/slsr-4.c scan-tree-dump-times optimized "\\\\+ 40" 1 (found 0 times) FAIL: gfortran.dg/reassoc_4.f -O scan-tree-dump-times reassoc1 "[0-9] \\\\* " 22 (found 23 times) Leaves us with those FAILs. Thus adjusted fold-const.c hunk would be Index: gcc/fold-const.c =================================================================== --- gcc/fold-const.c (revision 256977) +++ gcc/fold-const.c (working copy) @@ -7097,7 +7097,7 @@ fold_plusminus_mult_expr (location_t loc /* Same may be zero and thus the operation 'code' may overflow. Likewise same may be minus one and thus the multiplication may overflow. Perform - the operations in an unsigned type. */ + the sum operation in an unsigned type. */ tree utype = unsigned_type_for (type); tree tem = fold_build2_loc (loc, code, utype, fold_convert_loc (loc, utype, alt0), @@ -7110,9 +7110,9 @@ fold_plusminus_mult_expr (location_t loc return fold_build2_loc (loc, MULT_EXPR, type, fold_convert (type, tem), same); - return fold_convert_loc (loc, type, - fold_build2_loc (loc, MULT_EXPR, utype, tem, - fold_convert_loc (loc, utype, same))); + /* Do not resort to unsigned multiplication because + we lose the no-overflow property of the expression. */ + return NULL_TREE; } /* Subroutine of native_encode_expr. Encode the INTEGER_CST