<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - Optimization with `restrict`: is `p == q ? p : q` "based" on `p`?"
   href="https://bugs.llvm.org/show_bug.cgi?id=44373">44373</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Optimization with `restrict`: is `p == q ? p : q` "based" on `p`?
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>new-bugs
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>new bugs
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>ch3root@openwall.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>htmldeveloper@gmail.com, llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>The question: is `p == q ? p : q` "based" on `p`? The definition of "based" is
like this (C11, 6.7.3.1p3):

"In what follows, a pointer expression E is said to be based on object P if (at
some sequence point in the execution of B prior to the evaluation of E)
modifying P to point to a copy of the array object into which it formerly
pointed would change the value of E."

First, suppose that the answer is "yes". Then the following program should be
strictly conforming and should always print "2":

----------------------------------------------------------------------
#include <stdio.h>

static int f(int *restrict p, int *restrict q)
{
    *p = 1;

    int *r;
    if (p == q) {
        r = p;
    } else {
        r = q;
    }

    // is r "based" on p?

    *r = 2;

    return *p;
}

int main()
{
    int x;
    printf("%d\n", f(&x, &x));
}
----------------------------------------------------------------------
$ clang -std=c11 -Weverything test.c && ./a.out
2
$ clang -std=c11 -Weverything -O3 test.c && ./a.out
1
----------------------------------------------------------------------
clang x86-64 version: clang version 10.0.0
(<a href="https://github.com/llvm/llvm-project.git">https://github.com/llvm/llvm-project.git</a>
fccac1ec16951e9a9811abf19e2c18be147854fc)
----------------------------------------------------------------------

Ok, fair enough, `p == q ? p : q` is always equal to `q`, doesn't change when
`p` changes and, thus, is not "based" on `p`.
Then the following program (4 differences are marked) should be fine according
to the standard and should always print "2":

----------------------------------------------------------------------
#include <stdio.h>

static int f(int *restrict p, int *restrict q)
{
    *q = 1; // 1) changed p -> q

    int *r;
    if (p == q) {
        r = p;
    } else {
        r = q;
        printf("branch not taken"); // 2) added this
    }

    // is r "based" on p?

    if (p == q) // 3) added if
        *r = 2;

    return *q; // 4) changed p -> q
}

int main()
{
    int x;
    printf("%d\n", f(&x, &x));
}
----------------------------------------------------------------------
$ clang -std=c11 -Weverything test.c && ./a.out
2
$ clang -std=c11 -Weverything -O3 test.c && ./a.out
1
----------------------------------------------------------------------
clang x86-64 version: clang version 10.0.0
(<a href="https://github.com/llvm/llvm-project.git">https://github.com/llvm/llvm-project.git</a>
fccac1ec16951e9a9811abf19e2c18be147854fc)
----------------------------------------------------------------------

Either way, there is a problem...

Despite the gut instinct, equal restricted pointers are fine per se -- see,
e.g., Example 3 in C11, 6.7.3.1p10.

gcc bug -- <a href="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92963">https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92963</a>.</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>