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

128 bit multiplication doesn't work on windows #2250

Closed
andrewrk opened this issue Apr 11, 2019 · 1 comment
Closed

128 bit multiplication doesn't work on windows #2250

andrewrk opened this issue Apr 11, 2019 · 1 comment
Labels
bug Observed behavior contradicts documented or intended behavior os-windows
Milestone

Comments

@andrewrk
Copy link
Member

andrewrk commented Apr 11, 2019

const std = @import("std");
const expect = std.testing.expect;

test "128 bit multiplication" {
    var a: i128 = 3;
    var b: i128 = 2;
    var c = a * b;
    std.testing.expect(c == 6);
}

This results in a segfault. Here's what's happening. This invokes __muloti4 from compiler-rt:

00007FF68D311540  mov         rcx,qword ptr [rbp]  
00007FF68D311544  mov         rdx,qword ptr [rbp+8]  
00007FF68D311548  mov         r8,qword ptr [rbp-10h]  
00007FF68D31154C  mov         r9,qword ptr [rbp-8]  
00007FF68D311550  mov         qword ptr [rbp-28h],0  
00007FF68D311558  mov         rax,rsp  
00007FF68D31155B  lea         r10,[rbp-28h]  
00007FF68D31155F  mov         qword ptr [rax+20h],r10  
00007FF68D311563  call        compiler_rt.muloti4.__muloti4_windows_x86_64 (07FF68D33D5E0h)  

Inside the __muloti4 call:

;const v128 = @Vector(2, u64);
;pub extern fn __muloti4_windows_x86_64(a: v128, b: v128, overflow: *c_int) v128 {
00007FF68D33D5E0  push        rbp  
00007FF68D33D5E1  sub         rsp,1F0h  
00007FF68D33D5E8  lea         rbp,[rsp+80h]  
00007FF68D33D5F0  movaps      xmm0,xmmword ptr [rdx]  ; <==== segfault
00007FF68D33D5F3  movaps      xmm1,xmmword ptr [rcx]  
00007FF68D33D5F6  movaps      xmmword ptr [rbp+0C0h],xmm1  
00007FF68D33D5FD  movaps      xmmword ptr [rbp+0B0h],xmm0  
00007FF68D33D604  mov         qword ptr [rbp+0A8h],r8  

The segfault happens because rdx is 0. Curiosly, rcx is 3 in this example, and is set to the value of a. However for both rcx and rdx the __muloti4 function is expecting these to be pointers to a and b respectively, so this is an ABI mismatch. On the _muloti4 side of things this seems to be correct, however at the callsite, which is how LLVM lowers a * b for 128 bit integers, it does not seem to match.

I'm looking at the LLVM code for how they lower 128 bit multiplication on Windows to find out what's going on.

This is the issue blocking #2102.

@andrewrk andrewrk added bug Observed behavior contradicts documented or intended behavior os-windows labels Apr 11, 2019
@andrewrk andrewrk added this to the 0.5.0 milestone Apr 11, 2019
@andrewrk
Copy link
Member Author

I think what's going on here is that LLVM actually doesn't support 128-bit integer multiplication on Windows. That's one of the reasons that Zig has a port of compiler-rt and not actually a build of C compiler-rt from source, because we want to make it available. That being the case, Clang/LLVM has not actually fixed their ABI issue with __muloti4 and 128 bit integer multiplication, so it's up to Zig to put a workaround in.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Observed behavior contradicts documented or intended behavior os-windows
Projects
None yet
Development

No branches or pull requests

1 participant