[llvm] 57a7e75 - [X86][Windows] use `LowerWin64_INT128_TO_FP` for `u128` to `f128` conversion (#207285)

via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 7 00:56:57 PDT 2026


Author: Folkert de Vries
Date: 2026-07-07T09:56:51+02:00
New Revision: 57a7e7538cfc73184b8280160e8d89cedab04c5d

URL: https://github.com/llvm/llvm-project/commit/57a7e7538cfc73184b8280160e8d89cedab04c5d
DIFF: https://github.com/llvm/llvm-project/commit/57a7e7538cfc73184b8280160e8d89cedab04c5d.diff

LOG: [X86][Windows] use `LowerWin64_INT128_TO_FP` for `u128` to `f128` conversion (#207285)

This change fixes an ABI issue where the signed conversion passes a
`i128` different from a `u128`, and crucially different from GCC.

https://godbolt.org/z/x3daY3rej

```diff
--- <unnamed>
+++ <unnamed>
@@ -1,15 +1,15 @@
-conv_from_i128:
+conv_from_u128:
         push    rsi
-        sub     rsp, 64
+        sub     rsp, 48
         mov     rsi, rcx
-        movaps  xmm0, xmmword ptr [rdx]
-        movaps  xmmword ptr [rsp + 48], xmm0
+        mov     rax, qword ptr [rdx]
+        mov     r8, qword ptr [rdx + 8]
         lea     rcx, [rsp + 32]
-        lea     rdx, [rsp + 48]
-        call    __floattitf
+        mov     rdx, rax
+        call    __floatuntitf
         movaps  xmm0, xmmword ptr [rsp + 32]
         movaps  xmmword ptr [rsi], xmm0
         mov     rax, rsi
-        add     rsp, 64
+        add     rsp, 48
         pop     rsi
         ret
```

The signed case being correct is apparently due to a special
windows-specific path being chosen. The unsigned version bailed out too
early. So, I've changed `LowerUINT_TO_FP` to be more like
`LowerSINT_TO_FP`. In particular this moves the "Bail out when we don't
have native conversion instructions." down a bit, so that
`LowerWin64_INT128_TO_FP` is actually used.

I've then also added some testing for win64 SSE. I'm not sure if the
other target features are as relevant but I can add those too if
helpful.

This was found by running the `rust-lang/compiler-builtins` tests with a
build that includes https://github.com/llvm/llvm-project/pull/204887.

Added: 
    

Modified: 
    llvm/lib/Target/X86/X86ISelLowering.cpp
    llvm/test/CodeGen/X86/fp128-cast.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 91fce25ab23cb..e97b4e6d84a9f 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -21034,32 +21034,32 @@ SDValue X86TargetLowering::LowerUINT_TO_FP(SDValue Op,
   bool IsStrict = Op->isStrictFPOpcode();
   unsigned OpNo = IsStrict ? 1 : 0;
   SDValue Src = Op.getOperand(OpNo);
-  SDLoc dl(Op);
+  SDValue Chain = IsStrict ? Op.getOperand(0) : DAG.getEntryNode();
   auto PtrVT = getPointerTy(DAG.getDataLayout());
   MVT SrcVT = Src.getSimpleValueType();
   MVT DstVT = Op->getSimpleValueType(0);
-  SDValue Chain = IsStrict ? Op.getOperand(0) : DAG.getEntryNode();
-
-  // Bail out when we don't have native conversion instructions.
-  if (DstVT == MVT::f128)
-    return SDValue();
+  SDLoc dl(Op);
 
   if (isBF16orSoftF16(DstVT, Subtarget))
     return promoteXINT_TO_FP(Op, dl, DAG);
   else if (isLegalConversion(SrcVT, DstVT, false, Subtarget))
     return Op;
 
+  if (Subtarget.isTargetWin64() && SrcVT == MVT::i128)
+    return LowerWin64_INT128_TO_FP(Op, DAG);
+
+  if (SDValue Extract = vectorizeExtractedCast(Op, dl, DAG, Subtarget))
+    return Extract;
+
   if (SDValue V = lowerFPToIntToFP(Op, dl, DAG, Subtarget))
     return V;
 
   if (DstVT.isVector())
     return lowerUINT_TO_FP_vec(Op, dl, DAG, Subtarget);
 
-  if (Subtarget.isTargetWin64() && SrcVT == MVT::i128)
-    return LowerWin64_INT128_TO_FP(Op, DAG);
-
-  if (SDValue Extract = vectorizeExtractedCast(Op, dl, DAG, Subtarget))
-    return Extract;
+  // Bail out when we don't have native conversion instructions.
+  if (DstVT == MVT::f128)
+    return SDValue();
 
   if (Subtarget.hasAVX512() && isScalarFPTypeInSSEReg(DstVT) &&
       (SrcVT == MVT::i32 || (SrcVT == MVT::i64 && Subtarget.is64Bit()))) {

diff  --git a/llvm/test/CodeGen/X86/fp128-cast.ll b/llvm/test/CodeGen/X86/fp128-cast.ll
index 6d4ec063ccd46..2fef3746729c1 100644
--- a/llvm/test/CodeGen/X86/fp128-cast.ll
+++ b/llvm/test/CodeGen/X86/fp128-cast.ll
@@ -1,6 +1,7 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
 ; RUN: llc < %s -O2 -mtriple=x86_64-linux-android -mattr=+sse | FileCheck %s --check-prefix=X64-SSE
 ; RUN: llc < %s -O2 -mtriple=x86_64-linux-gnu -mattr=+sse | FileCheck %s --check-prefix=X64-SSE
+; RUN: llc < %s -O2 -mtriple=x86_64-pc-windows-gnu -mattr=+sse | FileCheck %s --check-prefix=WIN64-SSE
 ; RUN: llc < %s -O2 -mtriple=i686-linux-gnu -mattr=+mmx | FileCheck %s --check-prefix=X86
 ; RUN: llc < %s -O2 -mtriple=x86_64-linux-android -mattr=+avx | FileCheck %s --check-prefix=X64-AVX
 ; RUN: llc < %s -O2 -mtriple=x86_64-linux-gnu -mattr=+avx | FileCheck %s --check-prefix=X64-AVX
@@ -31,6 +32,17 @@ define dso_local void @TestFPExtF32_F128() nounwind {
 ; X64-SSE-NEXT:    popq %rax
 ; X64-SSE-NEXT:    retq
 ;
+; WIN64-SSE-LABEL: TestFPExtF32_F128:
+; WIN64-SSE:       # %bb.0: # %entry
+; WIN64-SSE-NEXT:    subq $56, %rsp
+; WIN64-SSE-NEXT:    movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
+; WIN64-SSE-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-SSE-NEXT:    callq __extendsftf2
+; WIN64-SSE-NEXT:    movaps {{[0-9]+}}(%rsp), %xmm0
+; WIN64-SSE-NEXT:    movaps %xmm0, vf128(%rip)
+; WIN64-SSE-NEXT:    addq $56, %rsp
+; WIN64-SSE-NEXT:    retq
+;
 ; X86-LABEL: TestFPExtF32_F128:
 ; X86:       # %bb.0: # %entry
 ; X86-NEXT:    pushl %esi
@@ -78,6 +90,17 @@ define dso_local void @TestFPExtF64_F128() nounwind {
 ; X64-SSE-NEXT:    popq %rax
 ; X64-SSE-NEXT:    retq
 ;
+; WIN64-SSE-LABEL: TestFPExtF64_F128:
+; WIN64-SSE:       # %bb.0: # %entry
+; WIN64-SSE-NEXT:    subq $56, %rsp
+; WIN64-SSE-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
+; WIN64-SSE-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-SSE-NEXT:    callq __extenddftf2
+; WIN64-SSE-NEXT:    movaps {{[0-9]+}}(%rsp), %xmm0
+; WIN64-SSE-NEXT:    movaps %xmm0, vf128(%rip)
+; WIN64-SSE-NEXT:    addq $56, %rsp
+; WIN64-SSE-NEXT:    retq
+;
 ; X86-LABEL: TestFPExtF64_F128:
 ; X86:       # %bb.0: # %entry
 ; X86-NEXT:    pushl %esi
@@ -126,6 +149,19 @@ define dso_local void @TestFPExtF80_F128() nounwind {
 ; X64-SSE-NEXT:    addq $24, %rsp
 ; X64-SSE-NEXT:    retq
 ;
+; WIN64-SSE-LABEL: TestFPExtF80_F128:
+; WIN64-SSE:       # %bb.0: # %entry
+; WIN64-SSE-NEXT:    subq $72, %rsp
+; WIN64-SSE-NEXT:    fldt vf80(%rip)
+; WIN64-SSE-NEXT:    fstpt {{[0-9]+}}(%rsp)
+; WIN64-SSE-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-SSE-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
+; WIN64-SSE-NEXT:    callq __extendxftf2
+; WIN64-SSE-NEXT:    movaps {{[0-9]+}}(%rsp), %xmm0
+; WIN64-SSE-NEXT:    movaps %xmm0, vf128(%rip)
+; WIN64-SSE-NEXT:    addq $72, %rsp
+; WIN64-SSE-NEXT:    retq
+;
 ; X86-LABEL: TestFPExtF80_F128:
 ; X86:       # %bb.0: # %entry
 ; X86-NEXT:    pushl %esi
@@ -174,6 +210,17 @@ define dso_local void @TestFPToSIF128_I16() nounwind {
 ; X64-SSE-NEXT:    popq %rax
 ; X64-SSE-NEXT:    retq
 ;
+; WIN64-SSE-LABEL: TestFPToSIF128_I16:
+; WIN64-SSE:       # %bb.0: # %entry
+; WIN64-SSE-NEXT:    subq $56, %rsp
+; WIN64-SSE-NEXT:    movaps vf128(%rip), %xmm0
+; WIN64-SSE-NEXT:    movaps %xmm0, {{[0-9]+}}(%rsp)
+; WIN64-SSE-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-SSE-NEXT:    callq __fixtfsi
+; WIN64-SSE-NEXT:    movw %ax, vi16(%rip)
+; WIN64-SSE-NEXT:    addq $56, %rsp
+; WIN64-SSE-NEXT:    retq
+;
 ; X86-LABEL: TestFPToSIF128_I16:
 ; X86:       # %bb.0: # %entry
 ; X86-NEXT:    subl $12, %esp
@@ -212,6 +259,17 @@ define dso_local void @TestFPToUIF128_I16() nounwind {
 ; X64-SSE-NEXT:    popq %rax
 ; X64-SSE-NEXT:    retq
 ;
+; WIN64-SSE-LABEL: TestFPToUIF128_I16:
+; WIN64-SSE:       # %bb.0: # %entry
+; WIN64-SSE-NEXT:    subq $56, %rsp
+; WIN64-SSE-NEXT:    movaps vf128(%rip), %xmm0
+; WIN64-SSE-NEXT:    movaps %xmm0, {{[0-9]+}}(%rsp)
+; WIN64-SSE-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-SSE-NEXT:    callq __fixtfsi
+; WIN64-SSE-NEXT:    movw %ax, vi16(%rip)
+; WIN64-SSE-NEXT:    addq $56, %rsp
+; WIN64-SSE-NEXT:    retq
+;
 ; X86-LABEL: TestFPToUIF128_I16:
 ; X86:       # %bb.0: # %entry
 ; X86-NEXT:    subl $12, %esp
@@ -250,6 +308,17 @@ define dso_local void @TestFPToSIF128_I32() nounwind {
 ; X64-SSE-NEXT:    popq %rax
 ; X64-SSE-NEXT:    retq
 ;
+; WIN64-SSE-LABEL: TestFPToSIF128_I32:
+; WIN64-SSE:       # %bb.0: # %entry
+; WIN64-SSE-NEXT:    subq $56, %rsp
+; WIN64-SSE-NEXT:    movaps vf128(%rip), %xmm0
+; WIN64-SSE-NEXT:    movaps %xmm0, {{[0-9]+}}(%rsp)
+; WIN64-SSE-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-SSE-NEXT:    callq __fixtfsi
+; WIN64-SSE-NEXT:    movl %eax, vi32(%rip)
+; WIN64-SSE-NEXT:    addq $56, %rsp
+; WIN64-SSE-NEXT:    retq
+;
 ; X86-LABEL: TestFPToSIF128_I32:
 ; X86:       # %bb.0: # %entry
 ; X86-NEXT:    subl $12, %esp
@@ -288,6 +357,17 @@ define dso_local void @TestFPToUIF128_U32() nounwind {
 ; X64-SSE-NEXT:    popq %rax
 ; X64-SSE-NEXT:    retq
 ;
+; WIN64-SSE-LABEL: TestFPToUIF128_U32:
+; WIN64-SSE:       # %bb.0: # %entry
+; WIN64-SSE-NEXT:    subq $56, %rsp
+; WIN64-SSE-NEXT:    movaps vf128(%rip), %xmm0
+; WIN64-SSE-NEXT:    movaps %xmm0, {{[0-9]+}}(%rsp)
+; WIN64-SSE-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-SSE-NEXT:    callq __fixunstfsi
+; WIN64-SSE-NEXT:    movl %eax, vu32(%rip)
+; WIN64-SSE-NEXT:    addq $56, %rsp
+; WIN64-SSE-NEXT:    retq
+;
 ; X86-LABEL: TestFPToUIF128_U32:
 ; X86:       # %bb.0: # %entry
 ; X86-NEXT:    subl $12, %esp
@@ -327,6 +407,18 @@ define dso_local void @TestFPToSIF128_I64() nounwind {
 ; X64-SSE-NEXT:    popq %rax
 ; X64-SSE-NEXT:    retq
 ;
+; WIN64-SSE-LABEL: TestFPToSIF128_I64:
+; WIN64-SSE:       # %bb.0: # %entry
+; WIN64-SSE-NEXT:    subq $56, %rsp
+; WIN64-SSE-NEXT:    movaps vf128(%rip), %xmm0
+; WIN64-SSE-NEXT:    movaps %xmm0, {{[0-9]+}}(%rsp)
+; WIN64-SSE-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-SSE-NEXT:    callq __fixtfsi
+; WIN64-SSE-NEXT:    cltq
+; WIN64-SSE-NEXT:    movq %rax, vi64(%rip)
+; WIN64-SSE-NEXT:    addq $56, %rsp
+; WIN64-SSE-NEXT:    retq
+;
 ; X86-LABEL: TestFPToSIF128_I64:
 ; X86:       # %bb.0: # %entry
 ; X86-NEXT:    subl $12, %esp
@@ -370,6 +462,18 @@ define dso_local void @TestFPToUIF128_U64() nounwind {
 ; X64-SSE-NEXT:    popq %rax
 ; X64-SSE-NEXT:    retq
 ;
+; WIN64-SSE-LABEL: TestFPToUIF128_U64:
+; WIN64-SSE:       # %bb.0: # %entry
+; WIN64-SSE-NEXT:    subq $56, %rsp
+; WIN64-SSE-NEXT:    movaps vf128(%rip), %xmm0
+; WIN64-SSE-NEXT:    movaps %xmm0, {{[0-9]+}}(%rsp)
+; WIN64-SSE-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-SSE-NEXT:    callq __fixunstfsi
+; WIN64-SSE-NEXT:    movl %eax, %eax
+; WIN64-SSE-NEXT:    movq %rax, vu64(%rip)
+; WIN64-SSE-NEXT:    addq $56, %rsp
+; WIN64-SSE-NEXT:    retq
+;
 ; X86-LABEL: TestFPToUIF128_U64:
 ; X86:       # %bb.0: # %entry
 ; X86-NEXT:    subl $12, %esp
@@ -412,6 +516,17 @@ define dso_local void @TestFPToSIF128_I128() nounwind {
 ; X64-SSE-NEXT:    popq %rax
 ; X64-SSE-NEXT:    retq
 ;
+; WIN64-SSE-LABEL: TestFPToSIF128_I128:
+; WIN64-SSE:       # %bb.0: # %entry
+; WIN64-SSE-NEXT:    subq $56, %rsp
+; WIN64-SSE-NEXT:    movaps vf128(%rip), %xmm0
+; WIN64-SSE-NEXT:    movaps %xmm0, {{[0-9]+}}(%rsp)
+; WIN64-SSE-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-SSE-NEXT:    callq __fixtfti
+; WIN64-SSE-NEXT:    movaps %xmm0, vi128(%rip)
+; WIN64-SSE-NEXT:    addq $56, %rsp
+; WIN64-SSE-NEXT:    retq
+;
 ; X86-LABEL: TestFPToSIF128_I128:
 ; X86:       # %bb.0: # %entry
 ; X86-NEXT:    pushl %esi
@@ -467,6 +582,17 @@ define dso_local void @TestFPToUIF128_U128() nounwind {
 ; X64-SSE-NEXT:    popq %rax
 ; X64-SSE-NEXT:    retq
 ;
+; WIN64-SSE-LABEL: TestFPToUIF128_U128:
+; WIN64-SSE:       # %bb.0: # %entry
+; WIN64-SSE-NEXT:    subq $56, %rsp
+; WIN64-SSE-NEXT:    movaps vf128(%rip), %xmm0
+; WIN64-SSE-NEXT:    movaps %xmm0, {{[0-9]+}}(%rsp)
+; WIN64-SSE-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-SSE-NEXT:    callq __fixunstfti
+; WIN64-SSE-NEXT:    movaps %xmm0, vu128(%rip)
+; WIN64-SSE-NEXT:    addq $56, %rsp
+; WIN64-SSE-NEXT:    retq
+;
 ; X86-LABEL: TestFPToUIF128_U128:
 ; X86:       # %bb.0: # %entry
 ; X86-NEXT:    pushl %esi
@@ -521,6 +647,17 @@ define dso_local void @TestFPTruncF128_F32() nounwind {
 ; X64-SSE-NEXT:    popq %rax
 ; X64-SSE-NEXT:    retq
 ;
+; WIN64-SSE-LABEL: TestFPTruncF128_F32:
+; WIN64-SSE:       # %bb.0: # %entry
+; WIN64-SSE-NEXT:    subq $56, %rsp
+; WIN64-SSE-NEXT:    movaps vf128(%rip), %xmm0
+; WIN64-SSE-NEXT:    movaps %xmm0, {{[0-9]+}}(%rsp)
+; WIN64-SSE-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-SSE-NEXT:    callq __trunctfsf2
+; WIN64-SSE-NEXT:    movss %xmm0, vf32(%rip)
+; WIN64-SSE-NEXT:    addq $56, %rsp
+; WIN64-SSE-NEXT:    retq
+;
 ; X86-LABEL: TestFPTruncF128_F32:
 ; X86:       # %bb.0: # %entry
 ; X86-NEXT:    subl $12, %esp
@@ -559,6 +696,17 @@ define dso_local void @TestFPTruncF128_F64() nounwind {
 ; X64-SSE-NEXT:    popq %rax
 ; X64-SSE-NEXT:    retq
 ;
+; WIN64-SSE-LABEL: TestFPTruncF128_F64:
+; WIN64-SSE:       # %bb.0: # %entry
+; WIN64-SSE-NEXT:    subq $56, %rsp
+; WIN64-SSE-NEXT:    movaps vf128(%rip), %xmm0
+; WIN64-SSE-NEXT:    movaps %xmm0, {{[0-9]+}}(%rsp)
+; WIN64-SSE-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-SSE-NEXT:    callq __trunctfdf2
+; WIN64-SSE-NEXT:    movsd %xmm0, vf64(%rip)
+; WIN64-SSE-NEXT:    addq $56, %rsp
+; WIN64-SSE-NEXT:    retq
+;
 ; X86-LABEL: TestFPTruncF128_F64:
 ; X86:       # %bb.0: # %entry
 ; X86-NEXT:    subl $12, %esp
@@ -597,6 +745,19 @@ define dso_local void @TestFPTruncF128_F80() nounwind {
 ; X64-SSE-NEXT:    popq %rax
 ; X64-SSE-NEXT:    retq
 ;
+; WIN64-SSE-LABEL: TestFPTruncF128_F80:
+; WIN64-SSE:       # %bb.0: # %entry
+; WIN64-SSE-NEXT:    subq $72, %rsp
+; WIN64-SSE-NEXT:    movaps vf128(%rip), %xmm0
+; WIN64-SSE-NEXT:    movaps %xmm0, {{[0-9]+}}(%rsp)
+; WIN64-SSE-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-SSE-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
+; WIN64-SSE-NEXT:    callq __trunctfxf2
+; WIN64-SSE-NEXT:    fldt {{[0-9]+}}(%rsp)
+; WIN64-SSE-NEXT:    fstpt vf80(%rip)
+; WIN64-SSE-NEXT:    addq $72, %rsp
+; WIN64-SSE-NEXT:    retq
+;
 ; X86-LABEL: TestFPTruncF128_F80:
 ; X86:       # %bb.0: # %entry
 ; X86-NEXT:    subl $12, %esp
@@ -635,6 +796,17 @@ define dso_local void @TestSIToFPI16_F128() nounwind {
 ; X64-SSE-NEXT:    popq %rax
 ; X64-SSE-NEXT:    retq
 ;
+; WIN64-SSE-LABEL: TestSIToFPI16_F128:
+; WIN64-SSE:       # %bb.0: # %entry
+; WIN64-SSE-NEXT:    subq $56, %rsp
+; WIN64-SSE-NEXT:    movswl vi16(%rip), %edx
+; WIN64-SSE-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-SSE-NEXT:    callq __floatsitf
+; WIN64-SSE-NEXT:    movaps {{[0-9]+}}(%rsp), %xmm0
+; WIN64-SSE-NEXT:    movaps %xmm0, vf128(%rip)
+; WIN64-SSE-NEXT:    addq $56, %rsp
+; WIN64-SSE-NEXT:    retq
+;
 ; X86-LABEL: TestSIToFPI16_F128:
 ; X86:       # %bb.0: # %entry
 ; X86-NEXT:    pushl %esi
@@ -683,6 +855,17 @@ define dso_local void @TestSIToFPU16_F128() nounwind {
 ; X64-SSE-NEXT:    popq %rax
 ; X64-SSE-NEXT:    retq
 ;
+; WIN64-SSE-LABEL: TestSIToFPU16_F128:
+; WIN64-SSE:       # %bb.0: # %entry
+; WIN64-SSE-NEXT:    subq $56, %rsp
+; WIN64-SSE-NEXT:    movzwl vi16(%rip), %edx
+; WIN64-SSE-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-SSE-NEXT:    callq __floatsitf
+; WIN64-SSE-NEXT:    movaps {{[0-9]+}}(%rsp), %xmm0
+; WIN64-SSE-NEXT:    movaps %xmm0, vf128(%rip)
+; WIN64-SSE-NEXT:    addq $56, %rsp
+; WIN64-SSE-NEXT:    retq
+;
 ; X86-LABEL: TestSIToFPU16_F128:
 ; X86:       # %bb.0: # %entry
 ; X86-NEXT:    pushl %esi
@@ -731,6 +914,17 @@ define dso_local void @TestSIToFPI32_F128() nounwind {
 ; X64-SSE-NEXT:    popq %rax
 ; X64-SSE-NEXT:    retq
 ;
+; WIN64-SSE-LABEL: TestSIToFPI32_F128:
+; WIN64-SSE:       # %bb.0: # %entry
+; WIN64-SSE-NEXT:    subq $56, %rsp
+; WIN64-SSE-NEXT:    movl vi32(%rip), %edx
+; WIN64-SSE-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-SSE-NEXT:    callq __floatsitf
+; WIN64-SSE-NEXT:    movaps {{[0-9]+}}(%rsp), %xmm0
+; WIN64-SSE-NEXT:    movaps %xmm0, vf128(%rip)
+; WIN64-SSE-NEXT:    addq $56, %rsp
+; WIN64-SSE-NEXT:    retq
+;
 ; X86-LABEL: TestSIToFPI32_F128:
 ; X86:       # %bb.0: # %entry
 ; X86-NEXT:    pushl %esi
@@ -777,6 +971,17 @@ define dso_local void @TestUIToFPU32_F128() #2 {
 ; X64-SSE-NEXT:    popq %rax
 ; X64-SSE-NEXT:    retq
 ;
+; WIN64-SSE-LABEL: TestUIToFPU32_F128:
+; WIN64-SSE:       # %bb.0: # %entry
+; WIN64-SSE-NEXT:    subq $56, %rsp
+; WIN64-SSE-NEXT:    movl vu32(%rip), %edx
+; WIN64-SSE-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-SSE-NEXT:    callq __floatunsitf
+; WIN64-SSE-NEXT:    movaps {{[0-9]+}}(%rsp), %xmm0
+; WIN64-SSE-NEXT:    movaps %xmm0, vf128(%rip)
+; WIN64-SSE-NEXT:    addq $56, %rsp
+; WIN64-SSE-NEXT:    retq
+;
 ; X86-LABEL: TestUIToFPU32_F128:
 ; X86:       # %bb.0: # %entry
 ; X86-NEXT:    pushl %esi
@@ -823,6 +1028,17 @@ define dso_local void @TestSIToFPI64_F128() nounwind {
 ; X64-SSE-NEXT:    popq %rax
 ; X64-SSE-NEXT:    retq
 ;
+; WIN64-SSE-LABEL: TestSIToFPI64_F128:
+; WIN64-SSE:       # %bb.0: # %entry
+; WIN64-SSE-NEXT:    subq $56, %rsp
+; WIN64-SSE-NEXT:    movq vi64(%rip), %rdx
+; WIN64-SSE-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-SSE-NEXT:    callq __floatditf
+; WIN64-SSE-NEXT:    movaps {{[0-9]+}}(%rsp), %xmm0
+; WIN64-SSE-NEXT:    movaps %xmm0, vf128(%rip)
+; WIN64-SSE-NEXT:    addq $56, %rsp
+; WIN64-SSE-NEXT:    retq
+;
 ; X86-LABEL: TestSIToFPI64_F128:
 ; X86:       # %bb.0: # %entry
 ; X86-NEXT:    pushl %esi
@@ -870,6 +1086,17 @@ define dso_local void @TestUIToFPU64_F128() #2 {
 ; X64-SSE-NEXT:    popq %rax
 ; X64-SSE-NEXT:    retq
 ;
+; WIN64-SSE-LABEL: TestUIToFPU64_F128:
+; WIN64-SSE:       # %bb.0: # %entry
+; WIN64-SSE-NEXT:    subq $56, %rsp
+; WIN64-SSE-NEXT:    movq vu64(%rip), %rdx
+; WIN64-SSE-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-SSE-NEXT:    callq __floatunditf
+; WIN64-SSE-NEXT:    movaps {{[0-9]+}}(%rsp), %xmm0
+; WIN64-SSE-NEXT:    movaps %xmm0, vf128(%rip)
+; WIN64-SSE-NEXT:    addq $56, %rsp
+; WIN64-SSE-NEXT:    retq
+;
 ; X86-LABEL: TestUIToFPU64_F128:
 ; X86:       # %bb.0: # %entry
 ; X86-NEXT:    pushl %esi
@@ -918,6 +1145,19 @@ define dso_local void @TestSIToFPI128_F128() nounwind {
 ; X64-SSE-NEXT:    popq %rax
 ; X64-SSE-NEXT:    retq
 ;
+; WIN64-SSE-LABEL: TestSIToFPI128_F128:
+; WIN64-SSE:       # %bb.0: # %entry
+; WIN64-SSE-NEXT:    subq $72, %rsp
+; WIN64-SSE-NEXT:    movaps vi128(%rip), %xmm0
+; WIN64-SSE-NEXT:    movaps %xmm0, {{[0-9]+}}(%rsp)
+; WIN64-SSE-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-SSE-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
+; WIN64-SSE-NEXT:    callq __floattitf
+; WIN64-SSE-NEXT:    movaps {{[0-9]+}}(%rsp), %xmm0
+; WIN64-SSE-NEXT:    movaps %xmm0, vf128(%rip)
+; WIN64-SSE-NEXT:    addq $72, %rsp
+; WIN64-SSE-NEXT:    retq
+;
 ; X86-LABEL: TestSIToFPI128_F128:
 ; X86:       # %bb.0: # %entry
 ; X86-NEXT:    pushl %esi
@@ -973,6 +1213,19 @@ define dso_local void @TestUIToFPU128_F128() #2 {
 ; X64-SSE-NEXT:    popq %rax
 ; X64-SSE-NEXT:    retq
 ;
+; WIN64-SSE-LABEL: TestUIToFPU128_F128:
+; WIN64-SSE:       # %bb.0: # %entry
+; WIN64-SSE-NEXT:    subq $72, %rsp
+; WIN64-SSE-NEXT:    movaps vu128(%rip), %xmm0
+; WIN64-SSE-NEXT:    movaps %xmm0, {{[0-9]+}}(%rsp)
+; WIN64-SSE-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-SSE-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
+; WIN64-SSE-NEXT:    callq __floatuntitf
+; WIN64-SSE-NEXT:    movaps {{[0-9]+}}(%rsp), %xmm0
+; WIN64-SSE-NEXT:    movaps %xmm0, vf128(%rip)
+; WIN64-SSE-NEXT:    addq $72, %rsp
+; WIN64-SSE-NEXT:    retq
+;
 ; X86-LABEL: TestUIToFPU128_F128:
 ; X86:       # %bb.0: # %entry
 ; X86-NEXT:    pushl %esi
@@ -1030,6 +1283,23 @@ define dso_local i32 @TestConst128(fp128 %v) nounwind {
 ; X64-SSE-NEXT:    popq %rcx
 ; X64-SSE-NEXT:    retq
 ;
+; WIN64-SSE-LABEL: TestConst128:
+; WIN64-SSE:       # %bb.0: # %entry
+; WIN64-SSE-NEXT:    subq $72, %rsp
+; WIN64-SSE-NEXT:    movaps (%rcx), %xmm0
+; WIN64-SSE-NEXT:    movaps {{.*#+}} xmm1 = [1.0E+0]
+; WIN64-SSE-NEXT:    movaps %xmm1, {{[0-9]+}}(%rsp)
+; WIN64-SSE-NEXT:    movaps %xmm0, {{[0-9]+}}(%rsp)
+; WIN64-SSE-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-SSE-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
+; WIN64-SSE-NEXT:    callq __gttf2
+; WIN64-SSE-NEXT:    xorl %ecx, %ecx
+; WIN64-SSE-NEXT:    testl %eax, %eax
+; WIN64-SSE-NEXT:    setg %cl
+; WIN64-SSE-NEXT:    movl %ecx, %eax
+; WIN64-SSE-NEXT:    addq $72, %rsp
+; WIN64-SSE-NEXT:    retq
+;
 ; X86-LABEL: TestConst128:
 ; X86:       # %bb.0: # %entry
 ; X86-NEXT:    subl $12, %esp
@@ -1081,6 +1351,23 @@ define dso_local i32 @TestConst128Zero(fp128 %v) nounwind {
 ; X64-SSE-NEXT:    popq %rcx
 ; X64-SSE-NEXT:    retq
 ;
+; WIN64-SSE-LABEL: TestConst128Zero:
+; WIN64-SSE:       # %bb.0: # %entry
+; WIN64-SSE-NEXT:    subq $72, %rsp
+; WIN64-SSE-NEXT:    movaps (%rcx), %xmm0
+; WIN64-SSE-NEXT:    xorps %xmm1, %xmm1
+; WIN64-SSE-NEXT:    movaps %xmm1, {{[0-9]+}}(%rsp)
+; WIN64-SSE-NEXT:    movaps %xmm0, {{[0-9]+}}(%rsp)
+; WIN64-SSE-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-SSE-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
+; WIN64-SSE-NEXT:    callq __gttf2
+; WIN64-SSE-NEXT:    xorl %ecx, %ecx
+; WIN64-SSE-NEXT:    testl %eax, %eax
+; WIN64-SSE-NEXT:    setg %cl
+; WIN64-SSE-NEXT:    movl %ecx, %eax
+; WIN64-SSE-NEXT:    addq $72, %rsp
+; WIN64-SSE-NEXT:    retq
+;
 ; X86-LABEL: TestConst128Zero:
 ; X86:       # %bb.0: # %entry
 ; X86-NEXT:    subl $12, %esp
@@ -1148,6 +1435,27 @@ define dso_local i32 @TestBits128(fp128 %ld) nounwind {
 ; X64-SSE-NEXT:    addq $24, %rsp
 ; X64-SSE-NEXT:    retq
 ;
+; WIN64-SSE-LABEL: TestBits128:
+; WIN64-SSE:       # %bb.0: # %entry
+; WIN64-SSE-NEXT:    subq $104, %rsp
+; WIN64-SSE-NEXT:    movaps (%rcx), %xmm0
+; WIN64-SSE-NEXT:    movaps %xmm0, {{[0-9]+}}(%rsp)
+; WIN64-SSE-NEXT:    movaps %xmm0, {{[0-9]+}}(%rsp)
+; WIN64-SSE-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-SSE-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
+; WIN64-SSE-NEXT:    leaq {{[0-9]+}}(%rsp), %r8
+; WIN64-SSE-NEXT:    callq __multf3
+; WIN64-SSE-NEXT:    movaps {{[0-9]+}}(%rsp), %xmm0
+; WIN64-SSE-NEXT:    movaps %xmm0, {{[0-9]+}}(%rsp)
+; WIN64-SSE-NEXT:    movq {{[0-9]+}}(%rsp), %rcx
+; WIN64-SSE-NEXT:    movq %rcx, %rdx
+; WIN64-SSE-NEXT:    shrq $32, %rdx
+; WIN64-SSE-NEXT:    xorl %eax, %eax
+; WIN64-SSE-NEXT:    orl %ecx, %edx
+; WIN64-SSE-NEXT:    sete %al
+; WIN64-SSE-NEXT:    addq $104, %rsp
+; WIN64-SSE-NEXT:    retq
+;
 ; X86-LABEL: TestBits128:
 ; X86:       # %bb.0: # %entry
 ; X86-NEXT:    pushl %esi
@@ -1225,6 +1533,15 @@ define fp128 @TestPair128(i64 %a, i64 %b) nounwind {
 ; X64-SSE-NEXT:    movaps -{{[0-9]+}}(%rsp), %xmm0
 ; X64-SSE-NEXT:    retq
 ;
+; WIN64-SSE-LABEL: TestPair128:
+; WIN64-SSE:       # %bb.0: # %entry
+; WIN64-SSE-NEXT:    movq %rcx, %rax
+; WIN64-SSE-NEXT:    addq $3, %r8
+; WIN64-SSE-NEXT:    adcq $0, %rdx
+; WIN64-SSE-NEXT:    movq %rdx, 8(%rcx)
+; WIN64-SSE-NEXT:    movq %r8, (%rcx)
+; WIN64-SSE-NEXT:    retq
+;
 ; X86-LABEL: TestPair128:
 ; X86:       # %bb.0: # %entry
 ; X86-NEXT:    pushl %edi
@@ -1279,6 +1596,31 @@ define fp128 @TestTruncCopysign(fp128 %x, i32 %n) nounwind {
 ; X64-SSE-NEXT:  .LBB26_2: # %cleanup
 ; X64-SSE-NEXT:    retq
 ;
+; WIN64-SSE-LABEL: TestTruncCopysign:
+; WIN64-SSE:       # %bb.0: # %entry
+; WIN64-SSE-NEXT:    pushq %rsi
+; WIN64-SSE-NEXT:    subq $64, %rsp
+; WIN64-SSE-NEXT:    movq %rcx, %rsi
+; WIN64-SSE-NEXT:    movaps (%rdx), %xmm0
+; WIN64-SSE-NEXT:    cmpl $50001, %r8d # imm = 0xC351
+; WIN64-SSE-NEXT:    jl .LBB26_2
+; WIN64-SSE-NEXT:  # %bb.1: # %if.then
+; WIN64-SSE-NEXT:    movaps %xmm0, {{[0-9]+}}(%rsp)
+; WIN64-SSE-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-SSE-NEXT:    callq __trunctfdf2
+; WIN64-SSE-NEXT:    andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; WIN64-SSE-NEXT:    orps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; WIN64-SSE-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-SSE-NEXT:    movaps %xmm0, %xmm1
+; WIN64-SSE-NEXT:    callq __extenddftf2
+; WIN64-SSE-NEXT:    movaps {{[0-9]+}}(%rsp), %xmm0
+; WIN64-SSE-NEXT:  .LBB26_2: # %cleanup
+; WIN64-SSE-NEXT:    movaps %xmm0, (%rsi)
+; WIN64-SSE-NEXT:    movq %rsi, %rax
+; WIN64-SSE-NEXT:    addq $64, %rsp
+; WIN64-SSE-NEXT:    popq %rsi
+; WIN64-SSE-NEXT:    retq
+;
 ; X86-LABEL: TestTruncCopysign:
 ; X86:       # %bb.0: # %entry
 ; X86-NEXT:    pushl %edi
@@ -1370,6 +1712,18 @@ define i1 @PR34866(i128 %x) nounwind {
 ; X64-SSE-NEXT:    sete %al
 ; X64-SSE-NEXT:    retq
 ;
+; WIN64-SSE-LABEL: PR34866:
+; WIN64-SSE:       # %bb.0:
+; WIN64-SSE-NEXT:    subq $24, %rsp
+; WIN64-SSE-NEXT:    xorps %xmm0, %xmm0
+; WIN64-SSE-NEXT:    movaps %xmm0, (%rsp)
+; WIN64-SSE-NEXT:    xorq {{[0-9]+}}(%rsp), %rdx
+; WIN64-SSE-NEXT:    xorq (%rsp), %rcx
+; WIN64-SSE-NEXT:    orq %rdx, %rcx
+; WIN64-SSE-NEXT:    sete %al
+; WIN64-SSE-NEXT:    addq $24, %rsp
+; WIN64-SSE-NEXT:    retq
+;
 ; X86-LABEL: PR34866:
 ; X86:       # %bb.0:
 ; X86-NEXT:    subl $12, %esp
@@ -1407,6 +1761,18 @@ define i1 @PR34866_commute(i128 %x) nounwind {
 ; X64-SSE-NEXT:    sete %al
 ; X64-SSE-NEXT:    retq
 ;
+; WIN64-SSE-LABEL: PR34866_commute:
+; WIN64-SSE:       # %bb.0:
+; WIN64-SSE-NEXT:    subq $24, %rsp
+; WIN64-SSE-NEXT:    xorps %xmm0, %xmm0
+; WIN64-SSE-NEXT:    movaps %xmm0, (%rsp)
+; WIN64-SSE-NEXT:    xorq {{[0-9]+}}(%rsp), %rdx
+; WIN64-SSE-NEXT:    xorq (%rsp), %rcx
+; WIN64-SSE-NEXT:    orq %rdx, %rcx
+; WIN64-SSE-NEXT:    sete %al
+; WIN64-SSE-NEXT:    addq $24, %rsp
+; WIN64-SSE-NEXT:    retq
+;
 ; X86-LABEL: PR34866_commute:
 ; X86:       # %bb.0:
 ; X86-NEXT:    subl $12, %esp


        


More information about the llvm-commits mailing list