Optimization of offset computations

Richard Kenner kenner@vlsi1.ultra.nyu.edu
Tue Nov 30 23:59:00 GMT 1999


       We have in the source file
         unsigned long x, y = 1;
         x = ((y * 8192) - 216) / 16;
       This gets transformed to
         x = y * 512 - (216 / 16);
       which is off by one.  Distributive law doesn't apply for integer
       divisions.  

It should if one part of the operation is divisible by the divisor, like in
this case, so I'm confused.  The old code did this, so I'm even more confused.

   It also doesn't apply for modulo operations; 

Likewise.

   extract_muldiv is called while computing the type size for the array.
   We have a SAVE_EXPR that contains a postincrement (representing the
   number of elements), and extract_muldiv returns a newly made SAVE_EXPR.
   The problem is that both SAVE_EXPRs get evaluated, and I is incremented
   too often.

Ah!  I was a bit worried about that sort of thing.  Let me think about this
one some because disabling the SAVE_EXPR case removes a lot of the benefit
of the optimization.

    3. I don't have a testcase for this, but doesn't the NOP/CONVERT/NON_LVALUE
       case lack a final type conversion (the code seems to do something other
       than the comment indicates)?  I noticed this while debugging #2.

No, that's fine, though the comments may indeed be wrong.  extract_muldiv
is not guaranteed to return a result of the proper type: the caller is
supposed to do the final conversion: this simplifies the recursive cases.

    4. The handling of MIN/MAX is wrong.  There are at least two problems:
       multiplication/division by a negative value changes order of the min/max
       operands, 

That's easy to fix.

    and unsigned overflows aren't handled properly.

As you say, it seems odd this would affect just the MIN/MAX cases.
   See below for a (C++) testcase I made up (assuming 32 bit ints).

The patches below should fix these problems.

Hmm, it just occurs to me that the unsigned overflow problem could possibly
affect more than just the MIN/MAX case.  This may need more thought.

Can you explain the precise concern about overflows?



More information about the Gcc-patches mailing list