<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 - awful code generated for std::any_of / std::find_if looking for a zero byte"
   href="https://bugs.llvm.org/show_bug.cgi?id=51253">51253</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>awful code generated for std::any_of / std::find_if looking for a zero byte
          </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>Scalar Optimizations
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>richard-llvm@metafoo.co.uk
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Live demo: <a href="https://godbolt.org/z/xsn9hY1W1">https://godbolt.org/z/xsn9hY1W1</a>

Testcase:

#include <algorithm>
#include <array>
void do_this();
void do_that();
void f5(std::array<unsigned char, 8> arr) {
  if (std::any_of(arr.begin(), arr.end(),
                  [](unsigned char c) { return c != 0x00; }))
    do_this();
  else
    do_that();
}

This should compile into a single 8-byte comparison of arr against zero and a
branch. But (when using libstdc++ as the standard library) LLVM produces awful
code:

define dso_local void @_Z2f5St5arrayIhLm8EE(i64 %0) local_unnamed_addr #0 {
  %2 = alloca i64, align 8
  %3 = bitcast i64* %2 to i8*
  store i64 %0, i64* %2, align 8
  %4 = getelementptr inbounds i64, i64* %2, i64 1
  %5 = bitcast i64* %4 to i8*
  %6 = getelementptr inbounds i8, i8* %3, i64 4
  %7 = trunc i64 %0 to i8
  %8 = icmp eq i8 %7, 0
  br i1 %8, label %9, label %33

9:                                                ; preds = %1
  %10 = and i64 %0, 65280
  %11 = icmp eq i64 %10, 0
  br i1 %11, label %12, label %21

12:                                               ; preds = %9
  %13 = and i64 %0, 16711680
  %14 = icmp eq i64 %13, 0
  br i1 %14, label %15, label %24

15:                                               ; preds = %12
  %16 = and i64 %0, 4278190080
  %17 = icmp eq i64 %16, 0
  br i1 %17, label %18, label %27

18:                                               ; preds = %15
  %19 = and i64 %0, 1095216660480
  %20 = icmp eq i64 %19, 0
  br i1 %20, label %36, label %33

...


(It's masking out a byte at a time, and comparing that, then eventually it
branches on whether any was non-zero.)

The code generated with -stdlib=libc++ is different but still bad: there we
spill the argument to the stack and do a series of 1-byte loads and compares.

If we remove all the abstraction manually:

void f5(std::array<unsigned char, 8> arr) {
  if (arr[0] || arr[1] || arr[2] || arr[3] || arr[4] || arr[5] || arr[6] ||
arr[7])
    do_this();
  else
    do_that();
}

... then LLVM generates good code:

  %2 = icmp eq i64 %0, 0
  br i1 %2, label %4, label %3

3:                                                ; preds = %1
  tail call void @_Z7do_thisv()
  br label %5

4:                                                ; preds = %1
  tail call void @_Z7do_thatv()
  br label %5</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>