http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56363



             Bug #: 56363

           Summary: over aggressive division folding ignores sign

                    conversion

    Classification: Unclassified

           Product: gcc

           Version: 4.7.2

            Status: UNCONFIRMED

          Severity: normal

          Priority: P3

         Component: middle-end

        AssignedTo: unassig...@gcc.gnu.org

        ReportedBy: jay.kr...@cornell.edu





Our frontend is slightly unusual in that it uses FLOOR_DIV_EXPR instead of C's

more common TRUNC_DIV_EXPR. (For years it generated calls to helper functions

for div and mod, but then I noticed this builtin support.)

So it hits perhaps not well covered code?





Based on debugging this years ago (in an older version of gcc), I think gcc is

a bit overaggressive at folding constants in division.





4.7.2/gcc/fold-const.c has this code:





tree

fold_binary_loc (location_t loc,

         enum tree_code code, tree type, tree op0, tree op1)

.

.

.

  arg0 = op0;

  arg1 = op1;

.

.

.

      STRIP_NOPS (arg0);

      STRIP_NOPS (arg1);

.

.

.

      /* If arg0 is a multiple of arg1, then rewrite to the fastest div

     operation, EXACT_DIV_EXPR.



     Note that only CEIL_DIV_EXPR and FLOOR_DIV_EXPR are rewritten now.

     At one time others generated faster code, it's not clear if they do

     after the last round to changes to the DIV code in expmed.c.  */

      if ((code == CEIL_DIV_EXPR || code == FLOOR_DIV_EXPR)

      && multiple_of_p (type, arg0, arg1))

    return fold_build2_loc (loc, EXACT_DIV_EXPR, type, arg0, arg1);





I think this is wrong if strip_nops stripped some signedness or other

conversions.





I added this condition:

      && arg0 == op0 && arg1 == op1 





Given the comment, that the code is not applied to C's TRUNC_DIV_EXPR, maybe

this can/should just be removed?

Reply via email to