<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 - Missed optimization: llvm unable to remove bounds check"
   href="https://bugs.llvm.org/show_bug.cgi?id=48909">48909</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Missed optimization: llvm unable to remove bounds check
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>new-bugs
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>unspecified
          </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>new bugs
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>alex.gaynor@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>htmldeveloper@gmail.com, llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre><a href="https://godbolt.org/z/vEfPYj">https://godbolt.org/z/vEfPYj</a> (also below)

LLVM should be able to remove the branch that leads to the call to abort() --
data.length is known to be the same as block_len, and block_len is known not to
be 0. Therefore llvm should know that block_len - is always < data.length.

Source:

#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>

typedef struct {
    uint8_t *data;
    size_t length;
} slice;

static inline uint8_t subscript(slice data, size_t index) {
    if (index >= data.length) {
        abort();
    }
    return data.data[index];
}

bool check_padding(slice data, size_t block_len) {
    if (data.length != block_len || block_len == 0) {
        return false;
    }

    uint8_t pad_size = subscript(data, block_len - 1);
    return pad_size > 7;
}


generated assembly:

check_padding:                          # @check_padding
        push    rax
        xor     eax, eax
        cmp     rsi, rdx
        jne     .LBB0_4
        test    rdx, rdx
        je      .LBB0_4
        test    rsi, rsi
        je      .LBB0_5
        cmp     byte ptr [rsi + rdi - 1], 7
        seta    al
.LBB0_4:
        pop     rcx
        ret
.LBB0_5:
        call    abort</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>