https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63184

--- Comment #19 from Richard Biener <rguenth at gcc dot gnu.org> ---
Btw, we alread manage to do sth like that on RTL.

typedef __UINTPTR_TYPE__ uintptr_t;
char a[1024];
char foo (uintptr_t b, uintptr_t c, uintptr_t d, uintptr_t e, uintptr_t f)
{
  uintptr_t tem = b + c + d + e + f + 1;
  return *(a + tem);
}

with the patch changes

-  _14 = f_10(D) + 1;
-  _15 = e_9(D) + _14;
-  _16 = d_8(D) + _15;
-  _17 = c_7(D) + _16;
-  tem_11 = b_6(D) + _17;
-  _5 = &a + tem_11;
+  _14 = e_9(D) + f_10(D);
+  _15 = d_8(D) + _14;
+  _16 = c_7(D) + _15;
+  tem_11 = b_6(D) + _16;
+  _5 = &MEM[(void *)&a + 1B] + tem_11;
   _13 = *_5;
   return _13;

but the asssembler is the same

        addq    %rsi, %rdi
        addq    %rdx, %rdi
        addq    %rcx, %rdi
        movzbl  a+1(%r8,%rdi), %eax
        ret

disabling TER makes it worse without the patch but not with:

        leaq    1(%r8,%rcx), %rax
        addq    %rax, %rdx
        addq    %rdx, %rsi
        movzbl  a(%rsi,%rdi), %eax
        ret

so I guess the incremental RTL build canonicalizes the constant outermost.

At least the patch looks like being in the correct direction for the
goal of removing TER...

Still most of the time the issue will be that ptr + a + b + c + 1 cannot
be handled because of the intermediate conversion.  That could be
mitigated by moving the constant part out of an outer conversion
(when permitted).

Reply via email to