[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