http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58742
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Component|tree-optimization |middle-end Known to work| |4.1.2 Target Milestone|--- |4.7.4 Summary|pointer arithmetic |[4.7/4.8/4.9 Regression] |simplification |pointer arithmetic | |simplification Known to fail| |4.2.0 --- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> --- This case is a signed exact division followed by an unsigned multiply. We do that to avoid introducing undefined signed overflow. signed exact division and unsigned multiply still cancel out though, handling of these is in extract_muldiv (ugh). I'm not going to enhance that but pattern match this case. Testing Index: gcc/fold-const.c =================================================================== --- gcc/fold-const.c (revision 203885) +++ gcc/fold-const.c (working copy) @@ -11002,6 +11002,13 @@ fold_binary_loc (location_t loc, fold_build2_loc (loc, MULT_EXPR, type, build_int_cst (type, 2) , arg1)); + /* ((T) (X /[ex] C)) * C cancels out if the conversion is + sign-changing only. */ + if (TREE_CODE (arg1) == INTEGER_CST + && TREE_CODE (arg0) == EXACT_DIV_EXPR + && operand_equal_p (arg1, TREE_OPERAND (arg0, 1), 0)) + return fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0)); + strict_overflow_p = false; if (TREE_CODE (arg1) == INTEGER_CST && 0 != (tem = extract_muldiv (op0, arg1, code, NULL_TREE, note that this simplification worked in 4.1.2 but stopped working in 4.2.0. Likely a wrong-code fix for extract_muldiv disabled this case (the way that function works makes special casing a pattern like above impossible).