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