Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bring back div_rem #914

Open
alexcrichton opened this issue Feb 27, 2015 · 13 comments
Open

Bring back div_rem #914

alexcrichton opened this issue Feb 27, 2015 · 13 comments
Labels
postponed RFCs that have been postponed and may be revisited at a later time. T-libs-api Relevant to the library API team, which will review and decide on the RFC.

Comments

@alexcrichton
Copy link
Member

Tracking issue for #850

@alexcrichton alexcrichton added the postponed RFCs that have been postponed and may be revisited at a later time. label Feb 27, 2015
@alexcrichton
Copy link
Member Author

cc @quantheory

@Boscop
Copy link

Boscop commented Feb 28, 2018

Any update on this? :)

@vi
Copy link

vi commented Mar 23, 2018

Shall it avoid giving negative remainders unlike %?

@Lokathor
Copy link
Contributor

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.

@dignifiedquire
Copy link

What exactly would it need to push this forward?

@Centril
Copy link
Contributor

Centril commented Dec 24, 2018

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

@Lokathor
Copy link
Contributor

Lokathor commented Dec 24, 2018

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

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

@AaronKutch
Copy link

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?

@programmerjake
Copy link
Member

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.

@AaronKutch
Copy link

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.

@programmerjake
Copy link
Member

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

@parraman
Copy link

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!

@NCGThompson
Copy link

NCGThompson commented Dec 21, 2023

I would like to point out that div_rem methods may have value even without intrinsic functions to implement them.

  • Most importantly, the methods might just help with convenience or readability.
  • The standard library is always compiled with opt-level=3, so the optimization will exist even in debug mode.
  • There is a little bit of room for optimization outside of the intrinsics. Ex: wrapping_div_rem_euclid()

Since the compiler doesn't recognize the hard coded div function, ethnum-rs has a set of div_rem methods analogous to the integer methods in the standard library. I suggest taking a look at the API and documentation as an example of what the div_rem methods could look like. The implementing code itself isn't as applicable because there were different intrinsics to work with.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
postponed RFCs that have been postponed and may be revisited at a later time. T-libs-api Relevant to the library API team, which will review and decide on the RFC.
Projects
None yet
Development

No branches or pull requests