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

--- Comment #4 from manolis.tsamis at vrull dot eu ---
(In reply to Richard Biener from comment #3)
> It's probably a mismatch of GENERIC/GIMPLE folding.  In this case it's
> pointer_int_sum prematurely distributing the multiplication:
> 
> /* Return a tree for the sum or difference (RESULTCODE says which)
>    of pointer PTROP and integer INTOP.  */
> 
> tree  
> pointer_int_sum (location_t loc, enum tree_code resultcode,
>                  tree ptrop, tree intop, bool complain)
> {     
> ...
>   /* If what we are about to multiply by the size of the elements
>      contains a constant term, apply distributive law
>      and multiply that constant term separately.
>      This helps produce common subexpressions.  */
> 
> but this kind of stuff shouldn't be done by the frontends these days.
> 
> Gating this fixes the issue.  I think this piece of code should be axed
> (after careful evaluation of its effect)

I have been testing this change and by looking at some tests that it causes to
fail, there is a regression on testcases like this (taken from
copy-headers-5.c, there are some similar fails):

int is_sorted(int *a, int n)
{
  for (int i = 0; i < n - 1; i++)
    if (a[i] > a[i + 1])
      return 0;
  return 1;
}

The gimple code for gcc currently is (taken from dump-tree-ch2):
  _1 = (long unsigned int) i_18;
  _2 = _1 * 4;
  _3 = a_13(D) + _2;
  _4 = *_3;
  _5 = _1 + 1;
  _6 = _5 * 4;
  _7 = a_13(D) + _6;
  _8 = *_7;

While with this change the result is:
  _1 = (long unsigned int) i_11;
  _2 = _1 * 4;
  _3 = a_14(D) + _2;
  _4 = *_3;
  _5 = i_11 + 1;
  _6 = (long unsigned int) _5;
  _7 = _6 * 4;
  _8 = a_14(D) + _7;
  _9 = *_8;

As a result the generated code has two loads per loop instead of one. 

The same holds if e.g. a[i + 1] > a[i + 2] is used because the constant
addition is done before the cast to long unsigned int. I believe this is
because the logic to distribute the constant is missing as a GIMPLE pattern?
Given the original transform it should be valid to propagate the constant
addition through the cast?

Reply via email to