<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 - Use of overflow checks causes loop idiom recognizer to miss memset"
   href="https://bugs.llvm.org/show_bug.cgi?id=46057">46057</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Use of overflow checks causes loop idiom recognizer to miss memset
          </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>alex.gaynor@gmail.com
          </td>
        </tr>

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

Using add/sub with overflow checks in this code causes the optimizer not to
recognize the loop idiom as memset. I realize this code looks a little wonky
for C -- this is because it's a port of some Rust code :-)

I've placed this in the scalar optimizations component, since that's where
previous overflow optimization bugs I've filed have ended up, but please let me
know if that's incorrect!

Paste of the relevant C code from the godbolt link -- I would like for f1 and
f1_overflow to both generate the same code:

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

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

static size_t add(size_t x, size_t y) {
    return x + y;
}

static size_t sub(size_t x, size_t y) {
    return x - y;
}

vec f1() {
    uint8_t *data = malloc(100000);
    size_t i = 100000;
    size_t length = 0;
    while (i > 0) {
        i = sub(i, 1);
        data[i] = 42;
        length = add(length, 1);
    }
    vec v = {data, length};
    return v;
}

extern void panic_at_the_disco() __attribute__((noreturn));

static size_t add_overflow(size_t x, size_t y) {
    size_t r;
    if (__builtin_add_overflow(x, y, &r)) {
        panic_at_the_disco();
    }
    return r;
}

static size_t sub_overflow(size_t x, size_t y) {
    size_t r;
    if (__builtin_sub_overflow(x, y, &r)) {
        panic_at_the_disco();
    }
    return r;
}

vec f1_overflow() {
    uint8_t *data = malloc(100000);
    size_t i = 100000;
    size_t length = 0;
    while (i > 0) {
        i = sub_overflow(i, 1);
        data[i] = 42;
        length = add_overflow(length, 1);
    }
    vec v = {data, length};
    return v;
}


If you're curious about the original Rust code that led to this bug, it can be
found at <a href="https://gist.github.com/alex/7cb86520bf8a4fe799a728180c257675">https://gist.github.com/alex/7cb86520bf8a4fe799a728180c257675</a> (t.rs is
the source, master.s is the assembly emitted by rust nightly, and
overflow-checks.s is what's emitted with the compiler patched to use overflow
checked arithmetic for all usize values.)</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>