-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
128-bit integer division with remainder is not combined to a single operation #44545
Comments
Note that the equivalent program in C: typedef struct {
unsigned __int128 a;
unsigned __int128 b;
} UInt128Pair;
UInt128Pair divmod(unsigned __int128 a, unsigned __int128 b) {
UInt128Pair result;
result.a = a / b;
result.b = a % b;
return result;
} Does not generate x86_64 assemblydivmod: # @divmod
push rbp
push r15
push r14
push r13
push r12
push rbx
push rax
mov r14, r8
mov r15, rcx
mov r12, rdx
mov r13, rsi
mov rbx, rdi
mov rdi, r13
mov rsi, r12
mov rdx, r15
mov rcx, r14
call __udivti3
mov qword ptr [rsp], rax # 8-byte Spill
mov rbp, rdx
mov rdi, r13
mov rsi, r12
mov rdx, r15
mov rcx, r14
call __umodti3
mov qword ptr [rbx + 8], rbp
mov rcx, qword ptr [rsp] # 8-byte Reload
mov qword ptr [rbx], rcx
mov qword ptr [rbx + 24], rdx
mov qword ptr [rbx + 16], rax
mov rax, rbx
add rsp, 8
pop rbx
pop r12
pop r13
pop r14
pop r15
pop rbp
ret
clang (trunk) does not call x86_64 assemblydivmod: # @divmod
push r15
push r14
push r13
push r12
push rbx
mov r14, r8
mov rbx, rcx
mov r15, rdx
mov r12, rsi
mov r13, rdi
mov rdi, r12
mov rsi, r15
mov rdx, rbx
mov rcx, r14
call __udivti3
mov rcx, rax
mov rsi, rdx
imul r14, rcx
mov rax, rcx
mul rbx
add rdx, r14
imul rbx, rsi
add rbx, rdx
sub r12, rax
sbb r15, rbx
mov qword ptr [r13 + 8], rsi
mov qword ptr [r13], rcx
mov qword ptr [r13 + 16], r12
mov qword ptr [r13 + 24], r15
mov rax, r13
pop rbx
pop r12
pop r13
pop r14
pop r15
ret
ICC 17 also won't combine the calls. GCC 7 does generate |
The saddest part of the story is probably the implementations of I guess its more up to LLVM to fix the issue than to Rust, as from what I saw in the LLVM IR specification there is no combined "divrem" LLVM instruction to give modulo and the quotient. |
That’s disappointing. Is it possible to manually call |
That would be rust-lang/rfcs#914. |
@henninglive sort of you could. My first impression: it would be more of a hack... Idk, what do others think about this? |
Still not generating udivmodti4: https://rust.godbolt.org/z/p-CxYF This is doing udivti3 + mul + sub. |
danlark1 opened an LLVM issue for this. |
Rustc fails to combine
div()
andmod()
operations withu128
to a single division with remainder on x64. The following code compiles down to separate calls to__udivti3()
and__umodti3()
when we would prefer a single call to__udivmodti4()
.Related to #39078.
Relevant in the Display implementation for i128 and u128.
The text was updated successfully, but these errors were encountered: