[X86][Windows] use LowerWin64_INT128_TO_FP for u128 to f128 conversion#207285
Conversation
| ; 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 |
There was a problem hiding this comment.
This generated code is now equivalent to the signed version
--- <unnamed>
+++ <unnamed>
@@ -1,11 +1,11 @@
-; WIN64-SSE-LABEL: TestSIToFPI128_F128:
+; WIN64-SSE-LABEL: TestUIToFPU128_F128:
; WIN64-SSE: # %bb.0: # %entry
; WIN64-SSE-NEXT: subq $72, %rsp
-; WIN64-SSE-NEXT: movaps vi128(%rip), %xmm0
+; 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 __floattitf
+; 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|
@llvm/pr-subscribers-backend-x86 Author: Folkert de Vries (folkertdev) ChangesThis change fixes an ABI issue where the signed conversion passes a https://godbolt.org/z/x3daY3rej --- <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
retThe 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 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 Patch is 22.80 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/207285.diff 2 Files Affected:
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 97a406d176a55..b4352527b3cc1 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -21439,32 +21439,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-LA...
[truncated]
|
…version (llvm#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 llvm#204887.
…version (#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 #204887.
This change fixes an ABI issue where the signed conversion passes a
i128different from au128, and crucially different from GCC.https://godbolt.org/z/x3daY3rej
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_FPto be more likeLowerSINT_TO_FP. In particular this moves the "Bail out when we don't have native conversion instructions." down a bit, so thatLowerWin64_INT128_TO_FPis 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-builtinstests with a build that includes #204887.