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

--- Comment #5 from Richard Guenther <rguenth at gcc dot gnu.org> 2012-03-19 
09:55:15 UTC ---
This statement,

  MEM[(int *)&a][i_13] = 100;

is expected to be like,

  D.4086_21 = (void *) ivtmp.11_9;
  MEM[base: D.4086_21, offset: 0B] = 100;

after loop ivopt.

If the mem is not changed then we failed to analyze it.

(In reply to comment #4)
> 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)".

Of course.  'i' is 'int', thus 32bit on 64bit, so it is
&a + 4 * (sizetype) i

this is the usual issue that we lose overflow knowledge with the current
POINTER_PLUS_EXPR representation (forced unsigned offset, forced sizetype
precision offset).

> 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?

We cannot fix it without relaxing the POINTER_PLUS_EXPR constraints.
I was working on that, but as usual the TYPE_IS_SIZETYPE removal
has priority.

Please consider fixing/XFAILing the testcases as they still FAIL and you
are responsible for this.  You can open a new enhancement PR covering
this.

> Thanks,
> -Jiangning

Reply via email to