[llvm] [BPF] Implement `canLowerReturn` for big returns (PR #174478)

Lucas Ste via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 8 07:14:24 PST 2026


================
@@ -0,0 +1,27 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -march=bpfel < %s | FileCheck %s
+; This test used to fail with "unable to allocate function return #1"
+
+define i128 @foo(i64 %a, i64 %b) {
----------------
LucasSte wrote:

> So your use case requires to return __int128 only (for 16 bytes) or some other return types e.g. struct ret { long a; long b;}?

Yes, right now, I'd like to be able to return int128 numbers. They are necessary to avoid precisions loss when you multiply two i64 and then divide them by a third i64.

> What exactly usage for this CanLowerReturn()? I assume you probably won't write bpf program with returning more than 8 bytes.

The int128 return will be used in internal functions only. `CanLowerReturn` will save the 16 bytes of i128 numbers in a pointer instead of using the r0 register, which only holds 8 bytes.

In this example that I create, that happens on line 15 and on 20, and r0 is unused.

```
Line 15: ; CHECK-NEXT:    *(u64 *)(r1 + 0) = r5
Line 20: ; CHECK-NEXT:    *(u64 *)(r1 + 8) = r2
```

> For the above test case, it would be great if you have both caller and callee. In the above function foo() corresponds to callee. This will give a complete picture about parameter and return registers.

Yes, sure. I'll include the caller for clarity.


https://github.com/llvm/llvm-project/pull/174478


More information about the llvm-commits mailing list