<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 - Code generation regression with trunk"
   href="https://bugs.llvm.org/show_bug.cgi?id=34554">34554</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Code generation regression with trunk
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </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>LLVM Codegen
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>matt@godbolt.org
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Hi all,

I'm not sure how best to explain what's going on, but this code:

#include <array>
#include <algorithm>

constexpr auto get_array() {
  return std::array<char, 42>{"This is my string that might have a char."};
}

bool has_char(const char c) {
  static constexpr auto a = get_array();
  return std::find(std::begin(a), std::end(a), c) != std::end(a);
}

( <a href="https://godbolt.org/g/qW58Cc">https://godbolt.org/g/qW58Cc</a> )

When compiled with `-std=c++17 -O3` on trunk (r312894) generates a jump table,
each of which corresponds to a long-winded "return true" or "return false", of
the form:

.LBB0_2:
  mov eax, has_char(char)::a+42
  mov ecx, has_char(char)::a+42
  cmp rax, rcx
  setne al
  ret

This is equivalent to `xor eax, eax; ret`. On clang 5.0.0 and with -O2,
different code is generated:

.LBB0_8:
  mov eax, has_char(char)::a+41
  jmp .LBB0_19
....
.LBB0_19:
  mov ecx, has_char(char)::a+42
  cmp rax, rcx
  setne al
  ret

It seems like the code generator is only one step from inferring that each leaf
of the jump table can be replaced with xor eax,eax;ret, or `mov eax,1;ret`, but
falls at the final hurdle.</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>