[llvm] [BPF] Define empty set of BPF libcalls (PR #169537)
Lucas Ste via llvm-commits
llvm-commits at lists.llvm.org
Fri Dec 5 10:09:03 PST 2025
LucasSte wrote:
Hi @vadorovsky, thank you for your detailed response!
This PR will lower memops without any error for any number of bytes. Let me show you why.
Yes, as you mentioned 128 is the limit BPF uses to decide whether to expand a memop into a chain of loads and stores or invoke a libcall.
Above that limit, there is yet another check that happens in `PreISelInstrinsicLowering.cpp`.
`canEmitMemcpy` checks whether there is a libcall available for memcpy (I'm focusing the example on memcpy, but you can check the file that the control flow is the same for other memops).
https://github.com/llvm/llvm-project/blob/fb6513130de7578c847aaaf6c278809b6c2476c3/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp#L250-L259
If the libcall is not available, then LLVM will emit a loop for copying memory:
https://github.com/llvm/llvm-project/blob/fb6513130de7578c847aaaf6c278809b6c2476c3/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp#L330-L336
If you are still not convinced, check the following example:
```
target triple = "bpfel--"
define void @test_memcpy(ptr %out, ptr %in) {
call void @llvm.memcpy.p0.p0.i64(ptr %out, ptr %in, i64 65000, i1 false)
ret void
}
declare void @llvm.memcpy.p0.p0.i64(ptr noalias writeonly captures(none), ptr noalias readonly captures(none), i64, i1 immarg) #0
attributes #0 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }
```
which generates with this patch the following code:
```
test_memcpy: # @test_memcpy
.cfi_startproc
# %bb.0:
r3 = 0
LBB0_1: # %load-store-loop
# =>This Inner Loop Header: Depth=1
r4 = r1
r4 += r3
r5 = r2
r5 += r3
w5 = *(u8 *)(r5 + 0)
*(u8 *)(r4 + 0) = w5
r3 += 1
if r3 < 65000 goto LBB0_1
# %bb.2: # %memcpy-split
exit
```
https://github.com/llvm/llvm-project/pull/169537
More information about the llvm-commits
mailing list