[PATCH] 128-bit ABI for x86_64-w64-mingw32 incorrectly generated

Jameson Nash vtjnash at gmail.com
Wed Oct 23 19:41:51 PDT 2013


  I am addressing the segfault in the following code snippet caused by the srem instruction using the wrong calling convention (GCC fixed this bug in 4.7). I have not been able to run the test suite on Windows (because my choices of python either don't support unix paths (native install), or don't support `import threading` (msys2 install)), but this is presumably already one of the tests.

  ```
  #include <stdint.h>

  int main() {
    volatile __int128 x = 1;
    return x % 3;
  }
  ```

  ```
  ; ModuleID = 'i128.c'
  target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
  target triple = "x86_64-w64-mingw32"

  define i32 @main() nounwind uwtable {
    %x = alloca i128, align 16
    store volatile i128 1, i128* %x, align 16
    %x.0.load1 = load volatile i128* %x, align 16
    %1 = srem i128 %x.0.load1, 3
    %2 = trunc i128 %1 to i32
    ret i32 %2
  }
  ```

  Note that there are 6 identical copies of the same patch here because there were 6 nearly identical functions in the code `makeLibCall/ExpandLibCall/etc.` . It seems all of these functions should be rewritten as 1 function. I mention that because I find it easier to refer to this as a change to a single function, while assuming the reader understands that that function exists in 6 locations.

  @asl I agree that it is unfortunate that this is encoding target specific information in this file. Let me explain why I put it here: After this function is called, the function has been translated to the "llvm calling convention" and the information necessary to map that information to the calling convention of the target platform has been destroyed. However, before this function is called the information on what function is getting called and it's arguments is somewhat scattered. I would like to see the LLVM calling convention actually match the platform C ABI, so that it could be trivially used from other front-ends -- but I have seen mentioned that the LLVM calling convention is necessary for efficient optimization and won't be changed. Perhaps this information (ByRef vs. ByVal) could be part of `RTLIB::Libcall`, but I'm not sufficiently familiar with LLVM to make that modification.
  To put this another way, `makeLibCall` is translating an LLVM opcode into a call to a C library function, and thus needs to know how to properly translate the C calling convention into LLVM.

  @majnemer thanks for the feedback. I will be sure to incorporate those fixes along the way.

http://llvm-reviews.chandlerc.com/D1998



More information about the llvm-commits mailing list