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

Jiangning Liu <liujiangning at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |liujiangning at gcc dot
                   |                            |gnu.org

--- Comment #4 from Jiangning Liu <liujiangning at gcc dot gnu.org> 2012-03-19 
04:10:36 UTC ---
Hi,

  /* In general,
     (TYPE) (BASE + STEP * i) = (TYPE) BASE + (TYPE -- sign extend) STEP * i,
     but we must check some assumptions.

     1) If [BASE, +, STEP] wraps, the equation is not valid when precision
        of CT is smaller than the precision of TYPE.  For example, when we
    cast unsigned char [254, +, 1] to unsigned, the values on left side
    are 254, 255, 0, 1, ..., but those on the right side are
    254, 255, 256, 257, ...
     2) In case that we must also preserve the fact that signed ivs do not
        overflow, we must additionally check that the new iv does not wrap.
    For example, unsigned char [125, +, 1] casted to signed char could
    become a wrapping variable with values 125, 126, 127, -128, -127, ...,
    which would confuse optimizers that assume that this does not
    happen.  */
  must_check_src_overflow = TYPE_PRECISION (ct) < TYPE_PRECISION (type);

The code above in function convert_affine_scev set must_check_src_overflow to
true for 32-bit, while set false for 64-bit code.

This means 64-bit mode fails to unfold the address expression for array element
because of the case 1) as listed in comments above.

For the address of array element a[i], "&a + unitsize * i" has different
representation for 32-bit and 64-bit. For 32-bit, it is "(32-bit pointer) +
(32-bit integer)", while for 64-bit, it is "(64-bit pointer) + (32-bit
integer)".

If you try the case scev-5.c as below, you may find the case can pass.

/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-optimized" } */

int *a_p;
int a[1000];

f(int k)
{
        long long i;

        for (i=k; i<1000; i+=k) {
                a_p = &a[i];
                *a_p = 100;
        }
}

/* { dg-final { scan-tree-dump-times "&a" 1 "optimized" } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */

Any idea to fix this problem?

Thanks,
-Jiangning

Reply via email to