The following test case __ea char *strchr_ea (__ea const char *s, int c); __ea char *foo (__ea char *s) { __ea char *ret = s; int i;
for (i = 0; i < 3; i++) ret = strchr_ea (ret, s[i]); return ret; } results in an ICE when compiled with -O -mea64. The reason is that the loop optimizers use an induction variable of type "long long int" to represent s+i, instead of using the appropriate pointer type. This causes rewrite_use_address to call create_mem_ref with an affine expression none of whose subexpressions is of pointer type. Therefore, the induction variable is assigned as the "index" of a TARGET_MEM_REF, which means it gets converted to sizetype. As sizetype is smaller than the __ea pointer type in the -ea64 case, this means that value would be truncated. This is later caught by an assertion in convert_memory_address, which causes the ICE. Note that use of an integral induction variable was introduced as part of the fix to PR tree-optimization/27865: http://gcc.gnu.org/ml/gcc-patches/2006-08/msg00198.html It seems to me it would be preferable to keep using pointer variables where possible, even on platforms where sizetype is the same size as pointers, in order to properly identify address base registers where this makes a performance difference. -- Summary: Loop optimizer breaks __ea pointers with -mea64 Product: gcc Version: 4.5.0 Status: UNCONFIRMED Keywords: ice-on-valid-code Severity: normal Priority: P3 Component: tree-optimization AssignedTo: uweigand at gcc dot gnu dot org ReportedBy: uweigand at gcc dot gnu dot org GCC target triplet: spu-unknown-elf http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41857