llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
29.13k stars 12.02k forks source link

bpf target tries to emit `memcpy` and fails to compile #93700

Open umanwizard opened 5 months ago

umanwizard commented 5 months ago

Consider this C code:

#include <stdint.h>
typedef struct {
    unsigned char x[8];
} buf_t;
void f(buf_t *buf, uint64_t y, uint64_t z) {
    if (z > 8) z = 8;
    unsigned char *y_bytes = (unsigned char *)&y;
    for (int i = 0; i < z; ++i) {
        buf->x[i] = y_bytes[i];
    }
}

It fails to compile on clang 18:

$ clang -O3 -target bpf test.c
test.c:5:6: error: A call to built-in function 'memcpy' is not supported.
    5 | void f(buf_t *buf, uint64_t y, uint64_t z) {
      |      ^
1 error generated.
JOE1994 commented 5 months ago

Thank you for reporting this.

It seems llc 18.1.0 can only codegen memcpy calls with constexpr length : https://godbolt.org/z/6T3b1onfY

Optimization level -O3 introduces memcpy calls with non-constexpr length.

umanwizard commented 5 months ago

Since in this example we can prove x is always <=8, couldn’t we replace the memcpy with a mask and store?