[Bug middle-end/88490] Missed autovectorization when indices are different

2018-12-17 Thread rguenther at suse dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88490

--- Comment #6 from rguenther at suse dot de  ---
On Fri, 14 Dec 2018, joseph at codesourcery dot com wrote:

> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88490
> 
> --- Comment #5 from joseph at codesourcery dot com  dot com> ---
> On Fri, 14 Dec 2018, rguenther at suse dot de wrote:
> 
> > Note I do not think the C standard is sufficiently clear with regarding 
> > to restrict qualified pointers loaded from memory.
> 
> I think this is where "Every access that modifies X shall be considered 
> also to modify P, for the purposes of this subclause." comes in.  (See 
> what I said at .)  
> Modifying s->d[n][0] is considered to modify s->d[n], and so considered to 
> modify s->d, and so considered to modify s.  (It's still perfectly valid 
> to have n == k; what's not valid is aliasing between objects accessed via 
> s->d[0] and s->d[1], for example.)

OK, thanks for clarifying.  I think we are fine implementation-wise
and I have a hard time thinking of a way to improve here given we
have to compute sth conservatively correct.

[Bug middle-end/88490] Missed autovectorization when indices are different

2018-12-14 Thread joseph at codesourcery dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88490

--- Comment #5 from joseph at codesourcery dot com  ---
On Fri, 14 Dec 2018, rguenther at suse dot de wrote:

> Note I do not think the C standard is sufficiently clear with regarding 
> to restrict qualified pointers loaded from memory.

I think this is where "Every access that modifies X shall be considered 
also to modify P, for the purposes of this subclause." comes in.  (See 
what I said at .)  
Modifying s->d[n][0] is considered to modify s->d[n], and so considered to 
modify s->d, and so considered to modify s.  (It's still perfectly valid 
to have n == k; what's not valid is aliasing between objects accessed via 
s->d[0] and s->d[1], for example.)

[Bug middle-end/88490] Missed autovectorization when indices are different

2018-12-14 Thread rguenther at suse dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88490

--- Comment #4 from rguenther at suse dot de  ---
On Fri, 14 Dec 2018, bugzi...@poradnik-webmastera.com wrote:

> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88490
> 
> --- Comment #3 from Daniel Fruzynski  ---
> In this case s->d is pointer to pointer to double, and both pointer levels 
> have
> restrict qualifier. I wonder if you could add some tag that s->d[n] and 
> s->d[k]
> points to separate memory areas. This tag could be later used to determine 
> that
> s->d[n][0] and s->d[k][0] also do not overlap.

Not easily.  Consider the loads being hoisted before the if (k > n) check
for example.  Note I do not think the C standard is sufficiently
clear with regarding to restrict qualified pointers loaded from
memory.  Clearly s->d[n][0] and s->d[n][0] alias but they are not
based on each other.

[Bug middle-end/88490] Missed autovectorization when indices are different

2018-12-14 Thread bugzi...@poradnik-webmastera.com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88490

--- Comment #3 from Daniel Fruzynski  ---
In this case s->d is pointer to pointer to double, and both pointer levels have
restrict qualifier. I wonder if you could add some tag that s->d[n] and s->d[k]
points to separate memory areas. This tag could be later used to determine that
s->d[n][0] and s->d[k][0] also do not overlap.

[Bug middle-end/88490] Missed autovectorization when indices are different

2018-12-14 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88490

Richard Biener  changed:

   What|Removed |Added

 Status|UNCONFIRMED |NEW
   Last reconfirmed||2018-12-14
 CC||rguenth at gcc dot gnu.org
 Blocks||49774
 Ever confirmed|0   |1

--- Comment #2 from Richard Biener  ---
Confirmed.

  _33 = MEM[(double *)_28 clique 1 base 2];
  MEM[(double *)_32 clique 1 base 2] = _33;
  _35 = MEM[(double *)_28 + 8B clique 1 base 2];
  MEM[(double *)_32 + 8B clique 1 base 2] = _35;
  _49 = MEM[(double *)_28 clique 1 base 2];
  MEM[(double *)_32 clique 1 base 2] = _49;
  _51 = MEM[(double *)_28 + 8B clique 1 base 2];
  MEM[(double *)_32 + 8B clique 1 base 2] = _51;

t.c:13:24: note: can't determine dependence between MEM[(double *)_32 clique 1
base 2] and MEM[(double *)_28 + 8B clique 1 base 2]

As you can see we do not exploit that n != k when assigning restrict tags
to the indirect loaded pointers.  Nor would we do that when you load
those in an unrolled loop.  Our restrict machinery is simply not set up
for this.

I don't see how a compiler could reliably and reasonably implement this.


Referenced Bugs:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=49774
[Bug 49774] [meta-bug] restrict qualification aliasing issues

[Bug middle-end/88490] Missed autovectorization when indices are different

2018-12-13 Thread bugzi...@poradnik-webmastera.com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88490

--- Comment #1 from Daniel Fruzynski  ---
Ehh, small typo. This is correct version, also not vectorized:

[code]
struct S
{
double* __restrict__ * __restrict__ d;
};

void test(S* __restrict__ s, int n, int k)
{
if (n > k)
{
for (int i = 0; i < 2; ++i)
{
s->d[n][0] = s->d[k][0];
s->d[n][1] = s->d[k][1];
}
}
}
[/code]

[asm]
test(S*, int, int):
cmp esi, edx
jle .L3
mov rax, QWORD PTR [rdi]
movsx   rdx, edx
mov rdx, QWORD PTR [rax+rdx*8]
movsx   rsi, esi
vmovsd  xmm0, QWORD PTR [rdx]
mov rax, QWORD PTR [rax+rsi*8]
vmovsd  QWORD PTR [rax], xmm0
vmovsd  xmm0, QWORD PTR [rdx+8]
vmovsd  QWORD PTR [rax+8], xmm0
vmovsd  xmm0, QWORD PTR [rdx]
vmovsd  QWORD PTR [rax], xmm0
vmovsd  xmm0, QWORD PTR [rdx+8]
vmovsd  QWORD PTR [rax+8], xmm0
.L3:
ret
[/asm]