diff --git a/src/int/sdiv.rs b/src/int/sdiv.rs index 57ef03cd..3d0c3afc 100644 --- a/src/int/sdiv.rs +++ b/src/int/sdiv.rs @@ -54,5 +54,12 @@ intrinsics! { i128_div_rem(a, b).1 } - // LLVM does not currently have a `__divmodti4` function + // LLVM does not currently have a `__divmodti4` function, but GCC does + #[maybe_use_optimized_c_shim] + /// Returns `n / d` and sets `*rem = n % d` + pub extern "C" fn __divmodti4(a: i128, b: i128, rem: &mut i128) -> i128 { + let quo_rem = i128_div_rem(a, b); + *rem = quo_rem.1; + quo_rem.0 + } } diff --git a/testcrate/build.rs b/testcrate/build.rs index e1d4cf9e..656fd2d2 100644 --- a/testcrate/build.rs +++ b/testcrate/build.rs @@ -805,6 +805,19 @@ fn main() { (builtins::int::sdiv::__divmodsi4(a, b, &mut r), r) }", ); + gen( + |(a, b): (MyI128, MyI128)| { + if b.0 == 0 { + None + } else { + Some((a.0 / b.0, a.0 % b.0)) + } + }, + "{ + let mut r = 0; + (builtins::int::sdiv::__divmodti4(a, b, &mut r), r) + }", + ); gen( |(a, b): (MyI32, MyI32)| { if b.0 == 0 { diff --git a/testcrate/tests/div_rem.rs b/testcrate/tests/div_rem.rs index 2a154f5e..199fa9db 100644 --- a/testcrate/tests/div_rem.rs +++ b/testcrate/tests/div_rem.rs @@ -1,15 +1,9 @@ use rand_xoshiro::rand_core::{RngCore, SeedableRng}; use rand_xoshiro::Xoshiro128StarStar; -use compiler_builtins::int::sdiv::{__divmoddi4, __divmodsi4, __divti3, __modti3}; +use compiler_builtins::int::sdiv::{__divmoddi4, __divmodsi4, __divmodti4}; use compiler_builtins::int::udiv::{__udivmoddi4, __udivmodsi4, __udivmodti4}; -// because `__divmodti4` does not exist, we synthesize it -fn __divmodti4(a: i128, b: i128, rem: &mut i128) -> i128 { - *rem = __modti3(a, b); - __divti3(a, b) -} - /// Creates intensive test functions for division functions of a certain size macro_rules! test { (