<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 - Failure to remove monotonic atomic reads"
   href="https://bugs.llvm.org/show_bug.cgi?id=44969">44969</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Failure to remove monotonic atomic reads
          </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>enhancement
          </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>hfinkel@anl.gov
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>jdoerfert@anl.gov, llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>#include <atomic>
#include <memory>

int *convert(std::atomic<int> *in, int n) {
    int *out = (int *) in;
    for (int i = 0; i < n; ++i) {
      int v = in[i].load(std::memory_order_relaxed);
      new (&out[i]) int(v);
    }

    return out;
}

currently generates IR, using clang -O3 -emit-llvm -g0 -fno-unroll-loops
-std=c++17, that looks like this:

define dso_local i32* @_Z7convertPSt6atomicIiEi(%"struct.std::atomic"* %0, i32
%1) local_unnamed_addr #0 personality i32 (...)* @__gxx_personality_v0 {
  %3 = getelementptr %"struct.std::atomic", %"struct.std::atomic"* %0, i64 0,
i32 0, i32 0
  %4 = icmp sgt i32 %1, 0
  br i1 %4, label %5, label %7

5:                                                ; preds = %2
  %6 = zext i32 %1 to i64
  br label %8

7:                                                ; preds = %8, %2
  ret i32* %3

8:                                                ; preds = %8, %5
  %9 = phi i64 [ 0, %5 ], [ %12, %8 ]
  %10 = getelementptr inbounds %"struct.std::atomic", %"struct.std::atomic"*
%0, i64 %9, i32 0, i32 0
  %11 = load atomic i32, i32* %10 monotonic, align 4
  %12 = add nuw nsw i64 %9, 1
  %13 = icmp eq i64 %12, %6
  br i1 %13, label %7, label %8
}

and so we successfully remove the store from the placement new, but not the
atomic. AFAIK, there's no reason why we cannot remove it, and we should do so
in order to make it possible for the compiler to remove loops converting atomic
data to non-atomic data (which actually do nothing at all).</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>