[llvm] [X86] Faster truncf and roundf on x86 SSE2 (PR #226513)

Divyansh Yadav via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 28 02:47:09 PDT 2026


https://github.com/schizophrenicmaniac updated https://github.com/llvm/llvm-project/pull/226513

>From a4052e43b8ab162e4cd2f9a9a444317ce45ff0a3 Mon Sep 17 00:00:00 2001
From: Divyansh <anshmcs at gmail.com>
Date: Fri, 25 Sep 2026 20:20:38 +0530
Subject: [PATCH 1/8] [X86] Faster truncf and roundf on x86 SSE2

---
 llvm/lib/Target/X86/X86ISelLowering.cpp       |  68 ++-
 llvm/test/Analysis/CostModel/X86/fround.ll    |  18 +-
 llvm/test/CodeGen/X86/fp-round.ll             | 539 ++++++++++--------
 llvm/test/CodeGen/X86/fp16-libcalls.ll        |  35 +-
 llvm/test/CodeGen/X86/freeze-unary.ll         |  41 +-
 llvm/test/CodeGen/X86/ftrunc.ll               | 359 +++++++-----
 llvm/test/CodeGen/X86/isel-ftrunc.ll          |  59 +-
 llvm/test/CodeGen/X86/isint.ll                |  96 +++-
 llvm/test/CodeGen/X86/llround-conv.ll         |  32 +-
 llvm/test/CodeGen/X86/lround-conv-i32.ll      |  41 +-
 llvm/test/CodeGen/X86/lround-conv-i64.ll      |  16 +-
 llvm/test/CodeGen/X86/unpredictable-brcond.ll |  29 +-
 .../Transforms/SLPVectorizer/X86/fround.ll    | 168 ++----
 13 files changed, 905 insertions(+), 596 deletions(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index e2f3b5f3cd3d5..c819efa95a515 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -632,6 +632,11 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
     setLoadExtAction(ISD::EXTLOAD, MVT::f64, MVT::f32, Expand);
 
     for (auto VT : { MVT::f32, MVT::f64 }) {
+      if (VT == MVT::f32 || Subtarget.is64Bit()) {
+        setOperationAction(ISD::FTRUNC, VT, Custom);
+        setOperationAction(ISD::FROUND, VT, Custom);
+      }
+
       // Use ANDPD to simulate FABS.
       setOperationAction(ISD::FABS, VT, Custom);
 
@@ -1096,6 +1101,13 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
     for (auto VT : { MVT::f64, MVT::v4f32, MVT::v2f64 })
       SetFPMinMaxAction(VT);
 
+    for (auto VT : { MVT::v4f32, MVT::v2f64 }) {
+      if (VT == MVT::v4f32 || Subtarget.is64Bit()) {
+        setOperationAction(ISD::FTRUNC, VT, Custom);
+        setOperationAction(ISD::FROUND, VT, Custom);
+      }
+    }
+
     setOperationAction(ISD::MUL,                MVT::v2i8,  Custom);
     setOperationAction(ISD::MUL,                MVT::v4i8,  Custom);
     setOperationAction(ISD::MUL,                MVT::v8i8,  Custom);
@@ -23178,6 +23190,51 @@ SDValue X86TargetLowering::lowerFaddFsub(SDValue Op, SelectionDAG &DAG) const {
   return lowerAddSubToHorizontalOp(Op, SDLoc(Op), DAG, Subtarget);
 }
 
+static SDValue lowerFTRUNC_FROUND_SSE2(SDValue Op, SelectionDAG &DAG) {
+  SDLoc DL(Op);
+  SDValue N0 = Op.getOperand(0);
+  MVT VT = Op.getSimpleValueType();
+  bool IsRound = Op.getOpcode() == ISD::FROUND;
+
+  SDValue Abs = DAG.getNode(ISD::FABS, DL, VT, N0);
+  SDValue AbsBiased = Abs;
+  if (IsRound) {
+    const fltSemantics &Sem = VT.getFltSemantics();
+    APFloat Bias = APFloat(0.5f);
+    bool Ignored;
+    Bias.convert(Sem, APFloat::rmNearestTiesToEven, &Ignored);
+    Bias.next(/*nextDown*/true);
+    AbsBiased = DAG.getNode(ISD::FADD, DL, VT, Abs, DAG.getConstantFP(Bias, DL, VT));
+  }
+
+  MVT IntVT;
+  if (VT == MVT::f32) IntVT = MVT::i32;
+  else if (VT == MVT::f64) IntVT = MVT::i64;
+  else if (VT == MVT::v4f32) IntVT = MVT::v4i32;
+  else if (VT == MVT::v2f64) IntVT = MVT::v2i64;
+  else llvm_unreachable("Unexpected type");
+
+  SDValue AbsInt = DAG.getBitcast(IntVT, Abs);
+
+  SDValue Threshold;
+  if (VT.getScalarType() == MVT::f32) {
+    Threshold = DAG.getConstant(0x4EFFFFFF, DL, IntVT);
+  } else {
+    Threshold = DAG.getConstant(0x432FFFFFFFFFFFFFULL, DL, IntVT);
+  }
+
+  EVT CCVT = DAG.getTargetLoweringInfo().getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), IntVT);
+  SDValue IsLarge = DAG.getSetCC(DL, CCVT, AbsInt, Threshold, ISD::SETGT);
+
+  SDValue TruncInt = DAG.getNode(ISD::FP_TO_SINT, DL, IntVT, AbsBiased);
+  SDValue AbsTrunc = DAG.getNode(ISD::SINT_TO_FP, DL, VT, TruncInt);
+
+  SDValue Trunc = DAG.getNode(ISD::FCOPYSIGN, DL, VT, AbsTrunc, N0);
+
+  unsigned SelOpc = VT.isVector() ? ISD::VSELECT : ISD::SELECT;
+  return DAG.getNode(SelOpc, DL, VT, IsLarge, N0, Trunc);
+}
+
 /// ISD::FROUND is defined to round to nearest with ties rounding away from 0.
 /// This mode isn't supported in hardware on X86. But as long as we aren't
 /// compiling with trapping math, we can emulate this with
@@ -34849,7 +34906,16 @@ SDValue X86TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
   case ISD::STORE:              return LowerStore(Op, Subtarget, DAG);
   case ISD::FADD:
   case ISD::FSUB:               return lowerFaddFsub(Op, DAG);
-  case ISD::FROUND:             return LowerFROUND(Op, DAG);
+  case ISD::FTRUNC:
+  case ISD::FROUND: {
+    MVT VT = Op.getSimpleValueType();
+    if (Subtarget.hasSSE2() && !Subtarget.hasSSE41() &&
+        (VT == MVT::f32 || VT == MVT::v4f32 || Subtarget.is64Bit()))
+      return lowerFTRUNC_FROUND_SSE2(Op, DAG);
+    if (Op.getOpcode() == ISD::FROUND)
+      return LowerFROUND(Op, DAG);
+    return SDValue();
+  }
   case ISD::FABS:
   case ISD::FNEG:               return LowerFABSorFNEG(Op, DAG);
   case ISD::FCOPYSIGN:          return LowerFCOPYSIGN(Op, DAG);
diff --git a/llvm/test/Analysis/CostModel/X86/fround.ll b/llvm/test/Analysis/CostModel/X86/fround.ll
index ed7965af202d9..e40319462b116 100644
--- a/llvm/test/Analysis/CostModel/X86/fround.ll
+++ b/llvm/test/Analysis/CostModel/X86/fround.ll
@@ -267,15 +267,15 @@ define i32 @rint(i32 %arg) {
 
 define i32 @trunc(i32 %arg) {
 ; SSE2-LABEL: 'trunc'
-; SSE2-NEXT:  Cost Model: Found an estimated cost of 10 for instruction: %F32 = call float @llvm.trunc.f32(float undef)
-; SSE2-NEXT:  Cost Model: Found an estimated cost of 21 for instruction: %V2F32 = call <2 x float> @llvm.trunc.v2f32(<2 x float> undef)
-; SSE2-NEXT:  Cost Model: Found an estimated cost of 43 for instruction: %V4F32 = call <4 x float> @llvm.trunc.v4f32(<4 x float> undef)
-; SSE2-NEXT:  Cost Model: Found an estimated cost of 86 for instruction: %V8F32 = call <8 x float> @llvm.trunc.v8f32(<8 x float> undef)
-; SSE2-NEXT:  Cost Model: Found an estimated cost of 172 for instruction: %V16F32 = call <16 x float> @llvm.trunc.v16f32(<16 x float> undef)
-; SSE2-NEXT:  Cost Model: Found an estimated cost of 10 for instruction: %F64 = call double @llvm.trunc.f64(double undef)
-; SSE2-NEXT:  Cost Model: Found an estimated cost of 21 for instruction: %V2F64 = call <2 x double> @llvm.trunc.v2f64(<2 x double> undef)
-; SSE2-NEXT:  Cost Model: Found an estimated cost of 42 for instruction: %V4F64 = call <4 x double> @llvm.trunc.v4f64(<4 x double> undef)
-; SSE2-NEXT:  Cost Model: Found an estimated cost of 84 for instruction: %V8F64 = call <8 x double> @llvm.trunc.v8f64(<8 x double> undef)
+; SSE2-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %F32 = call float @llvm.trunc.f32(float undef)
+; SSE2-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %V2F32 = call <2 x float> @llvm.trunc.v2f32(<2 x float> undef)
+; SSE2-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %V4F32 = call <4 x float> @llvm.trunc.v4f32(<4 x float> undef)
+; SSE2-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: %V8F32 = call <8 x float> @llvm.trunc.v8f32(<8 x float> undef)
+; SSE2-NEXT:  Cost Model: Found an estimated cost of 8 for instruction: %V16F32 = call <16 x float> @llvm.trunc.v16f32(<16 x float> undef)
+; SSE2-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %F64 = call double @llvm.trunc.f64(double undef)
+; SSE2-NEXT:  Cost Model: Found an estimated cost of 2 for instruction: %V2F64 = call <2 x double> @llvm.trunc.v2f64(<2 x double> undef)
+; SSE2-NEXT:  Cost Model: Found an estimated cost of 4 for instruction: %V4F64 = call <4 x double> @llvm.trunc.v4f64(<4 x double> undef)
+; SSE2-NEXT:  Cost Model: Found an estimated cost of 8 for instruction: %V8F64 = call <8 x double> @llvm.trunc.v8f64(<8 x double> undef)
 ; SSE2-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: ret i32 undef
 ;
 ; SSE42-LABEL: 'trunc'
diff --git a/llvm/test/CodeGen/X86/fp-round.ll b/llvm/test/CodeGen/X86/fp-round.ll
index 8595b63fc8107..145a922e12b9e 100644
--- a/llvm/test/CodeGen/X86/fp-round.ll
+++ b/llvm/test/CodeGen/X86/fp-round.ll
@@ -11,7 +11,21 @@ define half @round_f16(half %h) {
 ; SSE2-NEXT:    pushq %rax
 ; SSE2-NEXT:    .cfi_def_cfa_offset 16
 ; SSE2-NEXT:    callq __extendhfsf2 at PLT
-; SSE2-NEXT:    callq roundf at PLT
+; SSE2-NEXT:    movdqa {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
+; SSE2-NEXT:    movdqa %xmm0, %xmm2
+; SSE2-NEXT:    pand %xmm1, %xmm2
+; SSE2-NEXT:    movd %xmm2, %eax
+; SSE2-NEXT:    cmpl $1325400064, %eax # imm = 0x4F000000
+; SSE2-NEXT:    jge .LBB0_2
+; SSE2-NEXT:  # %bb.1: # %entry
+; SSE2-NEXT:    addss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
+; SSE2-NEXT:    cvttps2dq %xmm2, %xmm2
+; SSE2-NEXT:    cvtdq2ps %xmm2, %xmm2
+; SSE2-NEXT:    andps %xmm1, %xmm2
+; SSE2-NEXT:    pandn %xmm0, %xmm1
+; SSE2-NEXT:    por %xmm2, %xmm1
+; SSE2-NEXT:    movdqa %xmm1, %xmm0
+; SSE2-NEXT:  .LBB0_2: # %entry
 ; SSE2-NEXT:    callq __truncsfhf2 at PLT
 ; SSE2-NEXT:    popq %rax
 ; SSE2-NEXT:    .cfi_def_cfa_offset 8
@@ -74,7 +88,22 @@ entry:
 define float @round_f32(float %x) {
 ; SSE2-LABEL: round_f32:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    jmp roundf at PLT # TAILCALL
+; SSE2-NEXT:    movdqa {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
+; SSE2-NEXT:    movdqa %xmm0, %xmm2
+; SSE2-NEXT:    pand %xmm1, %xmm2
+; SSE2-NEXT:    movd %xmm2, %eax
+; SSE2-NEXT:    cmpl $1325400064, %eax # imm = 0x4F000000
+; SSE2-NEXT:    jge .LBB1_2
+; SSE2-NEXT:  # %bb.1:
+; SSE2-NEXT:    addss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
+; SSE2-NEXT:    cvttps2dq %xmm2, %xmm2
+; SSE2-NEXT:    cvtdq2ps %xmm2, %xmm2
+; SSE2-NEXT:    andps %xmm1, %xmm2
+; SSE2-NEXT:    pandn %xmm0, %xmm1
+; SSE2-NEXT:    por %xmm2, %xmm1
+; SSE2-NEXT:    movdqa %xmm1, %xmm0
+; SSE2-NEXT:  .LBB1_2:
+; SSE2-NEXT:    retq
 ;
 ; SSE41-LABEL: round_f32:
 ; SSE41:       # %bb.0:
@@ -117,7 +146,24 @@ define float @round_f32(float %x) {
 define double @round_f64(double %x) {
 ; SSE2-LABEL: round_f64:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    jmp round at PLT # TAILCALL
+; SSE2-NEXT:    movdqa {{.*#+}} xmm1 = [NaN,NaN]
+; SSE2-NEXT:    movdqa %xmm0, %xmm2
+; SSE2-NEXT:    pand %xmm1, %xmm2
+; SSE2-NEXT:    movq %xmm2, %rax
+; SSE2-NEXT:    movabsq $4841369599423283199, %rcx # imm = 0x432FFFFFFFFFFFFF
+; SSE2-NEXT:    cmpq %rcx, %rax
+; SSE2-NEXT:    jg .LBB2_2
+; SSE2-NEXT:  # %bb.1:
+; SSE2-NEXT:    addsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
+; SSE2-NEXT:    cvttsd2si %xmm2, %rax
+; SSE2-NEXT:    xorps %xmm2, %xmm2
+; SSE2-NEXT:    cvtsi2sd %rax, %xmm2
+; SSE2-NEXT:    andpd %xmm1, %xmm2
+; SSE2-NEXT:    pandn %xmm0, %xmm1
+; SSE2-NEXT:    por %xmm2, %xmm1
+; SSE2-NEXT:    movdqa %xmm1, %xmm0
+; SSE2-NEXT:  .LBB2_2:
+; SSE2-NEXT:    retq
 ;
 ; SSE41-LABEL: round_f64:
 ; SSE41:       # %bb.0:
@@ -161,31 +207,20 @@ define double @round_f64(double %x) {
 define <4 x float> @round_v4f32(<4 x float> %x) {
 ; SSE2-LABEL: round_v4f32:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    subq $56, %rsp
-; SSE2-NEXT:    .cfi_def_cfa_offset 64
-; SSE2-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
-; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[3,3,3,3]
-; SSE2-NEXT:    callq roundf at PLT
-; SSE2-NEXT:    movaps %xmm0, (%rsp) # 16-byte Spill
-; SSE2-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
-; SSE2-NEXT:    movhlps {{.*#+}} xmm0 = xmm0[1,1]
-; SSE2-NEXT:    callq roundf at PLT
-; SSE2-NEXT:    unpcklps (%rsp), %xmm0 # 16-byte Folded Reload
-; SSE2-NEXT:    # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
-; SSE2-NEXT:    movaps %xmm0, (%rsp) # 16-byte Spill
-; SSE2-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
-; SSE2-NEXT:    callq roundf at PLT
-; SSE2-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
-; SSE2-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
-; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,1,1,1]
-; SSE2-NEXT:    callq roundf at PLT
-; SSE2-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
-; SSE2-NEXT:    unpcklps {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
-; SSE2-NEXT:    unpcklpd (%rsp), %xmm1 # 16-byte Folded Reload
-; SSE2-NEXT:    # xmm1 = xmm1[0],mem[0]
-; SSE2-NEXT:    movaps %xmm1, %xmm0
-; SSE2-NEXT:    addq $56, %rsp
-; SSE2-NEXT:    .cfi_def_cfa_offset 8
+; SSE2-NEXT:    movaps {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
+; SSE2-NEXT:    movaps %xmm0, %xmm2
+; SSE2-NEXT:    andps %xmm1, %xmm2
+; SSE2-NEXT:    movaps {{.*#+}} xmm3 = [4.9999997E-1,4.9999997E-1,4.9999997E-1,4.9999997E-1]
+; SSE2-NEXT:    addps %xmm2, %xmm3
+; SSE2-NEXT:    cvttps2dq %xmm3, %xmm3
+; SSE2-NEXT:    cvtdq2ps %xmm3, %xmm3
+; SSE2-NEXT:    andps %xmm1, %xmm3
+; SSE2-NEXT:    andnps %xmm0, %xmm1
+; SSE2-NEXT:    orps %xmm1, %xmm3
+; SSE2-NEXT:    pcmpgtd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
+; SSE2-NEXT:    andps %xmm2, %xmm0
+; SSE2-NEXT:    andnps %xmm3, %xmm2
+; SSE2-NEXT:    orps %xmm2, %xmm0
 ; SSE2-NEXT:    retq
 ;
 ; SSE41-LABEL: round_v4f32:
@@ -227,19 +262,25 @@ define <4 x float> @round_v4f32(<4 x float> %x) {
 define <2 x double> @round_v2f64(<2 x double> %x) {
 ; SSE2-LABEL: round_v2f64:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    subq $40, %rsp
-; SSE2-NEXT:    .cfi_def_cfa_offset 48
-; SSE2-NEXT:    movaps %xmm0, (%rsp) # 16-byte Spill
-; SSE2-NEXT:    callq round at PLT
-; SSE2-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
-; SSE2-NEXT:    movaps (%rsp), %xmm0 # 16-byte Reload
-; SSE2-NEXT:    movhlps {{.*#+}} xmm0 = xmm0[1,1]
-; SSE2-NEXT:    callq round at PLT
-; SSE2-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
-; SSE2-NEXT:    movlhps {{.*#+}} xmm1 = xmm1[0],xmm0[0]
-; SSE2-NEXT:    movaps %xmm1, %xmm0
-; SSE2-NEXT:    addq $40, %rsp
-; SSE2-NEXT:    .cfi_def_cfa_offset 8
+; SSE2-NEXT:    movdqa {{.*#+}} xmm1 = [NaN,NaN]
+; SSE2-NEXT:    movdqa %xmm0, %xmm2
+; SSE2-NEXT:    pand %xmm1, %xmm2
+; SSE2-NEXT:    pshufd {{.*#+}} xmm3 = xmm2[1,1,3,3]
+; SSE2-NEXT:    addpd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
+; SSE2-NEXT:    cvttsd2si %xmm2, %rax
+; SSE2-NEXT:    cvtsi2sd %rax, %xmm4
+; SSE2-NEXT:    unpckhpd {{.*#+}} xmm2 = xmm2[1,1]
+; SSE2-NEXT:    cvttsd2si %xmm2, %rax
+; SSE2-NEXT:    xorps %xmm2, %xmm2
+; SSE2-NEXT:    cvtsi2sd %rax, %xmm2
+; SSE2-NEXT:    unpcklpd {{.*#+}} xmm4 = xmm4[0],xmm2[0]
+; SSE2-NEXT:    andpd %xmm1, %xmm4
+; SSE2-NEXT:    pandn %xmm0, %xmm1
+; SSE2-NEXT:    por %xmm4, %xmm1
+; SSE2-NEXT:    pcmpgtd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm3
+; SSE2-NEXT:    pand %xmm3, %xmm0
+; SSE2-NEXT:    pandn %xmm1, %xmm3
+; SSE2-NEXT:    por %xmm3, %xmm0
 ; SSE2-NEXT:    retq
 ;
 ; SSE41-LABEL: round_v2f64:
@@ -281,53 +322,35 @@ define <2 x double> @round_v2f64(<2 x double> %x) {
 define <8 x float> @round_v8f32(<8 x float> %x) {
 ; SSE2-LABEL: round_v8f32:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    subq $72, %rsp
-; SSE2-NEXT:    .cfi_def_cfa_offset 80
-; SSE2-NEXT:    movaps %xmm1, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
-; SSE2-NEXT:    movaps %xmm0, (%rsp) # 16-byte Spill
-; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[3,3,3,3]
-; SSE2-NEXT:    callq roundf at PLT
-; SSE2-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
-; SSE2-NEXT:    movaps (%rsp), %xmm0 # 16-byte Reload
-; SSE2-NEXT:    movhlps {{.*#+}} xmm0 = xmm0[1,1]
-; SSE2-NEXT:    callq roundf at PLT
-; SSE2-NEXT:    unpcklps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Folded Reload
-; SSE2-NEXT:    # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
-; SSE2-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
-; SSE2-NEXT:    movaps (%rsp), %xmm0 # 16-byte Reload
-; SSE2-NEXT:    callq roundf at PLT
-; SSE2-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
-; SSE2-NEXT:    movaps (%rsp), %xmm0 # 16-byte Reload
-; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,1,1,1]
-; SSE2-NEXT:    callq roundf at PLT
-; SSE2-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
-; SSE2-NEXT:    unpcklps {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
-; SSE2-NEXT:    unpcklpd {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Folded Reload
-; SSE2-NEXT:    # xmm1 = xmm1[0],mem[0]
-; SSE2-NEXT:    movaps %xmm1, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
-; SSE2-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
-; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[3,3,3,3]
-; SSE2-NEXT:    callq roundf at PLT
-; SSE2-NEXT:    movaps %xmm0, (%rsp) # 16-byte Spill
-; SSE2-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
-; SSE2-NEXT:    movhlps {{.*#+}} xmm0 = xmm0[1,1]
-; SSE2-NEXT:    callq roundf at PLT
-; SSE2-NEXT:    unpcklps (%rsp), %xmm0 # 16-byte Folded Reload
-; SSE2-NEXT:    # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
-; SSE2-NEXT:    movaps %xmm0, (%rsp) # 16-byte Spill
-; SSE2-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
-; SSE2-NEXT:    callq roundf at PLT
-; SSE2-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
-; SSE2-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
-; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,1,1,1]
-; SSE2-NEXT:    callq roundf at PLT
-; SSE2-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
-; SSE2-NEXT:    unpcklps {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
-; SSE2-NEXT:    unpcklpd (%rsp), %xmm1 # 16-byte Folded Reload
-; SSE2-NEXT:    # xmm1 = xmm1[0],mem[0]
-; SSE2-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
-; SSE2-NEXT:    addq $72, %rsp
-; SSE2-NEXT:    .cfi_def_cfa_offset 8
+; SSE2-NEXT:    movaps {{.*#+}} xmm3 = [NaN,NaN,NaN,NaN]
+; SSE2-NEXT:    movaps %xmm0, %xmm2
+; SSE2-NEXT:    andps %xmm3, %xmm2
+; SSE2-NEXT:    movaps {{.*#+}} xmm4 = [4.9999997E-1,4.9999997E-1,4.9999997E-1,4.9999997E-1]
+; SSE2-NEXT:    movaps %xmm2, %xmm5
+; SSE2-NEXT:    addps %xmm4, %xmm5
+; SSE2-NEXT:    cvttps2dq %xmm5, %xmm5
+; SSE2-NEXT:    cvtdq2ps %xmm5, %xmm5
+; SSE2-NEXT:    andps %xmm3, %xmm5
+; SSE2-NEXT:    movaps %xmm3, %xmm6
+; SSE2-NEXT:    movaps %xmm1, %xmm7
+; SSE2-NEXT:    andps %xmm3, %xmm7
+; SSE2-NEXT:    addps %xmm7, %xmm4
+; SSE2-NEXT:    cvttps2dq %xmm4, %xmm4
+; SSE2-NEXT:    cvtdq2ps %xmm4, %xmm4
+; SSE2-NEXT:    andps %xmm3, %xmm4
+; SSE2-NEXT:    andnps %xmm0, %xmm3
+; SSE2-NEXT:    orps %xmm3, %xmm5
+; SSE2-NEXT:    movdqa {{.*#+}} xmm3 = [1325400063,1325400063,1325400063,1325400063]
+; SSE2-NEXT:    pcmpgtd %xmm3, %xmm2
+; SSE2-NEXT:    andps %xmm2, %xmm0
+; SSE2-NEXT:    andnps %xmm5, %xmm2
+; SSE2-NEXT:    orps %xmm2, %xmm0
+; SSE2-NEXT:    andnps %xmm1, %xmm6
+; SSE2-NEXT:    orps %xmm6, %xmm4
+; SSE2-NEXT:    pcmpgtd %xmm3, %xmm7
+; SSE2-NEXT:    andps %xmm7, %xmm1
+; SSE2-NEXT:    andnps %xmm4, %xmm7
+; SSE2-NEXT:    orps %xmm7, %xmm1
 ; SSE2-NEXT:    retq
 ;
 ; SSE41-LABEL: round_v8f32:
@@ -375,29 +398,47 @@ define <8 x float> @round_v8f32(<8 x float> %x) {
 define <4 x double> @round_v4f64(<4 x double> %x) {
 ; SSE2-LABEL: round_v4f64:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    subq $56, %rsp
-; SSE2-NEXT:    .cfi_def_cfa_offset 64
-; SSE2-NEXT:    movaps %xmm1, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
-; SSE2-NEXT:    movaps %xmm0, (%rsp) # 16-byte Spill
-; SSE2-NEXT:    callq round at PLT
-; SSE2-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
-; SSE2-NEXT:    movaps (%rsp), %xmm0 # 16-byte Reload
-; SSE2-NEXT:    movhlps {{.*#+}} xmm0 = xmm0[1,1]
-; SSE2-NEXT:    callq round at PLT
-; SSE2-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
-; SSE2-NEXT:    movlhps {{.*#+}} xmm1 = xmm1[0],xmm0[0]
-; SSE2-NEXT:    movaps %xmm1, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
-; SSE2-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
-; SSE2-NEXT:    callq round at PLT
-; SSE2-NEXT:    movaps %xmm0, (%rsp) # 16-byte Spill
-; SSE2-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
-; SSE2-NEXT:    movhlps {{.*#+}} xmm0 = xmm0[1,1]
-; SSE2-NEXT:    callq round at PLT
-; SSE2-NEXT:    movaps (%rsp), %xmm1 # 16-byte Reload
-; SSE2-NEXT:    movlhps {{.*#+}} xmm1 = xmm1[0],xmm0[0]
-; SSE2-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
-; SSE2-NEXT:    addq $56, %rsp
-; SSE2-NEXT:    .cfi_def_cfa_offset 8
+; SSE2-NEXT:    movdqa {{.*#+}} xmm2 = [NaN,NaN]
+; SSE2-NEXT:    movdqa %xmm0, %xmm4
+; SSE2-NEXT:    pand %xmm2, %xmm4
+; SSE2-NEXT:    movapd {{.*#+}} xmm3 = [4.9999999999999994E-1,4.9999999999999994E-1]
+; SSE2-NEXT:    pshufd {{.*#+}} xmm5 = xmm4[1,1,3,3]
+; SSE2-NEXT:    addpd %xmm3, %xmm4
+; SSE2-NEXT:    cvttsd2si %xmm4, %rax
+; SSE2-NEXT:    cvtsi2sd %rax, %xmm6
+; SSE2-NEXT:    unpckhpd {{.*#+}} xmm4 = xmm4[1,1]
+; SSE2-NEXT:    cvttsd2si %xmm4, %rax
+; SSE2-NEXT:    xorps %xmm4, %xmm4
+; SSE2-NEXT:    cvtsi2sd %rax, %xmm4
+; SSE2-NEXT:    unpcklpd {{.*#+}} xmm6 = xmm6[0],xmm4[0]
+; SSE2-NEXT:    andpd %xmm2, %xmm6
+; SSE2-NEXT:    movdqa %xmm2, %xmm4
+; SSE2-NEXT:    pandn %xmm0, %xmm4
+; SSE2-NEXT:    por %xmm6, %xmm4
+; SSE2-NEXT:    movdqa {{.*#+}} xmm6 = [1127219199,1127219199,1127219199,1127219199]
+; SSE2-NEXT:    pcmpgtd %xmm6, %xmm5
+; SSE2-NEXT:    pand %xmm5, %xmm0
+; SSE2-NEXT:    pandn %xmm4, %xmm5
+; SSE2-NEXT:    por %xmm5, %xmm0
+; SSE2-NEXT:    movapd %xmm1, %xmm4
+; SSE2-NEXT:    andpd %xmm2, %xmm4
+; SSE2-NEXT:    addpd %xmm4, %xmm3
+; SSE2-NEXT:    cvttsd2si %xmm3, %rax
+; SSE2-NEXT:    xorps %xmm5, %xmm5
+; SSE2-NEXT:    cvtsi2sd %rax, %xmm5
+; SSE2-NEXT:    unpckhpd {{.*#+}} xmm3 = xmm3[1,1]
+; SSE2-NEXT:    cvttsd2si %xmm3, %rax
+; SSE2-NEXT:    xorps %xmm3, %xmm3
+; SSE2-NEXT:    cvtsi2sd %rax, %xmm3
+; SSE2-NEXT:    unpcklpd {{.*#+}} xmm5 = xmm5[0],xmm3[0]
+; SSE2-NEXT:    andpd %xmm2, %xmm5
+; SSE2-NEXT:    andnpd %xmm1, %xmm2
+; SSE2-NEXT:    orpd %xmm5, %xmm2
+; SSE2-NEXT:    pshufd {{.*#+}} xmm3 = xmm4[1,1,3,3]
+; SSE2-NEXT:    pcmpgtd %xmm6, %xmm3
+; SSE2-NEXT:    andpd %xmm3, %xmm1
+; SSE2-NEXT:    andnpd %xmm2, %xmm3
+; SSE2-NEXT:    orpd %xmm3, %xmm1
 ; SSE2-NEXT:    retq
 ;
 ; SSE41-LABEL: round_v4f64:
@@ -445,99 +486,63 @@ define <4 x double> @round_v4f64(<4 x double> %x) {
 define <16 x float> @round_v16f32(<16 x float> %x) {
 ; SSE2-LABEL: round_v16f32:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    subq $104, %rsp
-; SSE2-NEXT:    .cfi_def_cfa_offset 112
-; SSE2-NEXT:    movaps %xmm3, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
-; SSE2-NEXT:    movaps %xmm2, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
-; SSE2-NEXT:    movaps %xmm1, (%rsp) # 16-byte Spill
-; SSE2-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
-; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[3,3,3,3]
-; SSE2-NEXT:    callq roundf at PLT
-; SSE2-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
-; SSE2-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
-; SSE2-NEXT:    movhlps {{.*#+}} xmm0 = xmm0[1,1]
-; SSE2-NEXT:    callq roundf at PLT
-; SSE2-NEXT:    unpcklps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Folded Reload
-; SSE2-NEXT:    # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
-; SSE2-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
-; SSE2-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
-; SSE2-NEXT:    callq roundf at PLT
-; SSE2-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
-; SSE2-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
-; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,1,1,1]
-; SSE2-NEXT:    callq roundf at PLT
-; SSE2-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
-; SSE2-NEXT:    unpcklps {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
-; SSE2-NEXT:    unpcklpd {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Folded Reload
-; SSE2-NEXT:    # xmm1 = xmm1[0],mem[0]
-; SSE2-NEXT:    movaps %xmm1, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
-; SSE2-NEXT:    movaps (%rsp), %xmm0 # 16-byte Reload
-; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[3,3,3,3]
-; SSE2-NEXT:    callq roundf at PLT
-; SSE2-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
-; SSE2-NEXT:    movaps (%rsp), %xmm0 # 16-byte Reload
-; SSE2-NEXT:    movhlps {{.*#+}} xmm0 = xmm0[1,1]
-; SSE2-NEXT:    callq roundf at PLT
-; SSE2-NEXT:    unpcklps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Folded Reload
-; SSE2-NEXT:    # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
-; SSE2-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
-; SSE2-NEXT:    movaps (%rsp), %xmm0 # 16-byte Reload
-; SSE2-NEXT:    callq roundf at PLT
-; SSE2-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
-; SSE2-NEXT:    movaps (%rsp), %xmm0 # 16-byte Reload
-; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,1,1,1]
-; SSE2-NEXT:    callq roundf at PLT
-; SSE2-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
-; SSE2-NEXT:    unpcklps {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
-; SSE2-NEXT:    unpcklpd {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Folded Reload
-; SSE2-NEXT:    # xmm1 = xmm1[0],mem[0]
-; SSE2-NEXT:    movaps %xmm1, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
-; SSE2-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
-; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[3,3,3,3]
-; SSE2-NEXT:    callq roundf at PLT
-; SSE2-NEXT:    movaps %xmm0, (%rsp) # 16-byte Spill
-; SSE2-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
-; SSE2-NEXT:    movhlps {{.*#+}} xmm0 = xmm0[1,1]
-; SSE2-NEXT:    callq roundf at PLT
-; SSE2-NEXT:    unpcklps (%rsp), %xmm0 # 16-byte Folded Reload
-; SSE2-NEXT:    # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
-; SSE2-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
-; SSE2-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
-; SSE2-NEXT:    callq roundf at PLT
-; SSE2-NEXT:    movaps %xmm0, (%rsp) # 16-byte Spill
-; SSE2-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
-; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,1,1,1]
-; SSE2-NEXT:    callq roundf at PLT
-; SSE2-NEXT:    movaps (%rsp), %xmm1 # 16-byte Reload
-; SSE2-NEXT:    unpcklps {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
-; SSE2-NEXT:    unpcklpd {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Folded Reload
-; SSE2-NEXT:    # xmm1 = xmm1[0],mem[0]
-; SSE2-NEXT:    movaps %xmm1, (%rsp) # 16-byte Spill
-; SSE2-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
-; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[3,3,3,3]
-; SSE2-NEXT:    callq roundf at PLT
-; SSE2-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
-; SSE2-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
-; SSE2-NEXT:    movhlps {{.*#+}} xmm0 = xmm0[1,1]
-; SSE2-NEXT:    callq roundf at PLT
-; SSE2-NEXT:    unpcklps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Folded Reload
-; SSE2-NEXT:    # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
-; SSE2-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
-; SSE2-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
-; SSE2-NEXT:    callq roundf at PLT
-; SSE2-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
-; SSE2-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
-; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[1,1,1,1]
-; SSE2-NEXT:    callq roundf at PLT
-; SSE2-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm3 # 16-byte Reload
-; SSE2-NEXT:    unpcklps {{.*#+}} xmm3 = xmm3[0],xmm0[0],xmm3[1],xmm0[1]
-; SSE2-NEXT:    unpcklpd {{[-0-9]+}}(%r{{[sb]}}p), %xmm3 # 16-byte Folded Reload
-; SSE2-NEXT:    # xmm3 = xmm3[0],mem[0]
-; SSE2-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
-; SSE2-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
-; SSE2-NEXT:    movaps (%rsp), %xmm2 # 16-byte Reload
-; SSE2-NEXT:    addq $104, %rsp
-; SSE2-NEXT:    .cfi_def_cfa_offset 8
+; SSE2-NEXT:    movaps {{.*#+}} xmm5 = [NaN,NaN,NaN,NaN]
+; SSE2-NEXT:    movaps %xmm0, %xmm4
+; SSE2-NEXT:    andps %xmm5, %xmm4
+; SSE2-NEXT:    movaps {{.*#+}} xmm7 = [4.9999997E-1,4.9999997E-1,4.9999997E-1,4.9999997E-1]
+; SSE2-NEXT:    movaps %xmm4, %xmm6
+; SSE2-NEXT:    addps %xmm7, %xmm6
+; SSE2-NEXT:    cvttps2dq %xmm6, %xmm6
+; SSE2-NEXT:    cvtdq2ps %xmm6, %xmm6
+; SSE2-NEXT:    andps %xmm5, %xmm6
+; SSE2-NEXT:    movaps %xmm5, %xmm9
+; SSE2-NEXT:    movaps %xmm1, %xmm8
+; SSE2-NEXT:    andps %xmm5, %xmm8
+; SSE2-NEXT:    movaps %xmm8, %xmm10
+; SSE2-NEXT:    addps %xmm7, %xmm10
+; SSE2-NEXT:    cvttps2dq %xmm10, %xmm10
+; SSE2-NEXT:    cvtdq2ps %xmm10, %xmm10
+; SSE2-NEXT:    andps %xmm5, %xmm10
+; SSE2-NEXT:    movaps %xmm5, %xmm12
+; SSE2-NEXT:    movaps %xmm2, %xmm11
+; SSE2-NEXT:    andps %xmm5, %xmm11
+; SSE2-NEXT:    movaps %xmm11, %xmm13
+; SSE2-NEXT:    addps %xmm7, %xmm13
+; SSE2-NEXT:    cvttps2dq %xmm13, %xmm13
+; SSE2-NEXT:    cvtdq2ps %xmm13, %xmm13
+; SSE2-NEXT:    andps %xmm5, %xmm13
+; SSE2-NEXT:    movaps %xmm5, %xmm15
+; SSE2-NEXT:    movaps %xmm3, %xmm14
+; SSE2-NEXT:    andps %xmm5, %xmm14
+; SSE2-NEXT:    addps %xmm14, %xmm7
+; SSE2-NEXT:    cvttps2dq %xmm7, %xmm7
+; SSE2-NEXT:    cvtdq2ps %xmm7, %xmm7
+; SSE2-NEXT:    andps %xmm5, %xmm7
+; SSE2-NEXT:    andnps %xmm0, %xmm5
+; SSE2-NEXT:    orps %xmm5, %xmm6
+; SSE2-NEXT:    movdqa {{.*#+}} xmm5 = [1325400063,1325400063,1325400063,1325400063]
+; SSE2-NEXT:    pcmpgtd %xmm5, %xmm4
+; SSE2-NEXT:    andps %xmm4, %xmm0
+; SSE2-NEXT:    andnps %xmm6, %xmm4
+; SSE2-NEXT:    orps %xmm4, %xmm0
+; SSE2-NEXT:    andnps %xmm1, %xmm9
+; SSE2-NEXT:    orps %xmm9, %xmm10
+; SSE2-NEXT:    pcmpgtd %xmm5, %xmm8
+; SSE2-NEXT:    andps %xmm8, %xmm1
+; SSE2-NEXT:    andnps %xmm10, %xmm8
+; SSE2-NEXT:    orps %xmm8, %xmm1
+; SSE2-NEXT:    andnps %xmm2, %xmm12
+; SSE2-NEXT:    orps %xmm12, %xmm13
+; SSE2-NEXT:    pcmpgtd %xmm5, %xmm11
+; SSE2-NEXT:    andps %xmm11, %xmm2
+; SSE2-NEXT:    andnps %xmm13, %xmm11
+; SSE2-NEXT:    orps %xmm11, %xmm2
+; SSE2-NEXT:    andnps %xmm3, %xmm15
+; SSE2-NEXT:    orps %xmm15, %xmm7
+; SSE2-NEXT:    pcmpgtd %xmm5, %xmm14
+; SSE2-NEXT:    andps %xmm14, %xmm3
+; SSE2-NEXT:    andnps %xmm7, %xmm14
+; SSE2-NEXT:    orps %xmm14, %xmm3
 ; SSE2-NEXT:    retq
 ;
 ; SSE41-LABEL: round_v16f32:
@@ -601,51 +606,87 @@ define <16 x float> @round_v16f32(<16 x float> %x) {
 define <8 x double> @round_v8f64(<8 x double> %x) {
 ; SSE2-LABEL: round_v8f64:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    subq $88, %rsp
-; SSE2-NEXT:    .cfi_def_cfa_offset 96
-; SSE2-NEXT:    movaps %xmm3, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
-; SSE2-NEXT:    movaps %xmm2, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
-; SSE2-NEXT:    movaps %xmm1, (%rsp) # 16-byte Spill
-; SSE2-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
-; SSE2-NEXT:    callq round at PLT
-; SSE2-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
-; SSE2-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
-; SSE2-NEXT:    movhlps {{.*#+}} xmm0 = xmm0[1,1]
-; SSE2-NEXT:    callq round at PLT
-; SSE2-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
-; SSE2-NEXT:    movlhps {{.*#+}} xmm1 = xmm1[0],xmm0[0]
-; SSE2-NEXT:    movaps %xmm1, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
-; SSE2-NEXT:    movaps (%rsp), %xmm0 # 16-byte Reload
-; SSE2-NEXT:    callq round at PLT
-; SSE2-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
-; SSE2-NEXT:    movaps (%rsp), %xmm0 # 16-byte Reload
-; SSE2-NEXT:    movhlps {{.*#+}} xmm0 = xmm0[1,1]
-; SSE2-NEXT:    callq round at PLT
-; SSE2-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
-; SSE2-NEXT:    movlhps {{.*#+}} xmm1 = xmm1[0],xmm0[0]
-; SSE2-NEXT:    movaps %xmm1, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
-; SSE2-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
-; SSE2-NEXT:    callq round at PLT
-; SSE2-NEXT:    movaps %xmm0, (%rsp) # 16-byte Spill
-; SSE2-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
-; SSE2-NEXT:    movhlps {{.*#+}} xmm0 = xmm0[1,1]
-; SSE2-NEXT:    callq round at PLT
-; SSE2-NEXT:    movaps (%rsp), %xmm1 # 16-byte Reload
-; SSE2-NEXT:    movlhps {{.*#+}} xmm1 = xmm1[0],xmm0[0]
-; SSE2-NEXT:    movaps %xmm1, (%rsp) # 16-byte Spill
-; SSE2-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
-; SSE2-NEXT:    callq round at PLT
-; SSE2-NEXT:    movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
-; SSE2-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
-; SSE2-NEXT:    movhlps {{.*#+}} xmm0 = xmm0[1,1]
-; SSE2-NEXT:    callq round at PLT
-; SSE2-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm3 # 16-byte Reload
-; SSE2-NEXT:    movlhps {{.*#+}} xmm3 = xmm3[0],xmm0[0]
-; SSE2-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
-; SSE2-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
-; SSE2-NEXT:    movaps (%rsp), %xmm2 # 16-byte Reload
-; SSE2-NEXT:    addq $88, %rsp
-; SSE2-NEXT:    .cfi_def_cfa_offset 8
+; SSE2-NEXT:    movdqa {{.*#+}} xmm4 = [NaN,NaN]
+; SSE2-NEXT:    movdqa %xmm0, %xmm6
+; SSE2-NEXT:    pand %xmm4, %xmm6
+; SSE2-NEXT:    movapd {{.*#+}} xmm5 = [4.9999999999999994E-1,4.9999999999999994E-1]
+; SSE2-NEXT:    pshufd {{.*#+}} xmm7 = xmm6[1,1,3,3]
+; SSE2-NEXT:    addpd %xmm5, %xmm6
+; SSE2-NEXT:    cvttsd2si %xmm6, %rax
+; SSE2-NEXT:    cvtsi2sd %rax, %xmm8
+; SSE2-NEXT:    unpckhpd {{.*#+}} xmm6 = xmm6[1,1]
+; SSE2-NEXT:    cvttsd2si %xmm6, %rax
+; SSE2-NEXT:    xorps %xmm6, %xmm6
+; SSE2-NEXT:    cvtsi2sd %rax, %xmm6
+; SSE2-NEXT:    unpcklpd {{.*#+}} xmm8 = xmm8[0],xmm6[0]
+; SSE2-NEXT:    andpd %xmm4, %xmm8
+; SSE2-NEXT:    movdqa %xmm4, %xmm9
+; SSE2-NEXT:    pandn %xmm0, %xmm9
+; SSE2-NEXT:    por %xmm8, %xmm9
+; SSE2-NEXT:    movdqa {{.*#+}} xmm6 = [1127219199,1127219199,1127219199,1127219199]
+; SSE2-NEXT:    pcmpgtd %xmm6, %xmm7
+; SSE2-NEXT:    pand %xmm7, %xmm0
+; SSE2-NEXT:    pandn %xmm9, %xmm7
+; SSE2-NEXT:    por %xmm7, %xmm0
+; SSE2-NEXT:    movdqa %xmm1, %xmm7
+; SSE2-NEXT:    pand %xmm4, %xmm7
+; SSE2-NEXT:    pshufd {{.*#+}} xmm8 = xmm7[1,1,3,3]
+; SSE2-NEXT:    addpd %xmm5, %xmm7
+; SSE2-NEXT:    cvttsd2si %xmm7, %rax
+; SSE2-NEXT:    xorps %xmm9, %xmm9
+; SSE2-NEXT:    cvtsi2sd %rax, %xmm9
+; SSE2-NEXT:    unpckhpd {{.*#+}} xmm7 = xmm7[1,1]
+; SSE2-NEXT:    cvttsd2si %xmm7, %rax
+; SSE2-NEXT:    xorps %xmm7, %xmm7
+; SSE2-NEXT:    cvtsi2sd %rax, %xmm7
+; SSE2-NEXT:    unpcklpd {{.*#+}} xmm9 = xmm9[0],xmm7[0]
+; SSE2-NEXT:    andpd %xmm4, %xmm9
+; SSE2-NEXT:    movdqa %xmm4, %xmm7
+; SSE2-NEXT:    pandn %xmm1, %xmm7
+; SSE2-NEXT:    por %xmm9, %xmm7
+; SSE2-NEXT:    pcmpgtd %xmm6, %xmm8
+; SSE2-NEXT:    pand %xmm8, %xmm1
+; SSE2-NEXT:    pandn %xmm7, %xmm8
+; SSE2-NEXT:    por %xmm8, %xmm1
+; SSE2-NEXT:    movdqa %xmm2, %xmm7
+; SSE2-NEXT:    pand %xmm4, %xmm7
+; SSE2-NEXT:    pshufd {{.*#+}} xmm8 = xmm7[1,1,3,3]
+; SSE2-NEXT:    addpd %xmm5, %xmm7
+; SSE2-NEXT:    cvttsd2si %xmm7, %rax
+; SSE2-NEXT:    xorps %xmm9, %xmm9
+; SSE2-NEXT:    cvtsi2sd %rax, %xmm9
+; SSE2-NEXT:    unpckhpd {{.*#+}} xmm7 = xmm7[1,1]
+; SSE2-NEXT:    cvttsd2si %xmm7, %rax
+; SSE2-NEXT:    xorps %xmm7, %xmm7
+; SSE2-NEXT:    cvtsi2sd %rax, %xmm7
+; SSE2-NEXT:    unpcklpd {{.*#+}} xmm9 = xmm9[0],xmm7[0]
+; SSE2-NEXT:    andpd %xmm4, %xmm9
+; SSE2-NEXT:    movdqa %xmm4, %xmm7
+; SSE2-NEXT:    pandn %xmm2, %xmm7
+; SSE2-NEXT:    por %xmm9, %xmm7
+; SSE2-NEXT:    pcmpgtd %xmm6, %xmm8
+; SSE2-NEXT:    pand %xmm8, %xmm2
+; SSE2-NEXT:    pandn %xmm7, %xmm8
+; SSE2-NEXT:    por %xmm8, %xmm2
+; SSE2-NEXT:    movapd %xmm3, %xmm7
+; SSE2-NEXT:    andpd %xmm4, %xmm7
+; SSE2-NEXT:    addpd %xmm7, %xmm5
+; SSE2-NEXT:    cvttsd2si %xmm5, %rax
+; SSE2-NEXT:    xorps %xmm8, %xmm8
+; SSE2-NEXT:    cvtsi2sd %rax, %xmm8
+; SSE2-NEXT:    unpckhpd {{.*#+}} xmm5 = xmm5[1,1]
+; SSE2-NEXT:    cvttsd2si %xmm5, %rax
+; SSE2-NEXT:    xorps %xmm5, %xmm5
+; SSE2-NEXT:    cvtsi2sd %rax, %xmm5
+; SSE2-NEXT:    unpcklpd {{.*#+}} xmm8 = xmm8[0],xmm5[0]
+; SSE2-NEXT:    andpd %xmm4, %xmm8
+; SSE2-NEXT:    andnpd %xmm3, %xmm4
+; SSE2-NEXT:    orpd %xmm8, %xmm4
+; SSE2-NEXT:    pshufd {{.*#+}} xmm5 = xmm7[1,1,3,3]
+; SSE2-NEXT:    pcmpgtd %xmm6, %xmm5
+; SSE2-NEXT:    andpd %xmm5, %xmm3
+; SSE2-NEXT:    andnpd %xmm4, %xmm5
+; SSE2-NEXT:    orpd %xmm5, %xmm3
 ; SSE2-NEXT:    retq
 ;
 ; SSE41-LABEL: round_v8f64:
diff --git a/llvm/test/CodeGen/X86/fp16-libcalls.ll b/llvm/test/CodeGen/X86/fp16-libcalls.ll
index 6abdf9a5ba652..594418e9d4b0b 100644
--- a/llvm/test/CodeGen/X86/fp16-libcalls.ll
+++ b/llvm/test/CodeGen/X86/fp16-libcalls.ll
@@ -1152,7 +1152,20 @@ define void @test_half_trunc(half %a0, ptr %p0) nounwind {
 ; X64-NEXT:    pushq %rbx
 ; X64-NEXT:    movq %rdi, %rbx
 ; X64-NEXT:    callq __extendhfsf2 at PLT
-; X64-NEXT:    callq truncf at PLT
+; X64-NEXT:    movdqa {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
+; X64-NEXT:    movdqa %xmm0, %xmm2
+; X64-NEXT:    pand %xmm1, %xmm2
+; X64-NEXT:    movd %xmm2, %eax
+; X64-NEXT:    cmpl $1325400064, %eax # imm = 0x4F000000
+; X64-NEXT:    jge .LBB20_2
+; X64-NEXT:  # %bb.1:
+; X64-NEXT:    cvttps2dq %xmm2, %xmm2
+; X64-NEXT:    cvtdq2ps %xmm2, %xmm2
+; X64-NEXT:    andps %xmm1, %xmm2
+; X64-NEXT:    pandn %xmm0, %xmm1
+; X64-NEXT:    por %xmm2, %xmm1
+; X64-NEXT:    movdqa %xmm1, %xmm0
+; X64-NEXT:  .LBB20_2:
 ; X64-NEXT:    callq __truncsfhf2 at PLT
 ; X64-NEXT:    pextrw $0, %xmm0, %eax
 ; X64-NEXT:    movw %ax, (%rbx)
@@ -1168,9 +1181,23 @@ define void @test_half_trunc(half %a0, ptr %p0) nounwind {
 ; X86-NEXT:    pextrw $0, %xmm0, %eax
 ; X86-NEXT:    movw %ax, (%esp)
 ; X86-NEXT:    calll __extendhfsf2
-; X86-NEXT:    fstps (%esp)
-; X86-NEXT:    calll truncf
-; X86-NEXT:    fstps (%esp)
+; X86-NEXT:    fstps {{[0-9]+}}(%esp)
+; X86-NEXT:    movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
+; X86-NEXT:    movdqa {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
+; X86-NEXT:    movdqa %xmm0, %xmm2
+; X86-NEXT:    pand %xmm1, %xmm2
+; X86-NEXT:    movd %xmm2, %eax
+; X86-NEXT:    cmpl $1325400064, %eax # imm = 0x4F000000
+; X86-NEXT:    jge .LBB20_2
+; X86-NEXT:  # %bb.1:
+; X86-NEXT:    cvttps2dq %xmm2, %xmm2
+; X86-NEXT:    cvtdq2ps %xmm2, %xmm2
+; X86-NEXT:    andps %xmm1, %xmm2
+; X86-NEXT:    pandn %xmm0, %xmm1
+; X86-NEXT:    por %xmm2, %xmm1
+; X86-NEXT:    movdqa %xmm1, %xmm0
+; X86-NEXT:  .LBB20_2:
+; X86-NEXT:    movd %xmm0, (%esp)
 ; X86-NEXT:    calll __truncsfhf2
 ; X86-NEXT:    pextrw $0, %xmm0, %eax
 ; X86-NEXT:    movw %ax, (%esi)
diff --git a/llvm/test/CodeGen/X86/freeze-unary.ll b/llvm/test/CodeGen/X86/freeze-unary.ll
index 222ec1eb3b9de..addae1acca77a 100644
--- a/llvm/test/CodeGen/X86/freeze-unary.ll
+++ b/llvm/test/CodeGen/X86/freeze-unary.ll
@@ -485,9 +485,24 @@ define float @ftrunc_freeze_fround(float %a0) nounwind {
 ; X86-LABEL: ftrunc_freeze_fround:
 ; X86:       # %bb.0:
 ; X86-NEXT:    pushl %eax
-; X86-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
-; X86-NEXT:    movss %xmm0, (%esp)
-; X86-NEXT:    calll roundf
+; X86-NEXT:    movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
+; X86-NEXT:    movdqa {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
+; X86-NEXT:    movdqa %xmm0, %xmm2
+; X86-NEXT:    pand %xmm1, %xmm2
+; X86-NEXT:    movd %xmm2, %eax
+; X86-NEXT:    cmpl $1325400064, %eax # imm = 0x4F000000
+; X86-NEXT:    jge .LBB23_2
+; X86-NEXT:  # %bb.1:
+; X86-NEXT:    addss {{\.?LCPI[0-9]+_[0-9]+}}, %xmm2
+; X86-NEXT:    cvttps2dq %xmm2, %xmm2
+; X86-NEXT:    cvtdq2ps %xmm2, %xmm2
+; X86-NEXT:    andps %xmm1, %xmm2
+; X86-NEXT:    pandn %xmm0, %xmm1
+; X86-NEXT:    por %xmm2, %xmm1
+; X86-NEXT:    movdqa %xmm1, %xmm0
+; X86-NEXT:  .LBB23_2:
+; X86-NEXT:    movd %xmm0, (%esp)
+; X86-NEXT:    flds (%esp)
 ; X86-NEXT:    popl %eax
 ; X86-NEXT:    retl
 ;
@@ -550,9 +565,23 @@ define float @ftrunc_freeze_ftrunc(float %a0) nounwind {
 ; X86-LABEL: ftrunc_freeze_ftrunc:
 ; X86:       # %bb.0:
 ; X86-NEXT:    pushl %eax
-; X86-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
-; X86-NEXT:    movss %xmm0, (%esp)
-; X86-NEXT:    calll truncf
+; X86-NEXT:    movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
+; X86-NEXT:    movdqa {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
+; X86-NEXT:    movdqa %xmm0, %xmm2
+; X86-NEXT:    pand %xmm1, %xmm2
+; X86-NEXT:    movd %xmm2, %eax
+; X86-NEXT:    cmpl $1325400064, %eax # imm = 0x4F000000
+; X86-NEXT:    jge .LBB26_2
+; X86-NEXT:  # %bb.1:
+; X86-NEXT:    cvttps2dq %xmm2, %xmm2
+; X86-NEXT:    cvtdq2ps %xmm2, %xmm2
+; X86-NEXT:    andps %xmm1, %xmm2
+; X86-NEXT:    pandn %xmm0, %xmm1
+; X86-NEXT:    por %xmm2, %xmm1
+; X86-NEXT:    movdqa %xmm1, %xmm0
+; X86-NEXT:  .LBB26_2:
+; X86-NEXT:    movd %xmm0, (%esp)
+; X86-NEXT:    flds (%esp)
 ; X86-NEXT:    popl %eax
 ; X86-NEXT:    retl
 ;
diff --git a/llvm/test/CodeGen/X86/ftrunc.ll b/llvm/test/CodeGen/X86/ftrunc.ll
index 1ab9040a2810f..3e44569a33757 100644
--- a/llvm/test/CodeGen/X86/ftrunc.ll
+++ b/llvm/test/CodeGen/X86/ftrunc.ll
@@ -10,10 +10,20 @@ declare i64 @llvm.fptosi.sat.i64.f64(double)
 define float @trunc_unsigned_f32(float %x) #0 {
 ; SSE2-LABEL: trunc_unsigned_f32:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    cvttss2si %xmm0, %rax
-; SSE2-NEXT:    movl %eax, %eax
-; SSE2-NEXT:    xorps %xmm0, %xmm0
-; SSE2-NEXT:    cvtsi2ss %rax, %xmm0
+; SSE2-NEXT:    movdqa {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
+; SSE2-NEXT:    movdqa %xmm0, %xmm2
+; SSE2-NEXT:    pand %xmm1, %xmm2
+; SSE2-NEXT:    movd %xmm2, %eax
+; SSE2-NEXT:    cmpl $1325400064, %eax # imm = 0x4F000000
+; SSE2-NEXT:    jge .LBB0_2
+; SSE2-NEXT:  # %bb.1:
+; SSE2-NEXT:    cvttps2dq %xmm2, %xmm2
+; SSE2-NEXT:    cvtdq2ps %xmm2, %xmm2
+; SSE2-NEXT:    andps %xmm1, %xmm2
+; SSE2-NEXT:    pandn %xmm0, %xmm1
+; SSE2-NEXT:    por %xmm2, %xmm1
+; SSE2-NEXT:    movdqa %xmm1, %xmm0
+; SSE2-NEXT:  .LBB0_2:
 ; SSE2-NEXT:    retq
 ;
 ; SSE41-LABEL: trunc_unsigned_f32:
@@ -43,19 +53,22 @@ define float @trunc_unsigned_f32(float %x) #0 {
 define double @trunc_unsigned_f64(double %x) #0 {
 ; SSE2-LABEL: trunc_unsigned_f64:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    cvttsd2si %xmm0, %rax
-; SSE2-NEXT:    movq %rax, %rcx
-; SSE2-NEXT:    sarq $63, %rcx
-; SSE2-NEXT:    subsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
-; SSE2-NEXT:    cvttsd2si %xmm0, %rdx
-; SSE2-NEXT:    andq %rcx, %rdx
-; SSE2-NEXT:    orq %rax, %rdx
-; SSE2-NEXT:    movq %rdx, %xmm1
-; SSE2-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],mem[0],xmm1[1],mem[1]
-; SSE2-NEXT:    subpd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
-; SSE2-NEXT:    movapd %xmm1, %xmm0
-; SSE2-NEXT:    unpckhpd {{.*#+}} xmm0 = xmm0[1],xmm1[1]
-; SSE2-NEXT:    addsd %xmm1, %xmm0
+; SSE2-NEXT:    movdqa {{.*#+}} xmm1 = [NaN,NaN]
+; SSE2-NEXT:    movdqa %xmm0, %xmm2
+; SSE2-NEXT:    pand %xmm1, %xmm2
+; SSE2-NEXT:    movq %xmm2, %rax
+; SSE2-NEXT:    movabsq $4841369599423283199, %rcx # imm = 0x432FFFFFFFFFFFFF
+; SSE2-NEXT:    cmpq %rcx, %rax
+; SSE2-NEXT:    jg .LBB1_2
+; SSE2-NEXT:  # %bb.1:
+; SSE2-NEXT:    cvttsd2si %xmm2, %rax
+; SSE2-NEXT:    xorps %xmm2, %xmm2
+; SSE2-NEXT:    cvtsi2sd %rax, %xmm2
+; SSE2-NEXT:    andpd %xmm1, %xmm2
+; SSE2-NEXT:    pandn %xmm0, %xmm1
+; SSE2-NEXT:    por %xmm2, %xmm1
+; SSE2-NEXT:    movdqa %xmm1, %xmm0
+; SSE2-NEXT:  .LBB1_2:
 ; SSE2-NEXT:    retq
 ;
 ; SSE41-LABEL: trunc_unsigned_f64:
@@ -89,20 +102,18 @@ define double @trunc_unsigned_f64(double %x) #0 {
 define <4 x float> @trunc_unsigned_v4f32(<4 x float> %x) #0 {
 ; SSE2-LABEL: trunc_unsigned_v4f32:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    cvttps2dq %xmm0, %xmm1
-; SSE2-NEXT:    movdqa %xmm1, %xmm2
-; SSE2-NEXT:    psrad $31, %xmm2
-; SSE2-NEXT:    subps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
-; SSE2-NEXT:    cvttps2dq %xmm0, %xmm0
-; SSE2-NEXT:    pand %xmm2, %xmm0
-; SSE2-NEXT:    por %xmm1, %xmm0
-; SSE2-NEXT:    movdqa {{.*#+}} xmm1 = [65535,65535,65535,65535]
-; SSE2-NEXT:    pand %xmm0, %xmm1
-; SSE2-NEXT:    por {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
-; SSE2-NEXT:    psrld $16, %xmm0
-; SSE2-NEXT:    por {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
-; SSE2-NEXT:    subps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
-; SSE2-NEXT:    addps %xmm1, %xmm0
+; SSE2-NEXT:    movaps {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
+; SSE2-NEXT:    movaps %xmm0, %xmm2
+; SSE2-NEXT:    andps %xmm1, %xmm2
+; SSE2-NEXT:    cvttps2dq %xmm2, %xmm3
+; SSE2-NEXT:    cvtdq2ps %xmm3, %xmm3
+; SSE2-NEXT:    andps %xmm1, %xmm3
+; SSE2-NEXT:    andnps %xmm0, %xmm1
+; SSE2-NEXT:    orps %xmm1, %xmm3
+; SSE2-NEXT:    pcmpgtd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
+; SSE2-NEXT:    andps %xmm2, %xmm0
+; SSE2-NEXT:    andnps %xmm3, %xmm2
+; SSE2-NEXT:    orps %xmm2, %xmm0
 ; SSE2-NEXT:    retq
 ;
 ; SSE41-LABEL: trunc_unsigned_v4f32:
@@ -122,34 +133,24 @@ define <4 x float> @trunc_unsigned_v4f32(<4 x float> %x) #0 {
 define <2 x double> @trunc_unsigned_v2f64(<2 x double> %x) #0 {
 ; SSE2-LABEL: trunc_unsigned_v2f64:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    movsd {{.*#+}} xmm2 = [9.2233720368547758E+18,0.0E+0]
-; SSE2-NEXT:    movapd %xmm0, %xmm1
-; SSE2-NEXT:    subsd %xmm2, %xmm1
-; SSE2-NEXT:    cvttsd2si %xmm1, %rax
-; SSE2-NEXT:    cvttsd2si %xmm0, %rcx
-; SSE2-NEXT:    movq %rcx, %rdx
-; SSE2-NEXT:    sarq $63, %rdx
-; SSE2-NEXT:    andq %rax, %rdx
-; SSE2-NEXT:    orq %rcx, %rdx
-; SSE2-NEXT:    movq %rdx, %xmm1
-; SSE2-NEXT:    unpckhpd {{.*#+}} xmm0 = xmm0[1,1]
-; SSE2-NEXT:    cvttsd2si %xmm0, %rax
-; SSE2-NEXT:    subsd %xmm2, %xmm0
-; SSE2-NEXT:    cvttsd2si %xmm0, %rcx
-; SSE2-NEXT:    movq %rax, %rdx
-; SSE2-NEXT:    sarq $63, %rdx
-; SSE2-NEXT:    andq %rcx, %rdx
-; SSE2-NEXT:    orq %rax, %rdx
-; SSE2-NEXT:    movq %rdx, %xmm0
-; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm0[0]
-; SSE2-NEXT:    movdqa {{.*#+}} xmm0 = [4294967295,4294967295]
-; SSE2-NEXT:    pand %xmm1, %xmm0
-; SSE2-NEXT:    por {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
-; SSE2-NEXT:    psrlq $32, %xmm1
-; SSE2-NEXT:    por {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
-; SSE2-NEXT:    subpd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
-; SSE2-NEXT:    addpd %xmm0, %xmm1
-; SSE2-NEXT:    movapd %xmm1, %xmm0
+; SSE2-NEXT:    movapd {{.*#+}} xmm1 = [NaN,NaN]
+; SSE2-NEXT:    movapd %xmm0, %xmm2
+; SSE2-NEXT:    andpd %xmm1, %xmm2
+; SSE2-NEXT:    cvttsd2si %xmm2, %rax
+; SSE2-NEXT:    cvtsi2sd %rax, %xmm3
+; SSE2-NEXT:    pshufd {{.*#+}} xmm4 = xmm2[2,3,2,3]
+; SSE2-NEXT:    cvttsd2si %xmm4, %rax
+; SSE2-NEXT:    xorps %xmm4, %xmm4
+; SSE2-NEXT:    cvtsi2sd %rax, %xmm4
+; SSE2-NEXT:    unpcklpd {{.*#+}} xmm3 = xmm3[0],xmm4[0]
+; SSE2-NEXT:    andpd %xmm1, %xmm3
+; SSE2-NEXT:    andnpd %xmm0, %xmm1
+; SSE2-NEXT:    orpd %xmm3, %xmm1
+; SSE2-NEXT:    pshufd {{.*#+}} xmm2 = xmm2[1,1,3,3]
+; SSE2-NEXT:    pcmpgtd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
+; SSE2-NEXT:    andpd %xmm2, %xmm0
+; SSE2-NEXT:    andnpd %xmm1, %xmm2
+; SSE2-NEXT:    orpd %xmm2, %xmm0
 ; SSE2-NEXT:    retq
 ;
 ; SSE41-LABEL: trunc_unsigned_v2f64:
@@ -169,63 +170,44 @@ define <2 x double> @trunc_unsigned_v2f64(<2 x double> %x) #0 {
 define <4 x double> @trunc_unsigned_v4f64(<4 x double> %x) #0 {
 ; SSE2-LABEL: trunc_unsigned_v4f64:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    movapd %xmm1, %xmm2
-; SSE2-NEXT:    movsd {{.*#+}} xmm3 = [9.2233720368547758E+18,0.0E+0]
-; SSE2-NEXT:    subsd %xmm3, %xmm1
-; SSE2-NEXT:    cvttsd2si %xmm1, %rax
-; SSE2-NEXT:    cvttsd2si %xmm2, %rcx
-; SSE2-NEXT:    movq %rcx, %rdx
-; SSE2-NEXT:    sarq $63, %rdx
-; SSE2-NEXT:    andq %rax, %rdx
-; SSE2-NEXT:    orq %rcx, %rdx
-; SSE2-NEXT:    movq %rdx, %xmm1
-; SSE2-NEXT:    unpckhpd {{.*#+}} xmm2 = xmm2[1,1]
-; SSE2-NEXT:    cvttsd2si %xmm2, %rax
-; SSE2-NEXT:    subsd %xmm3, %xmm2
-; SSE2-NEXT:    cvttsd2si %xmm2, %rcx
-; SSE2-NEXT:    movq %rax, %rdx
-; SSE2-NEXT:    sarq $63, %rdx
-; SSE2-NEXT:    andq %rcx, %rdx
-; SSE2-NEXT:    orq %rax, %rdx
-; SSE2-NEXT:    movq %rdx, %xmm2
-; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm2[0]
-; SSE2-NEXT:    movapd %xmm0, %xmm2
-; SSE2-NEXT:    subsd %xmm3, %xmm2
-; SSE2-NEXT:    cvttsd2si %xmm2, %rax
-; SSE2-NEXT:    cvttsd2si %xmm0, %rcx
-; SSE2-NEXT:    movq %rcx, %rdx
-; SSE2-NEXT:    sarq $63, %rdx
-; SSE2-NEXT:    andq %rax, %rdx
-; SSE2-NEXT:    orq %rcx, %rdx
-; SSE2-NEXT:    movq %rdx, %xmm2
-; SSE2-NEXT:    unpckhpd {{.*#+}} xmm0 = xmm0[1,1]
-; SSE2-NEXT:    cvttsd2si %xmm0, %rax
-; SSE2-NEXT:    subsd %xmm3, %xmm0
-; SSE2-NEXT:    cvttsd2si %xmm0, %rcx
-; SSE2-NEXT:    movq %rax, %rdx
-; SSE2-NEXT:    sarq $63, %rdx
-; SSE2-NEXT:    andq %rcx, %rdx
-; SSE2-NEXT:    orq %rax, %rdx
-; SSE2-NEXT:    movq %rdx, %xmm0
-; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm0[0]
-; SSE2-NEXT:    movdqa {{.*#+}} xmm0 = [4294967295,4294967295]
-; SSE2-NEXT:    movdqa %xmm2, %xmm3
-; SSE2-NEXT:    pand %xmm0, %xmm3
-; SSE2-NEXT:    movdqa {{.*#+}} xmm4 = [4841369599423283200,4841369599423283200]
-; SSE2-NEXT:    por %xmm4, %xmm3
-; SSE2-NEXT:    psrlq $32, %xmm2
-; SSE2-NEXT:    movdqa {{.*#+}} xmm5 = [4985484787499139072,4985484787499139072]
-; SSE2-NEXT:    por %xmm5, %xmm2
-; SSE2-NEXT:    movapd {{.*#+}} xmm6 = [1.9342813118337666E+25,1.9342813118337666E+25]
-; SSE2-NEXT:    subpd %xmm6, %xmm2
-; SSE2-NEXT:    addpd %xmm3, %xmm2
-; SSE2-NEXT:    pand %xmm1, %xmm0
-; SSE2-NEXT:    por %xmm4, %xmm0
-; SSE2-NEXT:    psrlq $32, %xmm1
-; SSE2-NEXT:    por %xmm5, %xmm1
-; SSE2-NEXT:    subpd %xmm6, %xmm1
-; SSE2-NEXT:    addpd %xmm0, %xmm1
-; SSE2-NEXT:    movapd %xmm2, %xmm0
+; SSE2-NEXT:    movapd {{.*#+}} xmm2 = [NaN,NaN]
+; SSE2-NEXT:    movapd %xmm0, %xmm3
+; SSE2-NEXT:    andpd %xmm2, %xmm3
+; SSE2-NEXT:    cvttsd2si %xmm3, %rax
+; SSE2-NEXT:    cvtsi2sd %rax, %xmm4
+; SSE2-NEXT:    pshufd {{.*#+}} xmm5 = xmm3[2,3,2,3]
+; SSE2-NEXT:    cvttsd2si %xmm5, %rax
+; SSE2-NEXT:    xorps %xmm5, %xmm5
+; SSE2-NEXT:    cvtsi2sd %rax, %xmm5
+; SSE2-NEXT:    unpcklpd {{.*#+}} xmm4 = xmm4[0],xmm5[0]
+; SSE2-NEXT:    andpd %xmm2, %xmm4
+; SSE2-NEXT:    movapd %xmm2, %xmm5
+; SSE2-NEXT:    andnpd %xmm0, %xmm5
+; SSE2-NEXT:    orpd %xmm4, %xmm5
+; SSE2-NEXT:    pshufd {{.*#+}} xmm3 = xmm3[1,1,3,3]
+; SSE2-NEXT:    movdqa {{.*#+}} xmm4 = [1127219199,1127219199,1127219199,1127219199]
+; SSE2-NEXT:    pcmpgtd %xmm4, %xmm3
+; SSE2-NEXT:    andpd %xmm3, %xmm0
+; SSE2-NEXT:    andnpd %xmm5, %xmm3
+; SSE2-NEXT:    orpd %xmm3, %xmm0
+; SSE2-NEXT:    movapd %xmm1, %xmm3
+; SSE2-NEXT:    andpd %xmm2, %xmm3
+; SSE2-NEXT:    cvttsd2si %xmm3, %rax
+; SSE2-NEXT:    xorps %xmm5, %xmm5
+; SSE2-NEXT:    cvtsi2sd %rax, %xmm5
+; SSE2-NEXT:    pshufd {{.*#+}} xmm6 = xmm3[2,3,2,3]
+; SSE2-NEXT:    cvttsd2si %xmm6, %rax
+; SSE2-NEXT:    xorps %xmm6, %xmm6
+; SSE2-NEXT:    cvtsi2sd %rax, %xmm6
+; SSE2-NEXT:    unpcklpd {{.*#+}} xmm5 = xmm5[0],xmm6[0]
+; SSE2-NEXT:    andpd %xmm2, %xmm5
+; SSE2-NEXT:    andnpd %xmm1, %xmm2
+; SSE2-NEXT:    orpd %xmm5, %xmm2
+; SSE2-NEXT:    pshufd {{.*#+}} xmm3 = xmm3[1,1,3,3]
+; SSE2-NEXT:    pcmpgtd %xmm4, %xmm3
+; SSE2-NEXT:    andpd %xmm3, %xmm1
+; SSE2-NEXT:    andnpd %xmm2, %xmm3
+; SSE2-NEXT:    orpd %xmm3, %xmm1
 ; SSE2-NEXT:    retq
 ;
 ; SSE41-LABEL: trunc_unsigned_v4f64:
@@ -276,8 +258,20 @@ define float @trunc_signed_f32_no_fast_math(float %x) nounwind {
 define float @trunc_signed_f32_nsz(float %x) #0 {
 ; SSE2-LABEL: trunc_signed_f32_nsz:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    cvttps2dq %xmm0, %xmm0
-; SSE2-NEXT:    cvtdq2ps %xmm0, %xmm0
+; SSE2-NEXT:    movdqa {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
+; SSE2-NEXT:    movdqa %xmm0, %xmm2
+; SSE2-NEXT:    pand %xmm1, %xmm2
+; SSE2-NEXT:    movd %xmm2, %eax
+; SSE2-NEXT:    cmpl $1325400064, %eax # imm = 0x4F000000
+; SSE2-NEXT:    jge .LBB6_2
+; SSE2-NEXT:  # %bb.1:
+; SSE2-NEXT:    cvttps2dq %xmm2, %xmm2
+; SSE2-NEXT:    cvtdq2ps %xmm2, %xmm2
+; SSE2-NEXT:    andps %xmm1, %xmm2
+; SSE2-NEXT:    pandn %xmm0, %xmm1
+; SSE2-NEXT:    por %xmm2, %xmm1
+; SSE2-NEXT:    movdqa %xmm1, %xmm0
+; SSE2-NEXT:  .LBB6_2:
 ; SSE2-NEXT:    retq
 ;
 ; SSE41-LABEL: trunc_signed_f32_nsz:
@@ -339,8 +333,22 @@ define double @trunc_signed32_f64_no_fast_math(double %x) nounwind {
 define double @trunc_signed32_f64_nsz(double %x) #0 {
 ; SSE2-LABEL: trunc_signed32_f64_nsz:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    cvttpd2dq %xmm0, %xmm0
-; SSE2-NEXT:    cvtdq2pd %xmm0, %xmm0
+; SSE2-NEXT:    movdqa {{.*#+}} xmm1 = [NaN,NaN]
+; SSE2-NEXT:    movdqa %xmm0, %xmm2
+; SSE2-NEXT:    pand %xmm1, %xmm2
+; SSE2-NEXT:    movq %xmm2, %rax
+; SSE2-NEXT:    movabsq $4841369599423283199, %rcx # imm = 0x432FFFFFFFFFFFFF
+; SSE2-NEXT:    cmpq %rcx, %rax
+; SSE2-NEXT:    jg .LBB8_2
+; SSE2-NEXT:  # %bb.1:
+; SSE2-NEXT:    cvttsd2si %xmm2, %rax
+; SSE2-NEXT:    xorps %xmm2, %xmm2
+; SSE2-NEXT:    cvtsi2sd %rax, %xmm2
+; SSE2-NEXT:    andpd %xmm1, %xmm2
+; SSE2-NEXT:    pandn %xmm0, %xmm1
+; SSE2-NEXT:    por %xmm2, %xmm1
+; SSE2-NEXT:    movdqa %xmm1, %xmm0
+; SSE2-NEXT:  .LBB8_2:
 ; SSE2-NEXT:    retq
 ;
 ; SSE41-LABEL: trunc_signed32_f64_nsz:
@@ -531,9 +539,22 @@ define double @trunc_signed_f64_no_fast_math(double %x) nounwind {
 define double @trunc_signed_f64_nsz(double %x) #0 {
 ; SSE2-LABEL: trunc_signed_f64_nsz:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    cvttsd2si %xmm0, %rax
-; SSE2-NEXT:    xorps %xmm0, %xmm0
-; SSE2-NEXT:    cvtsi2sd %rax, %xmm0
+; SSE2-NEXT:    movdqa {{.*#+}} xmm1 = [NaN,NaN]
+; SSE2-NEXT:    movdqa %xmm0, %xmm2
+; SSE2-NEXT:    pand %xmm1, %xmm2
+; SSE2-NEXT:    movq %xmm2, %rax
+; SSE2-NEXT:    movabsq $4841369599423283199, %rcx # imm = 0x432FFFFFFFFFFFFF
+; SSE2-NEXT:    cmpq %rcx, %rax
+; SSE2-NEXT:    jg .LBB14_2
+; SSE2-NEXT:  # %bb.1:
+; SSE2-NEXT:    cvttsd2si %xmm2, %rax
+; SSE2-NEXT:    xorps %xmm2, %xmm2
+; SSE2-NEXT:    cvtsi2sd %rax, %xmm2
+; SSE2-NEXT:    andpd %xmm1, %xmm2
+; SSE2-NEXT:    pandn %xmm0, %xmm1
+; SSE2-NEXT:    por %xmm2, %xmm1
+; SSE2-NEXT:    movdqa %xmm1, %xmm0
+; SSE2-NEXT:  .LBB14_2:
 ; SSE2-NEXT:    retq
 ;
 ; SSE41-LABEL: trunc_signed_f64_nsz:
@@ -567,8 +588,18 @@ define double @trunc_signed_f64_nsz(double %x) #0 {
 define <4 x float> @trunc_signed_v4f32_nsz(<4 x float> %x) #0 {
 ; SSE2-LABEL: trunc_signed_v4f32_nsz:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    cvttps2dq %xmm0, %xmm0
-; SSE2-NEXT:    cvtdq2ps %xmm0, %xmm0
+; SSE2-NEXT:    movaps {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
+; SSE2-NEXT:    movaps %xmm0, %xmm2
+; SSE2-NEXT:    andps %xmm1, %xmm2
+; SSE2-NEXT:    cvttps2dq %xmm2, %xmm3
+; SSE2-NEXT:    cvtdq2ps %xmm3, %xmm3
+; SSE2-NEXT:    andps %xmm1, %xmm3
+; SSE2-NEXT:    andnps %xmm0, %xmm1
+; SSE2-NEXT:    orps %xmm1, %xmm3
+; SSE2-NEXT:    pcmpgtd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
+; SSE2-NEXT:    andps %xmm2, %xmm0
+; SSE2-NEXT:    andnps %xmm3, %xmm2
+; SSE2-NEXT:    orps %xmm2, %xmm0
 ; SSE2-NEXT:    retq
 ;
 ; SSE41-LABEL: trunc_signed_v4f32_nsz:
@@ -588,13 +619,24 @@ define <4 x float> @trunc_signed_v4f32_nsz(<4 x float> %x) #0 {
 define <2 x double> @trunc_signed_v2f64_nsz(<2 x double> %x) #0 {
 ; SSE2-LABEL: trunc_signed_v2f64_nsz:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    cvttsd2si %xmm0, %rax
-; SSE2-NEXT:    unpckhpd {{.*#+}} xmm0 = xmm0[1,1]
-; SSE2-NEXT:    cvttsd2si %xmm0, %rcx
-; SSE2-NEXT:    xorps %xmm0, %xmm0
-; SSE2-NEXT:    cvtsi2sd %rax, %xmm0
-; SSE2-NEXT:    cvtsi2sd %rcx, %xmm1
-; SSE2-NEXT:    unpcklpd {{.*#+}} xmm0 = xmm0[0],xmm1[0]
+; SSE2-NEXT:    movapd {{.*#+}} xmm1 = [NaN,NaN]
+; SSE2-NEXT:    movapd %xmm0, %xmm2
+; SSE2-NEXT:    andpd %xmm1, %xmm2
+; SSE2-NEXT:    cvttsd2si %xmm2, %rax
+; SSE2-NEXT:    cvtsi2sd %rax, %xmm3
+; SSE2-NEXT:    pshufd {{.*#+}} xmm4 = xmm2[2,3,2,3]
+; SSE2-NEXT:    cvttsd2si %xmm4, %rax
+; SSE2-NEXT:    xorps %xmm4, %xmm4
+; SSE2-NEXT:    cvtsi2sd %rax, %xmm4
+; SSE2-NEXT:    unpcklpd {{.*#+}} xmm3 = xmm3[0],xmm4[0]
+; SSE2-NEXT:    andpd %xmm1, %xmm3
+; SSE2-NEXT:    andnpd %xmm0, %xmm1
+; SSE2-NEXT:    orpd %xmm3, %xmm1
+; SSE2-NEXT:    pshufd {{.*#+}} xmm2 = xmm2[1,1,3,3]
+; SSE2-NEXT:    pcmpgtd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
+; SSE2-NEXT:    andpd %xmm2, %xmm0
+; SSE2-NEXT:    andnpd %xmm1, %xmm2
+; SSE2-NEXT:    orpd %xmm2, %xmm0
 ; SSE2-NEXT:    retq
 ;
 ; SSE41-LABEL: trunc_signed_v2f64_nsz:
@@ -614,21 +656,44 @@ define <2 x double> @trunc_signed_v2f64_nsz(<2 x double> %x) #0 {
 define <4 x double> @trunc_signed_v4f64_nsz(<4 x double> %x) #0 {
 ; SSE2-LABEL: trunc_signed_v4f64_nsz:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    cvttsd2si %xmm1, %rax
-; SSE2-NEXT:    unpckhpd {{.*#+}} xmm1 = xmm1[1,1]
-; SSE2-NEXT:    cvttsd2si %xmm1, %rcx
-; SSE2-NEXT:    cvttsd2si %xmm0, %rdx
-; SSE2-NEXT:    unpckhpd {{.*#+}} xmm0 = xmm0[1,1]
-; SSE2-NEXT:    cvttsd2si %xmm0, %rsi
-; SSE2-NEXT:    xorps %xmm0, %xmm0
-; SSE2-NEXT:    cvtsi2sd %rdx, %xmm0
-; SSE2-NEXT:    xorps %xmm1, %xmm1
-; SSE2-NEXT:    cvtsi2sd %rsi, %xmm1
-; SSE2-NEXT:    unpcklpd {{.*#+}} xmm0 = xmm0[0],xmm1[0]
-; SSE2-NEXT:    xorps %xmm1, %xmm1
-; SSE2-NEXT:    cvtsi2sd %rax, %xmm1
-; SSE2-NEXT:    cvtsi2sd %rcx, %xmm2
-; SSE2-NEXT:    unpcklpd {{.*#+}} xmm1 = xmm1[0],xmm2[0]
+; SSE2-NEXT:    movapd {{.*#+}} xmm2 = [NaN,NaN]
+; SSE2-NEXT:    movapd %xmm0, %xmm3
+; SSE2-NEXT:    andpd %xmm2, %xmm3
+; SSE2-NEXT:    cvttsd2si %xmm3, %rax
+; SSE2-NEXT:    cvtsi2sd %rax, %xmm4
+; SSE2-NEXT:    pshufd {{.*#+}} xmm5 = xmm3[2,3,2,3]
+; SSE2-NEXT:    cvttsd2si %xmm5, %rax
+; SSE2-NEXT:    xorps %xmm5, %xmm5
+; SSE2-NEXT:    cvtsi2sd %rax, %xmm5
+; SSE2-NEXT:    unpcklpd {{.*#+}} xmm4 = xmm4[0],xmm5[0]
+; SSE2-NEXT:    andpd %xmm2, %xmm4
+; SSE2-NEXT:    movapd %xmm2, %xmm5
+; SSE2-NEXT:    andnpd %xmm0, %xmm5
+; SSE2-NEXT:    orpd %xmm4, %xmm5
+; SSE2-NEXT:    pshufd {{.*#+}} xmm3 = xmm3[1,1,3,3]
+; SSE2-NEXT:    movdqa {{.*#+}} xmm4 = [1127219199,1127219199,1127219199,1127219199]
+; SSE2-NEXT:    pcmpgtd %xmm4, %xmm3
+; SSE2-NEXT:    andpd %xmm3, %xmm0
+; SSE2-NEXT:    andnpd %xmm5, %xmm3
+; SSE2-NEXT:    orpd %xmm3, %xmm0
+; SSE2-NEXT:    movapd %xmm1, %xmm3
+; SSE2-NEXT:    andpd %xmm2, %xmm3
+; SSE2-NEXT:    cvttsd2si %xmm3, %rax
+; SSE2-NEXT:    xorps %xmm5, %xmm5
+; SSE2-NEXT:    cvtsi2sd %rax, %xmm5
+; SSE2-NEXT:    pshufd {{.*#+}} xmm6 = xmm3[2,3,2,3]
+; SSE2-NEXT:    cvttsd2si %xmm6, %rax
+; SSE2-NEXT:    xorps %xmm6, %xmm6
+; SSE2-NEXT:    cvtsi2sd %rax, %xmm6
+; SSE2-NEXT:    unpcklpd {{.*#+}} xmm5 = xmm5[0],xmm6[0]
+; SSE2-NEXT:    andpd %xmm2, %xmm5
+; SSE2-NEXT:    andnpd %xmm1, %xmm2
+; SSE2-NEXT:    orpd %xmm5, %xmm2
+; SSE2-NEXT:    pshufd {{.*#+}} xmm3 = xmm3[1,1,3,3]
+; SSE2-NEXT:    pcmpgtd %xmm4, %xmm3
+; SSE2-NEXT:    andpd %xmm3, %xmm1
+; SSE2-NEXT:    andnpd %xmm2, %xmm3
+; SSE2-NEXT:    orpd %xmm3, %xmm1
 ; SSE2-NEXT:    retq
 ;
 ; SSE41-LABEL: trunc_signed_v4f64_nsz:
diff --git a/llvm/test/CodeGen/X86/isel-ftrunc.ll b/llvm/test/CodeGen/X86/isel-ftrunc.ll
index c2be47ca04567..15b98688569bd 100644
--- a/llvm/test/CodeGen/X86/isel-ftrunc.ll
+++ b/llvm/test/CodeGen/X86/isel-ftrunc.ll
@@ -7,16 +7,23 @@
 ; RUN: llc < %s -mtriple=i686-linux-gnu -global-isel -global-isel-abort=1 | FileCheck %s --check-prefixes=GISEL-X86
 
 define float @trunc_f32(float %a) nounwind readnone {
-; DAG-X64-LABEL: trunc_f32:
-; DAG-X64:       # %bb.0:
-; DAG-X64-NEXT:    jmp truncf at PLT # TAILCALL
-;
-; FASTISEL-X64-LABEL: trunc_f32:
-; FASTISEL-X64:       # %bb.0:
-; FASTISEL-X64-NEXT:    pushq %rax
-; FASTISEL-X64-NEXT:    callq truncf at PLT
-; FASTISEL-X64-NEXT:    popq %rax
-; FASTISEL-X64-NEXT:    retq
+; X64-LABEL: trunc_f32:
+; X64:       # %bb.0:
+; X64-NEXT:    movdqa {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
+; X64-NEXT:    movdqa %xmm0, %xmm2
+; X64-NEXT:    pand %xmm1, %xmm2
+; X64-NEXT:    movd %xmm2, %eax
+; X64-NEXT:    cmpl $1325400064, %eax # imm = 0x4F000000
+; X64-NEXT:    jge .LBB0_2
+; X64-NEXT:  # %bb.1:
+; X64-NEXT:    cvttps2dq %xmm2, %xmm2
+; X64-NEXT:    cvtdq2ps %xmm2, %xmm2
+; X64-NEXT:    andps %xmm1, %xmm2
+; X64-NEXT:    pandn %xmm0, %xmm1
+; X64-NEXT:    por %xmm2, %xmm1
+; X64-NEXT:    movdqa %xmm1, %xmm0
+; X64-NEXT:  .LBB0_2:
+; X64-NEXT:    retq
 ;
 ; X86-LABEL: trunc_f32:
 ; X86:       # %bb.0:
@@ -47,16 +54,25 @@ define float @trunc_f32(float %a) nounwind readnone {
 }
 
 define double @trunc_f64(double %a) nounwind readnone {
-; DAG-X64-LABEL: trunc_f64:
-; DAG-X64:       # %bb.0:
-; DAG-X64-NEXT:    jmp trunc at PLT # TAILCALL
-;
-; FASTISEL-X64-LABEL: trunc_f64:
-; FASTISEL-X64:       # %bb.0:
-; FASTISEL-X64-NEXT:    pushq %rax
-; FASTISEL-X64-NEXT:    callq trunc at PLT
-; FASTISEL-X64-NEXT:    popq %rax
-; FASTISEL-X64-NEXT:    retq
+; X64-LABEL: trunc_f64:
+; X64:       # %bb.0:
+; X64-NEXT:    movdqa {{.*#+}} xmm1 = [NaN,NaN]
+; X64-NEXT:    movdqa %xmm0, %xmm2
+; X64-NEXT:    pand %xmm1, %xmm2
+; X64-NEXT:    movq %xmm2, %rax
+; X64-NEXT:    movabsq $4841369599423283199, %rcx # imm = 0x432FFFFFFFFFFFFF
+; X64-NEXT:    cmpq %rcx, %rax
+; X64-NEXT:    jg .LBB1_2
+; X64-NEXT:  # %bb.1:
+; X64-NEXT:    cvttsd2si %xmm2, %rax
+; X64-NEXT:    xorps %xmm2, %xmm2
+; X64-NEXT:    cvtsi2sd %rax, %xmm2
+; X64-NEXT:    andpd %xmm1, %xmm2
+; X64-NEXT:    pandn %xmm0, %xmm1
+; X64-NEXT:    por %xmm2, %xmm1
+; X64-NEXT:    movdqa %xmm1, %xmm0
+; X64-NEXT:  .LBB1_2:
+; X64-NEXT:    retq
 ;
 ; X86-LABEL: trunc_f64:
 ; X86:       # %bb.0:
@@ -128,3 +144,6 @@ define x86_fp80 @trunc_f80(x86_fp80   %a) nounwind readnone {
   %c = call x86_fp80   @llvm.trunc.f80(x86_fp80   %a)
   ret x86_fp80   %c
 }
+;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+; DAG-X64: {{.*}}
+; FASTISEL-X64: {{.*}}
diff --git a/llvm/test/CodeGen/X86/isint.ll b/llvm/test/CodeGen/X86/isint.ll
index 778cfdf9e8351..c72e6c9a2c457 100644
--- a/llvm/test/CodeGen/X86/isint.ll
+++ b/llvm/test/CodeGen/X86/isint.ll
@@ -20,10 +20,25 @@ define i32 @isint_return(double %d) nounwind {
 ;
 ; X64-SSE2-LABEL: isint_return:
 ; X64-SSE2:       # %bb.0:
-; X64-SSE2-NEXT:    cvttpd2dq %xmm0, %xmm1
-; X64-SSE2-NEXT:    cvtdq2pd %xmm1, %xmm1
-; X64-SSE2-NEXT:    cmpeqsd %xmm0, %xmm1
-; X64-SSE2-NEXT:    movq %xmm1, %rax
+; X64-SSE2-NEXT:    movdqa {{.*#+}} xmm1 = [NaN,NaN]
+; X64-SSE2-NEXT:    movdqa %xmm0, %xmm2
+; X64-SSE2-NEXT:    pand %xmm1, %xmm2
+; X64-SSE2-NEXT:    movq %xmm2, %rax
+; X64-SSE2-NEXT:    movabsq $4841369599423283199, %rcx # imm = 0x432FFFFFFFFFFFFF
+; X64-SSE2-NEXT:    movdqa %xmm0, %xmm3
+; X64-SSE2-NEXT:    cmpq %rcx, %rax
+; X64-SSE2-NEXT:    jg .LBB0_2
+; X64-SSE2-NEXT:  # %bb.1:
+; X64-SSE2-NEXT:    cvttsd2si %xmm2, %rax
+; X64-SSE2-NEXT:    xorps %xmm2, %xmm2
+; X64-SSE2-NEXT:    cvtsi2sd %rax, %xmm2
+; X64-SSE2-NEXT:    andpd %xmm1, %xmm2
+; X64-SSE2-NEXT:    pandn %xmm0, %xmm1
+; X64-SSE2-NEXT:    por %xmm2, %xmm1
+; X64-SSE2-NEXT:    movdqa %xmm1, %xmm3
+; X64-SSE2-NEXT:  .LBB0_2:
+; X64-SSE2-NEXT:    cmpeqsd %xmm3, %xmm0
+; X64-SSE2-NEXT:    movq %xmm0, %rax
 ; X64-SSE2-NEXT:    andl $1, %eax
 ; X64-SSE2-NEXT:    # kill: def $eax killed $eax killed $rax
 ; X64-SSE2-NEXT:    retq
@@ -62,20 +77,46 @@ define i32 @isint_return(double %d) nounwind {
 define i32 @isint_float_return(float %f) nounwind {
 ; X86-LABEL: isint_float_return:
 ; X86:       # %bb.0:
-; X86-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
-; X86-NEXT:    cvttps2dq %xmm0, %xmm1
-; X86-NEXT:    cvtdq2ps %xmm1, %xmm1
-; X86-NEXT:    cmpeqss %xmm0, %xmm1
-; X86-NEXT:    movd %xmm1, %eax
+; X86-NEXT:    movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
+; X86-NEXT:    movdqa {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
+; X86-NEXT:    movdqa %xmm0, %xmm2
+; X86-NEXT:    pand %xmm1, %xmm2
+; X86-NEXT:    movd %xmm2, %eax
+; X86-NEXT:    cmpl $1325400064, %eax # imm = 0x4F000000
+; X86-NEXT:    movdqa %xmm0, %xmm3
+; X86-NEXT:    jge .LBB1_2
+; X86-NEXT:  # %bb.1:
+; X86-NEXT:    cvttps2dq %xmm2, %xmm2
+; X86-NEXT:    cvtdq2ps %xmm2, %xmm2
+; X86-NEXT:    andps %xmm1, %xmm2
+; X86-NEXT:    pandn %xmm0, %xmm1
+; X86-NEXT:    por %xmm2, %xmm1
+; X86-NEXT:    movdqa %xmm1, %xmm3
+; X86-NEXT:  .LBB1_2:
+; X86-NEXT:    cmpeqss %xmm0, %xmm3
+; X86-NEXT:    movd %xmm3, %eax
 ; X86-NEXT:    andl $1, %eax
 ; X86-NEXT:    retl
 ;
 ; X64-SSE2-LABEL: isint_float_return:
 ; X64-SSE2:       # %bb.0:
-; X64-SSE2-NEXT:    cvttps2dq %xmm0, %xmm1
-; X64-SSE2-NEXT:    cvtdq2ps %xmm1, %xmm1
-; X64-SSE2-NEXT:    cmpeqss %xmm0, %xmm1
-; X64-SSE2-NEXT:    movd %xmm1, %eax
+; X64-SSE2-NEXT:    movdqa {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
+; X64-SSE2-NEXT:    movdqa %xmm0, %xmm2
+; X64-SSE2-NEXT:    pand %xmm1, %xmm2
+; X64-SSE2-NEXT:    movd %xmm2, %eax
+; X64-SSE2-NEXT:    movdqa %xmm0, %xmm3
+; X64-SSE2-NEXT:    cmpl $1325400064, %eax # imm = 0x4F000000
+; X64-SSE2-NEXT:    jge .LBB1_2
+; X64-SSE2-NEXT:  # %bb.1:
+; X64-SSE2-NEXT:    cvttps2dq %xmm2, %xmm2
+; X64-SSE2-NEXT:    cvtdq2ps %xmm2, %xmm2
+; X64-SSE2-NEXT:    andps %xmm1, %xmm2
+; X64-SSE2-NEXT:    pandn %xmm0, %xmm1
+; X64-SSE2-NEXT:    por %xmm2, %xmm1
+; X64-SSE2-NEXT:    movdqa %xmm1, %xmm3
+; X64-SSE2-NEXT:  .LBB1_2:
+; X64-SSE2-NEXT:    cmpeqss %xmm3, %xmm0
+; X64-SSE2-NEXT:    movd %xmm0, %eax
 ; X64-SSE2-NEXT:    andl $1, %eax
 ; X64-SSE2-NEXT:    retq
 ;
@@ -126,16 +167,31 @@ define void @isint_branch(double %d) nounwind {
 ;
 ; X64-SSE2-LABEL: isint_branch:
 ; X64-SSE2:       # %bb.0:
-; X64-SSE2-NEXT:    cvttpd2dq %xmm0, %xmm1
-; X64-SSE2-NEXT:    cvtdq2pd %xmm1, %xmm1
-; X64-SSE2-NEXT:    ucomisd %xmm1, %xmm0
-; X64-SSE2-NEXT:    jne .LBB2_2
-; X64-SSE2-NEXT:    jp .LBB2_2
-; X64-SSE2-NEXT:  # %bb.1: # %true
+; X64-SSE2-NEXT:    movdqa {{.*#+}} xmm1 = [NaN,NaN]
+; X64-SSE2-NEXT:    movdqa %xmm0, %xmm2
+; X64-SSE2-NEXT:    pand %xmm1, %xmm2
+; X64-SSE2-NEXT:    movq %xmm2, %rax
+; X64-SSE2-NEXT:    movabsq $4841369599423283199, %rcx # imm = 0x432FFFFFFFFFFFFF
+; X64-SSE2-NEXT:    movdqa %xmm0, %xmm3
+; X64-SSE2-NEXT:    cmpq %rcx, %rax
+; X64-SSE2-NEXT:    jg .LBB2_2
+; X64-SSE2-NEXT:  # %bb.1:
+; X64-SSE2-NEXT:    cvttsd2si %xmm2, %rax
+; X64-SSE2-NEXT:    xorps %xmm2, %xmm2
+; X64-SSE2-NEXT:    cvtsi2sd %rax, %xmm2
+; X64-SSE2-NEXT:    andpd %xmm1, %xmm2
+; X64-SSE2-NEXT:    pandn %xmm0, %xmm1
+; X64-SSE2-NEXT:    por %xmm2, %xmm1
+; X64-SSE2-NEXT:    movdqa %xmm1, %xmm3
+; X64-SSE2-NEXT:  .LBB2_2:
+; X64-SSE2-NEXT:    ucomisd %xmm3, %xmm0
+; X64-SSE2-NEXT:    jne .LBB2_4
+; X64-SSE2-NEXT:    jp .LBB2_4
+; X64-SSE2-NEXT:  # %bb.3: # %true
 ; X64-SSE2-NEXT:    pushq %rax
 ; X64-SSE2-NEXT:    callq foo at PLT
 ; X64-SSE2-NEXT:    popq %rax
-; X64-SSE2-NEXT:  .LBB2_2: # %false
+; X64-SSE2-NEXT:  .LBB2_4: # %false
 ; X64-SSE2-NEXT:    retq
 ;
 ; X64-SSE42-LABEL: isint_branch:
diff --git a/llvm/test/CodeGen/X86/llround-conv.ll b/llvm/test/CodeGen/X86/llround-conv.ll
index 2b54c90f76906..1779538c61add 100644
--- a/llvm/test/CodeGen/X86/llround-conv.ll
+++ b/llvm/test/CodeGen/X86/llround-conv.ll
@@ -33,7 +33,21 @@ define i64 @test_llround_f16(half %x) nounwind {
 ; X64:       # %bb.0:
 ; X64-NEXT:    pushq %rax
 ; X64-NEXT:    callq __extendhfsf2 at PLT
-; X64-NEXT:    callq roundf at PLT
+; X64-NEXT:    movdqa {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
+; X64-NEXT:    movdqa %xmm0, %xmm2
+; X64-NEXT:    pand %xmm1, %xmm2
+; X64-NEXT:    movd %xmm2, %eax
+; X64-NEXT:    cmpl $1325400064, %eax # imm = 0x4F000000
+; X64-NEXT:    jge .LBB0_2
+; X64-NEXT:  # %bb.1:
+; X64-NEXT:    addss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
+; X64-NEXT:    cvttps2dq %xmm2, %xmm2
+; X64-NEXT:    cvtdq2ps %xmm2, %xmm2
+; X64-NEXT:    andps %xmm1, %xmm2
+; X64-NEXT:    pandn %xmm0, %xmm1
+; X64-NEXT:    por %xmm2, %xmm1
+; X64-NEXT:    movdqa %xmm1, %xmm0
+; X64-NEXT:  .LBB0_2:
 ; X64-NEXT:    callq __truncsfhf2 at PLT
 ; X64-NEXT:    callq __extendhfsf2 at PLT
 ; X64-NEXT:    cvttss2si %xmm0, %rax
@@ -213,7 +227,21 @@ define i64 @test_llround_i64_f16(half %x) nounwind {
 ; X64:       # %bb.0:
 ; X64-NEXT:    pushq %rax
 ; X64-NEXT:    callq __extendhfsf2 at PLT
-; X64-NEXT:    callq roundf at PLT
+; X64-NEXT:    movdqa {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
+; X64-NEXT:    movdqa %xmm0, %xmm2
+; X64-NEXT:    pand %xmm1, %xmm2
+; X64-NEXT:    movd %xmm2, %eax
+; X64-NEXT:    cmpl $1325400064, %eax # imm = 0x4F000000
+; X64-NEXT:    jge .LBB4_2
+; X64-NEXT:  # %bb.1:
+; X64-NEXT:    addss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
+; X64-NEXT:    cvttps2dq %xmm2, %xmm2
+; X64-NEXT:    cvtdq2ps %xmm2, %xmm2
+; X64-NEXT:    andps %xmm1, %xmm2
+; X64-NEXT:    pandn %xmm0, %xmm1
+; X64-NEXT:    por %xmm2, %xmm1
+; X64-NEXT:    movdqa %xmm1, %xmm0
+; X64-NEXT:  .LBB4_2:
 ; X64-NEXT:    callq __truncsfhf2 at PLT
 ; X64-NEXT:    callq __extendhfsf2 at PLT
 ; X64-NEXT:    cvttss2si %xmm0, %rax
diff --git a/llvm/test/CodeGen/X86/lround-conv-i32.ll b/llvm/test/CodeGen/X86/lround-conv-i32.ll
index 02480d087d884..7c15c8318353a 100644
--- a/llvm/test/CodeGen/X86/lround-conv-i32.ll
+++ b/llvm/test/CodeGen/X86/lround-conv-i32.ll
@@ -19,28 +19,57 @@ define i32 @test_lround_i32_f16(half %x) nounwind {
 ;
 ; X86-SSE2-LABEL: test_lround_i32_f16:
 ; X86-SSE2:       # %bb.0:
-; X86-SSE2-NEXT:    subl $8, %esp
+; X86-SSE2-NEXT:    subl $12, %esp
 ; X86-SSE2-NEXT:    pinsrw $0, {{[0-9]+}}(%esp), %xmm0
 ; X86-SSE2-NEXT:    pextrw $0, %xmm0, %eax
 ; X86-SSE2-NEXT:    movw %ax, (%esp)
 ; X86-SSE2-NEXT:    calll __extendhfsf2
-; X86-SSE2-NEXT:    fstps (%esp)
-; X86-SSE2-NEXT:    calll roundf
-; X86-SSE2-NEXT:    fstps (%esp)
+; X86-SSE2-NEXT:    fstps {{[0-9]+}}(%esp)
+; X86-SSE2-NEXT:    movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
+; X86-SSE2-NEXT:    movdqa {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
+; X86-SSE2-NEXT:    movdqa %xmm0, %xmm2
+; X86-SSE2-NEXT:    pand %xmm1, %xmm2
+; X86-SSE2-NEXT:    movd %xmm2, %eax
+; X86-SSE2-NEXT:    cmpl $1325400064, %eax # imm = 0x4F000000
+; X86-SSE2-NEXT:    jge .LBB0_2
+; X86-SSE2-NEXT:  # %bb.1:
+; X86-SSE2-NEXT:    addss {{\.?LCPI[0-9]+_[0-9]+}}, %xmm2
+; X86-SSE2-NEXT:    cvttps2dq %xmm2, %xmm2
+; X86-SSE2-NEXT:    cvtdq2ps %xmm2, %xmm2
+; X86-SSE2-NEXT:    andps %xmm1, %xmm2
+; X86-SSE2-NEXT:    pandn %xmm0, %xmm1
+; X86-SSE2-NEXT:    por %xmm2, %xmm1
+; X86-SSE2-NEXT:    movdqa %xmm1, %xmm0
+; X86-SSE2-NEXT:  .LBB0_2:
+; X86-SSE2-NEXT:    movd %xmm0, (%esp)
 ; X86-SSE2-NEXT:    calll __truncsfhf2
 ; X86-SSE2-NEXT:    pextrw $0, %xmm0, %eax
 ; X86-SSE2-NEXT:    movw %ax, (%esp)
 ; X86-SSE2-NEXT:    calll __extendhfsf2
 ; X86-SSE2-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-SSE2-NEXT:    cvttss2si {{[0-9]+}}(%esp), %eax
-; X86-SSE2-NEXT:    addl $8, %esp
+; X86-SSE2-NEXT:    addl $12, %esp
 ; X86-SSE2-NEXT:    retl
 ;
 ; X64-LABEL: test_lround_i32_f16:
 ; X64:       # %bb.0:
 ; X64-NEXT:    pushq %rax
 ; X64-NEXT:    callq __extendhfsf2 at PLT
-; X64-NEXT:    callq roundf at PLT
+; X64-NEXT:    movdqa {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
+; X64-NEXT:    movdqa %xmm0, %xmm2
+; X64-NEXT:    pand %xmm1, %xmm2
+; X64-NEXT:    movd %xmm2, %eax
+; X64-NEXT:    cmpl $1325400064, %eax # imm = 0x4F000000
+; X64-NEXT:    jge .LBB0_2
+; X64-NEXT:  # %bb.1:
+; X64-NEXT:    addss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
+; X64-NEXT:    cvttps2dq %xmm2, %xmm2
+; X64-NEXT:    cvtdq2ps %xmm2, %xmm2
+; X64-NEXT:    andps %xmm1, %xmm2
+; X64-NEXT:    pandn %xmm0, %xmm1
+; X64-NEXT:    por %xmm2, %xmm1
+; X64-NEXT:    movdqa %xmm1, %xmm0
+; X64-NEXT:  .LBB0_2:
 ; X64-NEXT:    callq __truncsfhf2 at PLT
 ; X64-NEXT:    callq __extendhfsf2 at PLT
 ; X64-NEXT:    cvttss2si %xmm0, %eax
diff --git a/llvm/test/CodeGen/X86/lround-conv-i64.ll b/llvm/test/CodeGen/X86/lround-conv-i64.ll
index f07e4a74bd5e3..fc9aa38a8475b 100644
--- a/llvm/test/CodeGen/X86/lround-conv-i64.ll
+++ b/llvm/test/CodeGen/X86/lround-conv-i64.ll
@@ -33,7 +33,21 @@ define i64 @test_lround_i64_f16(half %x) nounwind {
 ; X64:       # %bb.0: # %entry
 ; X64-NEXT:    pushq %rax
 ; X64-NEXT:    callq __extendhfsf2 at PLT
-; X64-NEXT:    callq roundf at PLT
+; X64-NEXT:    movdqa {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
+; X64-NEXT:    movdqa %xmm0, %xmm2
+; X64-NEXT:    pand %xmm1, %xmm2
+; X64-NEXT:    movd %xmm2, %eax
+; X64-NEXT:    cmpl $1325400064, %eax # imm = 0x4F000000
+; X64-NEXT:    jge .LBB0_2
+; X64-NEXT:  # %bb.1: # %entry
+; X64-NEXT:    addss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
+; X64-NEXT:    cvttps2dq %xmm2, %xmm2
+; X64-NEXT:    cvtdq2ps %xmm2, %xmm2
+; X64-NEXT:    andps %xmm1, %xmm2
+; X64-NEXT:    pandn %xmm0, %xmm1
+; X64-NEXT:    por %xmm2, %xmm1
+; X64-NEXT:    movdqa %xmm1, %xmm0
+; X64-NEXT:  .LBB0_2: # %entry
 ; X64-NEXT:    callq __truncsfhf2 at PLT
 ; X64-NEXT:    callq __extendhfsf2 at PLT
 ; X64-NEXT:    cvttss2si %xmm0, %rax
diff --git a/llvm/test/CodeGen/X86/unpredictable-brcond.ll b/llvm/test/CodeGen/X86/unpredictable-brcond.ll
index bb44171d20d65..ebf1178043d20 100644
--- a/llvm/test/CodeGen/X86/unpredictable-brcond.ll
+++ b/llvm/test/CodeGen/X86/unpredictable-brcond.ll
@@ -80,15 +80,34 @@ false:
 define void @isint_branch(double %d) nounwind {
   ; CHECK-LABEL: name: isint_branch
   ; CHECK: bb.0 (%ir-block.0):
-  ; CHECK-NEXT:   successors: %bb.1(0x50000000), %bb.2(0x30000000)
+  ; CHECK-NEXT:   successors: %bb.3(0x40000000), %bb.4(0x40000000)
   ; CHECK-NEXT:   liveins: $xmm0
   ; CHECK-NEXT: {{  $}}
   ; CHECK-NEXT:   [[COPY:%[0-9]+]]:fr64 = COPY $xmm0
   ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:vr128 = COPY [[COPY]]
-  ; CHECK-NEXT:   [[CVTTPD2DQrr:%[0-9]+]]:vr128 = nofpexcept CVTTPD2DQrr killed [[COPY1]], implicit $mxcsr
-  ; CHECK-NEXT:   [[CVTDQ2PDrr:%[0-9]+]]:vr128 = CVTDQ2PDrr killed [[CVTTPD2DQrr]]
-  ; CHECK-NEXT:   [[COPY2:%[0-9]+]]:fr64 = COPY killed [[CVTDQ2PDrr]]
-  ; CHECK-NEXT:   nofpexcept UCOMISDrr [[COPY]], killed [[COPY2]], implicit-def $eflags, implicit $mxcsr
+  ; CHECK-NEXT:   [[MOVAPDrm:%[0-9]+]]:vr128 = MOVAPDrm $rip, 1, $noreg, %const.0, $noreg :: (load (s128) from constant-pool)
+  ; CHECK-NEXT:   [[PANDNrr:%[0-9]+]]:vr128 = PANDNrr [[MOVAPDrm]], [[COPY1]]
+  ; CHECK-NEXT:   [[PANDrr:%[0-9]+]]:vr128 = PANDrr [[COPY1]], [[MOVAPDrm]]
+  ; CHECK-NEXT:   [[COPY2:%[0-9]+]]:fr64 = COPY killed [[PANDrr]]
+  ; CHECK-NEXT:   [[CVTTSD2SI64rr:%[0-9]+]]:gr64 = nofpexcept CVTTSD2SI64rr [[COPY2]], implicit $mxcsr
+  ; CHECK-NEXT:   [[CVTSI642SDrr:%[0-9]+]]:fr64 = nofpexcept CVTSI642SDrr killed [[CVTTSD2SI64rr]], implicit $mxcsr
+  ; CHECK-NEXT:   [[COPY3:%[0-9]+]]:vr128 = COPY killed [[CVTSI642SDrr]]
+  ; CHECK-NEXT:   [[PANDrr1:%[0-9]+]]:vr128 = PANDrr [[COPY3]], [[MOVAPDrm]]
+  ; CHECK-NEXT:   [[PORrr:%[0-9]+]]:vr128 = PORrr [[PANDrr1]], killed [[PANDNrr]]
+  ; CHECK-NEXT:   [[COPY4:%[0-9]+]]:fr64 = COPY killed [[PORrr]]
+  ; CHECK-NEXT:   [[MOVSDto64rr:%[0-9]+]]:gr64 = MOVSDto64rr [[COPY2]]
+  ; CHECK-NEXT:   [[MOV64ri:%[0-9]+]]:gr64 = MOV64ri 4841369599423283199
+  ; CHECK-NEXT:   [[SUB64rr:%[0-9]+]]:gr64 = SUB64rr [[MOVSDto64rr]], killed [[MOV64ri]], implicit-def $eflags
+  ; CHECK-NEXT:   JCC_1 %bb.4, 15, implicit $eflags
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.3 (%ir-block.0):
+  ; CHECK-NEXT:   successors: %bb.4(0x80000000)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.4 (%ir-block.0):
+  ; CHECK-NEXT:   successors: %bb.1(0x50000000), %bb.2(0x30000000)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[PHI:%[0-9]+]]:fr64 = PHI [[COPY4]], %bb.3, [[COPY]], %bb.0
+  ; CHECK-NEXT:   nofpexcept UCOMISDrr [[COPY]], killed [[PHI]], implicit-def $eflags, implicit $mxcsr
   ; CHECK-NEXT:   unpredictable JCC_1 %bb.2, 5, implicit $eflags
   ; CHECK-NEXT:   unpredictable JCC_1 %bb.2, 10, implicit $eflags
   ; CHECK-NEXT:   JMP_1 %bb.1
diff --git a/llvm/test/Transforms/SLPVectorizer/X86/fround.ll b/llvm/test/Transforms/SLPVectorizer/X86/fround.ll
index ac23a7b2e2921..7d0943a34d982 100644
--- a/llvm/test/Transforms/SLPVectorizer/X86/fround.ll
+++ b/llvm/test/Transforms/SLPVectorizer/X86/fround.ll
@@ -715,12 +715,9 @@ define void @rint_8f64() #0 {
 
 define void @trunc_2f64() #0 {
 ; SSE2-LABEL: @trunc_2f64(
-; SSE2-NEXT:    [[LD0:%.*]] = load double, ptr @src64, align 8
-; SSE2-NEXT:    [[LD1:%.*]] = load double, ptr getelementptr inbounds ([8 x double], ptr @src64, i32 0, i64 1), align 8
-; SSE2-NEXT:    [[TRUNC0:%.*]] = call double @llvm.trunc.f64(double [[LD0]])
-; SSE2-NEXT:    [[TRUNC1:%.*]] = call double @llvm.trunc.f64(double [[LD1]])
-; SSE2-NEXT:    store double [[TRUNC0]], ptr @dst64, align 8
-; SSE2-NEXT:    store double [[TRUNC1]], ptr getelementptr inbounds ([8 x double], ptr @dst64, i32 0, i64 1), align 8
+; SSE2-NEXT:    [[TMP1:%.*]] = load <2 x double>, ptr @src64, align 8
+; SSE2-NEXT:    [[TMP2:%.*]] = call <2 x double> @llvm.trunc.v2f64(<2 x double> [[TMP1]])
+; SSE2-NEXT:    store <2 x double> [[TMP2]], ptr @dst64, align 8
 ; SSE2-NEXT:    ret void
 ;
 ; SSE41-LABEL: @trunc_2f64(
@@ -746,18 +743,12 @@ define void @trunc_2f64() #0 {
 
 define void @trunc_4f64() #0 {
 ; SSE2-LABEL: @trunc_4f64(
-; SSE2-NEXT:    [[LD0:%.*]] = load double, ptr @src64, align 8
-; SSE2-NEXT:    [[LD1:%.*]] = load double, ptr getelementptr inbounds ([8 x double], ptr @src64, i32 0, i64 1), align 8
-; SSE2-NEXT:    [[LD2:%.*]] = load double, ptr getelementptr inbounds ([8 x double], ptr @src64, i32 0, i64 2), align 8
-; SSE2-NEXT:    [[LD3:%.*]] = load double, ptr getelementptr inbounds ([8 x double], ptr @src64, i32 0, i64 3), align 8
-; SSE2-NEXT:    [[TRUNC0:%.*]] = call double @llvm.trunc.f64(double [[LD0]])
-; SSE2-NEXT:    [[TRUNC1:%.*]] = call double @llvm.trunc.f64(double [[LD1]])
-; SSE2-NEXT:    [[TRUNC2:%.*]] = call double @llvm.trunc.f64(double [[LD2]])
-; SSE2-NEXT:    [[TRUNC3:%.*]] = call double @llvm.trunc.f64(double [[LD3]])
-; SSE2-NEXT:    store double [[TRUNC0]], ptr @dst64, align 8
-; SSE2-NEXT:    store double [[TRUNC1]], ptr getelementptr inbounds ([8 x double], ptr @dst64, i32 0, i64 1), align 8
-; SSE2-NEXT:    store double [[TRUNC2]], ptr getelementptr inbounds ([8 x double], ptr @dst64, i32 0, i64 2), align 8
-; SSE2-NEXT:    store double [[TRUNC3]], ptr getelementptr inbounds ([8 x double], ptr @dst64, i32 0, i64 3), align 8
+; SSE2-NEXT:    [[TMP1:%.*]] = load <2 x double>, ptr @src64, align 8
+; SSE2-NEXT:    [[TMP2:%.*]] = call <2 x double> @llvm.trunc.v2f64(<2 x double> [[TMP1]])
+; SSE2-NEXT:    store <2 x double> [[TMP2]], ptr @dst64, align 8
+; SSE2-NEXT:    [[TMP3:%.*]] = load <2 x double>, ptr getelementptr inbounds ([8 x double], ptr @src64, i32 0, i64 2), align 8
+; SSE2-NEXT:    [[TMP4:%.*]] = call <2 x double> @llvm.trunc.v2f64(<2 x double> [[TMP3]])
+; SSE2-NEXT:    store <2 x double> [[TMP4]], ptr getelementptr inbounds ([8 x double], ptr @dst64, i32 0, i64 2), align 8
 ; SSE2-NEXT:    ret void
 ;
 ; SSE41-LABEL: @trunc_4f64(
@@ -792,30 +783,18 @@ define void @trunc_4f64() #0 {
 
 define void @trunc_8f64() #0 {
 ; SSE2-LABEL: @trunc_8f64(
-; SSE2-NEXT:    [[LD0:%.*]] = load double, ptr @src64, align 8
-; SSE2-NEXT:    [[LD1:%.*]] = load double, ptr getelementptr inbounds ([8 x double], ptr @src64, i32 0, i64 1), align 8
-; SSE2-NEXT:    [[LD2:%.*]] = load double, ptr getelementptr inbounds ([8 x double], ptr @src64, i32 0, i64 2), align 8
-; SSE2-NEXT:    [[LD3:%.*]] = load double, ptr getelementptr inbounds ([8 x double], ptr @src64, i32 0, i64 3), align 8
-; SSE2-NEXT:    [[LD4:%.*]] = load double, ptr getelementptr inbounds ([8 x double], ptr @src64, i32 0, i64 4), align 8
-; SSE2-NEXT:    [[LD5:%.*]] = load double, ptr getelementptr inbounds ([8 x double], ptr @src64, i32 0, i64 5), align 8
-; SSE2-NEXT:    [[LD6:%.*]] = load double, ptr getelementptr inbounds ([8 x double], ptr @src64, i32 0, i64 6), align 8
-; SSE2-NEXT:    [[LD7:%.*]] = load double, ptr getelementptr inbounds ([8 x double], ptr @src64, i32 0, i64 7), align 8
-; SSE2-NEXT:    [[TRUNC0:%.*]] = call double @llvm.trunc.f64(double [[LD0]])
-; SSE2-NEXT:    [[TRUNC1:%.*]] = call double @llvm.trunc.f64(double [[LD1]])
-; SSE2-NEXT:    [[TRUNC2:%.*]] = call double @llvm.trunc.f64(double [[LD2]])
-; SSE2-NEXT:    [[TRUNC3:%.*]] = call double @llvm.trunc.f64(double [[LD3]])
-; SSE2-NEXT:    [[TRUNC4:%.*]] = call double @llvm.trunc.f64(double [[LD4]])
-; SSE2-NEXT:    [[TRUNC5:%.*]] = call double @llvm.trunc.f64(double [[LD5]])
-; SSE2-NEXT:    [[TRUNC6:%.*]] = call double @llvm.trunc.f64(double [[LD6]])
-; SSE2-NEXT:    [[TRUNC7:%.*]] = call double @llvm.trunc.f64(double [[LD7]])
-; SSE2-NEXT:    store double [[TRUNC0]], ptr @dst64, align 8
-; SSE2-NEXT:    store double [[TRUNC1]], ptr getelementptr inbounds ([8 x double], ptr @dst64, i32 0, i64 1), align 8
-; SSE2-NEXT:    store double [[TRUNC2]], ptr getelementptr inbounds ([8 x double], ptr @dst64, i32 0, i64 2), align 8
-; SSE2-NEXT:    store double [[TRUNC3]], ptr getelementptr inbounds ([8 x double], ptr @dst64, i32 0, i64 3), align 8
-; SSE2-NEXT:    store double [[TRUNC4]], ptr getelementptr inbounds ([8 x double], ptr @dst64, i32 0, i64 4), align 8
-; SSE2-NEXT:    store double [[TRUNC5]], ptr getelementptr inbounds ([8 x double], ptr @dst64, i32 0, i64 5), align 8
-; SSE2-NEXT:    store double [[TRUNC6]], ptr getelementptr inbounds ([8 x double], ptr @dst64, i32 0, i64 6), align 8
-; SSE2-NEXT:    store double [[TRUNC7]], ptr getelementptr inbounds ([8 x double], ptr @dst64, i32 0, i64 7), align 8
+; SSE2-NEXT:    [[TMP1:%.*]] = load <2 x double>, ptr @src64, align 8
+; SSE2-NEXT:    [[TMP2:%.*]] = call <2 x double> @llvm.trunc.v2f64(<2 x double> [[TMP1]])
+; SSE2-NEXT:    store <2 x double> [[TMP2]], ptr @dst64, align 8
+; SSE2-NEXT:    [[TMP3:%.*]] = load <2 x double>, ptr getelementptr inbounds ([8 x double], ptr @src64, i32 0, i64 2), align 8
+; SSE2-NEXT:    [[TMP4:%.*]] = call <2 x double> @llvm.trunc.v2f64(<2 x double> [[TMP3]])
+; SSE2-NEXT:    store <2 x double> [[TMP4]], ptr getelementptr inbounds ([8 x double], ptr @dst64, i32 0, i64 2), align 8
+; SSE2-NEXT:    [[TMP5:%.*]] = load <2 x double>, ptr getelementptr inbounds ([8 x double], ptr @src64, i32 0, i64 4), align 8
+; SSE2-NEXT:    [[TMP6:%.*]] = call <2 x double> @llvm.trunc.v2f64(<2 x double> [[TMP5]])
+; SSE2-NEXT:    store <2 x double> [[TMP6]], ptr getelementptr inbounds ([8 x double], ptr @dst64, i32 0, i64 4), align 8
+; SSE2-NEXT:    [[TMP7:%.*]] = load <2 x double>, ptr getelementptr inbounds ([8 x double], ptr @src64, i32 0, i64 6), align 8
+; SSE2-NEXT:    [[TMP8:%.*]] = call <2 x double> @llvm.trunc.v2f64(<2 x double> [[TMP7]])
+; SSE2-NEXT:    store <2 x double> [[TMP8]], ptr getelementptr inbounds ([8 x double], ptr @dst64, i32 0, i64 6), align 8
 ; SSE2-NEXT:    ret void
 ;
 ; SSE41-LABEL: @trunc_8f64(
@@ -1906,18 +1885,9 @@ define void @rint_16f32() #0 {
 
 define void @trunc_4f32() #0 {
 ; SSE2-LABEL: @trunc_4f32(
-; SSE2-NEXT:    [[LD0:%.*]] = load float, ptr @src32, align 4
-; SSE2-NEXT:    [[LD1:%.*]] = load float, ptr getelementptr inbounds ([16 x float], ptr @src32, i32 0, i64 1), align 4
-; SSE2-NEXT:    [[LD2:%.*]] = load float, ptr getelementptr inbounds ([16 x float], ptr @src32, i32 0, i64 2), align 4
-; SSE2-NEXT:    [[LD3:%.*]] = load float, ptr getelementptr inbounds ([16 x float], ptr @src32, i32 0, i64 3), align 4
-; SSE2-NEXT:    [[TRUNC0:%.*]] = call float @llvm.trunc.f32(float [[LD0]])
-; SSE2-NEXT:    [[TRUNC1:%.*]] = call float @llvm.trunc.f32(float [[LD1]])
-; SSE2-NEXT:    [[TRUNC2:%.*]] = call float @llvm.trunc.f32(float [[LD2]])
-; SSE2-NEXT:    [[TRUNC3:%.*]] = call float @llvm.trunc.f32(float [[LD3]])
-; SSE2-NEXT:    store float [[TRUNC0]], ptr @dst32, align 4
-; SSE2-NEXT:    store float [[TRUNC1]], ptr getelementptr inbounds ([16 x float], ptr @dst32, i32 0, i64 1), align 4
-; SSE2-NEXT:    store float [[TRUNC2]], ptr getelementptr inbounds ([16 x float], ptr @dst32, i32 0, i64 2), align 4
-; SSE2-NEXT:    store float [[TRUNC3]], ptr getelementptr inbounds ([16 x float], ptr @dst32, i32 0, i64 3), align 4
+; SSE2-NEXT:    [[TMP1:%.*]] = load <4 x float>, ptr @src32, align 4
+; SSE2-NEXT:    [[TMP2:%.*]] = call <4 x float> @llvm.trunc.v4f32(<4 x float> [[TMP1]])
+; SSE2-NEXT:    store <4 x float> [[TMP2]], ptr @dst32, align 4
 ; SSE2-NEXT:    ret void
 ;
 ; SSE41-LABEL: @trunc_4f32(
@@ -1949,30 +1919,12 @@ define void @trunc_4f32() #0 {
 
 define void @trunc_8f32() #0 {
 ; SSE2-LABEL: @trunc_8f32(
-; SSE2-NEXT:    [[LD0:%.*]] = load float, ptr @src32, align 4
-; SSE2-NEXT:    [[LD1:%.*]] = load float, ptr getelementptr inbounds ([16 x float], ptr @src32, i32 0, i64 1), align 4
-; SSE2-NEXT:    [[LD2:%.*]] = load float, ptr getelementptr inbounds ([16 x float], ptr @src32, i32 0, i64 2), align 4
-; SSE2-NEXT:    [[LD3:%.*]] = load float, ptr getelementptr inbounds ([16 x float], ptr @src32, i32 0, i64 3), align 4
-; SSE2-NEXT:    [[LD4:%.*]] = load float, ptr getelementptr inbounds ([16 x float], ptr @src32, i32 0, i64 4), align 4
-; SSE2-NEXT:    [[LD5:%.*]] = load float, ptr getelementptr inbounds ([16 x float], ptr @src32, i32 0, i64 5), align 4
-; SSE2-NEXT:    [[LD6:%.*]] = load float, ptr getelementptr inbounds ([16 x float], ptr @src32, i32 0, i64 6), align 4
-; SSE2-NEXT:    [[LD7:%.*]] = load float, ptr getelementptr inbounds ([16 x float], ptr @src32, i32 0, i64 7), align 4
-; SSE2-NEXT:    [[TRUNC0:%.*]] = call float @llvm.trunc.f32(float [[LD0]])
-; SSE2-NEXT:    [[TRUNC1:%.*]] = call float @llvm.trunc.f32(float [[LD1]])
-; SSE2-NEXT:    [[TRUNC2:%.*]] = call float @llvm.trunc.f32(float [[LD2]])
-; SSE2-NEXT:    [[TRUNC3:%.*]] = call float @llvm.trunc.f32(float [[LD3]])
-; SSE2-NEXT:    [[TRUNC4:%.*]] = call float @llvm.trunc.f32(float [[LD4]])
-; SSE2-NEXT:    [[TRUNC5:%.*]] = call float @llvm.trunc.f32(float [[LD5]])
-; SSE2-NEXT:    [[TRUNC6:%.*]] = call float @llvm.trunc.f32(float [[LD6]])
-; SSE2-NEXT:    [[TRUNC7:%.*]] = call float @llvm.trunc.f32(float [[LD7]])
-; SSE2-NEXT:    store float [[TRUNC0]], ptr @dst32, align 4
-; SSE2-NEXT:    store float [[TRUNC1]], ptr getelementptr inbounds ([16 x float], ptr @dst32, i32 0, i64 1), align 4
-; SSE2-NEXT:    store float [[TRUNC2]], ptr getelementptr inbounds ([16 x float], ptr @dst32, i32 0, i64 2), align 4
-; SSE2-NEXT:    store float [[TRUNC3]], ptr getelementptr inbounds ([16 x float], ptr @dst32, i32 0, i64 3), align 4
-; SSE2-NEXT:    store float [[TRUNC4]], ptr getelementptr inbounds ([16 x float], ptr @dst32, i32 0, i64 4), align 4
-; SSE2-NEXT:    store float [[TRUNC5]], ptr getelementptr inbounds ([16 x float], ptr @dst32, i32 0, i64 5), align 4
-; SSE2-NEXT:    store float [[TRUNC6]], ptr getelementptr inbounds ([16 x float], ptr @dst32, i32 0, i64 6), align 4
-; SSE2-NEXT:    store float [[TRUNC7]], ptr getelementptr inbounds ([16 x float], ptr @dst32, i32 0, i64 7), align 4
+; SSE2-NEXT:    [[TMP1:%.*]] = load <4 x float>, ptr @src32, align 4
+; SSE2-NEXT:    [[TMP2:%.*]] = call <4 x float> @llvm.trunc.v4f32(<4 x float> [[TMP1]])
+; SSE2-NEXT:    store <4 x float> [[TMP2]], ptr @dst32, align 4
+; SSE2-NEXT:    [[TMP3:%.*]] = load <4 x float>, ptr getelementptr inbounds ([16 x float], ptr @src32, i32 0, i64 4), align 4
+; SSE2-NEXT:    [[TMP4:%.*]] = call <4 x float> @llvm.trunc.v4f32(<4 x float> [[TMP3]])
+; SSE2-NEXT:    store <4 x float> [[TMP4]], ptr getelementptr inbounds ([16 x float], ptr @dst32, i32 0, i64 4), align 4
 ; SSE2-NEXT:    ret void
 ;
 ; SSE41-LABEL: @trunc_8f32(
@@ -2019,54 +1971,18 @@ define void @trunc_8f32() #0 {
 
 define void @trunc_16f32() #0 {
 ; SSE2-LABEL: @trunc_16f32(
-; SSE2-NEXT:    [[LD0:%.*]] = load float, ptr @src32, align 4
-; SSE2-NEXT:    [[LD1:%.*]] = load float, ptr getelementptr inbounds ([16 x float], ptr @src32, i32 0, i64 1), align 4
-; SSE2-NEXT:    [[LD2:%.*]] = load float, ptr getelementptr inbounds ([16 x float], ptr @src32, i32 0, i64 2), align 4
-; SSE2-NEXT:    [[LD3:%.*]] = load float, ptr getelementptr inbounds ([16 x float], ptr @src32, i32 0, i64 3), align 4
-; SSE2-NEXT:    [[LD4:%.*]] = load float, ptr getelementptr inbounds ([16 x float], ptr @src32, i32 0, i64 4), align 4
-; SSE2-NEXT:    [[LD5:%.*]] = load float, ptr getelementptr inbounds ([16 x float], ptr @src32, i32 0, i64 5), align 4
-; SSE2-NEXT:    [[LD6:%.*]] = load float, ptr getelementptr inbounds ([16 x float], ptr @src32, i32 0, i64 6), align 4
-; SSE2-NEXT:    [[LD7:%.*]] = load float, ptr getelementptr inbounds ([16 x float], ptr @src32, i32 0, i64 7), align 4
-; SSE2-NEXT:    [[LD8:%.*]] = load float, ptr getelementptr inbounds ([16 x float], ptr @src32, i32 0, i64 8), align 4
-; SSE2-NEXT:    [[LD9:%.*]] = load float, ptr getelementptr inbounds ([16 x float], ptr @src32, i32 0, i64 9), align 4
-; SSE2-NEXT:    [[LD10:%.*]] = load float, ptr getelementptr inbounds ([16 x float], ptr @src32, i32 0, i64 10), align 4
-; SSE2-NEXT:    [[LD11:%.*]] = load float, ptr getelementptr inbounds ([16 x float], ptr @src32, i32 0, i64 11), align 4
-; SSE2-NEXT:    [[LD12:%.*]] = load float, ptr getelementptr inbounds ([16 x float], ptr @src32, i32 0, i64 12), align 4
-; SSE2-NEXT:    [[LD13:%.*]] = load float, ptr getelementptr inbounds ([16 x float], ptr @src32, i32 0, i64 13), align 4
-; SSE2-NEXT:    [[LD14:%.*]] = load float, ptr getelementptr inbounds ([16 x float], ptr @src32, i32 0, i64 14), align 4
-; SSE2-NEXT:    [[LD15:%.*]] = load float, ptr getelementptr inbounds ([16 x float], ptr @src32, i32 0, i64 15), align 4
-; SSE2-NEXT:    [[TRUNC0:%.*]] = call float @llvm.trunc.f32(float [[LD0]])
-; SSE2-NEXT:    [[TRUNC1:%.*]] = call float @llvm.trunc.f32(float [[LD1]])
-; SSE2-NEXT:    [[TRUNC2:%.*]] = call float @llvm.trunc.f32(float [[LD2]])
-; SSE2-NEXT:    [[TRUNC3:%.*]] = call float @llvm.trunc.f32(float [[LD3]])
-; SSE2-NEXT:    [[TRUNC4:%.*]] = call float @llvm.trunc.f32(float [[LD4]])
-; SSE2-NEXT:    [[TRUNC5:%.*]] = call float @llvm.trunc.f32(float [[LD5]])
-; SSE2-NEXT:    [[TRUNC6:%.*]] = call float @llvm.trunc.f32(float [[LD6]])
-; SSE2-NEXT:    [[TRUNC7:%.*]] = call float @llvm.trunc.f32(float [[LD7]])
-; SSE2-NEXT:    [[TRUNC8:%.*]] = call float @llvm.trunc.f32(float [[LD8]])
-; SSE2-NEXT:    [[TRUNC9:%.*]] = call float @llvm.trunc.f32(float [[LD9]])
-; SSE2-NEXT:    [[TRUNC10:%.*]] = call float @llvm.trunc.f32(float [[LD10]])
-; SSE2-NEXT:    [[TRUNC11:%.*]] = call float @llvm.trunc.f32(float [[LD11]])
-; SSE2-NEXT:    [[TRUNC12:%.*]] = call float @llvm.trunc.f32(float [[LD12]])
-; SSE2-NEXT:    [[TRUNC13:%.*]] = call float @llvm.trunc.f32(float [[LD13]])
-; SSE2-NEXT:    [[TRUNC14:%.*]] = call float @llvm.trunc.f32(float [[LD14]])
-; SSE2-NEXT:    [[TRUNC15:%.*]] = call float @llvm.trunc.f32(float [[LD15]])
-; SSE2-NEXT:    store float [[TRUNC0]], ptr @dst32, align 4
-; SSE2-NEXT:    store float [[TRUNC1]], ptr getelementptr inbounds ([16 x float], ptr @dst32, i32 0, i64 1), align 4
-; SSE2-NEXT:    store float [[TRUNC2]], ptr getelementptr inbounds ([16 x float], ptr @dst32, i32 0, i64 2), align 4
-; SSE2-NEXT:    store float [[TRUNC3]], ptr getelementptr inbounds ([16 x float], ptr @dst32, i32 0, i64 3), align 4
-; SSE2-NEXT:    store float [[TRUNC4]], ptr getelementptr inbounds ([16 x float], ptr @dst32, i32 0, i64 4), align 4
-; SSE2-NEXT:    store float [[TRUNC5]], ptr getelementptr inbounds ([16 x float], ptr @dst32, i32 0, i64 5), align 4
-; SSE2-NEXT:    store float [[TRUNC6]], ptr getelementptr inbounds ([16 x float], ptr @dst32, i32 0, i64 6), align 4
-; SSE2-NEXT:    store float [[TRUNC7]], ptr getelementptr inbounds ([16 x float], ptr @dst32, i32 0, i64 7), align 4
-; SSE2-NEXT:    store float [[TRUNC8]], ptr getelementptr inbounds ([16 x float], ptr @dst32, i32 0, i64 8), align 4
-; SSE2-NEXT:    store float [[TRUNC9]], ptr getelementptr inbounds ([16 x float], ptr @dst32, i32 0, i64 9), align 4
-; SSE2-NEXT:    store float [[TRUNC10]], ptr getelementptr inbounds ([16 x float], ptr @dst32, i32 0, i64 10), align 4
-; SSE2-NEXT:    store float [[TRUNC11]], ptr getelementptr inbounds ([16 x float], ptr @dst32, i32 0, i64 11), align 4
-; SSE2-NEXT:    store float [[TRUNC12]], ptr getelementptr inbounds ([16 x float], ptr @dst32, i32 0, i64 12), align 4
-; SSE2-NEXT:    store float [[TRUNC13]], ptr getelementptr inbounds ([16 x float], ptr @dst32, i32 0, i64 13), align 4
-; SSE2-NEXT:    store float [[TRUNC14]], ptr getelementptr inbounds ([16 x float], ptr @dst32, i32 0, i64 14), align 4
-; SSE2-NEXT:    store float [[TRUNC15]], ptr getelementptr inbounds ([16 x float], ptr @dst32, i32 0, i64 15), align 4
+; SSE2-NEXT:    [[TMP1:%.*]] = load <4 x float>, ptr @src32, align 4
+; SSE2-NEXT:    [[TMP2:%.*]] = call <4 x float> @llvm.trunc.v4f32(<4 x float> [[TMP1]])
+; SSE2-NEXT:    store <4 x float> [[TMP2]], ptr @dst32, align 4
+; SSE2-NEXT:    [[TMP3:%.*]] = load <4 x float>, ptr getelementptr inbounds ([16 x float], ptr @src32, i32 0, i64 4), align 4
+; SSE2-NEXT:    [[TMP4:%.*]] = call <4 x float> @llvm.trunc.v4f32(<4 x float> [[TMP3]])
+; SSE2-NEXT:    store <4 x float> [[TMP4]], ptr getelementptr inbounds ([16 x float], ptr @dst32, i32 0, i64 4), align 4
+; SSE2-NEXT:    [[TMP5:%.*]] = load <4 x float>, ptr getelementptr inbounds ([16 x float], ptr @src32, i32 0, i64 8), align 4
+; SSE2-NEXT:    [[TMP6:%.*]] = call <4 x float> @llvm.trunc.v4f32(<4 x float> [[TMP5]])
+; SSE2-NEXT:    store <4 x float> [[TMP6]], ptr getelementptr inbounds ([16 x float], ptr @dst32, i32 0, i64 8), align 4
+; SSE2-NEXT:    [[TMP7:%.*]] = load <4 x float>, ptr getelementptr inbounds ([16 x float], ptr @src32, i32 0, i64 12), align 4
+; SSE2-NEXT:    [[TMP8:%.*]] = call <4 x float> @llvm.trunc.v4f32(<4 x float> [[TMP7]])
+; SSE2-NEXT:    store <4 x float> [[TMP8]], ptr getelementptr inbounds ([16 x float], ptr @dst32, i32 0, i64 12), align 4
 ; SSE2-NEXT:    ret void
 ;
 ; SSE41-LABEL: @trunc_16f32(

>From 5cfb995893ebb4f0ede103cdbf24ff0c5d261133 Mon Sep 17 00:00:00 2001
From: Divyansh <anshmcs at gmail.com>
Date: Fri, 25 Sep 2026 21:16:06 +0530
Subject: [PATCH 2/8] Apply clang-format fixes

---
 llvm/lib/Target/X86/X86ISelLowering.cpp | 25 ++++++++++++++++---------
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index c819efa95a515..08d1f549c2c5d 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -1101,7 +1101,7 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
     for (auto VT : { MVT::f64, MVT::v4f32, MVT::v2f64 })
       SetFPMinMaxAction(VT);
 
-    for (auto VT : { MVT::v4f32, MVT::v2f64 }) {
+    for (auto VT : {MVT::v4f32, MVT::v2f64}) {
       if (VT == MVT::v4f32 || Subtarget.is64Bit()) {
         setOperationAction(ISD::FTRUNC, VT, Custom);
         setOperationAction(ISD::FROUND, VT, Custom);
@@ -23203,16 +23203,22 @@ static SDValue lowerFTRUNC_FROUND_SSE2(SDValue Op, SelectionDAG &DAG) {
     APFloat Bias = APFloat(0.5f);
     bool Ignored;
     Bias.convert(Sem, APFloat::rmNearestTiesToEven, &Ignored);
-    Bias.next(/*nextDown*/true);
-    AbsBiased = DAG.getNode(ISD::FADD, DL, VT, Abs, DAG.getConstantFP(Bias, DL, VT));
+    Bias.next(/*nextDown*/ true);
+    AbsBiased =
+        DAG.getNode(ISD::FADD, DL, VT, Abs, DAG.getConstantFP(Bias, DL, VT));
   }
 
   MVT IntVT;
-  if (VT == MVT::f32) IntVT = MVT::i32;
-  else if (VT == MVT::f64) IntVT = MVT::i64;
-  else if (VT == MVT::v4f32) IntVT = MVT::v4i32;
-  else if (VT == MVT::v2f64) IntVT = MVT::v2i64;
-  else llvm_unreachable("Unexpected type");
+  if (VT == MVT::f32)
+    IntVT = MVT::i32;
+  else if (VT == MVT::f64)
+    IntVT = MVT::i64;
+  else if (VT == MVT::v4f32)
+    IntVT = MVT::v4i32;
+  else if (VT == MVT::v2f64)
+    IntVT = MVT::v2i64;
+  else
+    llvm_unreachable("Unexpected type");
 
   SDValue AbsInt = DAG.getBitcast(IntVT, Abs);
 
@@ -23223,7 +23229,8 @@ static SDValue lowerFTRUNC_FROUND_SSE2(SDValue Op, SelectionDAG &DAG) {
     Threshold = DAG.getConstant(0x432FFFFFFFFFFFFFULL, DL, IntVT);
   }
 
-  EVT CCVT = DAG.getTargetLoweringInfo().getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), IntVT);
+  EVT CCVT = DAG.getTargetLoweringInfo().getSetCCResultType(
+      DAG.getDataLayout(), *DAG.getContext(), IntVT);
   SDValue IsLarge = DAG.getSetCC(DL, CCVT, AbsInt, Threshold, ISD::SETGT);
 
   SDValue TruncInt = DAG.getNode(ISD::FP_TO_SINT, DL, IntVT, AbsBiased);

>From d3204ba84199669da8775bcc8f5662a16d8f6f2f Mon Sep 17 00:00:00 2001
From: Divyansh <anshmcs at gmail.com>
Date: Sat, 26 Sep 2026 01:13:20 +0530
Subject: [PATCH 3/8] [X86] Use unordered FP comparison and 2^23/2^52 bounds
 for SSE2 trunc and round

---
 llvm/lib/Target/X86/X86ISelLowering.cpp       |  17 +-
 llvm/test/CodeGen/X86/fp-round.ll             | 284 +++++++++---------
 llvm/test/CodeGen/X86/fp16-libcalls.ll        |  55 ++--
 llvm/test/CodeGen/X86/freeze-unary.ll         |  65 ++--
 llvm/test/CodeGen/X86/ftrunc.ll               | 152 ++++------
 llvm/test/CodeGen/X86/isel-ftrunc.ll          |  50 ++-
 llvm/test/CodeGen/X86/isint.ll                | 134 ++++-----
 llvm/test/CodeGen/X86/llround-conv.ll         |  54 ++--
 llvm/test/CodeGen/X86/lround-conv-i32.ll      |  61 ++--
 llvm/test/CodeGen/X86/lround-conv-i64.ll      |  27 +-
 llvm/test/CodeGen/X86/unpredictable-brcond.ll |  23 +-
 11 files changed, 429 insertions(+), 493 deletions(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 08d1f549c2c5d..e7d6a0a2d788f 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -23220,18 +23220,15 @@ static SDValue lowerFTRUNC_FROUND_SSE2(SDValue Op, SelectionDAG &DAG) {
   else
     llvm_unreachable("Unexpected type");
 
-  SDValue AbsInt = DAG.getBitcast(IntVT, Abs);
-
-  SDValue Threshold;
-  if (VT.getScalarType() == MVT::f32) {
-    Threshold = DAG.getConstant(0x4EFFFFFF, DL, IntVT);
-  } else {
-    Threshold = DAG.getConstant(0x432FFFFFFFFFFFFFULL, DL, IntVT);
-  }
+  const fltSemantics &Sem = VT.getFltSemantics();
+  APFloat Bound = VT.getScalarType() == MVT::f32
+                      ? APFloat(Sem, "0x1.0p23")
+                      : APFloat(Sem, "0x1.0p52");
+  SDValue Threshold = DAG.getConstantFP(Bound, DL, VT);
 
   EVT CCVT = DAG.getTargetLoweringInfo().getSetCCResultType(
-      DAG.getDataLayout(), *DAG.getContext(), IntVT);
-  SDValue IsLarge = DAG.getSetCC(DL, CCVT, AbsInt, Threshold, ISD::SETGT);
+      DAG.getDataLayout(), *DAG.getContext(), VT);
+  SDValue IsLarge = DAG.getSetCC(DL, CCVT, Abs, Threshold, ISD::SETUGE);
 
   SDValue TruncInt = DAG.getNode(ISD::FP_TO_SINT, DL, IntVT, AbsBiased);
   SDValue AbsTrunc = DAG.getNode(ISD::SINT_TO_FP, DL, VT, TruncInt);
diff --git a/llvm/test/CodeGen/X86/fp-round.ll b/llvm/test/CodeGen/X86/fp-round.ll
index 145a922e12b9e..797e8fbe7dafd 100644
--- a/llvm/test/CodeGen/X86/fp-round.ll
+++ b/llvm/test/CodeGen/X86/fp-round.ll
@@ -11,21 +11,20 @@ define half @round_f16(half %h) {
 ; SSE2-NEXT:    pushq %rax
 ; SSE2-NEXT:    .cfi_def_cfa_offset 16
 ; SSE2-NEXT:    callq __extendhfsf2 at PLT
-; SSE2-NEXT:    movdqa {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
-; SSE2-NEXT:    movdqa %xmm0, %xmm2
-; SSE2-NEXT:    pand %xmm1, %xmm2
-; SSE2-NEXT:    movd %xmm2, %eax
-; SSE2-NEXT:    cmpl $1325400064, %eax # imm = 0x4F000000
-; SSE2-NEXT:    jge .LBB0_2
-; SSE2-NEXT:  # %bb.1: # %entry
-; SSE2-NEXT:    addss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
-; SSE2-NEXT:    cvttps2dq %xmm2, %xmm2
-; SSE2-NEXT:    cvtdq2ps %xmm2, %xmm2
+; SSE2-NEXT:    movaps {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
+; SSE2-NEXT:    movaps %xmm0, %xmm2
 ; SSE2-NEXT:    andps %xmm1, %xmm2
-; SSE2-NEXT:    pandn %xmm0, %xmm1
-; SSE2-NEXT:    por %xmm2, %xmm1
-; SSE2-NEXT:    movdqa %xmm1, %xmm0
-; SSE2-NEXT:  .LBB0_2: # %entry
+; SSE2-NEXT:    movss {{.*#+}} xmm3 = [4.9999997E-1,0.0E+0,0.0E+0,0.0E+0]
+; SSE2-NEXT:    addss %xmm2, %xmm3
+; SSE2-NEXT:    cvttps2dq %xmm3, %xmm3
+; SSE2-NEXT:    cvtdq2ps %xmm3, %xmm3
+; SSE2-NEXT:    andps %xmm1, %xmm3
+; SSE2-NEXT:    andnps %xmm0, %xmm1
+; SSE2-NEXT:    orps %xmm1, %xmm3
+; SSE2-NEXT:    cmpnltss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
+; SSE2-NEXT:    andps %xmm2, %xmm0
+; SSE2-NEXT:    andnps %xmm3, %xmm2
+; SSE2-NEXT:    orps %xmm2, %xmm0
 ; SSE2-NEXT:    callq __truncsfhf2 at PLT
 ; SSE2-NEXT:    popq %rax
 ; SSE2-NEXT:    .cfi_def_cfa_offset 8
@@ -88,21 +87,20 @@ entry:
 define float @round_f32(float %x) {
 ; SSE2-LABEL: round_f32:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    movdqa {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
-; SSE2-NEXT:    movdqa %xmm0, %xmm2
-; SSE2-NEXT:    pand %xmm1, %xmm2
-; SSE2-NEXT:    movd %xmm2, %eax
-; SSE2-NEXT:    cmpl $1325400064, %eax # imm = 0x4F000000
-; SSE2-NEXT:    jge .LBB1_2
-; SSE2-NEXT:  # %bb.1:
-; SSE2-NEXT:    addss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
-; SSE2-NEXT:    cvttps2dq %xmm2, %xmm2
-; SSE2-NEXT:    cvtdq2ps %xmm2, %xmm2
+; SSE2-NEXT:    movaps {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
+; SSE2-NEXT:    movaps %xmm0, %xmm2
 ; SSE2-NEXT:    andps %xmm1, %xmm2
-; SSE2-NEXT:    pandn %xmm0, %xmm1
-; SSE2-NEXT:    por %xmm2, %xmm1
-; SSE2-NEXT:    movdqa %xmm1, %xmm0
-; SSE2-NEXT:  .LBB1_2:
+; SSE2-NEXT:    movss {{.*#+}} xmm3 = [4.9999997E-1,0.0E+0,0.0E+0,0.0E+0]
+; SSE2-NEXT:    addss %xmm2, %xmm3
+; SSE2-NEXT:    cvttps2dq %xmm3, %xmm3
+; SSE2-NEXT:    cvtdq2ps %xmm3, %xmm3
+; SSE2-NEXT:    andps %xmm1, %xmm3
+; SSE2-NEXT:    andnps %xmm0, %xmm1
+; SSE2-NEXT:    orps %xmm1, %xmm3
+; SSE2-NEXT:    cmpnltss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
+; SSE2-NEXT:    andps %xmm2, %xmm0
+; SSE2-NEXT:    andnps %xmm3, %xmm2
+; SSE2-NEXT:    orps %xmm2, %xmm0
 ; SSE2-NEXT:    retq
 ;
 ; SSE41-LABEL: round_f32:
@@ -146,23 +144,21 @@ define float @round_f32(float %x) {
 define double @round_f64(double %x) {
 ; SSE2-LABEL: round_f64:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    movdqa {{.*#+}} xmm1 = [NaN,NaN]
-; SSE2-NEXT:    movdqa %xmm0, %xmm2
-; SSE2-NEXT:    pand %xmm1, %xmm2
-; SSE2-NEXT:    movq %xmm2, %rax
-; SSE2-NEXT:    movabsq $4841369599423283199, %rcx # imm = 0x432FFFFFFFFFFFFF
-; SSE2-NEXT:    cmpq %rcx, %rax
-; SSE2-NEXT:    jg .LBB2_2
-; SSE2-NEXT:  # %bb.1:
-; SSE2-NEXT:    addsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
-; SSE2-NEXT:    cvttsd2si %xmm2, %rax
-; SSE2-NEXT:    xorps %xmm2, %xmm2
-; SSE2-NEXT:    cvtsi2sd %rax, %xmm2
+; SSE2-NEXT:    movapd {{.*#+}} xmm1 = [NaN,NaN]
+; SSE2-NEXT:    movapd %xmm0, %xmm2
 ; SSE2-NEXT:    andpd %xmm1, %xmm2
-; SSE2-NEXT:    pandn %xmm0, %xmm1
-; SSE2-NEXT:    por %xmm2, %xmm1
-; SSE2-NEXT:    movdqa %xmm1, %xmm0
-; SSE2-NEXT:  .LBB2_2:
+; SSE2-NEXT:    movsd {{.*#+}} xmm3 = [4.9999999999999994E-1,0.0E+0]
+; SSE2-NEXT:    addsd %xmm2, %xmm3
+; SSE2-NEXT:    cvttsd2si %xmm3, %rax
+; SSE2-NEXT:    xorps %xmm3, %xmm3
+; SSE2-NEXT:    cvtsi2sd %rax, %xmm3
+; SSE2-NEXT:    andpd %xmm1, %xmm3
+; SSE2-NEXT:    andnpd %xmm0, %xmm1
+; SSE2-NEXT:    orpd %xmm1, %xmm3
+; SSE2-NEXT:    cmpnltsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
+; SSE2-NEXT:    andpd %xmm2, %xmm0
+; SSE2-NEXT:    andnpd %xmm3, %xmm2
+; SSE2-NEXT:    orpd %xmm2, %xmm0
 ; SSE2-NEXT:    retq
 ;
 ; SSE41-LABEL: round_f64:
@@ -217,7 +213,7 @@ define <4 x float> @round_v4f32(<4 x float> %x) {
 ; SSE2-NEXT:    andps %xmm1, %xmm3
 ; SSE2-NEXT:    andnps %xmm0, %xmm1
 ; SSE2-NEXT:    orps %xmm1, %xmm3
-; SSE2-NEXT:    pcmpgtd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
+; SSE2-NEXT:    cmpnltps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
 ; SSE2-NEXT:    andps %xmm2, %xmm0
 ; SSE2-NEXT:    andnps %xmm3, %xmm2
 ; SSE2-NEXT:    orps %xmm2, %xmm0
@@ -262,25 +258,25 @@ define <4 x float> @round_v4f32(<4 x float> %x) {
 define <2 x double> @round_v2f64(<2 x double> %x) {
 ; SSE2-LABEL: round_v2f64:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    movdqa {{.*#+}} xmm1 = [NaN,NaN]
-; SSE2-NEXT:    movdqa %xmm0, %xmm2
-; SSE2-NEXT:    pand %xmm1, %xmm2
-; SSE2-NEXT:    pshufd {{.*#+}} xmm3 = xmm2[1,1,3,3]
-; SSE2-NEXT:    addpd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
-; SSE2-NEXT:    cvttsd2si %xmm2, %rax
+; SSE2-NEXT:    movapd {{.*#+}} xmm1 = [NaN,NaN]
+; SSE2-NEXT:    movapd %xmm0, %xmm2
+; SSE2-NEXT:    andpd %xmm1, %xmm2
+; SSE2-NEXT:    movapd {{.*#+}} xmm3 = [4.9999999999999994E-1,4.9999999999999994E-1]
+; SSE2-NEXT:    addpd %xmm2, %xmm3
+; SSE2-NEXT:    cvttsd2si %xmm3, %rax
 ; SSE2-NEXT:    cvtsi2sd %rax, %xmm4
-; SSE2-NEXT:    unpckhpd {{.*#+}} xmm2 = xmm2[1,1]
-; SSE2-NEXT:    cvttsd2si %xmm2, %rax
-; SSE2-NEXT:    xorps %xmm2, %xmm2
-; SSE2-NEXT:    cvtsi2sd %rax, %xmm2
-; SSE2-NEXT:    unpcklpd {{.*#+}} xmm4 = xmm4[0],xmm2[0]
+; SSE2-NEXT:    unpckhpd {{.*#+}} xmm3 = xmm3[1,1]
+; SSE2-NEXT:    cvttsd2si %xmm3, %rax
+; SSE2-NEXT:    xorps %xmm3, %xmm3
+; SSE2-NEXT:    cvtsi2sd %rax, %xmm3
+; SSE2-NEXT:    unpcklpd {{.*#+}} xmm4 = xmm4[0],xmm3[0]
 ; SSE2-NEXT:    andpd %xmm1, %xmm4
-; SSE2-NEXT:    pandn %xmm0, %xmm1
-; SSE2-NEXT:    por %xmm4, %xmm1
-; SSE2-NEXT:    pcmpgtd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm3
-; SSE2-NEXT:    pand %xmm3, %xmm0
-; SSE2-NEXT:    pandn %xmm1, %xmm3
-; SSE2-NEXT:    por %xmm3, %xmm0
+; SSE2-NEXT:    andnpd %xmm0, %xmm1
+; SSE2-NEXT:    orpd %xmm4, %xmm1
+; SSE2-NEXT:    cmpnltpd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
+; SSE2-NEXT:    andpd %xmm2, %xmm0
+; SSE2-NEXT:    andnpd %xmm1, %xmm2
+; SSE2-NEXT:    orpd %xmm2, %xmm0
 ; SSE2-NEXT:    retq
 ;
 ; SSE41-LABEL: round_v2f64:
@@ -340,14 +336,14 @@ define <8 x float> @round_v8f32(<8 x float> %x) {
 ; SSE2-NEXT:    andps %xmm3, %xmm4
 ; SSE2-NEXT:    andnps %xmm0, %xmm3
 ; SSE2-NEXT:    orps %xmm3, %xmm5
-; SSE2-NEXT:    movdqa {{.*#+}} xmm3 = [1325400063,1325400063,1325400063,1325400063]
-; SSE2-NEXT:    pcmpgtd %xmm3, %xmm2
+; SSE2-NEXT:    movaps {{.*#+}} xmm3 = [8.388608E+6,8.388608E+6,8.388608E+6,8.388608E+6]
+; SSE2-NEXT:    cmpnltps %xmm3, %xmm2
 ; SSE2-NEXT:    andps %xmm2, %xmm0
 ; SSE2-NEXT:    andnps %xmm5, %xmm2
 ; SSE2-NEXT:    orps %xmm2, %xmm0
 ; SSE2-NEXT:    andnps %xmm1, %xmm6
 ; SSE2-NEXT:    orps %xmm6, %xmm4
-; SSE2-NEXT:    pcmpgtd %xmm3, %xmm7
+; SSE2-NEXT:    cmpnltps %xmm3, %xmm7
 ; SSE2-NEXT:    andps %xmm7, %xmm1
 ; SSE2-NEXT:    andnps %xmm4, %xmm7
 ; SSE2-NEXT:    orps %xmm7, %xmm1
@@ -398,28 +394,28 @@ define <8 x float> @round_v8f32(<8 x float> %x) {
 define <4 x double> @round_v4f64(<4 x double> %x) {
 ; SSE2-LABEL: round_v4f64:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    movdqa {{.*#+}} xmm2 = [NaN,NaN]
-; SSE2-NEXT:    movdqa %xmm0, %xmm4
-; SSE2-NEXT:    pand %xmm2, %xmm4
+; SSE2-NEXT:    movapd {{.*#+}} xmm2 = [NaN,NaN]
+; SSE2-NEXT:    movapd %xmm0, %xmm4
+; SSE2-NEXT:    andpd %xmm2, %xmm4
 ; SSE2-NEXT:    movapd {{.*#+}} xmm3 = [4.9999999999999994E-1,4.9999999999999994E-1]
-; SSE2-NEXT:    pshufd {{.*#+}} xmm5 = xmm4[1,1,3,3]
-; SSE2-NEXT:    addpd %xmm3, %xmm4
-; SSE2-NEXT:    cvttsd2si %xmm4, %rax
+; SSE2-NEXT:    movapd %xmm4, %xmm5
+; SSE2-NEXT:    addpd %xmm3, %xmm5
+; SSE2-NEXT:    cvttsd2si %xmm5, %rax
 ; SSE2-NEXT:    cvtsi2sd %rax, %xmm6
-; SSE2-NEXT:    unpckhpd {{.*#+}} xmm4 = xmm4[1,1]
-; SSE2-NEXT:    cvttsd2si %xmm4, %rax
-; SSE2-NEXT:    xorps %xmm4, %xmm4
-; SSE2-NEXT:    cvtsi2sd %rax, %xmm4
-; SSE2-NEXT:    unpcklpd {{.*#+}} xmm6 = xmm6[0],xmm4[0]
+; SSE2-NEXT:    unpckhpd {{.*#+}} xmm5 = xmm5[1,1]
+; SSE2-NEXT:    cvttsd2si %xmm5, %rax
+; SSE2-NEXT:    xorps %xmm5, %xmm5
+; SSE2-NEXT:    cvtsi2sd %rax, %xmm5
+; SSE2-NEXT:    unpcklpd {{.*#+}} xmm6 = xmm6[0],xmm5[0]
 ; SSE2-NEXT:    andpd %xmm2, %xmm6
-; SSE2-NEXT:    movdqa %xmm2, %xmm4
-; SSE2-NEXT:    pandn %xmm0, %xmm4
-; SSE2-NEXT:    por %xmm6, %xmm4
-; SSE2-NEXT:    movdqa {{.*#+}} xmm6 = [1127219199,1127219199,1127219199,1127219199]
-; SSE2-NEXT:    pcmpgtd %xmm6, %xmm5
-; SSE2-NEXT:    pand %xmm5, %xmm0
-; SSE2-NEXT:    pandn %xmm4, %xmm5
-; SSE2-NEXT:    por %xmm5, %xmm0
+; SSE2-NEXT:    movapd %xmm2, %xmm5
+; SSE2-NEXT:    andnpd %xmm0, %xmm5
+; SSE2-NEXT:    orpd %xmm6, %xmm5
+; SSE2-NEXT:    movapd {{.*#+}} xmm6 = [4.503599627370496E+15,4.503599627370496E+15]
+; SSE2-NEXT:    cmpnltpd %xmm6, %xmm4
+; SSE2-NEXT:    andpd %xmm4, %xmm0
+; SSE2-NEXT:    andnpd %xmm5, %xmm4
+; SSE2-NEXT:    orpd %xmm4, %xmm0
 ; SSE2-NEXT:    movapd %xmm1, %xmm4
 ; SSE2-NEXT:    andpd %xmm2, %xmm4
 ; SSE2-NEXT:    addpd %xmm4, %xmm3
@@ -434,11 +430,10 @@ define <4 x double> @round_v4f64(<4 x double> %x) {
 ; SSE2-NEXT:    andpd %xmm2, %xmm5
 ; SSE2-NEXT:    andnpd %xmm1, %xmm2
 ; SSE2-NEXT:    orpd %xmm5, %xmm2
-; SSE2-NEXT:    pshufd {{.*#+}} xmm3 = xmm4[1,1,3,3]
-; SSE2-NEXT:    pcmpgtd %xmm6, %xmm3
-; SSE2-NEXT:    andpd %xmm3, %xmm1
-; SSE2-NEXT:    andnpd %xmm2, %xmm3
-; SSE2-NEXT:    orpd %xmm3, %xmm1
+; SSE2-NEXT:    cmpnltpd %xmm6, %xmm4
+; SSE2-NEXT:    andpd %xmm4, %xmm1
+; SSE2-NEXT:    andnpd %xmm2, %xmm4
+; SSE2-NEXT:    orpd %xmm4, %xmm1
 ; SSE2-NEXT:    retq
 ;
 ; SSE41-LABEL: round_v4f64:
@@ -520,26 +515,26 @@ define <16 x float> @round_v16f32(<16 x float> %x) {
 ; SSE2-NEXT:    andps %xmm5, %xmm7
 ; SSE2-NEXT:    andnps %xmm0, %xmm5
 ; SSE2-NEXT:    orps %xmm5, %xmm6
-; SSE2-NEXT:    movdqa {{.*#+}} xmm5 = [1325400063,1325400063,1325400063,1325400063]
-; SSE2-NEXT:    pcmpgtd %xmm5, %xmm4
+; SSE2-NEXT:    movaps {{.*#+}} xmm5 = [8.388608E+6,8.388608E+6,8.388608E+6,8.388608E+6]
+; SSE2-NEXT:    cmpnltps %xmm5, %xmm4
 ; SSE2-NEXT:    andps %xmm4, %xmm0
 ; SSE2-NEXT:    andnps %xmm6, %xmm4
 ; SSE2-NEXT:    orps %xmm4, %xmm0
 ; SSE2-NEXT:    andnps %xmm1, %xmm9
 ; SSE2-NEXT:    orps %xmm9, %xmm10
-; SSE2-NEXT:    pcmpgtd %xmm5, %xmm8
+; SSE2-NEXT:    cmpnltps %xmm5, %xmm8
 ; SSE2-NEXT:    andps %xmm8, %xmm1
 ; SSE2-NEXT:    andnps %xmm10, %xmm8
 ; SSE2-NEXT:    orps %xmm8, %xmm1
 ; SSE2-NEXT:    andnps %xmm2, %xmm12
 ; SSE2-NEXT:    orps %xmm12, %xmm13
-; SSE2-NEXT:    pcmpgtd %xmm5, %xmm11
+; SSE2-NEXT:    cmpnltps %xmm5, %xmm11
 ; SSE2-NEXT:    andps %xmm11, %xmm2
 ; SSE2-NEXT:    andnps %xmm13, %xmm11
 ; SSE2-NEXT:    orps %xmm11, %xmm2
 ; SSE2-NEXT:    andnps %xmm3, %xmm15
 ; SSE2-NEXT:    orps %xmm15, %xmm7
-; SSE2-NEXT:    pcmpgtd %xmm5, %xmm14
+; SSE2-NEXT:    cmpnltps %xmm5, %xmm14
 ; SSE2-NEXT:    andps %xmm14, %xmm3
 ; SSE2-NEXT:    andnps %xmm7, %xmm14
 ; SSE2-NEXT:    orps %xmm14, %xmm3
@@ -606,11 +601,11 @@ define <16 x float> @round_v16f32(<16 x float> %x) {
 define <8 x double> @round_v8f64(<8 x double> %x) {
 ; SSE2-LABEL: round_v8f64:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    movdqa {{.*#+}} xmm4 = [NaN,NaN]
-; SSE2-NEXT:    movdqa %xmm0, %xmm6
-; SSE2-NEXT:    pand %xmm4, %xmm6
+; SSE2-NEXT:    movapd {{.*#+}} xmm4 = [NaN,NaN]
+; SSE2-NEXT:    movapd %xmm0, %xmm7
+; SSE2-NEXT:    andpd %xmm4, %xmm7
 ; SSE2-NEXT:    movapd {{.*#+}} xmm5 = [4.9999999999999994E-1,4.9999999999999994E-1]
-; SSE2-NEXT:    pshufd {{.*#+}} xmm7 = xmm6[1,1,3,3]
+; SSE2-NEXT:    movapd %xmm7, %xmm6
 ; SSE2-NEXT:    addpd %xmm5, %xmm6
 ; SSE2-NEXT:    cvttsd2si %xmm6, %rax
 ; SSE2-NEXT:    cvtsi2sd %rax, %xmm8
@@ -620,54 +615,54 @@ define <8 x double> @round_v8f64(<8 x double> %x) {
 ; SSE2-NEXT:    cvtsi2sd %rax, %xmm6
 ; SSE2-NEXT:    unpcklpd {{.*#+}} xmm8 = xmm8[0],xmm6[0]
 ; SSE2-NEXT:    andpd %xmm4, %xmm8
-; SSE2-NEXT:    movdqa %xmm4, %xmm9
-; SSE2-NEXT:    pandn %xmm0, %xmm9
-; SSE2-NEXT:    por %xmm8, %xmm9
-; SSE2-NEXT:    movdqa {{.*#+}} xmm6 = [1127219199,1127219199,1127219199,1127219199]
-; SSE2-NEXT:    pcmpgtd %xmm6, %xmm7
-; SSE2-NEXT:    pand %xmm7, %xmm0
-; SSE2-NEXT:    pandn %xmm9, %xmm7
-; SSE2-NEXT:    por %xmm7, %xmm0
-; SSE2-NEXT:    movdqa %xmm1, %xmm7
-; SSE2-NEXT:    pand %xmm4, %xmm7
-; SSE2-NEXT:    pshufd {{.*#+}} xmm8 = xmm7[1,1,3,3]
-; SSE2-NEXT:    addpd %xmm5, %xmm7
-; SSE2-NEXT:    cvttsd2si %xmm7, %rax
+; SSE2-NEXT:    movapd %xmm4, %xmm9
+; SSE2-NEXT:    andnpd %xmm0, %xmm9
+; SSE2-NEXT:    orpd %xmm8, %xmm9
+; SSE2-NEXT:    movapd {{.*#+}} xmm6 = [4.503599627370496E+15,4.503599627370496E+15]
+; SSE2-NEXT:    cmpnltpd %xmm6, %xmm7
+; SSE2-NEXT:    andpd %xmm7, %xmm0
+; SSE2-NEXT:    andnpd %xmm9, %xmm7
+; SSE2-NEXT:    orpd %xmm7, %xmm0
+; SSE2-NEXT:    movapd %xmm1, %xmm7
+; SSE2-NEXT:    andpd %xmm4, %xmm7
+; SSE2-NEXT:    movapd %xmm7, %xmm8
+; SSE2-NEXT:    addpd %xmm5, %xmm8
+; SSE2-NEXT:    cvttsd2si %xmm8, %rax
 ; SSE2-NEXT:    xorps %xmm9, %xmm9
 ; SSE2-NEXT:    cvtsi2sd %rax, %xmm9
-; SSE2-NEXT:    unpckhpd {{.*#+}} xmm7 = xmm7[1,1]
-; SSE2-NEXT:    cvttsd2si %xmm7, %rax
-; SSE2-NEXT:    xorps %xmm7, %xmm7
-; SSE2-NEXT:    cvtsi2sd %rax, %xmm7
-; SSE2-NEXT:    unpcklpd {{.*#+}} xmm9 = xmm9[0],xmm7[0]
+; SSE2-NEXT:    unpckhpd {{.*#+}} xmm8 = xmm8[1,1]
+; SSE2-NEXT:    cvttsd2si %xmm8, %rax
+; SSE2-NEXT:    xorps %xmm8, %xmm8
+; SSE2-NEXT:    cvtsi2sd %rax, %xmm8
+; SSE2-NEXT:    unpcklpd {{.*#+}} xmm9 = xmm9[0],xmm8[0]
 ; SSE2-NEXT:    andpd %xmm4, %xmm9
-; SSE2-NEXT:    movdqa %xmm4, %xmm7
-; SSE2-NEXT:    pandn %xmm1, %xmm7
-; SSE2-NEXT:    por %xmm9, %xmm7
-; SSE2-NEXT:    pcmpgtd %xmm6, %xmm8
-; SSE2-NEXT:    pand %xmm8, %xmm1
-; SSE2-NEXT:    pandn %xmm7, %xmm8
-; SSE2-NEXT:    por %xmm8, %xmm1
-; SSE2-NEXT:    movdqa %xmm2, %xmm7
-; SSE2-NEXT:    pand %xmm4, %xmm7
-; SSE2-NEXT:    pshufd {{.*#+}} xmm8 = xmm7[1,1,3,3]
-; SSE2-NEXT:    addpd %xmm5, %xmm7
-; SSE2-NEXT:    cvttsd2si %xmm7, %rax
+; SSE2-NEXT:    movapd %xmm4, %xmm8
+; SSE2-NEXT:    andnpd %xmm1, %xmm8
+; SSE2-NEXT:    orpd %xmm9, %xmm8
+; SSE2-NEXT:    cmpnltpd %xmm6, %xmm7
+; SSE2-NEXT:    andpd %xmm7, %xmm1
+; SSE2-NEXT:    andnpd %xmm8, %xmm7
+; SSE2-NEXT:    orpd %xmm7, %xmm1
+; SSE2-NEXT:    movapd %xmm2, %xmm7
+; SSE2-NEXT:    andpd %xmm4, %xmm7
+; SSE2-NEXT:    movapd %xmm7, %xmm8
+; SSE2-NEXT:    addpd %xmm5, %xmm8
+; SSE2-NEXT:    cvttsd2si %xmm8, %rax
 ; SSE2-NEXT:    xorps %xmm9, %xmm9
 ; SSE2-NEXT:    cvtsi2sd %rax, %xmm9
-; SSE2-NEXT:    unpckhpd {{.*#+}} xmm7 = xmm7[1,1]
-; SSE2-NEXT:    cvttsd2si %xmm7, %rax
-; SSE2-NEXT:    xorps %xmm7, %xmm7
-; SSE2-NEXT:    cvtsi2sd %rax, %xmm7
-; SSE2-NEXT:    unpcklpd {{.*#+}} xmm9 = xmm9[0],xmm7[0]
+; SSE2-NEXT:    unpckhpd {{.*#+}} xmm8 = xmm8[1,1]
+; SSE2-NEXT:    cvttsd2si %xmm8, %rax
+; SSE2-NEXT:    xorps %xmm8, %xmm8
+; SSE2-NEXT:    cvtsi2sd %rax, %xmm8
+; SSE2-NEXT:    unpcklpd {{.*#+}} xmm9 = xmm9[0],xmm8[0]
 ; SSE2-NEXT:    andpd %xmm4, %xmm9
-; SSE2-NEXT:    movdqa %xmm4, %xmm7
-; SSE2-NEXT:    pandn %xmm2, %xmm7
-; SSE2-NEXT:    por %xmm9, %xmm7
-; SSE2-NEXT:    pcmpgtd %xmm6, %xmm8
-; SSE2-NEXT:    pand %xmm8, %xmm2
-; SSE2-NEXT:    pandn %xmm7, %xmm8
-; SSE2-NEXT:    por %xmm8, %xmm2
+; SSE2-NEXT:    movapd %xmm4, %xmm8
+; SSE2-NEXT:    andnpd %xmm2, %xmm8
+; SSE2-NEXT:    orpd %xmm9, %xmm8
+; SSE2-NEXT:    cmpnltpd %xmm6, %xmm7
+; SSE2-NEXT:    andpd %xmm7, %xmm2
+; SSE2-NEXT:    andnpd %xmm8, %xmm7
+; SSE2-NEXT:    orpd %xmm7, %xmm2
 ; SSE2-NEXT:    movapd %xmm3, %xmm7
 ; SSE2-NEXT:    andpd %xmm4, %xmm7
 ; SSE2-NEXT:    addpd %xmm7, %xmm5
@@ -682,11 +677,10 @@ define <8 x double> @round_v8f64(<8 x double> %x) {
 ; SSE2-NEXT:    andpd %xmm4, %xmm8
 ; SSE2-NEXT:    andnpd %xmm3, %xmm4
 ; SSE2-NEXT:    orpd %xmm8, %xmm4
-; SSE2-NEXT:    pshufd {{.*#+}} xmm5 = xmm7[1,1,3,3]
-; SSE2-NEXT:    pcmpgtd %xmm6, %xmm5
-; SSE2-NEXT:    andpd %xmm5, %xmm3
-; SSE2-NEXT:    andnpd %xmm4, %xmm5
-; SSE2-NEXT:    orpd %xmm5, %xmm3
+; SSE2-NEXT:    cmpnltpd %xmm6, %xmm7
+; SSE2-NEXT:    andpd %xmm7, %xmm3
+; SSE2-NEXT:    andnpd %xmm4, %xmm7
+; SSE2-NEXT:    orpd %xmm7, %xmm3
 ; SSE2-NEXT:    retq
 ;
 ; SSE41-LABEL: round_v8f64:
diff --git a/llvm/test/CodeGen/X86/fp16-libcalls.ll b/llvm/test/CodeGen/X86/fp16-libcalls.ll
index 594418e9d4b0b..af3f624edb0c9 100644
--- a/llvm/test/CodeGen/X86/fp16-libcalls.ll
+++ b/llvm/test/CodeGen/X86/fp16-libcalls.ll
@@ -1152,20 +1152,18 @@ define void @test_half_trunc(half %a0, ptr %p0) nounwind {
 ; X64-NEXT:    pushq %rbx
 ; X64-NEXT:    movq %rdi, %rbx
 ; X64-NEXT:    callq __extendhfsf2 at PLT
-; X64-NEXT:    movdqa {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
-; X64-NEXT:    movdqa %xmm0, %xmm2
-; X64-NEXT:    pand %xmm1, %xmm2
-; X64-NEXT:    movd %xmm2, %eax
-; X64-NEXT:    cmpl $1325400064, %eax # imm = 0x4F000000
-; X64-NEXT:    jge .LBB20_2
-; X64-NEXT:  # %bb.1:
-; X64-NEXT:    cvttps2dq %xmm2, %xmm2
-; X64-NEXT:    cvtdq2ps %xmm2, %xmm2
+; X64-NEXT:    movaps {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
+; X64-NEXT:    movaps %xmm0, %xmm2
 ; X64-NEXT:    andps %xmm1, %xmm2
-; X64-NEXT:    pandn %xmm0, %xmm1
-; X64-NEXT:    por %xmm2, %xmm1
-; X64-NEXT:    movdqa %xmm1, %xmm0
-; X64-NEXT:  .LBB20_2:
+; X64-NEXT:    cvttps2dq %xmm2, %xmm3
+; X64-NEXT:    cvtdq2ps %xmm3, %xmm3
+; X64-NEXT:    andps %xmm1, %xmm3
+; X64-NEXT:    andnps %xmm0, %xmm1
+; X64-NEXT:    orps %xmm1, %xmm3
+; X64-NEXT:    cmpnltss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
+; X64-NEXT:    andps %xmm2, %xmm0
+; X64-NEXT:    andnps %xmm3, %xmm2
+; X64-NEXT:    orps %xmm2, %xmm0
 ; X64-NEXT:    callq __truncsfhf2 at PLT
 ; X64-NEXT:    pextrw $0, %xmm0, %eax
 ; X64-NEXT:    movw %ax, (%rbx)
@@ -1182,22 +1180,21 @@ define void @test_half_trunc(half %a0, ptr %p0) nounwind {
 ; X86-NEXT:    movw %ax, (%esp)
 ; X86-NEXT:    calll __extendhfsf2
 ; X86-NEXT:    fstps {{[0-9]+}}(%esp)
-; X86-NEXT:    movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
-; X86-NEXT:    movdqa {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
-; X86-NEXT:    movdqa %xmm0, %xmm2
-; X86-NEXT:    pand %xmm1, %xmm2
-; X86-NEXT:    movd %xmm2, %eax
-; X86-NEXT:    cmpl $1325400064, %eax # imm = 0x4F000000
-; X86-NEXT:    jge .LBB20_2
-; X86-NEXT:  # %bb.1:
-; X86-NEXT:    cvttps2dq %xmm2, %xmm2
-; X86-NEXT:    cvtdq2ps %xmm2, %xmm2
-; X86-NEXT:    andps %xmm1, %xmm2
-; X86-NEXT:    pandn %xmm0, %xmm1
-; X86-NEXT:    por %xmm2, %xmm1
-; X86-NEXT:    movdqa %xmm1, %xmm0
-; X86-NEXT:  .LBB20_2:
-; X86-NEXT:    movd %xmm0, (%esp)
+; X86-NEXT:    movaps {{.*#+}} xmm2 = [NaN,NaN,NaN,NaN]
+; X86-NEXT:    movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
+; X86-NEXT:    movaps %xmm1, %xmm0
+; X86-NEXT:    andps %xmm2, %xmm0
+; X86-NEXT:    cvttps2dq %xmm0, %xmm3
+; X86-NEXT:    cvtdq2ps %xmm3, %xmm3
+; X86-NEXT:    andps %xmm2, %xmm3
+; X86-NEXT:    andnps %xmm1, %xmm2
+; X86-NEXT:    orps %xmm2, %xmm3
+; X86-NEXT:    cmpnltss {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
+; X86-NEXT:    movaps %xmm0, %xmm2
+; X86-NEXT:    andnps %xmm3, %xmm2
+; X86-NEXT:    andps %xmm1, %xmm0
+; X86-NEXT:    orps %xmm2, %xmm0
+; X86-NEXT:    movss %xmm0, (%esp)
 ; X86-NEXT:    calll __truncsfhf2
 ; X86-NEXT:    pextrw $0, %xmm0, %eax
 ; X86-NEXT:    movw %ax, (%esi)
diff --git a/llvm/test/CodeGen/X86/freeze-unary.ll b/llvm/test/CodeGen/X86/freeze-unary.ll
index addae1acca77a..cf74fd6d7c1c9 100644
--- a/llvm/test/CodeGen/X86/freeze-unary.ll
+++ b/llvm/test/CodeGen/X86/freeze-unary.ll
@@ -485,23 +485,23 @@ define float @ftrunc_freeze_fround(float %a0) nounwind {
 ; X86-LABEL: ftrunc_freeze_fround:
 ; X86:       # %bb.0:
 ; X86-NEXT:    pushl %eax
-; X86-NEXT:    movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
-; X86-NEXT:    movdqa {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
-; X86-NEXT:    movdqa %xmm0, %xmm2
-; X86-NEXT:    pand %xmm1, %xmm2
-; X86-NEXT:    movd %xmm2, %eax
-; X86-NEXT:    cmpl $1325400064, %eax # imm = 0x4F000000
-; X86-NEXT:    jge .LBB23_2
-; X86-NEXT:  # %bb.1:
-; X86-NEXT:    addss {{\.?LCPI[0-9]+_[0-9]+}}, %xmm2
-; X86-NEXT:    cvttps2dq %xmm2, %xmm2
-; X86-NEXT:    cvtdq2ps %xmm2, %xmm2
-; X86-NEXT:    andps %xmm1, %xmm2
-; X86-NEXT:    pandn %xmm0, %xmm1
-; X86-NEXT:    por %xmm2, %xmm1
-; X86-NEXT:    movdqa %xmm1, %xmm0
-; X86-NEXT:  .LBB23_2:
-; X86-NEXT:    movd %xmm0, (%esp)
+; X86-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
+; X86-NEXT:    movaps {{.*#+}} xmm2 = [NaN,NaN,NaN,NaN]
+; X86-NEXT:    movaps %xmm0, %xmm1
+; X86-NEXT:    andps %xmm2, %xmm1
+; X86-NEXT:    movss {{.*#+}} xmm3 = [4.9999997E-1,0.0E+0,0.0E+0,0.0E+0]
+; X86-NEXT:    addss %xmm1, %xmm3
+; X86-NEXT:    cvttps2dq %xmm3, %xmm3
+; X86-NEXT:    cvtdq2ps %xmm3, %xmm3
+; X86-NEXT:    andps %xmm2, %xmm3
+; X86-NEXT:    andnps %xmm0, %xmm2
+; X86-NEXT:    orps %xmm2, %xmm3
+; X86-NEXT:    cmpnltss {{\.?LCPI[0-9]+_[0-9]+}}, %xmm1
+; X86-NEXT:    movaps %xmm1, %xmm2
+; X86-NEXT:    andnps %xmm3, %xmm2
+; X86-NEXT:    andps %xmm0, %xmm1
+; X86-NEXT:    orps %xmm2, %xmm1
+; X86-NEXT:    movss %xmm1, (%esp)
 ; X86-NEXT:    flds (%esp)
 ; X86-NEXT:    popl %eax
 ; X86-NEXT:    retl
@@ -565,22 +565,21 @@ define float @ftrunc_freeze_ftrunc(float %a0) nounwind {
 ; X86-LABEL: ftrunc_freeze_ftrunc:
 ; X86:       # %bb.0:
 ; X86-NEXT:    pushl %eax
-; X86-NEXT:    movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
-; X86-NEXT:    movdqa {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
-; X86-NEXT:    movdqa %xmm0, %xmm2
-; X86-NEXT:    pand %xmm1, %xmm2
-; X86-NEXT:    movd %xmm2, %eax
-; X86-NEXT:    cmpl $1325400064, %eax # imm = 0x4F000000
-; X86-NEXT:    jge .LBB26_2
-; X86-NEXT:  # %bb.1:
-; X86-NEXT:    cvttps2dq %xmm2, %xmm2
-; X86-NEXT:    cvtdq2ps %xmm2, %xmm2
-; X86-NEXT:    andps %xmm1, %xmm2
-; X86-NEXT:    pandn %xmm0, %xmm1
-; X86-NEXT:    por %xmm2, %xmm1
-; X86-NEXT:    movdqa %xmm1, %xmm0
-; X86-NEXT:  .LBB26_2:
-; X86-NEXT:    movd %xmm0, (%esp)
+; X86-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
+; X86-NEXT:    movaps {{.*#+}} xmm2 = [NaN,NaN,NaN,NaN]
+; X86-NEXT:    movaps %xmm0, %xmm1
+; X86-NEXT:    andps %xmm2, %xmm1
+; X86-NEXT:    cvttps2dq %xmm1, %xmm3
+; X86-NEXT:    cvtdq2ps %xmm3, %xmm3
+; X86-NEXT:    andps %xmm2, %xmm3
+; X86-NEXT:    andnps %xmm0, %xmm2
+; X86-NEXT:    orps %xmm2, %xmm3
+; X86-NEXT:    cmpnltss {{\.?LCPI[0-9]+_[0-9]+}}, %xmm1
+; X86-NEXT:    movaps %xmm1, %xmm2
+; X86-NEXT:    andnps %xmm3, %xmm2
+; X86-NEXT:    andps %xmm0, %xmm1
+; X86-NEXT:    orps %xmm2, %xmm1
+; X86-NEXT:    movss %xmm1, (%esp)
 ; X86-NEXT:    flds (%esp)
 ; X86-NEXT:    popl %eax
 ; X86-NEXT:    retl
diff --git a/llvm/test/CodeGen/X86/ftrunc.ll b/llvm/test/CodeGen/X86/ftrunc.ll
index 3e44569a33757..11f9a921bc6aa 100644
--- a/llvm/test/CodeGen/X86/ftrunc.ll
+++ b/llvm/test/CodeGen/X86/ftrunc.ll
@@ -10,20 +10,18 @@ declare i64 @llvm.fptosi.sat.i64.f64(double)
 define float @trunc_unsigned_f32(float %x) #0 {
 ; SSE2-LABEL: trunc_unsigned_f32:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    movdqa {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
-; SSE2-NEXT:    movdqa %xmm0, %xmm2
-; SSE2-NEXT:    pand %xmm1, %xmm2
-; SSE2-NEXT:    movd %xmm2, %eax
-; SSE2-NEXT:    cmpl $1325400064, %eax # imm = 0x4F000000
-; SSE2-NEXT:    jge .LBB0_2
-; SSE2-NEXT:  # %bb.1:
-; SSE2-NEXT:    cvttps2dq %xmm2, %xmm2
-; SSE2-NEXT:    cvtdq2ps %xmm2, %xmm2
+; SSE2-NEXT:    movaps {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
+; SSE2-NEXT:    movaps %xmm0, %xmm2
 ; SSE2-NEXT:    andps %xmm1, %xmm2
-; SSE2-NEXT:    pandn %xmm0, %xmm1
-; SSE2-NEXT:    por %xmm2, %xmm1
-; SSE2-NEXT:    movdqa %xmm1, %xmm0
-; SSE2-NEXT:  .LBB0_2:
+; SSE2-NEXT:    cvttps2dq %xmm2, %xmm3
+; SSE2-NEXT:    cvtdq2ps %xmm3, %xmm3
+; SSE2-NEXT:    andps %xmm1, %xmm3
+; SSE2-NEXT:    andnps %xmm0, %xmm1
+; SSE2-NEXT:    orps %xmm1, %xmm3
+; SSE2-NEXT:    cmpnltss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
+; SSE2-NEXT:    andps %xmm2, %xmm0
+; SSE2-NEXT:    andnps %xmm3, %xmm2
+; SSE2-NEXT:    orps %xmm2, %xmm0
 ; SSE2-NEXT:    retq
 ;
 ; SSE41-LABEL: trunc_unsigned_f32:
@@ -53,22 +51,18 @@ define float @trunc_unsigned_f32(float %x) #0 {
 define double @trunc_unsigned_f64(double %x) #0 {
 ; SSE2-LABEL: trunc_unsigned_f64:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    movdqa {{.*#+}} xmm1 = [NaN,NaN]
-; SSE2-NEXT:    movdqa %xmm0, %xmm2
-; SSE2-NEXT:    pand %xmm1, %xmm2
-; SSE2-NEXT:    movq %xmm2, %rax
-; SSE2-NEXT:    movabsq $4841369599423283199, %rcx # imm = 0x432FFFFFFFFFFFFF
-; SSE2-NEXT:    cmpq %rcx, %rax
-; SSE2-NEXT:    jg .LBB1_2
-; SSE2-NEXT:  # %bb.1:
-; SSE2-NEXT:    cvttsd2si %xmm2, %rax
-; SSE2-NEXT:    xorps %xmm2, %xmm2
-; SSE2-NEXT:    cvtsi2sd %rax, %xmm2
+; SSE2-NEXT:    movapd {{.*#+}} xmm1 = [NaN,NaN]
+; SSE2-NEXT:    movapd %xmm0, %xmm2
 ; SSE2-NEXT:    andpd %xmm1, %xmm2
-; SSE2-NEXT:    pandn %xmm0, %xmm1
-; SSE2-NEXT:    por %xmm2, %xmm1
-; SSE2-NEXT:    movdqa %xmm1, %xmm0
-; SSE2-NEXT:  .LBB1_2:
+; SSE2-NEXT:    cvttsd2si %xmm2, %rax
+; SSE2-NEXT:    cvtsi2sd %rax, %xmm3
+; SSE2-NEXT:    andpd %xmm1, %xmm3
+; SSE2-NEXT:    andnpd %xmm0, %xmm1
+; SSE2-NEXT:    orpd %xmm1, %xmm3
+; SSE2-NEXT:    cmpnltsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
+; SSE2-NEXT:    andpd %xmm2, %xmm0
+; SSE2-NEXT:    andnpd %xmm3, %xmm2
+; SSE2-NEXT:    orpd %xmm2, %xmm0
 ; SSE2-NEXT:    retq
 ;
 ; SSE41-LABEL: trunc_unsigned_f64:
@@ -110,7 +104,7 @@ define <4 x float> @trunc_unsigned_v4f32(<4 x float> %x) #0 {
 ; SSE2-NEXT:    andps %xmm1, %xmm3
 ; SSE2-NEXT:    andnps %xmm0, %xmm1
 ; SSE2-NEXT:    orps %xmm1, %xmm3
-; SSE2-NEXT:    pcmpgtd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
+; SSE2-NEXT:    cmpnltps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
 ; SSE2-NEXT:    andps %xmm2, %xmm0
 ; SSE2-NEXT:    andnps %xmm3, %xmm2
 ; SSE2-NEXT:    orps %xmm2, %xmm0
@@ -146,8 +140,7 @@ define <2 x double> @trunc_unsigned_v2f64(<2 x double> %x) #0 {
 ; SSE2-NEXT:    andpd %xmm1, %xmm3
 ; SSE2-NEXT:    andnpd %xmm0, %xmm1
 ; SSE2-NEXT:    orpd %xmm3, %xmm1
-; SSE2-NEXT:    pshufd {{.*#+}} xmm2 = xmm2[1,1,3,3]
-; SSE2-NEXT:    pcmpgtd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
+; SSE2-NEXT:    cmpnltpd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
 ; SSE2-NEXT:    andpd %xmm2, %xmm0
 ; SSE2-NEXT:    andnpd %xmm1, %xmm2
 ; SSE2-NEXT:    orpd %xmm2, %xmm0
@@ -184,9 +177,8 @@ define <4 x double> @trunc_unsigned_v4f64(<4 x double> %x) #0 {
 ; SSE2-NEXT:    movapd %xmm2, %xmm5
 ; SSE2-NEXT:    andnpd %xmm0, %xmm5
 ; SSE2-NEXT:    orpd %xmm4, %xmm5
-; SSE2-NEXT:    pshufd {{.*#+}} xmm3 = xmm3[1,1,3,3]
-; SSE2-NEXT:    movdqa {{.*#+}} xmm4 = [1127219199,1127219199,1127219199,1127219199]
-; SSE2-NEXT:    pcmpgtd %xmm4, %xmm3
+; SSE2-NEXT:    movapd {{.*#+}} xmm4 = [4.503599627370496E+15,4.503599627370496E+15]
+; SSE2-NEXT:    cmpnltpd %xmm4, %xmm3
 ; SSE2-NEXT:    andpd %xmm3, %xmm0
 ; SSE2-NEXT:    andnpd %xmm5, %xmm3
 ; SSE2-NEXT:    orpd %xmm3, %xmm0
@@ -203,8 +195,7 @@ define <4 x double> @trunc_unsigned_v4f64(<4 x double> %x) #0 {
 ; SSE2-NEXT:    andpd %xmm2, %xmm5
 ; SSE2-NEXT:    andnpd %xmm1, %xmm2
 ; SSE2-NEXT:    orpd %xmm5, %xmm2
-; SSE2-NEXT:    pshufd {{.*#+}} xmm3 = xmm3[1,1,3,3]
-; SSE2-NEXT:    pcmpgtd %xmm4, %xmm3
+; SSE2-NEXT:    cmpnltpd %xmm4, %xmm3
 ; SSE2-NEXT:    andpd %xmm3, %xmm1
 ; SSE2-NEXT:    andnpd %xmm2, %xmm3
 ; SSE2-NEXT:    orpd %xmm3, %xmm1
@@ -258,20 +249,18 @@ define float @trunc_signed_f32_no_fast_math(float %x) nounwind {
 define float @trunc_signed_f32_nsz(float %x) #0 {
 ; SSE2-LABEL: trunc_signed_f32_nsz:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    movdqa {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
-; SSE2-NEXT:    movdqa %xmm0, %xmm2
-; SSE2-NEXT:    pand %xmm1, %xmm2
-; SSE2-NEXT:    movd %xmm2, %eax
-; SSE2-NEXT:    cmpl $1325400064, %eax # imm = 0x4F000000
-; SSE2-NEXT:    jge .LBB6_2
-; SSE2-NEXT:  # %bb.1:
-; SSE2-NEXT:    cvttps2dq %xmm2, %xmm2
-; SSE2-NEXT:    cvtdq2ps %xmm2, %xmm2
+; SSE2-NEXT:    movaps {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
+; SSE2-NEXT:    movaps %xmm0, %xmm2
 ; SSE2-NEXT:    andps %xmm1, %xmm2
-; SSE2-NEXT:    pandn %xmm0, %xmm1
-; SSE2-NEXT:    por %xmm2, %xmm1
-; SSE2-NEXT:    movdqa %xmm1, %xmm0
-; SSE2-NEXT:  .LBB6_2:
+; SSE2-NEXT:    cvttps2dq %xmm2, %xmm3
+; SSE2-NEXT:    cvtdq2ps %xmm3, %xmm3
+; SSE2-NEXT:    andps %xmm1, %xmm3
+; SSE2-NEXT:    andnps %xmm0, %xmm1
+; SSE2-NEXT:    orps %xmm1, %xmm3
+; SSE2-NEXT:    cmpnltss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
+; SSE2-NEXT:    andps %xmm2, %xmm0
+; SSE2-NEXT:    andnps %xmm3, %xmm2
+; SSE2-NEXT:    orps %xmm2, %xmm0
 ; SSE2-NEXT:    retq
 ;
 ; SSE41-LABEL: trunc_signed_f32_nsz:
@@ -333,22 +322,18 @@ define double @trunc_signed32_f64_no_fast_math(double %x) nounwind {
 define double @trunc_signed32_f64_nsz(double %x) #0 {
 ; SSE2-LABEL: trunc_signed32_f64_nsz:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    movdqa {{.*#+}} xmm1 = [NaN,NaN]
-; SSE2-NEXT:    movdqa %xmm0, %xmm2
-; SSE2-NEXT:    pand %xmm1, %xmm2
-; SSE2-NEXT:    movq %xmm2, %rax
-; SSE2-NEXT:    movabsq $4841369599423283199, %rcx # imm = 0x432FFFFFFFFFFFFF
-; SSE2-NEXT:    cmpq %rcx, %rax
-; SSE2-NEXT:    jg .LBB8_2
-; SSE2-NEXT:  # %bb.1:
-; SSE2-NEXT:    cvttsd2si %xmm2, %rax
-; SSE2-NEXT:    xorps %xmm2, %xmm2
-; SSE2-NEXT:    cvtsi2sd %rax, %xmm2
+; SSE2-NEXT:    movapd {{.*#+}} xmm1 = [NaN,NaN]
+; SSE2-NEXT:    movapd %xmm0, %xmm2
 ; SSE2-NEXT:    andpd %xmm1, %xmm2
-; SSE2-NEXT:    pandn %xmm0, %xmm1
-; SSE2-NEXT:    por %xmm2, %xmm1
-; SSE2-NEXT:    movdqa %xmm1, %xmm0
-; SSE2-NEXT:  .LBB8_2:
+; SSE2-NEXT:    cvttsd2si %xmm2, %rax
+; SSE2-NEXT:    cvtsi2sd %rax, %xmm3
+; SSE2-NEXT:    andpd %xmm1, %xmm3
+; SSE2-NEXT:    andnpd %xmm0, %xmm1
+; SSE2-NEXT:    orpd %xmm1, %xmm3
+; SSE2-NEXT:    cmpnltsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
+; SSE2-NEXT:    andpd %xmm2, %xmm0
+; SSE2-NEXT:    andnpd %xmm3, %xmm2
+; SSE2-NEXT:    orpd %xmm2, %xmm0
 ; SSE2-NEXT:    retq
 ;
 ; SSE41-LABEL: trunc_signed32_f64_nsz:
@@ -539,22 +524,18 @@ define double @trunc_signed_f64_no_fast_math(double %x) nounwind {
 define double @trunc_signed_f64_nsz(double %x) #0 {
 ; SSE2-LABEL: trunc_signed_f64_nsz:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    movdqa {{.*#+}} xmm1 = [NaN,NaN]
-; SSE2-NEXT:    movdqa %xmm0, %xmm2
-; SSE2-NEXT:    pand %xmm1, %xmm2
-; SSE2-NEXT:    movq %xmm2, %rax
-; SSE2-NEXT:    movabsq $4841369599423283199, %rcx # imm = 0x432FFFFFFFFFFFFF
-; SSE2-NEXT:    cmpq %rcx, %rax
-; SSE2-NEXT:    jg .LBB14_2
-; SSE2-NEXT:  # %bb.1:
-; SSE2-NEXT:    cvttsd2si %xmm2, %rax
-; SSE2-NEXT:    xorps %xmm2, %xmm2
-; SSE2-NEXT:    cvtsi2sd %rax, %xmm2
+; SSE2-NEXT:    movapd {{.*#+}} xmm1 = [NaN,NaN]
+; SSE2-NEXT:    movapd %xmm0, %xmm2
 ; SSE2-NEXT:    andpd %xmm1, %xmm2
-; SSE2-NEXT:    pandn %xmm0, %xmm1
-; SSE2-NEXT:    por %xmm2, %xmm1
-; SSE2-NEXT:    movdqa %xmm1, %xmm0
-; SSE2-NEXT:  .LBB14_2:
+; SSE2-NEXT:    cvttsd2si %xmm2, %rax
+; SSE2-NEXT:    cvtsi2sd %rax, %xmm3
+; SSE2-NEXT:    andpd %xmm1, %xmm3
+; SSE2-NEXT:    andnpd %xmm0, %xmm1
+; SSE2-NEXT:    orpd %xmm1, %xmm3
+; SSE2-NEXT:    cmpnltsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
+; SSE2-NEXT:    andpd %xmm2, %xmm0
+; SSE2-NEXT:    andnpd %xmm3, %xmm2
+; SSE2-NEXT:    orpd %xmm2, %xmm0
 ; SSE2-NEXT:    retq
 ;
 ; SSE41-LABEL: trunc_signed_f64_nsz:
@@ -596,7 +577,7 @@ define <4 x float> @trunc_signed_v4f32_nsz(<4 x float> %x) #0 {
 ; SSE2-NEXT:    andps %xmm1, %xmm3
 ; SSE2-NEXT:    andnps %xmm0, %xmm1
 ; SSE2-NEXT:    orps %xmm1, %xmm3
-; SSE2-NEXT:    pcmpgtd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
+; SSE2-NEXT:    cmpnltps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
 ; SSE2-NEXT:    andps %xmm2, %xmm0
 ; SSE2-NEXT:    andnps %xmm3, %xmm2
 ; SSE2-NEXT:    orps %xmm2, %xmm0
@@ -632,8 +613,7 @@ define <2 x double> @trunc_signed_v2f64_nsz(<2 x double> %x) #0 {
 ; SSE2-NEXT:    andpd %xmm1, %xmm3
 ; SSE2-NEXT:    andnpd %xmm0, %xmm1
 ; SSE2-NEXT:    orpd %xmm3, %xmm1
-; SSE2-NEXT:    pshufd {{.*#+}} xmm2 = xmm2[1,1,3,3]
-; SSE2-NEXT:    pcmpgtd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
+; SSE2-NEXT:    cmpnltpd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
 ; SSE2-NEXT:    andpd %xmm2, %xmm0
 ; SSE2-NEXT:    andnpd %xmm1, %xmm2
 ; SSE2-NEXT:    orpd %xmm2, %xmm0
@@ -670,9 +650,8 @@ define <4 x double> @trunc_signed_v4f64_nsz(<4 x double> %x) #0 {
 ; SSE2-NEXT:    movapd %xmm2, %xmm5
 ; SSE2-NEXT:    andnpd %xmm0, %xmm5
 ; SSE2-NEXT:    orpd %xmm4, %xmm5
-; SSE2-NEXT:    pshufd {{.*#+}} xmm3 = xmm3[1,1,3,3]
-; SSE2-NEXT:    movdqa {{.*#+}} xmm4 = [1127219199,1127219199,1127219199,1127219199]
-; SSE2-NEXT:    pcmpgtd %xmm4, %xmm3
+; SSE2-NEXT:    movapd {{.*#+}} xmm4 = [4.503599627370496E+15,4.503599627370496E+15]
+; SSE2-NEXT:    cmpnltpd %xmm4, %xmm3
 ; SSE2-NEXT:    andpd %xmm3, %xmm0
 ; SSE2-NEXT:    andnpd %xmm5, %xmm3
 ; SSE2-NEXT:    orpd %xmm3, %xmm0
@@ -689,8 +668,7 @@ define <4 x double> @trunc_signed_v4f64_nsz(<4 x double> %x) #0 {
 ; SSE2-NEXT:    andpd %xmm2, %xmm5
 ; SSE2-NEXT:    andnpd %xmm1, %xmm2
 ; SSE2-NEXT:    orpd %xmm5, %xmm2
-; SSE2-NEXT:    pshufd {{.*#+}} xmm3 = xmm3[1,1,3,3]
-; SSE2-NEXT:    pcmpgtd %xmm4, %xmm3
+; SSE2-NEXT:    cmpnltpd %xmm4, %xmm3
 ; SSE2-NEXT:    andpd %xmm3, %xmm1
 ; SSE2-NEXT:    andnpd %xmm2, %xmm3
 ; SSE2-NEXT:    orpd %xmm3, %xmm1
diff --git a/llvm/test/CodeGen/X86/isel-ftrunc.ll b/llvm/test/CodeGen/X86/isel-ftrunc.ll
index 15b98688569bd..14a88c68870a2 100644
--- a/llvm/test/CodeGen/X86/isel-ftrunc.ll
+++ b/llvm/test/CodeGen/X86/isel-ftrunc.ll
@@ -9,20 +9,18 @@
 define float @trunc_f32(float %a) nounwind readnone {
 ; X64-LABEL: trunc_f32:
 ; X64:       # %bb.0:
-; X64-NEXT:    movdqa {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
-; X64-NEXT:    movdqa %xmm0, %xmm2
-; X64-NEXT:    pand %xmm1, %xmm2
-; X64-NEXT:    movd %xmm2, %eax
-; X64-NEXT:    cmpl $1325400064, %eax # imm = 0x4F000000
-; X64-NEXT:    jge .LBB0_2
-; X64-NEXT:  # %bb.1:
-; X64-NEXT:    cvttps2dq %xmm2, %xmm2
-; X64-NEXT:    cvtdq2ps %xmm2, %xmm2
+; X64-NEXT:    movaps {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
+; X64-NEXT:    movaps %xmm0, %xmm2
 ; X64-NEXT:    andps %xmm1, %xmm2
-; X64-NEXT:    pandn %xmm0, %xmm1
-; X64-NEXT:    por %xmm2, %xmm1
-; X64-NEXT:    movdqa %xmm1, %xmm0
-; X64-NEXT:  .LBB0_2:
+; X64-NEXT:    cvttps2dq %xmm2, %xmm3
+; X64-NEXT:    cvtdq2ps %xmm3, %xmm3
+; X64-NEXT:    andps %xmm1, %xmm3
+; X64-NEXT:    andnps %xmm0, %xmm1
+; X64-NEXT:    orps %xmm1, %xmm3
+; X64-NEXT:    cmpnltss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
+; X64-NEXT:    andps %xmm2, %xmm0
+; X64-NEXT:    andnps %xmm3, %xmm2
+; X64-NEXT:    orps %xmm2, %xmm0
 ; X64-NEXT:    retq
 ;
 ; X86-LABEL: trunc_f32:
@@ -56,22 +54,18 @@ define float @trunc_f32(float %a) nounwind readnone {
 define double @trunc_f64(double %a) nounwind readnone {
 ; X64-LABEL: trunc_f64:
 ; X64:       # %bb.0:
-; X64-NEXT:    movdqa {{.*#+}} xmm1 = [NaN,NaN]
-; X64-NEXT:    movdqa %xmm0, %xmm2
-; X64-NEXT:    pand %xmm1, %xmm2
-; X64-NEXT:    movq %xmm2, %rax
-; X64-NEXT:    movabsq $4841369599423283199, %rcx # imm = 0x432FFFFFFFFFFFFF
-; X64-NEXT:    cmpq %rcx, %rax
-; X64-NEXT:    jg .LBB1_2
-; X64-NEXT:  # %bb.1:
-; X64-NEXT:    cvttsd2si %xmm2, %rax
-; X64-NEXT:    xorps %xmm2, %xmm2
-; X64-NEXT:    cvtsi2sd %rax, %xmm2
+; X64-NEXT:    movapd {{.*#+}} xmm1 = [NaN,NaN]
+; X64-NEXT:    movapd %xmm0, %xmm2
 ; X64-NEXT:    andpd %xmm1, %xmm2
-; X64-NEXT:    pandn %xmm0, %xmm1
-; X64-NEXT:    por %xmm2, %xmm1
-; X64-NEXT:    movdqa %xmm1, %xmm0
-; X64-NEXT:  .LBB1_2:
+; X64-NEXT:    cvttsd2si %xmm2, %rax
+; X64-NEXT:    cvtsi2sd %rax, %xmm3
+; X64-NEXT:    andpd %xmm1, %xmm3
+; X64-NEXT:    andnpd %xmm0, %xmm1
+; X64-NEXT:    orpd %xmm1, %xmm3
+; X64-NEXT:    cmpnltsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
+; X64-NEXT:    andpd %xmm2, %xmm0
+; X64-NEXT:    andnpd %xmm3, %xmm2
+; X64-NEXT:    orpd %xmm2, %xmm0
 ; X64-NEXT:    retq
 ;
 ; X86-LABEL: trunc_f64:
diff --git a/llvm/test/CodeGen/X86/isint.ll b/llvm/test/CodeGen/X86/isint.ll
index c72e6c9a2c457..eb05cf78cd36b 100644
--- a/llvm/test/CodeGen/X86/isint.ll
+++ b/llvm/test/CodeGen/X86/isint.ll
@@ -20,25 +20,21 @@ define i32 @isint_return(double %d) nounwind {
 ;
 ; X64-SSE2-LABEL: isint_return:
 ; X64-SSE2:       # %bb.0:
-; X64-SSE2-NEXT:    movdqa {{.*#+}} xmm1 = [NaN,NaN]
-; X64-SSE2-NEXT:    movdqa %xmm0, %xmm2
-; X64-SSE2-NEXT:    pand %xmm1, %xmm2
-; X64-SSE2-NEXT:    movq %xmm2, %rax
-; X64-SSE2-NEXT:    movabsq $4841369599423283199, %rcx # imm = 0x432FFFFFFFFFFFFF
-; X64-SSE2-NEXT:    movdqa %xmm0, %xmm3
-; X64-SSE2-NEXT:    cmpq %rcx, %rax
-; X64-SSE2-NEXT:    jg .LBB0_2
-; X64-SSE2-NEXT:  # %bb.1:
-; X64-SSE2-NEXT:    cvttsd2si %xmm2, %rax
-; X64-SSE2-NEXT:    xorps %xmm2, %xmm2
-; X64-SSE2-NEXT:    cvtsi2sd %rax, %xmm2
+; X64-SSE2-NEXT:    movapd {{.*#+}} xmm1 = [NaN,NaN]
+; X64-SSE2-NEXT:    movapd %xmm0, %xmm2
 ; X64-SSE2-NEXT:    andpd %xmm1, %xmm2
-; X64-SSE2-NEXT:    pandn %xmm0, %xmm1
-; X64-SSE2-NEXT:    por %xmm2, %xmm1
-; X64-SSE2-NEXT:    movdqa %xmm1, %xmm3
-; X64-SSE2-NEXT:  .LBB0_2:
-; X64-SSE2-NEXT:    cmpeqsd %xmm3, %xmm0
-; X64-SSE2-NEXT:    movq %xmm0, %rax
+; X64-SSE2-NEXT:    cvttsd2si %xmm2, %rax
+; X64-SSE2-NEXT:    cvtsi2sd %rax, %xmm3
+; X64-SSE2-NEXT:    andpd %xmm1, %xmm3
+; X64-SSE2-NEXT:    andnpd %xmm0, %xmm1
+; X64-SSE2-NEXT:    orpd %xmm1, %xmm3
+; X64-SSE2-NEXT:    cmpnltsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
+; X64-SSE2-NEXT:    movapd %xmm2, %xmm1
+; X64-SSE2-NEXT:    andnpd %xmm3, %xmm1
+; X64-SSE2-NEXT:    andpd %xmm0, %xmm2
+; X64-SSE2-NEXT:    orpd %xmm1, %xmm2
+; X64-SSE2-NEXT:    cmpeqsd %xmm0, %xmm2
+; X64-SSE2-NEXT:    movq %xmm2, %rax
 ; X64-SSE2-NEXT:    andl $1, %eax
 ; X64-SSE2-NEXT:    # kill: def $eax killed $eax killed $rax
 ; X64-SSE2-NEXT:    retq
@@ -77,46 +73,42 @@ define i32 @isint_return(double %d) nounwind {
 define i32 @isint_float_return(float %f) nounwind {
 ; X86-LABEL: isint_float_return:
 ; X86:       # %bb.0:
-; X86-NEXT:    movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
-; X86-NEXT:    movdqa {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
-; X86-NEXT:    movdqa %xmm0, %xmm2
-; X86-NEXT:    pand %xmm1, %xmm2
-; X86-NEXT:    movd %xmm2, %eax
-; X86-NEXT:    cmpl $1325400064, %eax # imm = 0x4F000000
-; X86-NEXT:    movdqa %xmm0, %xmm3
-; X86-NEXT:    jge .LBB1_2
-; X86-NEXT:  # %bb.1:
-; X86-NEXT:    cvttps2dq %xmm2, %xmm2
-; X86-NEXT:    cvtdq2ps %xmm2, %xmm2
-; X86-NEXT:    andps %xmm1, %xmm2
-; X86-NEXT:    pandn %xmm0, %xmm1
-; X86-NEXT:    por %xmm2, %xmm1
-; X86-NEXT:    movdqa %xmm1, %xmm3
-; X86-NEXT:  .LBB1_2:
-; X86-NEXT:    cmpeqss %xmm0, %xmm3
-; X86-NEXT:    movd %xmm3, %eax
+; X86-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
+; X86-NEXT:    movaps {{.*#+}} xmm2 = [NaN,NaN,NaN,NaN]
+; X86-NEXT:    movaps %xmm0, %xmm1
+; X86-NEXT:    andps %xmm2, %xmm1
+; X86-NEXT:    cvttps2dq %xmm1, %xmm3
+; X86-NEXT:    cvtdq2ps %xmm3, %xmm3
+; X86-NEXT:    andps %xmm2, %xmm3
+; X86-NEXT:    andnps %xmm0, %xmm2
+; X86-NEXT:    orps %xmm2, %xmm3
+; X86-NEXT:    cmpnltss {{\.?LCPI[0-9]+_[0-9]+}}, %xmm1
+; X86-NEXT:    movaps %xmm1, %xmm2
+; X86-NEXT:    andnps %xmm3, %xmm2
+; X86-NEXT:    andps %xmm0, %xmm1
+; X86-NEXT:    orps %xmm2, %xmm1
+; X86-NEXT:    cmpeqss %xmm0, %xmm1
+; X86-NEXT:    movd %xmm1, %eax
 ; X86-NEXT:    andl $1, %eax
 ; X86-NEXT:    retl
 ;
 ; X64-SSE2-LABEL: isint_float_return:
 ; X64-SSE2:       # %bb.0:
-; X64-SSE2-NEXT:    movdqa {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
-; X64-SSE2-NEXT:    movdqa %xmm0, %xmm2
-; X64-SSE2-NEXT:    pand %xmm1, %xmm2
-; X64-SSE2-NEXT:    movd %xmm2, %eax
-; X64-SSE2-NEXT:    movdqa %xmm0, %xmm3
-; X64-SSE2-NEXT:    cmpl $1325400064, %eax # imm = 0x4F000000
-; X64-SSE2-NEXT:    jge .LBB1_2
-; X64-SSE2-NEXT:  # %bb.1:
-; X64-SSE2-NEXT:    cvttps2dq %xmm2, %xmm2
-; X64-SSE2-NEXT:    cvtdq2ps %xmm2, %xmm2
+; X64-SSE2-NEXT:    movaps {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
+; X64-SSE2-NEXT:    movaps %xmm0, %xmm2
 ; X64-SSE2-NEXT:    andps %xmm1, %xmm2
-; X64-SSE2-NEXT:    pandn %xmm0, %xmm1
-; X64-SSE2-NEXT:    por %xmm2, %xmm1
-; X64-SSE2-NEXT:    movdqa %xmm1, %xmm3
-; X64-SSE2-NEXT:  .LBB1_2:
-; X64-SSE2-NEXT:    cmpeqss %xmm3, %xmm0
-; X64-SSE2-NEXT:    movd %xmm0, %eax
+; X64-SSE2-NEXT:    cvttps2dq %xmm2, %xmm3
+; X64-SSE2-NEXT:    cvtdq2ps %xmm3, %xmm3
+; X64-SSE2-NEXT:    andps %xmm1, %xmm3
+; X64-SSE2-NEXT:    andnps %xmm0, %xmm1
+; X64-SSE2-NEXT:    orps %xmm1, %xmm3
+; X64-SSE2-NEXT:    cmpnltss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
+; X64-SSE2-NEXT:    movaps %xmm2, %xmm1
+; X64-SSE2-NEXT:    andnps %xmm3, %xmm1
+; X64-SSE2-NEXT:    andps %xmm0, %xmm2
+; X64-SSE2-NEXT:    orps %xmm1, %xmm2
+; X64-SSE2-NEXT:    cmpeqss %xmm0, %xmm2
+; X64-SSE2-NEXT:    movd %xmm2, %eax
 ; X64-SSE2-NEXT:    andl $1, %eax
 ; X64-SSE2-NEXT:    retq
 ;
@@ -167,31 +159,27 @@ define void @isint_branch(double %d) nounwind {
 ;
 ; X64-SSE2-LABEL: isint_branch:
 ; X64-SSE2:       # %bb.0:
-; X64-SSE2-NEXT:    movdqa {{.*#+}} xmm1 = [NaN,NaN]
-; X64-SSE2-NEXT:    movdqa %xmm0, %xmm2
-; X64-SSE2-NEXT:    pand %xmm1, %xmm2
-; X64-SSE2-NEXT:    movq %xmm2, %rax
-; X64-SSE2-NEXT:    movabsq $4841369599423283199, %rcx # imm = 0x432FFFFFFFFFFFFF
-; X64-SSE2-NEXT:    movdqa %xmm0, %xmm3
-; X64-SSE2-NEXT:    cmpq %rcx, %rax
-; X64-SSE2-NEXT:    jg .LBB2_2
-; X64-SSE2-NEXT:  # %bb.1:
-; X64-SSE2-NEXT:    cvttsd2si %xmm2, %rax
-; X64-SSE2-NEXT:    xorps %xmm2, %xmm2
-; X64-SSE2-NEXT:    cvtsi2sd %rax, %xmm2
+; X64-SSE2-NEXT:    movapd {{.*#+}} xmm1 = [NaN,NaN]
+; X64-SSE2-NEXT:    movapd %xmm0, %xmm2
 ; X64-SSE2-NEXT:    andpd %xmm1, %xmm2
-; X64-SSE2-NEXT:    pandn %xmm0, %xmm1
-; X64-SSE2-NEXT:    por %xmm2, %xmm1
-; X64-SSE2-NEXT:    movdqa %xmm1, %xmm3
-; X64-SSE2-NEXT:  .LBB2_2:
-; X64-SSE2-NEXT:    ucomisd %xmm3, %xmm0
-; X64-SSE2-NEXT:    jne .LBB2_4
-; X64-SSE2-NEXT:    jp .LBB2_4
-; X64-SSE2-NEXT:  # %bb.3: # %true
+; X64-SSE2-NEXT:    cvttsd2si %xmm2, %rax
+; X64-SSE2-NEXT:    cvtsi2sd %rax, %xmm3
+; X64-SSE2-NEXT:    andpd %xmm1, %xmm3
+; X64-SSE2-NEXT:    andnpd %xmm0, %xmm1
+; X64-SSE2-NEXT:    orpd %xmm1, %xmm3
+; X64-SSE2-NEXT:    cmpnltsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
+; X64-SSE2-NEXT:    movapd %xmm2, %xmm1
+; X64-SSE2-NEXT:    andnpd %xmm3, %xmm1
+; X64-SSE2-NEXT:    andpd %xmm0, %xmm2
+; X64-SSE2-NEXT:    orpd %xmm1, %xmm2
+; X64-SSE2-NEXT:    ucomisd %xmm2, %xmm0
+; X64-SSE2-NEXT:    jne .LBB2_2
+; X64-SSE2-NEXT:    jp .LBB2_2
+; X64-SSE2-NEXT:  # %bb.1: # %true
 ; X64-SSE2-NEXT:    pushq %rax
 ; X64-SSE2-NEXT:    callq foo at PLT
 ; X64-SSE2-NEXT:    popq %rax
-; X64-SSE2-NEXT:  .LBB2_4: # %false
+; X64-SSE2-NEXT:  .LBB2_2: # %false
 ; X64-SSE2-NEXT:    retq
 ;
 ; X64-SSE42-LABEL: isint_branch:
diff --git a/llvm/test/CodeGen/X86/llround-conv.ll b/llvm/test/CodeGen/X86/llround-conv.ll
index 1779538c61add..4c335f60d60c9 100644
--- a/llvm/test/CodeGen/X86/llround-conv.ll
+++ b/llvm/test/CodeGen/X86/llround-conv.ll
@@ -33,21 +33,20 @@ define i64 @test_llround_f16(half %x) nounwind {
 ; X64:       # %bb.0:
 ; X64-NEXT:    pushq %rax
 ; X64-NEXT:    callq __extendhfsf2 at PLT
-; X64-NEXT:    movdqa {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
-; X64-NEXT:    movdqa %xmm0, %xmm2
-; X64-NEXT:    pand %xmm1, %xmm2
-; X64-NEXT:    movd %xmm2, %eax
-; X64-NEXT:    cmpl $1325400064, %eax # imm = 0x4F000000
-; X64-NEXT:    jge .LBB0_2
-; X64-NEXT:  # %bb.1:
-; X64-NEXT:    addss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
-; X64-NEXT:    cvttps2dq %xmm2, %xmm2
-; X64-NEXT:    cvtdq2ps %xmm2, %xmm2
+; X64-NEXT:    movaps {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
+; X64-NEXT:    movaps %xmm0, %xmm2
 ; X64-NEXT:    andps %xmm1, %xmm2
-; X64-NEXT:    pandn %xmm0, %xmm1
-; X64-NEXT:    por %xmm2, %xmm1
-; X64-NEXT:    movdqa %xmm1, %xmm0
-; X64-NEXT:  .LBB0_2:
+; X64-NEXT:    movss {{.*#+}} xmm3 = [4.9999997E-1,0.0E+0,0.0E+0,0.0E+0]
+; X64-NEXT:    addss %xmm2, %xmm3
+; X64-NEXT:    cvttps2dq %xmm3, %xmm3
+; X64-NEXT:    cvtdq2ps %xmm3, %xmm3
+; X64-NEXT:    andps %xmm1, %xmm3
+; X64-NEXT:    andnps %xmm0, %xmm1
+; X64-NEXT:    orps %xmm1, %xmm3
+; X64-NEXT:    cmpnltss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
+; X64-NEXT:    andps %xmm2, %xmm0
+; X64-NEXT:    andnps %xmm3, %xmm2
+; X64-NEXT:    orps %xmm2, %xmm0
 ; X64-NEXT:    callq __truncsfhf2 at PLT
 ; X64-NEXT:    callq __extendhfsf2 at PLT
 ; X64-NEXT:    cvttss2si %xmm0, %rax
@@ -227,21 +226,20 @@ define i64 @test_llround_i64_f16(half %x) nounwind {
 ; X64:       # %bb.0:
 ; X64-NEXT:    pushq %rax
 ; X64-NEXT:    callq __extendhfsf2 at PLT
-; X64-NEXT:    movdqa {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
-; X64-NEXT:    movdqa %xmm0, %xmm2
-; X64-NEXT:    pand %xmm1, %xmm2
-; X64-NEXT:    movd %xmm2, %eax
-; X64-NEXT:    cmpl $1325400064, %eax # imm = 0x4F000000
-; X64-NEXT:    jge .LBB4_2
-; X64-NEXT:  # %bb.1:
-; X64-NEXT:    addss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
-; X64-NEXT:    cvttps2dq %xmm2, %xmm2
-; X64-NEXT:    cvtdq2ps %xmm2, %xmm2
+; X64-NEXT:    movaps {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
+; X64-NEXT:    movaps %xmm0, %xmm2
 ; X64-NEXT:    andps %xmm1, %xmm2
-; X64-NEXT:    pandn %xmm0, %xmm1
-; X64-NEXT:    por %xmm2, %xmm1
-; X64-NEXT:    movdqa %xmm1, %xmm0
-; X64-NEXT:  .LBB4_2:
+; X64-NEXT:    movss {{.*#+}} xmm3 = [4.9999997E-1,0.0E+0,0.0E+0,0.0E+0]
+; X64-NEXT:    addss %xmm2, %xmm3
+; X64-NEXT:    cvttps2dq %xmm3, %xmm3
+; X64-NEXT:    cvtdq2ps %xmm3, %xmm3
+; X64-NEXT:    andps %xmm1, %xmm3
+; X64-NEXT:    andnps %xmm0, %xmm1
+; X64-NEXT:    orps %xmm1, %xmm3
+; X64-NEXT:    cmpnltss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
+; X64-NEXT:    andps %xmm2, %xmm0
+; X64-NEXT:    andnps %xmm3, %xmm2
+; X64-NEXT:    orps %xmm2, %xmm0
 ; X64-NEXT:    callq __truncsfhf2 at PLT
 ; X64-NEXT:    callq __extendhfsf2 at PLT
 ; X64-NEXT:    cvttss2si %xmm0, %rax
diff --git a/llvm/test/CodeGen/X86/lround-conv-i32.ll b/llvm/test/CodeGen/X86/lround-conv-i32.ll
index 7c15c8318353a..d52d7df6c1512 100644
--- a/llvm/test/CodeGen/X86/lround-conv-i32.ll
+++ b/llvm/test/CodeGen/X86/lround-conv-i32.ll
@@ -25,23 +25,23 @@ define i32 @test_lround_i32_f16(half %x) nounwind {
 ; X86-SSE2-NEXT:    movw %ax, (%esp)
 ; X86-SSE2-NEXT:    calll __extendhfsf2
 ; X86-SSE2-NEXT:    fstps {{[0-9]+}}(%esp)
-; X86-SSE2-NEXT:    movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
-; X86-SSE2-NEXT:    movdqa {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
-; X86-SSE2-NEXT:    movdqa %xmm0, %xmm2
-; X86-SSE2-NEXT:    pand %xmm1, %xmm2
-; X86-SSE2-NEXT:    movd %xmm2, %eax
-; X86-SSE2-NEXT:    cmpl $1325400064, %eax # imm = 0x4F000000
-; X86-SSE2-NEXT:    jge .LBB0_2
-; X86-SSE2-NEXT:  # %bb.1:
-; X86-SSE2-NEXT:    addss {{\.?LCPI[0-9]+_[0-9]+}}, %xmm2
-; X86-SSE2-NEXT:    cvttps2dq %xmm2, %xmm2
-; X86-SSE2-NEXT:    cvtdq2ps %xmm2, %xmm2
-; X86-SSE2-NEXT:    andps %xmm1, %xmm2
-; X86-SSE2-NEXT:    pandn %xmm0, %xmm1
-; X86-SSE2-NEXT:    por %xmm2, %xmm1
-; X86-SSE2-NEXT:    movdqa %xmm1, %xmm0
-; X86-SSE2-NEXT:  .LBB0_2:
-; X86-SSE2-NEXT:    movd %xmm0, (%esp)
+; X86-SSE2-NEXT:    movaps {{.*#+}} xmm2 = [NaN,NaN,NaN,NaN]
+; X86-SSE2-NEXT:    movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
+; X86-SSE2-NEXT:    movaps %xmm1, %xmm0
+; X86-SSE2-NEXT:    andps %xmm2, %xmm0
+; X86-SSE2-NEXT:    movss {{.*#+}} xmm3 = [4.9999997E-1,0.0E+0,0.0E+0,0.0E+0]
+; X86-SSE2-NEXT:    addss %xmm0, %xmm3
+; X86-SSE2-NEXT:    cvttps2dq %xmm3, %xmm3
+; X86-SSE2-NEXT:    cvtdq2ps %xmm3, %xmm3
+; X86-SSE2-NEXT:    andps %xmm2, %xmm3
+; X86-SSE2-NEXT:    andnps %xmm1, %xmm2
+; X86-SSE2-NEXT:    orps %xmm2, %xmm3
+; X86-SSE2-NEXT:    cmpnltss {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
+; X86-SSE2-NEXT:    movaps %xmm0, %xmm2
+; X86-SSE2-NEXT:    andnps %xmm3, %xmm2
+; X86-SSE2-NEXT:    andps %xmm1, %xmm0
+; X86-SSE2-NEXT:    orps %xmm2, %xmm0
+; X86-SSE2-NEXT:    movss %xmm0, (%esp)
 ; X86-SSE2-NEXT:    calll __truncsfhf2
 ; X86-SSE2-NEXT:    pextrw $0, %xmm0, %eax
 ; X86-SSE2-NEXT:    movw %ax, (%esp)
@@ -55,21 +55,20 @@ define i32 @test_lround_i32_f16(half %x) nounwind {
 ; X64:       # %bb.0:
 ; X64-NEXT:    pushq %rax
 ; X64-NEXT:    callq __extendhfsf2 at PLT
-; X64-NEXT:    movdqa {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
-; X64-NEXT:    movdqa %xmm0, %xmm2
-; X64-NEXT:    pand %xmm1, %xmm2
-; X64-NEXT:    movd %xmm2, %eax
-; X64-NEXT:    cmpl $1325400064, %eax # imm = 0x4F000000
-; X64-NEXT:    jge .LBB0_2
-; X64-NEXT:  # %bb.1:
-; X64-NEXT:    addss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
-; X64-NEXT:    cvttps2dq %xmm2, %xmm2
-; X64-NEXT:    cvtdq2ps %xmm2, %xmm2
+; X64-NEXT:    movaps {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
+; X64-NEXT:    movaps %xmm0, %xmm2
 ; X64-NEXT:    andps %xmm1, %xmm2
-; X64-NEXT:    pandn %xmm0, %xmm1
-; X64-NEXT:    por %xmm2, %xmm1
-; X64-NEXT:    movdqa %xmm1, %xmm0
-; X64-NEXT:  .LBB0_2:
+; X64-NEXT:    movss {{.*#+}} xmm3 = [4.9999997E-1,0.0E+0,0.0E+0,0.0E+0]
+; X64-NEXT:    addss %xmm2, %xmm3
+; X64-NEXT:    cvttps2dq %xmm3, %xmm3
+; X64-NEXT:    cvtdq2ps %xmm3, %xmm3
+; X64-NEXT:    andps %xmm1, %xmm3
+; X64-NEXT:    andnps %xmm0, %xmm1
+; X64-NEXT:    orps %xmm1, %xmm3
+; X64-NEXT:    cmpnltss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
+; X64-NEXT:    andps %xmm2, %xmm0
+; X64-NEXT:    andnps %xmm3, %xmm2
+; X64-NEXT:    orps %xmm2, %xmm0
 ; X64-NEXT:    callq __truncsfhf2 at PLT
 ; X64-NEXT:    callq __extendhfsf2 at PLT
 ; X64-NEXT:    cvttss2si %xmm0, %eax
diff --git a/llvm/test/CodeGen/X86/lround-conv-i64.ll b/llvm/test/CodeGen/X86/lround-conv-i64.ll
index fc9aa38a8475b..0a2bfe595031c 100644
--- a/llvm/test/CodeGen/X86/lround-conv-i64.ll
+++ b/llvm/test/CodeGen/X86/lround-conv-i64.ll
@@ -33,21 +33,20 @@ define i64 @test_lround_i64_f16(half %x) nounwind {
 ; X64:       # %bb.0: # %entry
 ; X64-NEXT:    pushq %rax
 ; X64-NEXT:    callq __extendhfsf2 at PLT
-; X64-NEXT:    movdqa {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
-; X64-NEXT:    movdqa %xmm0, %xmm2
-; X64-NEXT:    pand %xmm1, %xmm2
-; X64-NEXT:    movd %xmm2, %eax
-; X64-NEXT:    cmpl $1325400064, %eax # imm = 0x4F000000
-; X64-NEXT:    jge .LBB0_2
-; X64-NEXT:  # %bb.1: # %entry
-; X64-NEXT:    addss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
-; X64-NEXT:    cvttps2dq %xmm2, %xmm2
-; X64-NEXT:    cvtdq2ps %xmm2, %xmm2
+; X64-NEXT:    movaps {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
+; X64-NEXT:    movaps %xmm0, %xmm2
 ; X64-NEXT:    andps %xmm1, %xmm2
-; X64-NEXT:    pandn %xmm0, %xmm1
-; X64-NEXT:    por %xmm2, %xmm1
-; X64-NEXT:    movdqa %xmm1, %xmm0
-; X64-NEXT:  .LBB0_2: # %entry
+; X64-NEXT:    movss {{.*#+}} xmm3 = [4.9999997E-1,0.0E+0,0.0E+0,0.0E+0]
+; X64-NEXT:    addss %xmm2, %xmm3
+; X64-NEXT:    cvttps2dq %xmm3, %xmm3
+; X64-NEXT:    cvtdq2ps %xmm3, %xmm3
+; X64-NEXT:    andps %xmm1, %xmm3
+; X64-NEXT:    andnps %xmm0, %xmm1
+; X64-NEXT:    orps %xmm1, %xmm3
+; X64-NEXT:    cmpnltss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
+; X64-NEXT:    andps %xmm2, %xmm0
+; X64-NEXT:    andnps %xmm3, %xmm2
+; X64-NEXT:    orps %xmm2, %xmm0
 ; X64-NEXT:    callq __truncsfhf2 at PLT
 ; X64-NEXT:    callq __extendhfsf2 at PLT
 ; X64-NEXT:    cvttss2si %xmm0, %rax
diff --git a/llvm/test/CodeGen/X86/unpredictable-brcond.ll b/llvm/test/CodeGen/X86/unpredictable-brcond.ll
index ebf1178043d20..e93114a90242e 100644
--- a/llvm/test/CodeGen/X86/unpredictable-brcond.ll
+++ b/llvm/test/CodeGen/X86/unpredictable-brcond.ll
@@ -80,7 +80,7 @@ false:
 define void @isint_branch(double %d) nounwind {
   ; CHECK-LABEL: name: isint_branch
   ; CHECK: bb.0 (%ir-block.0):
-  ; CHECK-NEXT:   successors: %bb.3(0x40000000), %bb.4(0x40000000)
+  ; CHECK-NEXT:   successors: %bb.1(0x50000000), %bb.2(0x30000000)
   ; CHECK-NEXT:   liveins: $xmm0
   ; CHECK-NEXT: {{  $}}
   ; CHECK-NEXT:   [[COPY:%[0-9]+]]:fr64 = COPY $xmm0
@@ -94,20 +94,13 @@ define void @isint_branch(double %d) nounwind {
   ; CHECK-NEXT:   [[COPY3:%[0-9]+]]:vr128 = COPY killed [[CVTSI642SDrr]]
   ; CHECK-NEXT:   [[PANDrr1:%[0-9]+]]:vr128 = PANDrr [[COPY3]], [[MOVAPDrm]]
   ; CHECK-NEXT:   [[PORrr:%[0-9]+]]:vr128 = PORrr [[PANDrr1]], killed [[PANDNrr]]
-  ; CHECK-NEXT:   [[COPY4:%[0-9]+]]:fr64 = COPY killed [[PORrr]]
-  ; CHECK-NEXT:   [[MOVSDto64rr:%[0-9]+]]:gr64 = MOVSDto64rr [[COPY2]]
-  ; CHECK-NEXT:   [[MOV64ri:%[0-9]+]]:gr64 = MOV64ri 4841369599423283199
-  ; CHECK-NEXT:   [[SUB64rr:%[0-9]+]]:gr64 = SUB64rr [[MOVSDto64rr]], killed [[MOV64ri]], implicit-def $eflags
-  ; CHECK-NEXT:   JCC_1 %bb.4, 15, implicit $eflags
-  ; CHECK-NEXT: {{  $}}
-  ; CHECK-NEXT: bb.3 (%ir-block.0):
-  ; CHECK-NEXT:   successors: %bb.4(0x80000000)
-  ; CHECK-NEXT: {{  $}}
-  ; CHECK-NEXT: bb.4 (%ir-block.0):
-  ; CHECK-NEXT:   successors: %bb.1(0x50000000), %bb.2(0x30000000)
-  ; CHECK-NEXT: {{  $}}
-  ; CHECK-NEXT:   [[PHI:%[0-9]+]]:fr64 = PHI [[COPY4]], %bb.3, [[COPY]], %bb.0
-  ; CHECK-NEXT:   nofpexcept UCOMISDrr [[COPY]], killed [[PHI]], implicit-def $eflags, implicit $mxcsr
+  ; CHECK-NEXT:   [[CMPSDrmi:%[0-9]+]]:fr64 = nofpexcept CMPSDrmi [[COPY2]], $rip, 1, $noreg, %const.1, $noreg, 5, implicit $mxcsr :: (load (s64) from constant-pool)
+  ; CHECK-NEXT:   [[COPY4:%[0-9]+]]:vr128 = COPY killed [[CMPSDrmi]]
+  ; CHECK-NEXT:   [[PANDNrr1:%[0-9]+]]:vr128 = PANDNrr [[COPY4]], killed [[PORrr]]
+  ; CHECK-NEXT:   [[PANDrr2:%[0-9]+]]:vr128 = PANDrr [[COPY4]], [[COPY1]]
+  ; CHECK-NEXT:   [[PORrr1:%[0-9]+]]:vr128 = PORrr [[PANDNrr1]], killed [[PANDrr2]]
+  ; CHECK-NEXT:   [[COPY5:%[0-9]+]]:fr64 = COPY killed [[PORrr1]]
+  ; CHECK-NEXT:   nofpexcept UCOMISDrr [[COPY]], killed [[COPY5]], implicit-def $eflags, implicit $mxcsr
   ; CHECK-NEXT:   unpredictable JCC_1 %bb.2, 5, implicit $eflags
   ; CHECK-NEXT:   unpredictable JCC_1 %bb.2, 10, implicit $eflags
   ; CHECK-NEXT:   JMP_1 %bb.1

>From 2a221ace62348bd911d979a7cfc8661fa9195af8 Mon Sep 17 00:00:00 2001
From: Divyansh <anshmcs at gmail.com>
Date: Sat, 26 Sep 2026 10:15:22 +0530
Subject: [PATCH 4/8] Apply clang-format fixes

---
 llvm/lib/Target/X86/X86ISelLowering.cpp | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index e7d6a0a2d788f..9db2ab672eadd 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -23221,9 +23221,8 @@ static SDValue lowerFTRUNC_FROUND_SSE2(SDValue Op, SelectionDAG &DAG) {
     llvm_unreachable("Unexpected type");
 
   const fltSemantics &Sem = VT.getFltSemantics();
-  APFloat Bound = VT.getScalarType() == MVT::f32
-                      ? APFloat(Sem, "0x1.0p23")
-                      : APFloat(Sem, "0x1.0p52");
+  APFloat Bound = VT.getScalarType() == MVT::f32 ? APFloat(Sem, "0x1.0p23")
+                                                 : APFloat(Sem, "0x1.0p52");
   SDValue Threshold = DAG.getConstantFP(Bound, DL, VT);
 
   EVT CCVT = DAG.getTargetLoweringInfo().getSetCCResultType(

>From e4b7604a1ab5b2383652a6888780890520b5581d Mon Sep 17 00:00:00 2001
From: Divyansh <anshmcs at gmail.com>
Date: Sun, 27 Sep 2026 13:50:13 +0530
Subject: [PATCH 5/8] [X86] Use 2^31/2^63 thresholds for SSE2 ftrunc/fround to
 maximize branch elimination potential

---
 llvm/lib/Target/X86/X86ISelLowering.cpp | 6 ++++--
 llvm/test/CodeGen/X86/fp-round.ll       | 8 ++++----
 llvm/test/CodeGen/X86/ftrunc.ll         | 4 ++--
 3 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 9db2ab672eadd..7f0a7c8b2ccc7 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -23221,8 +23221,10 @@ static SDValue lowerFTRUNC_FROUND_SSE2(SDValue Op, SelectionDAG &DAG) {
     llvm_unreachable("Unexpected type");
 
   const fltSemantics &Sem = VT.getFltSemantics();
-  APFloat Bound = VT.getScalarType() == MVT::f32 ? APFloat(Sem, "0x1.0p23")
-                                                 : APFloat(Sem, "0x1.0p52");
+  // Any threshold in [2^23, 2^31] for float (or [2^52, 2^63] for double) is
+  // correct since all FP values at or above 2^23 (2^52) are already integers.
+  APFloat Bound = VT.getScalarType() == MVT::f32 ? APFloat(Sem, "0x1.0p31")
+                                                 : APFloat(Sem, "0x1.0p63");
   SDValue Threshold = DAG.getConstantFP(Bound, DL, VT);
 
   EVT CCVT = DAG.getTargetLoweringInfo().getSetCCResultType(
diff --git a/llvm/test/CodeGen/X86/fp-round.ll b/llvm/test/CodeGen/X86/fp-round.ll
index 797e8fbe7dafd..6a1cde72308dc 100644
--- a/llvm/test/CodeGen/X86/fp-round.ll
+++ b/llvm/test/CodeGen/X86/fp-round.ll
@@ -336,7 +336,7 @@ define <8 x float> @round_v8f32(<8 x float> %x) {
 ; SSE2-NEXT:    andps %xmm3, %xmm4
 ; SSE2-NEXT:    andnps %xmm0, %xmm3
 ; SSE2-NEXT:    orps %xmm3, %xmm5
-; SSE2-NEXT:    movaps {{.*#+}} xmm3 = [8.388608E+6,8.388608E+6,8.388608E+6,8.388608E+6]
+; SSE2-NEXT:    movaps {{.*#+}} xmm3 = [2.14748365E+9,2.14748365E+9,2.14748365E+9,2.14748365E+9]
 ; SSE2-NEXT:    cmpnltps %xmm3, %xmm2
 ; SSE2-NEXT:    andps %xmm2, %xmm0
 ; SSE2-NEXT:    andnps %xmm5, %xmm2
@@ -411,7 +411,7 @@ define <4 x double> @round_v4f64(<4 x double> %x) {
 ; SSE2-NEXT:    movapd %xmm2, %xmm5
 ; SSE2-NEXT:    andnpd %xmm0, %xmm5
 ; SSE2-NEXT:    orpd %xmm6, %xmm5
-; SSE2-NEXT:    movapd {{.*#+}} xmm6 = [4.503599627370496E+15,4.503599627370496E+15]
+; SSE2-NEXT:    movapd {{.*#+}} xmm6 = [9.2233720368547758E+18,9.2233720368547758E+18]
 ; SSE2-NEXT:    cmpnltpd %xmm6, %xmm4
 ; SSE2-NEXT:    andpd %xmm4, %xmm0
 ; SSE2-NEXT:    andnpd %xmm5, %xmm4
@@ -515,7 +515,7 @@ define <16 x float> @round_v16f32(<16 x float> %x) {
 ; SSE2-NEXT:    andps %xmm5, %xmm7
 ; SSE2-NEXT:    andnps %xmm0, %xmm5
 ; SSE2-NEXT:    orps %xmm5, %xmm6
-; SSE2-NEXT:    movaps {{.*#+}} xmm5 = [8.388608E+6,8.388608E+6,8.388608E+6,8.388608E+6]
+; SSE2-NEXT:    movaps {{.*#+}} xmm5 = [2.14748365E+9,2.14748365E+9,2.14748365E+9,2.14748365E+9]
 ; SSE2-NEXT:    cmpnltps %xmm5, %xmm4
 ; SSE2-NEXT:    andps %xmm4, %xmm0
 ; SSE2-NEXT:    andnps %xmm6, %xmm4
@@ -618,7 +618,7 @@ define <8 x double> @round_v8f64(<8 x double> %x) {
 ; SSE2-NEXT:    movapd %xmm4, %xmm9
 ; SSE2-NEXT:    andnpd %xmm0, %xmm9
 ; SSE2-NEXT:    orpd %xmm8, %xmm9
-; SSE2-NEXT:    movapd {{.*#+}} xmm6 = [4.503599627370496E+15,4.503599627370496E+15]
+; SSE2-NEXT:    movapd {{.*#+}} xmm6 = [9.2233720368547758E+18,9.2233720368547758E+18]
 ; SSE2-NEXT:    cmpnltpd %xmm6, %xmm7
 ; SSE2-NEXT:    andpd %xmm7, %xmm0
 ; SSE2-NEXT:    andnpd %xmm9, %xmm7
diff --git a/llvm/test/CodeGen/X86/ftrunc.ll b/llvm/test/CodeGen/X86/ftrunc.ll
index 11f9a921bc6aa..a73d9a6a1706b 100644
--- a/llvm/test/CodeGen/X86/ftrunc.ll
+++ b/llvm/test/CodeGen/X86/ftrunc.ll
@@ -177,7 +177,7 @@ define <4 x double> @trunc_unsigned_v4f64(<4 x double> %x) #0 {
 ; SSE2-NEXT:    movapd %xmm2, %xmm5
 ; SSE2-NEXT:    andnpd %xmm0, %xmm5
 ; SSE2-NEXT:    orpd %xmm4, %xmm5
-; SSE2-NEXT:    movapd {{.*#+}} xmm4 = [4.503599627370496E+15,4.503599627370496E+15]
+; SSE2-NEXT:    movapd {{.*#+}} xmm4 = [9.2233720368547758E+18,9.2233720368547758E+18]
 ; SSE2-NEXT:    cmpnltpd %xmm4, %xmm3
 ; SSE2-NEXT:    andpd %xmm3, %xmm0
 ; SSE2-NEXT:    andnpd %xmm5, %xmm3
@@ -650,7 +650,7 @@ define <4 x double> @trunc_signed_v4f64_nsz(<4 x double> %x) #0 {
 ; SSE2-NEXT:    movapd %xmm2, %xmm5
 ; SSE2-NEXT:    andnpd %xmm0, %xmm5
 ; SSE2-NEXT:    orpd %xmm4, %xmm5
-; SSE2-NEXT:    movapd {{.*#+}} xmm4 = [4.503599627370496E+15,4.503599627370496E+15]
+; SSE2-NEXT:    movapd {{.*#+}} xmm4 = [9.2233720368547758E+18,9.2233720368547758E+18]
 ; SSE2-NEXT:    cmpnltpd %xmm4, %xmm3
 ; SSE2-NEXT:    andpd %xmm3, %xmm0
 ; SSE2-NEXT:    andnpd %xmm5, %xmm3

>From 0629ad8ff719145e4f89bf6b4cad2506cf3ffdb5 Mon Sep 17 00:00:00 2001
From: Divyansh <anshmcs at gmail.com>
Date: Sun, 27 Sep 2026 16:45:08 +0530
Subject: [PATCH 6/8] [X86] Document NaN handling in SSE2 ftrunc/fround
 lowering

---
 llvm/lib/Target/X86/X86ISelLowering.cpp | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 7f0a7c8b2ccc7..54e1c3d81ff3d 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -23229,6 +23229,12 @@ static SDValue lowerFTRUNC_FROUND_SSE2(SDValue Op, SelectionDAG &DAG) {
 
   EVT CCVT = DAG.getTargetLoweringInfo().getSetCCResultType(
       DAG.getDataLayout(), *DAG.getContext(), VT);
+  // Return the input unchanged when |x| >= Threshold: such values are already
+  // integers and could overflow the FP_TO_SINT below. Inf takes this path too,
+  // and since the comparison is unordered, so does every NaN regardless of its
+  // sign bit. We therefore don't rely on FABS clearing the sign bit of a NaN
+  // (though it does: FABS is a bitwise operation defined on the bit
+  // representation, not on the abstract float value).
   SDValue IsLarge = DAG.getSetCC(DL, CCVT, Abs, Threshold, ISD::SETUGE);
 
   SDValue TruncInt = DAG.getNode(ISD::FP_TO_SINT, DL, IntVT, AbsBiased);

>From 0e4f7a0491f2ddc6d8afd7133e4782b12a2074a5 Mon Sep 17 00:00:00 2001
From: Divyansh <anshmcs at gmail.com>
Date: Mon, 28 Sep 2026 14:50:53 +0530
Subject: [PATCH 7/8] [X86] Don't fold fptosi/sitofp round trips into the SSE2
 FTRUNC expansion

---
 llvm/include/llvm/CodeGen/TargetLowering.h    |   8 +
 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp |   9 +-
 llvm/lib/Target/X86/X86ISelLowering.cpp       |   7 +
 llvm/lib/Target/X86/X86ISelLowering.h         |   2 +
 llvm/test/CodeGen/X86/ftrunc.ll               | 337 ++++++++----------
 llvm/test/CodeGen/X86/isint.ll                |  70 +---
 llvm/test/CodeGen/X86/unpredictable-brcond.ll |  20 +-
 7 files changed, 186 insertions(+), 267 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h
index 283b0f811dc2f..9a4a12957ad12 100644
--- a/llvm/include/llvm/CodeGen/TargetLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetLowering.h
@@ -3490,6 +3490,14 @@ class LLVM_ABI TargetLoweringBase {
     return false;
   }
 
+  /// Return true if a custom lowered FTRUNC of type VT is cheap enough that it
+  /// is worthwhile to fold an fpto[us]i -> [us]itofp round trip into it. This
+  /// is only queried when FTRUNC is not legal for VT.
+  virtual bool isCustomFTruncCheap(EVT VT) const {
+    assert(VT.isFloatingPoint());
+    return true;
+  }
+
   /// Return true if an FMA operation is faster than a pair of fmul and fadd
   /// instructions. fmuladd intrinsics will be expanded to FMAs when this method
   /// returns true, otherwise fmuladd is expanded to fmul + fadd.
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 4f20198244883..f9c4195d5a0d8 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -20583,15 +20583,16 @@ static SDValue foldFPToIntToFP(SDNode *N, const SDLoc &DL, SelectionDAG &DAG,
   bool IsSigned = N->getOpcode() == ISD::SINT_TO_FP;
   assert(IsSigned || IsUnsigned);
 
-  // Don't fold if the individual cast operations are already legal,
-  // as FTRUNC may have a more expensive custom expansion.
+  // Don't fold if the individual cast operations are already legal, or the
+  // target reports that its custom FTRUNC expansion is expensive.
   EVT IntVT = N->getOperand(0).getValueType();
   EVT LegalIntVT = TLI.getTypeToTransformTo(*DAG.getContext(), IntVT);
   unsigned FPToIntOp = IsUnsigned ? ISD::FP_TO_UINT : ISD::FP_TO_SINT;
   unsigned IntToFPOp = N->getOpcode(); // UINT_TO_FP or SINT_TO_FP
   if (!TLI.isOperationLegal(ISD::FTRUNC, VT) &&
-      TLI.isOperationLegal(FPToIntOp, LegalIntVT) &&
-      TLI.isOperationLegal(IntToFPOp, VT))
+      ((TLI.isOperationLegal(FPToIntOp, LegalIntVT) &&
+        TLI.isOperationLegal(IntToFPOp, VT)) ||
+       !TLI.isCustomFTruncCheap(VT)))
     return SDValue();
 
   bool IsSignedZeroSafe = DAG.canIgnoreSignBitOfZero(SDValue(N, 0));
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 54e1c3d81ff3d..268864da70a85 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -3814,6 +3814,13 @@ bool X86TargetLowering::isCtlzFast() const {
   return Subtarget.hasFastLZCNT();
 }
 
+bool X86TargetLowering::isCustomFTruncCheap(EVT VT) const {
+  // Without SSE41, FTRUNC is emulated with a conversion round trip plus a
+  // range check and select, which is more expensive than a plain
+  // fpto[us]i -> [us]itofp pair.
+  return false;
+}
+
 bool X86TargetLowering::preferZeroCompareBranch() const { return true; }
 
 bool X86TargetLowering::isMaskAndCmp0FoldingBeneficial(
diff --git a/llvm/lib/Target/X86/X86ISelLowering.h b/llvm/lib/Target/X86/X86ISelLowering.h
index 34bb76982eecb..12a45a5e1c8d9 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.h
+++ b/llvm/lib/Target/X86/X86ISelLowering.h
@@ -238,6 +238,8 @@ namespace llvm {
 
     bool isCtlzFast() const override;
 
+    bool isCustomFTruncCheap(EVT VT) const override;
+
     bool preferZeroCompareBranch() const override;
 
     bool isMultiStoresCheaperThanBitsMerge(EVT LTy, EVT HTy) const override {
diff --git a/llvm/test/CodeGen/X86/ftrunc.ll b/llvm/test/CodeGen/X86/ftrunc.ll
index a73d9a6a1706b..1ab9040a2810f 100644
--- a/llvm/test/CodeGen/X86/ftrunc.ll
+++ b/llvm/test/CodeGen/X86/ftrunc.ll
@@ -10,18 +10,10 @@ declare i64 @llvm.fptosi.sat.i64.f64(double)
 define float @trunc_unsigned_f32(float %x) #0 {
 ; SSE2-LABEL: trunc_unsigned_f32:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    movaps {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
-; SSE2-NEXT:    movaps %xmm0, %xmm2
-; SSE2-NEXT:    andps %xmm1, %xmm2
-; SSE2-NEXT:    cvttps2dq %xmm2, %xmm3
-; SSE2-NEXT:    cvtdq2ps %xmm3, %xmm3
-; SSE2-NEXT:    andps %xmm1, %xmm3
-; SSE2-NEXT:    andnps %xmm0, %xmm1
-; SSE2-NEXT:    orps %xmm1, %xmm3
-; SSE2-NEXT:    cmpnltss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
-; SSE2-NEXT:    andps %xmm2, %xmm0
-; SSE2-NEXT:    andnps %xmm3, %xmm2
-; SSE2-NEXT:    orps %xmm2, %xmm0
+; SSE2-NEXT:    cvttss2si %xmm0, %rax
+; SSE2-NEXT:    movl %eax, %eax
+; SSE2-NEXT:    xorps %xmm0, %xmm0
+; SSE2-NEXT:    cvtsi2ss %rax, %xmm0
 ; SSE2-NEXT:    retq
 ;
 ; SSE41-LABEL: trunc_unsigned_f32:
@@ -51,18 +43,19 @@ define float @trunc_unsigned_f32(float %x) #0 {
 define double @trunc_unsigned_f64(double %x) #0 {
 ; SSE2-LABEL: trunc_unsigned_f64:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    movapd {{.*#+}} xmm1 = [NaN,NaN]
-; SSE2-NEXT:    movapd %xmm0, %xmm2
-; SSE2-NEXT:    andpd %xmm1, %xmm2
-; SSE2-NEXT:    cvttsd2si %xmm2, %rax
-; SSE2-NEXT:    cvtsi2sd %rax, %xmm3
-; SSE2-NEXT:    andpd %xmm1, %xmm3
-; SSE2-NEXT:    andnpd %xmm0, %xmm1
-; SSE2-NEXT:    orpd %xmm1, %xmm3
-; SSE2-NEXT:    cmpnltsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
-; SSE2-NEXT:    andpd %xmm2, %xmm0
-; SSE2-NEXT:    andnpd %xmm3, %xmm2
-; SSE2-NEXT:    orpd %xmm2, %xmm0
+; SSE2-NEXT:    cvttsd2si %xmm0, %rax
+; SSE2-NEXT:    movq %rax, %rcx
+; SSE2-NEXT:    sarq $63, %rcx
+; SSE2-NEXT:    subsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; SSE2-NEXT:    cvttsd2si %xmm0, %rdx
+; SSE2-NEXT:    andq %rcx, %rdx
+; SSE2-NEXT:    orq %rax, %rdx
+; SSE2-NEXT:    movq %rdx, %xmm1
+; SSE2-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],mem[0],xmm1[1],mem[1]
+; SSE2-NEXT:    subpd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
+; SSE2-NEXT:    movapd %xmm1, %xmm0
+; SSE2-NEXT:    unpckhpd {{.*#+}} xmm0 = xmm0[1],xmm1[1]
+; SSE2-NEXT:    addsd %xmm1, %xmm0
 ; SSE2-NEXT:    retq
 ;
 ; SSE41-LABEL: trunc_unsigned_f64:
@@ -96,18 +89,20 @@ define double @trunc_unsigned_f64(double %x) #0 {
 define <4 x float> @trunc_unsigned_v4f32(<4 x float> %x) #0 {
 ; SSE2-LABEL: trunc_unsigned_v4f32:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    movaps {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
-; SSE2-NEXT:    movaps %xmm0, %xmm2
-; SSE2-NEXT:    andps %xmm1, %xmm2
-; SSE2-NEXT:    cvttps2dq %xmm2, %xmm3
-; SSE2-NEXT:    cvtdq2ps %xmm3, %xmm3
-; SSE2-NEXT:    andps %xmm1, %xmm3
-; SSE2-NEXT:    andnps %xmm0, %xmm1
-; SSE2-NEXT:    orps %xmm1, %xmm3
-; SSE2-NEXT:    cmpnltps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
-; SSE2-NEXT:    andps %xmm2, %xmm0
-; SSE2-NEXT:    andnps %xmm3, %xmm2
-; SSE2-NEXT:    orps %xmm2, %xmm0
+; SSE2-NEXT:    cvttps2dq %xmm0, %xmm1
+; SSE2-NEXT:    movdqa %xmm1, %xmm2
+; SSE2-NEXT:    psrad $31, %xmm2
+; SSE2-NEXT:    subps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; SSE2-NEXT:    cvttps2dq %xmm0, %xmm0
+; SSE2-NEXT:    pand %xmm2, %xmm0
+; SSE2-NEXT:    por %xmm1, %xmm0
+; SSE2-NEXT:    movdqa {{.*#+}} xmm1 = [65535,65535,65535,65535]
+; SSE2-NEXT:    pand %xmm0, %xmm1
+; SSE2-NEXT:    por {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
+; SSE2-NEXT:    psrld $16, %xmm0
+; SSE2-NEXT:    por {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; SSE2-NEXT:    subps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; SSE2-NEXT:    addps %xmm1, %xmm0
 ; SSE2-NEXT:    retq
 ;
 ; SSE41-LABEL: trunc_unsigned_v4f32:
@@ -127,23 +122,34 @@ define <4 x float> @trunc_unsigned_v4f32(<4 x float> %x) #0 {
 define <2 x double> @trunc_unsigned_v2f64(<2 x double> %x) #0 {
 ; SSE2-LABEL: trunc_unsigned_v2f64:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    movapd {{.*#+}} xmm1 = [NaN,NaN]
-; SSE2-NEXT:    movapd %xmm0, %xmm2
-; SSE2-NEXT:    andpd %xmm1, %xmm2
-; SSE2-NEXT:    cvttsd2si %xmm2, %rax
-; SSE2-NEXT:    cvtsi2sd %rax, %xmm3
-; SSE2-NEXT:    pshufd {{.*#+}} xmm4 = xmm2[2,3,2,3]
-; SSE2-NEXT:    cvttsd2si %xmm4, %rax
-; SSE2-NEXT:    xorps %xmm4, %xmm4
-; SSE2-NEXT:    cvtsi2sd %rax, %xmm4
-; SSE2-NEXT:    unpcklpd {{.*#+}} xmm3 = xmm3[0],xmm4[0]
-; SSE2-NEXT:    andpd %xmm1, %xmm3
-; SSE2-NEXT:    andnpd %xmm0, %xmm1
-; SSE2-NEXT:    orpd %xmm3, %xmm1
-; SSE2-NEXT:    cmpnltpd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
-; SSE2-NEXT:    andpd %xmm2, %xmm0
-; SSE2-NEXT:    andnpd %xmm1, %xmm2
-; SSE2-NEXT:    orpd %xmm2, %xmm0
+; SSE2-NEXT:    movsd {{.*#+}} xmm2 = [9.2233720368547758E+18,0.0E+0]
+; SSE2-NEXT:    movapd %xmm0, %xmm1
+; SSE2-NEXT:    subsd %xmm2, %xmm1
+; SSE2-NEXT:    cvttsd2si %xmm1, %rax
+; SSE2-NEXT:    cvttsd2si %xmm0, %rcx
+; SSE2-NEXT:    movq %rcx, %rdx
+; SSE2-NEXT:    sarq $63, %rdx
+; SSE2-NEXT:    andq %rax, %rdx
+; SSE2-NEXT:    orq %rcx, %rdx
+; SSE2-NEXT:    movq %rdx, %xmm1
+; SSE2-NEXT:    unpckhpd {{.*#+}} xmm0 = xmm0[1,1]
+; SSE2-NEXT:    cvttsd2si %xmm0, %rax
+; SSE2-NEXT:    subsd %xmm2, %xmm0
+; SSE2-NEXT:    cvttsd2si %xmm0, %rcx
+; SSE2-NEXT:    movq %rax, %rdx
+; SSE2-NEXT:    sarq $63, %rdx
+; SSE2-NEXT:    andq %rcx, %rdx
+; SSE2-NEXT:    orq %rax, %rdx
+; SSE2-NEXT:    movq %rdx, %xmm0
+; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm0[0]
+; SSE2-NEXT:    movdqa {{.*#+}} xmm0 = [4294967295,4294967295]
+; SSE2-NEXT:    pand %xmm1, %xmm0
+; SSE2-NEXT:    por {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; SSE2-NEXT:    psrlq $32, %xmm1
+; SSE2-NEXT:    por {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
+; SSE2-NEXT:    subpd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
+; SSE2-NEXT:    addpd %xmm0, %xmm1
+; SSE2-NEXT:    movapd %xmm1, %xmm0
 ; SSE2-NEXT:    retq
 ;
 ; SSE41-LABEL: trunc_unsigned_v2f64:
@@ -163,42 +169,63 @@ define <2 x double> @trunc_unsigned_v2f64(<2 x double> %x) #0 {
 define <4 x double> @trunc_unsigned_v4f64(<4 x double> %x) #0 {
 ; SSE2-LABEL: trunc_unsigned_v4f64:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    movapd {{.*#+}} xmm2 = [NaN,NaN]
-; SSE2-NEXT:    movapd %xmm0, %xmm3
-; SSE2-NEXT:    andpd %xmm2, %xmm3
-; SSE2-NEXT:    cvttsd2si %xmm3, %rax
-; SSE2-NEXT:    cvtsi2sd %rax, %xmm4
-; SSE2-NEXT:    pshufd {{.*#+}} xmm5 = xmm3[2,3,2,3]
-; SSE2-NEXT:    cvttsd2si %xmm5, %rax
-; SSE2-NEXT:    xorps %xmm5, %xmm5
-; SSE2-NEXT:    cvtsi2sd %rax, %xmm5
-; SSE2-NEXT:    unpcklpd {{.*#+}} xmm4 = xmm4[0],xmm5[0]
-; SSE2-NEXT:    andpd %xmm2, %xmm4
-; SSE2-NEXT:    movapd %xmm2, %xmm5
-; SSE2-NEXT:    andnpd %xmm0, %xmm5
-; SSE2-NEXT:    orpd %xmm4, %xmm5
-; SSE2-NEXT:    movapd {{.*#+}} xmm4 = [9.2233720368547758E+18,9.2233720368547758E+18]
-; SSE2-NEXT:    cmpnltpd %xmm4, %xmm3
-; SSE2-NEXT:    andpd %xmm3, %xmm0
-; SSE2-NEXT:    andnpd %xmm5, %xmm3
-; SSE2-NEXT:    orpd %xmm3, %xmm0
-; SSE2-NEXT:    movapd %xmm1, %xmm3
-; SSE2-NEXT:    andpd %xmm2, %xmm3
-; SSE2-NEXT:    cvttsd2si %xmm3, %rax
-; SSE2-NEXT:    xorps %xmm5, %xmm5
-; SSE2-NEXT:    cvtsi2sd %rax, %xmm5
-; SSE2-NEXT:    pshufd {{.*#+}} xmm6 = xmm3[2,3,2,3]
-; SSE2-NEXT:    cvttsd2si %xmm6, %rax
-; SSE2-NEXT:    xorps %xmm6, %xmm6
-; SSE2-NEXT:    cvtsi2sd %rax, %xmm6
-; SSE2-NEXT:    unpcklpd {{.*#+}} xmm5 = xmm5[0],xmm6[0]
-; SSE2-NEXT:    andpd %xmm2, %xmm5
-; SSE2-NEXT:    andnpd %xmm1, %xmm2
-; SSE2-NEXT:    orpd %xmm5, %xmm2
-; SSE2-NEXT:    cmpnltpd %xmm4, %xmm3
-; SSE2-NEXT:    andpd %xmm3, %xmm1
-; SSE2-NEXT:    andnpd %xmm2, %xmm3
-; SSE2-NEXT:    orpd %xmm3, %xmm1
+; SSE2-NEXT:    movapd %xmm1, %xmm2
+; SSE2-NEXT:    movsd {{.*#+}} xmm3 = [9.2233720368547758E+18,0.0E+0]
+; SSE2-NEXT:    subsd %xmm3, %xmm1
+; SSE2-NEXT:    cvttsd2si %xmm1, %rax
+; SSE2-NEXT:    cvttsd2si %xmm2, %rcx
+; SSE2-NEXT:    movq %rcx, %rdx
+; SSE2-NEXT:    sarq $63, %rdx
+; SSE2-NEXT:    andq %rax, %rdx
+; SSE2-NEXT:    orq %rcx, %rdx
+; SSE2-NEXT:    movq %rdx, %xmm1
+; SSE2-NEXT:    unpckhpd {{.*#+}} xmm2 = xmm2[1,1]
+; SSE2-NEXT:    cvttsd2si %xmm2, %rax
+; SSE2-NEXT:    subsd %xmm3, %xmm2
+; SSE2-NEXT:    cvttsd2si %xmm2, %rcx
+; SSE2-NEXT:    movq %rax, %rdx
+; SSE2-NEXT:    sarq $63, %rdx
+; SSE2-NEXT:    andq %rcx, %rdx
+; SSE2-NEXT:    orq %rax, %rdx
+; SSE2-NEXT:    movq %rdx, %xmm2
+; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm2[0]
+; SSE2-NEXT:    movapd %xmm0, %xmm2
+; SSE2-NEXT:    subsd %xmm3, %xmm2
+; SSE2-NEXT:    cvttsd2si %xmm2, %rax
+; SSE2-NEXT:    cvttsd2si %xmm0, %rcx
+; SSE2-NEXT:    movq %rcx, %rdx
+; SSE2-NEXT:    sarq $63, %rdx
+; SSE2-NEXT:    andq %rax, %rdx
+; SSE2-NEXT:    orq %rcx, %rdx
+; SSE2-NEXT:    movq %rdx, %xmm2
+; SSE2-NEXT:    unpckhpd {{.*#+}} xmm0 = xmm0[1,1]
+; SSE2-NEXT:    cvttsd2si %xmm0, %rax
+; SSE2-NEXT:    subsd %xmm3, %xmm0
+; SSE2-NEXT:    cvttsd2si %xmm0, %rcx
+; SSE2-NEXT:    movq %rax, %rdx
+; SSE2-NEXT:    sarq $63, %rdx
+; SSE2-NEXT:    andq %rcx, %rdx
+; SSE2-NEXT:    orq %rax, %rdx
+; SSE2-NEXT:    movq %rdx, %xmm0
+; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm0[0]
+; SSE2-NEXT:    movdqa {{.*#+}} xmm0 = [4294967295,4294967295]
+; SSE2-NEXT:    movdqa %xmm2, %xmm3
+; SSE2-NEXT:    pand %xmm0, %xmm3
+; SSE2-NEXT:    movdqa {{.*#+}} xmm4 = [4841369599423283200,4841369599423283200]
+; SSE2-NEXT:    por %xmm4, %xmm3
+; SSE2-NEXT:    psrlq $32, %xmm2
+; SSE2-NEXT:    movdqa {{.*#+}} xmm5 = [4985484787499139072,4985484787499139072]
+; SSE2-NEXT:    por %xmm5, %xmm2
+; SSE2-NEXT:    movapd {{.*#+}} xmm6 = [1.9342813118337666E+25,1.9342813118337666E+25]
+; SSE2-NEXT:    subpd %xmm6, %xmm2
+; SSE2-NEXT:    addpd %xmm3, %xmm2
+; SSE2-NEXT:    pand %xmm1, %xmm0
+; SSE2-NEXT:    por %xmm4, %xmm0
+; SSE2-NEXT:    psrlq $32, %xmm1
+; SSE2-NEXT:    por %xmm5, %xmm1
+; SSE2-NEXT:    subpd %xmm6, %xmm1
+; SSE2-NEXT:    addpd %xmm0, %xmm1
+; SSE2-NEXT:    movapd %xmm2, %xmm0
 ; SSE2-NEXT:    retq
 ;
 ; SSE41-LABEL: trunc_unsigned_v4f64:
@@ -249,18 +276,8 @@ define float @trunc_signed_f32_no_fast_math(float %x) nounwind {
 define float @trunc_signed_f32_nsz(float %x) #0 {
 ; SSE2-LABEL: trunc_signed_f32_nsz:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    movaps {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
-; SSE2-NEXT:    movaps %xmm0, %xmm2
-; SSE2-NEXT:    andps %xmm1, %xmm2
-; SSE2-NEXT:    cvttps2dq %xmm2, %xmm3
-; SSE2-NEXT:    cvtdq2ps %xmm3, %xmm3
-; SSE2-NEXT:    andps %xmm1, %xmm3
-; SSE2-NEXT:    andnps %xmm0, %xmm1
-; SSE2-NEXT:    orps %xmm1, %xmm3
-; SSE2-NEXT:    cmpnltss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
-; SSE2-NEXT:    andps %xmm2, %xmm0
-; SSE2-NEXT:    andnps %xmm3, %xmm2
-; SSE2-NEXT:    orps %xmm2, %xmm0
+; SSE2-NEXT:    cvttps2dq %xmm0, %xmm0
+; SSE2-NEXT:    cvtdq2ps %xmm0, %xmm0
 ; SSE2-NEXT:    retq
 ;
 ; SSE41-LABEL: trunc_signed_f32_nsz:
@@ -322,18 +339,8 @@ define double @trunc_signed32_f64_no_fast_math(double %x) nounwind {
 define double @trunc_signed32_f64_nsz(double %x) #0 {
 ; SSE2-LABEL: trunc_signed32_f64_nsz:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    movapd {{.*#+}} xmm1 = [NaN,NaN]
-; SSE2-NEXT:    movapd %xmm0, %xmm2
-; SSE2-NEXT:    andpd %xmm1, %xmm2
-; SSE2-NEXT:    cvttsd2si %xmm2, %rax
-; SSE2-NEXT:    cvtsi2sd %rax, %xmm3
-; SSE2-NEXT:    andpd %xmm1, %xmm3
-; SSE2-NEXT:    andnpd %xmm0, %xmm1
-; SSE2-NEXT:    orpd %xmm1, %xmm3
-; SSE2-NEXT:    cmpnltsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
-; SSE2-NEXT:    andpd %xmm2, %xmm0
-; SSE2-NEXT:    andnpd %xmm3, %xmm2
-; SSE2-NEXT:    orpd %xmm2, %xmm0
+; SSE2-NEXT:    cvttpd2dq %xmm0, %xmm0
+; SSE2-NEXT:    cvtdq2pd %xmm0, %xmm0
 ; SSE2-NEXT:    retq
 ;
 ; SSE41-LABEL: trunc_signed32_f64_nsz:
@@ -524,18 +531,9 @@ define double @trunc_signed_f64_no_fast_math(double %x) nounwind {
 define double @trunc_signed_f64_nsz(double %x) #0 {
 ; SSE2-LABEL: trunc_signed_f64_nsz:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    movapd {{.*#+}} xmm1 = [NaN,NaN]
-; SSE2-NEXT:    movapd %xmm0, %xmm2
-; SSE2-NEXT:    andpd %xmm1, %xmm2
-; SSE2-NEXT:    cvttsd2si %xmm2, %rax
-; SSE2-NEXT:    cvtsi2sd %rax, %xmm3
-; SSE2-NEXT:    andpd %xmm1, %xmm3
-; SSE2-NEXT:    andnpd %xmm0, %xmm1
-; SSE2-NEXT:    orpd %xmm1, %xmm3
-; SSE2-NEXT:    cmpnltsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
-; SSE2-NEXT:    andpd %xmm2, %xmm0
-; SSE2-NEXT:    andnpd %xmm3, %xmm2
-; SSE2-NEXT:    orpd %xmm2, %xmm0
+; SSE2-NEXT:    cvttsd2si %xmm0, %rax
+; SSE2-NEXT:    xorps %xmm0, %xmm0
+; SSE2-NEXT:    cvtsi2sd %rax, %xmm0
 ; SSE2-NEXT:    retq
 ;
 ; SSE41-LABEL: trunc_signed_f64_nsz:
@@ -569,18 +567,8 @@ define double @trunc_signed_f64_nsz(double %x) #0 {
 define <4 x float> @trunc_signed_v4f32_nsz(<4 x float> %x) #0 {
 ; SSE2-LABEL: trunc_signed_v4f32_nsz:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    movaps {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
-; SSE2-NEXT:    movaps %xmm0, %xmm2
-; SSE2-NEXT:    andps %xmm1, %xmm2
-; SSE2-NEXT:    cvttps2dq %xmm2, %xmm3
-; SSE2-NEXT:    cvtdq2ps %xmm3, %xmm3
-; SSE2-NEXT:    andps %xmm1, %xmm3
-; SSE2-NEXT:    andnps %xmm0, %xmm1
-; SSE2-NEXT:    orps %xmm1, %xmm3
-; SSE2-NEXT:    cmpnltps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
-; SSE2-NEXT:    andps %xmm2, %xmm0
-; SSE2-NEXT:    andnps %xmm3, %xmm2
-; SSE2-NEXT:    orps %xmm2, %xmm0
+; SSE2-NEXT:    cvttps2dq %xmm0, %xmm0
+; SSE2-NEXT:    cvtdq2ps %xmm0, %xmm0
 ; SSE2-NEXT:    retq
 ;
 ; SSE41-LABEL: trunc_signed_v4f32_nsz:
@@ -600,23 +588,13 @@ define <4 x float> @trunc_signed_v4f32_nsz(<4 x float> %x) #0 {
 define <2 x double> @trunc_signed_v2f64_nsz(<2 x double> %x) #0 {
 ; SSE2-LABEL: trunc_signed_v2f64_nsz:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    movapd {{.*#+}} xmm1 = [NaN,NaN]
-; SSE2-NEXT:    movapd %xmm0, %xmm2
-; SSE2-NEXT:    andpd %xmm1, %xmm2
-; SSE2-NEXT:    cvttsd2si %xmm2, %rax
-; SSE2-NEXT:    cvtsi2sd %rax, %xmm3
-; SSE2-NEXT:    pshufd {{.*#+}} xmm4 = xmm2[2,3,2,3]
-; SSE2-NEXT:    cvttsd2si %xmm4, %rax
-; SSE2-NEXT:    xorps %xmm4, %xmm4
-; SSE2-NEXT:    cvtsi2sd %rax, %xmm4
-; SSE2-NEXT:    unpcklpd {{.*#+}} xmm3 = xmm3[0],xmm4[0]
-; SSE2-NEXT:    andpd %xmm1, %xmm3
-; SSE2-NEXT:    andnpd %xmm0, %xmm1
-; SSE2-NEXT:    orpd %xmm3, %xmm1
-; SSE2-NEXT:    cmpnltpd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
-; SSE2-NEXT:    andpd %xmm2, %xmm0
-; SSE2-NEXT:    andnpd %xmm1, %xmm2
-; SSE2-NEXT:    orpd %xmm2, %xmm0
+; SSE2-NEXT:    cvttsd2si %xmm0, %rax
+; SSE2-NEXT:    unpckhpd {{.*#+}} xmm0 = xmm0[1,1]
+; SSE2-NEXT:    cvttsd2si %xmm0, %rcx
+; SSE2-NEXT:    xorps %xmm0, %xmm0
+; SSE2-NEXT:    cvtsi2sd %rax, %xmm0
+; SSE2-NEXT:    cvtsi2sd %rcx, %xmm1
+; SSE2-NEXT:    unpcklpd {{.*#+}} xmm0 = xmm0[0],xmm1[0]
 ; SSE2-NEXT:    retq
 ;
 ; SSE41-LABEL: trunc_signed_v2f64_nsz:
@@ -636,42 +614,21 @@ define <2 x double> @trunc_signed_v2f64_nsz(<2 x double> %x) #0 {
 define <4 x double> @trunc_signed_v4f64_nsz(<4 x double> %x) #0 {
 ; SSE2-LABEL: trunc_signed_v4f64_nsz:
 ; SSE2:       # %bb.0:
-; SSE2-NEXT:    movapd {{.*#+}} xmm2 = [NaN,NaN]
-; SSE2-NEXT:    movapd %xmm0, %xmm3
-; SSE2-NEXT:    andpd %xmm2, %xmm3
-; SSE2-NEXT:    cvttsd2si %xmm3, %rax
-; SSE2-NEXT:    cvtsi2sd %rax, %xmm4
-; SSE2-NEXT:    pshufd {{.*#+}} xmm5 = xmm3[2,3,2,3]
-; SSE2-NEXT:    cvttsd2si %xmm5, %rax
-; SSE2-NEXT:    xorps %xmm5, %xmm5
-; SSE2-NEXT:    cvtsi2sd %rax, %xmm5
-; SSE2-NEXT:    unpcklpd {{.*#+}} xmm4 = xmm4[0],xmm5[0]
-; SSE2-NEXT:    andpd %xmm2, %xmm4
-; SSE2-NEXT:    movapd %xmm2, %xmm5
-; SSE2-NEXT:    andnpd %xmm0, %xmm5
-; SSE2-NEXT:    orpd %xmm4, %xmm5
-; SSE2-NEXT:    movapd {{.*#+}} xmm4 = [9.2233720368547758E+18,9.2233720368547758E+18]
-; SSE2-NEXT:    cmpnltpd %xmm4, %xmm3
-; SSE2-NEXT:    andpd %xmm3, %xmm0
-; SSE2-NEXT:    andnpd %xmm5, %xmm3
-; SSE2-NEXT:    orpd %xmm3, %xmm0
-; SSE2-NEXT:    movapd %xmm1, %xmm3
-; SSE2-NEXT:    andpd %xmm2, %xmm3
-; SSE2-NEXT:    cvttsd2si %xmm3, %rax
-; SSE2-NEXT:    xorps %xmm5, %xmm5
-; SSE2-NEXT:    cvtsi2sd %rax, %xmm5
-; SSE2-NEXT:    pshufd {{.*#+}} xmm6 = xmm3[2,3,2,3]
-; SSE2-NEXT:    cvttsd2si %xmm6, %rax
-; SSE2-NEXT:    xorps %xmm6, %xmm6
-; SSE2-NEXT:    cvtsi2sd %rax, %xmm6
-; SSE2-NEXT:    unpcklpd {{.*#+}} xmm5 = xmm5[0],xmm6[0]
-; SSE2-NEXT:    andpd %xmm2, %xmm5
-; SSE2-NEXT:    andnpd %xmm1, %xmm2
-; SSE2-NEXT:    orpd %xmm5, %xmm2
-; SSE2-NEXT:    cmpnltpd %xmm4, %xmm3
-; SSE2-NEXT:    andpd %xmm3, %xmm1
-; SSE2-NEXT:    andnpd %xmm2, %xmm3
-; SSE2-NEXT:    orpd %xmm3, %xmm1
+; SSE2-NEXT:    cvttsd2si %xmm1, %rax
+; SSE2-NEXT:    unpckhpd {{.*#+}} xmm1 = xmm1[1,1]
+; SSE2-NEXT:    cvttsd2si %xmm1, %rcx
+; SSE2-NEXT:    cvttsd2si %xmm0, %rdx
+; SSE2-NEXT:    unpckhpd {{.*#+}} xmm0 = xmm0[1,1]
+; SSE2-NEXT:    cvttsd2si %xmm0, %rsi
+; SSE2-NEXT:    xorps %xmm0, %xmm0
+; SSE2-NEXT:    cvtsi2sd %rdx, %xmm0
+; SSE2-NEXT:    xorps %xmm1, %xmm1
+; SSE2-NEXT:    cvtsi2sd %rsi, %xmm1
+; SSE2-NEXT:    unpcklpd {{.*#+}} xmm0 = xmm0[0],xmm1[0]
+; SSE2-NEXT:    xorps %xmm1, %xmm1
+; SSE2-NEXT:    cvtsi2sd %rax, %xmm1
+; SSE2-NEXT:    cvtsi2sd %rcx, %xmm2
+; SSE2-NEXT:    unpcklpd {{.*#+}} xmm1 = xmm1[0],xmm2[0]
 ; SSE2-NEXT:    retq
 ;
 ; SSE41-LABEL: trunc_signed_v4f64_nsz:
diff --git a/llvm/test/CodeGen/X86/isint.ll b/llvm/test/CodeGen/X86/isint.ll
index eb05cf78cd36b..778cfdf9e8351 100644
--- a/llvm/test/CodeGen/X86/isint.ll
+++ b/llvm/test/CodeGen/X86/isint.ll
@@ -20,21 +20,10 @@ define i32 @isint_return(double %d) nounwind {
 ;
 ; X64-SSE2-LABEL: isint_return:
 ; X64-SSE2:       # %bb.0:
-; X64-SSE2-NEXT:    movapd {{.*#+}} xmm1 = [NaN,NaN]
-; X64-SSE2-NEXT:    movapd %xmm0, %xmm2
-; X64-SSE2-NEXT:    andpd %xmm1, %xmm2
-; X64-SSE2-NEXT:    cvttsd2si %xmm2, %rax
-; X64-SSE2-NEXT:    cvtsi2sd %rax, %xmm3
-; X64-SSE2-NEXT:    andpd %xmm1, %xmm3
-; X64-SSE2-NEXT:    andnpd %xmm0, %xmm1
-; X64-SSE2-NEXT:    orpd %xmm1, %xmm3
-; X64-SSE2-NEXT:    cmpnltsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
-; X64-SSE2-NEXT:    movapd %xmm2, %xmm1
-; X64-SSE2-NEXT:    andnpd %xmm3, %xmm1
-; X64-SSE2-NEXT:    andpd %xmm0, %xmm2
-; X64-SSE2-NEXT:    orpd %xmm1, %xmm2
-; X64-SSE2-NEXT:    cmpeqsd %xmm0, %xmm2
-; X64-SSE2-NEXT:    movq %xmm2, %rax
+; X64-SSE2-NEXT:    cvttpd2dq %xmm0, %xmm1
+; X64-SSE2-NEXT:    cvtdq2pd %xmm1, %xmm1
+; X64-SSE2-NEXT:    cmpeqsd %xmm0, %xmm1
+; X64-SSE2-NEXT:    movq %xmm1, %rax
 ; X64-SSE2-NEXT:    andl $1, %eax
 ; X64-SSE2-NEXT:    # kill: def $eax killed $eax killed $rax
 ; X64-SSE2-NEXT:    retq
@@ -74,19 +63,8 @@ define i32 @isint_float_return(float %f) nounwind {
 ; X86-LABEL: isint_float_return:
 ; X86:       # %bb.0:
 ; X86-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
-; X86-NEXT:    movaps {{.*#+}} xmm2 = [NaN,NaN,NaN,NaN]
-; X86-NEXT:    movaps %xmm0, %xmm1
-; X86-NEXT:    andps %xmm2, %xmm1
-; X86-NEXT:    cvttps2dq %xmm1, %xmm3
-; X86-NEXT:    cvtdq2ps %xmm3, %xmm3
-; X86-NEXT:    andps %xmm2, %xmm3
-; X86-NEXT:    andnps %xmm0, %xmm2
-; X86-NEXT:    orps %xmm2, %xmm3
-; X86-NEXT:    cmpnltss {{\.?LCPI[0-9]+_[0-9]+}}, %xmm1
-; X86-NEXT:    movaps %xmm1, %xmm2
-; X86-NEXT:    andnps %xmm3, %xmm2
-; X86-NEXT:    andps %xmm0, %xmm1
-; X86-NEXT:    orps %xmm2, %xmm1
+; X86-NEXT:    cvttps2dq %xmm0, %xmm1
+; X86-NEXT:    cvtdq2ps %xmm1, %xmm1
 ; X86-NEXT:    cmpeqss %xmm0, %xmm1
 ; X86-NEXT:    movd %xmm1, %eax
 ; X86-NEXT:    andl $1, %eax
@@ -94,21 +72,10 @@ define i32 @isint_float_return(float %f) nounwind {
 ;
 ; X64-SSE2-LABEL: isint_float_return:
 ; X64-SSE2:       # %bb.0:
-; X64-SSE2-NEXT:    movaps {{.*#+}} xmm1 = [NaN,NaN,NaN,NaN]
-; X64-SSE2-NEXT:    movaps %xmm0, %xmm2
-; X64-SSE2-NEXT:    andps %xmm1, %xmm2
-; X64-SSE2-NEXT:    cvttps2dq %xmm2, %xmm3
-; X64-SSE2-NEXT:    cvtdq2ps %xmm3, %xmm3
-; X64-SSE2-NEXT:    andps %xmm1, %xmm3
-; X64-SSE2-NEXT:    andnps %xmm0, %xmm1
-; X64-SSE2-NEXT:    orps %xmm1, %xmm3
-; X64-SSE2-NEXT:    cmpnltss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
-; X64-SSE2-NEXT:    movaps %xmm2, %xmm1
-; X64-SSE2-NEXT:    andnps %xmm3, %xmm1
-; X64-SSE2-NEXT:    andps %xmm0, %xmm2
-; X64-SSE2-NEXT:    orps %xmm1, %xmm2
-; X64-SSE2-NEXT:    cmpeqss %xmm0, %xmm2
-; X64-SSE2-NEXT:    movd %xmm2, %eax
+; X64-SSE2-NEXT:    cvttps2dq %xmm0, %xmm1
+; X64-SSE2-NEXT:    cvtdq2ps %xmm1, %xmm1
+; X64-SSE2-NEXT:    cmpeqss %xmm0, %xmm1
+; X64-SSE2-NEXT:    movd %xmm1, %eax
 ; X64-SSE2-NEXT:    andl $1, %eax
 ; X64-SSE2-NEXT:    retq
 ;
@@ -159,20 +126,9 @@ define void @isint_branch(double %d) nounwind {
 ;
 ; X64-SSE2-LABEL: isint_branch:
 ; X64-SSE2:       # %bb.0:
-; X64-SSE2-NEXT:    movapd {{.*#+}} xmm1 = [NaN,NaN]
-; X64-SSE2-NEXT:    movapd %xmm0, %xmm2
-; X64-SSE2-NEXT:    andpd %xmm1, %xmm2
-; X64-SSE2-NEXT:    cvttsd2si %xmm2, %rax
-; X64-SSE2-NEXT:    cvtsi2sd %rax, %xmm3
-; X64-SSE2-NEXT:    andpd %xmm1, %xmm3
-; X64-SSE2-NEXT:    andnpd %xmm0, %xmm1
-; X64-SSE2-NEXT:    orpd %xmm1, %xmm3
-; X64-SSE2-NEXT:    cmpnltsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2
-; X64-SSE2-NEXT:    movapd %xmm2, %xmm1
-; X64-SSE2-NEXT:    andnpd %xmm3, %xmm1
-; X64-SSE2-NEXT:    andpd %xmm0, %xmm2
-; X64-SSE2-NEXT:    orpd %xmm1, %xmm2
-; X64-SSE2-NEXT:    ucomisd %xmm2, %xmm0
+; X64-SSE2-NEXT:    cvttpd2dq %xmm0, %xmm1
+; X64-SSE2-NEXT:    cvtdq2pd %xmm1, %xmm1
+; X64-SSE2-NEXT:    ucomisd %xmm1, %xmm0
 ; X64-SSE2-NEXT:    jne .LBB2_2
 ; X64-SSE2-NEXT:    jp .LBB2_2
 ; X64-SSE2-NEXT:  # %bb.1: # %true
diff --git a/llvm/test/CodeGen/X86/unpredictable-brcond.ll b/llvm/test/CodeGen/X86/unpredictable-brcond.ll
index e93114a90242e..bb44171d20d65 100644
--- a/llvm/test/CodeGen/X86/unpredictable-brcond.ll
+++ b/llvm/test/CodeGen/X86/unpredictable-brcond.ll
@@ -85,22 +85,10 @@ define void @isint_branch(double %d) nounwind {
   ; CHECK-NEXT: {{  $}}
   ; CHECK-NEXT:   [[COPY:%[0-9]+]]:fr64 = COPY $xmm0
   ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:vr128 = COPY [[COPY]]
-  ; CHECK-NEXT:   [[MOVAPDrm:%[0-9]+]]:vr128 = MOVAPDrm $rip, 1, $noreg, %const.0, $noreg :: (load (s128) from constant-pool)
-  ; CHECK-NEXT:   [[PANDNrr:%[0-9]+]]:vr128 = PANDNrr [[MOVAPDrm]], [[COPY1]]
-  ; CHECK-NEXT:   [[PANDrr:%[0-9]+]]:vr128 = PANDrr [[COPY1]], [[MOVAPDrm]]
-  ; CHECK-NEXT:   [[COPY2:%[0-9]+]]:fr64 = COPY killed [[PANDrr]]
-  ; CHECK-NEXT:   [[CVTTSD2SI64rr:%[0-9]+]]:gr64 = nofpexcept CVTTSD2SI64rr [[COPY2]], implicit $mxcsr
-  ; CHECK-NEXT:   [[CVTSI642SDrr:%[0-9]+]]:fr64 = nofpexcept CVTSI642SDrr killed [[CVTTSD2SI64rr]], implicit $mxcsr
-  ; CHECK-NEXT:   [[COPY3:%[0-9]+]]:vr128 = COPY killed [[CVTSI642SDrr]]
-  ; CHECK-NEXT:   [[PANDrr1:%[0-9]+]]:vr128 = PANDrr [[COPY3]], [[MOVAPDrm]]
-  ; CHECK-NEXT:   [[PORrr:%[0-9]+]]:vr128 = PORrr [[PANDrr1]], killed [[PANDNrr]]
-  ; CHECK-NEXT:   [[CMPSDrmi:%[0-9]+]]:fr64 = nofpexcept CMPSDrmi [[COPY2]], $rip, 1, $noreg, %const.1, $noreg, 5, implicit $mxcsr :: (load (s64) from constant-pool)
-  ; CHECK-NEXT:   [[COPY4:%[0-9]+]]:vr128 = COPY killed [[CMPSDrmi]]
-  ; CHECK-NEXT:   [[PANDNrr1:%[0-9]+]]:vr128 = PANDNrr [[COPY4]], killed [[PORrr]]
-  ; CHECK-NEXT:   [[PANDrr2:%[0-9]+]]:vr128 = PANDrr [[COPY4]], [[COPY1]]
-  ; CHECK-NEXT:   [[PORrr1:%[0-9]+]]:vr128 = PORrr [[PANDNrr1]], killed [[PANDrr2]]
-  ; CHECK-NEXT:   [[COPY5:%[0-9]+]]:fr64 = COPY killed [[PORrr1]]
-  ; CHECK-NEXT:   nofpexcept UCOMISDrr [[COPY]], killed [[COPY5]], implicit-def $eflags, implicit $mxcsr
+  ; CHECK-NEXT:   [[CVTTPD2DQrr:%[0-9]+]]:vr128 = nofpexcept CVTTPD2DQrr killed [[COPY1]], implicit $mxcsr
+  ; CHECK-NEXT:   [[CVTDQ2PDrr:%[0-9]+]]:vr128 = CVTDQ2PDrr killed [[CVTTPD2DQrr]]
+  ; CHECK-NEXT:   [[COPY2:%[0-9]+]]:fr64 = COPY killed [[CVTDQ2PDrr]]
+  ; CHECK-NEXT:   nofpexcept UCOMISDrr [[COPY]], killed [[COPY2]], implicit-def $eflags, implicit $mxcsr
   ; CHECK-NEXT:   unpredictable JCC_1 %bb.2, 5, implicit $eflags
   ; CHECK-NEXT:   unpredictable JCC_1 %bb.2, 10, implicit $eflags
   ; CHECK-NEXT:   JMP_1 %bb.1

>From 43784597e382fba89cc4070b6c786f11a399db54 Mon Sep 17 00:00:00 2001
From: Divyansh <anshmcs at gmail.com>
Date: Mon, 28 Sep 2026 15:16:49 +0530
Subject: [PATCH 8/8] [X86] Use isTypeDesirableForOp instead of a new TLI hook
 to block the FTRUNC fold

---
 llvm/include/llvm/CodeGen/TargetLowering.h    |  8 --------
 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp |  7 ++++---
 llvm/lib/Target/X86/X86ISelLowering.cpp       | 13 ++++++-------
 llvm/lib/Target/X86/X86ISelLowering.h         |  2 --
 4 files changed, 10 insertions(+), 20 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h
index 9a4a12957ad12..283b0f811dc2f 100644
--- a/llvm/include/llvm/CodeGen/TargetLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetLowering.h
@@ -3490,14 +3490,6 @@ class LLVM_ABI TargetLoweringBase {
     return false;
   }
 
-  /// Return true if a custom lowered FTRUNC of type VT is cheap enough that it
-  /// is worthwhile to fold an fpto[us]i -> [us]itofp round trip into it. This
-  /// is only queried when FTRUNC is not legal for VT.
-  virtual bool isCustomFTruncCheap(EVT VT) const {
-    assert(VT.isFloatingPoint());
-    return true;
-  }
-
   /// Return true if an FMA operation is faster than a pair of fmul and fadd
   /// instructions. fmuladd intrinsics will be expanded to FMAs when this method
   /// returns true, otherwise fmuladd is expanded to fmul + fadd.
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index f9c4195d5a0d8..5b58a23e1764d 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -20583,8 +20583,9 @@ static SDValue foldFPToIntToFP(SDNode *N, const SDLoc &DL, SelectionDAG &DAG,
   bool IsSigned = N->getOpcode() == ISD::SINT_TO_FP;
   assert(IsSigned || IsUnsigned);
 
-  // Don't fold if the individual cast operations are already legal, or the
-  // target reports that its custom FTRUNC expansion is expensive.
+  // Don't fold if the individual cast operations are already legal or the
+  // target reports FTRUNC as undesirable, as FTRUNC may have a more expensive
+  // custom expansion.
   EVT IntVT = N->getOperand(0).getValueType();
   EVT LegalIntVT = TLI.getTypeToTransformTo(*DAG.getContext(), IntVT);
   unsigned FPToIntOp = IsUnsigned ? ISD::FP_TO_UINT : ISD::FP_TO_SINT;
@@ -20592,7 +20593,7 @@ static SDValue foldFPToIntToFP(SDNode *N, const SDLoc &DL, SelectionDAG &DAG,
   if (!TLI.isOperationLegal(ISD::FTRUNC, VT) &&
       ((TLI.isOperationLegal(FPToIntOp, LegalIntVT) &&
         TLI.isOperationLegal(IntToFPOp, VT)) ||
-       !TLI.isCustomFTruncCheap(VT)))
+       !TLI.isTypeDesirableForOp(ISD::FTRUNC, VT)))
     return SDValue();
 
   bool IsSignedZeroSafe = DAG.canIgnoreSignBitOfZero(SDValue(N, 0));
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 268864da70a85..f039039c8456f 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -3814,13 +3814,6 @@ bool X86TargetLowering::isCtlzFast() const {
   return Subtarget.hasFastLZCNT();
 }
 
-bool X86TargetLowering::isCustomFTruncCheap(EVT VT) const {
-  // Without SSE41, FTRUNC is emulated with a conversion round trip plus a
-  // range check and select, which is more expensive than a plain
-  // fpto[us]i -> [us]itofp pair.
-  return false;
-}
-
 bool X86TargetLowering::preferZeroCompareBranch() const { return true; }
 
 bool X86TargetLowering::isMaskAndCmp0FoldingBeneficial(
@@ -64272,6 +64265,12 @@ bool X86TargetLowering::isTypeDesirableForOp(unsigned Opc, EVT VT) const {
   if (Opc == ISD::SHL && VT.isVectorOf(MVT::i8))
     return false;
 
+  // Without SSE41, FTRUNC is emulated with a conversion round trip plus a range
+  // check and select, which is more expensive than a plain fpto[us]i ->
+  // [us]itofp pair.
+  if (Opc == ISD::FTRUNC && !Subtarget.hasSSE41())
+    return false;
+
   // TODO: Almost no 8-bit ops are desirable because they have no actual
   //       size/speed advantages vs. 32-bit ops, but they do have a major
   //       potential disadvantage by causing partial register stalls.
diff --git a/llvm/lib/Target/X86/X86ISelLowering.h b/llvm/lib/Target/X86/X86ISelLowering.h
index 12a45a5e1c8d9..34bb76982eecb 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.h
+++ b/llvm/lib/Target/X86/X86ISelLowering.h
@@ -238,8 +238,6 @@ namespace llvm {
 
     bool isCtlzFast() const override;
 
-    bool isCustomFTruncCheap(EVT VT) const override;
-
     bool preferZeroCompareBranch() const override;
 
     bool isMultiStoresCheaperThanBitsMerge(EVT LTy, EVT HTy) const override {



More information about the llvm-commits mailing list