<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 - Segfault with update-load-metadata-during-inlining"
   href="https://bugs.llvm.org/show_bug.cgi?id=45590">45590</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Segfault with update-load-metadata-during-inlining
          </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>All
          </td>
        </tr>

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

        <tr>
          <th>Severity</th>
          <td>enhancement
          </td>
        </tr>

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

        <tr>
          <th>Component</th>
          <td>Transformation Utilities
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>yamauchi@google.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>This regards this commit

<a href="https://reviews.llvm.org/rG1d0f757904919d19f1cf5dcd307874bceb1e9efb">https://reviews.llvm.org/rG1d0f757904919d19f1cf5dcd307874bceb1e9efb</a>
<a href="https://reviews.llvm.org/D76792">https://reviews.llvm.org/D76792</a>

What I think is happening is an incorrect hoisting of a load above the size
check. The dereferenceable attribute gets copied from the call instruction to
the load after inlining. The load incorrectly gets hoistable above due to the
dereferenceable.

Here's a reduced test with repro steps:

$ cat D76792.cc 
#include <cstddef>

template<typename T>
struct Vec {
  T *begin;
  T *end;
  T buf[1];
  Vec() : begin(nullptr), end(nullptr) {}
  size_t size() { return end - begin; }
  T& front() { return *begin; }
};

int g = 1;

__attribute((noinline))
int* test(Vec<int*> &v) {
  if (v.size() == 1) {
    return v.front(); // <---- this load gets hoisted above the size check
  }
  return &g;
}

int main() {
  Vec<int*> vec;
  int *p = test(vec);
  *p = 33;
  return *p;
}
$ # Disable x86-cmov-converter as it hides this bug
$ clang -O3 -o D76792 -mllvm -x86-cmov-converter=false D76792.cc 
$ ./D76792
Segmentation fault
$ clang -O3 -o D76792 -mllvm -x86-cmov-converter=false -mllvm
-update-load-metadata-during-inlining=false D76792.cc
$ ./D76792 
$ # No segfault
$ clang -S -O3 -emit-llvm D76792.cc
$ cat D76792.ll
...
define dso_local i32* @_Z4testR3VecIPiE(%struct.Vec* nocapture readonly
dereferenceable(24) %v) local_unnamed_addr #0 {
entry:
  %end.i = getelementptr inbounds %struct.Vec, %struct.Vec* %v, i64 0, i32 1
  %0 = bitcast i32*** %end.i to i64*
  %1 = load i64, i64* %0, align 8, !tbaa !2
  %2 = bitcast %struct.Vec* %v to i64*
  %3 = load i64, i64* %2, align 8
  %sub.ptr.sub.i = sub i64 %1, %3
  %cmp = icmp eq i64 %sub.ptr.sub.i, 8
  %.cast = inttoptr i64 %3 to i32**
  %4 = load i32*, i32** %.cast, align 8    ; <---- this load was hoisted above
the size check
  %retval.0 = select i1 %cmp, i32* %4, i32* @g
  ret i32* %retval.0
}</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>