Issue |
127723
|
Summary |
Libcalls for Windows without SSE should return `i128` on the stack
|
Labels |
new issue
|
Assignees |
|
Reporter |
tgross35
|
The following:
```llvm
attributes #0 = { "target-features"="-mmx,-sse,+soft-float" }
define void @do_div(ptr %xptr, ptr %yptr, ptr %rptr) #0 {
%x = load i128, ptr %xptr
%y = load i128, ptr %yptr
%res = udiv i128 %x, %y
store i128 %res, ptr %rptr
ret void
}
```
Generates:
```asm
do_div: # @do_div
push rsi
sub rsp, 64
mov rsi, r8
mov rax, qword ptr [rcx]
mov rcx, qword ptr [rcx + 8]
mov r8, qword ptr [rdx]
mov rdx, qword ptr [rdx + 8]
mov qword ptr [rsp + 56], rcx
mov qword ptr [rsp + 48], rax
mov qword ptr [rsp + 32], r8
mov qword ptr [rsp + 40], rdx
lea rcx, [rsp + 48]
lea rdx, [rsp + 32]
call __udivti3
mov qword ptr [rsi], rax
mov qword ptr [rsi + 8], rdx
add rsp, 64
pop rsi
ret
```
Link: https://llvm.godbolt.org/z/bcao4bdj1
In `do_div`, LLVM seems to expect `__udivti3` to takes its arguments indirectly but return in a register pair `(rax, rdx)`. This doesn't seem correct; nothing in the Windows calling convention suggests that values larger than 64 bits are ever returned in registers. Instead, `i128` should be returned in a stack slot if sse is not available.
`i128` is usually returned in xmm0, and the default is to both pass and return `i128` in registers, so this seems like it may just be fallback behavior.
There is more at https://github.com/rust-lang/compiler-builtins/issues/758, specifically this comment https://github.com/rust-lang/compiler-builtins/issues/758#issuecomment-2667130322.
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs