[llvm] [BPF] Define empty set of BPF libcalls (PR #169537)
Lucas Ste via llvm-commits
llvm-commits at lists.llvm.org
Mon Jan 5 10:42:03 PST 2026
https://github.com/LucasSte updated https://github.com/llvm/llvm-project/pull/169537
>From fdb1b9ab5614dd20bb65ec6463d753c6ea2c0a1b Mon Sep 17 00:00:00 2001
From: Lucas Steuernagel <lucas.tnagel at gmail.com>
Date: Tue, 25 Nov 2025 14:47:39 -0300
Subject: [PATCH] [BPF] Define set of BPF libcalls
---
llvm/include/llvm/IR/RuntimeLibcalls.td | 12 ++++-
llvm/test/CodeGen/BPF/atomic-oversize.ll | 10 ++---
llvm/test/CodeGen/BPF/i128_math.ll | 56 ++++++++++++++++++++++++
llvm/test/CodeGen/BPF/warn-call.ll | 2 +-
4 files changed, 72 insertions(+), 8 deletions(-)
create mode 100644 llvm/test/CodeGen/BPF/i128_math.ll
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.td b/llvm/include/llvm/IR/RuntimeLibcalls.td
index b9e68247de94d..5af7d5e4c29cd 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.td
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.td
@@ -3507,13 +3507,23 @@ def WasmSystemLibrary
__small_fprintf), isOSEmscripten>,
__stack_chk_fail, __stack_chk_guard)>;
+//===----------------------------------------------------------------------===//
+// BPF Runtime Libcalls
+//===----------------------------------------------------------------------===//
+
+def isBPF : RuntimeLibcallPredicate<"TT.isBPF()">;
+
+// Only memops
+def BPFSystemLibrary : SystemRuntimeLibrary<isBPF, (add memcpy, memmove,
+ memset)>;
+
//===----------------------------------------------------------------------===//
// Legacy Default Runtime Libcalls
//===----------------------------------------------------------------------===//
// TODO: Should make every target explicit.
def isDefaultLibcallArch : RuntimeLibcallPredicate<[{
- TT.isMIPS() || TT.isLoongArch() || TT.isVE() || TT.isBPF() ||
+ TT.isMIPS() || TT.isLoongArch() || TT.isVE() ||
TT.getArch() == Triple::csky || TT.getArch() == Triple::arc ||
TT.getArch() == Triple::m68k || TT.getArch() == Triple::xtensa ||
(TT.isSystemZ() && !TT.isOSzOS())
diff --git a/llvm/test/CodeGen/BPF/atomic-oversize.ll b/llvm/test/CodeGen/BPF/atomic-oversize.ll
index 187f0964d4fb8..1c60dca1b2056 100644
--- a/llvm/test/CodeGen/BPF/atomic-oversize.ll
+++ b/llvm/test/CodeGen/BPF/atomic-oversize.ll
@@ -1,11 +1,9 @@
-; RUN: llc -mtriple=bpf < %s | FileCheck %s
-; XFAIL: *
-; Doesn't currently build, with error 'only small returns supported'.
+; RUN: not llc -mtriple=bpf < %s 2> %t1
+; RUN: FileCheck %s < %t1
+; CHECK: error: unsupported atomic store
+; CHECK: error: unsupported atomic load
define void @test(ptr %a) nounwind {
-; CHECK-LABEL: test:
-; CHECK: call __atomic_load_16
-; CHECK: call __atomic_store_16
%1 = load atomic i128, ptr %a monotonic, align 16
store atomic i128 %1, ptr %a monotonic, align 16
ret void
diff --git a/llvm/test/CodeGen/BPF/i128_math.ll b/llvm/test/CodeGen/BPF/i128_math.ll
new file mode 100644
index 0000000000000..f67c921467300
--- /dev/null
+++ b/llvm/test/CodeGen/BPF/i128_math.ll
@@ -0,0 +1,56 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -march=bpfel < %s | FileCheck %s
+;
+; C code for this test case:
+;
+; long func(long a, long b) {
+; long x;
+; return __builtin_mul_overflow(a, b, &x);
+; }
+
+
+declare { i64, i1 } @llvm.smul.with.overflow.i64(i64, i64)
+
+define i64 @func(i64 %a, i64 %b) {
+; CHECK-LABEL: func:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: r3 = r1
+; CHECK-NEXT: r3 <<= 32
+; CHECK-NEXT: r3 >>= 32
+; CHECK-NEXT: r1 s>>= 32
+; CHECK-NEXT: r5 = r2
+; CHECK-NEXT: r5 <<= 32
+; CHECK-NEXT: r5 >>= 32
+; CHECK-NEXT: r4 = r1
+; CHECK-NEXT: r4 *= r5
+; CHECK-NEXT: r0 = r3
+; CHECK-NEXT: r0 *= r5
+; CHECK-NEXT: r0 >>= 32
+; CHECK-NEXT: r4 += r0
+; CHECK-NEXT: r5 = r4
+; CHECK-NEXT: r5 <<= 32
+; CHECK-NEXT: r5 >>= 32
+; CHECK-NEXT: r2 s>>= 32
+; CHECK-NEXT: r3 *= r2
+; CHECK-NEXT: r3 += r5
+; CHECK-NEXT: r1 *= r2
+; CHECK-NEXT: r4 s>>= 32
+; CHECK-NEXT: r2 = r3
+; CHECK-NEXT: r2 s>>= 32
+; CHECK-NEXT: r4 += r2
+; CHECK-NEXT: r1 += r4
+; CHECK-NEXT: r3 <<= 32
+; CHECK-NEXT: r3 s>>= 63
+; CHECK-NEXT: w0 = 1
+; CHECK-NEXT: if r1 != r3 goto LBB0_2
+; CHECK-NEXT: # %bb.1: # %entry
+; CHECK-NEXT: w0 = 0
+; CHECK-NEXT: LBB0_2: # %entry
+; CHECK-NEXT: exit
+entry:
+ %0 = tail call { i64, i1 } @llvm.smul.with.overflow.i64(i64 %a, i64 %b)
+ %1 = extractvalue { i64, i1 } %0, 1
+ %conv = zext i1 %1 to i64
+ ret i64 %conv
+}
+
diff --git a/llvm/test/CodeGen/BPF/warn-call.ll b/llvm/test/CodeGen/BPF/warn-call.ll
index d0b1da5e64264..bedf1d6579036 100644
--- a/llvm/test/CodeGen/BPF/warn-call.ll
+++ b/llvm/test/CodeGen/BPF/warn-call.ll
@@ -63,4 +63,4 @@ declare void @llvm.dbg.value(metadata, i64, metadata, metadata) #4
!29 = !DILocalVariable(name: "len", arg: 3, scope: !25, file: !1, line: 2, type: !12)
!30 = !DILocation(line: 2, column: 67, scope: !25)
!31 = !DILocation(line: 2, column: 86, scope: !25)
-!32 = !DILocation(line: 2, column: 93, scope: !25)
+!32 = !DILocation(line: 2, column: 93, scope: !25)
\ No newline at end of file
More information about the llvm-commits
mailing list