[llvm] r248114 - [X86] Fix sitofp and uitofp instruction matching failures with long double and avx512
Michael Kuperstein via llvm-commits
llvm-commits at lists.llvm.org
Sun Sep 20 01:12:18 PDT 2015
Author: mkuper
Date: Sun Sep 20 03:12:17 2015
New Revision: 248114
URL: http://llvm.org/viewvc/llvm-project?rev=248114&view=rev
Log:
[X86] Fix sitofp and uitofp instruction matching failures with long double and avx512
The operation action for i32 and i64 cannot be set to legal, as long double
needs custom lowering.
Patch by: mitch.l.bodart at intel.com
Differential Revision: http://reviews.llvm.org/D12372
Added:
llvm/trunk/test/CodeGen/X86/scalar-int-to-fp.ll
Modified:
llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=248114&r1=248113&r2=248114&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Sun Sep 20 03:12:17 2015
@@ -164,14 +164,18 @@ X86TargetLowering::X86TargetLowering(con
setOperationAction(ISD::UINT_TO_FP , MVT::i16 , Promote);
if (Subtarget->is64Bit()) {
- setOperationAction(ISD::UINT_TO_FP , MVT::i32 , Promote);
+ if (!Subtarget->useSoftFloat() && Subtarget->hasAVX512())
+ // f32/f64 are legal, f80 is custom.
+ setOperationAction(ISD::UINT_TO_FP , MVT::i32 , Custom);
+ else
+ setOperationAction(ISD::UINT_TO_FP , MVT::i32 , Promote);
setOperationAction(ISD::UINT_TO_FP , MVT::i64 , Custom);
} else if (!Subtarget->useSoftFloat()) {
// We have an algorithm for SSE2->double, and we turn this into a
// 64-bit FILD followed by conditional FADD for other targets.
setOperationAction(ISD::UINT_TO_FP , MVT::i64 , Custom);
// We have an algorithm for SSE2, and we turn this into a 64-bit
- // FILD for other targets.
+ // FILD or VCVTUSI2SS/SD for other targets.
setOperationAction(ISD::UINT_TO_FP , MVT::i32 , Custom);
}
@@ -1353,13 +1357,6 @@ X86TargetLowering::X86TargetLowering(con
setOperationAction(ISD::FMA, MVT::v8f64, Legal);
setOperationAction(ISD::FMA, MVT::v16f32, Legal);
- // FIXME: [US]INT_TO_FP are not legal for f80.
- setOperationAction(ISD::SINT_TO_FP, MVT::i32, Legal);
- setOperationAction(ISD::UINT_TO_FP, MVT::i32, Legal);
- if (Subtarget->is64Bit()) {
- setOperationAction(ISD::SINT_TO_FP, MVT::i64, Legal);
- setOperationAction(ISD::UINT_TO_FP, MVT::i64, Legal);
- }
setOperationAction(ISD::FP_TO_SINT, MVT::v16i32, Legal);
setOperationAction(ISD::FP_TO_UINT, MVT::v16i32, Legal);
setOperationAction(ISD::FP_TO_UINT, MVT::v8i32, Legal);
@@ -12516,6 +12513,14 @@ SDValue X86TargetLowering::LowerUINT_TO_
MVT SrcVT = N0.getSimpleValueType();
MVT DstVT = Op.getSimpleValueType();
+
+ if (Subtarget->hasAVX512() && isScalarFPTypeInSSEReg(DstVT) &&
+ (SrcVT == MVT::i32 || (SrcVT == MVT::i64 && Subtarget->is64Bit()))) {
+ // Conversions from unsigned i32 to f32/f64 are legal,
+ // using VCVTUSI2SS/SD. Same for i64 in 64-bit mode.
+ return Op;
+ }
+
if (SrcVT == MVT::i64 && DstVT == MVT::f64 && X86ScalarSSEf64)
return LowerUINT_TO_FP_i64(Op, DAG);
if (SrcVT == MVT::i32 && X86ScalarSSEf64)
Added: llvm/trunk/test/CodeGen/X86/scalar-int-to-fp.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/scalar-int-to-fp.ll?rev=248114&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/scalar-int-to-fp.ll (added)
+++ llvm/trunk/test/CodeGen/X86/scalar-int-to-fp.ll Sun Sep 20 03:12:17 2015
@@ -0,0 +1,132 @@
+; Verify that scalar integer conversions to FP compile successfully
+; (at one time long double failed with avx512f), and that reasonable
+; instruction sequences are selected based on subtarget features.
+; Due to the plethora of reasonable sequences we just check for
+; one key instruction, usually a cvt or fild, allowing the test
+; to be relatively easily updated when sequences are improved.
+;
+; RUN: llc < %s -mtriple=i386-unknown-unknown -mattr=+avx512f | FileCheck %s --check-prefix=CHECK --check-prefix=AVX512_32
+; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx512f | FileCheck %s --check-prefix=CHECK --check-prefix=AVX512_64
+; RUN: llc < %s -mtriple=i386-unknown-unknown -mattr=+sse2 | FileCheck %s --check-prefix=CHECK --check-prefix=SSE2_32
+; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse2 | FileCheck %s --check-prefix=CHECK --check-prefix=SSE2_64
+; RUN: llc < %s -mtriple=i386-unknown-unknown -mattr=-sse | FileCheck %s --check-prefix=CHECK --check-prefix=X87
+
+; CHECK-LABEL: u32_to_f
+; AVX512_32: vcvtusi2ssl
+; AVX512_64: vcvtusi2ssl
+; SSE2_32: cvtsd2ss
+; SSE2_64: cvtsi2ssq
+; X87: fildll
+define float @u32_to_f(i32 %a) nounwind {
+ %r = uitofp i32 %a to float
+ ret float %r
+}
+
+; CHECK-LABEL: s32_to_f
+; AVX512_32: vcvtsi2ssl
+; AVX512_64: vcvtsi2ssl
+; SSE2_32: cvtsi2ssl
+; SSE2_64: cvtsi2ssl
+; X87: fildl
+define float @s32_to_f(i32 %a) nounwind {
+ %r = sitofp i32 %a to float
+ ret float %r
+}
+
+; CHECK-LABEL: u32_to_d
+; AVX512_32: vcvtusi2sdl
+; AVX512_64: vcvtusi2sdl
+; SSE2_32: subsd
+; SSE2_64: cvtsi2sdq
+; X87: fildll
+define double @u32_to_d(i32 %a) nounwind {
+ %r = uitofp i32 %a to double
+ ret double %r
+}
+
+; CHECK-LABEL: s32_to_d
+; AVX512_32: vcvtsi2sdl
+; AVX512_64: vcvtsi2sdl
+; SSE2_32: cvtsi2sdl
+; SSE2_64: cvtsi2sdl
+; X87: fildl
+define double @s32_to_d(i32 %a) nounwind {
+ %r = sitofp i32 %a to double
+ ret double %r
+}
+
+; CHECK-LABEL: u32_to_x
+; AVX512_32: vsubsd
+; AVX512_64: vsubsd
+; SSE2_32: subsd
+; SSE2_64: fildll
+; X87: fildll
+define x86_fp80 @u32_to_x(i32 %a) nounwind {
+ %r = uitofp i32 %a to x86_fp80
+ ret x86_fp80 %r
+}
+
+; CHECK-LABEL: s32_to_x
+; CHECK: fildl
+define x86_fp80 @s32_to_x(i32 %a) nounwind {
+ %r = sitofp i32 %a to x86_fp80
+ ret x86_fp80 %r
+}
+
+; CHECK-LABEL: u64_to_f
+; AVX512_32: fildll
+; AVX512_64: vcvtusi2ssq
+; SSE2_32: fildll
+; SSE2_64: cvtsi2ssq
+; X87: fildll
+define float @u64_to_f(i64 %a) nounwind {
+ %r = uitofp i64 %a to float
+ ret float %r
+}
+
+; CHECK-LABEL: s64_to_f
+; AVX512_32: fildll
+; AVX512_64: vcvtsi2ssq
+; SSE2_32: fildll
+; SSE2_64: cvtsi2ssq
+; X87: fildll
+define float @s64_to_f(i64 %a) nounwind {
+ %r = sitofp i64 %a to float
+ ret float %r
+}
+
+; CHECK-LABEL: u64_to_d
+; AVX512_32: vpunpckldq
+; AVX512_64: vcvtusi2sdq
+; SSE2_32: punpckldq
+; SSE2_64: punpckldq
+; X87: fildll
+define double @u64_to_d(i64 %a) nounwind {
+ %r = uitofp i64 %a to double
+ ret double %r
+}
+
+; CHECK-LABEL: s64_to_d
+; AVX512_32: fildll
+; AVX512_64: vcvtsi2sdq
+; SSE2_32: fildll
+; SSE2_64: cvtsi2sdq
+; X87: fildll
+define double @s64_to_d(i64 %a) nounwind {
+ %r = sitofp i64 %a to double
+ ret double %r
+}
+
+; CHECK-LABEL: u64_to_x
+; CHECK: fildll
+define x86_fp80 @u64_to_x(i64 %a) nounwind {
+ %r = uitofp i64 %a to x86_fp80
+ ret x86_fp80 %r
+}
+
+; CHECK-LABEL: s64_to_x
+; CHECK: fildll
+define x86_fp80 @s64_to_x(i64 %a) nounwind {
+ %r = sitofp i64 %a to x86_fp80
+ ret x86_fp80 %r
+}
More information about the llvm-commits
mailing list