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

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
          Component|c                           |tree-optimization
   Last reconfirmed|                            |2023-01-09
             Status|UNCONFIRMED                 |NEW
           Keywords|                            |wrong-code
     Ever confirmed|0                           |1
             Blocks|                            |49774

--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Matthew House from comment #2)
> Isn't this example invalid per the spec? At `*r = 42;`, `&*r` is based on
> `s`. However, `*p = 13;` modifies the same object that `*r` refers to, and
> `&*p` is not based on `s`, so the behavior is undefined.
> 
> I've recently found another example which is valid under the current spec as
> well as the two new proposed definitions in N3025 and N3058. 
> 
> https://godbolt.org/z/ezvMfPd78
> 
> static int x;
> 
> __attribute__ ((noinline))
> int f(int * restrict p) {
>   *p = 1;
>   if (p == &x) {
>     *p = 2;
>   }
>   return *p;
> }
> 
> int main(void) {
>   return f(&x);
> }
> 
> At `*p = 2;`, `&*p` is based on `p` under every definition. However, both
> GCC and Clang incorrectly assume that the write to `*p` inside the `if`
> block cannot affect the return value.

While the early alias (restrict) pass figures correct base/cliques the
early VRP pass propagates the conditional equivalence and turns the IL
into

__attribute__((noinline))
int f (int * restrict p)
{
  int _6;

  <bb 2> :
  *p_3(D) = 1;
  if (p_3(D) == &x)
    goto <bb 3>; [INV]
  else
    goto <bb 4>; [INV]

  <bb 3> :
  x = 2;

  <bb 4> :
  _6 = *p_3(D);
  return _6;
}

which in turn is "invalid" as to the restrict rules.  So the core issue is
that we apply (a supposedly stricter set of) restrict rules to our internal
IL rather than the language definition to the language specific AST.  But
the propagation of conditional equivalences makes that "stricter" set of
rules not strict enough.

(Propagating) conditional equivalences is bad.

We _might_ get away with disallowing propagation to restrict qualified
uses, but that might in the end also pessimize things.  We could also
refrain from re-computing restrict info after inlining.


Referenced Bugs:

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

Reply via email to