[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