[Bug tree-optimization/113630] [11/12/13/14 Regression] -fno-strict-aliasing introduces out-of-bounds memory access

2024-01-31 Thread cvs-commit at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113630

--- Comment #6 from GCC Commits  ---
The master branch has been updated by Richard Biener :

https://gcc.gnu.org/g:724b64304ff5c8ac08a913509afd6fde38d7b767

commit r14-8653-g724b64304ff5c8ac08a913509afd6fde38d7b767
Author: Richard Biener 
Date:   Wed Jan 31 11:28:50 2024 +0100

tree-optimization/113630 - invalid code hoisting

The following avoids code hoisting (but also PRE insertion) of
expressions that got value-numbered to another one that are not
a valid replacement (but still compute the same value).  This time
because the access path ends in a structure with different size,
meaning we consider a related access as not trapping because of the
size of the base of the access.

PR tree-optimization/113630
* tree-ssa-pre.cc (compute_avail): Avoid registering a
reference with a representation with not matching base
access size.

* gcc.dg/torture/pr113630.c: New testcase.

[Bug tree-optimization/113630] [11/12/13/14 Regression] -fno-strict-aliasing introduces out-of-bounds memory access

2024-01-29 Thread rguenth at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113630

Richard Biener  changed:

   What|Removed |Added

 Status|NEW |ASSIGNED
   Assignee|unassigned at gcc dot gnu.org  |rguenth at gcc dot 
gnu.org

--- Comment #5 from Richard Biener  ---
(In reply to Andrew Pinski from comment #2)
> Confirmed.
> 
> I really think what PRE does is correct here since we have an aliasing set
> of 0 for both. Now what is incorrect is hoist_adjacent_loads which cannot do
> either of any of the aliasing sets are 0 ...
> 
> 
> 
> I think even the function below is valid for non-strict aliasing:
> ```
> int __attribute__((noipa,noinline))
> f(struct S *p, int c, int d)
> {
>   int r;
>   if (c)
> {
> r = ((struct M*)p)->a;
> }
>   else
> r = ((struct M*)p)->b;
>   return r;
> }
> ```
> 
> That is hoist_adjacent_loads is broken for non-strict-aliasing in general
> and has been since 4.8.0 when it was added (r0-117275-g372a6eb8d991eb).

It looks it relies on

  /* The zeroth operand of the two component references must be
 identical.  It is not sufficient to compare get_base_address of
 the two references, because this could allow for different
 elements of the same array in the two trees.  It is not safe to
 assume that the existence of one array element implies the
 existence of a different one.  */
  if (!operand_equal_p (TREE_OPERAND (ref1, 0), TREE_OPERAND (ref2, 0), 0))
continue;

for the correctness test.  Note the MEM accesses are of size sizeof (struct M).

With -fno-strict-aliasing we're not wiping that detail so I think it _is_
a bug in PRE that it merges the two accesses.

I'll have a more detailed look.

[Bug tree-optimization/113630] [11/12/13/14 Regression] -fno-strict-aliasing introduces out-of-bounds memory access

2024-01-29 Thread rguenth at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113630

--- Comment #4 from Richard Biener  ---
(In reply to Andrew Pinski from comment #3)
> Note LLVM produces decent code here by only using one load:
> ```
> xor eax, eax
> testesi, esi
> seteal
> mov eax, dword ptr [rdi + 4*rax]
> ```
> 
> Maybe GCC could do the same ...

IIRC there's duplicate bugs about this - phiprop does kind-of the reverse.
The sink pass can now sink two exactly same stores but doesn't try sinking
a "compatible" store by introducing a PHI for the address.

  /* ??? We could handle differing SSA uses in the LHS by inserting
 PHIs for them.  */
  else if (! operand_equal_p (gimple_assign_lhs (first_store),
  gimple_assign_lhs (def), 0)
   || (gimple_clobber_p (first_store)
   != gimple_clobber_p (def)))

[Bug tree-optimization/113630] [11/12/13/14 Regression] -fno-strict-aliasing introduces out-of-bounds memory access

2024-01-27 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113630

--- Comment #3 from Andrew Pinski  ---
Note LLVM produces decent code here by only using one load:
```
xor eax, eax
testesi, esi
seteal
mov eax, dword ptr [rdi + 4*rax]
```

Maybe GCC could do the same ...

[Bug tree-optimization/113630] [11/12/13/14 Regression] -fno-strict-aliasing introduces out-of-bounds memory access

2024-01-27 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113630

Andrew Pinski  changed:

   What|Removed |Added

 Status|UNCONFIRMED |NEW
   Last reconfirmed||2024-01-27
 Ever confirmed|0   |1
  Known to work|5.1.0, 6.1.0, 6.4.0 |

--- Comment #2 from Andrew Pinski  ---
Confirmed.

I really think what PRE does is correct here since we have an aliasing set of 0
for both. Now what is incorrect is hoist_adjacent_loads which cannot do either
of any of the aliasing sets are 0 ...



I think even the function below is valid for non-strict aliasing:
```
int __attribute__((noipa,noinline))
f(struct S *p, int c, int d)
{
  int r;
  if (c)
{
r = ((struct M*)p)->a;
}
  else
r = ((struct M*)p)->b;
  return r;
}
```

That is hoist_adjacent_loads is broken for non-strict-aliasing in general and
has been since 4.8.0 when it was added (r0-117275-g372a6eb8d991eb).

[Bug tree-optimization/113630] [11/12/13/14 Regression] -fno-strict-aliasing introduces out-of-bounds memory access

2024-01-27 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113630

Andrew Pinski  changed:

   What|Removed |Added

   Target Milestone|--- |11.5
   See Also||https://gcc.gnu.org/bugzill
   ||a/show_bug.cgi?id=110799
  Known to fail||10.1.0, 14.0, 7.1.0
  Known to work||5.1.0, 6.1.0, 6.4.0
   Keywords||needs-bisection, wrong-code
Summary|-fno-strict-aliasing|[11/12/13/14 Regression]
   |introduces out-of-bounds|-fno-strict-aliasing
   |memory access   |introduces out-of-bounds
   ||memory access