[llvm-bugs] [Bug 46057] New: Use of overflow checks causes loop idiom recognizer to miss memset

via llvm-bugs llvm-bugs at lists.llvm.org
Sun May 24 10:52:43 PDT 2020


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

            Bug ID: 46057
           Summary: Use of overflow checks causes loop idiom recognizer to
                    miss memset
           Product: libraries
           Version: trunk
          Hardware: PC
                OS: All
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: Scalar Optimizations
          Assignee: unassignedbugs at nondot.org
          Reporter: alex.gaynor at gmail.com
                CC: llvm-bugs at lists.llvm.org

Godbolt link: https://godbolt.org/z/JBB4vz

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 https://gist.github.com/alex/7cb86520bf8a4fe799a728180c257675 (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.)

-- 
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/20200524/adad55d7/attachment-0001.html>


More information about the llvm-bugs mailing list