Rfcs: Bring back div_rem

Created on 27 Feb 2015  路  12Comments  路  Source: rust-lang/rfcs

T-libs postponed

Most helpful comment

When you divide -1234 by 10, your remainder is -4.

I think the advantage of div_rem is that the computer is _already_ doing both at once, it's just throwing away part of the work instead of instead of letting us keep both parts.

All 12 comments

cc @quantheory

Any update on this? :)

Shall it avoid giving negative remainders unlike %?

When you divide -1234 by 10, your remainder is -4.

I think the advantage of div_rem is that the computer is _already_ doing both at once, it's just throwing away part of the work instead of instead of letting us keep both parts.

What exactly would it need to push this forward?

@dignifiedquire I'd just write a PR against https://github.com/rust-lang/rust/ and then T-libs can decide what to do.

Make sure to spec it as const from the start (for integers at least)

Edit: oh crap no const-if yet, nevermind i guess

I want to add a set of uX::wrapping_div_rem(lhs, rhs) -> (uX, uX) functions as a way to guarantee that __udivmodti4 and the like are called, and not have to rely on the compiler backend to combine operations. However, someone encountered an LLVM error where the target sparc-unknown-linux-gnu cannot lower any function that returns a tuple of two u128s. If the function were added, wouldn't that completely break 32-bit SPARC targets unless the LLVM issue is resolved?

I'd imagine rustc could add a workaround to do the return lowering in rustc if the LLVM bug is not easy to fix or we want to support old LLVM versions.

Is there someone who wants to tackle the problem? I might try myself, although I have no idea where to begin. I've never messed with code lowering before.

It seems to work fine from clang: https://gcc.godbolt.org/z/8xbrWE

I don't know if it's useful, but I have compiled the following code and generated the corresponding LLVM IR:

#[no_mangle]
fn test_128(one: u128, two: u128) -> (u128, u128) {
    let division = one / two;
    (division + 40000000, division - 100000)
}

The LLVM IR is:

; Function Attrs: minsize nounwind optsize
define { i128, i128 } @test_128(i128 %one, i128 %two) unnamed_addr #0 {
start:
  %_6 = icmp eq i128 %two, 0
  br i1 %_6, label %panic, label %bb1, !prof !1, !misexpect !2

bb1:                                              ; preds = %start
  %division = udiv i128 %one, %two
  %_7 = add i128 %division, 40000000
  %_9 = add i128 %division, -100000
  %0 = insertvalue { i128, i128 } undef, i128 %_7, 0
  %1 = insertvalue { i128, i128 } %0, i128 %_9, 1
  ret { i128, i128 } %1

NOTE: I have removed the panic block since I believe it shouldn't be what is causing the error.

The error output generated by rustc is:

LLVM ERROR: unable to allocate function return #6

I have generated the LLVM IR with the flag --emit=llvm-ir. The equivalent function in LLVM IR generated from clang is here.

Thanks a lot!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

clarfonthey picture clarfonthey  路  3Comments

3442853561 picture 3442853561  路  3Comments

rudolfschmidt picture rudolfschmidt  路  3Comments

torkleyy picture torkleyy  路  3Comments

silversolver1 picture silversolver1  路  3Comments