**Problem** In Rust, checked math functions (like `checked_mul`, `overflowing_mul`, `saturating_mul`) are part of the primitive implementation of integers ([see u64](https://doc.rust-lang.org/std/primitive.u64.html) for instance). The Rust compiler builds the Rust [compiler-builtins](https://github.com/rust-lang/compiler-builtins) crate as a step in the compilation processes, since it contains the math builtins to be lowered in the target. For BPF, however, when using those functions in Rust we hit the following errors: ``` ERROR llvm: <unknown>:0:0: in function func i64 (i64, i64): A call to built-in function '__multi3' is not supported. ERROR llvm: <unknown>:0:0: in function func i64 (i64, i64): only small returns supported ``` Those errors come from the following code: ``` pub fn func(a: u64, b: u64) -> u64 { a.saturating_mul(b) } ``` Those functions invoke underneath the llvm instrinc `{ i64, i1 } @llvm.umul.with.overflow.i64(i64, i64)` or its variants. It is very useful to use safe math operations when writing BPF code in Rust, and I would like to add support for those in the target. **Changes** 1. Create a target feature `allow-builtin-calls` to enable code generation for builtin functions. 2. Implement `CanLowerReturn` to fix the error `only small returns supported`. 3. Add code to correctly invoke lib functions. 4. Add a test case together with the corresponding C code.
13 lines
352 B
LLVM
13 lines
352 B
LLVM
; RUN: not llc -mtriple=bpf < %s 2> %t1
|
|
; RUN: FileCheck %s < %t1
|
|
; CHECK: too many arguments
|
|
|
|
; Function Attrs: nounwind uwtable
|
|
define { i64, i32 } @foo(i32 %a, i32 %b, i32 %c) #0 {
|
|
entry:
|
|
%call = tail call { i64, i32 } @bar(i32 %a, i32 %b, i32 %c, i32 1, i32 2) #3
|
|
ret { i64, i32 } %call
|
|
}
|
|
|
|
declare { i64, i32 } @bar(i32, i32, i32, i32, i32) #1
|