[llvm] 39a0aa5 - [SelectionDAG] Lower llvm.ldexp.f32 to ldexp() on Windows. (#95301)

via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 25 10:25:52 PDT 2024


Author: Eli Friedman
Date: 2024-06-25T10:25:48-07:00
New Revision: 39a0aa5876c20ef245fc4065b9f512008fac91a6

URL: https://github.com/llvm/llvm-project/commit/39a0aa5876c20ef245fc4065b9f512008fac91a6
DIFF: https://github.com/llvm/llvm-project/commit/39a0aa5876c20ef245fc4065b9f512008fac91a6.diff

LOG: [SelectionDAG] Lower llvm.ldexp.f32 to ldexp() on Windows. (#95301)

This reduces codesize. As discussed in #92707.

Added: 
    llvm/test/CodeGen/ARM/ldexp.ll

Modified: 
    llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
    llvm/lib/Target/ARM/ARMISelLowering.cpp
    llvm/lib/Target/X86/X86ISelLowering.cpp
    llvm/test/CodeGen/AArch64/ldexp.ll
    llvm/test/CodeGen/X86/ldexp.ll
    llvm/test/CodeGen/X86/llvm.frexp.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index bf38fcc2d2c3b..8b1107f9e08af 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -1786,6 +1786,20 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
   IsStrictFPEnabled = true;
   setMaxAtomicSizeInBitsSupported(128);
 
+  // On MSVC, both 32-bit and 64-bit, ldexpf(f32) is not defined.  MinGW has
+  // it, but it's just a wrapper around ldexp.
+  if (Subtarget->isTargetWindows()) {
+    for (ISD::NodeType Op : {ISD::FLDEXP, ISD::STRICT_FLDEXP, ISD::FFREXP})
+      if (isOperationExpand(Op, MVT::f32))
+        setOperationAction(Op, MVT::f32, Promote);
+  }
+
+  // LegalizeDAG currently can't expand fp16 LDEXP/FREXP on targets where i16
+  // isn't legal.
+  for (ISD::NodeType Op : {ISD::FLDEXP, ISD::STRICT_FLDEXP, ISD::FFREXP})
+    if (isOperationExpand(Op, MVT::f16))
+      setOperationAction(Op, MVT::f16, Promote);
+
   if (Subtarget->isWindowsArm64EC()) {
     // FIXME: are there intrinsics we need to exclude from this?
     for (int i = 0; i < RTLIB::UNKNOWN_LIBCALL; ++i) {

diff  --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index 5490c3c9df6c2..4a7da3bf97447 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -1594,6 +1594,20 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM,
     }
   }
 
+  // On MSVC, both 32-bit and 64-bit, ldexpf(f32) is not defined.  MinGW has
+  // it, but it's just a wrapper around ldexp.
+  if (Subtarget->isTargetWindows()) {
+    for (ISD::NodeType Op : {ISD::FLDEXP, ISD::STRICT_FLDEXP, ISD::FFREXP})
+      if (isOperationExpand(Op, MVT::f32))
+        setOperationAction(Op, MVT::f32, Promote);
+  }
+
+  // LegalizeDAG currently can't expand fp16 LDEXP/FREXP on targets where i16
+  // isn't legal.
+  for (ISD::NodeType Op : {ISD::FLDEXP, ISD::STRICT_FLDEXP, ISD::FFREXP})
+    if (isOperationExpand(Op, MVT::f16))
+      setOperationAction(Op, MVT::f16, Promote);
+
   // We have target-specific dag combine patterns for the following nodes:
   // ARMISD::VMOVRRD  - No need to call setTargetDAGCombine
   setTargetDAGCombine(

diff  --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 2a55ab3fafdd7..e75dfc3721ac6 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -2500,6 +2500,14 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
         setOperationAction(Op, MVT::f32, Promote);
   // clang-format on
 
+  // On MSVC, both 32-bit and 64-bit, ldexpf(f32) is not defined.  MinGW has
+  // it, but it's just a wrapper around ldexp.
+  if (Subtarget.isOSWindows()) {
+    for (ISD::NodeType Op : {ISD::FLDEXP, ISD::STRICT_FLDEXP, ISD::FFREXP})
+      if (isOperationExpand(Op, MVT::f32))
+        setOperationAction(Op, MVT::f32, Promote);
+  }
+
   // We have target-specific dag combine patterns for the following nodes:
   setTargetDAGCombine({ISD::VECTOR_SHUFFLE,
                        ISD::SCALAR_TO_VECTOR,

diff  --git a/llvm/test/CodeGen/AArch64/ldexp.ll b/llvm/test/CodeGen/AArch64/ldexp.ll
index ba04ba1d7bb6a..6019fa1490e3d 100644
--- a/llvm/test/CodeGen/AArch64/ldexp.ll
+++ b/llvm/test/CodeGen/AArch64/ldexp.ll
@@ -1,17 +1,23 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3
-; RUN: llc -mtriple=aarch64 -mattr=+sve < %s -o - | FileCheck %s
+; RUN: llc -mtriple=aarch64 -mattr=+sve < %s -o - | FileCheck -check-prefixes=SVE,SVELINUX %s
+; RUN: llc -mtriple=aarch64-windows-msvc -mattr=+sve < %s -o - | FileCheck -check-prefixes=SVE,SVEWINDOWS %s
+; RUN: llc -mtriple=aarch64-windows-msvc < %s -o - | FileCheck -check-prefixes=WINDOWS %s
 
 define double @testExp(double %val, i32 %a) {
-; CHECK-LABEL: testExp:
-; CHECK:       // %bb.0: // %entry
-; CHECK-NEXT:    // kill: def $w0 killed $w0 def $x0
-; CHECK-NEXT:    sxtw x8, w0
-; CHECK-NEXT:    ptrue p0.d
-; CHECK-NEXT:    // kill: def $d0 killed $d0 def $z0
-; CHECK-NEXT:    fmov d1, x8
-; CHECK-NEXT:    fscale z0.d, p0/m, z0.d, z1.d
-; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $z0
-; CHECK-NEXT:    ret
+; SVE-LABEL: testExp:
+; SVE:       // %bb.0: // %entry
+; SVE-NEXT:    // kill: def $w0 killed $w0 def $x0
+; SVE-NEXT:    sxtw x8, w0
+; SVE-NEXT:    ptrue p0.d
+; SVE-NEXT:    // kill: def $d0 killed $d0 def $z0
+; SVE-NEXT:    fmov d1, x8
+; SVE-NEXT:    fscale z0.d, p0/m, z0.d, z1.d
+; SVE-NEXT:    // kill: def $d0 killed $d0 killed $z0
+; SVE-NEXT:    ret
+;
+; WINDOWS-LABEL: testExp:
+; WINDOWS:       // %bb.0: // %entry
+; WINDOWS-NEXT:    b ldexp
 entry:
   %call = tail call fast double @ldexp(double %val, i32 %a)
   ret double %call
@@ -19,26 +25,90 @@ entry:
 
 declare double @ldexp(double, i32) memory(none)
 
+define double @testExpIntrinsic(double %val, i32 %a) {
+; SVE-LABEL: testExpIntrinsic:
+; SVE:       // %bb.0: // %entry
+; SVE-NEXT:    // kill: def $w0 killed $w0 def $x0
+; SVE-NEXT:    sxtw x8, w0
+; SVE-NEXT:    ptrue p0.d
+; SVE-NEXT:    // kill: def $d0 killed $d0 def $z0
+; SVE-NEXT:    fmov d1, x8
+; SVE-NEXT:    fscale z0.d, p0/m, z0.d, z1.d
+; SVE-NEXT:    // kill: def $d0 killed $d0 killed $z0
+; SVE-NEXT:    ret
+;
+; WINDOWS-LABEL: testExpIntrinsic:
+; WINDOWS:       // %bb.0: // %entry
+; WINDOWS-NEXT:    b ldexp
+entry:
+  %call = tail call fast double @llvm.ldexp.f64(double %val, i32 %a)
+  ret double %call
+}
+
 define float @testExpf(float %val, i32 %a) {
-; CHECK-LABEL: testExpf:
-; CHECK:       // %bb.0: // %entry
-; CHECK-NEXT:    fmov s1, w0
-; CHECK-NEXT:    ptrue p0.s
-; CHECK-NEXT:    // kill: def $s0 killed $s0 def $z0
-; CHECK-NEXT:    fscale z0.s, p0/m, z0.s, z1.s
-; CHECK-NEXT:    // kill: def $s0 killed $s0 killed $z0
-; CHECK-NEXT:    ret
+; SVELINUX-LABEL: testExpf:
+; SVELINUX:       // %bb.0: // %entry
+; SVELINUX-NEXT:    fmov s1, w0
+; SVELINUX-NEXT:    ptrue p0.s
+; SVELINUX-NEXT:    // kill: def $s0 killed $s0 def $z0
+; SVELINUX-NEXT:    fscale z0.s, p0/m, z0.s, z1.s
+; SVELINUX-NEXT:    // kill: def $s0 killed $s0 killed $z0
+; SVELINUX-NEXT:    ret
+;
+; SVEWINDOWS-LABEL: testExpf:
+; SVEWINDOWS:       // %bb.0: // %entry
+; SVEWINDOWS-NEXT:    b ldexpf
+;
+; WINDOWS-LABEL: testExpf:
+; WINDOWS:       // %bb.0: // %entry
+; WINDOWS-NEXT:    b ldexpf
 entry:
   %call = tail call fast float @ldexpf(float %val, i32 %a)
   ret float %call
 }
 
+define float @testExpfIntrinsic(float %val, i32 %a) {
+; SVE-LABEL: testExpfIntrinsic:
+; SVE:       // %bb.0: // %entry
+; SVE-NEXT:    fmov s1, w0
+; SVE-NEXT:    ptrue p0.s
+; SVE-NEXT:    // kill: def $s0 killed $s0 def $z0
+; SVE-NEXT:    fscale z0.s, p0/m, z0.s, z1.s
+; SVE-NEXT:    // kill: def $s0 killed $s0 killed $z0
+; SVE-NEXT:    ret
+;
+; WINDOWS-LABEL: testExpfIntrinsic:
+; WINDOWS:       .seh_proc testExpfIntrinsic
+; WINDOWS-NEXT:  // %bb.0: // %entry
+; WINDOWS-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
+; WINDOWS-NEXT:    .seh_save_reg_x x30, 16
+; WINDOWS-NEXT:    .seh_endprologue
+; WINDOWS-NEXT:    fcvt d0, s0
+; WINDOWS-NEXT:    bl ldexp
+; WINDOWS-NEXT:    fcvt s0, d0
+; WINDOWS-NEXT:    .seh_startepilogue
+; WINDOWS-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
+; WINDOWS-NEXT:    .seh_save_reg_x x30, 16
+; WINDOWS-NEXT:    .seh_endepilogue
+; WINDOWS-NEXT:    ret
+; WINDOWS-NEXT:    .seh_endfunclet
+; WINDOWS-NEXT:    .seh_endproc
+entry:
+  %call = tail call fast float @llvm.ldexp.f32(float %val, i32 %a)
+  ret float %call
+}
+
+
 declare float @ldexpf(float, i32) memory(none)
 
 define fp128 @testExpl(fp128 %val, i32 %a) {
-; CHECK-LABEL: testExpl:
-; CHECK:       // %bb.0: // %entry
-; CHECK-NEXT:    b ldexpl
+; SVE-LABEL: testExpl:
+; SVE:       // %bb.0: // %entry
+; SVE-NEXT:    b ldexpl
+;
+; WINDOWS-LABEL: testExpl:
+; WINDOWS:       // %bb.0: // %entry
+; WINDOWS-NEXT:    b ldexpl
 entry:
   %call = tail call fast fp128 @ldexpl(fp128 %val, i32 %a)
   ret fp128 %call
@@ -47,14 +117,31 @@ entry:
 declare fp128 @ldexpl(fp128, i32) memory(none)
 
 define half @testExpf16(half %val, i32 %a) {
-; CHECK-LABEL: testExpf16:
-; CHECK:       // %bb.0: // %entry
-; CHECK-NEXT:    fcvt s0, h0
-; CHECK-NEXT:    fmov s1, w0
-; CHECK-NEXT:    ptrue p0.s
-; CHECK-NEXT:    fscale z0.s, p0/m, z0.s, z1.s
-; CHECK-NEXT:    fcvt h0, s0
-; CHECK-NEXT:    ret
+; SVE-LABEL: testExpf16:
+; SVE:       // %bb.0: // %entry
+; SVE-NEXT:    fcvt s0, h0
+; SVE-NEXT:    fmov s1, w0
+; SVE-NEXT:    ptrue p0.s
+; SVE-NEXT:    fscale z0.s, p0/m, z0.s, z1.s
+; SVE-NEXT:    fcvt h0, s0
+; SVE-NEXT:    ret
+;
+; WINDOWS-LABEL: testExpf16:
+; WINDOWS:       .seh_proc testExpf16
+; WINDOWS-NEXT:  // %bb.0: // %entry
+; WINDOWS-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
+; WINDOWS-NEXT:    .seh_save_reg_x x30, 16
+; WINDOWS-NEXT:    .seh_endprologue
+; WINDOWS-NEXT:    fcvt d0, h0
+; WINDOWS-NEXT:    bl ldexp
+; WINDOWS-NEXT:    fcvt h0, d0
+; WINDOWS-NEXT:    .seh_startepilogue
+; WINDOWS-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
+; WINDOWS-NEXT:    .seh_save_reg_x x30, 16
+; WINDOWS-NEXT:    .seh_endepilogue
+; WINDOWS-NEXT:    ret
+; WINDOWS-NEXT:    .seh_endfunclet
+; WINDOWS-NEXT:    .seh_endproc
 entry:
   %0 = tail call fast half @llvm.ldexp.f16.i32(half %val, i32 %a)
   ret half %0

diff  --git a/llvm/test/CodeGen/ARM/ldexp.ll b/llvm/test/CodeGen/ARM/ldexp.ll
new file mode 100644
index 0000000000000..941390ee94c1e
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/ldexp.ll
@@ -0,0 +1,58 @@
+; RUN: llc -mtriple=armv7-linux < %s -o - | FileCheck -check-prefix=LINUX %s
+; RUN: llc -mtriple=thumbv7-windows-msvc -mattr=+thumb-mode < %s -o - | FileCheck -check-prefix=WINDOWS %s
+
+define double @testExp(double %val, i32 %a) {
+; LINUX:    b ldexp{{$}}
+; WINDOWS:  b.w ldexp{{$}}
+entry:
+  %call = tail call fast double @ldexp(double %val, i32 %a)
+  ret double %call
+}
+
+declare double @ldexp(double, i32) memory(none)
+
+define double @testExpIntrinsic(double %val, i32 %a) {
+; LINUX:    b ldexp{{$}}
+; WINDOWS:  b.w ldexp{{$}}
+entry:
+  %call = tail call fast double @llvm.ldexp.f64(double %val, i32 %a)
+  ret double %call
+}
+
+define float @testExpf(float %val, i32 %a) {
+; LINUX:    b ldexpf
+; WINDOWS:  b.w ldexpf
+entry:
+  %call = tail call fast float @ldexpf(float %val, i32 %a)
+  ret float %call
+}
+
+define float @testExpfIntrinsic(float %val, i32 %a) {
+; LINUX:    b ldexpf
+; WINDOWS:  bl ldexp{{$}}
+entry:
+  %call = tail call fast float @llvm.ldexp.f32(float %val, i32 %a)
+  ret float %call
+}
+
+declare float @ldexpf(float, i32) memory(none)
+
+define fp128 @testExpl(fp128 %val, i32 %a) {
+; LINUX:    bl ldexpl
+; WINDOWS:    b.w ldexpl
+entry:
+  %call = tail call fast fp128 @ldexpl(fp128 %val, i32 %a)
+  ret fp128 %call
+}
+
+declare fp128 @ldexpl(fp128, i32) memory(none)
+
+define half @testExpf16(half %val, i32 %a) {
+; LINUX: bl ldexpf
+; WINDOWS: bl ldexp{{$}}
+entry:
+  %0 = tail call fast half @llvm.ldexp.f16.i32(half %val, i32 %a)
+  ret half %0
+}
+
+declare half @llvm.ldexp.f16.i32(half, i32) memory(none)

diff  --git a/llvm/test/CodeGen/X86/ldexp.ll b/llvm/test/CodeGen/X86/ldexp.ll
index 2be5dec156690..0aa376195627d 100644
--- a/llvm/test/CodeGen/X86/ldexp.ll
+++ b/llvm/test/CodeGen/X86/ldexp.ll
@@ -1,5 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
 ; RUN: llc -mtriple=x86_64-unknown-unknown -verify-machineinstrs < %s | FileCheck -check-prefixes=X64 %s
+; RUN: llc -mtriple=x86_64-pc-win32 -verify-machineinstrs < %s | FileCheck -check-prefixes=WIN64 %s
 ; RUN: llc -mtriple=i386-pc-win32 -verify-machineinstrs < %s | FileCheck -check-prefix=WIN32 %s
 
 define float @ldexp_f32(i8 zeroext %x) {
@@ -8,75 +9,30 @@ define float @ldexp_f32(i8 zeroext %x) {
 ; X64-NEXT:    movss {{.*#+}} xmm0 = [1.0E+0,0.0E+0,0.0E+0,0.0E+0]
 ; X64-NEXT:    jmp ldexpf at PLT # TAILCALL
 ;
+; WIN64-LABEL: ldexp_f32:
+; WIN64:       # %bb.0:
+; WIN64-NEXT:    subq $40, %rsp
+; WIN64-NEXT:    .seh_stackalloc 40
+; WIN64-NEXT:    .seh_endprologue
+; WIN64-NEXT:    movzbl %cl, %edx
+; WIN64-NEXT:    movsd {{.*#+}} xmm0 = [1.0E+0,0.0E+0]
+; WIN64-NEXT:    callq ldexp
+; WIN64-NEXT:    cvtsd2ss %xmm0, %xmm0
+; WIN64-NEXT:    addq $40, %rsp
+; WIN64-NEXT:    retq
+; WIN64-NEXT:    .seh_endproc
+;
 ; WIN32-LABEL: ldexp_f32:
 ; WIN32:       # %bb.0:
-; WIN32-NEXT:    pushl %eax
-; WIN32-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
-; WIN32-NEXT:    cmpl $381, %ecx # imm = 0x17D
-; WIN32-NEXT:    movl %ecx, %eax
-; WIN32-NEXT:    jl LBB0_2
-; WIN32-NEXT:  # %bb.1:
-; WIN32-NEXT:    movl $381, %eax # imm = 0x17D
-; WIN32-NEXT:  LBB0_2:
-; WIN32-NEXT:    addl $-254, %eax
-; WIN32-NEXT:    leal -127(%ecx), %edx
-; WIN32-NEXT:    cmpl $255, %ecx
-; WIN32-NEXT:    jae LBB0_4
-; WIN32-NEXT:  # %bb.3:
-; WIN32-NEXT:    movl %edx, %eax
-; WIN32-NEXT:  LBB0_4:
-; WIN32-NEXT:    flds __real at 7f800000
-; WIN32-NEXT:    flds __real at 7f000000
-; WIN32-NEXT:    jae LBB0_6
-; WIN32-NEXT:  # %bb.5:
-; WIN32-NEXT:    fstp %st(1)
-; WIN32-NEXT:    fldz
-; WIN32-NEXT:  LBB0_6:
-; WIN32-NEXT:    fstp %st(0)
-; WIN32-NEXT:    cmpl $-329, %ecx # imm = 0xFEB7
-; WIN32-NEXT:    movl %ecx, %edx
-; WIN32-NEXT:    jge LBB0_8
-; WIN32-NEXT:  # %bb.7:
-; WIN32-NEXT:    movl $-330, %edx # imm = 0xFEB6
-; WIN32-NEXT:  LBB0_8:
-; WIN32-NEXT:    cmpl $-228, %ecx
-; WIN32-NEXT:    fldz
-; WIN32-NEXT:    flds __real at 0c800000
-; WIN32-NEXT:    jb LBB0_9
-; WIN32-NEXT:  # %bb.10:
-; WIN32-NEXT:    fstp %st(1)
-; WIN32-NEXT:    leal 102(%ecx), %edx
-; WIN32-NEXT:    cmpl $-126, %ecx
-; WIN32-NEXT:    jge LBB0_12
-; WIN32-NEXT:    jmp LBB0_13
-; WIN32-NEXT:  LBB0_9:
-; WIN32-NEXT:    fstp %st(0)
-; WIN32-NEXT:    addl $204, %edx
-; WIN32-NEXT:    cmpl $-126, %ecx
-; WIN32-NEXT:    jl LBB0_13
-; WIN32-NEXT:  LBB0_12:
-; WIN32-NEXT:    movl %ecx, %edx
-; WIN32-NEXT:  LBB0_13:
+; WIN32-NEXT:    subl $16, %esp
+; WIN32-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
+; WIN32-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; WIN32-NEXT:    fld1
-; WIN32-NEXT:    jl LBB0_15
-; WIN32-NEXT:  # %bb.14:
-; WIN32-NEXT:    fstp %st(1)
-; WIN32-NEXT:    fldz
-; WIN32-NEXT:  LBB0_15:
-; WIN32-NEXT:    fstp %st(0)
-; WIN32-NEXT:    cmpl $127, %ecx
-; WIN32-NEXT:    jg LBB0_17
-; WIN32-NEXT:  # %bb.16:
-; WIN32-NEXT:    fstp %st(1)
-; WIN32-NEXT:    movl %edx, %eax
-; WIN32-NEXT:    fldz
-; WIN32-NEXT:  LBB0_17:
-; WIN32-NEXT:    fstp %st(0)
-; WIN32-NEXT:    shll $23, %eax
-; WIN32-NEXT:    addl $1065353216, %eax # imm = 0x3F800000
-; WIN32-NEXT:    movl %eax, (%esp)
-; WIN32-NEXT:    fmuls (%esp)
-; WIN32-NEXT:    popl %eax
+; WIN32-NEXT:    fstpl (%esp)
+; WIN32-NEXT:    calll _ldexp
+; WIN32-NEXT:    fstps {{[0-9]+}}(%esp)
+; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
+; WIN32-NEXT:    addl $16, %esp
 ; WIN32-NEXT:    retl
   %zext = zext i8 %x to i32
   %ldexp = call float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 %zext)
@@ -89,6 +45,12 @@ define double @ldexp_f64(i8 zeroext %x) {
 ; X64-NEXT:    movsd {{.*#+}} xmm0 = [1.0E+0,0.0E+0]
 ; X64-NEXT:    jmp ldexp at PLT # TAILCALL
 ;
+; WIN64-LABEL: ldexp_f64:
+; WIN64:       # %bb.0:
+; WIN64-NEXT:    movzbl %cl, %edx
+; WIN64-NEXT:    movsd {{.*#+}} xmm0 = [1.0E+0,0.0E+0]
+; WIN64-NEXT:    jmp ldexp # TAILCALL
+;
 ; WIN32-LABEL: ldexp_f64:
 ; WIN32:       # %bb.0:
 ; WIN32-NEXT:    subl $12, %esp
@@ -127,152 +89,80 @@ define <2 x float> @ldexp_v2f32(<2 x float> %val, <2 x i32> %exp) {
 ; X64-NEXT:    .cfi_def_cfa_offset 8
 ; X64-NEXT:    retq
 ;
+; WIN64-LABEL: ldexp_v2f32:
+; WIN64:       # %bb.0:
+; WIN64-NEXT:    pushq %rsi
+; WIN64-NEXT:    .seh_pushreg %rsi
+; WIN64-NEXT:    subq $80, %rsp
+; WIN64-NEXT:    .seh_stackalloc 80
+; WIN64-NEXT:    movaps %xmm8, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
+; WIN64-NEXT:    .seh_savexmm %xmm8, 64
+; WIN64-NEXT:    movaps %xmm7, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
+; WIN64-NEXT:    .seh_savexmm %xmm7, 48
+; WIN64-NEXT:    movaps %xmm6, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
+; WIN64-NEXT:    .seh_savexmm %xmm6, 32
+; WIN64-NEXT:    .seh_endprologue
+; WIN64-NEXT:    movq %rdx, %rsi
+; WIN64-NEXT:    movaps (%rcx), %xmm7
+; WIN64-NEXT:    movl 12(%rdx), %edx
+; WIN64-NEXT:    movaps %xmm7, %xmm0
+; WIN64-NEXT:    shufps {{.*#+}} xmm0 = xmm0[3,3],xmm7[3,3]
+; WIN64-NEXT:    cvtss2sd %xmm0, %xmm0
+; WIN64-NEXT:    callq ldexp
+; WIN64-NEXT:    xorps %xmm6, %xmm6
+; WIN64-NEXT:    cvtsd2ss %xmm0, %xmm6
+; WIN64-NEXT:    movl 8(%rsi), %edx
+; WIN64-NEXT:    movaps %xmm7, %xmm0
+; WIN64-NEXT:    unpckhpd {{.*#+}} xmm0 = xmm0[1],xmm7[1]
+; WIN64-NEXT:    cvtss2sd %xmm0, %xmm0
+; WIN64-NEXT:    callq ldexp
+; WIN64-NEXT:    xorps %xmm8, %xmm8
+; WIN64-NEXT:    cvtsd2ss %xmm0, %xmm8
+; WIN64-NEXT:    unpcklps {{.*#+}} xmm8 = xmm8[0],xmm6[0],xmm8[1],xmm6[1]
+; WIN64-NEXT:    movl (%rsi), %edx
+; WIN64-NEXT:    movl 4(%rsi), %esi
+; WIN64-NEXT:    xorps %xmm0, %xmm0
+; WIN64-NEXT:    cvtss2sd %xmm7, %xmm0
+; WIN64-NEXT:    callq ldexp
+; WIN64-NEXT:    xorps %xmm6, %xmm6
+; WIN64-NEXT:    cvtsd2ss %xmm0, %xmm6
+; WIN64-NEXT:    shufps {{.*#+}} xmm7 = xmm7[1,1,1,1]
+; WIN64-NEXT:    xorps %xmm0, %xmm0
+; WIN64-NEXT:    cvtss2sd %xmm7, %xmm0
+; WIN64-NEXT:    movl %esi, %edx
+; WIN64-NEXT:    callq ldexp
+; WIN64-NEXT:    cvtsd2ss %xmm0, %xmm0
+; WIN64-NEXT:    unpcklps {{.*#+}} xmm6 = xmm6[0],xmm0[0],xmm6[1],xmm0[1]
+; WIN64-NEXT:    movlhps {{.*#+}} xmm6 = xmm6[0],xmm8[0]
+; WIN64-NEXT:    movaps %xmm6, %xmm0
+; WIN64-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm6 # 16-byte Reload
+; WIN64-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm7 # 16-byte Reload
+; WIN64-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm8 # 16-byte Reload
+; WIN64-NEXT:    addq $80, %rsp
+; WIN64-NEXT:    popq %rsi
+; WIN64-NEXT:    retq
+; WIN64-NEXT:    .seh_endproc
+;
 ; WIN32-LABEL: ldexp_v2f32:
 ; WIN32:       # %bb.0:
-; WIN32-NEXT:    pushl %edi
 ; WIN32-NEXT:    pushl %esi
-; WIN32-NEXT:    subl $8, %esp
-; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
+; WIN32-NEXT:    subl $20, %esp
+; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %esi
 ; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; WIN32-NEXT:    cmpl $-329, %eax # imm = 0xFEB7
-; WIN32-NEXT:    movl %eax, %edx
-; WIN32-NEXT:    jge LBB2_2
-; WIN32-NEXT:  # %bb.1:
-; WIN32-NEXT:    movl $-330, %edx # imm = 0xFEB6
-; WIN32-NEXT:  LBB2_2:
-; WIN32-NEXT:    addl $204, %edx
-; WIN32-NEXT:    leal 102(%eax), %ecx
-; WIN32-NEXT:    cmpl $-228, %eax
-; WIN32-NEXT:    jb LBB2_4
-; WIN32-NEXT:  # %bb.3:
-; WIN32-NEXT:    movl %ecx, %edx
-; WIN32-NEXT:  LBB2_4:
-; WIN32-NEXT:    flds __real at 0c800000
-; WIN32-NEXT:    fld %st(1)
-; WIN32-NEXT:    fmul %st(1), %st
-; WIN32-NEXT:    fld %st(0)
-; WIN32-NEXT:    fmul %st(2), %st
-; WIN32-NEXT:    jb LBB2_6
-; WIN32-NEXT:  # %bb.5:
-; WIN32-NEXT:    fstp %st(0)
-; WIN32-NEXT:    fldz
-; WIN32-NEXT:    fxch %st(1)
-; WIN32-NEXT:  LBB2_6:
-; WIN32-NEXT:    fstp %st(1)
-; WIN32-NEXT:    cmpl $-126, %eax
-; WIN32-NEXT:    jl LBB2_8
-; WIN32-NEXT:  # %bb.7:
-; WIN32-NEXT:    fstp %st(0)
-; WIN32-NEXT:    fld %st(1)
-; WIN32-NEXT:    movl %eax, %edx
-; WIN32-NEXT:  LBB2_8:
-; WIN32-NEXT:    cmpl $381, %eax # imm = 0x17D
-; WIN32-NEXT:    movl %eax, %esi
-; WIN32-NEXT:    jl LBB2_10
-; WIN32-NEXT:  # %bb.9:
-; WIN32-NEXT:    movl $381, %esi # imm = 0x17D
-; WIN32-NEXT:  LBB2_10:
-; WIN32-NEXT:    flds __real at 7f000000
-; WIN32-NEXT:    fmul %st, %st(3)
-; WIN32-NEXT:    fld %st(3)
-; WIN32-NEXT:    fmul %st(1), %st
-; WIN32-NEXT:    leal -127(%eax), %ecx
-; WIN32-NEXT:    cmpl $255, %eax
-; WIN32-NEXT:    jae LBB2_11
-; WIN32-NEXT:  # %bb.12:
-; WIN32-NEXT:    fstp %st(0)
-; WIN32-NEXT:    jmp LBB2_13
-; WIN32-NEXT:  LBB2_11:
-; WIN32-NEXT:    fstp %st(4)
-; WIN32-NEXT:    addl $-254, %esi
-; WIN32-NEXT:    movl %esi, %ecx
-; WIN32-NEXT:  LBB2_13:
-; WIN32-NEXT:    cmpl $127, %eax
+; WIN32-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
-; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %esi
-; WIN32-NEXT:    jg LBB2_15
-; WIN32-NEXT:  # %bb.14:
-; WIN32-NEXT:    movl %edx, %ecx
-; WIN32-NEXT:  LBB2_15:
-; WIN32-NEXT:    cmpl $381, %esi # imm = 0x17D
-; WIN32-NEXT:    movl %esi, %edx
-; WIN32-NEXT:    jl LBB2_17
-; WIN32-NEXT:  # %bb.16:
-; WIN32-NEXT:    movl $381, %edx # imm = 0x17D
-; WIN32-NEXT:  LBB2_17:
-; WIN32-NEXT:    addl $-254, %edx
-; WIN32-NEXT:    leal -127(%esi), %edi
-; WIN32-NEXT:    cmpl $255, %esi
-; WIN32-NEXT:    jae LBB2_19
-; WIN32-NEXT:  # %bb.18:
-; WIN32-NEXT:    movl %edi, %edx
-; WIN32-NEXT:  LBB2_19:
-; WIN32-NEXT:    fld %st(0)
-; WIN32-NEXT:    fmul %st(2), %st
-; WIN32-NEXT:    fmul %st, %st(2)
-; WIN32-NEXT:    jae LBB2_21
-; WIN32-NEXT:  # %bb.20:
-; WIN32-NEXT:    fstp %st(2)
-; WIN32-NEXT:    fldz
-; WIN32-NEXT:  LBB2_21:
-; WIN32-NEXT:    fstp %st(0)
-; WIN32-NEXT:    cmpl $-329, %esi # imm = 0xFEB7
-; WIN32-NEXT:    movl %esi, %edi
-; WIN32-NEXT:    jge LBB2_23
-; WIN32-NEXT:  # %bb.22:
-; WIN32-NEXT:    movl $-330, %edi # imm = 0xFEB6
-; WIN32-NEXT:  LBB2_23:
-; WIN32-NEXT:    fld %st(0)
-; WIN32-NEXT:    fmul %st(4), %st
-; WIN32-NEXT:    fmul %st, %st(4)
-; WIN32-NEXT:    cmpl $-228, %esi
-; WIN32-NEXT:    jb LBB2_24
-; WIN32-NEXT:  # %bb.25:
-; WIN32-NEXT:    fstp %st(4)
-; WIN32-NEXT:    leal 102(%esi), %edi
-; WIN32-NEXT:    cmpl $-126, %esi
-; WIN32-NEXT:    jge LBB2_27
-; WIN32-NEXT:    jmp LBB2_28
-; WIN32-NEXT:  LBB2_24:
-; WIN32-NEXT:    fstp %st(0)
-; WIN32-NEXT:    addl $204, %edi
-; WIN32-NEXT:    cmpl $-126, %esi
-; WIN32-NEXT:    jl LBB2_28
-; WIN32-NEXT:  LBB2_27:
-; WIN32-NEXT:    fstp %st(3)
-; WIN32-NEXT:    movl %esi, %edi
-; WIN32-NEXT:    fldz
-; WIN32-NEXT:  LBB2_28:
-; WIN32-NEXT:    fstp %st(0)
-; WIN32-NEXT:    cmpl $127, %esi
-; WIN32-NEXT:    jg LBB2_30
-; WIN32-NEXT:  # %bb.29:
-; WIN32-NEXT:    fstp %st(0)
-; WIN32-NEXT:    movl %edi, %edx
-; WIN32-NEXT:    fldz
-; WIN32-NEXT:    fxch %st(2)
-; WIN32-NEXT:  LBB2_30:
-; WIN32-NEXT:    fstp %st(2)
-; WIN32-NEXT:    cmpl $127, %eax
-; WIN32-NEXT:    jg LBB2_32
-; WIN32-NEXT:  # %bb.31:
-; WIN32-NEXT:    fstp %st(2)
-; WIN32-NEXT:    fldz
-; WIN32-NEXT:  LBB2_32:
-; WIN32-NEXT:    fstp %st(0)
-; WIN32-NEXT:    shll $23, %ecx
-; WIN32-NEXT:    addl $1065353216, %ecx # imm = 0x3F800000
-; WIN32-NEXT:    movl %ecx, (%esp)
-; WIN32-NEXT:    shll $23, %edx
-; WIN32-NEXT:    addl $1065353216, %edx # imm = 0x3F800000
-; WIN32-NEXT:    movl %edx, {{[0-9]+}}(%esp)
-; WIN32-NEXT:    fxch %st(1)
-; WIN32-NEXT:    fmuls (%esp)
-; WIN32-NEXT:    fxch %st(1)
-; WIN32-NEXT:    fmuls {{[0-9]+}}(%esp)
-; WIN32-NEXT:    addl $8, %esp
+; WIN32-NEXT:    fstpl (%esp)
+; WIN32-NEXT:    calll _ldexp
+; WIN32-NEXT:    movl %esi, {{[0-9]+}}(%esp)
+; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
+; WIN32-NEXT:    fstpl (%esp)
+; WIN32-NEXT:    fstps {{[0-9]+}}(%esp)
+; WIN32-NEXT:    calll _ldexp
+; WIN32-NEXT:    fstps {{[0-9]+}}(%esp)
+; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
+; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
+; WIN32-NEXT:    addl $20, %esp
 ; WIN32-NEXT:    popl %esi
-; WIN32-NEXT:    popl %edi
 ; WIN32-NEXT:    retl
   %1 = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %val, <2 x i32> %exp)
   ret <2 x float> %1
@@ -319,335 +209,106 @@ define <4 x float> @ldexp_v4f32(<4 x float> %val, <4 x i32> %exp) {
 ; X64-NEXT:    .cfi_def_cfa_offset 8
 ; X64-NEXT:    retq
 ;
+; WIN64-LABEL: ldexp_v4f32:
+; WIN64:       # %bb.0:
+; WIN64-NEXT:    pushq %rsi
+; WIN64-NEXT:    .seh_pushreg %rsi
+; WIN64-NEXT:    subq $80, %rsp
+; WIN64-NEXT:    .seh_stackalloc 80
+; WIN64-NEXT:    movaps %xmm8, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
+; WIN64-NEXT:    .seh_savexmm %xmm8, 64
+; WIN64-NEXT:    movaps %xmm7, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
+; WIN64-NEXT:    .seh_savexmm %xmm7, 48
+; WIN64-NEXT:    movaps %xmm6, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
+; WIN64-NEXT:    .seh_savexmm %xmm6, 32
+; WIN64-NEXT:    .seh_endprologue
+; WIN64-NEXT:    movq %rdx, %rsi
+; WIN64-NEXT:    movaps (%rcx), %xmm7
+; WIN64-NEXT:    movl 12(%rdx), %edx
+; WIN64-NEXT:    movaps %xmm7, %xmm0
+; WIN64-NEXT:    shufps {{.*#+}} xmm0 = xmm0[3,3],xmm7[3,3]
+; WIN64-NEXT:    cvtss2sd %xmm0, %xmm0
+; WIN64-NEXT:    callq ldexp
+; WIN64-NEXT:    xorps %xmm6, %xmm6
+; WIN64-NEXT:    cvtsd2ss %xmm0, %xmm6
+; WIN64-NEXT:    movl 8(%rsi), %edx
+; WIN64-NEXT:    movaps %xmm7, %xmm0
+; WIN64-NEXT:    unpckhpd {{.*#+}} xmm0 = xmm0[1],xmm7[1]
+; WIN64-NEXT:    cvtss2sd %xmm0, %xmm0
+; WIN64-NEXT:    callq ldexp
+; WIN64-NEXT:    xorps %xmm8, %xmm8
+; WIN64-NEXT:    cvtsd2ss %xmm0, %xmm8
+; WIN64-NEXT:    unpcklps {{.*#+}} xmm8 = xmm8[0],xmm6[0],xmm8[1],xmm6[1]
+; WIN64-NEXT:    movl (%rsi), %edx
+; WIN64-NEXT:    movl 4(%rsi), %esi
+; WIN64-NEXT:    xorps %xmm0, %xmm0
+; WIN64-NEXT:    cvtss2sd %xmm7, %xmm0
+; WIN64-NEXT:    callq ldexp
+; WIN64-NEXT:    xorps %xmm6, %xmm6
+; WIN64-NEXT:    cvtsd2ss %xmm0, %xmm6
+; WIN64-NEXT:    shufps {{.*#+}} xmm7 = xmm7[1,1,1,1]
+; WIN64-NEXT:    xorps %xmm0, %xmm0
+; WIN64-NEXT:    cvtss2sd %xmm7, %xmm0
+; WIN64-NEXT:    movl %esi, %edx
+; WIN64-NEXT:    callq ldexp
+; WIN64-NEXT:    cvtsd2ss %xmm0, %xmm0
+; WIN64-NEXT:    unpcklps {{.*#+}} xmm6 = xmm6[0],xmm0[0],xmm6[1],xmm0[1]
+; WIN64-NEXT:    movlhps {{.*#+}} xmm6 = xmm6[0],xmm8[0]
+; WIN64-NEXT:    movaps %xmm6, %xmm0
+; WIN64-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm6 # 16-byte Reload
+; WIN64-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm7 # 16-byte Reload
+; WIN64-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm8 # 16-byte Reload
+; WIN64-NEXT:    addq $80, %rsp
+; WIN64-NEXT:    popq %rsi
+; WIN64-NEXT:    retq
+; WIN64-NEXT:    .seh_endproc
+;
 ; WIN32-LABEL: ldexp_v4f32:
 ; WIN32:       # %bb.0:
 ; WIN32-NEXT:    pushl %ebp
 ; WIN32-NEXT:    pushl %ebx
 ; WIN32-NEXT:    pushl %edi
 ; WIN32-NEXT:    pushl %esi
-; WIN32-NEXT:    subl $32, %esp
+; WIN32-NEXT:    subl $44, %esp
+; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %esi
+; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %edi
+; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %ebx
+; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %ebp
+; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; WIN32-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
-; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; WIN32-NEXT:    fstpl (%esp)
+; WIN32-NEXT:    calll _ldexp
+; WIN32-NEXT:    fstpl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Spill
+; WIN32-NEXT:    movl %ebp, {{[0-9]+}}(%esp)
 ; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
-; WIN32-NEXT:    flds __real at 7f000000
-; WIN32-NEXT:    fld %st(1)
-; WIN32-NEXT:    fmul %st(1), %st
-; WIN32-NEXT:    fld %st(0)
-; WIN32-NEXT:    fmul %st(2), %st
-; WIN32-NEXT:    cmpl $255, %ecx
-; WIN32-NEXT:    jae LBB3_2
-; WIN32-NEXT:  # %bb.1:
-; WIN32-NEXT:    fstp %st(0)
-; WIN32-NEXT:    fldz
-; WIN32-NEXT:    fxch %st(1)
-; WIN32-NEXT:  LBB3_2:
-; WIN32-NEXT:    fstp %st(1)
-; WIN32-NEXT:    cmpl $-329, %ecx # imm = 0xFEB7
-; WIN32-NEXT:    movl %ecx, %esi
-; WIN32-NEXT:    jge LBB3_4
-; WIN32-NEXT:  # %bb.3:
-; WIN32-NEXT:    movl $-330, %esi # imm = 0xFEB6
-; WIN32-NEXT:  LBB3_4:
-; WIN32-NEXT:    addl $204, %esi
-; WIN32-NEXT:    leal 102(%ecx), %eax
-; WIN32-NEXT:    cmpl $-228, %ecx
-; WIN32-NEXT:    jb LBB3_6
-; WIN32-NEXT:  # %bb.5:
-; WIN32-NEXT:    movl %eax, %esi
-; WIN32-NEXT:  LBB3_6:
-; WIN32-NEXT:    flds __real at 0c800000
-; WIN32-NEXT:    fld %st(3)
-; WIN32-NEXT:    fmul %st(1), %st
-; WIN32-NEXT:    fld %st(0)
-; WIN32-NEXT:    fmul %st(2), %st
-; WIN32-NEXT:    jb LBB3_8
-; WIN32-NEXT:  # %bb.7:
-; WIN32-NEXT:    fstp %st(0)
-; WIN32-NEXT:    fldz
-; WIN32-NEXT:    fxch %st(1)
-; WIN32-NEXT:  LBB3_8:
-; WIN32-NEXT:    fstp %st(1)
-; WIN32-NEXT:    cmpl $-126, %ecx
-; WIN32-NEXT:    jl LBB3_10
-; WIN32-NEXT:  # %bb.9:
-; WIN32-NEXT:    fstp %st(0)
-; WIN32-NEXT:    fldz
-; WIN32-NEXT:    fxch %st(4)
-; WIN32-NEXT:  LBB3_10:
-; WIN32-NEXT:    fstp %st(4)
-; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %edi
-; WIN32-NEXT:    movl %ecx, %edx
-; WIN32-NEXT:    subl $127, %edx
-; WIN32-NEXT:    jg LBB3_12
-; WIN32-NEXT:  # %bb.11:
-; WIN32-NEXT:    fstp %st(1)
-; WIN32-NEXT:    fldz
-; WIN32-NEXT:    fxch %st(3)
-; WIN32-NEXT:    fxch %st(1)
-; WIN32-NEXT:  LBB3_12:
-; WIN32-NEXT:    fstp %st(3)
-; WIN32-NEXT:    fld %st(3)
-; WIN32-NEXT:    fmul %st(2), %st
-; WIN32-NEXT:    fld %st(0)
-; WIN32-NEXT:    fmul %st(3), %st
-; WIN32-NEXT:    cmpl $255, %edi
-; WIN32-NEXT:    jae LBB3_14
-; WIN32-NEXT:  # %bb.13:
-; WIN32-NEXT:    fstp %st(0)
-; WIN32-NEXT:    fldz
-; WIN32-NEXT:    fxch %st(1)
-; WIN32-NEXT:  LBB3_14:
-; WIN32-NEXT:    fstp %st(1)
-; WIN32-NEXT:    fxch %st(1)
-; WIN32-NEXT:    fstps {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Folded Spill
-; WIN32-NEXT:    cmpl $-329, %edi # imm = 0xFEB7
-; WIN32-NEXT:    movl %edi, %eax
-; WIN32-NEXT:    jge LBB3_16
-; WIN32-NEXT:  # %bb.15:
-; WIN32-NEXT:    movl $-330, %eax # imm = 0xFEB6
-; WIN32-NEXT:  LBB3_16:
-; WIN32-NEXT:    fld %st(3)
-; WIN32-NEXT:    fmul %st(3), %st
-; WIN32-NEXT:    fld %st(0)
-; WIN32-NEXT:    fmul %st(4), %st
-; WIN32-NEXT:    cmpl $-228, %edi
-; WIN32-NEXT:    jb LBB3_17
-; WIN32-NEXT:  # %bb.18:
-; WIN32-NEXT:    fstp %st(0)
-; WIN32-NEXT:    leal 102(%edi), %eax
-; WIN32-NEXT:    cmpl $-126, %edi
-; WIN32-NEXT:    jge LBB3_20
-; WIN32-NEXT:    jmp LBB3_21
-; WIN32-NEXT:  LBB3_17:
-; WIN32-NEXT:    fstp %st(1)
-; WIN32-NEXT:    addl $204, %eax
-; WIN32-NEXT:    cmpl $-126, %edi
-; WIN32-NEXT:    jl LBB3_21
-; WIN32-NEXT:  LBB3_20:
-; WIN32-NEXT:    fstp %st(0)
-; WIN32-NEXT:    movl %edi, %eax
-; WIN32-NEXT:    fldz
-; WIN32-NEXT:    fxch %st(4)
-; WIN32-NEXT:  LBB3_21:
-; WIN32-NEXT:    fstp %st(4)
-; WIN32-NEXT:    movl %eax, (%esp) # 4-byte Spill
-; WIN32-NEXT:    movl %edi, %ebx
-; WIN32-NEXT:    subl $127, %ebx
-; WIN32-NEXT:    jg LBB3_23
-; WIN32-NEXT:  # %bb.22:
-; WIN32-NEXT:    fstp %st(0)
-; WIN32-NEXT:    fldz
-; WIN32-NEXT:    fxch %st(3)
-; WIN32-NEXT:  LBB3_23:
-; WIN32-NEXT:    fstp %st(3)
-; WIN32-NEXT:    cmpl $381, %edi # imm = 0x17D
-; WIN32-NEXT:    movl %edi, %eax
-; WIN32-NEXT:    jge LBB3_24
-; WIN32-NEXT:  # %bb.25:
-; WIN32-NEXT:    cmpl $255, %edi
-; WIN32-NEXT:    jae LBB3_26
-; WIN32-NEXT:  LBB3_27:
-; WIN32-NEXT:    cmpl $-126, %ecx
-; WIN32-NEXT:    jl LBB3_29
-; WIN32-NEXT:  LBB3_28:
-; WIN32-NEXT:    movl %ecx, %esi
-; WIN32-NEXT:  LBB3_29:
-; WIN32-NEXT:    cmpl $381, %ecx # imm = 0x17D
-; WIN32-NEXT:    movl %ecx, %eax
-; WIN32-NEXT:    jl LBB3_31
-; WIN32-NEXT:  # %bb.30:
-; WIN32-NEXT:    movl $381, %eax # imm = 0x17D
-; WIN32-NEXT:  LBB3_31:
-; WIN32-NEXT:    cmpl $255, %ecx
+; WIN32-NEXT:    fstpl (%esp)
+; WIN32-NEXT:    calll _ldexp
+; WIN32-NEXT:    fstpl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Spill
+; WIN32-NEXT:    movl %ebx, {{[0-9]+}}(%esp)
 ; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
-; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %ebp
-; WIN32-NEXT:    jb LBB3_33
-; WIN32-NEXT:  # %bb.32:
-; WIN32-NEXT:    addl $-254, %eax
-; WIN32-NEXT:    movl %eax, %edx
-; WIN32-NEXT:  LBB3_33:
-; WIN32-NEXT:    fxch %st(3)
-; WIN32-NEXT:    fstps {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Folded Spill
-; WIN32-NEXT:    movl %esi, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill
-; WIN32-NEXT:    cmpl $381, %ebp # imm = 0x17D
-; WIN32-NEXT:    movl %ebp, %eax
-; WIN32-NEXT:    jl LBB3_35
-; WIN32-NEXT:  # %bb.34:
-; WIN32-NEXT:    movl $381, %eax # imm = 0x17D
-; WIN32-NEXT:  LBB3_35:
-; WIN32-NEXT:    fld %st(2)
-; WIN32-NEXT:    fmul %st(1), %st
-; WIN32-NEXT:    fld %st(0)
-; WIN32-NEXT:    fmul %st(2), %st
-; WIN32-NEXT:    leal -127(%ebp), %edi
-; WIN32-NEXT:    cmpl $255, %ebp
-; WIN32-NEXT:    jae LBB3_36
-; WIN32-NEXT:  # %bb.37:
-; WIN32-NEXT:    fstp %st(0)
-; WIN32-NEXT:    jmp LBB3_38
-; WIN32-NEXT:  LBB3_24:
-; WIN32-NEXT:    movl $381, %eax # imm = 0x17D
-; WIN32-NEXT:    cmpl $255, %edi
-; WIN32-NEXT:    jb LBB3_27
-; WIN32-NEXT:  LBB3_26:
-; WIN32-NEXT:    addl $-254, %eax
-; WIN32-NEXT:    movl %eax, %ebx
-; WIN32-NEXT:    cmpl $-126, %ecx
-; WIN32-NEXT:    jge LBB3_28
-; WIN32-NEXT:    jmp LBB3_29
-; WIN32-NEXT:  LBB3_36:
-; WIN32-NEXT:    fstp %st(1)
-; WIN32-NEXT:    addl $-254, %eax
-; WIN32-NEXT:    movl %eax, %edi
-; WIN32-NEXT:  LBB3_38:
-; WIN32-NEXT:    cmpl $-329, %ebp # imm = 0xFEB7
-; WIN32-NEXT:    movl %ebp, %ecx
-; WIN32-NEXT:    jge LBB3_40
-; WIN32-NEXT:  # %bb.39:
-; WIN32-NEXT:    movl $-330, %ecx # imm = 0xFEB6
-; WIN32-NEXT:  LBB3_40:
-; WIN32-NEXT:    addl $204, %ecx
-; WIN32-NEXT:    leal 102(%ebp), %eax
-; WIN32-NEXT:    cmpl $-228, %ebp
-; WIN32-NEXT:    jb LBB3_42
-; WIN32-NEXT:  # %bb.41:
-; WIN32-NEXT:    movl %eax, %ecx
-; WIN32-NEXT:  LBB3_42:
-; WIN32-NEXT:    fld %st(3)
-; WIN32-NEXT:    fmul %st(3), %st
-; WIN32-NEXT:    fld %st(0)
-; WIN32-NEXT:    fmul %st(4), %st
-; WIN32-NEXT:    jb LBB3_44
-; WIN32-NEXT:  # %bb.43:
-; WIN32-NEXT:    fstp %st(0)
-; WIN32-NEXT:    fldz
-; WIN32-NEXT:    fxch %st(1)
-; WIN32-NEXT:  LBB3_44:
-; WIN32-NEXT:    fstp %st(1)
-; WIN32-NEXT:    cmpl $-126, %ebp
-; WIN32-NEXT:    jl LBB3_46
-; WIN32-NEXT:  # %bb.45:
-; WIN32-NEXT:    fstp %st(0)
-; WIN32-NEXT:    movl %ebp, %ecx
-; WIN32-NEXT:    fldz
-; WIN32-NEXT:    fxch %st(4)
-; WIN32-NEXT:  LBB3_46:
-; WIN32-NEXT:    fstp %st(4)
-; WIN32-NEXT:    cmpl $127, %ebp
+; WIN32-NEXT:    fstpl (%esp)
+; WIN32-NEXT:    calll _ldexp
+; WIN32-NEXT:    movl %edi, {{[0-9]+}}(%esp)
 ; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
-; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %esi
-; WIN32-NEXT:    jg LBB3_48
-; WIN32-NEXT:  # %bb.47:
-; WIN32-NEXT:    movl %ecx, %edi
-; WIN32-NEXT:  LBB3_48:
-; WIN32-NEXT:    cmpl $381, %esi # imm = 0x17D
-; WIN32-NEXT:    movl %esi, %ecx
-; WIN32-NEXT:    jl LBB3_50
-; WIN32-NEXT:  # %bb.49:
-; WIN32-NEXT:    movl $381, %ecx # imm = 0x17D
-; WIN32-NEXT:  LBB3_50:
-; WIN32-NEXT:    addl $-254, %ecx
-; WIN32-NEXT:    leal -127(%esi), %eax
-; WIN32-NEXT:    cmpl $255, %esi
-; WIN32-NEXT:    jae LBB3_52
-; WIN32-NEXT:  # %bb.51:
-; WIN32-NEXT:    movl %eax, %ecx
-; WIN32-NEXT:  LBB3_52:
-; WIN32-NEXT:    fld %st(0)
-; WIN32-NEXT:    fmul %st(3), %st
-; WIN32-NEXT:    fmul %st, %st(3)
-; WIN32-NEXT:    jae LBB3_54
-; WIN32-NEXT:  # %bb.53:
-; WIN32-NEXT:    fstp %st(3)
-; WIN32-NEXT:    fldz
-; WIN32-NEXT:  LBB3_54:
-; WIN32-NEXT:    fstp %st(0)
-; WIN32-NEXT:    cmpl $-329, %esi # imm = 0xFEB7
-; WIN32-NEXT:    movl %esi, %eax
-; WIN32-NEXT:    jge LBB3_56
-; WIN32-NEXT:  # %bb.55:
-; WIN32-NEXT:    movl $-330, %eax # imm = 0xFEB6
-; WIN32-NEXT:  LBB3_56:
-; WIN32-NEXT:    fld %st(0)
-; WIN32-NEXT:    fmul %st(4), %st
-; WIN32-NEXT:    fmul %st, %st(4)
-; WIN32-NEXT:    cmpl $-228, %esi
-; WIN32-NEXT:    jb LBB3_57
-; WIN32-NEXT:  # %bb.58:
-; WIN32-NEXT:    fstp %st(4)
-; WIN32-NEXT:    leal 102(%esi), %eax
-; WIN32-NEXT:    cmpl $-126, %esi
-; WIN32-NEXT:    jge LBB3_60
-; WIN32-NEXT:    jmp LBB3_61
-; WIN32-NEXT:  LBB3_57:
-; WIN32-NEXT:    fstp %st(0)
-; WIN32-NEXT:    addl $204, %eax
-; WIN32-NEXT:    cmpl $-126, %esi
-; WIN32-NEXT:    jl LBB3_61
-; WIN32-NEXT:  LBB3_60:
-; WIN32-NEXT:    fstp %st(3)
+; WIN32-NEXT:    fstpl (%esp)
+; WIN32-NEXT:    fstps {{[0-9]+}}(%esp)
+; WIN32-NEXT:    fldl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Reload
+; WIN32-NEXT:    fstps {{[0-9]+}}(%esp)
+; WIN32-NEXT:    fldl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Reload
+; WIN32-NEXT:    fstps {{[0-9]+}}(%esp)
+; WIN32-NEXT:    calll _ldexp
+; WIN32-NEXT:    fstps {{[0-9]+}}(%esp)
+; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
+; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
+; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
+; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
+; WIN32-NEXT:    fstps 12(%esi)
+; WIN32-NEXT:    fstps 8(%esi)
+; WIN32-NEXT:    fstps 4(%esi)
+; WIN32-NEXT:    fstps (%esi)
 ; WIN32-NEXT:    movl %esi, %eax
-; WIN32-NEXT:    fldz
-; WIN32-NEXT:  LBB3_61:
-; WIN32-NEXT:    fstp %st(0)
-; WIN32-NEXT:    cmpl $127, %esi
-; WIN32-NEXT:    jg LBB3_63
-; WIN32-NEXT:  # %bb.62:
-; WIN32-NEXT:    fstp %st(1)
-; WIN32-NEXT:    movl %eax, %ecx
-; WIN32-NEXT:    fldz
-; WIN32-NEXT:    fxch %st(2)
-; WIN32-NEXT:    fxch %st(1)
-; WIN32-NEXT:  LBB3_63:
-; WIN32-NEXT:    fstp %st(2)
-; WIN32-NEXT:    cmpl $127, {{[0-9]+}}(%esp)
-; WIN32-NEXT:    jg LBB3_65
-; WIN32-NEXT:  # %bb.64:
-; WIN32-NEXT:    movl (%esp), %ebx # 4-byte Reload
-; WIN32-NEXT:  LBB3_65:
-; WIN32-NEXT:    cmpl $127, {{[0-9]+}}(%esp)
-; WIN32-NEXT:    flds {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Folded Reload
-; WIN32-NEXT:    jg LBB3_67
-; WIN32-NEXT:  # %bb.66:
-; WIN32-NEXT:    movl {{[-0-9]+}}(%e{{[sb]}}p), %edx # 4-byte Reload
-; WIN32-NEXT:  LBB3_67:
-; WIN32-NEXT:    cmpl $127, %ebp
-; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; WIN32-NEXT:    jg LBB3_69
-; WIN32-NEXT:  # %bb.68:
-; WIN32-NEXT:    fstp %st(2)
-; WIN32-NEXT:    fldz
-; WIN32-NEXT:    fxch %st(3)
-; WIN32-NEXT:    fxch %st(2)
-; WIN32-NEXT:  LBB3_69:
-; WIN32-NEXT:    fstp %st(3)
-; WIN32-NEXT:    shll $23, %edi
-; WIN32-NEXT:    addl $1065353216, %edi # imm = 0x3F800000
-; WIN32-NEXT:    movl %edi, {{[0-9]+}}(%esp)
-; WIN32-NEXT:    shll $23, %ecx
-; WIN32-NEXT:    addl $1065353216, %ecx # imm = 0x3F800000
-; WIN32-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
-; WIN32-NEXT:    shll $23, %ebx
-; WIN32-NEXT:    addl $1065353216, %ebx # imm = 0x3F800000
-; WIN32-NEXT:    movl %ebx, {{[0-9]+}}(%esp)
-; WIN32-NEXT:    shll $23, %edx
-; WIN32-NEXT:    addl $1065353216, %edx # imm = 0x3F800000
-; WIN32-NEXT:    movl %edx, {{[0-9]+}}(%esp)
-; WIN32-NEXT:    fxch %st(1)
-; WIN32-NEXT:    fmuls {{[0-9]+}}(%esp)
-; WIN32-NEXT:    fxch %st(1)
-; WIN32-NEXT:    fmuls {{[0-9]+}}(%esp)
-; WIN32-NEXT:    flds {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Folded Reload
-; WIN32-NEXT:    fmuls {{[0-9]+}}(%esp)
-; WIN32-NEXT:    fxch %st(3)
-; WIN32-NEXT:    fmuls {{[0-9]+}}(%esp)
-; WIN32-NEXT:    fstps 12(%eax)
-; WIN32-NEXT:    fxch %st(2)
-; WIN32-NEXT:    fstps 8(%eax)
-; WIN32-NEXT:    fxch %st(1)
-; WIN32-NEXT:    fstps 4(%eax)
-; WIN32-NEXT:    fstps (%eax)
-; WIN32-NEXT:    addl $32, %esp
+; WIN32-NEXT:    addl $44, %esp
 ; WIN32-NEXT:    popl %esi
 ; WIN32-NEXT:    popl %edi
 ; WIN32-NEXT:    popl %ebx
@@ -680,6 +341,37 @@ define <2 x double> @ldexp_v2f64(<2 x double> %val, <2 x i32> %exp) {
 ; X64-NEXT:    .cfi_def_cfa_offset 8
 ; X64-NEXT:    retq
 ;
+; WIN64-LABEL: ldexp_v2f64:
+; WIN64:       # %bb.0:
+; WIN64-NEXT:    pushq %rsi
+; WIN64-NEXT:    .seh_pushreg %rsi
+; WIN64-NEXT:    subq $64, %rsp
+; WIN64-NEXT:    .seh_stackalloc 64
+; WIN64-NEXT:    movaps %xmm7, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
+; WIN64-NEXT:    .seh_savexmm %xmm7, 48
+; WIN64-NEXT:    movaps %xmm6, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
+; WIN64-NEXT:    .seh_savexmm %xmm6, 32
+; WIN64-NEXT:    .seh_endprologue
+; WIN64-NEXT:    movaps (%rcx), %xmm6
+; WIN64-NEXT:    movl (%rdx), %eax
+; WIN64-NEXT:    movl 4(%rdx), %esi
+; WIN64-NEXT:    movaps %xmm6, %xmm0
+; WIN64-NEXT:    movl %eax, %edx
+; WIN64-NEXT:    callq ldexp
+; WIN64-NEXT:    movaps %xmm0, %xmm7
+; WIN64-NEXT:    movhlps {{.*#+}} xmm6 = xmm6[1,1]
+; WIN64-NEXT:    movaps %xmm6, %xmm0
+; WIN64-NEXT:    movl %esi, %edx
+; WIN64-NEXT:    callq ldexp
+; WIN64-NEXT:    movlhps {{.*#+}} xmm7 = xmm7[0],xmm0[0]
+; WIN64-NEXT:    movaps %xmm7, %xmm0
+; WIN64-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm6 # 16-byte Reload
+; WIN64-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm7 # 16-byte Reload
+; WIN64-NEXT:    addq $64, %rsp
+; WIN64-NEXT:    popq %rsi
+; WIN64-NEXT:    retq
+; WIN64-NEXT:    .seh_endproc
+;
 ; WIN32-LABEL: ldexp_v2f64:
 ; WIN32:       # %bb.0:
 ; WIN32-NEXT:    pushl %esi
@@ -756,6 +448,58 @@ define <4 x double> @ldexp_v4f64(<4 x double> %val, <4 x i32> %exp) {
 ; X64-NEXT:    .cfi_def_cfa_offset 8
 ; X64-NEXT:    retq
 ;
+; WIN64-LABEL: ldexp_v4f64:
+; WIN64:       # %bb.0:
+; WIN64-NEXT:    pushq %rsi
+; WIN64-NEXT:    .seh_pushreg %rsi
+; WIN64-NEXT:    pushq %rdi
+; WIN64-NEXT:    .seh_pushreg %rdi
+; WIN64-NEXT:    pushq %rbx
+; WIN64-NEXT:    .seh_pushreg %rbx
+; WIN64-NEXT:    subq $80, %rsp
+; WIN64-NEXT:    .seh_stackalloc 80
+; WIN64-NEXT:    movaps %xmm8, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
+; WIN64-NEXT:    .seh_savexmm %xmm8, 64
+; WIN64-NEXT:    movaps %xmm7, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
+; WIN64-NEXT:    .seh_savexmm %xmm7, 48
+; WIN64-NEXT:    movaps %xmm6, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
+; WIN64-NEXT:    .seh_savexmm %xmm6, 32
+; WIN64-NEXT:    .seh_endprologue
+; WIN64-NEXT:    movl 12(%r8), %esi
+; WIN64-NEXT:    movl 8(%r8), %edi
+; WIN64-NEXT:    movaps (%rdx), %xmm6
+; WIN64-NEXT:    movaps (%rcx), %xmm7
+; WIN64-NEXT:    movl (%r8), %edx
+; WIN64-NEXT:    movl 4(%r8), %ebx
+; WIN64-NEXT:    movaps %xmm7, %xmm0
+; WIN64-NEXT:    callq ldexp
+; WIN64-NEXT:    movaps %xmm0, %xmm8
+; WIN64-NEXT:    movhlps {{.*#+}} xmm7 = xmm7[1,1]
+; WIN64-NEXT:    movaps %xmm7, %xmm0
+; WIN64-NEXT:    movl %ebx, %edx
+; WIN64-NEXT:    callq ldexp
+; WIN64-NEXT:    movlhps {{.*#+}} xmm8 = xmm8[0],xmm0[0]
+; WIN64-NEXT:    movaps %xmm6, %xmm0
+; WIN64-NEXT:    movl %edi, %edx
+; WIN64-NEXT:    callq ldexp
+; WIN64-NEXT:    movaps %xmm0, %xmm7
+; WIN64-NEXT:    movhlps {{.*#+}} xmm6 = xmm6[1,1]
+; WIN64-NEXT:    movaps %xmm6, %xmm0
+; WIN64-NEXT:    movl %esi, %edx
+; WIN64-NEXT:    callq ldexp
+; WIN64-NEXT:    movlhps {{.*#+}} xmm7 = xmm7[0],xmm0[0]
+; WIN64-NEXT:    movaps %xmm8, %xmm0
+; WIN64-NEXT:    movaps %xmm7, %xmm1
+; WIN64-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm6 # 16-byte Reload
+; WIN64-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm7 # 16-byte Reload
+; WIN64-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm8 # 16-byte Reload
+; WIN64-NEXT:    addq $80, %rsp
+; WIN64-NEXT:    popq %rbx
+; WIN64-NEXT:    popq %rdi
+; WIN64-NEXT:    popq %rsi
+; WIN64-NEXT:    retq
+; WIN64-NEXT:    .seh_endproc
+;
 ; WIN32-LABEL: ldexp_v4f64:
 ; WIN32:       # %bb.0:
 ; WIN32-NEXT:    pushl %ebp
@@ -826,86 +570,42 @@ define half @ldexp_f16(half %arg0, i32 %arg1) {
 ; X64-NEXT:    .cfi_def_cfa_offset 8
 ; X64-NEXT:    retq
 ;
+; WIN64-LABEL: ldexp_f16:
+; WIN64:       # %bb.0:
+; WIN64-NEXT:    pushq %rsi
+; WIN64-NEXT:    .seh_pushreg %rsi
+; WIN64-NEXT:    subq $32, %rsp
+; WIN64-NEXT:    .seh_stackalloc 32
+; WIN64-NEXT:    .seh_endprologue
+; WIN64-NEXT:    movl %edx, %esi
+; WIN64-NEXT:    callq __extendhfsf2
+; WIN64-NEXT:    cvtss2sd %xmm0, %xmm0
+; WIN64-NEXT:    movl %esi, %edx
+; WIN64-NEXT:    callq ldexp
+; WIN64-NEXT:    callq __truncdfhf2
+; WIN64-NEXT:    nop
+; WIN64-NEXT:    addq $32, %rsp
+; WIN64-NEXT:    popq %rsi
+; WIN64-NEXT:    retq
+; WIN64-NEXT:    .seh_endproc
+;
 ; WIN32-LABEL: ldexp_f16:
 ; WIN32:       # %bb.0:
-; WIN32-NEXT:    pushl %edi
 ; WIN32-NEXT:    pushl %esi
-; WIN32-NEXT:    subl $8, %esp
-; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %edi
+; WIN32-NEXT:    subl $16, %esp
+; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %esi
 ; WIN32-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
 ; WIN32-NEXT:    movl %eax, (%esp)
-; WIN32-NEXT:    cmpl $381, %edi # imm = 0x17D
-; WIN32-NEXT:    movl %edi, %esi
-; WIN32-NEXT:    jl LBB6_2
-; WIN32-NEXT:  # %bb.1:
-; WIN32-NEXT:    movl $381, %esi # imm = 0x17D
-; WIN32-NEXT:  LBB6_2:
-; WIN32-NEXT:    addl $-254, %esi
 ; WIN32-NEXT:    calll ___gnu_h2f_ieee
-; WIN32-NEXT:    leal -127(%edi), %eax
-; WIN32-NEXT:    cmpl $255, %edi
-; WIN32-NEXT:    jae LBB6_4
-; WIN32-NEXT:  # %bb.3:
-; WIN32-NEXT:    movl %eax, %esi
-; WIN32-NEXT:  LBB6_4:
-; WIN32-NEXT:    flds __real at 7f000000
-; WIN32-NEXT:    fld %st(1)
-; WIN32-NEXT:    fmul %st(1), %st
-; WIN32-NEXT:    fmul %st, %st(1)
-; WIN32-NEXT:    jae LBB6_6
-; WIN32-NEXT:  # %bb.5:
-; WIN32-NEXT:    fstp %st(1)
-; WIN32-NEXT:    fldz
-; WIN32-NEXT:  LBB6_6:
-; WIN32-NEXT:    fstp %st(0)
-; WIN32-NEXT:    cmpl $-329, %edi # imm = 0xFEB7
-; WIN32-NEXT:    movl %edi, %eax
-; WIN32-NEXT:    jge LBB6_8
-; WIN32-NEXT:  # %bb.7:
-; WIN32-NEXT:    movl $-330, %eax # imm = 0xFEB6
-; WIN32-NEXT:  LBB6_8:
-; WIN32-NEXT:    flds __real at 0c800000
-; WIN32-NEXT:    fld %st(2)
-; WIN32-NEXT:    fmul %st(1), %st
-; WIN32-NEXT:    fmul %st, %st(1)
-; WIN32-NEXT:    cmpl $-228, %edi
-; WIN32-NEXT:    jb LBB6_9
-; WIN32-NEXT:  # %bb.10:
-; WIN32-NEXT:    fstp %st(1)
-; WIN32-NEXT:    leal 102(%edi), %eax
-; WIN32-NEXT:    cmpl $-126, %edi
-; WIN32-NEXT:    jge LBB6_12
-; WIN32-NEXT:    jmp LBB6_13
-; WIN32-NEXT:  LBB6_9:
-; WIN32-NEXT:    fstp %st(0)
-; WIN32-NEXT:    addl $204, %eax
-; WIN32-NEXT:    cmpl $-126, %edi
-; WIN32-NEXT:    jl LBB6_13
-; WIN32-NEXT:  LBB6_12:
-; WIN32-NEXT:    fstp %st(0)
-; WIN32-NEXT:    movl %edi, %eax
-; WIN32-NEXT:    fldz
-; WIN32-NEXT:    fxch %st(2)
-; WIN32-NEXT:  LBB6_13:
-; WIN32-NEXT:    fstp %st(2)
-; WIN32-NEXT:    cmpl $127, %edi
-; WIN32-NEXT:    jg LBB6_15
-; WIN32-NEXT:  # %bb.14:
-; WIN32-NEXT:    fstp %st(0)
-; WIN32-NEXT:    movl %eax, %esi
-; WIN32-NEXT:    fldz
-; WIN32-NEXT:    fxch %st(1)
-; WIN32-NEXT:  LBB6_15:
-; WIN32-NEXT:    fstp %st(1)
-; WIN32-NEXT:    shll $23, %esi
-; WIN32-NEXT:    addl $1065353216, %esi # imm = 0x3F800000
 ; WIN32-NEXT:    movl %esi, {{[0-9]+}}(%esp)
-; WIN32-NEXT:    fmuls {{[0-9]+}}(%esp)
+; WIN32-NEXT:    fstpl (%esp)
+; WIN32-NEXT:    calll _ldexp
+; WIN32-NEXT:    fstps {{[0-9]+}}(%esp)
+; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
 ; WIN32-NEXT:    fstps (%esp)
 ; WIN32-NEXT:    calll ___gnu_f2h_ieee
-; WIN32-NEXT:    addl $8, %esp
+; WIN32-NEXT:    addl $16, %esp
 ; WIN32-NEXT:    popl %esi
-; WIN32-NEXT:    popl %edi
 ; WIN32-NEXT:    retl
   %ldexp = call half @llvm.ldexp.f16.i32(half %arg0, i32 %arg1)
   ret half %ldexp

diff  --git a/llvm/test/CodeGen/X86/llvm.frexp.ll b/llvm/test/CodeGen/X86/llvm.frexp.ll
index d6038cebd4582..cd560ad627de4 100644
--- a/llvm/test/CodeGen/X86/llvm.frexp.ll
+++ b/llvm/test/CodeGen/X86/llvm.frexp.ll
@@ -42,55 +42,21 @@ define { half, i32 } @test_frexp_f16_i32(half %a) {
 ; WIN32-LABEL: test_frexp_f16_i32:
 ; WIN32:       # %bb.0:
 ; WIN32-NEXT:    pushl %esi
-; WIN32-NEXT:    subl $16, %esp
+; WIN32-NEXT:    subl $20, %esp
 ; WIN32-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
 ; WIN32-NEXT:    movl %eax, (%esp)
 ; WIN32-NEXT:    calll ___gnu_h2f_ieee
-; WIN32-NEXT:    fld %st(0)
-; WIN32-NEXT:    fmuls __real at 4c000000
+; WIN32-NEXT:    leal {{[0-9]+}}(%esp), %eax
+; WIN32-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; WIN32-NEXT:    fstpl (%esp)
+; WIN32-NEXT:    calll _frexp
 ; WIN32-NEXT:    fstps {{[0-9]+}}(%esp)
-; WIN32-NEXT:    fsts {{[0-9]+}}(%esp)
-; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %edx
-; WIN32-NEXT:    movl %edx, %ecx
-; WIN32-NEXT:    andl $2147483647, %ecx # imm = 0x7FFFFFFF
-; WIN32-NEXT:    cmpl $8388608, %ecx # imm = 0x800000
-; WIN32-NEXT:    jb LBB0_1
-; WIN32-NEXT:  # %bb.2:
-; WIN32-NEXT:    movl %ecx, %eax
-; WIN32-NEXT:    jmp LBB0_3
-; WIN32-NEXT:  LBB0_1:
-; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %edx
-; WIN32-NEXT:    movl %edx, %eax
-; WIN32-NEXT:    andl $2139095040, %eax # imm = 0x7F800000
-; WIN32-NEXT:  LBB0_3:
-; WIN32-NEXT:    shrl $23, %eax
-; WIN32-NEXT:    cmpl $8388608, %ecx # imm = 0x800000
-; WIN32-NEXT:    jae LBB0_5
-; WIN32-NEXT:  # %bb.4:
-; WIN32-NEXT:    addl $-25, %eax
-; WIN32-NEXT:  LBB0_5:
-; WIN32-NEXT:    andl $-2139095041, %edx # imm = 0x807FFFFF
-; WIN32-NEXT:    orl $1056964608, %edx # imm = 0x3F000000
-; WIN32-NEXT:    movl %edx, {{[0-9]+}}(%esp)
-; WIN32-NEXT:    addl $-126, %eax
-; WIN32-NEXT:    addl $-2139095040, %ecx # imm = 0x80800000
 ; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
-; WIN32-NEXT:    xorl %esi, %esi
-; WIN32-NEXT:    cmpl $-2139095040, %ecx # imm = 0x80800000
-; WIN32-NEXT:    jbe LBB0_7
-; WIN32-NEXT:  # %bb.6:
-; WIN32-NEXT:    fstp %st(1)
-; WIN32-NEXT:    fldz
-; WIN32-NEXT:  LBB0_7:
-; WIN32-NEXT:    fstp %st(0)
 ; WIN32-NEXT:    fstps (%esp)
-; WIN32-NEXT:    jbe LBB0_9
-; WIN32-NEXT:  # %bb.8:
-; WIN32-NEXT:    movl %eax, %esi
-; WIN32-NEXT:  LBB0_9:
+; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %esi
 ; WIN32-NEXT:    calll ___gnu_f2h_ieee
 ; WIN32-NEXT:    movl %esi, %edx
-; WIN32-NEXT:    addl $16, %esp
+; WIN32-NEXT:    addl $20, %esp
 ; WIN32-NEXT:    popl %esi
 ; WIN32-NEXT:    retl
   %result = call { half, i32 } @llvm.frexp.f16.i32(half %a)
@@ -126,37 +92,19 @@ define half @test_frexp_f16_i32_only_use_fract(half %a) {
 ;
 ; WIN32-LABEL: test_frexp_f16_i32_only_use_fract:
 ; WIN32:       # %bb.0:
-; WIN32-NEXT:    subl $16, %esp
+; WIN32-NEXT:    subl $20, %esp
 ; WIN32-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
 ; WIN32-NEXT:    movl %eax, (%esp)
 ; WIN32-NEXT:    calll ___gnu_h2f_ieee
-; WIN32-NEXT:    fsts {{[0-9]+}}(%esp)
-; WIN32-NEXT:    fld %st(0)
-; WIN32-NEXT:    fmuls __real at 4c000000
+; WIN32-NEXT:    leal {{[0-9]+}}(%esp), %eax
+; WIN32-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; WIN32-NEXT:    fstpl (%esp)
+; WIN32-NEXT:    calll _frexp
 ; WIN32-NEXT:    fstps {{[0-9]+}}(%esp)
-; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; WIN32-NEXT:    movl %ecx, %eax
-; WIN32-NEXT:    andl $2147483647, %eax # imm = 0x7FFFFFFF
-; WIN32-NEXT:    cmpl $8388608, %eax # imm = 0x800000
-; WIN32-NEXT:    jae LBB1_2
-; WIN32-NEXT:  # %bb.1:
-; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; WIN32-NEXT:  LBB1_2:
-; WIN32-NEXT:    andl $-2139095041, %ecx # imm = 0x807FFFFF
-; WIN32-NEXT:    orl $1056964608, %ecx # imm = 0x3F000000
-; WIN32-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
-; WIN32-NEXT:    addl $-2139095040, %eax # imm = 0x80800000
 ; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
-; WIN32-NEXT:    cmpl $-2139095040, %eax # imm = 0x80800000
-; WIN32-NEXT:    jbe LBB1_4
-; WIN32-NEXT:  # %bb.3:
-; WIN32-NEXT:    fstp %st(1)
-; WIN32-NEXT:    fldz
-; WIN32-NEXT:  LBB1_4:
-; WIN32-NEXT:    fstp %st(0)
 ; WIN32-NEXT:    fstps (%esp)
 ; WIN32-NEXT:    calll ___gnu_f2h_ieee
-; WIN32-NEXT:    addl $16, %esp
+; WIN32-NEXT:    addl $20, %esp
 ; WIN32-NEXT:    retl
   %result = call { half, i32 } @llvm.frexp.f16.i32(half %a)
   %result.0 = extractvalue { half, i32 } %result, 0
@@ -195,41 +143,17 @@ define i32 @test_frexp_f16_i32_only_use_exp(half %a) {
 ;
 ; WIN32-LABEL: test_frexp_f16_i32_only_use_exp:
 ; WIN32:       # %bb.0:
-; WIN32-NEXT:    subl $8, %esp
+; WIN32-NEXT:    subl $16, %esp
 ; WIN32-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
-; WIN32-NEXT:    pushl %eax
+; WIN32-NEXT:    movl %eax, (%esp)
 ; WIN32-NEXT:    calll ___gnu_h2f_ieee
-; WIN32-NEXT:    addl $4, %esp
-; WIN32-NEXT:    fld %st(0)
-; WIN32-NEXT:    fmuls __real at 4c000000
-; WIN32-NEXT:    fstps {{[0-9]+}}(%esp)
-; WIN32-NEXT:    fstps (%esp)
-; WIN32-NEXT:    movl $2147483647, %ecx # imm = 0x7FFFFFFF
-; WIN32-NEXT:    andl (%esp), %ecx
-; WIN32-NEXT:    cmpl $8388608, %ecx # imm = 0x800000
-; WIN32-NEXT:    jb LBB2_1
-; WIN32-NEXT:  # %bb.2:
-; WIN32-NEXT:    movl %ecx, %edx
-; WIN32-NEXT:    jmp LBB2_3
-; WIN32-NEXT:  LBB2_1:
-; WIN32-NEXT:    movl $2139095040, %edx # imm = 0x7F800000
-; WIN32-NEXT:    andl {{[0-9]+}}(%esp), %edx
-; WIN32-NEXT:  LBB2_3:
-; WIN32-NEXT:    shrl $23, %edx
-; WIN32-NEXT:    cmpl $8388608, %ecx # imm = 0x800000
-; WIN32-NEXT:    jae LBB2_5
-; WIN32-NEXT:  # %bb.4:
-; WIN32-NEXT:    addl $-25, %edx
-; WIN32-NEXT:  LBB2_5:
-; WIN32-NEXT:    addl $-2139095040, %ecx # imm = 0x80800000
-; WIN32-NEXT:    xorl %eax, %eax
-; WIN32-NEXT:    cmpl $-2139095040, %ecx # imm = 0x80800000
-; WIN32-NEXT:    jbe LBB2_7
-; WIN32-NEXT:  # %bb.6:
-; WIN32-NEXT:    addl $-126, %edx
-; WIN32-NEXT:    movl %edx, %eax
-; WIN32-NEXT:  LBB2_7:
-; WIN32-NEXT:    addl $8, %esp
+; WIN32-NEXT:    leal {{[0-9]+}}(%esp), %eax
+; WIN32-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; WIN32-NEXT:    fstpl (%esp)
+; WIN32-NEXT:    calll _frexp
+; WIN32-NEXT:    fstp %st(0)
+; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; WIN32-NEXT:    addl $16, %esp
 ; WIN32-NEXT:    retl
   %result = call { half, i32 } @llvm.frexp.f16.i32(half %a)
   %result.0 = extractvalue { half, i32 } %result, 1
@@ -268,50 +192,16 @@ define { float, i32 } @test_frexp_f32_i32(float %a) {
 ;
 ; WIN32-LABEL: test_frexp_f32_i32:
 ; WIN32:       # %bb.0:
-; WIN32-NEXT:    subl $12, %esp
+; WIN32-NEXT:    subl $20, %esp
+; WIN32-NEXT:    leal {{[0-9]+}}(%esp), %eax
+; WIN32-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
-; WIN32-NEXT:    fld %st(0)
-; WIN32-NEXT:    fmuls __real at 4c000000
+; WIN32-NEXT:    fstpl (%esp)
+; WIN32-NEXT:    calll _frexp
 ; WIN32-NEXT:    fstps {{[0-9]+}}(%esp)
-; WIN32-NEXT:    fsts (%esp)
-; WIN32-NEXT:    movl (%esp), %eax
-; WIN32-NEXT:    movl %eax, %ecx
-; WIN32-NEXT:    andl $2147483647, %ecx # imm = 0x7FFFFFFF
-; WIN32-NEXT:    cmpl $8388608, %ecx # imm = 0x800000
-; WIN32-NEXT:    jb LBB3_1
-; WIN32-NEXT:  # %bb.2:
-; WIN32-NEXT:    movl %ecx, %edx
-; WIN32-NEXT:    jmp LBB3_3
-; WIN32-NEXT:  LBB3_1:
 ; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; WIN32-NEXT:    movl %eax, %edx
-; WIN32-NEXT:    andl $2139095040, %edx # imm = 0x7F800000
-; WIN32-NEXT:  LBB3_3:
-; WIN32-NEXT:    shrl $23, %edx
-; WIN32-NEXT:    cmpl $8388608, %ecx # imm = 0x800000
-; WIN32-NEXT:    jae LBB3_5
-; WIN32-NEXT:  # %bb.4:
-; WIN32-NEXT:    addl $-25, %edx
-; WIN32-NEXT:  LBB3_5:
-; WIN32-NEXT:    andl $-2139095041, %eax # imm = 0x807FFFFF
-; WIN32-NEXT:    orl $1056964608, %eax # imm = 0x3F000000
-; WIN32-NEXT:    movl %eax, {{[0-9]+}}(%esp)
-; WIN32-NEXT:    addl $-126, %edx
-; WIN32-NEXT:    addl $-2139095040, %ecx # imm = 0x80800000
-; WIN32-NEXT:    xorl %eax, %eax
-; WIN32-NEXT:    cmpl $-2139095040, %ecx # imm = 0x80800000
-; WIN32-NEXT:    jbe LBB3_7
-; WIN32-NEXT:  # %bb.6:
-; WIN32-NEXT:    movl %edx, %eax
-; WIN32-NEXT:  LBB3_7:
 ; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
-; WIN32-NEXT:    jbe LBB3_9
-; WIN32-NEXT:  # %bb.8:
-; WIN32-NEXT:    fstp %st(1)
-; WIN32-NEXT:    fldz
-; WIN32-NEXT:  LBB3_9:
-; WIN32-NEXT:    fstp %st(0)
-; WIN32-NEXT:    addl $12, %esp
+; WIN32-NEXT:    addl $20, %esp
 ; WIN32-NEXT:    retl
   %result = call { float, i32 } @llvm.frexp.f32.i32(float %a)
   ret { float, i32 } %result
@@ -330,33 +220,15 @@ define float @test_frexp_f32_i32_only_use_fract(float %a) {
 ;
 ; WIN32-LABEL: test_frexp_f32_i32_only_use_fract:
 ; WIN32:       # %bb.0:
-; WIN32-NEXT:    subl $12, %esp
+; WIN32-NEXT:    subl $20, %esp
+; WIN32-NEXT:    leal {{[0-9]+}}(%esp), %eax
+; WIN32-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
-; WIN32-NEXT:    fsts (%esp)
-; WIN32-NEXT:    fld %st(0)
-; WIN32-NEXT:    fmuls __real at 4c000000
+; WIN32-NEXT:    fstpl (%esp)
+; WIN32-NEXT:    calll _frexp
 ; WIN32-NEXT:    fstps {{[0-9]+}}(%esp)
-; WIN32-NEXT:    movl (%esp), %ecx
-; WIN32-NEXT:    movl %ecx, %eax
-; WIN32-NEXT:    andl $2147483647, %eax # imm = 0x7FFFFFFF
-; WIN32-NEXT:    cmpl $8388608, %eax # imm = 0x800000
-; WIN32-NEXT:    jae LBB4_2
-; WIN32-NEXT:  # %bb.1:
-; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; WIN32-NEXT:  LBB4_2:
-; WIN32-NEXT:    andl $-2139095041, %ecx # imm = 0x807FFFFF
-; WIN32-NEXT:    orl $1056964608, %ecx # imm = 0x3F000000
-; WIN32-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
-; WIN32-NEXT:    addl $-2139095040, %eax # imm = 0x80800000
 ; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
-; WIN32-NEXT:    cmpl $-2139095040, %eax # imm = 0x80800000
-; WIN32-NEXT:    jbe LBB4_4
-; WIN32-NEXT:  # %bb.3:
-; WIN32-NEXT:    fstp %st(1)
-; WIN32-NEXT:    fldz
-; WIN32-NEXT:  LBB4_4:
-; WIN32-NEXT:    fstp %st(0)
-; WIN32-NEXT:    addl $12, %esp
+; WIN32-NEXT:    addl $20, %esp
 ; WIN32-NEXT:    retl
   %result = call { float, i32 } @llvm.frexp.f32.i32(float %a)
   %result.0 = extractvalue { float, i32 } %result, 0
@@ -377,38 +249,15 @@ define i32 @test_frexp_f32_i32_only_use_exp(float %a) {
 ;
 ; WIN32-LABEL: test_frexp_f32_i32_only_use_exp:
 ; WIN32:       # %bb.0:
-; WIN32-NEXT:    subl $8, %esp
+; WIN32-NEXT:    subl $16, %esp
+; WIN32-NEXT:    leal {{[0-9]+}}(%esp), %eax
+; WIN32-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
-; WIN32-NEXT:    fld %st(0)
-; WIN32-NEXT:    fmuls __real at 4c000000
-; WIN32-NEXT:    fstps {{[0-9]+}}(%esp)
-; WIN32-NEXT:    fstps (%esp)
-; WIN32-NEXT:    movl $2147483647, %ecx # imm = 0x7FFFFFFF
-; WIN32-NEXT:    andl (%esp), %ecx
-; WIN32-NEXT:    cmpl $8388608, %ecx # imm = 0x800000
-; WIN32-NEXT:    jb LBB5_1
-; WIN32-NEXT:  # %bb.2:
-; WIN32-NEXT:    movl %ecx, %edx
-; WIN32-NEXT:    jmp LBB5_3
-; WIN32-NEXT:  LBB5_1:
-; WIN32-NEXT:    movl $2139095040, %edx # imm = 0x7F800000
-; WIN32-NEXT:    andl {{[0-9]+}}(%esp), %edx
-; WIN32-NEXT:  LBB5_3:
-; WIN32-NEXT:    shrl $23, %edx
-; WIN32-NEXT:    cmpl $8388608, %ecx # imm = 0x800000
-; WIN32-NEXT:    jae LBB5_5
-; WIN32-NEXT:  # %bb.4:
-; WIN32-NEXT:    addl $-25, %edx
-; WIN32-NEXT:  LBB5_5:
-; WIN32-NEXT:    addl $-2139095040, %ecx # imm = 0x80800000
-; WIN32-NEXT:    xorl %eax, %eax
-; WIN32-NEXT:    cmpl $-2139095040, %ecx # imm = 0x80800000
-; WIN32-NEXT:    jbe LBB5_7
-; WIN32-NEXT:  # %bb.6:
-; WIN32-NEXT:    addl $-126, %edx
-; WIN32-NEXT:    movl %edx, %eax
-; WIN32-NEXT:  LBB5_7:
-; WIN32-NEXT:    addl $8, %esp
+; WIN32-NEXT:    fstpl (%esp)
+; WIN32-NEXT:    calll _frexp
+; WIN32-NEXT:    fstp %st(0)
+; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; WIN32-NEXT:    addl $16, %esp
 ; WIN32-NEXT:    retl
   %result = call { float, i32 } @llvm.frexp.f32.i32(float %a)
   %result.0 = extractvalue { float, i32 } %result, 1
@@ -476,206 +325,58 @@ define { <4 x float>, <4 x i32> } @test_frexp_v4f32_v4i32(<4 x float> %a) {
 ;
 ; WIN32-LABEL: test_frexp_v4f32_v4i32:
 ; WIN32:       # %bb.0:
-; WIN32-NEXT:    pushl %ebp
-; WIN32-NEXT:    pushl %ebx
 ; WIN32-NEXT:    pushl %edi
 ; WIN32-NEXT:    pushl %esi
-; WIN32-NEXT:    subl $68, %esp
+; WIN32-NEXT:    subl $60, %esp
+; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %esi
+; WIN32-NEXT:    leal {{[0-9]+}}(%esp), %eax
+; WIN32-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
-; WIN32-NEXT:    flds __real at 4c000000
-; WIN32-NEXT:    fld %st(1)
-; WIN32-NEXT:    fmul %st(1), %st
-; WIN32-NEXT:    fstps {{[0-9]+}}(%esp)
-; WIN32-NEXT:    fxch %st(1)
-; WIN32-NEXT:    fsts {{[0-9]+}}(%esp)
-; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %ebx
-; WIN32-NEXT:    movl %ebx, %eax
-; WIN32-NEXT:    andl $2147483647, %eax # imm = 0x7FFFFFFF
-; WIN32-NEXT:    cmpl $8388608, %eax # imm = 0x800000
-; WIN32-NEXT:    jb LBB6_1
-; WIN32-NEXT:  # %bb.2:
-; WIN32-NEXT:    movl %eax, %ecx
-; WIN32-NEXT:    jmp LBB6_3
-; WIN32-NEXT:  LBB6_1:
-; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %ebx
-; WIN32-NEXT:    movl %ebx, %ecx
-; WIN32-NEXT:    andl $2139095040, %ecx # imm = 0x7F800000
-; WIN32-NEXT:  LBB6_3:
-; WIN32-NEXT:    shrl $23, %ecx
-; WIN32-NEXT:    cmpl $8388608, %eax # imm = 0x800000
+; WIN32-NEXT:    fstpl (%esp)
+; WIN32-NEXT:    calll _frexp
+; WIN32-NEXT:    fstpl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Spill
+; WIN32-NEXT:    leal {{[0-9]+}}(%esp), %eax
+; WIN32-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
-; WIN32-NEXT:    fld %st(0)
-; WIN32-NEXT:    fmul %st(3), %st
-; WIN32-NEXT:    fstps {{[0-9]+}}(%esp)
-; WIN32-NEXT:    fsts {{[0-9]+}}(%esp)
-; WIN32-NEXT:    jae LBB6_5
-; WIN32-NEXT:  # %bb.4:
-; WIN32-NEXT:    addl $-25, %ecx
-; WIN32-NEXT:  LBB6_5:
-; WIN32-NEXT:    movl %ecx, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill
-; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; WIN32-NEXT:    movl %ecx, %edx
-; WIN32-NEXT:    andl $2147483647, %edx # imm = 0x7FFFFFFF
-; WIN32-NEXT:    cmpl $8388608, %edx # imm = 0x800000
-; WIN32-NEXT:    jb LBB6_6
-; WIN32-NEXT:  # %bb.7:
-; WIN32-NEXT:    movl %edx, %esi
-; WIN32-NEXT:    jmp LBB6_8
-; WIN32-NEXT:  LBB6_6:
-; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; WIN32-NEXT:    movl %ecx, %esi
-; WIN32-NEXT:    andl $2139095040, %esi # imm = 0x7F800000
-; WIN32-NEXT:  LBB6_8:
-; WIN32-NEXT:    shrl $23, %esi
-; WIN32-NEXT:    cmpl $8388608, %edx # imm = 0x800000
+; WIN32-NEXT:    fstpl (%esp)
+; WIN32-NEXT:    calll _frexp
+; WIN32-NEXT:    fstpl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Spill
+; WIN32-NEXT:    leal {{[0-9]+}}(%esp), %eax
+; WIN32-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
-; WIN32-NEXT:    fld %st(0)
-; WIN32-NEXT:    fmul %st(4), %st
-; WIN32-NEXT:    fstps {{[0-9]+}}(%esp)
-; WIN32-NEXT:    fsts {{[0-9]+}}(%esp)
-; WIN32-NEXT:    jae LBB6_10
-; WIN32-NEXT:  # %bb.9:
-; WIN32-NEXT:    addl $-25, %esi
-; WIN32-NEXT:  LBB6_10:
-; WIN32-NEXT:    movl %esi, (%esp) # 4-byte Spill
-; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %edi
-; WIN32-NEXT:    movl %edi, %ebp
-; WIN32-NEXT:    andl $2147483647, %ebp # imm = 0x7FFFFFFF
-; WIN32-NEXT:    cmpl $8388608, %ebp # imm = 0x800000
-; WIN32-NEXT:    jb LBB6_11
-; WIN32-NEXT:  # %bb.12:
-; WIN32-NEXT:    movl %ebp, %esi
-; WIN32-NEXT:    jmp LBB6_13
-; WIN32-NEXT:  LBB6_11:
-; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %edi
-; WIN32-NEXT:    movl %edi, %esi
-; WIN32-NEXT:    andl $2139095040, %esi # imm = 0x7F800000
-; WIN32-NEXT:  LBB6_13:
-; WIN32-NEXT:    shrl $23, %esi
-; WIN32-NEXT:    cmpl $8388608, %ebp # imm = 0x800000
+; WIN32-NEXT:    fstpl (%esp)
+; WIN32-NEXT:    calll _frexp
+; WIN32-NEXT:    leal {{[0-9]+}}(%esp), %eax
+; WIN32-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
-; WIN32-NEXT:    fmul %st, %st(4)
-; WIN32-NEXT:    fxch %st(4)
+; WIN32-NEXT:    fstpl (%esp)
+; WIN32-NEXT:    fstps {{[0-9]+}}(%esp)
+; WIN32-NEXT:    fldl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Reload
+; WIN32-NEXT:    fstps {{[0-9]+}}(%esp)
+; WIN32-NEXT:    fldl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Reload
+; WIN32-NEXT:    fstps {{[0-9]+}}(%esp)
+; WIN32-NEXT:    calll _frexp
 ; WIN32-NEXT:    fstps {{[0-9]+}}(%esp)
-; WIN32-NEXT:    fxch %st(3)
-; WIN32-NEXT:    fsts {{[0-9]+}}(%esp)
-; WIN32-NEXT:    movl %eax, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill
-; WIN32-NEXT:    movl %edx, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill
-; WIN32-NEXT:    jae LBB6_15
-; WIN32-NEXT:  # %bb.14:
-; WIN32-NEXT:    addl $-25, %esi
-; WIN32-NEXT:  LBB6_15:
-; WIN32-NEXT:    movl %esi, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill
-; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; WIN32-NEXT:    movl %eax, %edx
-; WIN32-NEXT:    andl $2147483647, %edx # imm = 0x7FFFFFFF
-; WIN32-NEXT:    cmpl $8388608, %edx # imm = 0x800000
-; WIN32-NEXT:    jb LBB6_16
-; WIN32-NEXT:  # %bb.17:
-; WIN32-NEXT:    movl %edx, %esi
-; WIN32-NEXT:    jmp LBB6_18
-; WIN32-NEXT:  LBB6_16:
-; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; WIN32-NEXT:    movl %eax, %esi
-; WIN32-NEXT:    andl $2139095040, %esi # imm = 0x7F800000
-; WIN32-NEXT:  LBB6_18:
-; WIN32-NEXT:    shrl $23, %esi
-; WIN32-NEXT:    cmpl $8388608, %edx # imm = 0x800000
-; WIN32-NEXT:    jae LBB6_20
-; WIN32-NEXT:  # %bb.19:
-; WIN32-NEXT:    addl $-25, %esi
-; WIN32-NEXT:  LBB6_20:
-; WIN32-NEXT:    andl $-2139095041, %eax # imm = 0x807FFFFF
-; WIN32-NEXT:    orl $1056964608, %eax # imm = 0x3F000000
-; WIN32-NEXT:    movl %eax, {{[0-9]+}}(%esp)
-; WIN32-NEXT:    andl $-2139095041, %ebx # imm = 0x807FFFFF
-; WIN32-NEXT:    orl $1056964608, %ebx # imm = 0x3F000000
-; WIN32-NEXT:    movl %ebx, {{[0-9]+}}(%esp)
-; WIN32-NEXT:    andl $-2139095041, %ecx # imm = 0x807FFFFF
-; WIN32-NEXT:    orl $1056964608, %ecx # imm = 0x3F000000
-; WIN32-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
-; WIN32-NEXT:    andl $-2139095041, %edi # imm = 0x807FFFFF
-; WIN32-NEXT:    orl $1056964608, %edi # imm = 0x3F000000
-; WIN32-NEXT:    movl %edi, {{[0-9]+}}(%esp)
-; WIN32-NEXT:    addl $-126, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Folded Spill
-; WIN32-NEXT:    addl $-126, (%esp) # 4-byte Folded Spill
-; WIN32-NEXT:    movl {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 4-byte Reload
-; WIN32-NEXT:    addl $-126, %ecx
-; WIN32-NEXT:    addl $-126, %esi
-; WIN32-NEXT:    addl $-2139095040, %edx # imm = 0x80800000
-; WIN32-NEXT:    xorl %edi, %edi
-; WIN32-NEXT:    cmpl $-2139095040, %edx # imm = 0x80800000
-; WIN32-NEXT:    movl $0, %ebx
-; WIN32-NEXT:    jbe LBB6_22
-; WIN32-NEXT:  # %bb.21:
-; WIN32-NEXT:    movl %esi, %ebx
-; WIN32-NEXT:  LBB6_22:
 ; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
-; WIN32-NEXT:    movl {{[-0-9]+}}(%e{{[sb]}}p), %eax # 4-byte Reload
-; WIN32-NEXT:    jbe LBB6_24
-; WIN32-NEXT:  # %bb.23:
-; WIN32-NEXT:    fstp %st(1)
-; WIN32-NEXT:    fldz
-; WIN32-NEXT:  LBB6_24:
-; WIN32-NEXT:    fstp %st(0)
-; WIN32-NEXT:    addl $-2139095040, %eax # imm = 0x80800000
-; WIN32-NEXT:    cmpl $-2139095040, %eax # imm = 0x80800000
-; WIN32-NEXT:    movl $0, %edx
-; WIN32-NEXT:    movl {{[-0-9]+}}(%e{{[sb]}}p), %esi # 4-byte Reload
-; WIN32-NEXT:    jbe LBB6_26
-; WIN32-NEXT:  # %bb.25:
-; WIN32-NEXT:    movl %ecx, %edx
-; WIN32-NEXT:  LBB6_26:
 ; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
-; WIN32-NEXT:    jbe LBB6_28
-; WIN32-NEXT:  # %bb.27:
-; WIN32-NEXT:    fstp %st(3)
-; WIN32-NEXT:    fldz
-; WIN32-NEXT:  LBB6_28:
-; WIN32-NEXT:    fstp %st(0)
-; WIN32-NEXT:    movl {{[-0-9]+}}(%e{{[sb]}}p), %eax # 4-byte Reload
-; WIN32-NEXT:    addl $-2139095040, %eax # imm = 0x80800000
-; WIN32-NEXT:    cmpl $-2139095040, %eax # imm = 0x80800000
-; WIN32-NEXT:    movl $0, %ecx
-; WIN32-NEXT:    jbe LBB6_30
-; WIN32-NEXT:  # %bb.29:
-; WIN32-NEXT:    movl (%esp), %ecx # 4-byte Reload
-; WIN32-NEXT:  LBB6_30:
 ; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
-; WIN32-NEXT:    jbe LBB6_32
-; WIN32-NEXT:  # %bb.31:
-; WIN32-NEXT:    fstp %st(2)
-; WIN32-NEXT:    fldz
-; WIN32-NEXT:  LBB6_32:
-; WIN32-NEXT:    fstp %st(0)
-; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; WIN32-NEXT:    addl $-2139095040, %ebp # imm = 0x80800000
-; WIN32-NEXT:    cmpl $-2139095040, %ebp # imm = 0x80800000
-; WIN32-NEXT:    jbe LBB6_34
-; WIN32-NEXT:  # %bb.33:
-; WIN32-NEXT:    movl %esi, %edi
-; WIN32-NEXT:  LBB6_34:
 ; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
-; WIN32-NEXT:    jbe LBB6_36
-; WIN32-NEXT:  # %bb.35:
-; WIN32-NEXT:    fstp %st(4)
-; WIN32-NEXT:    fldz
-; WIN32-NEXT:  LBB6_36:
-; WIN32-NEXT:    fstp %st(0)
-; WIN32-NEXT:    movl %edi, 28(%eax)
-; WIN32-NEXT:    movl %ecx, 24(%eax)
-; WIN32-NEXT:    movl %edx, 20(%eax)
-; WIN32-NEXT:    movl %ebx, 16(%eax)
-; WIN32-NEXT:    fxch %st(3)
-; WIN32-NEXT:    fstps 12(%eax)
-; WIN32-NEXT:    fstps 8(%eax)
-; WIN32-NEXT:    fstps 4(%eax)
-; WIN32-NEXT:    fstps (%eax)
-; WIN32-NEXT:    addl $68, %esp
+; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %edx
+; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %edi
+; WIN32-NEXT:    movl %edi, 28(%esi)
+; WIN32-NEXT:    movl %edx, 24(%esi)
+; WIN32-NEXT:    movl %ecx, 20(%esi)
+; WIN32-NEXT:    movl %eax, 16(%esi)
+; WIN32-NEXT:    fstps 12(%esi)
+; WIN32-NEXT:    fstps 8(%esi)
+; WIN32-NEXT:    fstps 4(%esi)
+; WIN32-NEXT:    fstps (%esi)
+; WIN32-NEXT:    movl %esi, %eax
+; WIN32-NEXT:    addl $60, %esp
 ; WIN32-NEXT:    popl %esi
 ; WIN32-NEXT:    popl %edi
-; WIN32-NEXT:    popl %ebx
-; WIN32-NEXT:    popl %ebp
 ; WIN32-NEXT:    retl
   %result = call { <4 x float>, <4 x i32> } @llvm.frexp.v4f32.v4i32(<4 x float> %a)
   ret { <4 x float>, <4 x i32> } %result
@@ -717,123 +418,48 @@ define <4 x float> @test_frexp_v4f32_v4i32_only_use_fract(<4 x float> %a) {
 ;
 ; WIN32-LABEL: test_frexp_v4f32_v4i32_only_use_fract:
 ; WIN32:       # %bb.0:
-; WIN32-NEXT:    pushl %edi
 ; WIN32-NEXT:    pushl %esi
-; WIN32-NEXT:    subl $48, %esp
+; WIN32-NEXT:    subl $60, %esp
+; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %esi
+; WIN32-NEXT:    leal {{[0-9]+}}(%esp), %eax
+; WIN32-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
+; WIN32-NEXT:    fstpl (%esp)
+; WIN32-NEXT:    calll _frexp
+; WIN32-NEXT:    fstpl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Spill
+; WIN32-NEXT:    leal {{[0-9]+}}(%esp), %eax
+; WIN32-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
+; WIN32-NEXT:    fstpl (%esp)
+; WIN32-NEXT:    calll _frexp
+; WIN32-NEXT:    fstpl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Spill
+; WIN32-NEXT:    leal {{[0-9]+}}(%esp), %eax
+; WIN32-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
+; WIN32-NEXT:    fstpl (%esp)
+; WIN32-NEXT:    calll _frexp
+; WIN32-NEXT:    leal {{[0-9]+}}(%esp), %eax
+; WIN32-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
-; WIN32-NEXT:    fsts {{[0-9]+}}(%esp)
-; WIN32-NEXT:    flds __real at 4c000000
-; WIN32-NEXT:    fld %st(1)
-; WIN32-NEXT:    fmul %st(1), %st
+; WIN32-NEXT:    fstpl (%esp)
 ; WIN32-NEXT:    fstps {{[0-9]+}}(%esp)
-; WIN32-NEXT:    fxch %st(2)
-; WIN32-NEXT:    fsts {{[0-9]+}}(%esp)
-; WIN32-NEXT:    fld %st(0)
-; WIN32-NEXT:    fmul %st(3), %st
+; WIN32-NEXT:    fldl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Reload
 ; WIN32-NEXT:    fstps {{[0-9]+}}(%esp)
-; WIN32-NEXT:    fxch %st(3)
-; WIN32-NEXT:    fsts {{[0-9]+}}(%esp)
-; WIN32-NEXT:    fld %st(0)
-; WIN32-NEXT:    fmul %st(3), %st
+; WIN32-NEXT:    fldl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Reload
 ; WIN32-NEXT:    fstps {{[0-9]+}}(%esp)
-; WIN32-NEXT:    fxch %st(4)
-; WIN32-NEXT:    fsts (%esp)
-; WIN32-NEXT:    fmul %st, %st(2)
-; WIN32-NEXT:    fxch %st(2)
+; WIN32-NEXT:    calll _frexp
 ; WIN32-NEXT:    fstps {{[0-9]+}}(%esp)
-; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; WIN32-NEXT:    movl %ecx, %eax
-; WIN32-NEXT:    andl $2147483647, %eax # imm = 0x7FFFFFFF
-; WIN32-NEXT:    cmpl $8388608, %eax # imm = 0x800000
-; WIN32-NEXT:    jae LBB7_2
-; WIN32-NEXT:  # %bb.1:
-; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; WIN32-NEXT:  LBB7_2:
-; WIN32-NEXT:    andl $-2139095041, %ecx # imm = 0x807FFFFF
-; WIN32-NEXT:    orl $1056964608, %ecx # imm = 0x3F000000
-; WIN32-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
-; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %edx
-; WIN32-NEXT:    movl %edx, %ecx
-; WIN32-NEXT:    andl $2147483647, %ecx # imm = 0x7FFFFFFF
-; WIN32-NEXT:    cmpl $8388608, %ecx # imm = 0x800000
-; WIN32-NEXT:    jae LBB7_4
-; WIN32-NEXT:  # %bb.3:
-; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %edx
-; WIN32-NEXT:  LBB7_4:
-; WIN32-NEXT:    andl $-2139095041, %edx # imm = 0x807FFFFF
-; WIN32-NEXT:    orl $1056964608, %edx # imm = 0x3F000000
-; WIN32-NEXT:    movl %edx, {{[0-9]+}}(%esp)
-; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %esi
-; WIN32-NEXT:    movl %esi, %edx
-; WIN32-NEXT:    andl $2147483647, %edx # imm = 0x7FFFFFFF
-; WIN32-NEXT:    cmpl $8388608, %edx # imm = 0x800000
-; WIN32-NEXT:    jae LBB7_6
-; WIN32-NEXT:  # %bb.5:
-; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %esi
-; WIN32-NEXT:  LBB7_6:
-; WIN32-NEXT:    andl $-2139095041, %esi # imm = 0x807FFFFF
-; WIN32-NEXT:    orl $1056964608, %esi # imm = 0x3F000000
-; WIN32-NEXT:    movl %esi, {{[0-9]+}}(%esp)
-; WIN32-NEXT:    movl (%esp), %edi
-; WIN32-NEXT:    movl %edi, %esi
-; WIN32-NEXT:    andl $2147483647, %esi # imm = 0x7FFFFFFF
-; WIN32-NEXT:    cmpl $8388608, %esi # imm = 0x800000
-; WIN32-NEXT:    jae LBB7_8
-; WIN32-NEXT:  # %bb.7:
-; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %edi
-; WIN32-NEXT:  LBB7_8:
-; WIN32-NEXT:    andl $-2139095041, %edi # imm = 0x807FFFFF
-; WIN32-NEXT:    orl $1056964608, %edi # imm = 0x3F000000
-; WIN32-NEXT:    movl %edi, {{[0-9]+}}(%esp)
-; WIN32-NEXT:    addl $-2139095040, %eax # imm = 0x80800000
 ; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
-; WIN32-NEXT:    cmpl $-2139095040, %eax # imm = 0x80800000
-; WIN32-NEXT:    jbe LBB7_10
-; WIN32-NEXT:  # %bb.9:
-; WIN32-NEXT:    fstp %st(1)
-; WIN32-NEXT:    fldz
-; WIN32-NEXT:  LBB7_10:
-; WIN32-NEXT:    fstp %st(0)
-; WIN32-NEXT:    addl $-2139095040, %ecx # imm = 0x80800000
 ; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
-; WIN32-NEXT:    cmpl $-2139095040, %ecx # imm = 0x80800000
-; WIN32-NEXT:    jbe LBB7_12
-; WIN32-NEXT:  # %bb.11:
-; WIN32-NEXT:    fstp %st(3)
-; WIN32-NEXT:    fldz
-; WIN32-NEXT:  LBB7_12:
-; WIN32-NEXT:    fstp %st(0)
-; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; WIN32-NEXT:    addl $-2139095040, %edx # imm = 0x80800000
 ; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
-; WIN32-NEXT:    cmpl $-2139095040, %edx # imm = 0x80800000
-; WIN32-NEXT:    jbe LBB7_14
-; WIN32-NEXT:  # %bb.13:
-; WIN32-NEXT:    fstp %st(4)
-; WIN32-NEXT:    fldz
-; WIN32-NEXT:  LBB7_14:
-; WIN32-NEXT:    fstp %st(0)
-; WIN32-NEXT:    addl $-2139095040, %esi # imm = 0x80800000
 ; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
-; WIN32-NEXT:    cmpl $-2139095040, %esi # imm = 0x80800000
-; WIN32-NEXT:    jbe LBB7_16
-; WIN32-NEXT:  # %bb.15:
-; WIN32-NEXT:    fstp %st(2)
-; WIN32-NEXT:    fldz
-; WIN32-NEXT:  LBB7_16:
-; WIN32-NEXT:    fstp %st(0)
-; WIN32-NEXT:    fxch %st(1)
-; WIN32-NEXT:    fstps 12(%eax)
-; WIN32-NEXT:    fxch %st(2)
-; WIN32-NEXT:    fstps 8(%eax)
-; WIN32-NEXT:    fstps 4(%eax)
-; WIN32-NEXT:    fstps (%eax)
-; WIN32-NEXT:    addl $48, %esp
+; WIN32-NEXT:    fstps 12(%esi)
+; WIN32-NEXT:    fstps 8(%esi)
+; WIN32-NEXT:    fstps 4(%esi)
+; WIN32-NEXT:    fstps (%esi)
+; WIN32-NEXT:    movl %esi, %eax
+; WIN32-NEXT:    addl $60, %esp
 ; WIN32-NEXT:    popl %esi
-; WIN32-NEXT:    popl %edi
 ; WIN32-NEXT:    retl
   %result = call { <4 x float>, <4 x i32> } @llvm.frexp.v4f32.v4i32(<4 x float> %a)
   %result.0 = extractvalue { <4 x float>, <4 x i32> } %result, 0
@@ -873,146 +499,46 @@ define <4 x i32> @test_frexp_v4f32_v4i32_only_use_exp(<4 x float> %a) {
 ;
 ; WIN32-LABEL: test_frexp_v4f32_v4i32_only_use_exp:
 ; WIN32:       # %bb.0:
-; WIN32-NEXT:    pushl %ebp
-; WIN32-NEXT:    pushl %ebx
 ; WIN32-NEXT:    pushl %edi
 ; WIN32-NEXT:    pushl %esi
-; WIN32-NEXT:    subl $36, %esp
-; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
-; WIN32-NEXT:    flds __real at 4c000000
-; WIN32-NEXT:    fld %st(1)
-; WIN32-NEXT:    fmul %st(1), %st
-; WIN32-NEXT:    fstps {{[0-9]+}}(%esp)
-; WIN32-NEXT:    fxch %st(1)
-; WIN32-NEXT:    fstps {{[0-9]+}}(%esp)
-; WIN32-NEXT:    movl $2139095040, %ecx # imm = 0x7F800000
-; WIN32-NEXT:    movl $2147483647, %edx # imm = 0x7FFFFFFF
-; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; WIN32-NEXT:    andl %edx, %eax
-; WIN32-NEXT:    cmpl $8388608, %eax # imm = 0x800000
-; WIN32-NEXT:    jb LBB8_1
-; WIN32-NEXT:  # %bb.2:
-; WIN32-NEXT:    movl %eax, %esi
-; WIN32-NEXT:    jmp LBB8_3
-; WIN32-NEXT:  LBB8_1:
+; WIN32-NEXT:    subl $28, %esp
 ; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %esi
-; WIN32-NEXT:    andl %ecx, %esi
-; WIN32-NEXT:  LBB8_3:
-; WIN32-NEXT:    shrl $23, %esi
-; WIN32-NEXT:    cmpl $8388608, %eax # imm = 0x800000
+; WIN32-NEXT:    leal {{[0-9]+}}(%esp), %eax
+; WIN32-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
-; WIN32-NEXT:    fld %st(0)
-; WIN32-NEXT:    fmul %st(2), %st
-; WIN32-NEXT:    fstps {{[0-9]+}}(%esp)
-; WIN32-NEXT:    fstps {{[0-9]+}}(%esp)
-; WIN32-NEXT:    jae LBB8_5
-; WIN32-NEXT:  # %bb.4:
-; WIN32-NEXT:    addl $-25, %esi
-; WIN32-NEXT:  LBB8_5:
-; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %edi
-; WIN32-NEXT:    andl %edx, %edi
-; WIN32-NEXT:    cmpl $8388608, %edi # imm = 0x800000
-; WIN32-NEXT:    jb LBB8_6
-; WIN32-NEXT:  # %bb.7:
-; WIN32-NEXT:    movl %edi, %ebx
-; WIN32-NEXT:    jmp LBB8_8
-; WIN32-NEXT:  LBB8_6:
-; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %ebx
-; WIN32-NEXT:    andl %ecx, %ebx
-; WIN32-NEXT:  LBB8_8:
-; WIN32-NEXT:    shrl $23, %ebx
-; WIN32-NEXT:    cmpl $8388608, %edi # imm = 0x800000
+; WIN32-NEXT:    fstpl (%esp)
+; WIN32-NEXT:    calll _frexp
+; WIN32-NEXT:    fstp %st(0)
+; WIN32-NEXT:    leal {{[0-9]+}}(%esp), %eax
+; WIN32-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
-; WIN32-NEXT:    fld %st(0)
-; WIN32-NEXT:    fmul %st(2), %st
-; WIN32-NEXT:    fstps {{[0-9]+}}(%esp)
-; WIN32-NEXT:    fstps {{[0-9]+}}(%esp)
-; WIN32-NEXT:    jae LBB8_10
-; WIN32-NEXT:  # %bb.9:
-; WIN32-NEXT:    addl $-25, %ebx
-; WIN32-NEXT:  LBB8_10:
-; WIN32-NEXT:    movl %esi, (%esp) # 4-byte Spill
-; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %ebp
-; WIN32-NEXT:    andl %edx, %ebp
-; WIN32-NEXT:    cmpl $8388608, %ebp # imm = 0x800000
-; WIN32-NEXT:    jb LBB8_11
-; WIN32-NEXT:  # %bb.12:
-; WIN32-NEXT:    movl %ebp, %esi
-; WIN32-NEXT:    jmp LBB8_13
-; WIN32-NEXT:  LBB8_11:
-; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %esi
-; WIN32-NEXT:    andl %ecx, %esi
-; WIN32-NEXT:  LBB8_13:
-; WIN32-NEXT:    shrl $23, %esi
-; WIN32-NEXT:    cmpl $8388608, %ebp # imm = 0x800000
+; WIN32-NEXT:    fstpl (%esp)
+; WIN32-NEXT:    calll _frexp
+; WIN32-NEXT:    fstp %st(0)
+; WIN32-NEXT:    leal {{[0-9]+}}(%esp), %eax
+; WIN32-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
-; WIN32-NEXT:    fmul %st, %st(1)
-; WIN32-NEXT:    fxch %st(1)
-; WIN32-NEXT:    fstps {{[0-9]+}}(%esp)
-; WIN32-NEXT:    fstps {{[0-9]+}}(%esp)
-; WIN32-NEXT:    jae LBB8_15
-; WIN32-NEXT:  # %bb.14:
-; WIN32-NEXT:    addl $-25, %esi
-; WIN32-NEXT:  LBB8_15:
-; WIN32-NEXT:    andl {{[0-9]+}}(%esp), %edx
-; WIN32-NEXT:    cmpl $8388608, %edx # imm = 0x800000
-; WIN32-NEXT:    jb LBB8_16
-; WIN32-NEXT:  # %bb.17:
-; WIN32-NEXT:    movl %edx, %ecx
-; WIN32-NEXT:    jmp LBB8_18
-; WIN32-NEXT:  LBB8_16:
-; WIN32-NEXT:    andl {{[0-9]+}}(%esp), %ecx
-; WIN32-NEXT:  LBB8_18:
-; WIN32-NEXT:    shrl $23, %ecx
-; WIN32-NEXT:    cmpl $8388608, %edx # imm = 0x800000
-; WIN32-NEXT:    jae LBB8_20
-; WIN32-NEXT:  # %bb.19:
-; WIN32-NEXT:    addl $-25, %ecx
-; WIN32-NEXT:  LBB8_20:
-; WIN32-NEXT:    addl $-2139095040, %eax # imm = 0x80800000
-; WIN32-NEXT:    cmpl $-2139095040, %eax # imm = 0x80800000
-; WIN32-NEXT:    movl $0, %eax
-; WIN32-NEXT:    jbe LBB8_22
-; WIN32-NEXT:  # %bb.21:
-; WIN32-NEXT:    movl (%esp), %eax # 4-byte Reload
-; WIN32-NEXT:    addl $-126, %eax
-; WIN32-NEXT:  LBB8_22:
-; WIN32-NEXT:    movl %eax, (%esp) # 4-byte Spill
-; WIN32-NEXT:    addl $-2139095040, %edi # imm = 0x80800000
-; WIN32-NEXT:    cmpl $-2139095040, %edi # imm = 0x80800000
-; WIN32-NEXT:    movl $0, %edi
-; WIN32-NEXT:    jbe LBB8_24
-; WIN32-NEXT:  # %bb.23:
-; WIN32-NEXT:    addl $-126, %ebx
-; WIN32-NEXT:    movl %ebx, %edi
-; WIN32-NEXT:  LBB8_24:
+; WIN32-NEXT:    fstpl (%esp)
+; WIN32-NEXT:    calll _frexp
+; WIN32-NEXT:    fstp %st(0)
+; WIN32-NEXT:    leal {{[0-9]+}}(%esp), %eax
+; WIN32-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
+; WIN32-NEXT:    fstpl (%esp)
+; WIN32-NEXT:    calll _frexp
+; WIN32-NEXT:    fstp %st(0)
 ; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; WIN32-NEXT:    addl $-2139095040, %ebp # imm = 0x80800000
-; WIN32-NEXT:    cmpl $-2139095040, %ebp # imm = 0x80800000
-; WIN32-NEXT:    movl $0, %ebx
-; WIN32-NEXT:    jbe LBB8_26
-; WIN32-NEXT:  # %bb.25:
-; WIN32-NEXT:    addl $-126, %esi
-; WIN32-NEXT:    movl %esi, %ebx
-; WIN32-NEXT:  LBB8_26:
-; WIN32-NEXT:    addl $-2139095040, %edx # imm = 0x80800000
-; WIN32-NEXT:    cmpl $-2139095040, %edx # imm = 0x80800000
-; WIN32-NEXT:    movl $0, %edx
-; WIN32-NEXT:    jbe LBB8_28
-; WIN32-NEXT:  # %bb.27:
-; WIN32-NEXT:    addl $-126, %ecx
-; WIN32-NEXT:    movl %ecx, %edx
-; WIN32-NEXT:  LBB8_28:
-; WIN32-NEXT:    movl %edx, 12(%eax)
-; WIN32-NEXT:    movl %ebx, 8(%eax)
-; WIN32-NEXT:    movl %edi, 4(%eax)
-; WIN32-NEXT:    movl (%esp), %ecx # 4-byte Reload
-; WIN32-NEXT:    movl %ecx, (%eax)
-; WIN32-NEXT:    addl $36, %esp
+; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %edx
+; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %edi
+; WIN32-NEXT:    movl %edi, 12(%esi)
+; WIN32-NEXT:    movl %edx, 8(%esi)
+; WIN32-NEXT:    movl %ecx, 4(%esi)
+; WIN32-NEXT:    movl %eax, (%esi)
+; WIN32-NEXT:    movl %esi, %eax
+; WIN32-NEXT:    addl $28, %esp
 ; WIN32-NEXT:    popl %esi
 ; WIN32-NEXT:    popl %edi
-; WIN32-NEXT:    popl %ebx
-; WIN32-NEXT:    popl %ebp
 ; WIN32-NEXT:    retl
   %result = call { <4 x float>, <4 x i32> } @llvm.frexp.v4f32.v4i32(<4 x float> %a)
   %result.1 = extractvalue { <4 x float>, <4 x i32> } %result, 1


        


More information about the llvm-commits mailing list