[llvm-bugs] [Bug 39254] New: Bad code generated for search in constexpr arrays

via llvm-bugs llvm-bugs at lists.llvm.org
Thu Oct 11 08:04:02 PDT 2018


https://bugs.llvm.org/show_bug.cgi?id=39254

            Bug ID: 39254
           Summary: Bad code generated for search in constexpr arrays
           Product: clang
           Version: trunk
          Hardware: PC
                OS: Linux
            Status: NEW
          Keywords: code-quality
          Severity: enhancement
          Priority: P
         Component: C++
          Assignee: unassignedclangbugs at nondot.org
          Reporter: antoshkka at gmail.com
                CC: dgregor at apple.com, llvm-bugs at lists.llvm.org

The following code:

constexpr const char* find(const char* begin, const char* end, char value) {
    for (; begin != end; ++begin)
      if (*begin == value) return begin;
    return begin;
}

unsigned find_first_to_escape(const char* s, unsigned size) {
  for (unsigned i = 0; i < size; ++i) {
    const char c = s[i];
    if (c == '\\') {
      //static
       constexpr char allowed_2char_escapes[] = {
        '\"', '/', '\\', 'b', 'f' , 'n', 'r', 't'
      };

      ++i;
      const char* begin = allowed_2char_escapes;
      const char* end = begin + sizeof(allowed_2char_escapes);
      if (find(begin, end, s[i]) == end) return i - 1;

      continue;
    }

    if (c <= 0x1F) return i;
  }

  return -1;
}


When compiled with `-std=c++17 -O3` produces assembly with multiple suboptimal
places:
1) It writes the content of the `allowed_2char_escapes` to memory `mov qword
ptr [rsp - 8], r10`. Marking `allowed_2char_escapes` with `static constexpr`
fixes that and removes unnecessary memory write.
2) Clumsy jump table generated. It consumes many bytes and does not seem to be
optimal. For example the code that compares a single char consumes more
assembly instructions than all the char comparisons on GCC. Clang's jump table
size consumes additional ~552 bytes, while GCC does not have it at all.
3) More registers used than with GCC. This forces clang to unnecessarily
push/pop data on stack.

Assembly comparison for last stable versions: https://godbolt.org/z/5uJOiD
Assembly comparison for trunks: https://godbolt.org/z/GxspEi

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20181011/831b6ecc/attachment.html>


More information about the llvm-bugs mailing list