<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 - IndVarSimplify incorrectly replaces a pointer with another"
   href="https://bugs.llvm.org/show_bug.cgi?id=40371">40371</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>IndVarSimplify incorrectly replaces a pointer with another
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>libraries
          </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>Scalar Optimizations
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>juneyoung.lee@sf.snu.ac.kr
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Created <span class=""><a href="attachment.cgi?id=21352" name="attach_21352" title="test.ll">attachment 21352</a> <a href="attachment.cgi?id=21352&action=edit" title="test.ll">[details]</a></span>
test.ll

$ cat test.ll

; while (p != q) p++;
; return p;

define i8* @iterate_until_p_becomes_q(i8* %p, i8* %q) {
label:
  br label %while.cond

while.cond:
  %p.addr.0 = phi i8* [ %p, %label ], [ %incdec.ptr, %while.body ]
  %cmp = icmp ne i8* %p.addr.0, %q
  br i1 %cmp, label %while.body, label %while.end

while.body:
  %incdec.ptr = getelementptr inbounds i8, i8* %p.addr.0, i32 1
  br label %while.cond

while.end:
  ret i8* %p.addr.0
}


After `opt test.ll -indvars -S -o -`, the returned value %p.addr.0 is replaced
with %q:


define i8* @iterate_until_p_becomes_q(i8* %p, i8* %q) {
label:
  br label %while.cond

while.cond:                                       ; preds = %while.body, %label
  %p.addr.0 = phi i8* [ %p, %label ], [ %incdec.ptr, %while.body ]
  %cmp = icmp ne i8* %p.addr.0, %q
  br i1 %cmp, label %while.body, label %while.end

while.body:                                       ; preds = %while.cond
  %incdec.ptr = getelementptr inbounds i8, i8* %p.addr.0, i32 1
  br label %while.cond

while.end:                                        ; preds = %while.cond
  ret i8* %q
}

This is incorrect because %p and %q may have different provenances. This causes
miscompilation in this case:

char p[4]; // 0x100
char q[4]; // 0x104
char *ptr = iterate_until_p_becomes_q(&p[0], &q[0]); // ptr = &p[4]
ptr--;
*ptr = 'a'; // After the optimization, this raises UB because ptr becomes
q[-1].


Interesting thing is that if %p and %q are defined as non-i8-type (e.g. i16*),
LLVM compiles correctly, by introducing uglygep (<a href="https://godbolt.org/z/Rk1dWt">https://godbolt.org/z/Rk1dWt</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>