[clang] [llvm] [X86] Fix x87 excess precision escaping into f32/f64 values (PR #215104)

Dennis Duda via cfe-commits cfe-commits at lists.llvm.org
Sun Sep 13 15:15:10 PDT 2026


https://github.com/seritools updated https://github.com/llvm/llvm-project/pull/215104

>From 0b13d5a0291d02d2f689c5baa4dbef5c3c3702d3 Mon Sep 17 00:00:00 2001
From: Dennis Duda <git at seri.tools>
Date: Sat, 8 Aug 2026 01:01:51 +0200
Subject: [PATCH 01/15] [X86] Pre-commit tests for x87 f32/f64 rounding

x87 registers are always 80 bits wide and x87 instructions round to the
precision selected by the FPU control word, not to the type of the value
they nominally produce, so an f32/f64 result is not in general a value of
its own type. These checks record the current output before the changes.

Co-authored-by: Claude (Claude-Opus-5) <noreply at anthropic.com>
---
 llvm/test/CodeGen/X86/x87-round-to-type.ll | 500 +++++++++++++++++++++
 1 file changed, 500 insertions(+)
 create mode 100644 llvm/test/CodeGen/X86/x87-round-to-type.ll

diff --git a/llvm/test/CodeGen/X86/x87-round-to-type.ll b/llvm/test/CodeGen/X86/x87-round-to-type.ll
new file mode 100644
index 0000000000000..5e52529fb38ee
--- /dev/null
+++ b/llvm/test/CodeGen/X86/x87-round-to-type.ll
@@ -0,0 +1,500 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=i686-unknown-linux-gnu -mattr=-sse | FileCheck %s --check-prefixes=X87
+
+declare float @llvm.sqrt.f32(float)
+declare double @llvm.sqrt.f64(double)
+declare float @llvm.fabs.f32(float)
+declare float @llvm.experimental.constrained.fadd.f32(float, float, metadata, metadata)
+declare float @llvm.experimental.constrained.sitofp.f32.i32(i32, metadata, metadata)
+declare void @opaque()
+
+; %add has type float, so storing it and reading it back must yield the same value:
+; this has to return 1.
+define i32 @cmp_reload_f32(float %a, float %b, ptr %p) nounwind {
+; X87-LABEL: cmp_reload_f32:
+; X87:       # %bb.0:
+; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
+; X87-NEXT:    fadds {{[0-9]+}}(%esp)
+; X87-NEXT:    fsts (%eax)
+; X87-NEXT:    flds (%eax)
+; X87-NEXT:    fxch %st(1)
+; X87-NEXT:    fucompp
+; X87-NEXT:    fnstsw %ax
+; X87-NEXT:    # kill: def $ah killed $ah killed $ax
+; X87-NEXT:    sahf
+; X87-NEXT:    setnp %al
+; X87-NEXT:    sete %cl
+; X87-NEXT:    andb %al, %cl
+; X87-NEXT:    movzbl %cl, %eax
+; X87-NEXT:    retl
+  %add = fadd float %a, %b
+  store volatile float %add, ptr %p
+  %reload = load volatile float, ptr %p
+  %cmp = fcmp oeq float %add, %reload
+  %ret = zext i1 %cmp to i32
+  ret i32 %ret
+}
+
+define i32 @cmp_reload_f64(double %a, double %b, ptr %p) nounwind {
+; X87-LABEL: cmp_reload_f64:
+; X87:       # %bb.0:
+; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
+; X87-NEXT:    faddl {{[0-9]+}}(%esp)
+; X87-NEXT:    fstl (%eax)
+; X87-NEXT:    fldl (%eax)
+; X87-NEXT:    fxch %st(1)
+; X87-NEXT:    fucompp
+; X87-NEXT:    fnstsw %ax
+; X87-NEXT:    # kill: def $ah killed $ah killed $ax
+; X87-NEXT:    sahf
+; X87-NEXT:    setnp %al
+; X87-NEXT:    sete %cl
+; X87-NEXT:    andb %al, %cl
+; X87-NEXT:    movzbl %cl, %eax
+; X87-NEXT:    retl
+  %add = fadd double %a, %b
+  store volatile double %add, ptr %p
+  %reload = load volatile double, ptr %p
+  %cmp = fcmp oeq double %add, %reload
+  %ret = zext i1 %cmp to i32
+  ret i32 %ret
+}
+
+; Results that stay live in a register: returning an f32/f64 leaves it in st0,
+; which is 80 bits wide, so the round is not optional.
+define float @fadd_f32(float %a, float %b) nounwind {
+; X87-LABEL: fadd_f32:
+; X87:       # %bb.0:
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
+; X87-NEXT:    fadds {{[0-9]+}}(%esp)
+; X87-NEXT:    retl
+  %r = fadd float %a, %b
+  ret float %r
+}
+
+define float @fsub_f32(float %a, float %b) nounwind {
+; X87-LABEL: fsub_f32:
+; X87:       # %bb.0:
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
+; X87-NEXT:    fsubs {{[0-9]+}}(%esp)
+; X87-NEXT:    retl
+  %r = fsub float %a, %b
+  ret float %r
+}
+
+define float @fmul_f32(float %a, float %b) nounwind {
+; X87-LABEL: fmul_f32:
+; X87:       # %bb.0:
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
+; X87-NEXT:    fmuls {{[0-9]+}}(%esp)
+; X87-NEXT:    retl
+  %r = fmul float %a, %b
+  ret float %r
+}
+
+define float @fdiv_f32(float %a, float %b) nounwind {
+; X87-LABEL: fdiv_f32:
+; X87:       # %bb.0:
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
+; X87-NEXT:    fdivs {{[0-9]+}}(%esp)
+; X87-NEXT:    retl
+  %r = fdiv float %a, %b
+  ret float %r
+}
+
+define float @fsqrt_f32(float %a) nounwind {
+; X87-LABEL: fsqrt_f32:
+; X87:       # %bb.0:
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
+; X87-NEXT:    fsqrt
+; X87-NEXT:    retl
+  %r = call float @llvm.sqrt.f32(float %a)
+  ret float %r
+}
+
+define double @fadd_f64(double %a, double %b) nounwind {
+; X87-LABEL: fadd_f64:
+; X87:       # %bb.0:
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
+; X87-NEXT:    faddl {{[0-9]+}}(%esp)
+; X87-NEXT:    retl
+  %r = fadd double %a, %b
+  ret double %r
+}
+
+define double @fsqrt_f64(double %a) nounwind {
+; X87-LABEL: fsqrt_f64:
+; X87:       # %bb.0:
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
+; X87-NEXT:    fsqrt
+; X87-NEXT:    retl
+  %r = call double @llvm.sqrt.f64(double %a)
+  ret double %r
+}
+
+; f80 is the register's own width, so f80 arithmetic is already exact for its
+; type and must never gain a round trip.
+define x86_fp80 @fadd_f80(x86_fp80 %a, x86_fp80 %b) nounwind {
+; X87-LABEL: fadd_f80:
+; X87:       # %bb.0:
+; X87-NEXT:    fldt {{[0-9]+}}(%esp)
+; X87-NEXT:    fldt {{[0-9]+}}(%esp)
+; X87-NEXT:    faddp %st, %st(1)
+; X87-NEXT:    retl
+  %r = fadd x86_fp80 %a, %b
+  ret x86_fp80 %r
+}
+
+; A legal FP immediate is materialised with fld1 rather than loaded from the
+; constant pool, but the result still needs rounding.
+define float @fadd_const_f32(float %a) nounwind {
+; X87-LABEL: fadd_const_f32:
+; X87:       # %bb.0:
+; X87-NEXT:    fld1
+; X87-NEXT:    fadds {{[0-9]+}}(%esp)
+; X87-NEXT:    retl
+  %r = fadd float %a, 1.0
+  ret float %r
+}
+
+; fneg and fabs only flip the sign bit, so they are exact and must not gain a
+; round trip.
+define float @fneg_f32(float %a) nounwind {
+; X87-LABEL: fneg_f32:
+; X87:       # %bb.0:
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
+; X87-NEXT:    fchs
+; X87-NEXT:    retl
+  %r = fneg float %a
+  ret float %r
+}
+
+define float @fabs_f32(float %a) nounwind {
+; X87-LABEL: fabs_f32:
+; X87:       # %bb.0:
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
+; X87-NEXT:    fabs
+; X87-NEXT:    retl
+  %r = call float @llvm.fabs.f32(float %a)
+  ret float %r
+}
+
+; The result is only stored, and a store of exactly this width already rounds,
+; so this must not gain a stack temporary on top of the store.
+define void @store_only_f32(float %a, float %b, ptr %p) nounwind {
+; X87-LABEL: store_only_f32:
+; X87:       # %bb.0:
+; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
+; X87-NEXT:    fadds {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps (%eax)
+; X87-NEXT:    retl
+  %r = fadd float %a, %b
+  store float %r, ptr %p
+  ret void
+}
+
+define void @store_only_f64(double %a, double %b, ptr %p) nounwind {
+; X87-LABEL: store_only_f64:
+; X87:       # %bb.0:
+; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
+; X87-NEXT:    faddl {{[0-9]+}}(%esp)
+; X87-NEXT:    fstpl (%eax)
+; X87-NEXT:    retl
+  %r = fadd double %a, %b
+  store double %r, ptr %p
+  ret void
+}
+
+; Stored twice: still only the stores are needed.
+define void @store_twice_f32(float %a, float %b, ptr %p, ptr %q) nounwind {
+; X87-LABEL: store_twice_f32:
+; X87:       # %bb.0:
+; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X87-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
+; X87-NEXT:    fadds {{[0-9]+}}(%esp)
+; X87-NEXT:    fsts (%ecx)
+; X87-NEXT:    fstps (%eax)
+; X87-NEXT:    retl
+  %r = fadd float %a, %b
+  store float %r, ptr %p
+  store float %r, ptr %q
+  ret void
+}
+
+; Stored and also kept in a register: the rounded value has to reach both.
+define float @store_and_use_f32(float %a, float %b, ptr %p) nounwind {
+; X87-LABEL: store_and_use_f32:
+; X87:       # %bb.0:
+; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
+; X87-NEXT:    fadds {{[0-9]+}}(%esp)
+; X87-NEXT:    fsts (%eax)
+; X87-NEXT:    retl
+  %r = fadd float %a, %b
+  store float %r, ptr %p
+  ret float %r
+}
+
+; A store of a narrower type than the value is a rounding step of its own.
+define void @store_narrower_f32(double %a, double %b, ptr %p) nounwind {
+; X87-LABEL: store_narrower_f32:
+; X87:       # %bb.0:
+; X87-NEXT:    pushl %eax
+; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
+; X87-NEXT:    faddl {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps (%esp)
+; X87-NEXT:    flds (%esp)
+; X87-NEXT:    fstps (%eax)
+; X87-NEXT:    popl %eax
+; X87-NEXT:    retl
+  %r = fadd double %a, %b
+  %t = fptrunc double %r to float
+  store float %t, ptr %p
+  ret void
+}
+
+; fild rounds to the control word's precision too, so sitofp needs the same
+; treatment.
+define float @sitofp_i32_f32(i32 %x) nounwind {
+; X87-LABEL: sitofp_i32_f32:
+; X87:       # %bb.0:
+; X87-NEXT:    pushl %eax
+; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X87-NEXT:    movl %eax, (%esp)
+; X87-NEXT:    fildl (%esp)
+; X87-NEXT:    popl %eax
+; X87-NEXT:    retl
+  %r = sitofp i32 %x to float
+  ret float %r
+}
+
+define double @sitofp_i32_f64(i32 %x) nounwind {
+; X87-LABEL: sitofp_i32_f64:
+; X87:       # %bb.0:
+; X87-NEXT:    pushl %eax
+; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X87-NEXT:    movl %eax, (%esp)
+; X87-NEXT:    fildl (%esp)
+; X87-NEXT:    popl %eax
+; X87-NEXT:    retl
+  %r = sitofp i32 %x to double
+  ret double %r
+}
+
+define float @sitofp_i64_f32(i64 %x) nounwind {
+; X87-LABEL: sitofp_i64_f32:
+; X87:       # %bb.0:
+; X87-NEXT:    fildll {{[0-9]+}}(%esp)
+; X87-NEXT:    retl
+  %r = sitofp i64 %x to float
+  ret float %r
+}
+
+; Every use of the conversion is a store that rounds on its own, so the round
+; the fild needs must not also go through a stack temporary.
+define void @sitofp_store_only_f32(i32 %x, ptr %p) nounwind {
+; X87-LABEL: sitofp_store_only_f32:
+; X87:       # %bb.0:
+; X87-NEXT:    pushl %eax
+; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X87-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X87-NEXT:    movl %ecx, (%esp)
+; X87-NEXT:    fildl (%esp)
+; X87-NEXT:    fstps (%eax)
+; X87-NEXT:    popl %eax
+; X87-NEXT:    retl
+  %r = sitofp i32 %x to float
+  store float %r, ptr %p
+  ret void
+}
+
+define void @sitofp_store_twice_f32(i32 %x, ptr %p, ptr %q) nounwind {
+; X87-LABEL: sitofp_store_twice_f32:
+; X87:       # %bb.0:
+; X87-NEXT:    pushl %eax
+; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X87-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X87-NEXT:    movl {{[0-9]+}}(%esp), %edx
+; X87-NEXT:    movl %edx, (%esp)
+; X87-NEXT:    fildl (%esp)
+; X87-NEXT:    fsts (%ecx)
+; X87-NEXT:    fstps (%eax)
+; X87-NEXT:    popl %eax
+; X87-NEXT:    retl
+  %r = sitofp i32 %x to float
+  store float %r, ptr %p
+  store float %r, ptr %q
+  ret void
+}
+
+; Also kept in a register, so the rounded value has to reach both and the
+; temporary earns its keep.
+define float @sitofp_store_and_use_f32(i32 %x, ptr %p) nounwind {
+; X87-LABEL: sitofp_store_and_use_f32:
+; X87:       # %bb.0:
+; X87-NEXT:    pushl %eax
+; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X87-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X87-NEXT:    movl %ecx, (%esp)
+; X87-NEXT:    fildl (%esp)
+; X87-NEXT:    fsts (%eax)
+; X87-NEXT:    popl %eax
+; X87-NEXT:    retl
+  %r = sitofp i32 %x to float
+  store float %r, ptr %p
+  ret float %r
+}
+
+; The store is not ordered against the conversion, so rounding at the store
+; instead would round under whatever mode is current there.
+define void @strict_sitofp_store_f32(i32 %x, ptr %p) nounwind strictfp {
+; X87-LABEL: strict_sitofp_store_f32:
+; X87:       # %bb.0:
+; X87-NEXT:    pushl %eax
+; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X87-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X87-NEXT:    movl %ecx, (%esp)
+; X87-NEXT:    fildl (%esp)
+; X87-NEXT:    fstps (%eax)
+; X87-NEXT:    wait
+; X87-NEXT:    popl %eax
+; X87-NEXT:    retl
+  %r = call float @llvm.experimental.constrained.sitofp.f32.i32(i32 %x,
+                                                          metadata !"round.dynamic",
+                                                          metadata !"fpexcept.strict")
+  store float %r, ptr %p
+  ret void
+}
+
+; uitofp reaches the same fild by a different route: it zero-extends to i64
+; first, because x87 has no unsigned integer load.
+define float @uitofp_i32_f32(i32 %x) nounwind {
+; X87-LABEL: uitofp_i32_f32:
+; X87:       # %bb.0:
+; X87-NEXT:    subl $12, %esp
+; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X87-NEXT:    movl %eax, (%esp)
+; X87-NEXT:    movl $0, {{[0-9]+}}(%esp)
+; X87-NEXT:    fildll (%esp)
+; X87-NEXT:    addl $12, %esp
+; X87-NEXT:    retl
+  %r = uitofp i32 %x to float
+  ret float %r
+}
+
+; An i64 fits exactly in an 80-bit register, and f80 is the register's own
+; width, so this must stay a bare fild.
+define x86_fp80 @sitofp_i64_f80(i64 %x) nounwind {
+; X87-LABEL: sitofp_i64_f80:
+; X87:       # %bb.0:
+; X87-NEXT:    fildll {{[0-9]+}}(%esp)
+; X87-NEXT:    retl
+  %r = sitofp i64 %x to x86_fp80
+  ret x86_fp80 %r
+}
+
+; Explicit narrowing between two x87 types is a real rounding step
+define float @fptrunc_f80_f32(x86_fp80 %a) nounwind {
+; X87-LABEL: fptrunc_f80_f32:
+; X87:       # %bb.0:
+; X87-NEXT:    pushl %eax
+; X87-NEXT:    fldt {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps (%esp)
+; X87-NEXT:    flds (%esp)
+; X87-NEXT:    popl %eax
+; X87-NEXT:    retl
+  %r = fptrunc x86_fp80 %a to float
+  ret float %r
+}
+
+define double @fptrunc_f80_f64(x86_fp80 %a) nounwind {
+; X87-LABEL: fptrunc_f80_f64:
+; X87:       # %bb.0:
+; X87-NEXT:    subl $12, %esp
+; X87-NEXT:    fldt {{[0-9]+}}(%esp)
+; X87-NEXT:    fstpl (%esp)
+; X87-NEXT:    fldl (%esp)
+; X87-NEXT:    addl $12, %esp
+; X87-NEXT:    retl
+  %r = fptrunc x86_fp80 %a to double
+  ret double %r
+}
+
+define float @fptrunc_f64_f32(double %a) nounwind {
+; X87-LABEL: fptrunc_f64_f32:
+; X87:       # %bb.0:
+; X87-NEXT:    pushl %eax
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps (%esp)
+; X87-NEXT:    flds (%esp)
+; X87-NEXT:    popl %eax
+; X87-NEXT:    retl
+  %r = fptrunc double %a to float
+  ret float %r
+}
+
+; Widening is exact, so it costs nothing.
+define x86_fp80 @fpext_f32_f80(float %a) nounwind {
+; X87-LABEL: fpext_f32_f80:
+; X87:       # %bb.0:
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
+; X87-NEXT:    retl
+  %r = fpext float %a to x86_fp80
+  ret x86_fp80 %r
+}
+
+; Live across a call, so the value is spilled. The spill slot must be 4 bytes
+; wide: spilling through a wider slot would preserve the excess precision.
+define float @spill_across_call(float %a, float %b) nounwind {
+; X87-LABEL: spill_across_call:
+; X87:       # %bb.0:
+; X87-NEXT:    subl $12, %esp
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
+; X87-NEXT:    fadds {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Folded Spill
+; X87-NEXT:    calll opaque at PLT
+; X87-NEXT:    flds {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Folded Reload
+; X87-NEXT:    addl $12, %esp
+; X87-NEXT:    retl
+  %r = fadd float %a, %b
+  call void @opaque()
+  ret float %r
+}
+
+; A chain of operations: C requires each assignment to round, and with no
+; frontend help the backend has to round every one of them.
+define float @chain_f32(float %a, float %b, float %c, float %d) nounwind {
+; X87-LABEL: chain_f32:
+; X87:       # %bb.0:
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
+; X87-NEXT:    fmuls {{[0-9]+}}(%esp)
+; X87-NEXT:    fxch %st(1)
+; X87-NEXT:    fmuls {{[0-9]+}}(%esp)
+; X87-NEXT:    faddp %st, %st(1)
+; X87-NEXT:    retl
+  %ab = fmul float %a, %b
+  %cd = fmul float %c, %d
+  %r = fadd float %ab, %cd
+  ret float %r
+}
+
+; The constrained opcodes need the same treatment as their unconstrained forms.
+define float @strict_fadd_f32(float %a, float %b) nounwind strictfp {
+; X87-LABEL: strict_fadd_f32:
+; X87:       # %bb.0:
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
+; X87-NEXT:    fadds {{[0-9]+}}(%esp)
+; X87-NEXT:    wait
+; X87-NEXT:    retl
+  %r = call float @llvm.experimental.constrained.fadd.f32(float %a, float %b,
+                                                          metadata !"round.dynamic",
+                                                          metadata !"fpexcept.strict")
+  ret float %r
+}

>From 66777acec33f637d08fec85d2073cc6027dbeaf7 Mon Sep 17 00:00:00 2001
From: Dennis Duda <git at seri.tools>
Date: Fri, 7 Aug 2026 22:54:15 +0200
Subject: [PATCH 02/15] [X86] Promote f32/f64 to f80 iif they are on the x87
 stack

Co-authored-by: Claude (Claude-Opus-5) <noreply at anthropic.com>
---
 llvm/lib/Target/X86/X86ISelLowering.cpp       |  22 +
 llvm/lib/Target/X86/X86ISelLowering.h         |   5 +
 llvm/test/CodeGen/X86/and-su.ll               |   3 +
 llvm/test/CodeGen/X86/bfloat-constrained.ll   |  12 +-
 llvm/test/CodeGen/X86/canonicalize-vars.ll    | 205 +++++--
 llvm/test/CodeGen/X86/fmf-flags.ll            |  34 +-
 llvm/test/CodeGen/X86/fp-intrinsics.ll        |  61 +-
 .../CodeGen/X86/fp-strict-scalar-fptoint.ll   |  24 +-
 llvm/test/CodeGen/X86/fp-strict-scalar.ll     |  94 ++-
 llvm/test/CodeGen/X86/fp_constant_op.ll       |  84 ++-
 llvm/test/CodeGen/X86/fp_load_fold.ll         |  96 +++-
 llvm/test/CodeGen/X86/fptoui-sat-scalar.ll    | 186 +++---
 llvm/test/CodeGen/X86/half-constrained.ll     |  12 +-
 llvm/test/CodeGen/X86/inline-asm-fpstack.ll   |   8 +
 llvm/test/CodeGen/X86/isel-fadd.ll            |  60 +-
 llvm/test/CodeGen/X86/isel-fdiv.ll            |  60 +-
 llvm/test/CodeGen/X86/isel-fmul.ll            |  60 +-
 llvm/test/CodeGen/X86/isel-fsub.ll            |  60 +-
 llvm/test/CodeGen/X86/isel-sqrt.ll            |  44 +-
 llvm/test/CodeGen/X86/limited-prec.ll         | 534 ++++++++++++++----
 llvm/test/CodeGen/X86/negate-add-zero.ll      |  60 +-
 llvm/test/CodeGen/X86/no-ret-in-x87-reg.ll    |  16 +-
 llvm/test/CodeGen/X86/nosse-vector.ll         |  46 +-
 llvm/test/CodeGen/X86/powi-const.ll           |  28 +-
 llvm/test/CodeGen/X86/pr34080-2.ll            |   8 +-
 llvm/test/CodeGen/X86/pr35982.ll              |  26 +-
 llvm/test/CodeGen/X86/pr50782.ll              |  44 +-
 llvm/test/CodeGen/X86/pr59305.ll              |  39 +-
 llvm/test/CodeGen/X86/scalar-fp-to-i64.ll     |  46 +-
 llvm/test/CodeGen/X86/select.ll               |  60 +-
 llvm/test/CodeGen/X86/x87-round-to-type.ll    |  78 ++-
 31 files changed, 1629 insertions(+), 486 deletions(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 69eab53dca965..b07e629cd6770 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -907,6 +907,21 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
     setOperationAction(ISD::STRICT_FP_ROUND, MVT::f80, Legal);
   }
 
+  // On x87, do rounding-sensitive arithmetic in f80, because a f32/f64 vreg on
+  // its stack doesn't generally hold a value of its own type. The promotion
+  // takes care of fp_extending, doing the op, then fp_rounding back to the
+  // narrow type.
+  for (auto VT : {MVT::f32, MVT::f64}) {
+    if (!isScalarFPTypeOnX87Stack(VT))
+      continue;
+    // Promote only ops that may need rounding (fneg/fabs are just sign flips,
+    // always exact)
+    for (unsigned Opc : {ISD::FADD, ISD::FSUB, ISD::FMUL, ISD::FDIV, ISD::FSQRT,
+                         ISD::STRICT_FADD, ISD::STRICT_FSUB, ISD::STRICT_FMUL,
+                         ISD::STRICT_FDIV, ISD::STRICT_FSQRT})
+      setOperationPromotedToType(Opc, VT, MVT::f80);
+  }
+
   // f128 uses xmm registers, but most operations require libcalls.
   if (!Subtarget.useSoftFloat() && Subtarget.is64Bit() && Subtarget.hasSSE1()) {
     addRegisterClass(MVT::f128, Subtarget.hasVLX() ? &X86::VR128XRegClass
@@ -3713,6 +3728,13 @@ bool X86TargetLowering::isScalarFPTypeInSSEReg(EVT VT) const {
          (VT == MVT::f32 && Subtarget.hasSSE1()) || VT == MVT::f16;
 }
 
+bool X86TargetLowering::isScalarFPTypeOnX87Stack(EVT VT) const {
+  if (Subtarget.useSoftFloat() || !Subtarget.hasX87())
+    return false;
+  return (VT == MVT::f80) ||
+         ((VT == MVT::f32 || VT == MVT::f64) && !isScalarFPTypeInSSEReg(VT));
+}
+
 bool X86TargetLowering::isLoadBitCastBeneficial(EVT LoadVT, EVT BitcastVT,
                                                 const SelectionDAG &DAG,
                                                 const MachineMemOperand &MMO) const {
diff --git a/llvm/lib/Target/X86/X86ISelLowering.h b/llvm/lib/Target/X86/X86ISelLowering.h
index 5215bb0704dca..21b0d0053d52a 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.h
+++ b/llvm/lib/Target/X86/X86ISelLowering.h
@@ -563,6 +563,11 @@ namespace llvm {
     /// register, not on the X87 floating point stack.
     bool isScalarFPTypeInSSEReg(EVT VT) const;
 
+    /// Returns true if the specified scalar FP type is computed on the
+    /// X87 floating point stack. Important because the registers are always 80
+    /// bits wide, regardless of the precision of the value being computed.
+    bool isScalarFPTypeOnX87Stack(EVT VT) const;
+
     /// Returns true if it is beneficial to convert a load of a constant
     /// to just the constant itself.
     bool shouldConvertConstantLoadToIntImm(const APInt &Imm,
diff --git a/llvm/test/CodeGen/X86/and-su.ll b/llvm/test/CodeGen/X86/and-su.ll
index b657ed28f6dc6..d3b568e4da96f 100644
--- a/llvm/test/CodeGen/X86/and-su.ll
+++ b/llvm/test/CodeGen/X86/and-su.ll
@@ -30,6 +30,7 @@ define fastcc double @bar(i32 %hash, double %x, double %y) nounwind {
 ; CHECK-NEXT:    pushl %ebp
 ; CHECK-NEXT:    movl %esp, %ebp
 ; CHECK-NEXT:    andl $-8, %esp
+; CHECK-NEXT:    subl $8, %esp
 ; CHECK-NEXT:    fldl 16(%ebp)
 ; CHECK-NEXT:    fldl 8(%ebp)
 ; CHECK-NEXT:    movl %ecx, %eax
@@ -50,6 +51,8 @@ define fastcc double @bar(i32 %hash, double %x, double %y) nounwind {
 ; CHECK-NEXT:    fxch %st(1)
 ; CHECK-NEXT:  .LBB1_5: # %bb16
 ; CHECK-NEXT:    faddp %st, %st(1)
+; CHECK-NEXT:    fstpl (%esp)
+; CHECK-NEXT:    fldl (%esp)
 ; CHECK-NEXT:    movl %ebp, %esp
 ; CHECK-NEXT:    popl %ebp
 ; CHECK-NEXT:    retl
diff --git a/llvm/test/CodeGen/X86/bfloat-constrained.ll b/llvm/test/CodeGen/X86/bfloat-constrained.ll
index 081b1cebfc43d..a8c723a9ea0d1 100644
--- a/llvm/test/CodeGen/X86/bfloat-constrained.ll
+++ b/llvm/test/CodeGen/X86/bfloat-constrained.ll
@@ -123,23 +123,25 @@ define void @double_to_bfloat(double %0) strictfp {
 define void @add() strictfp {
 ; X86-LABEL: add:
 ; X86:       # %bb.0:
-; X86-NEXT:    subl $12, %esp
-; X86-NEXT:    .cfi_def_cfa_offset 16
+; X86-NEXT:    subl $28, %esp
+; X86-NEXT:    .cfi_def_cfa_offset 32
 ; X86-NEXT:    movzwl a, %eax
 ; X86-NEXT:    movl %eax, (%esp)
 ; X86-NEXT:    calll __extendbfsf2
-; X86-NEXT:    fstps {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Folded Spill
+; X86-NEXT:    fstpt {{[-0-9]+}}(%e{{[sb]}}p) # 10-byte Folded Spill
 ; X86-NEXT:    wait
 ; X86-NEXT:    movzwl b, %eax
 ; X86-NEXT:    movl %eax, (%esp)
 ; X86-NEXT:    calll __extendbfsf2
-; X86-NEXT:    flds {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Folded Reload
+; X86-NEXT:    fldt {{[-0-9]+}}(%e{{[sb]}}p) # 10-byte Folded Reload
 ; X86-NEXT:    faddp %st, %st(1)
+; X86-NEXT:    fstps {{[0-9]+}}(%esp)
+; X86-NEXT:    flds {{[0-9]+}}(%esp)
 ; X86-NEXT:    fstps (%esp)
 ; X86-NEXT:    wait
 ; X86-NEXT:    calll __truncsfbf2
 ; X86-NEXT:    movw %ax, c
-; X86-NEXT:    addl $12, %esp
+; X86-NEXT:    addl $28, %esp
 ; X86-NEXT:    .cfi_def_cfa_offset 4
 ; X86-NEXT:    retl
 ;
diff --git a/llvm/test/CodeGen/X86/canonicalize-vars.ll b/llvm/test/CodeGen/X86/canonicalize-vars.ll
index 67213b38277dc..4e53d1e20a670 100644
--- a/llvm/test/CodeGen/X86/canonicalize-vars.ll
+++ b/llvm/test/CodeGen/X86/canonicalize-vars.ll
@@ -10,8 +10,15 @@
 define float @canon_fp32_varargsf32(float %a) {
 ; X87-LABEL: canon_fp32_varargsf32:
 ; X87:       # %bb.0:
+; X87-NEXT:    pushl %eax
+; X87-NEXT:    .cfi_def_cfa_offset 8
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    fld1
-; X87-NEXT:    fmuls {{[0-9]+}}(%esp)
+; X87-NEXT:    fmulp %st, %st(1)
+; X87-NEXT:    fstps (%esp)
+; X87-NEXT:    flds (%esp)
+; X87-NEXT:    popl %eax
+; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl
 ;
 ; X86-SSE-LABEL: canon_fp32_varargsf32:
@@ -167,8 +174,15 @@ entry:
 define double @canonicalize_fp64(double %a, double %b) unnamed_addr #0 {
 ; X87-LABEL: canonicalize_fp64:
 ; X87:       # %bb.0: # %start
-; X87-NEXT:    fldl {{[0-9]+}}(%esp)
-; X87-NEXT:    fldl {{[0-9]+}}(%esp)
+; X87-NEXT:    pushl %ebp
+; X87-NEXT:    .cfi_def_cfa_offset 8
+; X87-NEXT:    .cfi_offset %ebp, -8
+; X87-NEXT:    movl %esp, %ebp
+; X87-NEXT:    .cfi_def_cfa_register %ebp
+; X87-NEXT:    andl $-8, %esp
+; X87-NEXT:    subl $8, %esp
+; X87-NEXT:    fldl 8(%ebp)
+; X87-NEXT:    fldl 16(%ebp)
 ; X87-NEXT:    fucom %st(1)
 ; X87-NEXT:    fnstsw %ax
 ; X87-NEXT:    # kill: def $ah killed $ah killed $ax
@@ -194,6 +208,11 @@ define double @canonicalize_fp64(double %a, double %b) unnamed_addr #0 {
 ; X87-NEXT:    fstp %st(0)
 ; X87-NEXT:    fld1
 ; X87-NEXT:    fmulp %st, %st(1)
+; X87-NEXT:    fstpl (%esp)
+; X87-NEXT:    fldl (%esp)
+; X87-NEXT:    movl %ebp, %esp
+; X87-NEXT:    popl %ebp
+; X87-NEXT:    .cfi_def_cfa %esp, 4
 ; X87-NEXT:    retl
 ;
 ; X86-SSE-LABEL: canonicalize_fp64:
@@ -292,6 +311,8 @@ start:
 define float @canonicalize_fp32(float %aa, float %bb) unnamed_addr #0 {
 ; X87-LABEL: canonicalize_fp32:
 ; X87:       # %bb.0: # %start
+; X87-NEXT:    pushl %eax
+; X87-NEXT:    .cfi_def_cfa_offset 8
 ; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    fucom %st(1)
@@ -319,6 +340,10 @@ define float @canonicalize_fp32(float %aa, float %bb) unnamed_addr #0 {
 ; X87-NEXT:    fstp %st(0)
 ; X87-NEXT:    fld1
 ; X87-NEXT:    fmulp %st, %st(1)
+; X87-NEXT:    fstps (%esp)
+; X87-NEXT:    flds (%esp)
+; X87-NEXT:    popl %eax
+; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl
 ;
 ; X86-SSE-LABEL: canonicalize_fp32:
@@ -405,10 +430,17 @@ start:
 define void @v_test_canonicalize_var_f32(float addrspace(1)* %out) #1 {
 ; X87-LABEL: v_test_canonicalize_var_f32:
 ; X87:       # %bb.0:
+; X87-NEXT:    pushl %eax
+; X87-NEXT:    .cfi_def_cfa_offset 8
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X87-NEXT:    flds (%eax)
 ; X87-NEXT:    fld1
-; X87-NEXT:    fmuls (%eax)
+; X87-NEXT:    fmulp %st, %st(1)
+; X87-NEXT:    fstps (%esp)
+; X87-NEXT:    flds (%esp)
 ; X87-NEXT:    fstps (%eax)
+; X87-NEXT:    popl %eax
+; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl
 ;
 ; X86-SSE-LABEL: v_test_canonicalize_var_f32:
@@ -498,10 +530,23 @@ define void @v_test_canonicalize_x86_fp80(x86_fp80 addrspace(1)* %out) #1 {
 define void @v_test_canonicalize_var_f64(double addrspace(1)* %out) #1 {
 ; X87-LABEL: v_test_canonicalize_var_f64:
 ; X87:       # %bb.0:
-; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X87-NEXT:    pushl %ebp
+; X87-NEXT:    .cfi_def_cfa_offset 8
+; X87-NEXT:    .cfi_offset %ebp, -8
+; X87-NEXT:    movl %esp, %ebp
+; X87-NEXT:    .cfi_def_cfa_register %ebp
+; X87-NEXT:    andl $-8, %esp
+; X87-NEXT:    subl $8, %esp
+; X87-NEXT:    movl 8(%ebp), %eax
+; X87-NEXT:    fldl (%eax)
 ; X87-NEXT:    fld1
-; X87-NEXT:    fmull (%eax)
+; X87-NEXT:    fmulp %st, %st(1)
+; X87-NEXT:    fstpl (%esp)
+; X87-NEXT:    fldl (%esp)
 ; X87-NEXT:    fstpl (%eax)
+; X87-NEXT:    movl %ebp, %esp
+; X87-NEXT:    popl %ebp
+; X87-NEXT:    .cfi_def_cfa %esp, 4
 ; X87-NEXT:    retl
 ;
 ; X86-SSE-LABEL: v_test_canonicalize_var_f64:
@@ -580,22 +625,35 @@ define void @canonicalize_undef(double addrspace(1)* %out) {
 define <4 x float> @canon_fp32_varargsv4f32(<4 x float> %a) {
 ; X87-LABEL: canon_fp32_varargsv4f32:
 ; X87:       # %bb.0:
+; X87-NEXT:    subl $16, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 20
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    fld1
-; X87-NEXT:    fld %st(0)
-; X87-NEXT:    fmuls {{[0-9]+}}(%esp)
-; X87-NEXT:    fld %st(1)
-; X87-NEXT:    fmuls {{[0-9]+}}(%esp)
-; X87-NEXT:    fld %st(2)
-; X87-NEXT:    fmuls {{[0-9]+}}(%esp)
-; X87-NEXT:    fxch %st(3)
-; X87-NEXT:    fmuls {{[0-9]+}}(%esp)
+; X87-NEXT:    fmul %st, %st(1)
+; X87-NEXT:    fxch %st(1)
+; X87-NEXT:    fstps {{[0-9]+}}(%esp)
+; X87-NEXT:    fmul %st, %st(1)
+; X87-NEXT:    fxch %st(1)
+; X87-NEXT:    fstps {{[0-9]+}}(%esp)
+; X87-NEXT:    fmul %st, %st(1)
+; X87-NEXT:    fxch %st(1)
+; X87-NEXT:    fstps {{[0-9]+}}(%esp)
+; X87-NEXT:    fmulp %st, %st(1)
+; X87-NEXT:    fstps (%esp)
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
+; X87-NEXT:    flds (%esp)
 ; X87-NEXT:    fstps 12(%eax)
-; X87-NEXT:    fxch %st(2)
 ; X87-NEXT:    fstps 8(%eax)
-; X87-NEXT:    fxch %st(1)
 ; X87-NEXT:    fstps 4(%eax)
 ; X87-NEXT:    fstps (%eax)
+; X87-NEXT:    addl $16, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl $4
 ;
 ; X86-SSE-LABEL: canon_fp32_varargsv4f32:
@@ -636,22 +694,41 @@ define <4 x float> @canon_fp32_varargsv4f32(<4 x float> %a) {
 define <4 x double> @canon_fp64_varargsv4f64(<4 x double> %a) {
 ; X87-LABEL: canon_fp64_varargsv4f64:
 ; X87:       # %bb.0:
-; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X87-NEXT:    pushl %ebp
+; X87-NEXT:    .cfi_def_cfa_offset 8
+; X87-NEXT:    .cfi_offset %ebp, -8
+; X87-NEXT:    movl %esp, %ebp
+; X87-NEXT:    .cfi_def_cfa_register %ebp
+; X87-NEXT:    andl $-8, %esp
+; X87-NEXT:    subl $32, %esp
+; X87-NEXT:    movl 8(%ebp), %eax
+; X87-NEXT:    fldl 36(%ebp)
+; X87-NEXT:    fldl 28(%ebp)
+; X87-NEXT:    fldl 20(%ebp)
+; X87-NEXT:    fldl 12(%ebp)
 ; X87-NEXT:    fld1
-; X87-NEXT:    fld %st(0)
-; X87-NEXT:    fmull {{[0-9]+}}(%esp)
-; X87-NEXT:    fld %st(1)
-; X87-NEXT:    fmull {{[0-9]+}}(%esp)
-; X87-NEXT:    fld %st(2)
-; X87-NEXT:    fmull {{[0-9]+}}(%esp)
-; X87-NEXT:    fxch %st(3)
-; X87-NEXT:    fmull {{[0-9]+}}(%esp)
+; X87-NEXT:    fmul %st, %st(1)
+; X87-NEXT:    fxch %st(1)
+; X87-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X87-NEXT:    fmul %st, %st(1)
+; X87-NEXT:    fxch %st(1)
+; X87-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X87-NEXT:    fmul %st, %st(1)
+; X87-NEXT:    fxch %st(1)
+; X87-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X87-NEXT:    fmulp %st, %st(1)
+; X87-NEXT:    fstpl (%esp)
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
+; X87-NEXT:    fldl (%esp)
 ; X87-NEXT:    fstpl 24(%eax)
-; X87-NEXT:    fxch %st(2)
 ; X87-NEXT:    fstpl 16(%eax)
-; X87-NEXT:    fxch %st(1)
 ; X87-NEXT:    fstpl 8(%eax)
 ; X87-NEXT:    fstpl (%eax)
+; X87-NEXT:    movl %ebp, %esp
+; X87-NEXT:    popl %ebp
+; X87-NEXT:    .cfi_def_cfa %esp, 4
 ; X87-NEXT:    retl $4
 ;
 ; X86-SSE-LABEL: canon_fp64_varargsv4f64:
@@ -750,22 +827,35 @@ define <2 x x86_fp80> @canon_fp80_varargsv2fp80(<2 x x86_fp80> %a) {
 define void @vec_canonicalize_var_v4f32(<4 x float> addrspace(1)* %out) #1 {
 ; X87-LABEL: vec_canonicalize_var_v4f32:
 ; X87:       # %bb.0:
+; X87-NEXT:    subl $16, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 20
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X87-NEXT:    flds 12(%eax)
+; X87-NEXT:    flds 8(%eax)
+; X87-NEXT:    flds 4(%eax)
+; X87-NEXT:    flds (%eax)
 ; X87-NEXT:    fld1
-; X87-NEXT:    fld %st(0)
-; X87-NEXT:    fmuls (%eax)
-; X87-NEXT:    fld %st(1)
-; X87-NEXT:    fmuls 4(%eax)
-; X87-NEXT:    fld %st(2)
-; X87-NEXT:    fmuls 8(%eax)
-; X87-NEXT:    fxch %st(3)
-; X87-NEXT:    fmuls 12(%eax)
+; X87-NEXT:    fmul %st, %st(1)
+; X87-NEXT:    fxch %st(1)
+; X87-NEXT:    fstps {{[0-9]+}}(%esp)
+; X87-NEXT:    fmul %st, %st(1)
+; X87-NEXT:    fxch %st(1)
+; X87-NEXT:    fstps {{[0-9]+}}(%esp)
+; X87-NEXT:    fmul %st, %st(1)
+; X87-NEXT:    fxch %st(1)
+; X87-NEXT:    fstps (%esp)
+; X87-NEXT:    fmulp %st, %st(1)
+; X87-NEXT:    fstps {{[0-9]+}}(%esp)
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
+; X87-NEXT:    flds (%esp)
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    fstps 12(%eax)
-; X87-NEXT:    fxch %st(2)
 ; X87-NEXT:    fstps 8(%eax)
-; X87-NEXT:    fxch %st(1)
 ; X87-NEXT:    fstps 4(%eax)
 ; X87-NEXT:    fstps (%eax)
+; X87-NEXT:    addl $16, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl
 ;
 ; X86-SSE-LABEL: vec_canonicalize_var_v4f32:
@@ -820,22 +910,41 @@ define void @vec_canonicalize_var_v4f32(<4 x float> addrspace(1)* %out) #1 {
 define void @vec_canonicalize_var_v4f64(<4 x double> addrspace(1)* %out) #1 {
 ; X87-LABEL: vec_canonicalize_var_v4f64:
 ; X87:       # %bb.0:
-; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X87-NEXT:    pushl %ebp
+; X87-NEXT:    .cfi_def_cfa_offset 8
+; X87-NEXT:    .cfi_offset %ebp, -8
+; X87-NEXT:    movl %esp, %ebp
+; X87-NEXT:    .cfi_def_cfa_register %ebp
+; X87-NEXT:    andl $-8, %esp
+; X87-NEXT:    subl $32, %esp
+; X87-NEXT:    movl 8(%ebp), %eax
+; X87-NEXT:    fldl 24(%eax)
+; X87-NEXT:    fldl 16(%eax)
+; X87-NEXT:    fldl 8(%eax)
+; X87-NEXT:    fldl (%eax)
 ; X87-NEXT:    fld1
-; X87-NEXT:    fld %st(0)
-; X87-NEXT:    fmull (%eax)
-; X87-NEXT:    fld %st(1)
-; X87-NEXT:    fmull 8(%eax)
-; X87-NEXT:    fld %st(2)
-; X87-NEXT:    fmull 16(%eax)
-; X87-NEXT:    fxch %st(3)
-; X87-NEXT:    fmull 24(%eax)
+; X87-NEXT:    fmul %st, %st(1)
+; X87-NEXT:    fxch %st(1)
+; X87-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X87-NEXT:    fmul %st, %st(1)
+; X87-NEXT:    fxch %st(1)
+; X87-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X87-NEXT:    fmul %st, %st(1)
+; X87-NEXT:    fxch %st(1)
+; X87-NEXT:    fstpl (%esp)
+; X87-NEXT:    fmulp %st, %st(1)
+; X87-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
+; X87-NEXT:    fldl (%esp)
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    fstpl 24(%eax)
-; X87-NEXT:    fxch %st(2)
 ; X87-NEXT:    fstpl 16(%eax)
-; X87-NEXT:    fxch %st(1)
 ; X87-NEXT:    fstpl 8(%eax)
 ; X87-NEXT:    fstpl (%eax)
+; X87-NEXT:    movl %ebp, %esp
+; X87-NEXT:    popl %ebp
+; X87-NEXT:    .cfi_def_cfa %esp, 4
 ; X87-NEXT:    retl
 ;
 ; X86-SSE-LABEL: vec_canonicalize_var_v4f64:
diff --git a/llvm/test/CodeGen/X86/fmf-flags.ll b/llvm/test/CodeGen/X86/fmf-flags.ll
index 16ebf70126f8b..bd71da43eaeb0 100644
--- a/llvm/test/CodeGen/X86/fmf-flags.ll
+++ b/llvm/test/CodeGen/X86/fmf-flags.ll
@@ -17,10 +17,16 @@ define dso_local float @fast_recip_sqrt(float %x) {
 ;
 ; X86-LABEL: fast_recip_sqrt:
 ; X86:       # %bb.0:
+; X86-NEXT:    pushl %eax
+; X86-NEXT:    .cfi_def_cfa_offset 8
 ; X86-NEXT:    flds {{[0-9]+}}(%esp)
 ; X86-NEXT:    fsqrt
 ; X86-NEXT:    fld1
 ; X86-NEXT:    fdivp %st, %st(1)
+; X86-NEXT:    fstps (%esp)
+; X86-NEXT:    flds (%esp)
+; X86-NEXT:    popl %eax
+; X86-NEXT:    .cfi_def_cfa_offset 4
 ; X86-NEXT:    retl
   %y = call fast float @llvm.sqrt.f32(float %x)
   %z = fdiv fast float 1.0,  %y
@@ -37,8 +43,14 @@ define dso_local float @fast_fmuladd_opts(float %a , float %b , float %c) {
 ;
 ; X86-LABEL: fast_fmuladd_opts:
 ; X86:       # %bb.0:
+; X86-NEXT:    pushl %eax
+; X86-NEXT:    .cfi_def_cfa_offset 8
 ; X86-NEXT:    flds {{[0-9]+}}(%esp)
 ; X86-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
+; X86-NEXT:    fstps (%esp)
+; X86-NEXT:    flds (%esp)
+; X86-NEXT:    popl %eax
+; X86-NEXT:    .cfi_def_cfa_offset 4
 ; X86-NEXT:    retl
   %res = call fast float @llvm.fmuladd.f32(float %a, float 2.0, float %a)
   ret float %res
@@ -59,13 +71,25 @@ define dso_local double @not_so_fast_mul_add(double %x) {
 ;
 ; X86-LABEL: not_so_fast_mul_add:
 ; X86:       # %bb.0:
-; X86-NEXT:    fldl {{[0-9]+}}(%esp)
+; X86-NEXT:    pushl %ebp
+; X86-NEXT:    .cfi_def_cfa_offset 8
+; X86-NEXT:    .cfi_offset %ebp, -8
+; X86-NEXT:    movl %esp, %ebp
+; X86-NEXT:    .cfi_def_cfa_register %ebp
+; X86-NEXT:    andl $-8, %esp
+; X86-NEXT:    subl $8, %esp
+; X86-NEXT:    fldl 8(%ebp)
 ; X86-NEXT:    fld %st(0)
 ; X86-NEXT:    fmull {{\.?LCPI[0-9]+_[0-9]+}}
 ; X86-NEXT:    fxch %st(1)
 ; X86-NEXT:    fmull {{\.?LCPI[0-9]+_[0-9]+}}
+; X86-NEXT:    fstpl (%esp)
+; X86-NEXT:    fldl (%esp)
 ; X86-NEXT:    fxch %st(1)
 ; X86-NEXT:    fstpl mul1
+; X86-NEXT:    movl %ebp, %esp
+; X86-NEXT:    popl %ebp
+; X86-NEXT:    .cfi_def_cfa %esp, 4
 ; X86-NEXT:    retl
   %m = fmul double %x, 4.2
   %a = fadd fast double %m, %x
@@ -92,12 +116,20 @@ define dso_local float @not_so_fast_recip_sqrt(float %x) {
 ;
 ; X86-LABEL: not_so_fast_recip_sqrt:
 ; X86:       # %bb.0:
+; X86-NEXT:    subl $8, %esp
+; X86-NEXT:    .cfi_def_cfa_offset 12
 ; X86-NEXT:    flds {{[0-9]+}}(%esp)
 ; X86-NEXT:    fsqrt
+; X86-NEXT:    fstps (%esp)
+; X86-NEXT:    flds (%esp)
 ; X86-NEXT:    fld1
 ; X86-NEXT:    fdiv %st(1), %st
+; X86-NEXT:    fstps {{[0-9]+}}(%esp)
+; X86-NEXT:    flds {{[0-9]+}}(%esp)
 ; X86-NEXT:    fxch %st(1)
 ; X86-NEXT:    fstps sqrt1
+; X86-NEXT:    addl $8, %esp
+; X86-NEXT:    .cfi_def_cfa_offset 4
 ; X86-NEXT:    retl
   %y = call float @llvm.sqrt.f32(float %x)
   %z = fdiv fast float 1.0, %y
diff --git a/llvm/test/CodeGen/X86/fp-intrinsics.ll b/llvm/test/CodeGen/X86/fp-intrinsics.ll
index fd459be0d0ec1..48c268f02ed72 100644
--- a/llvm/test/CodeGen/X86/fp-intrinsics.ll
+++ b/llvm/test/CodeGen/X86/fp-intrinsics.ll
@@ -17,9 +17,16 @@
 define double @f1() #0 {
 ; X87-LABEL: f1:
 ; X87:       # %bb.0: # %entry
+; X87-NEXT:    subl $12, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 16
+; X87-NEXT:    flds {{\.?LCPI[0-9]+_[0-9]+}}
 ; X87-NEXT:    fld1
-; X87-NEXT:    fdivs {{\.?LCPI[0-9]+_[0-9]+}}
+; X87-NEXT:    fdivp %st, %st(1)
+; X87-NEXT:    fstpl (%esp)
+; X87-NEXT:    fldl (%esp)
 ; X87-NEXT:    wait
+; X87-NEXT:    addl $12, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl
 ;
 ; X86-SSE-LABEL: f1:
@@ -66,9 +73,16 @@ entry:
 define double @f2(double %a) #0 {
 ; X87-LABEL: f2:
 ; X87:       # %bb.0: # %entry
+; X87-NEXT:    subl $12, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 16
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    fldz
-; X87-NEXT:    fsubrl {{[0-9]+}}(%esp)
+; X87-NEXT:    fsubrp %st, %st(1)
+; X87-NEXT:    fstpl (%esp)
+; X87-NEXT:    fldl (%esp)
 ; X87-NEXT:    wait
+; X87-NEXT:    addl $12, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl
 ;
 ; X86-SSE-LABEL: f2:
@@ -117,13 +131,26 @@ entry:
 define double @f3(double %a, double %b) #0 {
 ; X87-LABEL: f3:
 ; X87:       # %bb.0: # %entry
+; X87-NEXT:    subl $28, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 32
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    fldz
 ; X87-NEXT:    fchs
-; X87-NEXT:    fld %st(0)
-; X87-NEXT:    fsubl {{[0-9]+}}(%esp)
-; X87-NEXT:    fmull {{[0-9]+}}(%esp)
+; X87-NEXT:    fsub %st, %st(1)
+; X87-NEXT:    fxch %st(1)
+; X87-NEXT:    fstpl (%esp)
+; X87-NEXT:    fldl (%esp)
+; X87-NEXT:    fmulp %st, %st(2)
+; X87-NEXT:    fxch %st(1)
+; X87-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    fsubrp %st, %st(1)
+; X87-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    wait
+; X87-NEXT:    addl $28, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl
 ;
 ; X86-SSE-LABEL: f3:
@@ -190,6 +217,8 @@ entry:
 define double @f4(i32 %n, double %a) #0 {
 ; X87-LABEL: f4:
 ; X87:       # %bb.0: # %entry
+; X87-NEXT:    subl $12, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 16
 ; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    wait
 ; X87-NEXT:    cmpl $0, {{[0-9]+}}(%esp)
@@ -197,8 +226,12 @@ define double @f4(i32 %n, double %a) #0 {
 ; X87-NEXT:  # %bb.1: # %if.then
 ; X87-NEXT:    fld1
 ; X87-NEXT:    faddp %st, %st(1)
+; X87-NEXT:    fstpl (%esp)
+; X87-NEXT:    fldl (%esp)
 ; X87-NEXT:    wait
 ; X87-NEXT:  .LBB3_2: # %if.end
+; X87-NEXT:    addl $12, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl
 ;
 ; X86-SSE-LABEL: f4:
@@ -255,9 +288,15 @@ if.end:
 define double @f5() #0 {
 ; X87-LABEL: f5:
 ; X87:       # %bb.0: # %entry
+; X87-NEXT:    subl $12, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 16
 ; X87-NEXT:    flds {{\.?LCPI[0-9]+_[0-9]+}}
 ; X87-NEXT:    fsqrt
+; X87-NEXT:    fstpl (%esp)
+; X87-NEXT:    fldl (%esp)
 ; X87-NEXT:    wait
+; X87-NEXT:    addl $12, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl
 ;
 ; X86-SSE-LABEL: f5:
@@ -1345,19 +1384,21 @@ entry:
 define i64 @f20u64(double %x) #0 {
 ; X87-LABEL: f20u64:
 ; X87:       # %bb.0: # %entry
-; X87-NEXT:    subl $20, %esp
-; X87-NEXT:    .cfi_def_cfa_offset 24
+; X87-NEXT:    subl $28, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 32
 ; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    flds {{\.?LCPI[0-9]+_[0-9]+}}
 ; X87-NEXT:    wait
 ; X87-NEXT:    xorl %edx, %edx
 ; X87-NEXT:    fcomi %st(1), %st
-; X87-NEXT:    wait
-; X87-NEXT:    setbe %dl
 ; X87-NEXT:    fldz
 ; X87-NEXT:    fcmovbe %st(1), %st
 ; X87-NEXT:    fstp %st(1)
 ; X87-NEXT:    fsubrp %st, %st(1)
+; X87-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X87-NEXT:    wait
+; X87-NEXT:    setbe %dl
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    wait
 ; X87-NEXT:    fnstcw {{[0-9]+}}(%esp)
 ; X87-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
@@ -1369,7 +1410,7 @@ define i64 @f20u64(double %x) #0 {
 ; X87-NEXT:    shll $31, %edx
 ; X87-NEXT:    xorl {{[0-9]+}}(%esp), %edx
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X87-NEXT:    addl $20, %esp
+; X87-NEXT:    addl $28, %esp
 ; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl
 ;
diff --git a/llvm/test/CodeGen/X86/fp-strict-scalar-fptoint.ll b/llvm/test/CodeGen/X86/fp-strict-scalar-fptoint.ll
index ecdc507a882c3..ff9b2f6f72973 100644
--- a/llvm/test/CodeGen/X86/fp-strict-scalar-fptoint.ll
+++ b/llvm/test/CodeGen/X86/fp-strict-scalar-fptoint.ll
@@ -683,10 +683,8 @@ define i64 @fptoui_f32toi64(float %x) #0 {
 ; X87-NEXT:    fcom %st(1)
 ; X87-NEXT:    wait
 ; X87-NEXT:    fnstsw %ax
-; X87-NEXT:    xorl %edx, %edx
 ; X87-NEXT:    # kill: def $ah killed $ah killed $ax
 ; X87-NEXT:    sahf
-; X87-NEXT:    setbe %al
 ; X87-NEXT:    fldz
 ; X87-NEXT:    jbe .LBB9_2
 ; X87-NEXT:  # %bb.1:
@@ -695,15 +693,19 @@ define i64 @fptoui_f32toi64(float %x) #0 {
 ; X87-NEXT:  .LBB9_2:
 ; X87-NEXT:    fstp %st(0)
 ; X87-NEXT:    fsubrp %st, %st(1)
+; X87-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X87-NEXT:    wait
-; X87-NEXT:    fnstcw {{[0-9]+}}(%esp)
-; X87-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
+; X87-NEXT:    setbe %al
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
+; X87-NEXT:    wait
+; X87-NEXT:    fnstcw (%esp)
+; X87-NEXT:    movzwl (%esp), %ecx
 ; X87-NEXT:    orl $3072, %ecx # imm = 0xC00
 ; X87-NEXT:    movw %cx, {{[0-9]+}}(%esp)
 ; X87-NEXT:    fldcw {{[0-9]+}}(%esp)
 ; X87-NEXT:    fistpll {{[0-9]+}}(%esp)
-; X87-NEXT:    fldcw {{[0-9]+}}(%esp)
-; X87-NEXT:    movb %al, %dl
+; X87-NEXT:    fldcw (%esp)
+; X87-NEXT:    movzbl %al, %edx
 ; X87-NEXT:    shll $31, %edx
 ; X87-NEXT:    xorl {{[0-9]+}}(%esp), %edx
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
@@ -1317,16 +1319,14 @@ define i64 @fptoui_f64toi64(double %x) #0 {
 ; X87-NEXT:    movl %esp, %ebp
 ; X87-NEXT:    .cfi_def_cfa_register %ebp
 ; X87-NEXT:    andl $-8, %esp
-; X87-NEXT:    subl $16, %esp
+; X87-NEXT:    subl $24, %esp
 ; X87-NEXT:    fldl 8(%ebp)
 ; X87-NEXT:    flds {{\.?LCPI[0-9]+_[0-9]+}}
 ; X87-NEXT:    fcom %st(1)
 ; X87-NEXT:    wait
 ; X87-NEXT:    fnstsw %ax
-; X87-NEXT:    xorl %edx, %edx
 ; X87-NEXT:    # kill: def $ah killed $ah killed $ax
 ; X87-NEXT:    sahf
-; X87-NEXT:    setbe %al
 ; X87-NEXT:    fldz
 ; X87-NEXT:    jbe .LBB18_2
 ; X87-NEXT:  # %bb.1:
@@ -1335,6 +1335,10 @@ define i64 @fptoui_f64toi64(double %x) #0 {
 ; X87-NEXT:  .LBB18_2:
 ; X87-NEXT:    fstp %st(0)
 ; X87-NEXT:    fsubrp %st, %st(1)
+; X87-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X87-NEXT:    wait
+; X87-NEXT:    setbe %al
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    wait
 ; X87-NEXT:    fnstcw {{[0-9]+}}(%esp)
 ; X87-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
@@ -1343,7 +1347,7 @@ define i64 @fptoui_f64toi64(double %x) #0 {
 ; X87-NEXT:    fldcw {{[0-9]+}}(%esp)
 ; X87-NEXT:    fistpll {{[0-9]+}}(%esp)
 ; X87-NEXT:    fldcw {{[0-9]+}}(%esp)
-; X87-NEXT:    movb %al, %dl
+; X87-NEXT:    movzbl %al, %edx
 ; X87-NEXT:    shll $31, %edx
 ; X87-NEXT:    xorl {{[0-9]+}}(%esp), %edx
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
diff --git a/llvm/test/CodeGen/X86/fp-strict-scalar.ll b/llvm/test/CodeGen/X86/fp-strict-scalar.ll
index f1be74f5c3ac4..c04c6f5b5c279 100644
--- a/llvm/test/CodeGen/X86/fp-strict-scalar.ll
+++ b/llvm/test/CodeGen/X86/fp-strict-scalar.ll
@@ -65,9 +65,18 @@ define double @fadd_f64(double %a, double %b) nounwind strictfp {
 ;
 ; X87-LABEL: fadd_f64:
 ; X87:       # %bb.0:
-; X87-NEXT:    fldl {{[0-9]+}}(%esp)
-; X87-NEXT:    faddl {{[0-9]+}}(%esp)
+; X87-NEXT:    pushl %ebp
+; X87-NEXT:    movl %esp, %ebp
+; X87-NEXT:    andl $-8, %esp
+; X87-NEXT:    subl $8, %esp
+; X87-NEXT:    fldl 8(%ebp)
+; X87-NEXT:    fldl 16(%ebp)
+; X87-NEXT:    faddp %st, %st(1)
+; X87-NEXT:    fstpl (%esp)
+; X87-NEXT:    fldl (%esp)
 ; X87-NEXT:    wait
+; X87-NEXT:    movl %ebp, %esp
+; X87-NEXT:    popl %ebp
 ; X87-NEXT:    retl
   %ret = call double @llvm.experimental.constrained.fadd.f64(double %a, double %b,
                                                              metadata !"round.dynamic",
@@ -110,9 +119,14 @@ define float @fadd_f32(float %a, float %b) nounwind strictfp {
 ;
 ; X87-LABEL: fadd_f32:
 ; X87:       # %bb.0:
+; X87-NEXT:    pushl %eax
 ; X87-NEXT:    flds {{[0-9]+}}(%esp)
-; X87-NEXT:    fadds {{[0-9]+}}(%esp)
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
+; X87-NEXT:    faddp %st, %st(1)
+; X87-NEXT:    fstps (%esp)
+; X87-NEXT:    flds (%esp)
 ; X87-NEXT:    wait
+; X87-NEXT:    popl %eax
 ; X87-NEXT:    retl
   %ret = call float @llvm.experimental.constrained.fadd.f32(float %a, float %b,
                                                             metadata !"round.dynamic",
@@ -163,9 +177,18 @@ define double @fsub_f64(double %a, double %b) nounwind strictfp {
 ;
 ; X87-LABEL: fsub_f64:
 ; X87:       # %bb.0:
-; X87-NEXT:    fldl {{[0-9]+}}(%esp)
-; X87-NEXT:    fsubl {{[0-9]+}}(%esp)
+; X87-NEXT:    pushl %ebp
+; X87-NEXT:    movl %esp, %ebp
+; X87-NEXT:    andl $-8, %esp
+; X87-NEXT:    subl $8, %esp
+; X87-NEXT:    fldl 8(%ebp)
+; X87-NEXT:    fldl 16(%ebp)
+; X87-NEXT:    fsubrp %st, %st(1)
+; X87-NEXT:    fstpl (%esp)
+; X87-NEXT:    fldl (%esp)
 ; X87-NEXT:    wait
+; X87-NEXT:    movl %ebp, %esp
+; X87-NEXT:    popl %ebp
 ; X87-NEXT:    retl
   %ret = call double @llvm.experimental.constrained.fsub.f64(double %a, double %b,
                                                              metadata !"round.dynamic",
@@ -208,9 +231,14 @@ define float @fsub_f32(float %a, float %b) nounwind strictfp {
 ;
 ; X87-LABEL: fsub_f32:
 ; X87:       # %bb.0:
+; X87-NEXT:    pushl %eax
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    flds {{[0-9]+}}(%esp)
-; X87-NEXT:    fsubs {{[0-9]+}}(%esp)
+; X87-NEXT:    fsubrp %st, %st(1)
+; X87-NEXT:    fstps (%esp)
+; X87-NEXT:    flds (%esp)
 ; X87-NEXT:    wait
+; X87-NEXT:    popl %eax
 ; X87-NEXT:    retl
   %ret = call float @llvm.experimental.constrained.fsub.f32(float %a, float %b,
                                                             metadata !"round.dynamic",
@@ -261,9 +289,18 @@ define double @fmul_f64(double %a, double %b) nounwind strictfp {
 ;
 ; X87-LABEL: fmul_f64:
 ; X87:       # %bb.0:
-; X87-NEXT:    fldl {{[0-9]+}}(%esp)
-; X87-NEXT:    fmull {{[0-9]+}}(%esp)
+; X87-NEXT:    pushl %ebp
+; X87-NEXT:    movl %esp, %ebp
+; X87-NEXT:    andl $-8, %esp
+; X87-NEXT:    subl $8, %esp
+; X87-NEXT:    fldl 8(%ebp)
+; X87-NEXT:    fldl 16(%ebp)
+; X87-NEXT:    fmulp %st, %st(1)
+; X87-NEXT:    fstpl (%esp)
+; X87-NEXT:    fldl (%esp)
 ; X87-NEXT:    wait
+; X87-NEXT:    movl %ebp, %esp
+; X87-NEXT:    popl %ebp
 ; X87-NEXT:    retl
   %ret = call double @llvm.experimental.constrained.fmul.f64(double %a, double %b,
                                                              metadata !"round.dynamic",
@@ -306,9 +343,14 @@ define float @fmul_f32(float %a, float %b) nounwind strictfp {
 ;
 ; X87-LABEL: fmul_f32:
 ; X87:       # %bb.0:
+; X87-NEXT:    pushl %eax
 ; X87-NEXT:    flds {{[0-9]+}}(%esp)
-; X87-NEXT:    fmuls {{[0-9]+}}(%esp)
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
+; X87-NEXT:    fmulp %st, %st(1)
+; X87-NEXT:    fstps (%esp)
+; X87-NEXT:    flds (%esp)
 ; X87-NEXT:    wait
+; X87-NEXT:    popl %eax
 ; X87-NEXT:    retl
   %ret = call float @llvm.experimental.constrained.fmul.f32(float %a, float %b,
                                                             metadata !"round.dynamic",
@@ -359,9 +401,18 @@ define double @fdiv_f64(double %a, double %b) nounwind strictfp {
 ;
 ; X87-LABEL: fdiv_f64:
 ; X87:       # %bb.0:
-; X87-NEXT:    fldl {{[0-9]+}}(%esp)
-; X87-NEXT:    fdivl {{[0-9]+}}(%esp)
+; X87-NEXT:    pushl %ebp
+; X87-NEXT:    movl %esp, %ebp
+; X87-NEXT:    andl $-8, %esp
+; X87-NEXT:    subl $8, %esp
+; X87-NEXT:    fldl 8(%ebp)
+; X87-NEXT:    fldl 16(%ebp)
+; X87-NEXT:    fdivrp %st, %st(1)
+; X87-NEXT:    fstpl (%esp)
+; X87-NEXT:    fldl (%esp)
 ; X87-NEXT:    wait
+; X87-NEXT:    movl %ebp, %esp
+; X87-NEXT:    popl %ebp
 ; X87-NEXT:    retl
   %ret = call double @llvm.experimental.constrained.fdiv.f64(double %a, double %b,
                                                              metadata !"round.dynamic",
@@ -404,9 +455,14 @@ define float @fdiv_f32(float %a, float %b) nounwind strictfp {
 ;
 ; X87-LABEL: fdiv_f32:
 ; X87:       # %bb.0:
+; X87-NEXT:    pushl %eax
 ; X87-NEXT:    flds {{[0-9]+}}(%esp)
-; X87-NEXT:    fdivs {{[0-9]+}}(%esp)
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
+; X87-NEXT:    fdivrp %st, %st(1)
+; X87-NEXT:    fstps (%esp)
+; X87-NEXT:    flds (%esp)
 ; X87-NEXT:    wait
+; X87-NEXT:    popl %eax
 ; X87-NEXT:    retl
   %ret = call float @llvm.experimental.constrained.fdiv.f32(float %a, float %b,
                                                             metadata !"round.dynamic",
@@ -548,11 +604,19 @@ define void @fsqrt_f64(ptr %a) nounwind strictfp {
 ;
 ; X87-LABEL: fsqrt_f64:
 ; X87:       # %bb.0:
-; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X87-NEXT:    pushl %ebp
+; X87-NEXT:    movl %esp, %ebp
+; X87-NEXT:    andl $-8, %esp
+; X87-NEXT:    subl $8, %esp
+; X87-NEXT:    movl 8(%ebp), %eax
 ; X87-NEXT:    fldl (%eax)
 ; X87-NEXT:    fsqrt
+; X87-NEXT:    fstpl (%esp)
+; X87-NEXT:    fldl (%esp)
 ; X87-NEXT:    fstpl (%eax)
 ; X87-NEXT:    wait
+; X87-NEXT:    movl %ebp, %esp
+; X87-NEXT:    popl %ebp
 ; X87-NEXT:    retl
   %1 = load double, ptr %a, align 8
   %res = call double @llvm.experimental.constrained.sqrt.f64(double %1,
@@ -595,11 +659,15 @@ define void @fsqrt_f32(ptr %a) nounwind strictfp {
 ;
 ; X87-LABEL: fsqrt_f32:
 ; X87:       # %bb.0:
+; X87-NEXT:    pushl %eax
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X87-NEXT:    flds (%eax)
 ; X87-NEXT:    fsqrt
+; X87-NEXT:    fstps (%esp)
+; X87-NEXT:    flds (%esp)
 ; X87-NEXT:    fstps (%eax)
 ; X87-NEXT:    wait
+; X87-NEXT:    popl %eax
 ; X87-NEXT:    retl
   %1 = load float, ptr %a, align 4
   %res = call float @llvm.experimental.constrained.sqrt.f32(float %1,
diff --git a/llvm/test/CodeGen/X86/fp_constant_op.ll b/llvm/test/CodeGen/X86/fp_constant_op.ll
index 36fc83508e603..df69e6aa2fdd1 100644
--- a/llvm/test/CodeGen/X86/fp_constant_op.ll
+++ b/llvm/test/CodeGen/X86/fp_constant_op.ll
@@ -7,8 +7,20 @@
 define double @foo_add(double %P) {
 ; CHECK-LABEL: foo_add:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    fld qword ptr [esp + 4]
+; CHECK-NEXT:    push ebp
+; CHECK-NEXT:    .cfi_def_cfa_offset 8
+; CHECK-NEXT:    .cfi_offset ebp, -8
+; CHECK-NEXT:    mov ebp, esp
+; CHECK-NEXT:    .cfi_def_cfa_register ebp
+; CHECK-NEXT:    and esp, -8
+; CHECK-NEXT:    sub esp, 8
+; CHECK-NEXT:    fld qword ptr [ebp + 8]
 ; CHECK-NEXT:    fadd dword ptr [{{\.?LCPI[0-9]+_[0-9]+}}]
+; CHECK-NEXT:    fstp qword ptr [esp]
+; CHECK-NEXT:    fld qword ptr [esp]
+; CHECK-NEXT:    mov esp, ebp
+; CHECK-NEXT:    pop ebp
+; CHECK-NEXT:    .cfi_def_cfa esp, 4
 ; CHECK-NEXT:    ret
 	%tmp.1 = fadd double %P, 1.230000e+02		; <double> [#uses=1]
 	ret double %tmp.1
@@ -17,8 +29,20 @@ define double @foo_add(double %P) {
 define double @foo_mul(double %P) {
 ; CHECK-LABEL: foo_mul:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    fld qword ptr [esp + 4]
+; CHECK-NEXT:    push ebp
+; CHECK-NEXT:    .cfi_def_cfa_offset 8
+; CHECK-NEXT:    .cfi_offset ebp, -8
+; CHECK-NEXT:    mov ebp, esp
+; CHECK-NEXT:    .cfi_def_cfa_register ebp
+; CHECK-NEXT:    and esp, -8
+; CHECK-NEXT:    sub esp, 8
+; CHECK-NEXT:    fld qword ptr [ebp + 8]
 ; CHECK-NEXT:    fmul dword ptr [{{\.?LCPI[0-9]+_[0-9]+}}]
+; CHECK-NEXT:    fstp qword ptr [esp]
+; CHECK-NEXT:    fld qword ptr [esp]
+; CHECK-NEXT:    mov esp, ebp
+; CHECK-NEXT:    pop ebp
+; CHECK-NEXT:    .cfi_def_cfa esp, 4
 ; CHECK-NEXT:    ret
 	%tmp.1 = fmul double %P, 1.230000e+02		; <double> [#uses=1]
 	ret double %tmp.1
@@ -27,8 +51,20 @@ define double @foo_mul(double %P) {
 define double @foo_sub(double %P) {
 ; CHECK-LABEL: foo_sub:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    fld qword ptr [esp + 4]
+; CHECK-NEXT:    push ebp
+; CHECK-NEXT:    .cfi_def_cfa_offset 8
+; CHECK-NEXT:    .cfi_offset ebp, -8
+; CHECK-NEXT:    mov ebp, esp
+; CHECK-NEXT:    .cfi_def_cfa_register ebp
+; CHECK-NEXT:    and esp, -8
+; CHECK-NEXT:    sub esp, 8
+; CHECK-NEXT:    fld qword ptr [ebp + 8]
 ; CHECK-NEXT:    fadd dword ptr [{{\.?LCPI[0-9]+_[0-9]+}}]
+; CHECK-NEXT:    fstp qword ptr [esp]
+; CHECK-NEXT:    fld qword ptr [esp]
+; CHECK-NEXT:    mov esp, ebp
+; CHECK-NEXT:    pop ebp
+; CHECK-NEXT:    .cfi_def_cfa esp, 4
 ; CHECK-NEXT:    ret
 	%tmp.1 = fsub double %P, 1.230000e+02		; <double> [#uses=1]
 	ret double %tmp.1
@@ -37,8 +73,20 @@ define double @foo_sub(double %P) {
 define double @foo_subr(double %P) {
 ; CHECK-LABEL: foo_subr:
 ; CHECK:       # %bb.0:
+; CHECK-NEXT:    push ebp
+; CHECK-NEXT:    .cfi_def_cfa_offset 8
+; CHECK-NEXT:    .cfi_offset ebp, -8
+; CHECK-NEXT:    mov ebp, esp
+; CHECK-NEXT:    .cfi_def_cfa_register ebp
+; CHECK-NEXT:    and esp, -8
+; CHECK-NEXT:    sub esp, 8
 ; CHECK-NEXT:    fld dword ptr [{{\.?LCPI[0-9]+_[0-9]+}}]
-; CHECK-NEXT:    fsub qword ptr [esp + 4]
+; CHECK-NEXT:    fsub qword ptr [ebp + 8]
+; CHECK-NEXT:    fstp qword ptr [esp]
+; CHECK-NEXT:    fld qword ptr [esp]
+; CHECK-NEXT:    mov esp, ebp
+; CHECK-NEXT:    pop ebp
+; CHECK-NEXT:    .cfi_def_cfa esp, 4
 ; CHECK-NEXT:    ret
 	%tmp.1 = fsub double 1.230000e+02, %P		; <double> [#uses=1]
 	ret double %tmp.1
@@ -47,8 +95,20 @@ define double @foo_subr(double %P) {
 define double @foo_div(double %P) {
 ; CHECK-LABEL: foo_div:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    fld qword ptr [esp + 4]
+; CHECK-NEXT:    push ebp
+; CHECK-NEXT:    .cfi_def_cfa_offset 8
+; CHECK-NEXT:    .cfi_offset ebp, -8
+; CHECK-NEXT:    mov ebp, esp
+; CHECK-NEXT:    .cfi_def_cfa_register ebp
+; CHECK-NEXT:    and esp, -8
+; CHECK-NEXT:    sub esp, 8
+; CHECK-NEXT:    fld qword ptr [ebp + 8]
 ; CHECK-NEXT:    fdiv dword ptr [{{\.?LCPI[0-9]+_[0-9]+}}]
+; CHECK-NEXT:    fstp qword ptr [esp]
+; CHECK-NEXT:    fld qword ptr [esp]
+; CHECK-NEXT:    mov esp, ebp
+; CHECK-NEXT:    pop ebp
+; CHECK-NEXT:    .cfi_def_cfa esp, 4
 ; CHECK-NEXT:    ret
 	%tmp.1 = fdiv double %P, 1.230000e+02		; <double> [#uses=1]
 	ret double %tmp.1
@@ -57,8 +117,20 @@ define double @foo_div(double %P) {
 define double @foo_divr(double %P) {
 ; CHECK-LABEL: foo_divr:
 ; CHECK:       # %bb.0:
+; CHECK-NEXT:    push ebp
+; CHECK-NEXT:    .cfi_def_cfa_offset 8
+; CHECK-NEXT:    .cfi_offset ebp, -8
+; CHECK-NEXT:    mov ebp, esp
+; CHECK-NEXT:    .cfi_def_cfa_register ebp
+; CHECK-NEXT:    and esp, -8
+; CHECK-NEXT:    sub esp, 8
 ; CHECK-NEXT:    fld dword ptr [{{\.?LCPI[0-9]+_[0-9]+}}]
-; CHECK-NEXT:    fdiv qword ptr [esp + 4]
+; CHECK-NEXT:    fdiv qword ptr [ebp + 8]
+; CHECK-NEXT:    fstp qword ptr [esp]
+; CHECK-NEXT:    fld qword ptr [esp]
+; CHECK-NEXT:    mov esp, ebp
+; CHECK-NEXT:    pop ebp
+; CHECK-NEXT:    .cfi_def_cfa esp, 4
 ; CHECK-NEXT:    ret
 	%tmp.1 = fdiv double 1.230000e+02, %P		; <double> [#uses=1]
 	ret double %tmp.1
diff --git a/llvm/test/CodeGen/X86/fp_load_fold.ll b/llvm/test/CodeGen/X86/fp_load_fold.ll
index 58d2b686a8697..38b1562661005 100644
--- a/llvm/test/CodeGen/X86/fp_load_fold.ll
+++ b/llvm/test/CodeGen/X86/fp_load_fold.ll
@@ -6,9 +6,21 @@
 define double @test_add(double %X, ptr %P) {
 ; CHECK-LABEL: test_add:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    mov eax, dword ptr [esp + 12]
-; CHECK-NEXT:    fld qword ptr [esp + 4]
+; CHECK-NEXT:    push ebp
+; CHECK-NEXT:    .cfi_def_cfa_offset 8
+; CHECK-NEXT:    .cfi_offset ebp, -8
+; CHECK-NEXT:    mov ebp, esp
+; CHECK-NEXT:    .cfi_def_cfa_register ebp
+; CHECK-NEXT:    and esp, -8
+; CHECK-NEXT:    sub esp, 8
+; CHECK-NEXT:    mov eax, dword ptr [ebp + 16]
+; CHECK-NEXT:    fld qword ptr [ebp + 8]
 ; CHECK-NEXT:    fadd qword ptr [eax]
+; CHECK-NEXT:    fstp qword ptr [esp]
+; CHECK-NEXT:    fld qword ptr [esp]
+; CHECK-NEXT:    mov esp, ebp
+; CHECK-NEXT:    pop ebp
+; CHECK-NEXT:    .cfi_def_cfa esp, 4
 ; CHECK-NEXT:    ret
 	%Y = load double, ptr %P		; <double> [#uses=1]
 	%R = fadd double %X, %Y		; <double> [#uses=1]
@@ -18,9 +30,21 @@ define double @test_add(double %X, ptr %P) {
 define double @test_mul(double %X, ptr %P) {
 ; CHECK-LABEL: test_mul:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    mov eax, dword ptr [esp + 12]
-; CHECK-NEXT:    fld qword ptr [esp + 4]
+; CHECK-NEXT:    push ebp
+; CHECK-NEXT:    .cfi_def_cfa_offset 8
+; CHECK-NEXT:    .cfi_offset ebp, -8
+; CHECK-NEXT:    mov ebp, esp
+; CHECK-NEXT:    .cfi_def_cfa_register ebp
+; CHECK-NEXT:    and esp, -8
+; CHECK-NEXT:    sub esp, 8
+; CHECK-NEXT:    mov eax, dword ptr [ebp + 16]
+; CHECK-NEXT:    fld qword ptr [ebp + 8]
 ; CHECK-NEXT:    fmul qword ptr [eax]
+; CHECK-NEXT:    fstp qword ptr [esp]
+; CHECK-NEXT:    fld qword ptr [esp]
+; CHECK-NEXT:    mov esp, ebp
+; CHECK-NEXT:    pop ebp
+; CHECK-NEXT:    .cfi_def_cfa esp, 4
 ; CHECK-NEXT:    ret
 	%Y = load double, ptr %P		; <double> [#uses=1]
 	%R = fmul double %X, %Y		; <double> [#uses=1]
@@ -30,9 +54,21 @@ define double @test_mul(double %X, ptr %P) {
 define double @test_sub(double %X, ptr %P) {
 ; CHECK-LABEL: test_sub:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    mov eax, dword ptr [esp + 12]
-; CHECK-NEXT:    fld qword ptr [esp + 4]
+; CHECK-NEXT:    push ebp
+; CHECK-NEXT:    .cfi_def_cfa_offset 8
+; CHECK-NEXT:    .cfi_offset ebp, -8
+; CHECK-NEXT:    mov ebp, esp
+; CHECK-NEXT:    .cfi_def_cfa_register ebp
+; CHECK-NEXT:    and esp, -8
+; CHECK-NEXT:    sub esp, 8
+; CHECK-NEXT:    mov eax, dword ptr [ebp + 16]
+; CHECK-NEXT:    fld qword ptr [ebp + 8]
 ; CHECK-NEXT:    fsub qword ptr [eax]
+; CHECK-NEXT:    fstp qword ptr [esp]
+; CHECK-NEXT:    fld qword ptr [esp]
+; CHECK-NEXT:    mov esp, ebp
+; CHECK-NEXT:    pop ebp
+; CHECK-NEXT:    .cfi_def_cfa esp, 4
 ; CHECK-NEXT:    ret
 	%Y = load double, ptr %P		; <double> [#uses=1]
 	%R = fsub double %X, %Y		; <double> [#uses=1]
@@ -42,9 +78,21 @@ define double @test_sub(double %X, ptr %P) {
 define double @test_subr(double %X, ptr %P) {
 ; CHECK-LABEL: test_subr:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    mov eax, dword ptr [esp + 12]
+; CHECK-NEXT:    push ebp
+; CHECK-NEXT:    .cfi_def_cfa_offset 8
+; CHECK-NEXT:    .cfi_offset ebp, -8
+; CHECK-NEXT:    mov ebp, esp
+; CHECK-NEXT:    .cfi_def_cfa_register ebp
+; CHECK-NEXT:    and esp, -8
+; CHECK-NEXT:    sub esp, 8
+; CHECK-NEXT:    mov eax, dword ptr [ebp + 16]
 ; CHECK-NEXT:    fld qword ptr [eax]
-; CHECK-NEXT:    fsub qword ptr [esp + 4]
+; CHECK-NEXT:    fsub qword ptr [ebp + 8]
+; CHECK-NEXT:    fstp qword ptr [esp]
+; CHECK-NEXT:    fld qword ptr [esp]
+; CHECK-NEXT:    mov esp, ebp
+; CHECK-NEXT:    pop ebp
+; CHECK-NEXT:    .cfi_def_cfa esp, 4
 ; CHECK-NEXT:    ret
 	%Y = load double, ptr %P		; <double> [#uses=1]
 	%R = fsub double %Y, %X		; <double> [#uses=1]
@@ -54,9 +102,21 @@ define double @test_subr(double %X, ptr %P) {
 define double @test_div(double %X, ptr %P) {
 ; CHECK-LABEL: test_div:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    mov eax, dword ptr [esp + 12]
-; CHECK-NEXT:    fld qword ptr [esp + 4]
+; CHECK-NEXT:    push ebp
+; CHECK-NEXT:    .cfi_def_cfa_offset 8
+; CHECK-NEXT:    .cfi_offset ebp, -8
+; CHECK-NEXT:    mov ebp, esp
+; CHECK-NEXT:    .cfi_def_cfa_register ebp
+; CHECK-NEXT:    and esp, -8
+; CHECK-NEXT:    sub esp, 8
+; CHECK-NEXT:    mov eax, dword ptr [ebp + 16]
+; CHECK-NEXT:    fld qword ptr [ebp + 8]
 ; CHECK-NEXT:    fdiv qword ptr [eax]
+; CHECK-NEXT:    fstp qword ptr [esp]
+; CHECK-NEXT:    fld qword ptr [esp]
+; CHECK-NEXT:    mov esp, ebp
+; CHECK-NEXT:    pop ebp
+; CHECK-NEXT:    .cfi_def_cfa esp, 4
 ; CHECK-NEXT:    ret
 	%Y = load double, ptr %P		; <double> [#uses=1]
 	%R = fdiv double %X, %Y		; <double> [#uses=1]
@@ -66,9 +126,21 @@ define double @test_div(double %X, ptr %P) {
 define double @test_divr(double %X, ptr %P) {
 ; CHECK-LABEL: test_divr:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    mov eax, dword ptr [esp + 12]
+; CHECK-NEXT:    push ebp
+; CHECK-NEXT:    .cfi_def_cfa_offset 8
+; CHECK-NEXT:    .cfi_offset ebp, -8
+; CHECK-NEXT:    mov ebp, esp
+; CHECK-NEXT:    .cfi_def_cfa_register ebp
+; CHECK-NEXT:    and esp, -8
+; CHECK-NEXT:    sub esp, 8
+; CHECK-NEXT:    mov eax, dword ptr [ebp + 16]
 ; CHECK-NEXT:    fld qword ptr [eax]
-; CHECK-NEXT:    fdiv qword ptr [esp + 4]
+; CHECK-NEXT:    fdiv qword ptr [ebp + 8]
+; CHECK-NEXT:    fstp qword ptr [esp]
+; CHECK-NEXT:    fld qword ptr [esp]
+; CHECK-NEXT:    mov esp, ebp
+; CHECK-NEXT:    pop ebp
+; CHECK-NEXT:    .cfi_def_cfa esp, 4
 ; CHECK-NEXT:    ret
 	%Y = load double, ptr %P		; <double> [#uses=1]
 	%R = fdiv double %Y, %X		; <double> [#uses=1]
diff --git a/llvm/test/CodeGen/X86/fptoui-sat-scalar.ll b/llvm/test/CodeGen/X86/fptoui-sat-scalar.ll
index a074c78d512f5..1d7d29db2daab 100644
--- a/llvm/test/CodeGen/X86/fptoui-sat-scalar.ll
+++ b/llvm/test/CodeGen/X86/fptoui-sat-scalar.ll
@@ -410,10 +410,8 @@ define i50 @test_unsigned_i50_f32(float %f) nounwind {
 ; X86-X87-NEXT:    flds {{\.?LCPI[0-9]+_[0-9]+}}
 ; X86-X87-NEXT:    fucom %st(1)
 ; X86-X87-NEXT:    fnstsw %ax
-; X86-X87-NEXT:    xorl %ecx, %ecx
 ; X86-X87-NEXT:    # kill: def $ah killed $ah killed $ax
 ; X86-X87-NEXT:    sahf
-; X86-X87-NEXT:    setbe %al
 ; X86-X87-NEXT:    fldz
 ; X86-X87-NEXT:    jbe .LBB6_2
 ; X86-X87-NEXT:  # %bb.1:
@@ -423,16 +421,19 @@ define i50 @test_unsigned_i50_f32(float %f) nounwind {
 ; X86-X87-NEXT:  .LBB6_2:
 ; X86-X87-NEXT:    fxch %st(1)
 ; X86-X87-NEXT:    fsubr %st(2), %st
-; X86-X87-NEXT:    fnstcw {{[0-9]+}}(%esp)
-; X86-X87-NEXT:    movzwl {{[0-9]+}}(%esp), %edx
-; X86-X87-NEXT:    orl $3072, %edx # imm = 0xC00
-; X86-X87-NEXT:    movw %dx, {{[0-9]+}}(%esp)
+; X86-X87-NEXT:    fstps {{[0-9]+}}(%esp)
+; X86-X87-NEXT:    setbe %al
+; X86-X87-NEXT:    flds {{[0-9]+}}(%esp)
+; X86-X87-NEXT:    fnstcw (%esp)
+; X86-X87-NEXT:    movzwl (%esp), %ecx
+; X86-X87-NEXT:    orl $3072, %ecx # imm = 0xC00
+; X86-X87-NEXT:    movw %cx, {{[0-9]+}}(%esp)
 ; X86-X87-NEXT:    fldcw {{[0-9]+}}(%esp)
 ; X86-X87-NEXT:    fistpll {{[0-9]+}}(%esp)
-; X86-X87-NEXT:    fldcw {{[0-9]+}}(%esp)
-; X86-X87-NEXT:    movb %al, %cl
-; X86-X87-NEXT:    shll $31, %ecx
-; X86-X87-NEXT:    xorl {{[0-9]+}}(%esp), %ecx
+; X86-X87-NEXT:    fldcw (%esp)
+; X86-X87-NEXT:    movzbl %al, %esi
+; X86-X87-NEXT:    shll $31, %esi
+; X86-X87-NEXT:    xorl {{[0-9]+}}(%esp), %esi
 ; X86-X87-NEXT:    fxch %st(1)
 ; X86-X87-NEXT:    fucom %st(1)
 ; X86-X87-NEXT:    fstp %st(1)
@@ -440,10 +441,10 @@ define i50 @test_unsigned_i50_f32(float %f) nounwind {
 ; X86-X87-NEXT:    xorl %edx, %edx
 ; X86-X87-NEXT:    # kill: def $ah killed $ah killed $ax
 ; X86-X87-NEXT:    sahf
-; X86-X87-NEXT:    movl $0, %esi
+; X86-X87-NEXT:    movl $0, %ecx
 ; X86-X87-NEXT:    jb .LBB6_4
 ; X86-X87-NEXT:  # %bb.3:
-; X86-X87-NEXT:    movl %ecx, %esi
+; X86-X87-NEXT:    movl %esi, %ecx
 ; X86-X87-NEXT:  .LBB6_4:
 ; X86-X87-NEXT:    jb .LBB6_6
 ; X86-X87-NEXT:  # %bb.5:
@@ -463,7 +464,7 @@ define i50 @test_unsigned_i50_f32(float %f) nounwind {
 ; X86-X87-NEXT:    movl $262143, %edx # imm = 0x3FFFF
 ; X86-X87-NEXT:    ja .LBB6_10
 ; X86-X87-NEXT:  # %bb.9:
-; X86-X87-NEXT:    movl %esi, %edx
+; X86-X87-NEXT:    movl %ecx, %edx
 ; X86-X87-NEXT:  .LBB6_10:
 ; X86-X87-NEXT:    addl $16, %esp
 ; X86-X87-NEXT:    popl %esi
@@ -530,17 +531,14 @@ define i50 @test_unsigned_i50_f32(float %f) nounwind {
 define i64 @test_unsigned_i64_f32(float %f) nounwind {
 ; X86-X87-LABEL: test_unsigned_i64_f32:
 ; X86-X87:       # %bb.0:
-; X86-X87-NEXT:    pushl %edi
 ; X86-X87-NEXT:    pushl %esi
-; X86-X87-NEXT:    subl $20, %esp
+; X86-X87-NEXT:    subl $16, %esp
 ; X86-X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X86-X87-NEXT:    flds {{\.?LCPI[0-9]+_[0-9]+}}
 ; X86-X87-NEXT:    fucom %st(1)
 ; X86-X87-NEXT:    fnstsw %ax
-; X86-X87-NEXT:    xorl %ecx, %ecx
 ; X86-X87-NEXT:    # kill: def $ah killed $ah killed $ax
 ; X86-X87-NEXT:    sahf
-; X86-X87-NEXT:    setbe %al
 ; X86-X87-NEXT:    fldz
 ; X86-X87-NEXT:    jbe .LBB7_2
 ; X86-X87-NEXT:  # %bb.1:
@@ -550,31 +548,34 @@ define i64 @test_unsigned_i64_f32(float %f) nounwind {
 ; X86-X87-NEXT:  .LBB7_2:
 ; X86-X87-NEXT:    fxch %st(1)
 ; X86-X87-NEXT:    fsubr %st(2), %st
-; X86-X87-NEXT:    fnstcw {{[0-9]+}}(%esp)
-; X86-X87-NEXT:    movzwl {{[0-9]+}}(%esp), %edx
-; X86-X87-NEXT:    orl $3072, %edx # imm = 0xC00
-; X86-X87-NEXT:    movw %dx, {{[0-9]+}}(%esp)
+; X86-X87-NEXT:    fstps {{[0-9]+}}(%esp)
+; X86-X87-NEXT:    setbe %al
+; X86-X87-NEXT:    flds {{[0-9]+}}(%esp)
+; X86-X87-NEXT:    fnstcw (%esp)
+; X86-X87-NEXT:    movzwl (%esp), %ecx
+; X86-X87-NEXT:    orl $3072, %ecx # imm = 0xC00
+; X86-X87-NEXT:    movw %cx, {{[0-9]+}}(%esp)
 ; X86-X87-NEXT:    fldcw {{[0-9]+}}(%esp)
 ; X86-X87-NEXT:    fistpll {{[0-9]+}}(%esp)
-; X86-X87-NEXT:    fldcw {{[0-9]+}}(%esp)
-; X86-X87-NEXT:    movb %al, %cl
-; X86-X87-NEXT:    shll $31, %ecx
-; X86-X87-NEXT:    xorl {{[0-9]+}}(%esp), %ecx
+; X86-X87-NEXT:    fldcw (%esp)
+; X86-X87-NEXT:    movzbl %al, %edx
+; X86-X87-NEXT:    shll $31, %edx
+; X86-X87-NEXT:    xorl {{[0-9]+}}(%esp), %edx
 ; X86-X87-NEXT:    fxch %st(1)
 ; X86-X87-NEXT:    fucom %st(1)
 ; X86-X87-NEXT:    fstp %st(1)
 ; X86-X87-NEXT:    fnstsw %ax
-; X86-X87-NEXT:    xorl %esi, %esi
+; X86-X87-NEXT:    xorl %ecx, %ecx
 ; X86-X87-NEXT:    # kill: def $ah killed $ah killed $ax
 ; X86-X87-NEXT:    sahf
-; X86-X87-NEXT:    movl $0, %edi
+; X86-X87-NEXT:    movl $0, %esi
 ; X86-X87-NEXT:    jb .LBB7_4
 ; X86-X87-NEXT:  # %bb.3:
-; X86-X87-NEXT:    movl %ecx, %edi
+; X86-X87-NEXT:    movl %edx, %esi
 ; X86-X87-NEXT:  .LBB7_4:
 ; X86-X87-NEXT:    jb .LBB7_6
 ; X86-X87-NEXT:  # %bb.5:
-; X86-X87-NEXT:    movl {{[0-9]+}}(%esp), %esi
+; X86-X87-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; X86-X87-NEXT:  .LBB7_6:
 ; X86-X87-NEXT:    flds {{\.?LCPI[0-9]+_[0-9]+}}
 ; X86-X87-NEXT:    fxch %st(1)
@@ -586,12 +587,11 @@ define i64 @test_unsigned_i64_f32(float %f) nounwind {
 ; X86-X87-NEXT:    movl $-1, %edx
 ; X86-X87-NEXT:    ja .LBB7_8
 ; X86-X87-NEXT:  # %bb.7:
-; X86-X87-NEXT:    movl %esi, %eax
-; X86-X87-NEXT:    movl %edi, %edx
+; X86-X87-NEXT:    movl %ecx, %eax
+; X86-X87-NEXT:    movl %esi, %edx
 ; X86-X87-NEXT:  .LBB7_8:
-; X86-X87-NEXT:    addl $20, %esp
+; X86-X87-NEXT:    addl $16, %esp
 ; X86-X87-NEXT:    popl %esi
-; X86-X87-NEXT:    popl %edi
 ; X86-X87-NEXT:    retl
 ;
 ; X86-SSE-LABEL: test_unsigned_i64_f32:
@@ -1333,15 +1333,13 @@ define i50 @test_unsigned_i50_f64(double %f) nounwind {
 ; X86-X87-LABEL: test_unsigned_i50_f64:
 ; X86-X87:       # %bb.0:
 ; X86-X87-NEXT:    pushl %esi
-; X86-X87-NEXT:    subl $16, %esp
+; X86-X87-NEXT:    subl $24, %esp
 ; X86-X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-X87-NEXT:    flds {{\.?LCPI[0-9]+_[0-9]+}}
 ; X86-X87-NEXT:    fucom %st(1)
 ; X86-X87-NEXT:    fnstsw %ax
-; X86-X87-NEXT:    xorl %ecx, %ecx
 ; X86-X87-NEXT:    # kill: def $ah killed $ah killed $ax
 ; X86-X87-NEXT:    sahf
-; X86-X87-NEXT:    setbe %al
 ; X86-X87-NEXT:    fldz
 ; X86-X87-NEXT:    jbe .LBB16_2
 ; X86-X87-NEXT:  # %bb.1:
@@ -1351,16 +1349,19 @@ define i50 @test_unsigned_i50_f64(double %f) nounwind {
 ; X86-X87-NEXT:  .LBB16_2:
 ; X86-X87-NEXT:    fxch %st(1)
 ; X86-X87-NEXT:    fsubr %st(2), %st
+; X86-X87-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-X87-NEXT:    setbe %al
+; X86-X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-X87-NEXT:    fnstcw {{[0-9]+}}(%esp)
-; X86-X87-NEXT:    movzwl {{[0-9]+}}(%esp), %edx
-; X86-X87-NEXT:    orl $3072, %edx # imm = 0xC00
-; X86-X87-NEXT:    movw %dx, {{[0-9]+}}(%esp)
+; X86-X87-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
+; X86-X87-NEXT:    orl $3072, %ecx # imm = 0xC00
+; X86-X87-NEXT:    movw %cx, {{[0-9]+}}(%esp)
 ; X86-X87-NEXT:    fldcw {{[0-9]+}}(%esp)
 ; X86-X87-NEXT:    fistpll {{[0-9]+}}(%esp)
 ; X86-X87-NEXT:    fldcw {{[0-9]+}}(%esp)
-; X86-X87-NEXT:    movb %al, %cl
-; X86-X87-NEXT:    shll $31, %ecx
-; X86-X87-NEXT:    xorl {{[0-9]+}}(%esp), %ecx
+; X86-X87-NEXT:    movzbl %al, %esi
+; X86-X87-NEXT:    shll $31, %esi
+; X86-X87-NEXT:    xorl {{[0-9]+}}(%esp), %esi
 ; X86-X87-NEXT:    fxch %st(1)
 ; X86-X87-NEXT:    fucom %st(1)
 ; X86-X87-NEXT:    fstp %st(1)
@@ -1368,10 +1369,10 @@ define i50 @test_unsigned_i50_f64(double %f) nounwind {
 ; X86-X87-NEXT:    xorl %edx, %edx
 ; X86-X87-NEXT:    # kill: def $ah killed $ah killed $ax
 ; X86-X87-NEXT:    sahf
-; X86-X87-NEXT:    movl $0, %esi
+; X86-X87-NEXT:    movl $0, %ecx
 ; X86-X87-NEXT:    jb .LBB16_4
 ; X86-X87-NEXT:  # %bb.3:
-; X86-X87-NEXT:    movl %ecx, %esi
+; X86-X87-NEXT:    movl %esi, %ecx
 ; X86-X87-NEXT:  .LBB16_4:
 ; X86-X87-NEXT:    jb .LBB16_6
 ; X86-X87-NEXT:  # %bb.5:
@@ -1391,9 +1392,9 @@ define i50 @test_unsigned_i50_f64(double %f) nounwind {
 ; X86-X87-NEXT:    movl $262143, %edx # imm = 0x3FFFF
 ; X86-X87-NEXT:    ja .LBB16_10
 ; X86-X87-NEXT:  # %bb.9:
-; X86-X87-NEXT:    movl %esi, %edx
+; X86-X87-NEXT:    movl %ecx, %edx
 ; X86-X87-NEXT:  .LBB16_10:
-; X86-X87-NEXT:    addl $16, %esp
+; X86-X87-NEXT:    addl $24, %esp
 ; X86-X87-NEXT:    popl %esi
 ; X86-X87-NEXT:    retl
 ;
@@ -1442,17 +1443,14 @@ define i50 @test_unsigned_i50_f64(double %f) nounwind {
 define i64 @test_unsigned_i64_f64(double %f) nounwind {
 ; X86-X87-LABEL: test_unsigned_i64_f64:
 ; X86-X87:       # %bb.0:
-; X86-X87-NEXT:    pushl %edi
 ; X86-X87-NEXT:    pushl %esi
-; X86-X87-NEXT:    subl $20, %esp
+; X86-X87-NEXT:    subl $24, %esp
 ; X86-X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-X87-NEXT:    flds {{\.?LCPI[0-9]+_[0-9]+}}
 ; X86-X87-NEXT:    fucom %st(1)
 ; X86-X87-NEXT:    fnstsw %ax
-; X86-X87-NEXT:    xorl %ecx, %ecx
 ; X86-X87-NEXT:    # kill: def $ah killed $ah killed $ax
 ; X86-X87-NEXT:    sahf
-; X86-X87-NEXT:    setbe %al
 ; X86-X87-NEXT:    fldz
 ; X86-X87-NEXT:    jbe .LBB17_2
 ; X86-X87-NEXT:  # %bb.1:
@@ -1462,31 +1460,34 @@ define i64 @test_unsigned_i64_f64(double %f) nounwind {
 ; X86-X87-NEXT:  .LBB17_2:
 ; X86-X87-NEXT:    fxch %st(1)
 ; X86-X87-NEXT:    fsubr %st(2), %st
+; X86-X87-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-X87-NEXT:    setbe %al
+; X86-X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-X87-NEXT:    fnstcw {{[0-9]+}}(%esp)
-; X86-X87-NEXT:    movzwl {{[0-9]+}}(%esp), %edx
-; X86-X87-NEXT:    orl $3072, %edx # imm = 0xC00
-; X86-X87-NEXT:    movw %dx, {{[0-9]+}}(%esp)
+; X86-X87-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
+; X86-X87-NEXT:    orl $3072, %ecx # imm = 0xC00
+; X86-X87-NEXT:    movw %cx, {{[0-9]+}}(%esp)
 ; X86-X87-NEXT:    fldcw {{[0-9]+}}(%esp)
 ; X86-X87-NEXT:    fistpll {{[0-9]+}}(%esp)
 ; X86-X87-NEXT:    fldcw {{[0-9]+}}(%esp)
-; X86-X87-NEXT:    movb %al, %cl
-; X86-X87-NEXT:    shll $31, %ecx
-; X86-X87-NEXT:    xorl {{[0-9]+}}(%esp), %ecx
+; X86-X87-NEXT:    movzbl %al, %edx
+; X86-X87-NEXT:    shll $31, %edx
+; X86-X87-NEXT:    xorl {{[0-9]+}}(%esp), %edx
 ; X86-X87-NEXT:    fxch %st(1)
 ; X86-X87-NEXT:    fucom %st(1)
 ; X86-X87-NEXT:    fstp %st(1)
 ; X86-X87-NEXT:    fnstsw %ax
-; X86-X87-NEXT:    xorl %esi, %esi
+; X86-X87-NEXT:    xorl %ecx, %ecx
 ; X86-X87-NEXT:    # kill: def $ah killed $ah killed $ax
 ; X86-X87-NEXT:    sahf
-; X86-X87-NEXT:    movl $0, %edi
+; X86-X87-NEXT:    movl $0, %esi
 ; X86-X87-NEXT:    jb .LBB17_4
 ; X86-X87-NEXT:  # %bb.3:
-; X86-X87-NEXT:    movl %ecx, %edi
+; X86-X87-NEXT:    movl %edx, %esi
 ; X86-X87-NEXT:  .LBB17_4:
 ; X86-X87-NEXT:    jb .LBB17_6
 ; X86-X87-NEXT:  # %bb.5:
-; X86-X87-NEXT:    movl {{[0-9]+}}(%esp), %esi
+; X86-X87-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; X86-X87-NEXT:  .LBB17_6:
 ; X86-X87-NEXT:    fldl {{\.?LCPI[0-9]+_[0-9]+}}
 ; X86-X87-NEXT:    fxch %st(1)
@@ -1498,12 +1499,11 @@ define i64 @test_unsigned_i64_f64(double %f) nounwind {
 ; X86-X87-NEXT:    movl $-1, %edx
 ; X86-X87-NEXT:    ja .LBB17_8
 ; X86-X87-NEXT:  # %bb.7:
-; X86-X87-NEXT:    movl %esi, %eax
-; X86-X87-NEXT:    movl %edi, %edx
+; X86-X87-NEXT:    movl %ecx, %eax
+; X86-X87-NEXT:    movl %esi, %edx
 ; X86-X87-NEXT:  .LBB17_8:
-; X86-X87-NEXT:    addl $20, %esp
+; X86-X87-NEXT:    addl $24, %esp
 ; X86-X87-NEXT:    popl %esi
-; X86-X87-NEXT:    popl %edi
 ; X86-X87-NEXT:    retl
 ;
 ; X86-SSE-LABEL: test_unsigned_i64_f64:
@@ -2335,10 +2335,8 @@ define i50 @test_unsigned_i50_f16(half %f) nounwind {
 ; X86-X87-NEXT:    fxch %st(1)
 ; X86-X87-NEXT:    fucom %st(1)
 ; X86-X87-NEXT:    fnstsw %ax
-; X86-X87-NEXT:    xorl %ecx, %ecx
 ; X86-X87-NEXT:    # kill: def $ah killed $ah killed $ax
 ; X86-X87-NEXT:    sahf
-; X86-X87-NEXT:    setae %al
 ; X86-X87-NEXT:    fldz
 ; X86-X87-NEXT:    jae .LBB26_2
 ; X86-X87-NEXT:  # %bb.1:
@@ -2348,26 +2346,29 @@ define i50 @test_unsigned_i50_f16(half %f) nounwind {
 ; X86-X87-NEXT:  .LBB26_2:
 ; X86-X87-NEXT:    fxch %st(2)
 ; X86-X87-NEXT:    fsubr %st(1), %st
+; X86-X87-NEXT:    fstps {{[0-9]+}}(%esp)
+; X86-X87-NEXT:    setae %al
+; X86-X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X86-X87-NEXT:    fnstcw {{[0-9]+}}(%esp)
-; X86-X87-NEXT:    movzwl {{[0-9]+}}(%esp), %edx
-; X86-X87-NEXT:    orl $3072, %edx # imm = 0xC00
-; X86-X87-NEXT:    movw %dx, {{[0-9]+}}(%esp)
+; X86-X87-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
+; X86-X87-NEXT:    orl $3072, %ecx # imm = 0xC00
+; X86-X87-NEXT:    movw %cx, {{[0-9]+}}(%esp)
 ; X86-X87-NEXT:    fldcw {{[0-9]+}}(%esp)
 ; X86-X87-NEXT:    fistpll {{[0-9]+}}(%esp)
 ; X86-X87-NEXT:    fldcw {{[0-9]+}}(%esp)
-; X86-X87-NEXT:    movb %al, %cl
-; X86-X87-NEXT:    shll $31, %ecx
-; X86-X87-NEXT:    xorl {{[0-9]+}}(%esp), %ecx
+; X86-X87-NEXT:    movzbl %al, %esi
+; X86-X87-NEXT:    shll $31, %esi
+; X86-X87-NEXT:    xorl {{[0-9]+}}(%esp), %esi
 ; X86-X87-NEXT:    fucom %st(1)
 ; X86-X87-NEXT:    fstp %st(1)
 ; X86-X87-NEXT:    fnstsw %ax
 ; X86-X87-NEXT:    xorl %edx, %edx
 ; X86-X87-NEXT:    # kill: def $ah killed $ah killed $ax
 ; X86-X87-NEXT:    sahf
-; X86-X87-NEXT:    movl $0, %esi
+; X86-X87-NEXT:    movl $0, %ecx
 ; X86-X87-NEXT:    jb .LBB26_4
 ; X86-X87-NEXT:  # %bb.3:
-; X86-X87-NEXT:    movl %ecx, %esi
+; X86-X87-NEXT:    movl %esi, %ecx
 ; X86-X87-NEXT:  .LBB26_4:
 ; X86-X87-NEXT:    jb .LBB26_6
 ; X86-X87-NEXT:  # %bb.5:
@@ -2387,7 +2388,7 @@ define i50 @test_unsigned_i50_f16(half %f) nounwind {
 ; X86-X87-NEXT:    movl $262143, %edx # imm = 0x3FFFF
 ; X86-X87-NEXT:    ja .LBB26_10
 ; X86-X87-NEXT:  # %bb.9:
-; X86-X87-NEXT:    movl %esi, %edx
+; X86-X87-NEXT:    movl %ecx, %edx
 ; X86-X87-NEXT:  .LBB26_10:
 ; X86-X87-NEXT:    addl $24, %esp
 ; X86-X87-NEXT:    popl %esi
@@ -2469,9 +2470,8 @@ define i50 @test_unsigned_i50_f16(half %f) nounwind {
 define i64 @test_unsigned_i64_f16(half %f) nounwind {
 ; X86-X87-LABEL: test_unsigned_i64_f16:
 ; X86-X87:       # %bb.0:
-; X86-X87-NEXT:    pushl %edi
 ; X86-X87-NEXT:    pushl %esi
-; X86-X87-NEXT:    subl $20, %esp
+; X86-X87-NEXT:    subl $24, %esp
 ; X86-X87-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
 ; X86-X87-NEXT:    movl %eax, (%esp)
 ; X86-X87-NEXT:    calll __extendhfsf2
@@ -2479,10 +2479,8 @@ define i64 @test_unsigned_i64_f16(half %f) nounwind {
 ; X86-X87-NEXT:    fxch %st(1)
 ; X86-X87-NEXT:    fucom %st(1)
 ; X86-X87-NEXT:    fnstsw %ax
-; X86-X87-NEXT:    xorl %ecx, %ecx
 ; X86-X87-NEXT:    # kill: def $ah killed $ah killed $ax
 ; X86-X87-NEXT:    sahf
-; X86-X87-NEXT:    setae %al
 ; X86-X87-NEXT:    fldz
 ; X86-X87-NEXT:    jae .LBB27_2
 ; X86-X87-NEXT:  # %bb.1:
@@ -2492,30 +2490,33 @@ define i64 @test_unsigned_i64_f16(half %f) nounwind {
 ; X86-X87-NEXT:  .LBB27_2:
 ; X86-X87-NEXT:    fxch %st(2)
 ; X86-X87-NEXT:    fsubr %st(1), %st
+; X86-X87-NEXT:    fstps {{[0-9]+}}(%esp)
+; X86-X87-NEXT:    setae %al
+; X86-X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X86-X87-NEXT:    fnstcw {{[0-9]+}}(%esp)
-; X86-X87-NEXT:    movzwl {{[0-9]+}}(%esp), %edx
-; X86-X87-NEXT:    orl $3072, %edx # imm = 0xC00
-; X86-X87-NEXT:    movw %dx, {{[0-9]+}}(%esp)
+; X86-X87-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
+; X86-X87-NEXT:    orl $3072, %ecx # imm = 0xC00
+; X86-X87-NEXT:    movw %cx, {{[0-9]+}}(%esp)
 ; X86-X87-NEXT:    fldcw {{[0-9]+}}(%esp)
 ; X86-X87-NEXT:    fistpll {{[0-9]+}}(%esp)
 ; X86-X87-NEXT:    fldcw {{[0-9]+}}(%esp)
-; X86-X87-NEXT:    movb %al, %cl
-; X86-X87-NEXT:    shll $31, %ecx
-; X86-X87-NEXT:    xorl {{[0-9]+}}(%esp), %ecx
+; X86-X87-NEXT:    movzbl %al, %edx
+; X86-X87-NEXT:    shll $31, %edx
+; X86-X87-NEXT:    xorl {{[0-9]+}}(%esp), %edx
 ; X86-X87-NEXT:    fucom %st(1)
 ; X86-X87-NEXT:    fstp %st(1)
 ; X86-X87-NEXT:    fnstsw %ax
-; X86-X87-NEXT:    xorl %esi, %esi
+; X86-X87-NEXT:    xorl %ecx, %ecx
 ; X86-X87-NEXT:    # kill: def $ah killed $ah killed $ax
 ; X86-X87-NEXT:    sahf
-; X86-X87-NEXT:    movl $0, %edi
+; X86-X87-NEXT:    movl $0, %esi
 ; X86-X87-NEXT:    jb .LBB27_4
 ; X86-X87-NEXT:  # %bb.3:
-; X86-X87-NEXT:    movl %ecx, %edi
+; X86-X87-NEXT:    movl %edx, %esi
 ; X86-X87-NEXT:  .LBB27_4:
 ; X86-X87-NEXT:    jb .LBB27_6
 ; X86-X87-NEXT:  # %bb.5:
-; X86-X87-NEXT:    movl {{[0-9]+}}(%esp), %esi
+; X86-X87-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; X86-X87-NEXT:  .LBB27_6:
 ; X86-X87-NEXT:    flds {{\.?LCPI[0-9]+_[0-9]+}}
 ; X86-X87-NEXT:    fxch %st(1)
@@ -2527,12 +2528,11 @@ define i64 @test_unsigned_i64_f16(half %f) nounwind {
 ; X86-X87-NEXT:    movl $-1, %edx
 ; X86-X87-NEXT:    ja .LBB27_8
 ; X86-X87-NEXT:  # %bb.7:
-; X86-X87-NEXT:    movl %esi, %eax
-; X86-X87-NEXT:    movl %edi, %edx
+; X86-X87-NEXT:    movl %ecx, %eax
+; X86-X87-NEXT:    movl %esi, %edx
 ; X86-X87-NEXT:  .LBB27_8:
-; X86-X87-NEXT:    addl $20, %esp
+; X86-X87-NEXT:    addl $24, %esp
 ; X86-X87-NEXT:    popl %esi
-; X86-X87-NEXT:    popl %edi
 ; X86-X87-NEXT:    retl
 ;
 ; X86-SSE-LABEL: test_unsigned_i64_f16:
diff --git a/llvm/test/CodeGen/X86/half-constrained.ll b/llvm/test/CodeGen/X86/half-constrained.ll
index d5f2060ca20e3..b584ee101a8d7 100644
--- a/llvm/test/CodeGen/X86/half-constrained.ll
+++ b/llvm/test/CodeGen/X86/half-constrained.ll
@@ -320,23 +320,25 @@ define void @fp80_to_half(x86_fp80 %0) strictfp {
 define void @add() strictfp {
 ; X86-NOF16C-LABEL: add:
 ; X86-NOF16C:       # %bb.0:
-; X86-NOF16C-NEXT:    subl $12, %esp
-; X86-NOF16C-NEXT:    .cfi_def_cfa_offset 16
+; X86-NOF16C-NEXT:    subl $28, %esp
+; X86-NOF16C-NEXT:    .cfi_def_cfa_offset 32
 ; X86-NOF16C-NEXT:    movzwl a, %eax
 ; X86-NOF16C-NEXT:    movl %eax, (%esp)
 ; X86-NOF16C-NEXT:    calll __extendhfsf2
-; X86-NOF16C-NEXT:    fstps {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Folded Spill
+; X86-NOF16C-NEXT:    fstpt {{[-0-9]+}}(%e{{[sb]}}p) # 10-byte Folded Spill
 ; X86-NOF16C-NEXT:    wait
 ; X86-NOF16C-NEXT:    movzwl b, %eax
 ; X86-NOF16C-NEXT:    movl %eax, (%esp)
 ; X86-NOF16C-NEXT:    calll __extendhfsf2
-; X86-NOF16C-NEXT:    flds {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Folded Reload
+; X86-NOF16C-NEXT:    fldt {{[-0-9]+}}(%e{{[sb]}}p) # 10-byte Folded Reload
 ; X86-NOF16C-NEXT:    faddp %st, %st(1)
+; X86-NOF16C-NEXT:    fstps {{[0-9]+}}(%esp)
+; X86-NOF16C-NEXT:    flds {{[0-9]+}}(%esp)
 ; X86-NOF16C-NEXT:    fstps (%esp)
 ; X86-NOF16C-NEXT:    wait
 ; X86-NOF16C-NEXT:    calll __truncsfhf2
 ; X86-NOF16C-NEXT:    movw %ax, c
-; X86-NOF16C-NEXT:    addl $12, %esp
+; X86-NOF16C-NEXT:    addl $28, %esp
 ; X86-NOF16C-NEXT:    .cfi_def_cfa_offset 4
 ; X86-NOF16C-NEXT:    retl
 ;
diff --git a/llvm/test/CodeGen/X86/inline-asm-fpstack.ll b/llvm/test/CodeGen/X86/inline-asm-fpstack.ll
index af188ef3a2cf8..bc0c9c9229488 100644
--- a/llvm/test/CodeGen/X86/inline-asm-fpstack.ll
+++ b/llvm/test/CodeGen/X86/inline-asm-fpstack.ll
@@ -55,11 +55,15 @@ define void @test4(double %X) nounwind {
 define void @test5(double %X) nounwind {
 ; CHECK-LABEL: test5:
 ; CHECK:       ## %bb.0:
+; CHECK-NEXT:    subl $12, %esp
 ; CHECK-NEXT:    fldl {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; CHECK-NEXT:    fstpl (%esp)
+; CHECK-NEXT:    fldl (%esp)
 ; CHECK-NEXT:    ## InlineAsm Start
 ; CHECK-NEXT:    frob
 ; CHECK-NEXT:    ## InlineAsm End
+; CHECK-NEXT:    addl $12, %esp
 ; CHECK-NEXT:    retl
   %Y = fadd double %X, 123.0
   call void asm sideeffect "frob ", "{st(0)},~{st},~{dirflag},~{fpsr},~{flags}"( double %Y)
@@ -491,10 +495,14 @@ return:
 define double @test_operand_rewrite() nounwind {
 ; CHECK-LABEL: test_operand_rewrite:
 ; CHECK:       ## %bb.0: ## %entry
+; CHECK-NEXT:    subl $12, %esp
 ; CHECK-NEXT:    ## InlineAsm Start
 ; CHECK-NEXT:    foo %st, %st(1)
 ; CHECK-NEXT:    ## InlineAsm End
 ; CHECK-NEXT:    fsubp %st, %st(1)
+; CHECK-NEXT:    fstpl (%esp)
+; CHECK-NEXT:    fldl (%esp)
+; CHECK-NEXT:    addl $12, %esp
 ; CHECK-NEXT:    retl
 entry:
   %0 = tail call { double, double } asm sideeffect "foo $0, $1", "={st},={st(1)},~{dirflag},~{fpsr},~{flags}"()
diff --git a/llvm/test/CodeGen/X86/isel-fadd.ll b/llvm/test/CodeGen/X86/isel-fadd.ll
index cd3622f9444b3..659d0d8f43386 100644
--- a/llvm/test/CodeGen/X86/isel-fadd.ll
+++ b/llvm/test/CodeGen/X86/isel-fadd.ll
@@ -15,15 +15,27 @@
 define float @test_fadd_f32(float %arg1, float %arg2) {
 ; SDAG-X86-LABEL: test_fadd_f32:
 ; SDAG-X86:       # %bb.0:
+; SDAG-X86-NEXT:    pushl %eax
+; SDAG-X86-NEXT:    .cfi_def_cfa_offset 8
 ; SDAG-X86-NEXT:    flds {{[0-9]+}}(%esp)
 ; SDAG-X86-NEXT:    fadds {{[0-9]+}}(%esp)
+; SDAG-X86-NEXT:    fstps (%esp)
+; SDAG-X86-NEXT:    flds (%esp)
+; SDAG-X86-NEXT:    popl %eax
+; SDAG-X86-NEXT:    .cfi_def_cfa_offset 4
 ; SDAG-X86-NEXT:    retl
 ;
 ; FASTISEL-X86-LABEL: test_fadd_f32:
 ; FASTISEL-X86:       # %bb.0:
+; FASTISEL-X86-NEXT:    pushl %eax
+; FASTISEL-X86-NEXT:    .cfi_def_cfa_offset 8
 ; FASTISEL-X86-NEXT:    flds {{[0-9]+}}(%esp)
 ; FASTISEL-X86-NEXT:    flds {{[0-9]+}}(%esp)
 ; FASTISEL-X86-NEXT:    faddp %st, %st(1)
+; FASTISEL-X86-NEXT:    fstps (%esp)
+; FASTISEL-X86-NEXT:    flds (%esp)
+; FASTISEL-X86-NEXT:    popl %eax
+; FASTISEL-X86-NEXT:    .cfi_def_cfa_offset 4
 ; FASTISEL-X86-NEXT:    retl
 ;
 ; GISEL-X86-LABEL: test_fadd_f32:
@@ -48,21 +60,57 @@ define float @test_fadd_f32(float %arg1, float %arg2) {
 define double @test_fadd_f64(double %arg1, double %arg2) {
 ; SDAG-X86-LABEL: test_fadd_f64:
 ; SDAG-X86:       # %bb.0:
-; SDAG-X86-NEXT:    fldl {{[0-9]+}}(%esp)
-; SDAG-X86-NEXT:    faddl {{[0-9]+}}(%esp)
+; SDAG-X86-NEXT:    pushl %ebp
+; SDAG-X86-NEXT:    .cfi_def_cfa_offset 8
+; SDAG-X86-NEXT:    .cfi_offset %ebp, -8
+; SDAG-X86-NEXT:    movl %esp, %ebp
+; SDAG-X86-NEXT:    .cfi_def_cfa_register %ebp
+; SDAG-X86-NEXT:    andl $-8, %esp
+; SDAG-X86-NEXT:    subl $8, %esp
+; SDAG-X86-NEXT:    fldl 8(%ebp)
+; SDAG-X86-NEXT:    faddl 16(%ebp)
+; SDAG-X86-NEXT:    fstpl (%esp)
+; SDAG-X86-NEXT:    fldl (%esp)
+; SDAG-X86-NEXT:    movl %ebp, %esp
+; SDAG-X86-NEXT:    popl %ebp
+; SDAG-X86-NEXT:    .cfi_def_cfa %esp, 4
 ; SDAG-X86-NEXT:    retl
 ;
 ; FASTISEL-X86-LABEL: test_fadd_f64:
 ; FASTISEL-X86:       # %bb.0:
-; FASTISEL-X86-NEXT:    fldl {{[0-9]+}}(%esp)
-; FASTISEL-X86-NEXT:    fldl {{[0-9]+}}(%esp)
+; FASTISEL-X86-NEXT:    pushl %ebp
+; FASTISEL-X86-NEXT:    .cfi_def_cfa_offset 8
+; FASTISEL-X86-NEXT:    .cfi_offset %ebp, -8
+; FASTISEL-X86-NEXT:    movl %esp, %ebp
+; FASTISEL-X86-NEXT:    .cfi_def_cfa_register %ebp
+; FASTISEL-X86-NEXT:    andl $-8, %esp
+; FASTISEL-X86-NEXT:    subl $8, %esp
+; FASTISEL-X86-NEXT:    fldl 16(%ebp)
+; FASTISEL-X86-NEXT:    fldl 8(%ebp)
 ; FASTISEL-X86-NEXT:    faddp %st, %st(1)
+; FASTISEL-X86-NEXT:    fstpl (%esp)
+; FASTISEL-X86-NEXT:    fldl (%esp)
+; FASTISEL-X86-NEXT:    movl %ebp, %esp
+; FASTISEL-X86-NEXT:    popl %ebp
+; FASTISEL-X86-NEXT:    .cfi_def_cfa %esp, 4
 ; FASTISEL-X86-NEXT:    retl
 ;
 ; GISEL-X86-LABEL: test_fadd_f64:
 ; GISEL-X86:       # %bb.0:
-; GISEL-X86-NEXT:    fldl {{[0-9]+}}(%esp)
-; GISEL-X86-NEXT:    faddl {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    pushl %ebp
+; GISEL-X86-NEXT:    .cfi_def_cfa_offset 8
+; GISEL-X86-NEXT:    .cfi_offset %ebp, -8
+; GISEL-X86-NEXT:    movl %esp, %ebp
+; GISEL-X86-NEXT:    .cfi_def_cfa_register %ebp
+; GISEL-X86-NEXT:    andl $-8, %esp
+; GISEL-X86-NEXT:    subl $8, %esp
+; GISEL-X86-NEXT:    fldl 8(%ebp)
+; GISEL-X86-NEXT:    faddl 16(%ebp)
+; GISEL-X86-NEXT:    fstpl (%esp)
+; GISEL-X86-NEXT:    fldl (%esp)
+; GISEL-X86-NEXT:    movl %ebp, %esp
+; GISEL-X86-NEXT:    popl %ebp
+; GISEL-X86-NEXT:    .cfi_def_cfa %esp, 4
 ; GISEL-X86-NEXT:    retl
 ;
 ; SSE-LABEL: test_fadd_f64:
diff --git a/llvm/test/CodeGen/X86/isel-fdiv.ll b/llvm/test/CodeGen/X86/isel-fdiv.ll
index 34fad618843b4..ad3f9cc353167 100644
--- a/llvm/test/CodeGen/X86/isel-fdiv.ll
+++ b/llvm/test/CodeGen/X86/isel-fdiv.ll
@@ -15,15 +15,27 @@
 define float @test_fdiv_f32(float %arg1, float %arg2) {
 ; SDAG-X86-LABEL: test_fdiv_f32:
 ; SDAG-X86:       # %bb.0:
+; SDAG-X86-NEXT:    pushl %eax
+; SDAG-X86-NEXT:    .cfi_def_cfa_offset 8
 ; SDAG-X86-NEXT:    flds {{[0-9]+}}(%esp)
 ; SDAG-X86-NEXT:    fdivs {{[0-9]+}}(%esp)
+; SDAG-X86-NEXT:    fstps (%esp)
+; SDAG-X86-NEXT:    flds (%esp)
+; SDAG-X86-NEXT:    popl %eax
+; SDAG-X86-NEXT:    .cfi_def_cfa_offset 4
 ; SDAG-X86-NEXT:    retl
 ;
 ; FASTISEL-X86-LABEL: test_fdiv_f32:
 ; FASTISEL-X86:       # %bb.0:
+; FASTISEL-X86-NEXT:    pushl %eax
+; FASTISEL-X86-NEXT:    .cfi_def_cfa_offset 8
 ; FASTISEL-X86-NEXT:    flds {{[0-9]+}}(%esp)
 ; FASTISEL-X86-NEXT:    flds {{[0-9]+}}(%esp)
 ; FASTISEL-X86-NEXT:    fdivp %st, %st(1)
+; FASTISEL-X86-NEXT:    fstps (%esp)
+; FASTISEL-X86-NEXT:    flds (%esp)
+; FASTISEL-X86-NEXT:    popl %eax
+; FASTISEL-X86-NEXT:    .cfi_def_cfa_offset 4
 ; FASTISEL-X86-NEXT:    retl
 ;
 ; GISEL-X86-LABEL: test_fdiv_f32:
@@ -48,21 +60,57 @@ define float @test_fdiv_f32(float %arg1, float %arg2) {
 define double @test_fdiv_f64(double %arg1, double %arg2) {
 ; SDAG-X86-LABEL: test_fdiv_f64:
 ; SDAG-X86:       # %bb.0:
-; SDAG-X86-NEXT:    fldl {{[0-9]+}}(%esp)
-; SDAG-X86-NEXT:    fdivl {{[0-9]+}}(%esp)
+; SDAG-X86-NEXT:    pushl %ebp
+; SDAG-X86-NEXT:    .cfi_def_cfa_offset 8
+; SDAG-X86-NEXT:    .cfi_offset %ebp, -8
+; SDAG-X86-NEXT:    movl %esp, %ebp
+; SDAG-X86-NEXT:    .cfi_def_cfa_register %ebp
+; SDAG-X86-NEXT:    andl $-8, %esp
+; SDAG-X86-NEXT:    subl $8, %esp
+; SDAG-X86-NEXT:    fldl 8(%ebp)
+; SDAG-X86-NEXT:    fdivl 16(%ebp)
+; SDAG-X86-NEXT:    fstpl (%esp)
+; SDAG-X86-NEXT:    fldl (%esp)
+; SDAG-X86-NEXT:    movl %ebp, %esp
+; SDAG-X86-NEXT:    popl %ebp
+; SDAG-X86-NEXT:    .cfi_def_cfa %esp, 4
 ; SDAG-X86-NEXT:    retl
 ;
 ; FASTISEL-X86-LABEL: test_fdiv_f64:
 ; FASTISEL-X86:       # %bb.0:
-; FASTISEL-X86-NEXT:    fldl {{[0-9]+}}(%esp)
-; FASTISEL-X86-NEXT:    fldl {{[0-9]+}}(%esp)
+; FASTISEL-X86-NEXT:    pushl %ebp
+; FASTISEL-X86-NEXT:    .cfi_def_cfa_offset 8
+; FASTISEL-X86-NEXT:    .cfi_offset %ebp, -8
+; FASTISEL-X86-NEXT:    movl %esp, %ebp
+; FASTISEL-X86-NEXT:    .cfi_def_cfa_register %ebp
+; FASTISEL-X86-NEXT:    andl $-8, %esp
+; FASTISEL-X86-NEXT:    subl $8, %esp
+; FASTISEL-X86-NEXT:    fldl 16(%ebp)
+; FASTISEL-X86-NEXT:    fldl 8(%ebp)
 ; FASTISEL-X86-NEXT:    fdivp %st, %st(1)
+; FASTISEL-X86-NEXT:    fstpl (%esp)
+; FASTISEL-X86-NEXT:    fldl (%esp)
+; FASTISEL-X86-NEXT:    movl %ebp, %esp
+; FASTISEL-X86-NEXT:    popl %ebp
+; FASTISEL-X86-NEXT:    .cfi_def_cfa %esp, 4
 ; FASTISEL-X86-NEXT:    retl
 ;
 ; GISEL-X86-LABEL: test_fdiv_f64:
 ; GISEL-X86:       # %bb.0:
-; GISEL-X86-NEXT:    fldl {{[0-9]+}}(%esp)
-; GISEL-X86-NEXT:    fdivl {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    pushl %ebp
+; GISEL-X86-NEXT:    .cfi_def_cfa_offset 8
+; GISEL-X86-NEXT:    .cfi_offset %ebp, -8
+; GISEL-X86-NEXT:    movl %esp, %ebp
+; GISEL-X86-NEXT:    .cfi_def_cfa_register %ebp
+; GISEL-X86-NEXT:    andl $-8, %esp
+; GISEL-X86-NEXT:    subl $8, %esp
+; GISEL-X86-NEXT:    fldl 8(%ebp)
+; GISEL-X86-NEXT:    fdivl 16(%ebp)
+; GISEL-X86-NEXT:    fstpl (%esp)
+; GISEL-X86-NEXT:    fldl (%esp)
+; GISEL-X86-NEXT:    movl %ebp, %esp
+; GISEL-X86-NEXT:    popl %ebp
+; GISEL-X86-NEXT:    .cfi_def_cfa %esp, 4
 ; GISEL-X86-NEXT:    retl
 ;
 ; SSE-LABEL: test_fdiv_f64:
diff --git a/llvm/test/CodeGen/X86/isel-fmul.ll b/llvm/test/CodeGen/X86/isel-fmul.ll
index b9ecbe529fe64..0453acf4801a9 100644
--- a/llvm/test/CodeGen/X86/isel-fmul.ll
+++ b/llvm/test/CodeGen/X86/isel-fmul.ll
@@ -15,15 +15,27 @@
 define float @test_fmul_f32(float %arg1, float %arg2) {
 ; SDAG-X86-LABEL: test_fmul_f32:
 ; SDAG-X86:       # %bb.0:
+; SDAG-X86-NEXT:    pushl %eax
+; SDAG-X86-NEXT:    .cfi_def_cfa_offset 8
 ; SDAG-X86-NEXT:    flds {{[0-9]+}}(%esp)
 ; SDAG-X86-NEXT:    fmuls {{[0-9]+}}(%esp)
+; SDAG-X86-NEXT:    fstps (%esp)
+; SDAG-X86-NEXT:    flds (%esp)
+; SDAG-X86-NEXT:    popl %eax
+; SDAG-X86-NEXT:    .cfi_def_cfa_offset 4
 ; SDAG-X86-NEXT:    retl
 ;
 ; FASTISEL-X86-LABEL: test_fmul_f32:
 ; FASTISEL-X86:       # %bb.0:
+; FASTISEL-X86-NEXT:    pushl %eax
+; FASTISEL-X86-NEXT:    .cfi_def_cfa_offset 8
 ; FASTISEL-X86-NEXT:    flds {{[0-9]+}}(%esp)
 ; FASTISEL-X86-NEXT:    flds {{[0-9]+}}(%esp)
 ; FASTISEL-X86-NEXT:    fmulp %st, %st(1)
+; FASTISEL-X86-NEXT:    fstps (%esp)
+; FASTISEL-X86-NEXT:    flds (%esp)
+; FASTISEL-X86-NEXT:    popl %eax
+; FASTISEL-X86-NEXT:    .cfi_def_cfa_offset 4
 ; FASTISEL-X86-NEXT:    retl
 ;
 ; GISEL-X86-LABEL: test_fmul_f32:
@@ -48,21 +60,57 @@ define float @test_fmul_f32(float %arg1, float %arg2) {
 define double @test_fmul_f64(double %arg1, double %arg2) {
 ; SDAG-X86-LABEL: test_fmul_f64:
 ; SDAG-X86:       # %bb.0:
-; SDAG-X86-NEXT:    fldl {{[0-9]+}}(%esp)
-; SDAG-X86-NEXT:    fmull {{[0-9]+}}(%esp)
+; SDAG-X86-NEXT:    pushl %ebp
+; SDAG-X86-NEXT:    .cfi_def_cfa_offset 8
+; SDAG-X86-NEXT:    .cfi_offset %ebp, -8
+; SDAG-X86-NEXT:    movl %esp, %ebp
+; SDAG-X86-NEXT:    .cfi_def_cfa_register %ebp
+; SDAG-X86-NEXT:    andl $-8, %esp
+; SDAG-X86-NEXT:    subl $8, %esp
+; SDAG-X86-NEXT:    fldl 8(%ebp)
+; SDAG-X86-NEXT:    fmull 16(%ebp)
+; SDAG-X86-NEXT:    fstpl (%esp)
+; SDAG-X86-NEXT:    fldl (%esp)
+; SDAG-X86-NEXT:    movl %ebp, %esp
+; SDAG-X86-NEXT:    popl %ebp
+; SDAG-X86-NEXT:    .cfi_def_cfa %esp, 4
 ; SDAG-X86-NEXT:    retl
 ;
 ; FASTISEL-X86-LABEL: test_fmul_f64:
 ; FASTISEL-X86:       # %bb.0:
-; FASTISEL-X86-NEXT:    fldl {{[0-9]+}}(%esp)
-; FASTISEL-X86-NEXT:    fldl {{[0-9]+}}(%esp)
+; FASTISEL-X86-NEXT:    pushl %ebp
+; FASTISEL-X86-NEXT:    .cfi_def_cfa_offset 8
+; FASTISEL-X86-NEXT:    .cfi_offset %ebp, -8
+; FASTISEL-X86-NEXT:    movl %esp, %ebp
+; FASTISEL-X86-NEXT:    .cfi_def_cfa_register %ebp
+; FASTISEL-X86-NEXT:    andl $-8, %esp
+; FASTISEL-X86-NEXT:    subl $8, %esp
+; FASTISEL-X86-NEXT:    fldl 16(%ebp)
+; FASTISEL-X86-NEXT:    fldl 8(%ebp)
 ; FASTISEL-X86-NEXT:    fmulp %st, %st(1)
+; FASTISEL-X86-NEXT:    fstpl (%esp)
+; FASTISEL-X86-NEXT:    fldl (%esp)
+; FASTISEL-X86-NEXT:    movl %ebp, %esp
+; FASTISEL-X86-NEXT:    popl %ebp
+; FASTISEL-X86-NEXT:    .cfi_def_cfa %esp, 4
 ; FASTISEL-X86-NEXT:    retl
 ;
 ; GISEL-X86-LABEL: test_fmul_f64:
 ; GISEL-X86:       # %bb.0:
-; GISEL-X86-NEXT:    fldl {{[0-9]+}}(%esp)
-; GISEL-X86-NEXT:    fmull {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    pushl %ebp
+; GISEL-X86-NEXT:    .cfi_def_cfa_offset 8
+; GISEL-X86-NEXT:    .cfi_offset %ebp, -8
+; GISEL-X86-NEXT:    movl %esp, %ebp
+; GISEL-X86-NEXT:    .cfi_def_cfa_register %ebp
+; GISEL-X86-NEXT:    andl $-8, %esp
+; GISEL-X86-NEXT:    subl $8, %esp
+; GISEL-X86-NEXT:    fldl 8(%ebp)
+; GISEL-X86-NEXT:    fmull 16(%ebp)
+; GISEL-X86-NEXT:    fstpl (%esp)
+; GISEL-X86-NEXT:    fldl (%esp)
+; GISEL-X86-NEXT:    movl %ebp, %esp
+; GISEL-X86-NEXT:    popl %ebp
+; GISEL-X86-NEXT:    .cfi_def_cfa %esp, 4
 ; GISEL-X86-NEXT:    retl
 ;
 ; SSE-LABEL: test_fmul_f64:
diff --git a/llvm/test/CodeGen/X86/isel-fsub.ll b/llvm/test/CodeGen/X86/isel-fsub.ll
index d748a6cbabc17..090a8a45cb424 100644
--- a/llvm/test/CodeGen/X86/isel-fsub.ll
+++ b/llvm/test/CodeGen/X86/isel-fsub.ll
@@ -15,15 +15,27 @@
 define float @test_fsub_f32(float %arg1, float %arg2) {
 ; SDAG-X86-LABEL: test_fsub_f32:
 ; SDAG-X86:       # %bb.0:
+; SDAG-X86-NEXT:    pushl %eax
+; SDAG-X86-NEXT:    .cfi_def_cfa_offset 8
 ; SDAG-X86-NEXT:    flds {{[0-9]+}}(%esp)
 ; SDAG-X86-NEXT:    fsubs {{[0-9]+}}(%esp)
+; SDAG-X86-NEXT:    fstps (%esp)
+; SDAG-X86-NEXT:    flds (%esp)
+; SDAG-X86-NEXT:    popl %eax
+; SDAG-X86-NEXT:    .cfi_def_cfa_offset 4
 ; SDAG-X86-NEXT:    retl
 ;
 ; FASTISEL-X86-LABEL: test_fsub_f32:
 ; FASTISEL-X86:       # %bb.0:
+; FASTISEL-X86-NEXT:    pushl %eax
+; FASTISEL-X86-NEXT:    .cfi_def_cfa_offset 8
 ; FASTISEL-X86-NEXT:    flds {{[0-9]+}}(%esp)
 ; FASTISEL-X86-NEXT:    flds {{[0-9]+}}(%esp)
 ; FASTISEL-X86-NEXT:    fsubp %st, %st(1)
+; FASTISEL-X86-NEXT:    fstps (%esp)
+; FASTISEL-X86-NEXT:    flds (%esp)
+; FASTISEL-X86-NEXT:    popl %eax
+; FASTISEL-X86-NEXT:    .cfi_def_cfa_offset 4
 ; FASTISEL-X86-NEXT:    retl
 ;
 ; GISEL-X86-LABEL: test_fsub_f32:
@@ -48,21 +60,57 @@ define float @test_fsub_f32(float %arg1, float %arg2) {
 define double @test_fsub_f64(double %arg1, double %arg2) {
 ; SDAG-X86-LABEL: test_fsub_f64:
 ; SDAG-X86:       # %bb.0:
-; SDAG-X86-NEXT:    fldl {{[0-9]+}}(%esp)
-; SDAG-X86-NEXT:    fsubl {{[0-9]+}}(%esp)
+; SDAG-X86-NEXT:    pushl %ebp
+; SDAG-X86-NEXT:    .cfi_def_cfa_offset 8
+; SDAG-X86-NEXT:    .cfi_offset %ebp, -8
+; SDAG-X86-NEXT:    movl %esp, %ebp
+; SDAG-X86-NEXT:    .cfi_def_cfa_register %ebp
+; SDAG-X86-NEXT:    andl $-8, %esp
+; SDAG-X86-NEXT:    subl $8, %esp
+; SDAG-X86-NEXT:    fldl 8(%ebp)
+; SDAG-X86-NEXT:    fsubl 16(%ebp)
+; SDAG-X86-NEXT:    fstpl (%esp)
+; SDAG-X86-NEXT:    fldl (%esp)
+; SDAG-X86-NEXT:    movl %ebp, %esp
+; SDAG-X86-NEXT:    popl %ebp
+; SDAG-X86-NEXT:    .cfi_def_cfa %esp, 4
 ; SDAG-X86-NEXT:    retl
 ;
 ; FASTISEL-X86-LABEL: test_fsub_f64:
 ; FASTISEL-X86:       # %bb.0:
-; FASTISEL-X86-NEXT:    fldl {{[0-9]+}}(%esp)
-; FASTISEL-X86-NEXT:    fldl {{[0-9]+}}(%esp)
+; FASTISEL-X86-NEXT:    pushl %ebp
+; FASTISEL-X86-NEXT:    .cfi_def_cfa_offset 8
+; FASTISEL-X86-NEXT:    .cfi_offset %ebp, -8
+; FASTISEL-X86-NEXT:    movl %esp, %ebp
+; FASTISEL-X86-NEXT:    .cfi_def_cfa_register %ebp
+; FASTISEL-X86-NEXT:    andl $-8, %esp
+; FASTISEL-X86-NEXT:    subl $8, %esp
+; FASTISEL-X86-NEXT:    fldl 16(%ebp)
+; FASTISEL-X86-NEXT:    fldl 8(%ebp)
 ; FASTISEL-X86-NEXT:    fsubp %st, %st(1)
+; FASTISEL-X86-NEXT:    fstpl (%esp)
+; FASTISEL-X86-NEXT:    fldl (%esp)
+; FASTISEL-X86-NEXT:    movl %ebp, %esp
+; FASTISEL-X86-NEXT:    popl %ebp
+; FASTISEL-X86-NEXT:    .cfi_def_cfa %esp, 4
 ; FASTISEL-X86-NEXT:    retl
 ;
 ; GISEL-X86-LABEL: test_fsub_f64:
 ; GISEL-X86:       # %bb.0:
-; GISEL-X86-NEXT:    fldl {{[0-9]+}}(%esp)
-; GISEL-X86-NEXT:    fsubl {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    pushl %ebp
+; GISEL-X86-NEXT:    .cfi_def_cfa_offset 8
+; GISEL-X86-NEXT:    .cfi_offset %ebp, -8
+; GISEL-X86-NEXT:    movl %esp, %ebp
+; GISEL-X86-NEXT:    .cfi_def_cfa_register %ebp
+; GISEL-X86-NEXT:    andl $-8, %esp
+; GISEL-X86-NEXT:    subl $8, %esp
+; GISEL-X86-NEXT:    fldl 8(%ebp)
+; GISEL-X86-NEXT:    fsubl 16(%ebp)
+; GISEL-X86-NEXT:    fstpl (%esp)
+; GISEL-X86-NEXT:    fldl (%esp)
+; GISEL-X86-NEXT:    movl %ebp, %esp
+; GISEL-X86-NEXT:    popl %ebp
+; GISEL-X86-NEXT:    .cfi_def_cfa %esp, 4
 ; GISEL-X86-NEXT:    retl
 ;
 ; SSE-LABEL: test_fsub_f64:
diff --git a/llvm/test/CodeGen/X86/isel-sqrt.ll b/llvm/test/CodeGen/X86/isel-sqrt.ll
index 45ac3bdb2e40b..6d742da2129f6 100644
--- a/llvm/test/CodeGen/X86/isel-sqrt.ll
+++ b/llvm/test/CodeGen/X86/isel-sqrt.ll
@@ -21,11 +21,35 @@ define float @test_sqrt_f32(float %a) {
 ; AVX-NEXT:    vsqrtss %xmm0, %xmm0, %xmm0
 ; AVX-NEXT:    retq
 ;
-; X86-LABEL: test_sqrt_f32:
-; X86:       # %bb.0:
-; X86-NEXT:    flds {{[0-9]+}}(%esp)
-; X86-NEXT:    fsqrt
-; X86-NEXT:    retl
+; SDAG-X86-LABEL: test_sqrt_f32:
+; SDAG-X86:       # %bb.0:
+; SDAG-X86-NEXT:    pushl %eax
+; SDAG-X86-NEXT:    .cfi_def_cfa_offset 8
+; SDAG-X86-NEXT:    flds {{[0-9]+}}(%esp)
+; SDAG-X86-NEXT:    fsqrt
+; SDAG-X86-NEXT:    fstps (%esp)
+; SDAG-X86-NEXT:    flds (%esp)
+; SDAG-X86-NEXT:    popl %eax
+; SDAG-X86-NEXT:    .cfi_def_cfa_offset 4
+; SDAG-X86-NEXT:    retl
+;
+; FASTISEL-X86-LABEL: test_sqrt_f32:
+; FASTISEL-X86:       # %bb.0:
+; FASTISEL-X86-NEXT:    pushl %eax
+; FASTISEL-X86-NEXT:    .cfi_def_cfa_offset 8
+; FASTISEL-X86-NEXT:    flds {{[0-9]+}}(%esp)
+; FASTISEL-X86-NEXT:    fsqrt
+; FASTISEL-X86-NEXT:    fstps (%esp)
+; FASTISEL-X86-NEXT:    flds (%esp)
+; FASTISEL-X86-NEXT:    popl %eax
+; FASTISEL-X86-NEXT:    .cfi_def_cfa_offset 4
+; FASTISEL-X86-NEXT:    retl
+;
+; GISEL-X86-LABEL: test_sqrt_f32:
+; GISEL-X86:       # %bb.0:
+; GISEL-X86-NEXT:    flds {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    fsqrt
+; GISEL-X86-NEXT:    retl
   %res = call float @llvm.sqrt.f32(float %a)
   ret float %res
 }
@@ -44,8 +68,14 @@ define double @test_sqrt_f64(double %a) {
 ;
 ; X86-LABEL: test_sqrt_f64:
 ; X86:       # %bb.0:
+; X86-NEXT:    subl $12, %esp
+; X86-NEXT:    .cfi_def_cfa_offset 16
 ; X86-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-NEXT:    fsqrt
+; X86-NEXT:    fstpl (%esp)
+; X86-NEXT:    fldl (%esp)
+; X86-NEXT:    addl $12, %esp
+; X86-NEXT:    .cfi_def_cfa_offset 4
 ; X86-NEXT:    retl
   %res = call double @llvm.sqrt.f64(double %a)
   ret double %res
@@ -69,7 +99,3 @@ define x86_fp80 @test_sqrt_f80(x86_fp80 %a) {
 }
 declare x86_fp80 @llvm.sqrt.f80(x86_fp80) nounwind readnone
 
-;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
-; FASTISEL-X86: {{.*}}
-; GISEL-X86: {{.*}}
-; SDAG-X86: {{.*}}
diff --git a/llvm/test/CodeGen/X86/limited-prec.ll b/llvm/test/CodeGen/X86/limited-prec.ll
index b2b722841eff3..03c32c044c1a1 100644
--- a/llvm/test/CodeGen/X86/limited-prec.ll
+++ b/llvm/test/CodeGen/X86/limited-prec.ll
@@ -6,9 +6,11 @@
 define float @f1(float %x) nounwind noinline {
 ; precision6-LABEL: f1:
 ; precision6:       # %bb.0: # %entry
-; precision6-NEXT:    subl $20, %esp
+; precision6-NEXT:    subl $40, %esp
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
+; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fnstcw (%esp)
 ; precision6-NEXT:    movzwl (%esp), %eax
 ; precision6-NEXT:    orl $3072, %eax # imm = 0xC00
@@ -18,25 +20,36 @@ define float @f1(float %x) nounwind noinline {
 ; precision6-NEXT:    fldcw (%esp)
 ; precision6-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; precision6-NEXT:    movl %eax, {{[0-9]+}}(%esp)
-; precision6-NEXT:    fisubl {{[0-9]+}}(%esp)
+; precision6-NEXT:    fildl {{[0-9]+}}(%esp)
+; precision6-NEXT:    fsubrp %st, %st(1)
+; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fld %st(0)
 ; precision6-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
+; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fmulp %st, %st(1)
+; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision6-NEXT:    shll $23, %eax
 ; precision6-NEXT:    addl {{[0-9]+}}(%esp), %eax
 ; precision6-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
-; precision6-NEXT:    addl $20, %esp
+; precision6-NEXT:    addl $40, %esp
 ; precision6-NEXT:    retl
 ;
 ; precision12-LABEL: f1:
 ; precision12:       # %bb.0: # %entry
-; precision12-NEXT:    subl $20, %esp
+; precision12-NEXT:    subl $48, %esp
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fnstcw (%esp)
 ; precision12-NEXT:    movzwl (%esp), %eax
 ; precision12-NEXT:    orl $3072, %eax # imm = 0xC00
@@ -46,27 +59,42 @@ define float @f1(float %x) nounwind noinline {
 ; precision12-NEXT:    fldcw (%esp)
 ; precision12-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; precision12-NEXT:    movl %eax, {{[0-9]+}}(%esp)
-; precision12-NEXT:    fisubl {{[0-9]+}}(%esp)
+; precision12-NEXT:    fildl {{[0-9]+}}(%esp)
+; precision12-NEXT:    fsubrp %st, %st(1)
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fld %st(0)
 ; precision12-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fmul %st(1), %st
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fmulp %st, %st(1)
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision12-NEXT:    shll $23, %eax
 ; precision12-NEXT:    addl {{[0-9]+}}(%esp), %eax
 ; precision12-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
-; precision12-NEXT:    addl $20, %esp
+; precision12-NEXT:    addl $48, %esp
 ; precision12-NEXT:    retl
 ;
 ; precision18-LABEL: f1:
 ; precision18:       # %bb.0: # %entry
-; precision18-NEXT:    subl $20, %esp
+; precision18-NEXT:    subl $72, %esp
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fnstcw (%esp)
 ; precision18-NEXT:    movzwl (%esp), %eax
 ; precision18-NEXT:    orl $3072, %eax # imm = 0xC00
@@ -76,19 +104,44 @@ define float @f1(float %x) nounwind noinline {
 ; precision18-NEXT:    fldcw (%esp)
 ; precision18-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; precision18-NEXT:    movl %eax, {{[0-9]+}}(%esp)
-; precision18-NEXT:    fisubl {{[0-9]+}}(%esp)
+; precision18-NEXT:    fildl {{[0-9]+}}(%esp)
+; precision18-NEXT:    fsubrp %st, %st(1)
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fld %st(0)
 ; precision18-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fmul %st(1), %st
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fmul %st(1), %st
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fmul %st(1), %st
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fmul %st(1), %st
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fmulp %st, %st(1)
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fld1
 ; precision18-NEXT:    faddp %st, %st(1)
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
@@ -96,7 +149,7 @@ define float @f1(float %x) nounwind noinline {
 ; precision18-NEXT:    addl {{[0-9]+}}(%esp), %eax
 ; precision18-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    addl $20, %esp
+; precision18-NEXT:    addl $72, %esp
 ; precision18-NEXT:    retl
 entry:
 	%"alloca point" = bitcast i32 0 to i32		; <i32> [#uses=0]
@@ -109,7 +162,7 @@ declare float @llvm.exp.f32(float) nounwind readonly
 define float @f2(float %x) nounwind noinline {
 ; precision6-LABEL: f2:
 ; precision6:       # %bb.0: # %entry
-; precision6-NEXT:    subl $20, %esp
+; precision6-NEXT:    subl $36, %esp
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fnstcw (%esp)
 ; precision6-NEXT:    movzwl (%esp), %eax
@@ -120,23 +173,32 @@ define float @f2(float %x) nounwind noinline {
 ; precision6-NEXT:    fldcw (%esp)
 ; precision6-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; precision6-NEXT:    movl %eax, {{[0-9]+}}(%esp)
-; precision6-NEXT:    fisubl {{[0-9]+}}(%esp)
+; precision6-NEXT:    fildl {{[0-9]+}}(%esp)
+; precision6-NEXT:    fsubrp %st, %st(1)
+; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fld %st(0)
 ; precision6-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
+; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fmulp %st, %st(1)
+; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision6-NEXT:    shll $23, %eax
 ; precision6-NEXT:    addl {{[0-9]+}}(%esp), %eax
 ; precision6-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
-; precision6-NEXT:    addl $20, %esp
+; precision6-NEXT:    addl $36, %esp
 ; precision6-NEXT:    retl
 ;
 ; precision12-LABEL: f2:
 ; precision12:       # %bb.0: # %entry
-; precision12-NEXT:    subl $20, %esp
+; precision12-NEXT:    subl $44, %esp
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fnstcw (%esp)
 ; precision12-NEXT:    movzwl (%esp), %eax
@@ -147,25 +209,38 @@ define float @f2(float %x) nounwind noinline {
 ; precision12-NEXT:    fldcw (%esp)
 ; precision12-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; precision12-NEXT:    movl %eax, {{[0-9]+}}(%esp)
-; precision12-NEXT:    fisubl {{[0-9]+}}(%esp)
+; precision12-NEXT:    fildl {{[0-9]+}}(%esp)
+; precision12-NEXT:    fsubrp %st, %st(1)
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fld %st(0)
 ; precision12-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fmul %st(1), %st
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fmulp %st, %st(1)
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision12-NEXT:    shll $23, %eax
 ; precision12-NEXT:    addl {{[0-9]+}}(%esp), %eax
 ; precision12-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
-; precision12-NEXT:    addl $20, %esp
+; precision12-NEXT:    addl $44, %esp
 ; precision12-NEXT:    retl
 ;
 ; precision18-LABEL: f2:
 ; precision18:       # %bb.0: # %entry
-; precision18-NEXT:    subl $20, %esp
+; precision18-NEXT:    subl $68, %esp
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fnstcw (%esp)
 ; precision18-NEXT:    movzwl (%esp), %eax
@@ -176,19 +251,44 @@ define float @f2(float %x) nounwind noinline {
 ; precision18-NEXT:    fldcw (%esp)
 ; precision18-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; precision18-NEXT:    movl %eax, {{[0-9]+}}(%esp)
-; precision18-NEXT:    fisubl {{[0-9]+}}(%esp)
+; precision18-NEXT:    fildl {{[0-9]+}}(%esp)
+; precision18-NEXT:    fsubrp %st, %st(1)
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fld %st(0)
 ; precision18-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fmul %st(1), %st
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fmul %st(1), %st
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fmul %st(1), %st
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fmul %st(1), %st
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fmulp %st, %st(1)
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fld1
 ; precision18-NEXT:    faddp %st, %st(1)
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
@@ -196,7 +296,7 @@ define float @f2(float %x) nounwind noinline {
 ; precision18-NEXT:    addl {{[0-9]+}}(%esp), %eax
 ; precision18-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    addl $20, %esp
+; precision18-NEXT:    addl $68, %esp
 ; precision18-NEXT:    retl
 entry:
 	%"alloca point" = bitcast i32 0 to i32		; <i32> [#uses=0]
@@ -209,9 +309,11 @@ declare float @llvm.exp2.f32(float) nounwind readonly
 define float @f3(float %x) nounwind noinline {
 ; precision6-LABEL: f3:
 ; precision6:       # %bb.0: # %entry
-; precision6-NEXT:    subl $20, %esp
+; precision6-NEXT:    subl $40, %esp
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
+; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fnstcw (%esp)
 ; precision6-NEXT:    movzwl (%esp), %eax
 ; precision6-NEXT:    orl $3072, %eax # imm = 0xC00
@@ -221,25 +323,36 @@ define float @f3(float %x) nounwind noinline {
 ; precision6-NEXT:    fldcw (%esp)
 ; precision6-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; precision6-NEXT:    movl %eax, {{[0-9]+}}(%esp)
-; precision6-NEXT:    fisubl {{[0-9]+}}(%esp)
+; precision6-NEXT:    fildl {{[0-9]+}}(%esp)
+; precision6-NEXT:    fsubrp %st, %st(1)
+; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fld %st(0)
 ; precision6-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
+; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fmulp %st, %st(1)
+; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision6-NEXT:    shll $23, %eax
 ; precision6-NEXT:    addl {{[0-9]+}}(%esp), %eax
 ; precision6-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
-; precision6-NEXT:    addl $20, %esp
+; precision6-NEXT:    addl $40, %esp
 ; precision6-NEXT:    retl
 ;
 ; precision12-LABEL: f3:
 ; precision12:       # %bb.0: # %entry
-; precision12-NEXT:    subl $20, %esp
+; precision12-NEXT:    subl $48, %esp
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fnstcw (%esp)
 ; precision12-NEXT:    movzwl (%esp), %eax
 ; precision12-NEXT:    orl $3072, %eax # imm = 0xC00
@@ -249,27 +362,42 @@ define float @f3(float %x) nounwind noinline {
 ; precision12-NEXT:    fldcw (%esp)
 ; precision12-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; precision12-NEXT:    movl %eax, {{[0-9]+}}(%esp)
-; precision12-NEXT:    fisubl {{[0-9]+}}(%esp)
+; precision12-NEXT:    fildl {{[0-9]+}}(%esp)
+; precision12-NEXT:    fsubrp %st, %st(1)
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fld %st(0)
 ; precision12-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fmul %st(1), %st
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fmulp %st, %st(1)
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision12-NEXT:    shll $23, %eax
 ; precision12-NEXT:    addl {{[0-9]+}}(%esp), %eax
 ; precision12-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
-; precision12-NEXT:    addl $20, %esp
+; precision12-NEXT:    addl $48, %esp
 ; precision12-NEXT:    retl
 ;
 ; precision18-LABEL: f3:
 ; precision18:       # %bb.0: # %entry
-; precision18-NEXT:    subl $20, %esp
+; precision18-NEXT:    subl $72, %esp
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fnstcw (%esp)
 ; precision18-NEXT:    movzwl (%esp), %eax
 ; precision18-NEXT:    orl $3072, %eax # imm = 0xC00
@@ -279,19 +407,44 @@ define float @f3(float %x) nounwind noinline {
 ; precision18-NEXT:    fldcw (%esp)
 ; precision18-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; precision18-NEXT:    movl %eax, {{[0-9]+}}(%esp)
-; precision18-NEXT:    fisubl {{[0-9]+}}(%esp)
+; precision18-NEXT:    fildl {{[0-9]+}}(%esp)
+; precision18-NEXT:    fsubrp %st, %st(1)
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fld %st(0)
 ; precision18-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fmul %st(1), %st
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fmul %st(1), %st
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fmul %st(1), %st
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fmul %st(1), %st
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fmulp %st, %st(1)
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fld1
 ; precision18-NEXT:    faddp %st, %st(1)
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
@@ -299,7 +452,7 @@ define float @f3(float %x) nounwind noinline {
 ; precision18-NEXT:    addl {{[0-9]+}}(%esp), %eax
 ; precision18-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    addl $20, %esp
+; precision18-NEXT:    addl $72, %esp
 ; precision18-NEXT:    retl
 entry:
 	%"alloca point" = bitcast i32 0 to i32		; <i32> [#uses=0]
@@ -312,86 +465,146 @@ declare float @llvm.pow.f32(float, float) nounwind readonly
 define float @f4(float %x) nounwind noinline {
 ; precision6-LABEL: f4:
 ; precision6:       # %bb.0: # %entry
-; precision6-NEXT:    subl $8, %esp
+; precision6-NEXT:    subl $32, %esp
 ; precision6-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; precision6-NEXT:    movl %eax, %ecx
 ; precision6-NEXT:    andl $8388607, %ecx # imm = 0x7FFFFF
 ; precision6-NEXT:    orl $1065353216, %ecx # imm = 0x3F800000
-; precision6-NEXT:    movl %ecx, (%esp)
+; precision6-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
+; precision6-NEXT:    flds {{[0-9]+}}(%esp)
+; precision6-NEXT:    fld %st(0)
+; precision6-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
+; precision6-NEXT:    fstps (%esp)
+; precision6-NEXT:    flds (%esp)
+; precision6-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision6-NEXT:    andl $2139095040, %eax # imm = 0x7F800000
 ; precision6-NEXT:    shrl $23, %eax
 ; precision6-NEXT:    addl $-127, %eax
 ; precision6-NEXT:    movl %eax, {{[0-9]+}}(%esp)
-; precision6-NEXT:    flds (%esp)
-; precision6-NEXT:    fld %st(0)
-; precision6-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
-; precision6-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fmulp %st, %st(1)
-; precision6-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fildl {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
+; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision6-NEXT:    flds {{[0-9]+}}(%esp)
+; precision6-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision6-NEXT:    flds {{[0-9]+}}(%esp)
+; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    faddp %st, %st(1)
-; precision6-NEXT:    addl $8, %esp
+; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision6-NEXT:    flds {{[0-9]+}}(%esp)
+; precision6-NEXT:    addl $32, %esp
 ; precision6-NEXT:    retl
 ;
 ; precision12-LABEL: f4:
 ; precision12:       # %bb.0: # %entry
-; precision12-NEXT:    subl $8, %esp
+; precision12-NEXT:    subl $48, %esp
 ; precision12-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; precision12-NEXT:    movl %eax, %ecx
 ; precision12-NEXT:    andl $8388607, %ecx # imm = 0x7FFFFF
 ; precision12-NEXT:    orl $1065353216, %ecx # imm = 0x3F800000
-; precision12-NEXT:    movl %ecx, (%esp)
-; precision12-NEXT:    andl $2139095040, %eax # imm = 0x7F800000
-; precision12-NEXT:    shrl $23, %eax
-; precision12-NEXT:    addl $-127, %eax
-; precision12-NEXT:    movl %eax, {{[0-9]+}}(%esp)
-; precision12-NEXT:    flds (%esp)
+; precision12-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fld %st(0)
 ; precision12-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
+; precision12-NEXT:    fstps (%esp)
+; precision12-NEXT:    flds (%esp)
 ; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fmul %st(1), %st
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fmul %st(1), %st
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    andl $2139095040, %eax # imm = 0x7F800000
+; precision12-NEXT:    shrl $23, %eax
+; precision12-NEXT:    addl $-127, %eax
+; precision12-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fmulp %st, %st(1)
-; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fildl {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
+; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    faddp %st, %st(1)
-; precision12-NEXT:    addl $8, %esp
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
+; precision12-NEXT:    addl $48, %esp
 ; precision12-NEXT:    retl
 ;
 ; precision18-LABEL: f4:
 ; precision18:       # %bb.0: # %entry
-; precision18-NEXT:    subl $8, %esp
+; precision18-NEXT:    subl $64, %esp
 ; precision18-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; precision18-NEXT:    movl %eax, %ecx
 ; precision18-NEXT:    andl $8388607, %ecx # imm = 0x7FFFFF
 ; precision18-NEXT:    orl $1065353216, %ecx # imm = 0x3F800000
-; precision18-NEXT:    movl %ecx, (%esp)
-; precision18-NEXT:    andl $2139095040, %eax # imm = 0x7F800000
-; precision18-NEXT:    shrl $23, %eax
-; precision18-NEXT:    addl $-127, %eax
-; precision18-NEXT:    movl %eax, {{[0-9]+}}(%esp)
-; precision18-NEXT:    flds (%esp)
+; precision18-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fld %st(0)
 ; precision18-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
+; precision18-NEXT:    fstps (%esp)
+; precision18-NEXT:    flds (%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fmul %st(1), %st
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fmul %st(1), %st
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fmul %st(1), %st
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fmul %st(1), %st
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    andl $2139095040, %eax # imm = 0x7F800000
+; precision18-NEXT:    shrl $23, %eax
+; precision18-NEXT:    addl $-127, %eax
+; precision18-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fmulp %st, %st(1)
-; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fildl {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
+; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    faddp %st, %st(1)
-; precision18-NEXT:    addl $8, %esp
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
+; precision18-NEXT:    addl $64, %esp
 ; precision18-NEXT:    retl
 entry:
 	%"alloca point" = bitcast i32 0 to i32		; <i32> [#uses=0]
@@ -404,80 +617,137 @@ declare float @llvm.log.f32(float) nounwind readonly
 define float @f5(float %x) nounwind noinline {
 ; precision6-LABEL: f5:
 ; precision6:       # %bb.0: # %entry
-; precision6-NEXT:    subl $8, %esp
+; precision6-NEXT:    subl $28, %esp
 ; precision6-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; precision6-NEXT:    movl %eax, %ecx
 ; precision6-NEXT:    andl $8388607, %ecx # imm = 0x7FFFFF
 ; precision6-NEXT:    orl $1065353216, %ecx # imm = 0x3F800000
-; precision6-NEXT:    movl %ecx, (%esp)
-; precision6-NEXT:    andl $2139095040, %eax # imm = 0x7F800000
-; precision6-NEXT:    shrl $23, %eax
-; precision6-NEXT:    addl $-127, %eax
-; precision6-NEXT:    movl %eax, {{[0-9]+}}(%esp)
-; precision6-NEXT:    flds (%esp)
+; precision6-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
+; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fld %st(0)
 ; precision6-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
+; precision6-NEXT:    fstps (%esp)
+; precision6-NEXT:    flds (%esp)
 ; precision6-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fmulp %st, %st(1)
+; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision6-NEXT:    andl $2139095040, %eax # imm = 0x7F800000
+; precision6-NEXT:    shrl $23, %eax
+; precision6-NEXT:    addl $-127, %eax
+; precision6-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
-; precision6-NEXT:    fiaddl {{[0-9]+}}(%esp)
-; precision6-NEXT:    addl $8, %esp
+; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision6-NEXT:    fildl {{[0-9]+}}(%esp)
+; precision6-NEXT:    flds {{[0-9]+}}(%esp)
+; precision6-NEXT:    faddp %st, %st(1)
+; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision6-NEXT:    flds {{[0-9]+}}(%esp)
+; precision6-NEXT:    addl $28, %esp
 ; precision6-NEXT:    retl
 ;
 ; precision12-LABEL: f5:
 ; precision12:       # %bb.0: # %entry
-; precision12-NEXT:    subl $8, %esp
+; precision12-NEXT:    subl $44, %esp
 ; precision12-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; precision12-NEXT:    movl %eax, %ecx
 ; precision12-NEXT:    andl $8388607, %ecx # imm = 0x7FFFFF
 ; precision12-NEXT:    orl $1065353216, %ecx # imm = 0x3F800000
-; precision12-NEXT:    movl %ecx, (%esp)
-; precision12-NEXT:    andl $2139095040, %eax # imm = 0x7F800000
-; precision12-NEXT:    shrl $23, %eax
-; precision12-NEXT:    addl $-127, %eax
-; precision12-NEXT:    movl %eax, {{[0-9]+}}(%esp)
-; precision12-NEXT:    flds (%esp)
+; precision12-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fld %st(0)
 ; precision12-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
+; precision12-NEXT:    fstps (%esp)
+; precision12-NEXT:    flds (%esp)
 ; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fmul %st(1), %st
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fmul %st(1), %st
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fmulp %st, %st(1)
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    andl $2139095040, %eax # imm = 0x7F800000
+; precision12-NEXT:    shrl $23, %eax
+; precision12-NEXT:    addl $-127, %eax
+; precision12-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
-; precision12-NEXT:    fiaddl {{[0-9]+}}(%esp)
-; precision12-NEXT:    addl $8, %esp
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    fildl {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
+; precision12-NEXT:    faddp %st, %st(1)
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
+; precision12-NEXT:    addl $44, %esp
 ; precision12-NEXT:    retl
 ;
 ; precision18-LABEL: f5:
 ; precision18:       # %bb.0: # %entry
-; precision18-NEXT:    subl $8, %esp
+; precision18-NEXT:    subl $60, %esp
 ; precision18-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; precision18-NEXT:    movl %eax, %ecx
 ; precision18-NEXT:    andl $8388607, %ecx # imm = 0x7FFFFF
 ; precision18-NEXT:    orl $1065353216, %ecx # imm = 0x3F800000
-; precision18-NEXT:    movl %ecx, (%esp)
-; precision18-NEXT:    andl $2139095040, %eax # imm = 0x7F800000
-; precision18-NEXT:    shrl $23, %eax
-; precision18-NEXT:    addl $-127, %eax
-; precision18-NEXT:    movl %eax, {{[0-9]+}}(%esp)
-; precision18-NEXT:    flds (%esp)
+; precision18-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fld %st(0)
 ; precision18-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
+; precision18-NEXT:    fstps (%esp)
+; precision18-NEXT:    flds (%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fmul %st(1), %st
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fmul %st(1), %st
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fmul %st(1), %st
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fmul %st(1), %st
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fmulp %st, %st(1)
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    andl $2139095040, %eax # imm = 0x7F800000
+; precision18-NEXT:    shrl $23, %eax
+; precision18-NEXT:    addl $-127, %eax
+; precision18-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
-; precision18-NEXT:    fiaddl {{[0-9]+}}(%esp)
-; precision18-NEXT:    addl $8, %esp
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    fildl {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
+; precision18-NEXT:    faddp %st, %st(1)
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
+; precision18-NEXT:    addl $60, %esp
 ; precision18-NEXT:    retl
 entry:
 	%"alloca point" = bitcast i32 0 to i32		; <i32> [#uses=0]
@@ -490,82 +760,134 @@ declare float @llvm.log2.f32(float) nounwind readonly
 define float @f6(float %x) nounwind noinline {
 ; precision6-LABEL: f6:
 ; precision6:       # %bb.0: # %entry
-; precision6-NEXT:    subl $8, %esp
+; precision6-NEXT:    subl $32, %esp
 ; precision6-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; precision6-NEXT:    movl %eax, %ecx
 ; precision6-NEXT:    andl $8388607, %ecx # imm = 0x7FFFFF
 ; precision6-NEXT:    orl $1065353216, %ecx # imm = 0x3F800000
-; precision6-NEXT:    movl %ecx, (%esp)
+; precision6-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
+; precision6-NEXT:    flds {{[0-9]+}}(%esp)
+; precision6-NEXT:    fld %st(0)
+; precision6-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
+; precision6-NEXT:    fstps (%esp)
+; precision6-NEXT:    flds (%esp)
+; precision6-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision6-NEXT:    andl $2139095040, %eax # imm = 0x7F800000
 ; precision6-NEXT:    shrl $23, %eax
 ; precision6-NEXT:    addl $-127, %eax
 ; precision6-NEXT:    movl %eax, {{[0-9]+}}(%esp)
-; precision6-NEXT:    flds (%esp)
-; precision6-NEXT:    fld %st(0)
-; precision6-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
-; precision6-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fmulp %st, %st(1)
-; precision6-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fildl {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
+; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision6-NEXT:    flds {{[0-9]+}}(%esp)
+; precision6-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision6-NEXT:    flds {{[0-9]+}}(%esp)
+; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    faddp %st, %st(1)
-; precision6-NEXT:    addl $8, %esp
+; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision6-NEXT:    flds {{[0-9]+}}(%esp)
+; precision6-NEXT:    addl $32, %esp
 ; precision6-NEXT:    retl
 ;
 ; precision12-LABEL: f6:
 ; precision12:       # %bb.0: # %entry
-; precision12-NEXT:    subl $8, %esp
+; precision12-NEXT:    subl $40, %esp
 ; precision12-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; precision12-NEXT:    movl %eax, %ecx
 ; precision12-NEXT:    andl $8388607, %ecx # imm = 0x7FFFFF
 ; precision12-NEXT:    orl $1065353216, %ecx # imm = 0x3F800000
-; precision12-NEXT:    movl %ecx, (%esp)
-; precision12-NEXT:    andl $2139095040, %eax # imm = 0x7F800000
-; precision12-NEXT:    shrl $23, %eax
-; precision12-NEXT:    addl $-127, %eax
-; precision12-NEXT:    movl %eax, {{[0-9]+}}(%esp)
-; precision12-NEXT:    flds (%esp)
+; precision12-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fld %st(0)
 ; precision12-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
+; precision12-NEXT:    fstps (%esp)
+; precision12-NEXT:    flds (%esp)
 ; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fmul %st(1), %st
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    andl $2139095040, %eax # imm = 0x7F800000
+; precision12-NEXT:    shrl $23, %eax
+; precision12-NEXT:    addl $-127, %eax
+; precision12-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fmulp %st, %st(1)
-; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fildl {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
+; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    faddp %st, %st(1)
-; precision12-NEXT:    addl $8, %esp
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
+; precision12-NEXT:    addl $40, %esp
 ; precision12-NEXT:    retl
 ;
 ; precision18-LABEL: f6:
 ; precision18:       # %bb.0: # %entry
-; precision18-NEXT:    subl $8, %esp
+; precision18-NEXT:    subl $56, %esp
 ; precision18-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; precision18-NEXT:    movl %eax, %ecx
 ; precision18-NEXT:    andl $8388607, %ecx # imm = 0x7FFFFF
 ; precision18-NEXT:    orl $1065353216, %ecx # imm = 0x3F800000
-; precision18-NEXT:    movl %ecx, (%esp)
-; precision18-NEXT:    andl $2139095040, %eax # imm = 0x7F800000
-; precision18-NEXT:    shrl $23, %eax
-; precision18-NEXT:    addl $-127, %eax
-; precision18-NEXT:    movl %eax, {{[0-9]+}}(%esp)
-; precision18-NEXT:    flds (%esp)
+; precision18-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fld %st(0)
 ; precision18-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
+; precision18-NEXT:    fstps (%esp)
+; precision18-NEXT:    flds (%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fmul %st(1), %st
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fmul %st(1), %st
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fmul %st(1), %st
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    andl $2139095040, %eax # imm = 0x7F800000
+; precision18-NEXT:    shrl $23, %eax
+; precision18-NEXT:    addl $-127, %eax
+; precision18-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fmulp %st, %st(1)
-; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fildl {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
+; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    faddp %st, %st(1)
-; precision18-NEXT:    addl $8, %esp
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
+; precision18-NEXT:    addl $56, %esp
 ; precision18-NEXT:    retl
 entry:
 	%"alloca point" = bitcast i32 0 to i32		; <i32> [#uses=0]
diff --git a/llvm/test/CodeGen/X86/negate-add-zero.ll b/llvm/test/CodeGen/X86/negate-add-zero.ll
index 4884832a91a52..5623fdb50fb25 100644
--- a/llvm/test/CodeGen/X86/negate-add-zero.ll
+++ b/llvm/test/CodeGen/X86/negate-add-zero.ll
@@ -827,44 +827,70 @@ declare void @_ZN21HNodeTranslateRotate311toCartesianEv(ptr)
 define linkonce void @_ZN21HNodeTranslateRotate36setVelERK9CDSVectorIdLi1EN3CDS12DefaultAllocEE(ptr %this, ptr %velv) {
 ; CHECK-LABEL: _ZN21HNodeTranslateRotate36setVelERK9CDSVectorIdLi1EN3CDS12DefaultAllocEE:
 ; CHECK:       ## %bb.0:
+; CHECK-NEXT:    subl $100, %esp
+; CHECK-NEXT:    .cfi_def_cfa_offset 104
 ; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; CHECK-NEXT:    fldl 0
-; CHECK-NEXT:    fldl 3184(%ecx)
-; CHECK-NEXT:    fld %st(1)
+; CHECK-NEXT:    fld %st(0)
 ; CHECK-NEXT:    fmull 3176(%ecx)
+; CHECK-NEXT:    fstpl {{[0-9]+}}(%esp)
+; CHECK-NEXT:    fldl {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    fldz
 ; CHECK-NEXT:    fld %st(1)
 ; CHECK-NEXT:    fadd %st(1), %st
-; CHECK-NEXT:    fld %st(3)
+; CHECK-NEXT:    fstpl {{[0-9]+}}(%esp)
+; CHECK-NEXT:    fldl {{[0-9]+}}(%esp)
+; CHECK-NEXT:    fldl 3184(%ecx)
+; CHECK-NEXT:    fld %st(0)
 ; CHECK-NEXT:    fmul %st(5), %st
-; CHECK-NEXT:    fadd %st(2), %st
+; CHECK-NEXT:    fstpl {{[0-9]+}}(%esp)
+; CHECK-NEXT:    fldl {{[0-9]+}}(%esp)
+; CHECK-NEXT:    fadd %st(3), %st
+; CHECK-NEXT:    fstpl {{[0-9]+}}(%esp)
+; CHECK-NEXT:    fldl {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    fxch %st(5)
 ; CHECK-NEXT:    fmul %st, %st(0)
+; CHECK-NEXT:    fstpl (%esp)
+; CHECK-NEXT:    fldl (%esp)
 ; CHECK-NEXT:    fadd %st, %st(5)
-; CHECK-NEXT:    fsubr %st, %st(5)
-; CHECK-NEXT:    fxch %st(4)
-; CHECK-NEXT:    fmull -8
 ; CHECK-NEXT:    fxch %st(5)
-; CHECK-NEXT:    fstl 8
-; CHECK-NEXT:    fxch %st(2)
-; CHECK-NEXT:    fsubp %st, %st(5)
-; CHECK-NEXT:    fxch %st(4)
-; CHECK-NEXT:    fsubp %st, %st(2)
+; CHECK-NEXT:    fstpl {{[0-9]+}}(%esp)
+; CHECK-NEXT:    fldl {{[0-9]+}}(%esp)
+; CHECK-NEXT:    fsub %st(5), %st
+; CHECK-NEXT:    fstpl {{[0-9]+}}(%esp)
+; CHECK-NEXT:    fldl {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    fxch %st(1)
-; CHECK-NEXT:    fadd %st(2), %st
-; CHECK-NEXT:    faddp %st, %st(2)
+; CHECK-NEXT:    fmull -8
 ; CHECK-NEXT:    fxch %st(1)
-; CHECK-NEXT:    fstl 16
+; CHECK-NEXT:    fstl 8
+; CHECK-NEXT:    fxch %st(1)
+; CHECK-NEXT:    fstpl {{[0-9]+}}(%esp)
+; CHECK-NEXT:    fldl {{[0-9]+}}(%esp)
+; CHECK-NEXT:    fsubrp %st, %st(3)
 ; CHECK-NEXT:    fxch %st(2)
-; CHECK-NEXT:    fadd %st, %st(0)
+; CHECK-NEXT:    fstpl {{[0-9]+}}(%esp)
+; CHECK-NEXT:    fldl {{[0-9]+}}(%esp)
+; CHECK-NEXT:    fsubp %st, %st(3)
+; CHECK-NEXT:    fxch %st(2)
+; CHECK-NEXT:    fstpl {{[0-9]+}}(%esp)
+; CHECK-NEXT:    fldl {{[0-9]+}}(%esp)
+; CHECK-NEXT:    fadd %st(3), %st
+; CHECK-NEXT:    fstpl {{[0-9]+}}(%esp)
+; CHECK-NEXT:    fldl {{[0-9]+}}(%esp)
+; CHECK-NEXT:    faddp %st, %st(3)
+; CHECK-NEXT:    fxch %st(2)
+; CHECK-NEXT:    fstpl {{[0-9]+}}(%esp)
+; CHECK-NEXT:    fldl {{[0-9]+}}(%esp)
+; CHECK-NEXT:    fstl 16
 ; CHECK-NEXT:    fxch %st(1)
 ; CHECK-NEXT:    fadd %st, %st(0)
 ; CHECK-NEXT:    fxch %st(2)
 ; CHECK-NEXT:    fadd %st, %st(0)
 ; CHECK-NEXT:    fxch %st(1)
+; CHECK-NEXT:    fadd %st, %st(0)
+; CHECK-NEXT:    fxch %st(2)
 ; CHECK-NEXT:    fstpl 2056(%ecx)
-; CHECK-NEXT:    fxch %st(1)
 ; CHECK-NEXT:    fstpl 2064(%ecx)
 ; CHECK-NEXT:    fstpl 2072(%ecx)
 ; CHECK-NEXT:    movl %eax, 0
diff --git a/llvm/test/CodeGen/X86/no-ret-in-x87-reg.ll b/llvm/test/CodeGen/X86/no-ret-in-x87-reg.ll
index 19554e652e4cc..89ffbd76071ef 100644
--- a/llvm/test/CodeGen/X86/no-ret-in-x87-reg.ll
+++ b/llvm/test/CodeGen/X86/no-ret-in-x87-reg.ll
@@ -58,8 +58,12 @@ entry:
 define float @f4(float %a, float %b) nounwind {
 ; X87-LABEL: f4:
 ; X87:       # %bb.0: # %entry
+; X87-NEXT:    pushl %eax
 ; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    fadds {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps (%esp)
+; X87-NEXT:    flds (%esp)
+; X87-NEXT:    popl %eax
 ; X87-NEXT:    retl
 ;
 ; NOSSE-NOX87-LABEL: f4:
@@ -84,8 +88,16 @@ entry:
 define double @f5(double %a, double %b) nounwind {
 ; X87-LABEL: f5:
 ; X87:       # %bb.0: # %entry
-; X87-NEXT:    fldl {{[0-9]+}}(%esp)
-; X87-NEXT:    faddl {{[0-9]+}}(%esp)
+; X87-NEXT:    pushl %ebp
+; X87-NEXT:    movl %esp, %ebp
+; X87-NEXT:    andl $-8, %esp
+; X87-NEXT:    subl $8, %esp
+; X87-NEXT:    fldl 8(%ebp)
+; X87-NEXT:    faddl 16(%ebp)
+; X87-NEXT:    fstpl (%esp)
+; X87-NEXT:    fldl (%esp)
+; X87-NEXT:    movl %ebp, %esp
+; X87-NEXT:    popl %ebp
 ; X87-NEXT:    retl
 ;
 ; NOSSE-NOX87-LABEL: f5:
diff --git a/llvm/test/CodeGen/X86/nosse-vector.ll b/llvm/test/CodeGen/X86/nosse-vector.ll
index 9807d1b09d8ef..edf96ba76dc78 100644
--- a/llvm/test/CodeGen/X86/nosse-vector.ll
+++ b/llvm/test/CodeGen/X86/nosse-vector.ll
@@ -8,10 +8,9 @@ define void @fadd_2f64_mem(ptr %p0, ptr %p1, ptr %p2) nounwind {
 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx
-; X32-NEXT:    fldl 8(%edx)
 ; X32-NEXT:    fldl (%edx)
 ; X32-NEXT:    faddl (%ecx)
-; X32-NEXT:    fxch %st(1)
+; X32-NEXT:    fldl 8(%edx)
 ; X32-NEXT:    faddl 8(%ecx)
 ; X32-NEXT:    fstpl 8(%eax)
 ; X32-NEXT:    fstpl (%eax)
@@ -19,10 +18,9 @@ define void @fadd_2f64_mem(ptr %p0, ptr %p1, ptr %p2) nounwind {
 ;
 ; X64-LABEL: fadd_2f64_mem:
 ; X64:       # %bb.0:
-; X64-NEXT:    fldl 8(%rdi)
 ; X64-NEXT:    fldl (%rdi)
 ; X64-NEXT:    faddl (%rsi)
-; X64-NEXT:    fxch %st(1)
+; X64-NEXT:    fldl 8(%rdi)
 ; X64-NEXT:    faddl 8(%rsi)
 ; X64-NEXT:    fstpl 8(%rdx)
 ; X64-NEXT:    fstpl (%rdx)
@@ -40,19 +38,15 @@ define void @fadd_4f32_mem(ptr %p0, ptr %p1, ptr %p2) nounwind {
 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx
-; X32-NEXT:    flds 12(%edx)
-; X32-NEXT:    flds 8(%edx)
-; X32-NEXT:    flds 4(%edx)
 ; X32-NEXT:    flds (%edx)
 ; X32-NEXT:    fadds (%ecx)
-; X32-NEXT:    fxch %st(1)
+; X32-NEXT:    flds 4(%edx)
 ; X32-NEXT:    fadds 4(%ecx)
-; X32-NEXT:    fxch %st(2)
+; X32-NEXT:    flds 8(%edx)
 ; X32-NEXT:    fadds 8(%ecx)
-; X32-NEXT:    fxch %st(3)
+; X32-NEXT:    flds 12(%edx)
 ; X32-NEXT:    fadds 12(%ecx)
 ; X32-NEXT:    fstps 12(%eax)
-; X32-NEXT:    fxch %st(2)
 ; X32-NEXT:    fstps 8(%eax)
 ; X32-NEXT:    fstps 4(%eax)
 ; X32-NEXT:    fstps (%eax)
@@ -60,19 +54,15 @@ define void @fadd_4f32_mem(ptr %p0, ptr %p1, ptr %p2) nounwind {
 ;
 ; X64-LABEL: fadd_4f32_mem:
 ; X64:       # %bb.0:
-; X64-NEXT:    flds 12(%rdi)
-; X64-NEXT:    flds 8(%rdi)
-; X64-NEXT:    flds 4(%rdi)
 ; X64-NEXT:    flds (%rdi)
 ; X64-NEXT:    fadds (%rsi)
-; X64-NEXT:    fxch %st(1)
+; X64-NEXT:    flds 4(%rdi)
 ; X64-NEXT:    fadds 4(%rsi)
-; X64-NEXT:    fxch %st(2)
+; X64-NEXT:    flds 8(%rdi)
 ; X64-NEXT:    fadds 8(%rsi)
-; X64-NEXT:    fxch %st(3)
+; X64-NEXT:    flds 12(%rdi)
 ; X64-NEXT:    fadds 12(%rsi)
 ; X64-NEXT:    fstps 12(%rdx)
-; X64-NEXT:    fxch %st(2)
 ; X64-NEXT:    fstps 8(%rdx)
 ; X64-NEXT:    fstps 4(%rdx)
 ; X64-NEXT:    fstps (%rdx)
@@ -90,19 +80,15 @@ define void @fdiv_4f32_mem(ptr %p0, ptr %p1, ptr %p2) nounwind {
 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx
-; X32-NEXT:    flds 12(%edx)
-; X32-NEXT:    flds 8(%edx)
-; X32-NEXT:    flds 4(%edx)
 ; X32-NEXT:    flds (%edx)
 ; X32-NEXT:    fdivs (%ecx)
-; X32-NEXT:    fxch %st(1)
+; X32-NEXT:    flds 4(%edx)
 ; X32-NEXT:    fdivs 4(%ecx)
-; X32-NEXT:    fxch %st(2)
+; X32-NEXT:    flds 8(%edx)
 ; X32-NEXT:    fdivs 8(%ecx)
-; X32-NEXT:    fxch %st(3)
+; X32-NEXT:    flds 12(%edx)
 ; X32-NEXT:    fdivs 12(%ecx)
 ; X32-NEXT:    fstps 12(%eax)
-; X32-NEXT:    fxch %st(2)
 ; X32-NEXT:    fstps 8(%eax)
 ; X32-NEXT:    fstps 4(%eax)
 ; X32-NEXT:    fstps (%eax)
@@ -110,19 +96,15 @@ define void @fdiv_4f32_mem(ptr %p0, ptr %p1, ptr %p2) nounwind {
 ;
 ; X64-LABEL: fdiv_4f32_mem:
 ; X64:       # %bb.0:
-; X64-NEXT:    flds 12(%rdi)
-; X64-NEXT:    flds 8(%rdi)
-; X64-NEXT:    flds 4(%rdi)
 ; X64-NEXT:    flds (%rdi)
 ; X64-NEXT:    fdivs (%rsi)
-; X64-NEXT:    fxch %st(1)
+; X64-NEXT:    flds 4(%rdi)
 ; X64-NEXT:    fdivs 4(%rsi)
-; X64-NEXT:    fxch %st(2)
+; X64-NEXT:    flds 8(%rdi)
 ; X64-NEXT:    fdivs 8(%rsi)
-; X64-NEXT:    fxch %st(3)
+; X64-NEXT:    flds 12(%rdi)
 ; X64-NEXT:    fdivs 12(%rsi)
 ; X64-NEXT:    fstps 12(%rdx)
-; X64-NEXT:    fxch %st(2)
 ; X64-NEXT:    fstps 8(%rdx)
 ; X64-NEXT:    fstps 4(%rdx)
 ; X64-NEXT:    fstps (%rdx)
diff --git a/llvm/test/CodeGen/X86/powi-const.ll b/llvm/test/CodeGen/X86/powi-const.ll
index 49f0e9a6b1455..594e252d5f7ec 100644
--- a/llvm/test/CodeGen/X86/powi-const.ll
+++ b/llvm/test/CodeGen/X86/powi-const.ll
@@ -8,14 +8,34 @@
 define double @pow_wrapper(double %a) nounwind readonly ssp noredzone {
 ; X86-X87-LABEL: pow_wrapper:
 ; X86-X87:       # %bb.0:
+; X86-X87-NEXT:    pushl %ebp
+; X86-X87-NEXT:    movl %esp, %ebp
+; X86-X87-NEXT:    andl $-8, %esp
+; X86-X87-NEXT:    subl $48, %esp
+; X86-X87-NEXT:    fldl 8(%ebp)
+; X86-X87-NEXT:    fld %st(0)
+; X86-X87-NEXT:    fmul %st(1), %st
+; X86-X87-NEXT:    fstpl (%esp)
+; X86-X87-NEXT:    fldl (%esp)
+; X86-X87-NEXT:    fld %st(0)
+; X86-X87-NEXT:    fmul %st(1), %st
+; X86-X87-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-X87-NEXT:    fmulp %st, %st(1)
+; X86-X87-NEXT:    fstpl {{[0-9]+}}(%esp)
 ; X86-X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-X87-NEXT:    fld %st(0)
 ; X86-X87-NEXT:    fmul %st(1), %st
-; X86-X87-NEXT:    fmul %st, %st(1)
-; X86-X87-NEXT:    fmul %st, %st(0)
-; X86-X87-NEXT:    fmul %st, %st(1)
-; X86-X87-NEXT:    fmul %st, %st(0)
+; X86-X87-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-X87-NEXT:    fmulp %st, %st(1)
+; X86-X87-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-X87-NEXT:    fldl {{[0-9]+}}(%esp)
+; X86-X87-NEXT:    fldl {{[0-9]+}}(%esp)
+; X86-X87-NEXT:    fmulp %st, %st(1)
+; X86-X87-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-X87-NEXT:    fldl {{[0-9]+}}(%esp)
+; X86-X87-NEXT:    movl %ebp, %esp
+; X86-X87-NEXT:    popl %ebp
 ; X86-X87-NEXT:    retl
 ;
 ; X86-SSE-LABEL: pow_wrapper:
diff --git a/llvm/test/CodeGen/X86/pr34080-2.ll b/llvm/test/CodeGen/X86/pr34080-2.ll
index 279373a7aab3f..79798c898fbdd 100644
--- a/llvm/test/CodeGen/X86/pr34080-2.ll
+++ b/llvm/test/CodeGen/X86/pr34080-2.ll
@@ -12,7 +12,7 @@ define void @computeJD(ptr) nounwind {
 ; CHECK-NEXT:    pushl %edi
 ; CHECK-NEXT:    pushl %esi
 ; CHECK-NEXT:    andl $-8, %esp
-; CHECK-NEXT:    subl $40, %esp
+; CHECK-NEXT:    subl $64, %esp
 ; CHECK-NEXT:    movl 8(%ebp), %ebx
 ; CHECK-NEXT:    movl 8(%ebx), %esi
 ; CHECK-NEXT:    xorl %eax, %eax
@@ -49,7 +49,11 @@ define void @computeJD(ptr) nounwind {
 ; CHECK-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    fildl {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; CHECK-NEXT:    fstpl {{[0-9]+}}(%esp)
+; CHECK-NEXT:    fldl {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
+; CHECK-NEXT:    fstpl {{[0-9]+}}(%esp)
+; CHECK-NEXT:    fldl {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    fnstcw {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
 ; CHECK-NEXT:    orl $3072, %eax # imm = 0xC00
@@ -63,6 +67,8 @@ define void @computeJD(ptr) nounwind {
 ; CHECK-NEXT:    addl %ecx, %eax
 ; CHECK-NEXT:    fldl 28(%ebx)
 ; CHECK-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
+; CHECK-NEXT:    fstpl {{[0-9]+}}(%esp)
+; CHECK-NEXT:    fldl {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    fnstcw {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
 ; CHECK-NEXT:    orl $3072, %ecx # imm = 0xC00
diff --git a/llvm/test/CodeGen/X86/pr35982.ll b/llvm/test/CodeGen/X86/pr35982.ll
index 0ad35309b87bb..39f266f09bbc9 100644
--- a/llvm/test/CodeGen/X86/pr35982.ll
+++ b/llvm/test/CodeGen/X86/pr35982.ll
@@ -5,32 +5,38 @@
 define float @PR35982_emms(<1 x i64>) nounwind {
 ; NO-POSTRA-LABEL: PR35982_emms:
 ; NO-POSTRA:       # %bb.0:
-; NO-POSTRA-NEXT:    subl $8, %esp
+; NO-POSTRA-NEXT:    subl $12, %esp
 ; NO-POSTRA-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; NO-POSTRA-NEXT:    movq {{[0-9]+}}(%esp), %mm0
 ; NO-POSTRA-NEXT:    punpckhdq %mm0, %mm0 # mm0 = mm0[1,1]
 ; NO-POSTRA-NEXT:    movd %mm0, %ecx
 ; NO-POSTRA-NEXT:    emms
-; NO-POSTRA-NEXT:    movl %eax, (%esp)
-; NO-POSTRA-NEXT:    fildl (%esp)
+; NO-POSTRA-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; NO-POSTRA-NEXT:    fildl {{[0-9]+}}(%esp)
 ; NO-POSTRA-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
-; NO-POSTRA-NEXT:    fiaddl {{[0-9]+}}(%esp)
-; NO-POSTRA-NEXT:    addl $8, %esp
+; NO-POSTRA-NEXT:    fildl {{[0-9]+}}(%esp)
+; NO-POSTRA-NEXT:    faddp %st, %st(1)
+; NO-POSTRA-NEXT:    fstps (%esp)
+; NO-POSTRA-NEXT:    flds (%esp)
+; NO-POSTRA-NEXT:    addl $12, %esp
 ; NO-POSTRA-NEXT:    retl
 ;
 ; POSTRA-LABEL: PR35982_emms:
 ; POSTRA:       # %bb.0:
-; POSTRA-NEXT:    subl $8, %esp
+; POSTRA-NEXT:    subl $12, %esp
 ; POSTRA-NEXT:    movq {{[0-9]+}}(%esp), %mm0
 ; POSTRA-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; POSTRA-NEXT:    punpckhdq %mm0, %mm0 # mm0 = mm0[1,1]
 ; POSTRA-NEXT:    movd %mm0, %ecx
 ; POSTRA-NEXT:    emms
-; POSTRA-NEXT:    movl %eax, (%esp)
-; POSTRA-NEXT:    fildl (%esp)
+; POSTRA-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; POSTRA-NEXT:    fildl {{[0-9]+}}(%esp)
 ; POSTRA-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
-; POSTRA-NEXT:    fiaddl {{[0-9]+}}(%esp)
-; POSTRA-NEXT:    addl $8, %esp
+; POSTRA-NEXT:    fildl {{[0-9]+}}(%esp)
+; POSTRA-NEXT:    faddp %st, %st(1)
+; POSTRA-NEXT:    fstps (%esp)
+; POSTRA-NEXT:    flds (%esp)
+; POSTRA-NEXT:    addl $12, %esp
 ; POSTRA-NEXT:    retl
   %2 = bitcast <1 x i64> %0 to <2 x i32>
   %3 = extractelement <2 x i32> %2, i32 0
diff --git a/llvm/test/CodeGen/X86/pr50782.ll b/llvm/test/CodeGen/X86/pr50782.ll
index 591a33446d4e3..7bb7db376d279 100644
--- a/llvm/test/CodeGen/X86/pr50782.ll
+++ b/llvm/test/CodeGen/X86/pr50782.ll
@@ -20,7 +20,7 @@ define void @h(float %i) {
 ; CHECK-NEXT:    .cfi_def_cfa_register %ebp
 ; CHECK-NEXT:    pushl %esi
 ; CHECK-NEXT:    andl $-16, %esp
-; CHECK-NEXT:    subl $32, %esp
+; CHECK-NEXT:    subl $64, %esp
 ; CHECK-NEXT:    movl %esp, %esi
 ; CHECK-NEXT:    .cfi_offset %esi, -12
 ; CHECK-NEXT:    flds 8(%ebp)
@@ -31,50 +31,62 @@ define void @h(float %i) {
 ; CHECK-NEXT:    movl %esp, %eax
 ; CHECK-NEXT:    andl $-16, %eax
 ; CHECK-NEXT:    movl %eax, %esp
-; CHECK-NEXT:    fsts 8(%esi) # 4-byte Folded Spill
+; CHECK-NEXT:    fld %st(0)
+; CHECK-NEXT:    fstpt 36(%esi) # 10-byte Folded Spill
 ; CHECK-NEXT:    fadds _b
+; CHECK-NEXT:    fstps 32(%esi)
+; CHECK-NEXT:    flds 32(%esi)
 ; CHECK-NEXT:    fsts _d
 ; CHECK-NEXT:    fld1
 ; CHECK-NEXT:    fldz
 ; CHECK-NEXT:    testl %ecx, %ecx
-; CHECK-NEXT:    fld %st(0)
-; CHECK-NEXT:    fld %st(2)
 ; CHECK-NEXT:    je LBB0_2
 ; CHECK-NEXT:  # %bb.1: # %for.body.preheader
-; CHECK-NEXT:    fstp %st(1)
+; CHECK-NEXT:    fstp %st(0)
 ; CHECK-NEXT:    fstp %st(0)
 ; CHECK-NEXT:    movl _f, %ecx
 ; CHECK-NEXT:    flds (%eax,%ecx,4)
-; CHECK-NEXT:    fld %st(3)
+; CHECK-NEXT:    fld %st(1)
+; CHECK-NEXT:    fxch %st(1)
 ; CHECK-NEXT:  LBB0_2: # %for.cond1.preheader
 ; CHECK-NEXT:    movl _e, %ecx
-; CHECK-NEXT:    movl %ecx, 12(%esi)
-; CHECK-NEXT:    fildl 12(%esi)
+; CHECK-NEXT:    movl %ecx, 28(%esi)
+; CHECK-NEXT:    fildl 28(%esi)
 ; CHECK-NEXT:    movl _c, %edx
+; CHECK-NEXT:    fldz
+; CHECK-NEXT:    fld1
 ; CHECK-NEXT:    jmp LBB0_3
 ; CHECK-NEXT:    .p2align 4
 ; CHECK-NEXT:  LBB0_5: # %for.inc
 ; CHECK-NEXT:    # in Loop: Header=BB0_3 Depth=1
+; CHECK-NEXT:    fadd %st, %st(5)
 ; CHECK-NEXT:    fxch %st(5)
-; CHECK-NEXT:    fadd %st(4), %st
+; CHECK-NEXT:    fstps 12(%esi)
+; CHECK-NEXT:    flds 12(%esi)
 ; CHECK-NEXT:    fxch %st(5)
 ; CHECK-NEXT:  LBB0_3: # %for.cond1
 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
 ; CHECK-NEXT:    fld %st(5)
-; CHECK-NEXT:    fmul %st(4), %st
-; CHECK-NEXT:    fdiv %st(2), %st
-; CHECK-NEXT:    fadd %st(3), %st
+; CHECK-NEXT:    fmul %st(2), %st
+; CHECK-NEXT:    fstps 16(%esi)
+; CHECK-NEXT:    flds 16(%esi)
+; CHECK-NEXT:    fdiv %st(5), %st
+; CHECK-NEXT:    fstps 20(%esi)
+; CHECK-NEXT:    flds 20(%esi)
+; CHECK-NEXT:    fadd %st(4), %st
+; CHECK-NEXT:    fstps 24(%esi)
+; CHECK-NEXT:    flds 24(%esi)
 ; CHECK-NEXT:    fsts _g
-; CHECK-NEXT:    fxch %st(1)
-; CHECK-NEXT:    fucom %st(1)
-; CHECK-NEXT:    fstp %st(1)
+; CHECK-NEXT:    fxch %st(3)
+; CHECK-NEXT:    fucom %st(3)
+; CHECK-NEXT:    fstp %st(3)
 ; CHECK-NEXT:    fnstsw %ax
 ; CHECK-NEXT:    # kill: def $ah killed $ah killed $ax
 ; CHECK-NEXT:    sahf
 ; CHECK-NEXT:    jbe LBB0_5
 ; CHECK-NEXT:  # %bb.4: # %if.then
 ; CHECK-NEXT:    # in Loop: Header=BB0_3 Depth=1
-; CHECK-NEXT:    flds 8(%esi) # 4-byte Folded Reload
+; CHECK-NEXT:    fldt 36(%esi) # 10-byte Folded Reload
 ; CHECK-NEXT:    fstps (%edx,%ecx,4)
 ; CHECK-NEXT:    jmp LBB0_5
 entry:
diff --git a/llvm/test/CodeGen/X86/pr59305.ll b/llvm/test/CodeGen/X86/pr59305.ll
index d8738081842a3..d203f3037c807 100644
--- a/llvm/test/CodeGen/X86/pr59305.ll
+++ b/llvm/test/CodeGen/X86/pr59305.ll
@@ -31,38 +31,45 @@ define double @foo(double %0) #0 {
 ;
 ; X86-LABEL: foo:
 ; X86:       # %bb.0:
-; X86-NEXT:    subl $60, %esp
+; X86-NEXT:    subl $92, %esp
 ; X86-NEXT:    fldl {{[0-9]+}}(%esp)
-; X86-NEXT:    fstpl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Spill
+; X86-NEXT:    fstpt {{[-0-9]+}}(%e{{[sb]}}p) # 10-byte Folded Spill
 ; X86-NEXT:    wait
 ; X86-NEXT:    movl $1024, (%esp) # imm = 0x400
 ; X86-NEXT:    calll fesetround at PLT
 ; X86-NEXT:    fld1
-; X86-NEXT:    fstl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Spill
-; X86-NEXT:    fldl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Reload
+; X86-NEXT:    fld %st(0)
+; X86-NEXT:    fstpt {{[-0-9]+}}(%e{{[sb]}}p) # 10-byte Folded Spill
+; X86-NEXT:    fldt {{[-0-9]+}}(%e{{[sb]}}p) # 10-byte Folded Reload
 ; X86-NEXT:    fdivrp %st, %st(1)
+; X86-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-NEXT:    fstpl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Spill
 ; X86-NEXT:    wait
 ; X86-NEXT:    movl $1024, (%esp) # imm = 0x400
 ; X86-NEXT:    calll fesetround at PLT
-; X86-NEXT:    fldl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Reload
-; X86-NEXT:    fldl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Reload
+; X86-NEXT:    fldt {{[-0-9]+}}(%e{{[sb]}}p) # 10-byte Folded Reload
+; X86-NEXT:    fldt {{[-0-9]+}}(%e{{[sb]}}p) # 10-byte Folded Reload
 ; X86-NEXT:    fdivp %st, %st(1)
+; X86-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-NEXT:    fstpl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Spill
 ; X86-NEXT:    wait
 ; X86-NEXT:    movl $1024, (%esp) # imm = 0x400
 ; X86-NEXT:    calll fesetround at PLT
-; X86-NEXT:    fldl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Reload
-; X86-NEXT:    fldl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Reload
+; X86-NEXT:    fldt {{[-0-9]+}}(%e{{[sb]}}p) # 10-byte Folded Reload
+; X86-NEXT:    fldt {{[-0-9]+}}(%e{{[sb]}}p) # 10-byte Folded Reload
 ; X86-NEXT:    fdivp %st, %st(1)
 ; X86-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-NEXT:    fldl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Reload
 ; X86-NEXT:    fstpl {{[0-9]+}}(%esp)
 ; X86-NEXT:    fldl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Reload
 ; X86-NEXT:    fstpl (%esp)
+; X86-NEXT:    fstpl {{[0-9]+}}(%esp)
 ; X86-NEXT:    wait
 ; X86-NEXT:    calll fma
-; X86-NEXT:    addl $60, %esp
+; X86-NEXT:    addl $92, %esp
 ; X86-NEXT:    retl
     %2 = call i32 @fesetround(i32 noundef 1024)
     %3 = call double @llvm.experimental.constrained.fdiv.f64(double 1.000000e+00, double %0, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
@@ -100,7 +107,7 @@ define double @bar(double %0) #0 {
 ;
 ; X86-LABEL: bar:
 ; X86:       # %bb.0:
-; X86-NEXT:    subl $28, %esp
+; X86-NEXT:    subl $60, %esp
 ; X86-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-NEXT:    wait
 ; X86-NEXT:    #APP
@@ -109,11 +116,17 @@ define double @bar(double %0) #0 {
 ; X86-NEXT:    fld1
 ; X86-NEXT:    fld %st(0)
 ; X86-NEXT:    fdiv %st(2), %st
+; X86-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-NEXT:    fldl {{[0-9]+}}(%esp)
+; X86-NEXT:    wait
 ; X86-NEXT:    #APP
 ; X86-NEXT:    fldcw 0
 ; X86-NEXT:    #NO_APP
 ; X86-NEXT:    fld %st(1)
 ; X86-NEXT:    fdiv %st(3), %st
+; X86-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-NEXT:    fldl {{[0-9]+}}(%esp)
+; X86-NEXT:    wait
 ; X86-NEXT:    #APP
 ; X86-NEXT:    fldcw 0
 ; X86-NEXT:    #NO_APP
@@ -121,11 +134,15 @@ define double @bar(double %0) #0 {
 ; X86-NEXT:    fdivp %st, %st(3)
 ; X86-NEXT:    fxch %st(2)
 ; X86-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-NEXT:    fldl {{[0-9]+}}(%esp)
+; X86-NEXT:    fxch %st(1)
 ; X86-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-NEXT:    fxch %st(1)
 ; X86-NEXT:    fstpl (%esp)
+; X86-NEXT:    fstpl {{[0-9]+}}(%esp)
 ; X86-NEXT:    wait
 ; X86-NEXT:    calll fma
-; X86-NEXT:    addl $28, %esp
+; X86-NEXT:    addl $60, %esp
 ; X86-NEXT:    retl
     call void asm sideeffect "SETROUND $0", "*m,~{dirflag},~{fpsr},~{flags}"(ptr elementtype(i32) null)
     %2 = call double @llvm.experimental.constrained.fdiv.f64(double 1.000000e+00, double %0, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
diff --git a/llvm/test/CodeGen/X86/scalar-fp-to-i64.ll b/llvm/test/CodeGen/X86/scalar-fp-to-i64.ll
index 3287869f2c601..09289dbbc3f13 100644
--- a/llvm/test/CodeGen/X86/scalar-fp-to-i64.ll
+++ b/llvm/test/CodeGen/X86/scalar-fp-to-i64.ll
@@ -245,10 +245,8 @@ define i64 @f_to_u64(float %a) nounwind {
 ; X87-WIN-NEXT:    flds __real at 5f000000
 ; X87-WIN-NEXT:    fucom %st(1)
 ; X87-WIN-NEXT:    fnstsw %ax
-; X87-WIN-NEXT:    xorl %edx, %edx
 ; X87-WIN-NEXT:    # kill: def $ah killed $ah killed $ax
 ; X87-WIN-NEXT:    sahf
-; X87-WIN-NEXT:    setbe %al
 ; X87-WIN-NEXT:    fldz
 ; X87-WIN-NEXT:    jbe LBB0_2
 ; X87-WIN-NEXT:  # %bb.1:
@@ -257,14 +255,17 @@ define i64 @f_to_u64(float %a) nounwind {
 ; X87-WIN-NEXT:  LBB0_2:
 ; X87-WIN-NEXT:    fstp %st(0)
 ; X87-WIN-NEXT:    fsubrp %st, %st(1)
-; X87-WIN-NEXT:    fnstcw {{[0-9]+}}(%esp)
-; X87-WIN-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
+; X87-WIN-NEXT:    fstps {{[0-9]+}}(%esp)
+; X87-WIN-NEXT:    setbe %al
+; X87-WIN-NEXT:    flds {{[0-9]+}}(%esp)
+; X87-WIN-NEXT:    fnstcw (%esp)
+; X87-WIN-NEXT:    movzwl (%esp), %ecx
 ; X87-WIN-NEXT:    orl $3072, %ecx # imm = 0xC00
 ; X87-WIN-NEXT:    movw %cx, {{[0-9]+}}(%esp)
 ; X87-WIN-NEXT:    fldcw {{[0-9]+}}(%esp)
 ; X87-WIN-NEXT:    fistpll {{[0-9]+}}(%esp)
-; X87-WIN-NEXT:    fldcw {{[0-9]+}}(%esp)
-; X87-WIN-NEXT:    movb %al, %dl
+; X87-WIN-NEXT:    fldcw (%esp)
+; X87-WIN-NEXT:    movzbl %al, %edx
 ; X87-WIN-NEXT:    shll $31, %edx
 ; X87-WIN-NEXT:    xorl {{[0-9]+}}(%esp), %edx
 ; X87-WIN-NEXT:    movl {{[0-9]+}}(%esp), %eax
@@ -279,10 +280,8 @@ define i64 @f_to_u64(float %a) nounwind {
 ; X87-LIN-NEXT:    flds {{\.?LCPI[0-9]+_[0-9]+}}
 ; X87-LIN-NEXT:    fucom %st(1)
 ; X87-LIN-NEXT:    fnstsw %ax
-; X87-LIN-NEXT:    xorl %edx, %edx
 ; X87-LIN-NEXT:    # kill: def $ah killed $ah killed $ax
 ; X87-LIN-NEXT:    sahf
-; X87-LIN-NEXT:    setbe %al
 ; X87-LIN-NEXT:    fldz
 ; X87-LIN-NEXT:    jbe .LBB0_2
 ; X87-LIN-NEXT:  # %bb.1:
@@ -291,14 +290,17 @@ define i64 @f_to_u64(float %a) nounwind {
 ; X87-LIN-NEXT:  .LBB0_2:
 ; X87-LIN-NEXT:    fstp %st(0)
 ; X87-LIN-NEXT:    fsubrp %st, %st(1)
-; X87-LIN-NEXT:    fnstcw {{[0-9]+}}(%esp)
-; X87-LIN-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
+; X87-LIN-NEXT:    fstps {{[0-9]+}}(%esp)
+; X87-LIN-NEXT:    setbe %al
+; X87-LIN-NEXT:    flds {{[0-9]+}}(%esp)
+; X87-LIN-NEXT:    fnstcw (%esp)
+; X87-LIN-NEXT:    movzwl (%esp), %ecx
 ; X87-LIN-NEXT:    orl $3072, %ecx # imm = 0xC00
 ; X87-LIN-NEXT:    movw %cx, {{[0-9]+}}(%esp)
 ; X87-LIN-NEXT:    fldcw {{[0-9]+}}(%esp)
 ; X87-LIN-NEXT:    fistpll {{[0-9]+}}(%esp)
-; X87-LIN-NEXT:    fldcw {{[0-9]+}}(%esp)
-; X87-LIN-NEXT:    movb %al, %dl
+; X87-LIN-NEXT:    fldcw (%esp)
+; X87-LIN-NEXT:    movzbl %al, %edx
 ; X87-LIN-NEXT:    shll $31, %edx
 ; X87-LIN-NEXT:    xorl {{[0-9]+}}(%esp), %edx
 ; X87-LIN-NEXT:    movl {{[0-9]+}}(%esp), %eax
@@ -673,15 +675,13 @@ define i64 @d_to_u64(double %a) nounwind {
 ; X87-WIN-NEXT:    pushl %ebp
 ; X87-WIN-NEXT:    movl %esp, %ebp
 ; X87-WIN-NEXT:    andl $-8, %esp
-; X87-WIN-NEXT:    subl $16, %esp
+; X87-WIN-NEXT:    subl $24, %esp
 ; X87-WIN-NEXT:    fldl 8(%ebp)
 ; X87-WIN-NEXT:    flds __real at 5f000000
 ; X87-WIN-NEXT:    fucom %st(1)
 ; X87-WIN-NEXT:    fnstsw %ax
-; X87-WIN-NEXT:    xorl %edx, %edx
 ; X87-WIN-NEXT:    # kill: def $ah killed $ah killed $ax
 ; X87-WIN-NEXT:    sahf
-; X87-WIN-NEXT:    setbe %al
 ; X87-WIN-NEXT:    fldz
 ; X87-WIN-NEXT:    jbe LBB2_2
 ; X87-WIN-NEXT:  # %bb.1:
@@ -690,6 +690,9 @@ define i64 @d_to_u64(double %a) nounwind {
 ; X87-WIN-NEXT:  LBB2_2:
 ; X87-WIN-NEXT:    fstp %st(0)
 ; X87-WIN-NEXT:    fsubrp %st, %st(1)
+; X87-WIN-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X87-WIN-NEXT:    setbe %al
+; X87-WIN-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-WIN-NEXT:    fnstcw {{[0-9]+}}(%esp)
 ; X87-WIN-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
 ; X87-WIN-NEXT:    orl $3072, %ecx # imm = 0xC00
@@ -697,7 +700,7 @@ define i64 @d_to_u64(double %a) nounwind {
 ; X87-WIN-NEXT:    fldcw {{[0-9]+}}(%esp)
 ; X87-WIN-NEXT:    fistpll {{[0-9]+}}(%esp)
 ; X87-WIN-NEXT:    fldcw {{[0-9]+}}(%esp)
-; X87-WIN-NEXT:    movb %al, %dl
+; X87-WIN-NEXT:    movzbl %al, %edx
 ; X87-WIN-NEXT:    shll $31, %edx
 ; X87-WIN-NEXT:    xorl {{[0-9]+}}(%esp), %edx
 ; X87-WIN-NEXT:    movl {{[0-9]+}}(%esp), %eax
@@ -707,15 +710,13 @@ define i64 @d_to_u64(double %a) nounwind {
 ;
 ; X87-LIN-LABEL: d_to_u64:
 ; X87-LIN:       # %bb.0:
-; X87-LIN-NEXT:    subl $20, %esp
+; X87-LIN-NEXT:    subl $28, %esp
 ; X87-LIN-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-LIN-NEXT:    flds {{\.?LCPI[0-9]+_[0-9]+}}
 ; X87-LIN-NEXT:    fucom %st(1)
 ; X87-LIN-NEXT:    fnstsw %ax
-; X87-LIN-NEXT:    xorl %edx, %edx
 ; X87-LIN-NEXT:    # kill: def $ah killed $ah killed $ax
 ; X87-LIN-NEXT:    sahf
-; X87-LIN-NEXT:    setbe %al
 ; X87-LIN-NEXT:    fldz
 ; X87-LIN-NEXT:    jbe .LBB2_2
 ; X87-LIN-NEXT:  # %bb.1:
@@ -724,6 +725,9 @@ define i64 @d_to_u64(double %a) nounwind {
 ; X87-LIN-NEXT:  .LBB2_2:
 ; X87-LIN-NEXT:    fstp %st(0)
 ; X87-LIN-NEXT:    fsubrp %st, %st(1)
+; X87-LIN-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X87-LIN-NEXT:    setbe %al
+; X87-LIN-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-LIN-NEXT:    fnstcw {{[0-9]+}}(%esp)
 ; X87-LIN-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
 ; X87-LIN-NEXT:    orl $3072, %ecx # imm = 0xC00
@@ -731,11 +735,11 @@ define i64 @d_to_u64(double %a) nounwind {
 ; X87-LIN-NEXT:    fldcw {{[0-9]+}}(%esp)
 ; X87-LIN-NEXT:    fistpll {{[0-9]+}}(%esp)
 ; X87-LIN-NEXT:    fldcw {{[0-9]+}}(%esp)
-; X87-LIN-NEXT:    movb %al, %dl
+; X87-LIN-NEXT:    movzbl %al, %edx
 ; X87-LIN-NEXT:    shll $31, %edx
 ; X87-LIN-NEXT:    xorl {{[0-9]+}}(%esp), %edx
 ; X87-LIN-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X87-LIN-NEXT:    addl $20, %esp
+; X87-LIN-NEXT:    addl $28, %esp
 ; X87-LIN-NEXT:    retl
   %r = fptoui double %a to i64
   ret i64 %r
diff --git a/llvm/test/CodeGen/X86/select.ll b/llvm/test/CodeGen/X86/select.ll
index 1901ba9408e91..376615258ea20 100644
--- a/llvm/test/CodeGen/X86/select.ll
+++ b/llvm/test/CodeGen/X86/select.ll
@@ -293,30 +293,39 @@ define void @test6(i32 %C, ptr %A, ptr %B) nounwind {
 ;
 ; ATHLON-LABEL: test6:
 ; ATHLON:       ## %bb.0:
+; ATHLON-NEXT:    subl $16, %esp
 ; ATHLON-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; ATHLON-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; ATHLON-NEXT:    flds 12(%eax)
 ; ATHLON-NEXT:    flds 8(%eax)
 ; ATHLON-NEXT:    flds 4(%eax)
 ; ATHLON-NEXT:    flds (%eax)
+; ATHLON-NEXT:    flds 12(%ecx)
+; ATHLON-NEXT:    fmul %st, %st(0)
+; ATHLON-NEXT:    fstps {{[0-9]+}}(%esp)
+; ATHLON-NEXT:    flds 8(%ecx)
+; ATHLON-NEXT:    fmul %st, %st(0)
+; ATHLON-NEXT:    fstps {{[0-9]+}}(%esp)
+; ATHLON-NEXT:    flds 4(%ecx)
+; ATHLON-NEXT:    fmul %st, %st(0)
+; ATHLON-NEXT:    fstps {{[0-9]+}}(%esp)
 ; ATHLON-NEXT:    flds (%ecx)
 ; ATHLON-NEXT:    fmul %st, %st(0)
+; ATHLON-NEXT:    fstps (%esp)
+; ATHLON-NEXT:    flds (%esp)
 ; ATHLON-NEXT:    cmpl $0, {{[0-9]+}}(%esp)
 ; ATHLON-NEXT:    fxch %st(1)
 ; ATHLON-NEXT:    fcmove %st(1), %st
 ; ATHLON-NEXT:    fstp %st(1)
-; ATHLON-NEXT:    flds 4(%ecx)
-; ATHLON-NEXT:    fmul %st, %st(0)
+; ATHLON-NEXT:    flds {{[0-9]+}}(%esp)
 ; ATHLON-NEXT:    fxch %st(2)
 ; ATHLON-NEXT:    fcmove %st(2), %st
 ; ATHLON-NEXT:    fstp %st(2)
-; ATHLON-NEXT:    flds 8(%ecx)
-; ATHLON-NEXT:    fmul %st, %st(0)
+; ATHLON-NEXT:    flds {{[0-9]+}}(%esp)
 ; ATHLON-NEXT:    fxch %st(3)
 ; ATHLON-NEXT:    fcmove %st(3), %st
 ; ATHLON-NEXT:    fstp %st(3)
-; ATHLON-NEXT:    flds 12(%ecx)
-; ATHLON-NEXT:    fmul %st, %st(0)
+; ATHLON-NEXT:    flds {{[0-9]+}}(%esp)
 ; ATHLON-NEXT:    fxch %st(4)
 ; ATHLON-NEXT:    fcmove %st(4), %st
 ; ATHLON-NEXT:    fstp %st(4)
@@ -326,57 +335,62 @@ define void @test6(i32 %C, ptr %A, ptr %B) nounwind {
 ; ATHLON-NEXT:    fstps 8(%eax)
 ; ATHLON-NEXT:    fstps 4(%eax)
 ; ATHLON-NEXT:    fstps (%eax)
+; ATHLON-NEXT:    addl $16, %esp
 ; ATHLON-NEXT:    retl
 ;
 ; MCU-LABEL: test6:
 ; MCU:       # %bb.0:
-; MCU-NEXT:    pushl %eax
+; MCU-NEXT:    subl $20, %esp
 ; MCU-NEXT:    flds 12(%edx)
 ; MCU-NEXT:    fstps (%esp) # 4-byte Folded Spill
 ; MCU-NEXT:    flds 8(%edx)
 ; MCU-NEXT:    flds 4(%edx)
-; MCU-NEXT:    flds (%ecx)
-; MCU-NEXT:    flds 4(%ecx)
-; MCU-NEXT:    flds 8(%ecx)
+; MCU-NEXT:    flds (%edx)
 ; MCU-NEXT:    flds 12(%ecx)
 ; MCU-NEXT:    fmul %st, %st(0)
-; MCU-NEXT:    fxch %st(1)
+; MCU-NEXT:    fstps {{[0-9]+}}(%esp)
+; MCU-NEXT:    flds 8(%ecx)
 ; MCU-NEXT:    fmul %st, %st(0)
-; MCU-NEXT:    fxch %st(2)
+; MCU-NEXT:    fstps {{[0-9]+}}(%esp)
+; MCU-NEXT:    flds 4(%ecx)
 ; MCU-NEXT:    fmul %st, %st(0)
-; MCU-NEXT:    fxch %st(3)
+; MCU-NEXT:    fstps {{[0-9]+}}(%esp)
+; MCU-NEXT:    flds (%ecx)
 ; MCU-NEXT:    fmul %st, %st(0)
+; MCU-NEXT:    fstps {{[0-9]+}}(%esp)
+; MCU-NEXT:    flds {{[0-9]+}}(%esp)
+; MCU-NEXT:    flds {{[0-9]+}}(%esp)
+; MCU-NEXT:    flds {{[0-9]+}}(%esp)
 ; MCU-NEXT:    testl %eax, %eax
-; MCU-NEXT:    flds (%edx)
+; MCU-NEXT:    flds {{[0-9]+}}(%esp)
 ; MCU-NEXT:    je .LBB5_2
 ; MCU-NEXT:  # %bb.1:
-; MCU-NEXT:    fstp %st(1)
 ; MCU-NEXT:    fstp %st(3)
+; MCU-NEXT:    fstp %st(0)
 ; MCU-NEXT:    fstp %st(1)
 ; MCU-NEXT:    fstp %st(0)
 ; MCU-NEXT:    flds (%esp) # 4-byte Folded Reload
 ; MCU-NEXT:    fldz
 ; MCU-NEXT:    fldz
 ; MCU-NEXT:    fldz
-; MCU-NEXT:    fxch %st(1)
+; MCU-NEXT:    fxch %st(2)
 ; MCU-NEXT:    fxch %st(6)
 ; MCU-NEXT:    fxch %st(1)
 ; MCU-NEXT:    fxch %st(5)
+; MCU-NEXT:    fxch %st(2)
 ; MCU-NEXT:    fxch %st(4)
 ; MCU-NEXT:    fxch %st(1)
-; MCU-NEXT:    fxch %st(3)
 ; MCU-NEXT:    fxch %st(2)
+; MCU-NEXT:    fxch %st(1)
 ; MCU-NEXT:  .LBB5_2:
-; MCU-NEXT:    fstp %st(0)
-; MCU-NEXT:    fstp %st(5)
-; MCU-NEXT:    fstp %st(3)
-; MCU-NEXT:    fxch %st(2)
+; MCU-NEXT:    fstp %st(6)
+; MCU-NEXT:    fstp %st(4)
+; MCU-NEXT:    fstp %st(2)
 ; MCU-NEXT:    fstps 12(%edx)
-; MCU-NEXT:    fxch %st(1)
 ; MCU-NEXT:    fstps 8(%edx)
 ; MCU-NEXT:    fstps 4(%edx)
 ; MCU-NEXT:    fstps (%edx)
-; MCU-NEXT:    popl %eax
+; MCU-NEXT:    addl $20, %esp
 ; MCU-NEXT:    retl
   %tmp = load <4 x float>, ptr %A
   %tmp3 = load <4 x float>, ptr %B
diff --git a/llvm/test/CodeGen/X86/x87-round-to-type.ll b/llvm/test/CodeGen/X86/x87-round-to-type.ll
index 5e52529fb38ee..997b2734289f3 100644
--- a/llvm/test/CodeGen/X86/x87-round-to-type.ll
+++ b/llvm/test/CodeGen/X86/x87-round-to-type.ll
@@ -13,9 +13,12 @@ declare void @opaque()
 define i32 @cmp_reload_f32(float %a, float %b, ptr %p) nounwind {
 ; X87-LABEL: cmp_reload_f32:
 ; X87:       # %bb.0:
+; X87-NEXT:    pushl %eax
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    fadds {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps (%esp)
+; X87-NEXT:    flds (%esp)
 ; X87-NEXT:    fsts (%eax)
 ; X87-NEXT:    flds (%eax)
 ; X87-NEXT:    fxch %st(1)
@@ -27,6 +30,7 @@ define i32 @cmp_reload_f32(float %a, float %b, ptr %p) nounwind {
 ; X87-NEXT:    sete %cl
 ; X87-NEXT:    andb %al, %cl
 ; X87-NEXT:    movzbl %cl, %eax
+; X87-NEXT:    popl %ecx
 ; X87-NEXT:    retl
   %add = fadd float %a, %b
   store volatile float %add, ptr %p
@@ -39,9 +43,12 @@ define i32 @cmp_reload_f32(float %a, float %b, ptr %p) nounwind {
 define i32 @cmp_reload_f64(double %a, double %b, ptr %p) nounwind {
 ; X87-LABEL: cmp_reload_f64:
 ; X87:       # %bb.0:
+; X87-NEXT:    subl $12, %esp
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    faddl {{[0-9]+}}(%esp)
+; X87-NEXT:    fstpl (%esp)
+; X87-NEXT:    fldl (%esp)
 ; X87-NEXT:    fstl (%eax)
 ; X87-NEXT:    fldl (%eax)
 ; X87-NEXT:    fxch %st(1)
@@ -53,6 +60,7 @@ define i32 @cmp_reload_f64(double %a, double %b, ptr %p) nounwind {
 ; X87-NEXT:    sete %cl
 ; X87-NEXT:    andb %al, %cl
 ; X87-NEXT:    movzbl %cl, %eax
+; X87-NEXT:    addl $12, %esp
 ; X87-NEXT:    retl
   %add = fadd double %a, %b
   store volatile double %add, ptr %p
@@ -67,8 +75,12 @@ define i32 @cmp_reload_f64(double %a, double %b, ptr %p) nounwind {
 define float @fadd_f32(float %a, float %b) nounwind {
 ; X87-LABEL: fadd_f32:
 ; X87:       # %bb.0:
+; X87-NEXT:    pushl %eax
 ; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    fadds {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps (%esp)
+; X87-NEXT:    flds (%esp)
+; X87-NEXT:    popl %eax
 ; X87-NEXT:    retl
   %r = fadd float %a, %b
   ret float %r
@@ -77,8 +89,12 @@ define float @fadd_f32(float %a, float %b) nounwind {
 define float @fsub_f32(float %a, float %b) nounwind {
 ; X87-LABEL: fsub_f32:
 ; X87:       # %bb.0:
+; X87-NEXT:    pushl %eax
 ; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    fsubs {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps (%esp)
+; X87-NEXT:    flds (%esp)
+; X87-NEXT:    popl %eax
 ; X87-NEXT:    retl
   %r = fsub float %a, %b
   ret float %r
@@ -87,8 +103,12 @@ define float @fsub_f32(float %a, float %b) nounwind {
 define float @fmul_f32(float %a, float %b) nounwind {
 ; X87-LABEL: fmul_f32:
 ; X87:       # %bb.0:
+; X87-NEXT:    pushl %eax
 ; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    fmuls {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps (%esp)
+; X87-NEXT:    flds (%esp)
+; X87-NEXT:    popl %eax
 ; X87-NEXT:    retl
   %r = fmul float %a, %b
   ret float %r
@@ -97,8 +117,12 @@ define float @fmul_f32(float %a, float %b) nounwind {
 define float @fdiv_f32(float %a, float %b) nounwind {
 ; X87-LABEL: fdiv_f32:
 ; X87:       # %bb.0:
+; X87-NEXT:    pushl %eax
 ; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    fdivs {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps (%esp)
+; X87-NEXT:    flds (%esp)
+; X87-NEXT:    popl %eax
 ; X87-NEXT:    retl
   %r = fdiv float %a, %b
   ret float %r
@@ -107,8 +131,12 @@ define float @fdiv_f32(float %a, float %b) nounwind {
 define float @fsqrt_f32(float %a) nounwind {
 ; X87-LABEL: fsqrt_f32:
 ; X87:       # %bb.0:
+; X87-NEXT:    pushl %eax
 ; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    fsqrt
+; X87-NEXT:    fstps (%esp)
+; X87-NEXT:    flds (%esp)
+; X87-NEXT:    popl %eax
 ; X87-NEXT:    retl
   %r = call float @llvm.sqrt.f32(float %a)
   ret float %r
@@ -117,8 +145,12 @@ define float @fsqrt_f32(float %a) nounwind {
 define double @fadd_f64(double %a, double %b) nounwind {
 ; X87-LABEL: fadd_f64:
 ; X87:       # %bb.0:
+; X87-NEXT:    subl $12, %esp
 ; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    faddl {{[0-9]+}}(%esp)
+; X87-NEXT:    fstpl (%esp)
+; X87-NEXT:    fldl (%esp)
+; X87-NEXT:    addl $12, %esp
 ; X87-NEXT:    retl
   %r = fadd double %a, %b
   ret double %r
@@ -127,8 +159,12 @@ define double @fadd_f64(double %a, double %b) nounwind {
 define double @fsqrt_f64(double %a) nounwind {
 ; X87-LABEL: fsqrt_f64:
 ; X87:       # %bb.0:
+; X87-NEXT:    subl $12, %esp
 ; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    fsqrt
+; X87-NEXT:    fstpl (%esp)
+; X87-NEXT:    fldl (%esp)
+; X87-NEXT:    addl $12, %esp
 ; X87-NEXT:    retl
   %r = call double @llvm.sqrt.f64(double %a)
   ret double %r
@@ -152,8 +188,12 @@ define x86_fp80 @fadd_f80(x86_fp80 %a, x86_fp80 %b) nounwind {
 define float @fadd_const_f32(float %a) nounwind {
 ; X87-LABEL: fadd_const_f32:
 ; X87:       # %bb.0:
+; X87-NEXT:    pushl %eax
 ; X87-NEXT:    fld1
 ; X87-NEXT:    fadds {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps (%esp)
+; X87-NEXT:    flds (%esp)
+; X87-NEXT:    popl %eax
 ; X87-NEXT:    retl
   %r = fadd float %a, 1.0
   ret float %r
@@ -213,12 +253,16 @@ define void @store_only_f64(double %a, double %b, ptr %p) nounwind {
 define void @store_twice_f32(float %a, float %b, ptr %p, ptr %q) nounwind {
 ; X87-LABEL: store_twice_f32:
 ; X87:       # %bb.0:
+; X87-NEXT:    pushl %eax
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    fadds {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps (%esp)
+; X87-NEXT:    flds (%esp)
 ; X87-NEXT:    fsts (%ecx)
 ; X87-NEXT:    fstps (%eax)
+; X87-NEXT:    popl %eax
 ; X87-NEXT:    retl
   %r = fadd float %a, %b
   store float %r, ptr %p
@@ -230,10 +274,14 @@ define void @store_twice_f32(float %a, float %b, ptr %p, ptr %q) nounwind {
 define float @store_and_use_f32(float %a, float %b, ptr %p) nounwind {
 ; X87-LABEL: store_and_use_f32:
 ; X87:       # %bb.0:
+; X87-NEXT:    pushl %eax
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    fadds {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps (%esp)
+; X87-NEXT:    flds (%esp)
 ; X87-NEXT:    fsts (%eax)
+; X87-NEXT:    popl %eax
 ; X87-NEXT:    retl
   %r = fadd float %a, %b
   store float %r, ptr %p
@@ -244,14 +292,16 @@ define float @store_and_use_f32(float %a, float %b, ptr %p) nounwind {
 define void @store_narrower_f32(double %a, double %b, ptr %p) nounwind {
 ; X87-LABEL: store_narrower_f32:
 ; X87:       # %bb.0:
-; X87-NEXT:    pushl %eax
+; X87-NEXT:    subl $20, %esp
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    faddl {{[0-9]+}}(%esp)
-; X87-NEXT:    fstps (%esp)
-; X87-NEXT:    flds (%esp)
+; X87-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps {{[0-9]+}}(%esp)
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    fstps (%eax)
-; X87-NEXT:    popl %eax
+; X87-NEXT:    addl $20, %esp
 ; X87-NEXT:    retl
   %r = fadd double %a, %b
   %t = fptrunc double %r to float
@@ -457,6 +507,8 @@ define float @spill_across_call(float %a, float %b) nounwind {
 ; X87-NEXT:    subl $12, %esp
 ; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    fadds {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps {{[0-9]+}}(%esp)
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    fstps {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Folded Spill
 ; X87-NEXT:    calll opaque at PLT
 ; X87-NEXT:    flds {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Folded Reload
@@ -472,12 +524,19 @@ define float @spill_across_call(float %a, float %b) nounwind {
 define float @chain_f32(float %a, float %b, float %c, float %d) nounwind {
 ; X87-LABEL: chain_f32:
 ; X87:       # %bb.0:
-; X87-NEXT:    flds {{[0-9]+}}(%esp)
+; X87-NEXT:    subl $12, %esp
 ; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    fmuls {{[0-9]+}}(%esp)
-; X87-NEXT:    fxch %st(1)
+; X87-NEXT:    fstps (%esp)
+; X87-NEXT:    flds (%esp)
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    fmuls {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps {{[0-9]+}}(%esp)
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    faddp %st, %st(1)
+; X87-NEXT:    fstps {{[0-9]+}}(%esp)
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
+; X87-NEXT:    addl $12, %esp
 ; X87-NEXT:    retl
   %ab = fmul float %a, %b
   %cd = fmul float %c, %d
@@ -489,9 +548,14 @@ define float @chain_f32(float %a, float %b, float %c, float %d) nounwind {
 define float @strict_fadd_f32(float %a, float %b) nounwind strictfp {
 ; X87-LABEL: strict_fadd_f32:
 ; X87:       # %bb.0:
+; X87-NEXT:    pushl %eax
 ; X87-NEXT:    flds {{[0-9]+}}(%esp)
-; X87-NEXT:    fadds {{[0-9]+}}(%esp)
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
+; X87-NEXT:    faddp %st, %st(1)
+; X87-NEXT:    fstps (%esp)
+; X87-NEXT:    flds (%esp)
 ; X87-NEXT:    wait
+; X87-NEXT:    popl %eax
 ; X87-NEXT:    retl
   %r = call float @llvm.experimental.constrained.fadd.f32(float %a, float %b,
                                                           metadata !"round.dynamic",

>From c59be4ac2f70245b0e34d8168690d2c00dce8074 Mon Sep 17 00:00:00 2001
From: Dennis Duda <git at seri.tools>
Date: Sat, 8 Aug 2026 00:23:54 +0200
Subject: [PATCH 03/15] [X86] Add rounding memory roundtrip for `fild`

Co-authored-by: Claude (Claude-Opus-5) <noreply at anthropic.com>
---
 llvm/lib/Target/X86/X86ISelLowering.cpp       |  11 +-
 llvm/lib/Target/X86/X86ISelLowering.h         |   5 +
 .../test/CodeGen/X86/bfloat-int64-cvt-i686.ll |   6 +
 llvm/test/CodeGen/X86/fildll.ll               |   4 +-
 llvm/test/CodeGen/X86/fp-intrinsics.ll        | 120 +++++++-----
 .../CodeGen/X86/fp-strict-scalar-inttofp.ll   | 136 ++++++++-----
 llvm/test/CodeGen/X86/int-to-fp-demanded.ll   |  56 ++++--
 llvm/test/CodeGen/X86/isel-sint-to-fp-x87.ll  | 178 +++++++++++++-----
 llvm/test/CodeGen/X86/limited-prec.ll         | 168 ++++++++++-------
 llvm/test/CodeGen/X86/nosse-vector.ll         |  42 ++++-
 llvm/test/CodeGen/X86/pr178410.ll             |   8 +-
 llvm/test/CodeGen/X86/pr34080-2.ll            |   4 +-
 llvm/test/CodeGen/X86/pr35982.ll              |  18 +-
 llvm/test/CodeGen/X86/pr50782.ll              |  14 +-
 llvm/test/CodeGen/X86/scalar-int-to-fp.ll     |  83 +++++---
 llvm/test/CodeGen/X86/x87-round-to-type.ll    |  70 ++++---
 16 files changed, 612 insertions(+), 311 deletions(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index b07e629cd6770..b365b3ce9a508 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -912,7 +912,7 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
   // takes care of fp_extending, doing the op, then fp_rounding back to the
   // narrow type.
   for (auto VT : {MVT::f32, MVT::f64}) {
-    if (!isScalarFPTypeOnX87Stack(VT))
+    if (!needsX87RoundToType(VT))
       continue;
     // Promote only ops that may need rounding (fneg/fabs are just sign flips,
     // always exact)
@@ -3735,6 +3735,10 @@ bool X86TargetLowering::isScalarFPTypeOnX87Stack(EVT VT) const {
          ((VT == MVT::f32 || VT == MVT::f64) && !isScalarFPTypeInSSEReg(VT));
 }
 
+bool X86TargetLowering::needsX87RoundToType(EVT VT) const {
+  return (VT == MVT::f32 || VT == MVT::f64) && isScalarFPTypeOnX87Stack(VT);
+}
+
 bool X86TargetLowering::isLoadBitCastBeneficial(EVT LoadVT, EVT BitcastVT,
                                                 const SelectionDAG &DAG,
                                                 const MachineMemOperand &MMO) const {
@@ -20706,7 +20710,8 @@ std::pair<SDValue, SDValue> X86TargetLowering::BuildFILD(
   // Build the FILD
   SDVTList Tys;
   bool useSSE = isScalarFPTypeInSSEReg(DstVT);
-  if (useSSE)
+  bool needsX87Round = needsX87RoundToType(DstVT);
+  if (useSSE || needsX87Round)
     Tys = DAG.getVTList(MVT::f80, MVT::Other);
   else
     Tys = DAG.getVTList(DstVT, MVT::Other);
@@ -20717,7 +20722,7 @@ std::pair<SDValue, SDValue> X86TargetLowering::BuildFILD(
                               Alignment, MachineMemOperand::MOLoad);
   Chain = Result.getValue(1);
 
-  if (useSSE) {
+  if (useSSE || needsX87Round) {
     MachineFunction &MF = DAG.getMachineFunction();
     unsigned SSFISize = DstVT.getStoreSize();
     // The slot is private, so ABI alignment is enough. More might realign the
diff --git a/llvm/lib/Target/X86/X86ISelLowering.h b/llvm/lib/Target/X86/X86ISelLowering.h
index 21b0d0053d52a..dd94ce26d2765 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.h
+++ b/llvm/lib/Target/X86/X86ISelLowering.h
@@ -568,6 +568,11 @@ namespace llvm {
     /// bits wide, regardless of the precision of the value being computed.
     bool isScalarFPTypeOnX87Stack(EVT VT) const;
 
+    /// Returns true if results of x87 operations on \p VT must be rounded back
+    /// to \p VT through memory instead of being left at the register's 80-bit
+    /// precision, i.e. f32/f64 on the x87 stack.
+    bool needsX87RoundToType(EVT VT) const;
+
     /// Returns true if it is beneficial to convert a load of a constant
     /// to just the constant itself.
     bool shouldConvertConstantLoadToIntImm(const APInt &Imm,
diff --git a/llvm/test/CodeGen/X86/bfloat-int64-cvt-i686.ll b/llvm/test/CodeGen/X86/bfloat-int64-cvt-i686.ll
index 9236951501a5f..a205dcb8987eb 100644
--- a/llvm/test/CodeGen/X86/bfloat-int64-cvt-i686.ll
+++ b/llvm/test/CodeGen/X86/bfloat-int64-cvt-i686.ll
@@ -16,6 +16,8 @@ define bfloat @sitofp_i64_to_bf16(i64 %a) nounwind {
 ; X87-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
 ; X87-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; X87-NEXT:    fildll {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps {{[0-9]+}}(%esp)
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    fstps (%esp)
 ; X87-NEXT:    calll __truncsfbf2
 ; X87-NEXT:    # kill: def $ax killed $ax def $eax
@@ -70,6 +72,8 @@ define bfloat @sitofp_load_i64_to_bf16(ptr %p) nounwind {
 ; X87-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; X87-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
 ; X87-NEXT:    fildll {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps {{[0-9]+}}(%esp)
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    fstps (%esp)
 ; X87-NEXT:    calll __truncsfbf2
 ; X87-NEXT:    # kill: def $ax killed $ax def $eax
@@ -268,6 +272,8 @@ define bfloat @strict_sitofp_load_i64_to_bf16(ptr %p) strictfp nounwind {
 ; X87-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; X87-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
 ; X87-NEXT:    fildll {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps {{[0-9]+}}(%esp)
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    fstps (%esp)
 ; X87-NEXT:    wait
 ; X87-NEXT:    calll __truncsfbf2
diff --git a/llvm/test/CodeGen/X86/fildll.ll b/llvm/test/CodeGen/X86/fildll.ll
index 43c5525f6068c..4b3a07829ce10 100644
--- a/llvm/test/CodeGen/X86/fildll.ll
+++ b/llvm/test/CodeGen/X86/fildll.ll
@@ -10,10 +10,12 @@ define fastcc double @sint64_to_fp(i64 %X) {
 ; CHECK-NEXT:    movl %esp, %ebp
 ; CHECK-NEXT:    .cfi_def_cfa_register %ebp
 ; CHECK-NEXT:    andl $-8, %esp
-; CHECK-NEXT:    subl $8, %esp
+; CHECK-NEXT:    subl $16, %esp
 ; CHECK-NEXT:    movl %edx, {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    movl %ecx, (%esp)
 ; CHECK-NEXT:    fildll (%esp)
+; CHECK-NEXT:    fstpl {{[0-9]+}}(%esp)
+; CHECK-NEXT:    fldl {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    movl %ebp, %esp
 ; CHECK-NEXT:    popl %ebp
 ; CHECK-NEXT:    .cfi_def_cfa %esp, 4
diff --git a/llvm/test/CodeGen/X86/fp-intrinsics.ll b/llvm/test/CodeGen/X86/fp-intrinsics.ll
index 48c268f02ed72..9a5e678a1d85f 100644
--- a/llvm/test/CodeGen/X86/fp-intrinsics.ll
+++ b/llvm/test/CodeGen/X86/fp-intrinsics.ll
@@ -2027,13 +2027,15 @@ entry:
 define double @sifdb(i8 %x) #0 {
 ; X87-LABEL: sifdb:
 ; X87:       # %bb.0: # %entry
-; X87-NEXT:    pushl %eax
-; X87-NEXT:    .cfi_def_cfa_offset 8
+; X87-NEXT:    subl $12, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 16
 ; X87-NEXT:    movsbl {{[0-9]+}}(%esp), %eax
 ; X87-NEXT:    movw %ax, {{[0-9]+}}(%esp)
 ; X87-NEXT:    filds {{[0-9]+}}(%esp)
+; X87-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    wait
-; X87-NEXT:    popl %eax
+; X87-NEXT:    addl $12, %esp
 ; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl
 ;
@@ -2071,13 +2073,15 @@ entry:
 define double @sifdw(i16 %x) #0 {
 ; X87-LABEL: sifdw:
 ; X87:       # %bb.0: # %entry
-; X87-NEXT:    pushl %eax
-; X87-NEXT:    .cfi_def_cfa_offset 8
+; X87-NEXT:    subl $12, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 16
 ; X87-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
 ; X87-NEXT:    movw %ax, {{[0-9]+}}(%esp)
 ; X87-NEXT:    filds {{[0-9]+}}(%esp)
+; X87-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    wait
-; X87-NEXT:    popl %eax
+; X87-NEXT:    addl $12, %esp
 ; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl
 ;
@@ -2115,13 +2119,15 @@ entry:
 define double @sifdi(i32 %x) #0 {
 ; X87-LABEL: sifdi:
 ; X87:       # %bb.0: # %entry
-; X87-NEXT:    pushl %eax
-; X87-NEXT:    .cfi_def_cfa_offset 8
+; X87-NEXT:    subl $12, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 16
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X87-NEXT:    movl %eax, (%esp)
 ; X87-NEXT:    fildl (%esp)
+; X87-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    wait
-; X87-NEXT:    popl %eax
+; X87-NEXT:    addl $12, %esp
 ; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl
 ;
@@ -2156,13 +2162,15 @@ entry:
 define float @siffb(i8 %x) #0 {
 ; X87-LABEL: siffb:
 ; X87:       # %bb.0: # %entry
-; X87-NEXT:    pushl %eax
-; X87-NEXT:    .cfi_def_cfa_offset 8
+; X87-NEXT:    subl $8, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 12
 ; X87-NEXT:    movsbl {{[0-9]+}}(%esp), %eax
 ; X87-NEXT:    movw %ax, {{[0-9]+}}(%esp)
 ; X87-NEXT:    filds {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps {{[0-9]+}}(%esp)
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    wait
-; X87-NEXT:    popl %eax
+; X87-NEXT:    addl $8, %esp
 ; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl
 ;
@@ -2200,13 +2208,15 @@ entry:
 define float @siffw(i16 %x) #0 {
 ; X87-LABEL: siffw:
 ; X87:       # %bb.0: # %entry
-; X87-NEXT:    pushl %eax
-; X87-NEXT:    .cfi_def_cfa_offset 8
+; X87-NEXT:    subl $8, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 12
 ; X87-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
 ; X87-NEXT:    movw %ax, {{[0-9]+}}(%esp)
 ; X87-NEXT:    filds {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps {{[0-9]+}}(%esp)
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    wait
-; X87-NEXT:    popl %eax
+; X87-NEXT:    addl $8, %esp
 ; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl
 ;
@@ -2244,13 +2254,15 @@ entry:
 define float @siffi(i32 %x) #0 {
 ; X87-LABEL: siffi:
 ; X87:       # %bb.0: # %entry
-; X87-NEXT:    pushl %eax
-; X87-NEXT:    .cfi_def_cfa_offset 8
+; X87-NEXT:    subl $8, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 12
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X87-NEXT:    movl %eax, (%esp)
-; X87-NEXT:    fildl (%esp)
+; X87-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; X87-NEXT:    fildl {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps (%esp)
+; X87-NEXT:    flds (%esp)
 ; X87-NEXT:    wait
-; X87-NEXT:    popl %eax
+; X87-NEXT:    addl $8, %esp
 ; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl
 ;
@@ -2285,8 +2297,14 @@ entry:
 define double @sifdl(i64 %x) #0 {
 ; X87-LABEL: sifdl:
 ; X87:       # %bb.0: # %entry
+; X87-NEXT:    subl $8, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 12
 ; X87-NEXT:    fildll {{[0-9]+}}(%esp)
+; X87-NEXT:    fstpl (%esp)
+; X87-NEXT:    fldl (%esp)
 ; X87-NEXT:    wait
+; X87-NEXT:    addl $8, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl
 ;
 ; X86-SSE-LABEL: sifdl:
@@ -2320,8 +2338,14 @@ entry:
 define float @siffl(i64 %x) #0 {
 ; X87-LABEL: siffl:
 ; X87:       # %bb.0: # %entry
+; X87-NEXT:    pushl %eax
+; X87-NEXT:    .cfi_def_cfa_offset 8
 ; X87-NEXT:    fildll {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps (%esp)
+; X87-NEXT:    flds (%esp)
 ; X87-NEXT:    wait
+; X87-NEXT:    popl %eax
+; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl
 ;
 ; X86-SSE-LABEL: siffl:
@@ -2358,13 +2382,15 @@ entry:
 define double @uifdb(i8 %x) #0 {
 ; X87-LABEL: uifdb:
 ; X87:       # %bb.0: # %entry
-; X87-NEXT:    pushl %eax
-; X87-NEXT:    .cfi_def_cfa_offset 8
+; X87-NEXT:    subl $12, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 16
 ; X87-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
 ; X87-NEXT:    movw %ax, {{[0-9]+}}(%esp)
 ; X87-NEXT:    filds {{[0-9]+}}(%esp)
+; X87-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    wait
-; X87-NEXT:    popl %eax
+; X87-NEXT:    addl $12, %esp
 ; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl
 ;
@@ -2402,13 +2428,15 @@ entry:
 define double @uifdw(i16 %x) #0 {
 ; X87-LABEL: uifdw:
 ; X87:       # %bb.0: # %entry
-; X87-NEXT:    pushl %eax
-; X87-NEXT:    .cfi_def_cfa_offset 8
+; X87-NEXT:    subl $12, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 16
 ; X87-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
 ; X87-NEXT:    movl %eax, (%esp)
 ; X87-NEXT:    fildl (%esp)
+; X87-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    wait
-; X87-NEXT:    popl %eax
+; X87-NEXT:    addl $12, %esp
 ; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl
 ;
@@ -2446,14 +2474,16 @@ entry:
 define double @uifdi(i32 %x) #0 {
 ; X87-LABEL: uifdi:
 ; X87:       # %bb.0: # %entry
-; X87-NEXT:    subl $12, %esp
-; X87-NEXT:    .cfi_def_cfa_offset 16
+; X87-NEXT:    subl $20, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 24
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X87-NEXT:    movl %eax, (%esp)
 ; X87-NEXT:    movl $0, {{[0-9]+}}(%esp)
 ; X87-NEXT:    fildll (%esp)
+; X87-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    wait
-; X87-NEXT:    addl $12, %esp
+; X87-NEXT:    addl $20, %esp
 ; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl
 ;
@@ -2580,13 +2610,15 @@ entry:
 define float @uiffb(i8 %x) #0 {
 ; X87-LABEL: uiffb:
 ; X87:       # %bb.0: # %entry
-; X87-NEXT:    pushl %eax
-; X87-NEXT:    .cfi_def_cfa_offset 8
+; X87-NEXT:    subl $8, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 12
 ; X87-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
 ; X87-NEXT:    movw %ax, {{[0-9]+}}(%esp)
 ; X87-NEXT:    filds {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps {{[0-9]+}}(%esp)
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    wait
-; X87-NEXT:    popl %eax
+; X87-NEXT:    addl $8, %esp
 ; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl
 ;
@@ -2624,13 +2656,15 @@ entry:
 define float @uiffw(i16 %x) #0 {
 ; X87-LABEL: uiffw:
 ; X87:       # %bb.0: # %entry
-; X87-NEXT:    pushl %eax
-; X87-NEXT:    .cfi_def_cfa_offset 8
+; X87-NEXT:    subl $8, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 12
 ; X87-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
-; X87-NEXT:    movl %eax, (%esp)
-; X87-NEXT:    fildl (%esp)
+; X87-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; X87-NEXT:    fildl {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps (%esp)
+; X87-NEXT:    flds (%esp)
 ; X87-NEXT:    wait
-; X87-NEXT:    popl %eax
+; X87-NEXT:    addl $8, %esp
 ; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl
 ;
@@ -2668,14 +2702,16 @@ entry:
 define float @uiffi(i32 %x) #0 {
 ; X87-LABEL: uiffi:
 ; X87:       # %bb.0: # %entry
-; X87-NEXT:    subl $12, %esp
-; X87-NEXT:    .cfi_def_cfa_offset 16
+; X87-NEXT:    subl $20, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 24
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X87-NEXT:    movl %eax, (%esp)
+; X87-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; X87-NEXT:    movl $0, {{[0-9]+}}(%esp)
-; X87-NEXT:    fildll (%esp)
+; X87-NEXT:    fildll {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps {{[0-9]+}}(%esp)
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    wait
-; X87-NEXT:    addl $12, %esp
+; X87-NEXT:    addl $20, %esp
 ; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl
 ;
diff --git a/llvm/test/CodeGen/X86/fp-strict-scalar-inttofp.ll b/llvm/test/CodeGen/X86/fp-strict-scalar-inttofp.ll
index 1e7b4ef7b6285..042699827c15e 100644
--- a/llvm/test/CodeGen/X86/fp-strict-scalar-inttofp.ll
+++ b/llvm/test/CodeGen/X86/fp-strict-scalar-inttofp.ll
@@ -80,16 +80,18 @@ define float @sitofp_i1tof32(i1 %x) #0 {
 ;
 ; X87-LABEL: sitofp_i1tof32:
 ; X87:       # %bb.0:
-; X87-NEXT:    pushl %eax
-; X87-NEXT:    .cfi_def_cfa_offset 8
+; X87-NEXT:    subl $8, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 12
 ; X87-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
 ; X87-NEXT:    andb $1, %al
 ; X87-NEXT:    negb %al
 ; X87-NEXT:    movsbl %al, %eax
 ; X87-NEXT:    movw %ax, {{[0-9]+}}(%esp)
 ; X87-NEXT:    filds {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps {{[0-9]+}}(%esp)
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    wait
-; X87-NEXT:    popl %eax
+; X87-NEXT:    addl $8, %esp
 ; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl
   %result = call float @llvm.experimental.constrained.sitofp.f32.i1(i1 %x,
@@ -139,13 +141,15 @@ define float @sitofp_i8tof32(i8 %x) #0 {
 ;
 ; X87-LABEL: sitofp_i8tof32:
 ; X87:       # %bb.0:
-; X87-NEXT:    pushl %eax
-; X87-NEXT:    .cfi_def_cfa_offset 8
+; X87-NEXT:    subl $8, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 12
 ; X87-NEXT:    movsbl {{[0-9]+}}(%esp), %eax
 ; X87-NEXT:    movw %ax, {{[0-9]+}}(%esp)
 ; X87-NEXT:    filds {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps {{[0-9]+}}(%esp)
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    wait
-; X87-NEXT:    popl %eax
+; X87-NEXT:    addl $8, %esp
 ; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl
   %result = call float @llvm.experimental.constrained.sitofp.f32.i8(i8 %x,
@@ -195,13 +199,15 @@ define float @sitofp_i16tof32(i16 %x) #0 {
 ;
 ; X87-LABEL: sitofp_i16tof32:
 ; X87:       # %bb.0:
-; X87-NEXT:    pushl %eax
-; X87-NEXT:    .cfi_def_cfa_offset 8
+; X87-NEXT:    subl $8, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 12
 ; X87-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
 ; X87-NEXT:    movw %ax, {{[0-9]+}}(%esp)
 ; X87-NEXT:    filds {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps {{[0-9]+}}(%esp)
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    wait
-; X87-NEXT:    popl %eax
+; X87-NEXT:    addl $8, %esp
 ; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl
   %result = call float @llvm.experimental.constrained.sitofp.f32.i16(i16 %x,
@@ -247,13 +253,15 @@ define float @sitofp_i32tof32(i32 %x) #0 {
 ;
 ; X87-LABEL: sitofp_i32tof32:
 ; X87:       # %bb.0:
-; X87-NEXT:    pushl %eax
-; X87-NEXT:    .cfi_def_cfa_offset 8
+; X87-NEXT:    subl $8, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 12
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X87-NEXT:    movl %eax, (%esp)
-; X87-NEXT:    fildl (%esp)
+; X87-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; X87-NEXT:    fildl {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps (%esp)
+; X87-NEXT:    flds (%esp)
 ; X87-NEXT:    wait
-; X87-NEXT:    popl %eax
+; X87-NEXT:    addl $8, %esp
 ; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl
   %result = call float @llvm.experimental.constrained.sitofp.f32.i32(i32 %x,
@@ -299,8 +307,14 @@ define float @sitofp_i64tof32(i64 %x) #0 {
 ;
 ; X87-LABEL: sitofp_i64tof32:
 ; X87:       # %bb.0:
+; X87-NEXT:    pushl %eax
+; X87-NEXT:    .cfi_def_cfa_offset 8
 ; X87-NEXT:    fildll {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps (%esp)
+; X87-NEXT:    flds (%esp)
 ; X87-NEXT:    wait
+; X87-NEXT:    popl %eax
+; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl
   %result = call float @llvm.experimental.constrained.sitofp.f32.i64(i64 %x,
                                                metadata !"round.dynamic",
@@ -353,15 +367,17 @@ define float @uitofp_i1tof32(i1 %x) #0 {
 ;
 ; X87-LABEL: uitofp_i1tof32:
 ; X87:       # %bb.0:
-; X87-NEXT:    pushl %eax
-; X87-NEXT:    .cfi_def_cfa_offset 8
+; X87-NEXT:    subl $8, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 12
 ; X87-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
 ; X87-NEXT:    andb $1, %al
 ; X87-NEXT:    movzbl %al, %eax
 ; X87-NEXT:    movw %ax, {{[0-9]+}}(%esp)
 ; X87-NEXT:    filds {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps {{[0-9]+}}(%esp)
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    wait
-; X87-NEXT:    popl %eax
+; X87-NEXT:    addl $8, %esp
 ; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl
   %result = call float @llvm.experimental.constrained.uitofp.f32.i1(i1 %x,
@@ -411,13 +427,15 @@ define float @uitofp_i8tof32(i8 %x) #0 {
 ;
 ; X87-LABEL: uitofp_i8tof32:
 ; X87:       # %bb.0:
-; X87-NEXT:    pushl %eax
-; X87-NEXT:    .cfi_def_cfa_offset 8
+; X87-NEXT:    subl $8, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 12
 ; X87-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
 ; X87-NEXT:    movw %ax, {{[0-9]+}}(%esp)
 ; X87-NEXT:    filds {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps {{[0-9]+}}(%esp)
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    wait
-; X87-NEXT:    popl %eax
+; X87-NEXT:    addl $8, %esp
 ; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl
   %result = call float @llvm.experimental.constrained.uitofp.f32.i8(i8 %x,
@@ -467,13 +485,15 @@ define float @uitofp_i16tof32(i16 %x) #0 {
 ;
 ; X87-LABEL: uitofp_i16tof32:
 ; X87:       # %bb.0:
-; X87-NEXT:    pushl %eax
-; X87-NEXT:    .cfi_def_cfa_offset 8
+; X87-NEXT:    subl $8, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 12
 ; X87-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
-; X87-NEXT:    movl %eax, (%esp)
-; X87-NEXT:    fildl (%esp)
+; X87-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; X87-NEXT:    fildl {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps (%esp)
+; X87-NEXT:    flds (%esp)
 ; X87-NEXT:    wait
-; X87-NEXT:    popl %eax
+; X87-NEXT:    addl $8, %esp
 ; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl
   %result = call float @llvm.experimental.constrained.uitofp.f32.i16(i16 %x,
@@ -562,11 +582,13 @@ define float @uitofp_i32tof32(i32 %x) #0 {
 ; X87-NEXT:    movl %esp, %ebp
 ; X87-NEXT:    .cfi_def_cfa_register %ebp
 ; X87-NEXT:    andl $-8, %esp
-; X87-NEXT:    subl $8, %esp
+; X87-NEXT:    subl $16, %esp
 ; X87-NEXT:    movl 8(%ebp), %eax
-; X87-NEXT:    movl %eax, (%esp)
+; X87-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; X87-NEXT:    movl $0, {{[0-9]+}}(%esp)
-; X87-NEXT:    fildll (%esp)
+; X87-NEXT:    fildll {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps {{[0-9]+}}(%esp)
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    wait
 ; X87-NEXT:    movl %ebp, %esp
 ; X87-NEXT:    popl %ebp
@@ -750,13 +772,15 @@ define double @sitofp_i8tof64(i8 %x) #0 {
 ;
 ; X87-LABEL: sitofp_i8tof64:
 ; X87:       # %bb.0:
-; X87-NEXT:    pushl %eax
-; X87-NEXT:    .cfi_def_cfa_offset 8
+; X87-NEXT:    subl $12, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 16
 ; X87-NEXT:    movsbl {{[0-9]+}}(%esp), %eax
 ; X87-NEXT:    movw %ax, {{[0-9]+}}(%esp)
 ; X87-NEXT:    filds {{[0-9]+}}(%esp)
+; X87-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    wait
-; X87-NEXT:    popl %eax
+; X87-NEXT:    addl $12, %esp
 ; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl
   %result = call double @llvm.experimental.constrained.sitofp.f64.i8(i8 %x,
@@ -818,13 +842,15 @@ define double @sitofp_i16tof64(i16 %x) #0 {
 ;
 ; X87-LABEL: sitofp_i16tof64:
 ; X87:       # %bb.0:
-; X87-NEXT:    pushl %eax
-; X87-NEXT:    .cfi_def_cfa_offset 8
+; X87-NEXT:    subl $12, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 16
 ; X87-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
 ; X87-NEXT:    movw %ax, {{[0-9]+}}(%esp)
 ; X87-NEXT:    filds {{[0-9]+}}(%esp)
+; X87-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    wait
-; X87-NEXT:    popl %eax
+; X87-NEXT:    addl $12, %esp
 ; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl
   %result = call double @llvm.experimental.constrained.sitofp.f64.i16(i16 %x,
@@ -882,13 +908,15 @@ define double @sitofp_i32tof64(i32 %x) #0 {
 ;
 ; X87-LABEL: sitofp_i32tof64:
 ; X87:       # %bb.0:
-; X87-NEXT:    pushl %eax
-; X87-NEXT:    .cfi_def_cfa_offset 8
+; X87-NEXT:    subl $12, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 16
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X87-NEXT:    movl %eax, (%esp)
 ; X87-NEXT:    fildl (%esp)
+; X87-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    wait
-; X87-NEXT:    popl %eax
+; X87-NEXT:    addl $12, %esp
 ; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl
   %result = call double @llvm.experimental.constrained.sitofp.f64.i32(i32 %x,
@@ -934,8 +962,14 @@ define double @sitofp_i64tof64(i64 %x) #0 {
 ;
 ; X87-LABEL: sitofp_i64tof64:
 ; X87:       # %bb.0:
+; X87-NEXT:    subl $8, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 12
 ; X87-NEXT:    fildll {{[0-9]+}}(%esp)
+; X87-NEXT:    fstpl (%esp)
+; X87-NEXT:    fldl (%esp)
 ; X87-NEXT:    wait
+; X87-NEXT:    addl $8, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl
   %result = call double @llvm.experimental.constrained.sitofp.f64.i64(i64 %x,
                                                metadata !"round.dynamic",
@@ -1000,15 +1034,17 @@ define double @uitofp_i1tof64(i1 %x) #0 {
 ;
 ; X87-LABEL: uitofp_i1tof64:
 ; X87:       # %bb.0:
-; X87-NEXT:    pushl %eax
-; X87-NEXT:    .cfi_def_cfa_offset 8
+; X87-NEXT:    subl $12, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 16
 ; X87-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
 ; X87-NEXT:    andb $1, %al
 ; X87-NEXT:    movzbl %al, %eax
 ; X87-NEXT:    movw %ax, {{[0-9]+}}(%esp)
 ; X87-NEXT:    filds {{[0-9]+}}(%esp)
+; X87-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    wait
-; X87-NEXT:    popl %eax
+; X87-NEXT:    addl $12, %esp
 ; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl
   %result = call double @llvm.experimental.constrained.uitofp.f64.i1(i1 %x,
@@ -1070,13 +1106,15 @@ define double @uitofp_i8tof64(i8 %x) #0 {
 ;
 ; X87-LABEL: uitofp_i8tof64:
 ; X87:       # %bb.0:
-; X87-NEXT:    pushl %eax
-; X87-NEXT:    .cfi_def_cfa_offset 8
+; X87-NEXT:    subl $12, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 16
 ; X87-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
 ; X87-NEXT:    movw %ax, {{[0-9]+}}(%esp)
 ; X87-NEXT:    filds {{[0-9]+}}(%esp)
+; X87-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    wait
-; X87-NEXT:    popl %eax
+; X87-NEXT:    addl $12, %esp
 ; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl
   %result = call double @llvm.experimental.constrained.uitofp.f64.i8(i8 %x,
@@ -1138,13 +1176,15 @@ define double @uitofp_i16tof64(i16 %x) #0 {
 ;
 ; X87-LABEL: uitofp_i16tof64:
 ; X87:       # %bb.0:
-; X87-NEXT:    pushl %eax
-; X87-NEXT:    .cfi_def_cfa_offset 8
+; X87-NEXT:    subl $12, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 16
 ; X87-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
 ; X87-NEXT:    movl %eax, (%esp)
 ; X87-NEXT:    fildl (%esp)
+; X87-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    wait
-; X87-NEXT:    popl %eax
+; X87-NEXT:    addl $12, %esp
 ; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl
   %result = call double @llvm.experimental.constrained.uitofp.f64.i16(i16 %x,
@@ -1239,11 +1279,13 @@ define double @uitofp_i32tof64(i32 %x) #0 {
 ; X87-NEXT:    movl %esp, %ebp
 ; X87-NEXT:    .cfi_def_cfa_register %ebp
 ; X87-NEXT:    andl $-8, %esp
-; X87-NEXT:    subl $8, %esp
+; X87-NEXT:    subl $16, %esp
 ; X87-NEXT:    movl 8(%ebp), %eax
 ; X87-NEXT:    movl %eax, (%esp)
 ; X87-NEXT:    movl $0, {{[0-9]+}}(%esp)
 ; X87-NEXT:    fildll (%esp)
+; X87-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    wait
 ; X87-NEXT:    movl %ebp, %esp
 ; X87-NEXT:    popl %ebp
diff --git a/llvm/test/CodeGen/X86/int-to-fp-demanded.ll b/llvm/test/CodeGen/X86/int-to-fp-demanded.ll
index 54e4db33e5f22..80dcdf5ec34f4 100644
--- a/llvm/test/CodeGen/X86/int-to-fp-demanded.ll
+++ b/llvm/test/CodeGen/X86/int-to-fp-demanded.ll
@@ -7,14 +7,16 @@ declare void @use.i32(i32)
 define i32 @sitofp_signbit_only(i32 %i_in) nounwind {
 ; X86-LABEL: sitofp_signbit_only:
 ; X86:       # %bb.0:
-; X86-NEXT:    subl $8, %esp
+; X86-NEXT:    subl $12, %esp
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    movl %eax, (%esp)
-; X86-NEXT:    fildl (%esp)
+; X86-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; X86-NEXT:    fildl {{[0-9]+}}(%esp)
+; X86-NEXT:    fstps (%esp)
+; X86-NEXT:    flds (%esp)
 ; X86-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-NEXT:    movl $-2147483648, %eax # imm = 0x80000000
 ; X86-NEXT:    andl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    addl $8, %esp
+; X86-NEXT:    addl $12, %esp
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: sitofp_signbit_only:
@@ -32,14 +34,16 @@ define i32 @sitofp_signbit_only(i32 %i_in) nounwind {
 define i32 @sitofp_signbit_only_okay_width(i16 %i_in) nounwind {
 ; X86-LABEL: sitofp_signbit_only_okay_width:
 ; X86:       # %bb.0:
-; X86-NEXT:    subl $8, %esp
+; X86-NEXT:    subl $12, %esp
 ; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
 ; X86-NEXT:    movw %ax, {{[0-9]+}}(%esp)
 ; X86-NEXT:    filds {{[0-9]+}}(%esp)
 ; X86-NEXT:    fstps {{[0-9]+}}(%esp)
+; X86-NEXT:    flds {{[0-9]+}}(%esp)
+; X86-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-NEXT:    movl $-2147483648, %eax # imm = 0x80000000
 ; X86-NEXT:    andl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    addl $8, %esp
+; X86-NEXT:    addl $12, %esp
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: sitofp_signbit_only_okay_width:
@@ -81,10 +85,12 @@ define i32 @sitofp_signbit_only_fail_bad_width1(i64 %i_in) nounwind {
 define <2 x i16> @sitofp_signbit_only_fail_bad_width2(i32 %i_in) nounwind {
 ; X86-LABEL: sitofp_signbit_only_fail_bad_width2:
 ; X86:       # %bb.0:
-; X86-NEXT:    subl $8, %esp
+; X86-NEXT:    subl $12, %esp
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    movl %eax, (%esp)
-; X86-NEXT:    fildl (%esp)
+; X86-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; X86-NEXT:    fildl {{[0-9]+}}(%esp)
+; X86-NEXT:    fstps (%esp)
+; X86-NEXT:    flds (%esp)
 ; X86-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NEXT:    movl %eax, %edx
@@ -93,7 +99,7 @@ define <2 x i16> @sitofp_signbit_only_fail_bad_width2(i32 %i_in) nounwind {
 ; X86-NEXT:    andl $32768, %edx # imm = 0x8000
 ; X86-NEXT:    # kill: def $ax killed $ax killed $eax
 ; X86-NEXT:    # kill: def $dx killed $dx killed $edx
-; X86-NEXT:    addl $8, %esp
+; X86-NEXT:    addl $12, %esp
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: sitofp_signbit_only_fail_bad_width2:
@@ -110,14 +116,16 @@ define <2 x i16> @sitofp_signbit_only_fail_bad_width2(i32 %i_in) nounwind {
 define i32 @sitofp_many_bits_fail(i32 %i_in) nounwind {
 ; X86-LABEL: sitofp_many_bits_fail:
 ; X86:       # %bb.0:
-; X86-NEXT:    subl $8, %esp
+; X86-NEXT:    subl $12, %esp
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    movl %eax, (%esp)
-; X86-NEXT:    fildl (%esp)
+; X86-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; X86-NEXT:    fildl {{[0-9]+}}(%esp)
+; X86-NEXT:    fstps (%esp)
+; X86-NEXT:    flds (%esp)
 ; X86-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-NEXT:    movl $-2147483647, %eax # imm = 0x80000001
 ; X86-NEXT:    andl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    addl $8, %esp
+; X86-NEXT:    addl $12, %esp
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: sitofp_many_bits_fail:
@@ -135,16 +143,18 @@ define i32 @sitofp_many_bits_fail(i32 %i_in) nounwind {
 define i32 @sitofp_multiuse_fail(i32 %i_in) nounwind {
 ; X86-LABEL: sitofp_multiuse_fail:
 ; X86:       # %bb.0:
-; X86-NEXT:    subl $12, %esp
+; X86-NEXT:    subl $16, %esp
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; X86-NEXT:    fildl {{[0-9]+}}(%esp)
+; X86-NEXT:    fstps {{[0-9]+}}(%esp)
+; X86-NEXT:    flds {{[0-9]+}}(%esp)
 ; X86-NEXT:    fsts {{[0-9]+}}(%esp)
 ; X86-NEXT:    fstps (%esp)
 ; X86-NEXT:    calll use.i32 at PLT
 ; X86-NEXT:    movl $-2147483648, %eax # imm = 0x80000000
 ; X86-NEXT:    andl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    addl $12, %esp
+; X86-NEXT:    addl $16, %esp
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: sitofp_multiuse_fail:
@@ -168,16 +178,18 @@ define i32 @sitofp_multiuse_fail(i32 %i_in) nounwind {
 define i32 @sitofp_multiuse_okay(i32 %i_in) nounwind {
 ; X86-LABEL: sitofp_multiuse_okay:
 ; X86:       # %bb.0:
-; X86-NEXT:    subl $12, %esp
+; X86-NEXT:    subl $16, %esp
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; X86-NEXT:    fildl {{[0-9]+}}(%esp)
+; X86-NEXT:    fstps {{[0-9]+}}(%esp)
+; X86-NEXT:    flds {{[0-9]+}}(%esp)
 ; X86-NEXT:    fsts {{[0-9]+}}(%esp)
 ; X86-NEXT:    fstps (%esp)
 ; X86-NEXT:    calll use.i1 at PLT
 ; X86-NEXT:    movl $-2147483648, %eax # imm = 0x80000000
 ; X86-NEXT:    andl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    addl $12, %esp
+; X86-NEXT:    addl $16, %esp
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: sitofp_multiuse_okay:
@@ -258,6 +270,8 @@ define <2 x i16> @uitofp_signbit_only_fail_bad_width2(i32 %i_in) nounwind {
 ; X86-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; X86-NEXT:    movl $0, {{[0-9]+}}(%esp)
 ; X86-NEXT:    fildll {{[0-9]+}}(%esp)
+; X86-NEXT:    fstps (%esp)
+; X86-NEXT:    flds (%esp)
 ; X86-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-NEXT:    movl $32768, %eax # imm = 0x8000
 ; X86-NEXT:    andl {{[0-9]+}}(%esp), %eax
@@ -290,6 +304,8 @@ define i32 @uitofp_many_bits_fail(i32 %i_in) nounwind {
 ; X86-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; X86-NEXT:    movl $0, {{[0-9]+}}(%esp)
 ; X86-NEXT:    fildll {{[0-9]+}}(%esp)
+; X86-NEXT:    fstps (%esp)
+; X86-NEXT:    flds (%esp)
 ; X86-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NEXT:    andl $1, %eax
@@ -321,6 +337,8 @@ define i32 @uitofp_multiuse_fail(i32 %i_in) nounwind {
 ; X86-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; X86-NEXT:    movl $0, {{[0-9]+}}(%esp)
 ; X86-NEXT:    fildll {{[0-9]+}}(%esp)
+; X86-NEXT:    fstps {{[0-9]+}}(%esp)
+; X86-NEXT:    flds {{[0-9]+}}(%esp)
 ; X86-NEXT:    fstps (%esp)
 ; X86-NEXT:    calll use.i32 at PLT
 ; X86-NEXT:    xorl %eax, %eax
@@ -356,6 +374,8 @@ define i32 @uitofp_multiuse_okay(i32 %i_in) nounwind {
 ; X86-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; X86-NEXT:    movl $0, {{[0-9]+}}(%esp)
 ; X86-NEXT:    fildll {{[0-9]+}}(%esp)
+; X86-NEXT:    fstps {{[0-9]+}}(%esp)
+; X86-NEXT:    flds {{[0-9]+}}(%esp)
 ; X86-NEXT:    fstps (%esp)
 ; X86-NEXT:    calll use.i1 at PLT
 ; X86-NEXT:    xorl %eax, %eax
diff --git a/llvm/test/CodeGen/X86/isel-sint-to-fp-x87.ll b/llvm/test/CodeGen/X86/isel-sint-to-fp-x87.ll
index 98fa3c9541faa..3aadd487b62a9 100644
--- a/llvm/test/CodeGen/X86/isel-sint-to-fp-x87.ll
+++ b/llvm/test/CodeGen/X86/isel-sint-to-fp-x87.ll
@@ -14,6 +14,8 @@ define void @test_int8_to_float(i8 %x, ptr %p) nounwind {
 ; SDAG-X64-NEXT:    movsbl %dil, %eax
 ; SDAG-X64-NEXT:    movw %ax, -{{[0-9]+}}(%rsp)
 ; SDAG-X64-NEXT:    filds -{{[0-9]+}}(%rsp)
+; SDAG-X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
+; SDAG-X64-NEXT:    flds -{{[0-9]+}}(%rsp)
 ; SDAG-X64-NEXT:    fstps (%rsi)
 ; SDAG-X64-NEXT:    retq
 ;
@@ -28,13 +30,15 @@ define void @test_int8_to_float(i8 %x, ptr %p) nounwind {
 ;
 ; SDAG-X86-LABEL: test_int8_to_float:
 ; SDAG-X86:       # %bb.0: # %entry
-; SDAG-X86-NEXT:    pushl %eax
+; SDAG-X86-NEXT:    subl $8, %esp
 ; SDAG-X86-NEXT:    movsbl {{[0-9]+}}(%esp), %eax
 ; SDAG-X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; SDAG-X86-NEXT:    movw %ax, {{[0-9]+}}(%esp)
 ; SDAG-X86-NEXT:    filds {{[0-9]+}}(%esp)
+; SDAG-X86-NEXT:    fstps {{[0-9]+}}(%esp)
+; SDAG-X86-NEXT:    flds {{[0-9]+}}(%esp)
 ; SDAG-X86-NEXT:    fstps (%ecx)
-; SDAG-X86-NEXT:    popl %eax
+; SDAG-X86-NEXT:    addl $8, %esp
 ; SDAG-X86-NEXT:    retl
 ;
 ; GISEL-X86-LABEL: test_int8_to_float:
@@ -56,22 +60,33 @@ entry:
 }
 
 define void @test_int16_to_float(i16 %x, ptr %p) nounwind {
-; X64-LABEL: test_int16_to_float:
-; X64:       # %bb.0: # %entry
-; X64-NEXT:    movw %di, -{{[0-9]+}}(%rsp)
-; X64-NEXT:    filds -{{[0-9]+}}(%rsp)
-; X64-NEXT:    fstps (%rsi)
-; X64-NEXT:    retq
+; SDAG-X64-LABEL: test_int16_to_float:
+; SDAG-X64:       # %bb.0: # %entry
+; SDAG-X64-NEXT:    movw %di, -{{[0-9]+}}(%rsp)
+; SDAG-X64-NEXT:    filds -{{[0-9]+}}(%rsp)
+; SDAG-X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
+; SDAG-X64-NEXT:    flds -{{[0-9]+}}(%rsp)
+; SDAG-X64-NEXT:    fstps (%rsi)
+; SDAG-X64-NEXT:    retq
+;
+; GISEL-X64-LABEL: test_int16_to_float:
+; GISEL-X64:       # %bb.0: # %entry
+; GISEL-X64-NEXT:    movw %di, -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    filds -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    fstps (%rsi)
+; GISEL-X64-NEXT:    retq
 ;
 ; SDAG-X86-LABEL: test_int16_to_float:
 ; SDAG-X86:       # %bb.0: # %entry
-; SDAG-X86-NEXT:    pushl %eax
+; SDAG-X86-NEXT:    subl $8, %esp
 ; SDAG-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; SDAG-X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
 ; SDAG-X86-NEXT:    movw %cx, {{[0-9]+}}(%esp)
 ; SDAG-X86-NEXT:    filds {{[0-9]+}}(%esp)
+; SDAG-X86-NEXT:    fstps {{[0-9]+}}(%esp)
+; SDAG-X86-NEXT:    flds {{[0-9]+}}(%esp)
 ; SDAG-X86-NEXT:    fstps (%eax)
-; SDAG-X86-NEXT:    popl %eax
+; SDAG-X86-NEXT:    addl $8, %esp
 ; SDAG-X86-NEXT:    retl
 ;
 ; GISEL-X86-LABEL: test_int16_to_float:
@@ -91,22 +106,33 @@ entry:
 }
 
 define void @test_int32_to_float(i32 %x, ptr %p) nounwind {
-; X64-LABEL: test_int32_to_float:
-; X64:       # %bb.0: # %entry
-; X64-NEXT:    movl %edi, -{{[0-9]+}}(%rsp)
-; X64-NEXT:    fildl -{{[0-9]+}}(%rsp)
-; X64-NEXT:    fstps (%rsi)
-; X64-NEXT:    retq
+; SDAG-X64-LABEL: test_int32_to_float:
+; SDAG-X64:       # %bb.0: # %entry
+; SDAG-X64-NEXT:    movl %edi, -{{[0-9]+}}(%rsp)
+; SDAG-X64-NEXT:    fildl -{{[0-9]+}}(%rsp)
+; SDAG-X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
+; SDAG-X64-NEXT:    flds -{{[0-9]+}}(%rsp)
+; SDAG-X64-NEXT:    fstps (%rsi)
+; SDAG-X64-NEXT:    retq
+;
+; GISEL-X64-LABEL: test_int32_to_float:
+; GISEL-X64:       # %bb.0: # %entry
+; GISEL-X64-NEXT:    movl %edi, -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    fildl -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    fstps (%rsi)
+; GISEL-X64-NEXT:    retq
 ;
 ; SDAG-X86-LABEL: test_int32_to_float:
 ; SDAG-X86:       # %bb.0: # %entry
-; SDAG-X86-NEXT:    pushl %eax
+; SDAG-X86-NEXT:    subl $8, %esp
 ; SDAG-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; SDAG-X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; SDAG-X86-NEXT:    movl %ecx, (%esp)
-; SDAG-X86-NEXT:    fildl (%esp)
+; SDAG-X86-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
+; SDAG-X86-NEXT:    fildl {{[0-9]+}}(%esp)
+; SDAG-X86-NEXT:    fstps (%esp)
+; SDAG-X86-NEXT:    flds (%esp)
 ; SDAG-X86-NEXT:    fstps (%eax)
-; SDAG-X86-NEXT:    popl %eax
+; SDAG-X86-NEXT:    addl $8, %esp
 ; SDAG-X86-NEXT:    retl
 ;
 ; GISEL-X86-LABEL: test_int32_to_float:
@@ -126,18 +152,31 @@ entry:
 }
 
 define void @test_int64_to_float(i64 %x, ptr %p) nounwind {
-; X64-LABEL: test_int64_to_float:
-; X64:       # %bb.0: # %entry
-; X64-NEXT:    movq %rdi, -{{[0-9]+}}(%rsp)
-; X64-NEXT:    fildll -{{[0-9]+}}(%rsp)
-; X64-NEXT:    fstps (%rsi)
-; X64-NEXT:    retq
+; SDAG-X64-LABEL: test_int64_to_float:
+; SDAG-X64:       # %bb.0: # %entry
+; SDAG-X64-NEXT:    movq %rdi, -{{[0-9]+}}(%rsp)
+; SDAG-X64-NEXT:    fildll -{{[0-9]+}}(%rsp)
+; SDAG-X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
+; SDAG-X64-NEXT:    flds -{{[0-9]+}}(%rsp)
+; SDAG-X64-NEXT:    fstps (%rsi)
+; SDAG-X64-NEXT:    retq
+;
+; GISEL-X64-LABEL: test_int64_to_float:
+; GISEL-X64:       # %bb.0: # %entry
+; GISEL-X64-NEXT:    movq %rdi, -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    fildll -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    fstps (%rsi)
+; GISEL-X64-NEXT:    retq
 ;
 ; X86-LABEL: test_int64_to_float:
 ; X86:       # %bb.0: # %entry
+; X86-NEXT:    pushl %eax
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NEXT:    fildll {{[0-9]+}}(%esp)
+; X86-NEXT:    fstps (%esp)
+; X86-NEXT:    flds (%esp)
 ; X86-NEXT:    fstps (%eax)
+; X86-NEXT:    popl %eax
 ; X86-NEXT:    retl
 entry:
   %conv = sitofp i64 %x to float
@@ -244,6 +283,8 @@ define void @test_int8to_double(i8 %x, ptr %p) nounwind {
 ; SDAG-X64-NEXT:    movsbl %dil, %eax
 ; SDAG-X64-NEXT:    movw %ax, -{{[0-9]+}}(%rsp)
 ; SDAG-X64-NEXT:    filds -{{[0-9]+}}(%rsp)
+; SDAG-X64-NEXT:    fstpl -{{[0-9]+}}(%rsp)
+; SDAG-X64-NEXT:    fldl -{{[0-9]+}}(%rsp)
 ; SDAG-X64-NEXT:    fstpl (%rsi)
 ; SDAG-X64-NEXT:    retq
 ;
@@ -258,13 +299,15 @@ define void @test_int8to_double(i8 %x, ptr %p) nounwind {
 ;
 ; X86-LABEL: test_int8to_double:
 ; X86:       # %bb.0: # %entry
-; X86-NEXT:    pushl %eax
+; X86-NEXT:    subl $12, %esp
 ; X86-NEXT:    movsbl {{[0-9]+}}(%esp), %eax
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; X86-NEXT:    movw %ax, {{[0-9]+}}(%esp)
 ; X86-NEXT:    filds {{[0-9]+}}(%esp)
+; X86-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-NEXT:    fstpl (%ecx)
-; X86-NEXT:    popl %eax
+; X86-NEXT:    addl $12, %esp
 ; X86-NEXT:    retl
 entry:
   %conv = sitofp i8 %x to double
@@ -273,22 +316,33 @@ entry:
 }
 
 define void @test_int16_to_double(i16 %x, ptr %p) nounwind {
-; X64-LABEL: test_int16_to_double:
-; X64:       # %bb.0: # %entry
-; X64-NEXT:    movw %di, -{{[0-9]+}}(%rsp)
-; X64-NEXT:    filds -{{[0-9]+}}(%rsp)
-; X64-NEXT:    fstpl (%rsi)
-; X64-NEXT:    retq
+; SDAG-X64-LABEL: test_int16_to_double:
+; SDAG-X64:       # %bb.0: # %entry
+; SDAG-X64-NEXT:    movw %di, -{{[0-9]+}}(%rsp)
+; SDAG-X64-NEXT:    filds -{{[0-9]+}}(%rsp)
+; SDAG-X64-NEXT:    fstpl -{{[0-9]+}}(%rsp)
+; SDAG-X64-NEXT:    fldl -{{[0-9]+}}(%rsp)
+; SDAG-X64-NEXT:    fstpl (%rsi)
+; SDAG-X64-NEXT:    retq
+;
+; GISEL-X64-LABEL: test_int16_to_double:
+; GISEL-X64:       # %bb.0: # %entry
+; GISEL-X64-NEXT:    movw %di, -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    filds -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    fstpl (%rsi)
+; GISEL-X64-NEXT:    retq
 ;
 ; X86-LABEL: test_int16_to_double:
 ; X86:       # %bb.0: # %entry
-; X86-NEXT:    pushl %eax
+; X86-NEXT:    subl $12, %esp
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
 ; X86-NEXT:    movw %cx, {{[0-9]+}}(%esp)
 ; X86-NEXT:    filds {{[0-9]+}}(%esp)
+; X86-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-NEXT:    fstpl (%eax)
-; X86-NEXT:    popl %eax
+; X86-NEXT:    addl $12, %esp
 ; X86-NEXT:    retl
 entry:
   %conv = sitofp i16 %x to double
@@ -297,22 +351,33 @@ entry:
 }
 
 define void @test_int32_to_double(i32 %x, ptr %p) nounwind {
-; X64-LABEL: test_int32_to_double:
-; X64:       # %bb.0: # %entry
-; X64-NEXT:    movl %edi, -{{[0-9]+}}(%rsp)
-; X64-NEXT:    fildl -{{[0-9]+}}(%rsp)
-; X64-NEXT:    fstpl (%rsi)
-; X64-NEXT:    retq
+; SDAG-X64-LABEL: test_int32_to_double:
+; SDAG-X64:       # %bb.0: # %entry
+; SDAG-X64-NEXT:    movl %edi, -{{[0-9]+}}(%rsp)
+; SDAG-X64-NEXT:    fildl -{{[0-9]+}}(%rsp)
+; SDAG-X64-NEXT:    fstpl -{{[0-9]+}}(%rsp)
+; SDAG-X64-NEXT:    fldl -{{[0-9]+}}(%rsp)
+; SDAG-X64-NEXT:    fstpl (%rsi)
+; SDAG-X64-NEXT:    retq
+;
+; GISEL-X64-LABEL: test_int32_to_double:
+; GISEL-X64:       # %bb.0: # %entry
+; GISEL-X64-NEXT:    movl %edi, -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    fildl -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    fstpl (%rsi)
+; GISEL-X64-NEXT:    retq
 ;
 ; X86-LABEL: test_int32_to_double:
 ; X86:       # %bb.0: # %entry
-; X86-NEXT:    pushl %eax
+; X86-NEXT:    subl $12, %esp
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; X86-NEXT:    movl %ecx, (%esp)
 ; X86-NEXT:    fildl (%esp)
+; X86-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-NEXT:    fstpl (%eax)
-; X86-NEXT:    popl %eax
+; X86-NEXT:    addl $12, %esp
 ; X86-NEXT:    retl
 entry:
   %conv = sitofp i32 %x to double
@@ -321,18 +386,31 @@ entry:
 }
 
 define void @test_int64_to_double(i64 %x, ptr %p) nounwind {
-; X64-LABEL: test_int64_to_double:
-; X64:       # %bb.0: # %entry
-; X64-NEXT:    movq %rdi, -{{[0-9]+}}(%rsp)
-; X64-NEXT:    fildll -{{[0-9]+}}(%rsp)
-; X64-NEXT:    fstpl (%rsi)
-; X64-NEXT:    retq
+; SDAG-X64-LABEL: test_int64_to_double:
+; SDAG-X64:       # %bb.0: # %entry
+; SDAG-X64-NEXT:    movq %rdi, -{{[0-9]+}}(%rsp)
+; SDAG-X64-NEXT:    fildll -{{[0-9]+}}(%rsp)
+; SDAG-X64-NEXT:    fstpl -{{[0-9]+}}(%rsp)
+; SDAG-X64-NEXT:    fldl -{{[0-9]+}}(%rsp)
+; SDAG-X64-NEXT:    fstpl (%rsi)
+; SDAG-X64-NEXT:    retq
+;
+; GISEL-X64-LABEL: test_int64_to_double:
+; GISEL-X64:       # %bb.0: # %entry
+; GISEL-X64-NEXT:    movq %rdi, -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    fildll -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    fstpl (%rsi)
+; GISEL-X64-NEXT:    retq
 ;
 ; X86-LABEL: test_int64_to_double:
 ; X86:       # %bb.0: # %entry
+; X86-NEXT:    subl $8, %esp
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NEXT:    fildll {{[0-9]+}}(%esp)
+; X86-NEXT:    fstpl (%esp)
+; X86-NEXT:    fldl (%esp)
 ; X86-NEXT:    fstpl (%eax)
+; X86-NEXT:    addl $8, %esp
 ; X86-NEXT:    retl
 entry:
   %conv = sitofp i64 %x to double
diff --git a/llvm/test/CodeGen/X86/limited-prec.ll b/llvm/test/CodeGen/X86/limited-prec.ll
index 03c32c044c1a1..203260e606a5b 100644
--- a/llvm/test/CodeGen/X86/limited-prec.ll
+++ b/llvm/test/CodeGen/X86/limited-prec.ll
@@ -6,7 +6,7 @@
 define float @f1(float %x) nounwind noinline {
 ; precision6-LABEL: f1:
 ; precision6:       # %bb.0: # %entry
-; precision6-NEXT:    subl $40, %esp
+; precision6-NEXT:    subl $44, %esp
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
@@ -21,7 +21,8 @@ define float @f1(float %x) nounwind noinline {
 ; precision6-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; precision6-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fildl {{[0-9]+}}(%esp)
-; precision6-NEXT:    fsubrp %st, %st(1)
+; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision6-NEXT:    fsubs {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fld %st(0)
@@ -40,12 +41,12 @@ define float @f1(float %x) nounwind noinline {
 ; precision6-NEXT:    addl {{[0-9]+}}(%esp), %eax
 ; precision6-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
-; precision6-NEXT:    addl $40, %esp
+; precision6-NEXT:    addl $44, %esp
 ; precision6-NEXT:    retl
 ;
 ; precision12-LABEL: f1:
 ; precision12:       # %bb.0: # %entry
-; precision12-NEXT:    subl $48, %esp
+; precision12-NEXT:    subl $52, %esp
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
@@ -60,7 +61,8 @@ define float @f1(float %x) nounwind noinline {
 ; precision12-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; precision12-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fildl {{[0-9]+}}(%esp)
-; precision12-NEXT:    fsubrp %st, %st(1)
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    fsubs {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fld %st(0)
@@ -85,12 +87,12 @@ define float @f1(float %x) nounwind noinline {
 ; precision12-NEXT:    addl {{[0-9]+}}(%esp), %eax
 ; precision12-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
-; precision12-NEXT:    addl $48, %esp
+; precision12-NEXT:    addl $52, %esp
 ; precision12-NEXT:    retl
 ;
 ; precision18-LABEL: f1:
 ; precision18:       # %bb.0: # %entry
-; precision18-NEXT:    subl $72, %esp
+; precision18-NEXT:    subl $76, %esp
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
@@ -105,7 +107,8 @@ define float @f1(float %x) nounwind noinline {
 ; precision18-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; precision18-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fildl {{[0-9]+}}(%esp)
-; precision18-NEXT:    fsubrp %st, %st(1)
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    fsubs {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fld %st(0)
@@ -149,7 +152,7 @@ define float @f1(float %x) nounwind noinline {
 ; precision18-NEXT:    addl {{[0-9]+}}(%esp), %eax
 ; precision18-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    addl $72, %esp
+; precision18-NEXT:    addl $76, %esp
 ; precision18-NEXT:    retl
 entry:
 	%"alloca point" = bitcast i32 0 to i32		; <i32> [#uses=0]
@@ -162,7 +165,7 @@ declare float @llvm.exp.f32(float) nounwind readonly
 define float @f2(float %x) nounwind noinline {
 ; precision6-LABEL: f2:
 ; precision6:       # %bb.0: # %entry
-; precision6-NEXT:    subl $36, %esp
+; precision6-NEXT:    subl $40, %esp
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fnstcw (%esp)
 ; precision6-NEXT:    movzwl (%esp), %eax
@@ -174,7 +177,8 @@ define float @f2(float %x) nounwind noinline {
 ; precision6-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; precision6-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fildl {{[0-9]+}}(%esp)
-; precision6-NEXT:    fsubrp %st, %st(1)
+; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision6-NEXT:    fsubs {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fld %st(0)
@@ -193,12 +197,12 @@ define float @f2(float %x) nounwind noinline {
 ; precision6-NEXT:    addl {{[0-9]+}}(%esp), %eax
 ; precision6-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
-; precision6-NEXT:    addl $36, %esp
+; precision6-NEXT:    addl $40, %esp
 ; precision6-NEXT:    retl
 ;
 ; precision12-LABEL: f2:
 ; precision12:       # %bb.0: # %entry
-; precision12-NEXT:    subl $44, %esp
+; precision12-NEXT:    subl $48, %esp
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fnstcw (%esp)
 ; precision12-NEXT:    movzwl (%esp), %eax
@@ -210,7 +214,8 @@ define float @f2(float %x) nounwind noinline {
 ; precision12-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; precision12-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fildl {{[0-9]+}}(%esp)
-; precision12-NEXT:    fsubrp %st, %st(1)
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    fsubs {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fld %st(0)
@@ -235,12 +240,12 @@ define float @f2(float %x) nounwind noinline {
 ; precision12-NEXT:    addl {{[0-9]+}}(%esp), %eax
 ; precision12-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
-; precision12-NEXT:    addl $44, %esp
+; precision12-NEXT:    addl $48, %esp
 ; precision12-NEXT:    retl
 ;
 ; precision18-LABEL: f2:
 ; precision18:       # %bb.0: # %entry
-; precision18-NEXT:    subl $68, %esp
+; precision18-NEXT:    subl $72, %esp
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fnstcw (%esp)
 ; precision18-NEXT:    movzwl (%esp), %eax
@@ -252,7 +257,8 @@ define float @f2(float %x) nounwind noinline {
 ; precision18-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; precision18-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fildl {{[0-9]+}}(%esp)
-; precision18-NEXT:    fsubrp %st, %st(1)
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    fsubs {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fld %st(0)
@@ -296,7 +302,7 @@ define float @f2(float %x) nounwind noinline {
 ; precision18-NEXT:    addl {{[0-9]+}}(%esp), %eax
 ; precision18-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    addl $68, %esp
+; precision18-NEXT:    addl $72, %esp
 ; precision18-NEXT:    retl
 entry:
 	%"alloca point" = bitcast i32 0 to i32		; <i32> [#uses=0]
@@ -309,7 +315,7 @@ declare float @llvm.exp2.f32(float) nounwind readonly
 define float @f3(float %x) nounwind noinline {
 ; precision6-LABEL: f3:
 ; precision6:       # %bb.0: # %entry
-; precision6-NEXT:    subl $40, %esp
+; precision6-NEXT:    subl $44, %esp
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
@@ -324,7 +330,8 @@ define float @f3(float %x) nounwind noinline {
 ; precision6-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; precision6-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fildl {{[0-9]+}}(%esp)
-; precision6-NEXT:    fsubrp %st, %st(1)
+; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision6-NEXT:    fsubs {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fld %st(0)
@@ -343,12 +350,12 @@ define float @f3(float %x) nounwind noinline {
 ; precision6-NEXT:    addl {{[0-9]+}}(%esp), %eax
 ; precision6-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
-; precision6-NEXT:    addl $40, %esp
+; precision6-NEXT:    addl $44, %esp
 ; precision6-NEXT:    retl
 ;
 ; precision12-LABEL: f3:
 ; precision12:       # %bb.0: # %entry
-; precision12-NEXT:    subl $48, %esp
+; precision12-NEXT:    subl $52, %esp
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
@@ -363,7 +370,8 @@ define float @f3(float %x) nounwind noinline {
 ; precision12-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; precision12-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fildl {{[0-9]+}}(%esp)
-; precision12-NEXT:    fsubrp %st, %st(1)
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    fsubs {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fld %st(0)
@@ -388,12 +396,12 @@ define float @f3(float %x) nounwind noinline {
 ; precision12-NEXT:    addl {{[0-9]+}}(%esp), %eax
 ; precision12-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
-; precision12-NEXT:    addl $48, %esp
+; precision12-NEXT:    addl $52, %esp
 ; precision12-NEXT:    retl
 ;
 ; precision18-LABEL: f3:
 ; precision18:       # %bb.0: # %entry
-; precision18-NEXT:    subl $72, %esp
+; precision18-NEXT:    subl $76, %esp
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
@@ -408,7 +416,8 @@ define float @f3(float %x) nounwind noinline {
 ; precision18-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; precision18-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fildl {{[0-9]+}}(%esp)
-; precision18-NEXT:    fsubrp %st, %st(1)
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    fsubs {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fld %st(0)
@@ -452,7 +461,7 @@ define float @f3(float %x) nounwind noinline {
 ; precision18-NEXT:    addl {{[0-9]+}}(%esp), %eax
 ; precision18-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    addl $72, %esp
+; precision18-NEXT:    addl $76, %esp
 ; precision18-NEXT:    retl
 entry:
 	%"alloca point" = bitcast i32 0 to i32		; <i32> [#uses=0]
@@ -465,7 +474,7 @@ declare float @llvm.pow.f32(float, float) nounwind readonly
 define float @f4(float %x) nounwind noinline {
 ; precision6-LABEL: f4:
 ; precision6:       # %bb.0: # %entry
-; precision6-NEXT:    subl $32, %esp
+; precision6-NEXT:    subl $36, %esp
 ; precision6-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; precision6-NEXT:    movl %eax, %ecx
 ; precision6-NEXT:    andl $8388607, %ecx # imm = 0x7FFFFF
@@ -475,17 +484,19 @@ define float @f4(float %x) nounwind noinline {
 ; precision6-NEXT:    fld %st(0)
 ; precision6-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision6-NEXT:    fstps (%esp)
-; precision6-NEXT:    flds (%esp)
-; precision6-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
-; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision6-NEXT:    andl $2139095040, %eax # imm = 0x7F800000
 ; precision6-NEXT:    shrl $23, %eax
 ; precision6-NEXT:    addl $-127, %eax
 ; precision6-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; precision6-NEXT:    flds (%esp)
+; precision6-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision6-NEXT:    fildl {{[0-9]+}}(%esp)
+; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fmulp %st, %st(1)
 ; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision6-NEXT:    fildl {{[0-9]+}}(%esp)
+; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
@@ -496,12 +507,12 @@ define float @f4(float %x) nounwind noinline {
 ; precision6-NEXT:    faddp %st, %st(1)
 ; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
-; precision6-NEXT:    addl $32, %esp
+; precision6-NEXT:    addl $36, %esp
 ; precision6-NEXT:    retl
 ;
 ; precision12-LABEL: f4:
 ; precision12:       # %bb.0: # %entry
-; precision12-NEXT:    subl $48, %esp
+; precision12-NEXT:    subl $52, %esp
 ; precision12-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; precision12-NEXT:    movl %eax, %ecx
 ; precision12-NEXT:    andl $8388607, %ecx # imm = 0x7FFFFF
@@ -523,17 +534,19 @@ define float @f4(float %x) nounwind noinline {
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fmul %st(1), %st
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision12-NEXT:    flds {{[0-9]+}}(%esp)
-; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
-; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision12-NEXT:    andl $2139095040, %eax # imm = 0x7F800000
 ; precision12-NEXT:    shrl $23, %eax
 ; precision12-NEXT:    addl $-127, %eax
 ; precision12-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
-; precision12-NEXT:    fmulp %st, %st(1)
+; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fildl {{[0-9]+}}(%esp)
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
+; precision12-NEXT:    fmulp %st, %st(1)
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
@@ -544,12 +557,12 @@ define float @f4(float %x) nounwind noinline {
 ; precision12-NEXT:    faddp %st, %st(1)
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
-; precision12-NEXT:    addl $48, %esp
+; precision12-NEXT:    addl $52, %esp
 ; precision12-NEXT:    retl
 ;
 ; precision18-LABEL: f4:
 ; precision18:       # %bb.0: # %entry
-; precision18-NEXT:    subl $64, %esp
+; precision18-NEXT:    subl $68, %esp
 ; precision18-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; precision18-NEXT:    movl %eax, %ecx
 ; precision18-NEXT:    andl $8388607, %ecx # imm = 0x7FFFFF
@@ -583,17 +596,19 @@ define float @f4(float %x) nounwind noinline {
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fmul %st(1), %st
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
-; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    andl $2139095040, %eax # imm = 0x7F800000
 ; precision18-NEXT:    shrl $23, %eax
 ; precision18-NEXT:    addl $-127, %eax
 ; precision18-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    fmulp %st, %st(1)
+; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fildl {{[0-9]+}}(%esp)
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
+; precision18-NEXT:    fmulp %st, %st(1)
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
@@ -604,7 +619,7 @@ define float @f4(float %x) nounwind noinline {
 ; precision18-NEXT:    faddp %st, %st(1)
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    addl $64, %esp
+; precision18-NEXT:    addl $68, %esp
 ; precision18-NEXT:    retl
 entry:
 	%"alloca point" = bitcast i32 0 to i32		; <i32> [#uses=0]
@@ -617,7 +632,7 @@ declare float @llvm.log.f32(float) nounwind readonly
 define float @f5(float %x) nounwind noinline {
 ; precision6-LABEL: f5:
 ; precision6:       # %bb.0: # %entry
-; precision6-NEXT:    subl $28, %esp
+; precision6-NEXT:    subl $32, %esp
 ; precision6-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; precision6-NEXT:    movl %eax, %ecx
 ; precision6-NEXT:    andl $8388607, %ecx # imm = 0x7FFFFF
@@ -641,16 +656,17 @@ define float @f5(float %x) nounwind noinline {
 ; precision6-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fildl {{[0-9]+}}(%esp)
+; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
-; precision6-NEXT:    faddp %st, %st(1)
+; precision6-NEXT:    fadds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
-; precision6-NEXT:    addl $28, %esp
+; precision6-NEXT:    addl $32, %esp
 ; precision6-NEXT:    retl
 ;
 ; precision12-LABEL: f5:
 ; precision12:       # %bb.0: # %entry
-; precision12-NEXT:    subl $44, %esp
+; precision12-NEXT:    subl $48, %esp
 ; precision12-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; precision12-NEXT:    movl %eax, %ecx
 ; precision12-NEXT:    andl $8388607, %ecx # imm = 0x7FFFFF
@@ -686,16 +702,17 @@ define float @f5(float %x) nounwind noinline {
 ; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fildl {{[0-9]+}}(%esp)
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
-; precision12-NEXT:    faddp %st, %st(1)
+; precision12-NEXT:    fadds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
-; precision12-NEXT:    addl $44, %esp
+; precision12-NEXT:    addl $48, %esp
 ; precision12-NEXT:    retl
 ;
 ; precision18-LABEL: f5:
 ; precision18:       # %bb.0: # %entry
-; precision18-NEXT:    subl $60, %esp
+; precision18-NEXT:    subl $64, %esp
 ; precision18-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; precision18-NEXT:    movl %eax, %ecx
 ; precision18-NEXT:    andl $8388607, %ecx # imm = 0x7FFFFF
@@ -743,11 +760,12 @@ define float @f5(float %x) nounwind noinline {
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fildl {{[0-9]+}}(%esp)
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    faddp %st, %st(1)
+; precision18-NEXT:    fadds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    addl $60, %esp
+; precision18-NEXT:    addl $64, %esp
 ; precision18-NEXT:    retl
 entry:
 	%"alloca point" = bitcast i32 0 to i32		; <i32> [#uses=0]
@@ -760,7 +778,7 @@ declare float @llvm.log2.f32(float) nounwind readonly
 define float @f6(float %x) nounwind noinline {
 ; precision6-LABEL: f6:
 ; precision6:       # %bb.0: # %entry
-; precision6-NEXT:    subl $32, %esp
+; precision6-NEXT:    subl $36, %esp
 ; precision6-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; precision6-NEXT:    movl %eax, %ecx
 ; precision6-NEXT:    andl $8388607, %ecx # imm = 0x7FFFFF
@@ -770,17 +788,19 @@ define float @f6(float %x) nounwind noinline {
 ; precision6-NEXT:    fld %st(0)
 ; precision6-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision6-NEXT:    fstps (%esp)
-; precision6-NEXT:    flds (%esp)
-; precision6-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
-; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision6-NEXT:    andl $2139095040, %eax # imm = 0x7F800000
 ; precision6-NEXT:    shrl $23, %eax
 ; precision6-NEXT:    addl $-127, %eax
 ; precision6-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; precision6-NEXT:    flds (%esp)
+; precision6-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision6-NEXT:    fildl {{[0-9]+}}(%esp)
+; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fmulp %st, %st(1)
 ; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision6-NEXT:    fildl {{[0-9]+}}(%esp)
+; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
@@ -791,12 +811,12 @@ define float @f6(float %x) nounwind noinline {
 ; precision6-NEXT:    faddp %st, %st(1)
 ; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
-; precision6-NEXT:    addl $32, %esp
+; precision6-NEXT:    addl $36, %esp
 ; precision6-NEXT:    retl
 ;
 ; precision12-LABEL: f6:
 ; precision12:       # %bb.0: # %entry
-; precision12-NEXT:    subl $40, %esp
+; precision12-NEXT:    subl $44, %esp
 ; precision12-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; precision12-NEXT:    movl %eax, %ecx
 ; precision12-NEXT:    andl $8388607, %ecx # imm = 0x7FFFFF
@@ -812,17 +832,19 @@ define float @f6(float %x) nounwind noinline {
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fmul %st(1), %st
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision12-NEXT:    flds {{[0-9]+}}(%esp)
-; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
-; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision12-NEXT:    andl $2139095040, %eax # imm = 0x7F800000
 ; precision12-NEXT:    shrl $23, %eax
 ; precision12-NEXT:    addl $-127, %eax
 ; precision12-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
-; precision12-NEXT:    fmulp %st, %st(1)
+; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fildl {{[0-9]+}}(%esp)
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
+; precision12-NEXT:    fmulp %st, %st(1)
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
@@ -833,12 +855,12 @@ define float @f6(float %x) nounwind noinline {
 ; precision12-NEXT:    faddp %st, %st(1)
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
-; precision12-NEXT:    addl $40, %esp
+; precision12-NEXT:    addl $44, %esp
 ; precision12-NEXT:    retl
 ;
 ; precision18-LABEL: f6:
 ; precision18:       # %bb.0: # %entry
-; precision18-NEXT:    subl $56, %esp
+; precision18-NEXT:    subl $60, %esp
 ; precision18-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; precision18-NEXT:    movl %eax, %ecx
 ; precision18-NEXT:    andl $8388607, %ecx # imm = 0x7FFFFF
@@ -866,17 +888,19 @@ define float @f6(float %x) nounwind noinline {
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fmul %st(1), %st
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
-; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    andl $2139095040, %eax # imm = 0x7F800000
 ; precision18-NEXT:    shrl $23, %eax
 ; precision18-NEXT:    addl $-127, %eax
 ; precision18-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    fmulp %st, %st(1)
+; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fildl {{[0-9]+}}(%esp)
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
+; precision18-NEXT:    fmulp %st, %st(1)
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
@@ -887,7 +911,7 @@ define float @f6(float %x) nounwind noinline {
 ; precision18-NEXT:    faddp %st, %st(1)
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    addl $56, %esp
+; precision18-NEXT:    addl $60, %esp
 ; precision18-NEXT:    retl
 entry:
 	%"alloca point" = bitcast i32 0 to i32		; <i32> [#uses=0]
diff --git a/llvm/test/CodeGen/X86/nosse-vector.ll b/llvm/test/CodeGen/X86/nosse-vector.ll
index edf96ba76dc78..746c91af19a39 100644
--- a/llvm/test/CodeGen/X86/nosse-vector.ll
+++ b/llvm/test/CodeGen/X86/nosse-vector.ll
@@ -125,7 +125,7 @@ define void @sitofp_4i64_4f32_mem(ptr %p0, ptr %p1) nounwind {
 ; X32-NEXT:    pushl %edi
 ; X32-NEXT:    pushl %esi
 ; X32-NEXT:    andl $-8, %esp
-; X32-NEXT:    subl $48, %esp
+; X32-NEXT:    subl $64, %esp
 ; X32-NEXT:    movl 8(%ebp), %edx
 ; X32-NEXT:    movl 24(%edx), %eax
 ; X32-NEXT:    movl %eax, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill
@@ -149,9 +149,17 @@ define void @sitofp_4i64_4f32_mem(ptr %p0, ptr %p1) nounwind {
 ; X32-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; X32-NEXT:    movl 12(%ebp), %eax
 ; X32-NEXT:    fildll {{[0-9]+}}(%esp)
+; X32-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X32-NEXT:    fildll {{[0-9]+}}(%esp)
+; X32-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X32-NEXT:    fildll {{[0-9]+}}(%esp)
+; X32-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X32-NEXT:    fildll {{[0-9]+}}(%esp)
+; X32-NEXT:    fstps {{[0-9]+}}(%esp)
+; X32-NEXT:    flds {{[0-9]+}}(%esp)
+; X32-NEXT:    flds {{[0-9]+}}(%esp)
+; X32-NEXT:    flds {{[0-9]+}}(%esp)
+; X32-NEXT:    flds {{[0-9]+}}(%esp)
 ; X32-NEXT:    fstps 12(%eax)
 ; X32-NEXT:    fstps 8(%eax)
 ; X32-NEXT:    fstps 4(%eax)
@@ -174,9 +182,17 @@ define void @sitofp_4i64_4f32_mem(ptr %p0, ptr %p1) nounwind {
 ; X64-NEXT:    movq %rcx, -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    movq %rax, -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    fildll -{{[0-9]+}}(%rsp)
+; X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    fildll -{{[0-9]+}}(%rsp)
+; X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    fildll -{{[0-9]+}}(%rsp)
+; X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    fildll -{{[0-9]+}}(%rsp)
+; X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
+; X64-NEXT:    flds -{{[0-9]+}}(%rsp)
+; X64-NEXT:    flds -{{[0-9]+}}(%rsp)
+; X64-NEXT:    flds -{{[0-9]+}}(%rsp)
+; X64-NEXT:    flds -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    fstps 12(%rsi)
 ; X64-NEXT:    fstps 8(%rsi)
 ; X64-NEXT:    fstps 4(%rsi)
@@ -193,26 +209,34 @@ define void @sitofp_4i32_4f32_mem(ptr %p0, ptr %p1) nounwind {
 ; X32:       # %bb.0:
 ; X32-NEXT:    pushl %edi
 ; X32-NEXT:    pushl %esi
-; X32-NEXT:    subl $16, %esp
+; X32-NEXT:    subl $32, %esp
 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; X32-NEXT:    movl 12(%ecx), %edx
 ; X32-NEXT:    movl 8(%ecx), %esi
 ; X32-NEXT:    movl (%ecx), %edi
 ; X32-NEXT:    movl 4(%ecx), %ecx
-; X32-NEXT:    movl %edi, (%esp)
+; X32-NEXT:    movl %edi, {{[0-9]+}}(%esp)
 ; X32-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
 ; X32-NEXT:    movl %esi, {{[0-9]+}}(%esp)
 ; X32-NEXT:    movl %edx, {{[0-9]+}}(%esp)
-; X32-NEXT:    fildl (%esp)
 ; X32-NEXT:    fildl {{[0-9]+}}(%esp)
+; X32-NEXT:    fstps (%esp)
+; X32-NEXT:    fildl {{[0-9]+}}(%esp)
+; X32-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X32-NEXT:    fildl {{[0-9]+}}(%esp)
+; X32-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X32-NEXT:    fildl {{[0-9]+}}(%esp)
+; X32-NEXT:    fstps {{[0-9]+}}(%esp)
+; X32-NEXT:    flds (%esp)
+; X32-NEXT:    flds {{[0-9]+}}(%esp)
+; X32-NEXT:    flds {{[0-9]+}}(%esp)
+; X32-NEXT:    flds {{[0-9]+}}(%esp)
 ; X32-NEXT:    fstps 12(%eax)
 ; X32-NEXT:    fstps 8(%eax)
 ; X32-NEXT:    fstps 4(%eax)
 ; X32-NEXT:    fstps (%eax)
-; X32-NEXT:    addl $16, %esp
+; X32-NEXT:    addl $32, %esp
 ; X32-NEXT:    popl %esi
 ; X32-NEXT:    popl %edi
 ; X32-NEXT:    retl
@@ -228,9 +252,17 @@ define void @sitofp_4i32_4f32_mem(ptr %p0, ptr %p1) nounwind {
 ; X64-NEXT:    movl %ecx, -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    movl %eax, -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    fildl -{{[0-9]+}}(%rsp)
+; X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    fildl -{{[0-9]+}}(%rsp)
+; X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    fildl -{{[0-9]+}}(%rsp)
+; X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    fildl -{{[0-9]+}}(%rsp)
+; X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
+; X64-NEXT:    flds -{{[0-9]+}}(%rsp)
+; X64-NEXT:    flds -{{[0-9]+}}(%rsp)
+; X64-NEXT:    flds -{{[0-9]+}}(%rsp)
+; X64-NEXT:    flds -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    fstps 12(%rsi)
 ; X64-NEXT:    fstps 8(%rsi)
 ; X64-NEXT:    fstps 4(%rsi)
diff --git a/llvm/test/CodeGen/X86/pr178410.ll b/llvm/test/CodeGen/X86/pr178410.ll
index 09be5428001e6..fa8a066d5211d 100644
--- a/llvm/test/CodeGen/X86/pr178410.ll
+++ b/llvm/test/CodeGen/X86/pr178410.ll
@@ -11,13 +11,15 @@ define float @PR178410(ptr %p0) nounwind {
 ; X86-NEXT:    pushl %ebp
 ; X86-NEXT:    movl %esp, %ebp
 ; X86-NEXT:    andl $-8, %esp
-; X86-NEXT:    subl $8, %esp
+; X86-NEXT:    subl $16, %esp
 ; X86-NEXT:    movl 8(%ebp), %eax
 ; X86-NEXT:    movl (%eax), %ecx
 ; X86-NEXT:    movl 4(%eax), %eax
 ; X86-NEXT:    movl %eax, {{[0-9]+}}(%esp)
-; X86-NEXT:    movl %ecx, (%esp)
-; X86-NEXT:    fildll (%esp)
+; X86-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
+; X86-NEXT:    fildll {{[0-9]+}}(%esp)
+; X86-NEXT:    fstps {{[0-9]+}}(%esp)
+; X86-NEXT:    flds {{[0-9]+}}(%esp)
 ; X86-NEXT:    movl %ebp, %esp
 ; X86-NEXT:    popl %ebp
 ; X86-NEXT:    retl
diff --git a/llvm/test/CodeGen/X86/pr34080-2.ll b/llvm/test/CodeGen/X86/pr34080-2.ll
index 79798c898fbdd..712b63f7e3254 100644
--- a/llvm/test/CodeGen/X86/pr34080-2.ll
+++ b/llvm/test/CodeGen/X86/pr34080-2.ll
@@ -12,7 +12,7 @@ define void @computeJD(ptr) nounwind {
 ; CHECK-NEXT:    pushl %edi
 ; CHECK-NEXT:    pushl %esi
 ; CHECK-NEXT:    andl $-8, %esp
-; CHECK-NEXT:    subl $64, %esp
+; CHECK-NEXT:    subl $72, %esp
 ; CHECK-NEXT:    movl 8(%ebp), %ebx
 ; CHECK-NEXT:    movl 8(%ebx), %esi
 ; CHECK-NEXT:    xorl %eax, %eax
@@ -48,6 +48,8 @@ define void @computeJD(ptr) nounwind {
 ; CHECK-NEXT:    leal 257(%ecx,%edx), %eax
 ; CHECK-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    fildl {{[0-9]+}}(%esp)
+; CHECK-NEXT:    fstpl {{[0-9]+}}(%esp)
+; CHECK-NEXT:    fldl {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; CHECK-NEXT:    fstpl {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    fldl {{[0-9]+}}(%esp)
diff --git a/llvm/test/CodeGen/X86/pr35982.ll b/llvm/test/CodeGen/X86/pr35982.ll
index 39f266f09bbc9..6d8cb8bcf3e16 100644
--- a/llvm/test/CodeGen/X86/pr35982.ll
+++ b/llvm/test/CodeGen/X86/pr35982.ll
@@ -5,7 +5,7 @@
 define float @PR35982_emms(<1 x i64>) nounwind {
 ; NO-POSTRA-LABEL: PR35982_emms:
 ; NO-POSTRA:       # %bb.0:
-; NO-POSTRA-NEXT:    subl $12, %esp
+; NO-POSTRA-NEXT:    subl $20, %esp
 ; NO-POSTRA-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; NO-POSTRA-NEXT:    movq {{[0-9]+}}(%esp), %mm0
 ; NO-POSTRA-NEXT:    punpckhdq %mm0, %mm0 # mm0 = mm0[1,1]
@@ -13,17 +13,20 @@ define float @PR35982_emms(<1 x i64>) nounwind {
 ; NO-POSTRA-NEXT:    emms
 ; NO-POSTRA-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; NO-POSTRA-NEXT:    fildl {{[0-9]+}}(%esp)
+; NO-POSTRA-NEXT:    fstps {{[0-9]+}}(%esp)
 ; NO-POSTRA-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
 ; NO-POSTRA-NEXT:    fildl {{[0-9]+}}(%esp)
-; NO-POSTRA-NEXT:    faddp %st, %st(1)
+; NO-POSTRA-NEXT:    fstps {{[0-9]+}}(%esp)
+; NO-POSTRA-NEXT:    flds {{[0-9]+}}(%esp)
+; NO-POSTRA-NEXT:    fadds {{[0-9]+}}(%esp)
 ; NO-POSTRA-NEXT:    fstps (%esp)
 ; NO-POSTRA-NEXT:    flds (%esp)
-; NO-POSTRA-NEXT:    addl $12, %esp
+; NO-POSTRA-NEXT:    addl $20, %esp
 ; NO-POSTRA-NEXT:    retl
 ;
 ; POSTRA-LABEL: PR35982_emms:
 ; POSTRA:       # %bb.0:
-; POSTRA-NEXT:    subl $12, %esp
+; POSTRA-NEXT:    subl $20, %esp
 ; POSTRA-NEXT:    movq {{[0-9]+}}(%esp), %mm0
 ; POSTRA-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; POSTRA-NEXT:    punpckhdq %mm0, %mm0 # mm0 = mm0[1,1]
@@ -31,12 +34,15 @@ define float @PR35982_emms(<1 x i64>) nounwind {
 ; POSTRA-NEXT:    emms
 ; POSTRA-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; POSTRA-NEXT:    fildl {{[0-9]+}}(%esp)
+; POSTRA-NEXT:    fstps {{[0-9]+}}(%esp)
 ; POSTRA-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
 ; POSTRA-NEXT:    fildl {{[0-9]+}}(%esp)
-; POSTRA-NEXT:    faddp %st, %st(1)
+; POSTRA-NEXT:    fstps {{[0-9]+}}(%esp)
+; POSTRA-NEXT:    flds {{[0-9]+}}(%esp)
+; POSTRA-NEXT:    fadds {{[0-9]+}}(%esp)
 ; POSTRA-NEXT:    fstps (%esp)
 ; POSTRA-NEXT:    flds (%esp)
-; POSTRA-NEXT:    addl $12, %esp
+; POSTRA-NEXT:    addl $20, %esp
 ; POSTRA-NEXT:    retl
   %2 = bitcast <1 x i64> %0 to <2 x i32>
   %3 = extractelement <2 x i32> %2, i32 0
diff --git a/llvm/test/CodeGen/X86/pr50782.ll b/llvm/test/CodeGen/X86/pr50782.ll
index 7bb7db376d279..7e6c971e32b2a 100644
--- a/llvm/test/CodeGen/X86/pr50782.ll
+++ b/llvm/test/CodeGen/X86/pr50782.ll
@@ -52,6 +52,8 @@ define void @h(float %i) {
 ; CHECK-NEXT:    movl _e, %ecx
 ; CHECK-NEXT:    movl %ecx, 28(%esi)
 ; CHECK-NEXT:    fildl 28(%esi)
+; CHECK-NEXT:    fstps 24(%esi)
+; CHECK-NEXT:    flds 24(%esi)
 ; CHECK-NEXT:    movl _c, %edx
 ; CHECK-NEXT:    fldz
 ; CHECK-NEXT:    fld1
@@ -61,21 +63,21 @@ define void @h(float %i) {
 ; CHECK-NEXT:    # in Loop: Header=BB0_3 Depth=1
 ; CHECK-NEXT:    fadd %st, %st(5)
 ; CHECK-NEXT:    fxch %st(5)
-; CHECK-NEXT:    fstps 12(%esi)
-; CHECK-NEXT:    flds 12(%esi)
+; CHECK-NEXT:    fstps 8(%esi)
+; CHECK-NEXT:    flds 8(%esi)
 ; CHECK-NEXT:    fxch %st(5)
 ; CHECK-NEXT:  LBB0_3: # %for.cond1
 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
 ; CHECK-NEXT:    fld %st(5)
 ; CHECK-NEXT:    fmul %st(2), %st
+; CHECK-NEXT:    fstps 12(%esi)
+; CHECK-NEXT:    flds 12(%esi)
+; CHECK-NEXT:    fdiv %st(5), %st
 ; CHECK-NEXT:    fstps 16(%esi)
 ; CHECK-NEXT:    flds 16(%esi)
-; CHECK-NEXT:    fdiv %st(5), %st
+; CHECK-NEXT:    fadd %st(4), %st
 ; CHECK-NEXT:    fstps 20(%esi)
 ; CHECK-NEXT:    flds 20(%esi)
-; CHECK-NEXT:    fadd %st(4), %st
-; CHECK-NEXT:    fstps 24(%esi)
-; CHECK-NEXT:    flds 24(%esi)
 ; CHECK-NEXT:    fsts _g
 ; CHECK-NEXT:    fxch %st(3)
 ; CHECK-NEXT:    fucom %st(3)
diff --git a/llvm/test/CodeGen/X86/scalar-int-to-fp.ll b/llvm/test/CodeGen/X86/scalar-int-to-fp.ll
index 3dd67ae0fb9c8..7c76dfdcdde8f 100644
--- a/llvm/test/CodeGen/X86/scalar-int-to-fp.ll
+++ b/llvm/test/CodeGen/X86/scalar-int-to-fp.ll
@@ -68,11 +68,13 @@ define float @u32_to_f(i32 %a) nounwind {
 ; X87-NEXT:    pushl %ebp
 ; X87-NEXT:    movl %esp, %ebp
 ; X87-NEXT:    andl $-8, %esp
-; X87-NEXT:    subl $8, %esp
+; X87-NEXT:    subl $16, %esp
 ; X87-NEXT:    movl 8(%ebp), %eax
-; X87-NEXT:    movl %eax, (%esp)
+; X87-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; X87-NEXT:    movl $0, {{[0-9]+}}(%esp)
-; X87-NEXT:    fildll (%esp)
+; X87-NEXT:    fildll {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps {{[0-9]+}}(%esp)
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    movl %ebp, %esp
 ; X87-NEXT:    popl %ebp
 ; X87-NEXT:    retl
@@ -111,11 +113,13 @@ define float @s32_to_f(i32 %a) nounwind {
 ;
 ; X87-LABEL: s32_to_f:
 ; X87:       # %bb.0:
-; X87-NEXT:    pushl %eax
+; X87-NEXT:    subl $8, %esp
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X87-NEXT:    movl %eax, (%esp)
-; X87-NEXT:    fildl (%esp)
-; X87-NEXT:    popl %eax
+; X87-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; X87-NEXT:    fildl {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps (%esp)
+; X87-NEXT:    flds (%esp)
+; X87-NEXT:    addl $8, %esp
 ; X87-NEXT:    retl
   %r = sitofp i32 %a to float
   ret float %r
@@ -166,11 +170,13 @@ define double @u32_to_d(i32 %a) nounwind {
 ; SSE1_32-NEXT:    pushl %ebp
 ; SSE1_32-NEXT:    movl %esp, %ebp
 ; SSE1_32-NEXT:    andl $-8, %esp
-; SSE1_32-NEXT:    subl $8, %esp
+; SSE1_32-NEXT:    subl $16, %esp
 ; SSE1_32-NEXT:    movl 8(%ebp), %eax
 ; SSE1_32-NEXT:    movl %eax, (%esp)
 ; SSE1_32-NEXT:    movl $0, {{[0-9]+}}(%esp)
 ; SSE1_32-NEXT:    fildll (%esp)
+; SSE1_32-NEXT:    fstpl {{[0-9]+}}(%esp)
+; SSE1_32-NEXT:    fldl {{[0-9]+}}(%esp)
 ; SSE1_32-NEXT:    movl %ebp, %esp
 ; SSE1_32-NEXT:    popl %ebp
 ; SSE1_32-NEXT:    retl
@@ -180,11 +186,13 @@ define double @u32_to_d(i32 %a) nounwind {
 ; X87-NEXT:    pushl %ebp
 ; X87-NEXT:    movl %esp, %ebp
 ; X87-NEXT:    andl $-8, %esp
-; X87-NEXT:    subl $8, %esp
+; X87-NEXT:    subl $16, %esp
 ; X87-NEXT:    movl 8(%ebp), %eax
 ; X87-NEXT:    movl %eax, (%esp)
 ; X87-NEXT:    movl $0, {{[0-9]+}}(%esp)
 ; X87-NEXT:    fildll (%esp)
+; X87-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    movl %ebp, %esp
 ; X87-NEXT:    popl %ebp
 ; X87-NEXT:    retl
@@ -231,20 +239,24 @@ define double @s32_to_d(i32 %a) nounwind {
 ;
 ; SSE1_32-LABEL: s32_to_d:
 ; SSE1_32:       # %bb.0:
-; SSE1_32-NEXT:    pushl %eax
+; SSE1_32-NEXT:    subl $12, %esp
 ; SSE1_32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; SSE1_32-NEXT:    movl %eax, (%esp)
 ; SSE1_32-NEXT:    fildl (%esp)
-; SSE1_32-NEXT:    popl %eax
+; SSE1_32-NEXT:    fstpl {{[0-9]+}}(%esp)
+; SSE1_32-NEXT:    fldl {{[0-9]+}}(%esp)
+; SSE1_32-NEXT:    addl $12, %esp
 ; SSE1_32-NEXT:    retl
 ;
 ; X87-LABEL: s32_to_d:
 ; X87:       # %bb.0:
-; X87-NEXT:    pushl %eax
+; X87-NEXT:    subl $12, %esp
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X87-NEXT:    movl %eax, (%esp)
 ; X87-NEXT:    fildl (%esp)
-; X87-NEXT:    popl %eax
+; X87-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
+; X87-NEXT:    addl $12, %esp
 ; X87-NEXT:    retl
   %r = sitofp i32 %a to double
   ret double %r
@@ -476,7 +488,11 @@ define float @s64_to_f(i64 %a) nounwind {
 ;
 ; X87-LABEL: s64_to_f:
 ; X87:       # %bb.0:
+; X87-NEXT:    pushl %eax
 ; X87-NEXT:    fildll {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps (%esp)
+; X87-NEXT:    flds (%esp)
+; X87-NEXT:    popl %eax
 ; X87-NEXT:    retl
   %r = sitofp i64 %a to float
   ret float %r
@@ -592,14 +608,16 @@ define float @s64_to_f_2(i64 %a) nounwind {
 ; X87-NEXT:    pushl %ebp
 ; X87-NEXT:    movl %esp, %ebp
 ; X87-NEXT:    andl $-8, %esp
-; X87-NEXT:    subl $8, %esp
+; X87-NEXT:    subl $16, %esp
 ; X87-NEXT:    movl 8(%ebp), %eax
 ; X87-NEXT:    movl 12(%ebp), %ecx
 ; X87-NEXT:    addl $5, %eax
 ; X87-NEXT:    adcl $0, %ecx
-; X87-NEXT:    movl %eax, (%esp)
+; X87-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; X87-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
-; X87-NEXT:    fildll (%esp)
+; X87-NEXT:    fildll {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps {{[0-9]+}}(%esp)
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    movl %ebp, %esp
 ; X87-NEXT:    popl %ebp
 ; X87-NEXT:    retl
@@ -896,28 +914,27 @@ define double @s64_to_d(i64 %a) nounwind {
 ; AVX512F_32-NEXT:    addl $8, %esp
 ; AVX512F_32-NEXT:    retl
 ;
-; SSE2_32-LABEL: s64_to_d:
-; SSE2_32:       # %bb.0:
-; SSE2_32-NEXT:    subl $8, %esp
-; SSE2_32-NEXT:    fildll {{[0-9]+}}(%esp)
-; SSE2_32-NEXT:    fstpl (%esp)
-; SSE2_32-NEXT:    fldl (%esp)
-; SSE2_32-NEXT:    addl $8, %esp
-; SSE2_32-NEXT:    retl
+; SSE_32-LABEL: s64_to_d:
+; SSE_32:       # %bb.0:
+; SSE_32-NEXT:    subl $8, %esp
+; SSE_32-NEXT:    fildll {{[0-9]+}}(%esp)
+; SSE_32-NEXT:    fstpl (%esp)
+; SSE_32-NEXT:    fldl (%esp)
+; SSE_32-NEXT:    addl $8, %esp
+; SSE_32-NEXT:    retl
 ;
 ; SSE2_64-LABEL: s64_to_d:
 ; SSE2_64:       # %bb.0:
 ; SSE2_64-NEXT:    cvtsi2sd %rdi, %xmm0
 ; SSE2_64-NEXT:    retq
 ;
-; SSE1_32-LABEL: s64_to_d:
-; SSE1_32:       # %bb.0:
-; SSE1_32-NEXT:    fildll {{[0-9]+}}(%esp)
-; SSE1_32-NEXT:    retl
-;
 ; X87-LABEL: s64_to_d:
 ; X87:       # %bb.0:
+; X87-NEXT:    subl $8, %esp
 ; X87-NEXT:    fildll {{[0-9]+}}(%esp)
+; X87-NEXT:    fstpl (%esp)
+; X87-NEXT:    fldl (%esp)
+; X87-NEXT:    addl $8, %esp
 ; X87-NEXT:    retl
   %r = sitofp i64 %a to double
   ret double %r
@@ -1022,7 +1039,7 @@ define double @s64_to_d_2(i64 %a) nounwind {
 ; SSE1_32-NEXT:    pushl %ebp
 ; SSE1_32-NEXT:    movl %esp, %ebp
 ; SSE1_32-NEXT:    andl $-8, %esp
-; SSE1_32-NEXT:    subl $8, %esp
+; SSE1_32-NEXT:    subl $16, %esp
 ; SSE1_32-NEXT:    movl 8(%ebp), %eax
 ; SSE1_32-NEXT:    movl 12(%ebp), %ecx
 ; SSE1_32-NEXT:    addl $5, %eax
@@ -1030,6 +1047,8 @@ define double @s64_to_d_2(i64 %a) nounwind {
 ; SSE1_32-NEXT:    movl %eax, (%esp)
 ; SSE1_32-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
 ; SSE1_32-NEXT:    fildll (%esp)
+; SSE1_32-NEXT:    fstpl {{[0-9]+}}(%esp)
+; SSE1_32-NEXT:    fldl {{[0-9]+}}(%esp)
 ; SSE1_32-NEXT:    movl %ebp, %esp
 ; SSE1_32-NEXT:    popl %ebp
 ; SSE1_32-NEXT:    retl
@@ -1039,7 +1058,7 @@ define double @s64_to_d_2(i64 %a) nounwind {
 ; X87-NEXT:    pushl %ebp
 ; X87-NEXT:    movl %esp, %ebp
 ; X87-NEXT:    andl $-8, %esp
-; X87-NEXT:    subl $8, %esp
+; X87-NEXT:    subl $16, %esp
 ; X87-NEXT:    movl 8(%ebp), %eax
 ; X87-NEXT:    movl 12(%ebp), %ecx
 ; X87-NEXT:    addl $5, %eax
@@ -1047,6 +1066,8 @@ define double @s64_to_d_2(i64 %a) nounwind {
 ; X87-NEXT:    movl %eax, (%esp)
 ; X87-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
 ; X87-NEXT:    fildll (%esp)
+; X87-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    movl %ebp, %esp
 ; X87-NEXT:    popl %ebp
 ; X87-NEXT:    retl
diff --git a/llvm/test/CodeGen/X86/x87-round-to-type.ll b/llvm/test/CodeGen/X86/x87-round-to-type.ll
index 997b2734289f3..468cc362b2444 100644
--- a/llvm/test/CodeGen/X86/x87-round-to-type.ll
+++ b/llvm/test/CodeGen/X86/x87-round-to-type.ll
@@ -314,11 +314,13 @@ define void @store_narrower_f32(double %a, double %b, ptr %p) nounwind {
 define float @sitofp_i32_f32(i32 %x) nounwind {
 ; X87-LABEL: sitofp_i32_f32:
 ; X87:       # %bb.0:
-; X87-NEXT:    pushl %eax
+; X87-NEXT:    subl $8, %esp
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X87-NEXT:    movl %eax, (%esp)
-; X87-NEXT:    fildl (%esp)
-; X87-NEXT:    popl %eax
+; X87-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; X87-NEXT:    fildl {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps (%esp)
+; X87-NEXT:    flds (%esp)
+; X87-NEXT:    addl $8, %esp
 ; X87-NEXT:    retl
   %r = sitofp i32 %x to float
   ret float %r
@@ -327,11 +329,13 @@ define float @sitofp_i32_f32(i32 %x) nounwind {
 define double @sitofp_i32_f64(i32 %x) nounwind {
 ; X87-LABEL: sitofp_i32_f64:
 ; X87:       # %bb.0:
-; X87-NEXT:    pushl %eax
+; X87-NEXT:    subl $12, %esp
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X87-NEXT:    movl %eax, (%esp)
 ; X87-NEXT:    fildl (%esp)
-; X87-NEXT:    popl %eax
+; X87-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
+; X87-NEXT:    addl $12, %esp
 ; X87-NEXT:    retl
   %r = sitofp i32 %x to double
   ret double %r
@@ -340,7 +344,11 @@ define double @sitofp_i32_f64(i32 %x) nounwind {
 define float @sitofp_i64_f32(i64 %x) nounwind {
 ; X87-LABEL: sitofp_i64_f32:
 ; X87:       # %bb.0:
+; X87-NEXT:    pushl %eax
 ; X87-NEXT:    fildll {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps (%esp)
+; X87-NEXT:    flds (%esp)
+; X87-NEXT:    popl %eax
 ; X87-NEXT:    retl
   %r = sitofp i64 %x to float
   ret float %r
@@ -351,13 +359,15 @@ define float @sitofp_i64_f32(i64 %x) nounwind {
 define void @sitofp_store_only_f32(i32 %x, ptr %p) nounwind {
 ; X87-LABEL: sitofp_store_only_f32:
 ; X87:       # %bb.0:
-; X87-NEXT:    pushl %eax
+; X87-NEXT:    subl $8, %esp
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; X87-NEXT:    movl %ecx, (%esp)
-; X87-NEXT:    fildl (%esp)
+; X87-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
+; X87-NEXT:    fildl {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps (%esp)
+; X87-NEXT:    flds (%esp)
 ; X87-NEXT:    fstps (%eax)
-; X87-NEXT:    popl %eax
+; X87-NEXT:    addl $8, %esp
 ; X87-NEXT:    retl
   %r = sitofp i32 %x to float
   store float %r, ptr %p
@@ -367,15 +377,17 @@ define void @sitofp_store_only_f32(i32 %x, ptr %p) nounwind {
 define void @sitofp_store_twice_f32(i32 %x, ptr %p, ptr %q) nounwind {
 ; X87-LABEL: sitofp_store_twice_f32:
 ; X87:       # %bb.0:
-; X87-NEXT:    pushl %eax
+; X87-NEXT:    subl $8, %esp
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %edx
-; X87-NEXT:    movl %edx, (%esp)
-; X87-NEXT:    fildl (%esp)
+; X87-NEXT:    movl %edx, {{[0-9]+}}(%esp)
+; X87-NEXT:    fildl {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps (%esp)
+; X87-NEXT:    flds (%esp)
 ; X87-NEXT:    fsts (%ecx)
 ; X87-NEXT:    fstps (%eax)
-; X87-NEXT:    popl %eax
+; X87-NEXT:    addl $8, %esp
 ; X87-NEXT:    retl
   %r = sitofp i32 %x to float
   store float %r, ptr %p
@@ -388,13 +400,15 @@ define void @sitofp_store_twice_f32(i32 %x, ptr %p, ptr %q) nounwind {
 define float @sitofp_store_and_use_f32(i32 %x, ptr %p) nounwind {
 ; X87-LABEL: sitofp_store_and_use_f32:
 ; X87:       # %bb.0:
-; X87-NEXT:    pushl %eax
+; X87-NEXT:    subl $8, %esp
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; X87-NEXT:    movl %ecx, (%esp)
-; X87-NEXT:    fildl (%esp)
+; X87-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
+; X87-NEXT:    fildl {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps (%esp)
+; X87-NEXT:    flds (%esp)
 ; X87-NEXT:    fsts (%eax)
-; X87-NEXT:    popl %eax
+; X87-NEXT:    addl $8, %esp
 ; X87-NEXT:    retl
   %r = sitofp i32 %x to float
   store float %r, ptr %p
@@ -406,14 +420,16 @@ define float @sitofp_store_and_use_f32(i32 %x, ptr %p) nounwind {
 define void @strict_sitofp_store_f32(i32 %x, ptr %p) nounwind strictfp {
 ; X87-LABEL: strict_sitofp_store_f32:
 ; X87:       # %bb.0:
-; X87-NEXT:    pushl %eax
+; X87-NEXT:    subl $8, %esp
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; X87-NEXT:    movl %ecx, (%esp)
-; X87-NEXT:    fildl (%esp)
+; X87-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
+; X87-NEXT:    fildl {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps (%esp)
+; X87-NEXT:    flds (%esp)
 ; X87-NEXT:    fstps (%eax)
 ; X87-NEXT:    wait
-; X87-NEXT:    popl %eax
+; X87-NEXT:    addl $8, %esp
 ; X87-NEXT:    retl
   %r = call float @llvm.experimental.constrained.sitofp.f32.i32(i32 %x,
                                                           metadata !"round.dynamic",
@@ -427,12 +443,14 @@ define void @strict_sitofp_store_f32(i32 %x, ptr %p) nounwind strictfp {
 define float @uitofp_i32_f32(i32 %x) nounwind {
 ; X87-LABEL: uitofp_i32_f32:
 ; X87:       # %bb.0:
-; X87-NEXT:    subl $12, %esp
+; X87-NEXT:    subl $20, %esp
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X87-NEXT:    movl %eax, (%esp)
+; X87-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; X87-NEXT:    movl $0, {{[0-9]+}}(%esp)
-; X87-NEXT:    fildll (%esp)
-; X87-NEXT:    addl $12, %esp
+; X87-NEXT:    fildll {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps {{[0-9]+}}(%esp)
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
+; X87-NEXT:    addl $20, %esp
 ; X87-NEXT:    retl
   %r = uitofp i32 %x to float
   ret float %r

>From 0790bc82acd1d6ab386cda36751bd7dc3115d35c Mon Sep 17 00:00:00 2001
From: Dennis Duda <git at seri.tools>
Date: Sun, 9 Aug 2026 00:15:21 +0200
Subject: [PATCH 04/15] [X86] Extract `RoundX87ToType` from
 `X86TargetLowering::BuildFILD`

This will later be used during lowering for FP_ROUND and STRICT_FP_ROUND.

Co-authored-by: Claude (Claude-Opus-5) <noreply at anthropic.com>
---
 llvm/lib/Target/X86/X86ISelLowering.cpp | 50 +++++++++++++------------
 llvm/lib/Target/X86/X86ISelLowering.h   |  6 +++
 2 files changed, 33 insertions(+), 23 deletions(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index b365b3ce9a508..863698a582ff3 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -20704,6 +20704,31 @@ SDValue X86TargetLowering::LowerSINT_TO_FP(SDValue Op,
   return Tmp.first;
 }
 
+std::pair<SDValue, SDValue>
+X86TargetLowering::RoundX87ToType(EVT VT, const SDLoc &DL, SDValue Chain,
+                                  SDValue Src, SelectionDAG &DAG) const {
+  MachineFunction &MF = DAG.getMachineFunction();
+  unsigned SSFISize = VT.getStoreSize();
+  // The slot is private, so ABI alignment is enough. More might realign the
+  // frame.
+  Align SlotAlign = DAG.getEVTAlign(VT);
+  int SSFI = MF.getFrameInfo().CreateStackObject(SSFISize, SlotAlign, false);
+  auto PtrVT = getPointerTy(MF.getDataLayout());
+  SDValue StackSlot = DAG.getFrameIndex(SSFI, PtrVT);
+  MachinePointerInfo PtrInfo = MachinePointerInfo::getFixedStack(MF, SSFI);
+
+  SDVTList Tys = DAG.getVTList(MVT::Other);
+  SDValue FSTOps[] = {Chain, Src, StackSlot};
+  MachineMemOperand *StoreMMO = MF.getMachineMemOperand(
+      PtrInfo, MachineMemOperand::MOStore, SSFISize, SlotAlign);
+
+  Chain = DAG.getMemIntrinsicNode(X86ISD::FST, DL, Tys, FSTOps, VT, StoreMMO);
+  SDValue Result = DAG.getLoad(VT, DL, Chain, StackSlot, PtrInfo, SlotAlign);
+  Chain = Result.getValue(1);
+
+  return {Result, Chain};
+}
+
 std::pair<SDValue, SDValue> X86TargetLowering::BuildFILD(
     EVT DstVT, EVT SrcVT, const SDLoc &DL, SDValue Chain, SDValue Pointer,
     MachinePointerInfo PtrInfo, Align Alignment, SelectionDAG &DAG) const {
@@ -20722,29 +20747,8 @@ std::pair<SDValue, SDValue> X86TargetLowering::BuildFILD(
                               Alignment, MachineMemOperand::MOLoad);
   Chain = Result.getValue(1);
 
-  if (useSSE || needsX87Round) {
-    MachineFunction &MF = DAG.getMachineFunction();
-    unsigned SSFISize = DstVT.getStoreSize();
-    // The slot is private, so ABI alignment is enough. More might realign the
-    // frame.
-    Align SlotAlign = DAG.getEVTAlign(DstVT);
-    int SSFI = MF.getFrameInfo().CreateStackObject(SSFISize, SlotAlign, false);
-    auto PtrVT = getPointerTy(MF.getDataLayout());
-    SDValue StackSlot = DAG.getFrameIndex(SSFI, PtrVT);
-    Tys = DAG.getVTList(MVT::Other);
-    SDValue FSTOps[] = {Chain, Result, StackSlot};
-    MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
-        MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), SSFI),
-        MachineMemOperand::MOStore, SSFISize, SlotAlign);
-
-    Chain =
-        DAG.getMemIntrinsicNode(X86ISD::FST, DL, Tys, FSTOps, DstVT, StoreMMO);
-    Result = DAG.getLoad(
-        DstVT, DL, Chain, StackSlot,
-        MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), SSFI),
-        SlotAlign);
-    Chain = Result.getValue(1);
-  }
+  if (useSSE || needsX87Round)
+    std::tie(Result, Chain) = RoundX87ToType(DstVT, DL, Chain, Result, DAG);
 
   return { Result, Chain };
 }
diff --git a/llvm/lib/Target/X86/X86ISelLowering.h b/llvm/lib/Target/X86/X86ISelLowering.h
index dd94ce26d2765..b52ba6ddf3e69 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.h
+++ b/llvm/lib/Target/X86/X86ISelLowering.h
@@ -670,6 +670,12 @@ namespace llvm {
     Value *getSafeStackPointerLocation(
         IRBuilderBase &IRB, const LibcallLoweringInfo &Libcalls) const override;
 
+    /// Rounds the x87 value \p Src to \p VT by storing it to a stack slot of
+    /// that width and reloading it.
+    std::pair<SDValue, SDValue> RoundX87ToType(EVT VT, const SDLoc &DL,
+                                               SDValue Chain, SDValue Src,
+                                               SelectionDAG &DAG) const;
+
     std::pair<SDValue, SDValue> BuildFILD(EVT DstVT, EVT SrcVT, const SDLoc &DL,
                                           SDValue Chain, SDValue Pointer,
                                           MachinePointerInfo PtrInfo,

>From 27d542bb4b8b9afe88abce789887db78d235782d Mon Sep 17 00:00:00 2001
From: Dennis Duda <git at seri.tools>
Date: Sun, 9 Aug 2026 00:23:19 +0200
Subject: [PATCH 05/15] [X86] Lower `FP_ROUND` and `STRICT_FP_ROUND`

Instead of via `PreprocessISelDAG`, manually lower them:

1. `PreprocessISelDAG` uses preferred alignment, causing dynamic stack alignment for f64 on a target with 4-byte-aligned stack. Manually lowering them allows us to reuse `RoundX87ToType` with its minimal stack alignment.

2. it runs after every DAG combine and the output is final, preventing us to do better than the `truncstore X -> slot ; extload slot ; store` in generates

3. we can't make it optional to support excess-precision

This causes a temporary regression as the combiner can't turn `store (fp_round X)` into a truncating store anymore. Fixing that in the next commit.

Co-authored-by: Claude (Claude-Opus-5) <noreply at anthropic.com>
---
 llvm/lib/Target/X86/X86ISelLowering.cpp       |  14 +
 llvm/test/CodeGen/X86/atomic-fp.ll            | 320 ++++++++++------
 .../test/CodeGen/X86/bfloat-int64-cvt-i686.ll |   4 +
 llvm/test/CodeGen/X86/canonicalize-vars.ll    |  90 ++---
 llvm/test/CodeGen/X86/fmf-flags.ll            |  47 ++-
 .../CodeGen/X86/fminimum-fmaximum-i686.ll     |  16 +-
 llvm/test/CodeGen/X86/fp-intrinsics.ll        |  38 +-
 llvm/test/CodeGen/X86/fp-strict-scalar.ll     |  48 +--
 llvm/test/CodeGen/X86/fp80-strict-scalar.ll   |   8 +-
 llvm/test/CodeGen/X86/fp_constant_op.ll       |  84 ++---
 llvm/test/CodeGen/X86/fp_load_fold.ll         |  96 ++---
 llvm/test/CodeGen/X86/inline-asm-fpstack.ll   |  29 +-
 llvm/test/CodeGen/X86/isel-fadd.ll            |  48 +--
 llvm/test/CodeGen/X86/isel-fdiv.ll            |  48 +--
 llvm/test/CodeGen/X86/isel-fmul.ll            |  48 +--
 llvm/test/CodeGen/X86/isel-fptrunc-fpext.ll   |   8 +-
 llvm/test/CodeGen/X86/isel-fsub.ll            |  48 +--
 llvm/test/CodeGen/X86/isel-sqrt.ll            |   6 +-
 llvm/test/CodeGen/X86/isel-x87.ll             |   6 +
 llvm/test/CodeGen/X86/limited-prec.ll         | 341 +++++++++---------
 llvm/test/CodeGen/X86/negate-add-zero.ll      |  56 +--
 llvm/test/CodeGen/X86/no-ret-in-x87-reg.ll    |  10 +-
 llvm/test/CodeGen/X86/nosse-vector.ll         |  46 +++
 llvm/test/CodeGen/X86/peep-test-1.ll          |   4 +
 llvm/test/CodeGen/X86/powi-const.ll           |  24 +-
 llvm/test/CodeGen/X86/pr1505b.ll              |  14 +-
 llvm/test/CodeGen/X86/pr50782.ll              |  12 +-
 llvm/test/CodeGen/X86/select.ll               |   8 +-
 llvm/test/CodeGen/X86/sincos-stack-args.ll    |   8 +-
 llvm/test/CodeGen/X86/x87-round-to-type.ll    |  41 ++-
 30 files changed, 783 insertions(+), 787 deletions(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 863698a582ff3..70551556aeb6b 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -920,6 +920,9 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
                          ISD::STRICT_FADD, ISD::STRICT_FSUB, ISD::STRICT_FMUL,
                          ISD::STRICT_FDIV, ISD::STRICT_FSQRT})
       setOperationPromotedToType(Opc, VT, MVT::f80);
+
+    setOperationAction(ISD::FP_ROUND, VT, Custom);
+    setOperationAction(ISD::STRICT_FP_ROUND, VT, Custom);
   }
 
   // f128 uses xmm registers, but most operations require libcalls.
@@ -22963,6 +22966,17 @@ SDValue X86TargetLowering::LowerFP_ROUND(SDValue Op, SelectionDAG &DAG) const {
     return Res;
   }
 
+  if (needsX87RoundToType(VT) && isScalarFPTypeOnX87Stack(SVT)) {
+    SDValue Res;
+    Chain = IsStrict ? Op.getOperand(0) : DAG.getEntryNode();
+    std::tie(Res, Chain) = RoundX87ToType(VT, DL, Chain, In, DAG);
+
+    if (IsStrict)
+      return DAG.getMergeValues({Res, Chain}, DL);
+
+    return Res;
+  }
+
   return Op;
 }
 
diff --git a/llvm/test/CodeGen/X86/atomic-fp.ll b/llvm/test/CodeGen/X86/atomic-fp.ll
index 2dee1d12e7255..37ff7cfed7a58 100644
--- a/llvm/test/CodeGen/X86/atomic-fp.ll
+++ b/llvm/test/CodeGen/X86/atomic-fp.ll
@@ -13,16 +13,18 @@
 define dso_local void @fadd_32r(ptr %loc, float %val) nounwind {
 ; X86-NOSSE-LABEL: fadd_32r:
 ; X86-NOSSE:       # %bb.0:
-; X86-NOSSE-NEXT:    subl $8, %esp
+; X86-NOSSE-NEXT:    subl $12, %esp
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NOSSE-NEXT:    movl (%eax), %ecx
-; X86-NOSSE-NEXT:    movl %ecx, (%esp)
-; X86-NOSSE-NEXT:    flds (%esp)
+; X86-NOSSE-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    flds {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fadds {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    fstps (%esp)
+; X86-NOSSE-NEXT:    flds (%esp)
 ; X86-NOSSE-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; X86-NOSSE-NEXT:    movl %ecx, (%eax)
-; X86-NOSSE-NEXT:    addl $8, %esp
+; X86-NOSSE-NEXT:    addl $12, %esp
 ; X86-NOSSE-NEXT:    retl
 ;
 ; X86-SSE1-LABEL: fadd_32r:
@@ -80,7 +82,7 @@ define dso_local void @fadd_64r(ptr %loc, double %val) nounwind {
 ; X86-NOSSE-NEXT:    pushl %ebp
 ; X86-NOSSE-NEXT:    movl %esp, %ebp
 ; X86-NOSSE-NEXT:    andl $-8, %esp
-; X86-NOSSE-NEXT:    subl $24, %esp
+; X86-NOSSE-NEXT:    subl $32, %esp
 ; X86-NOSSE-NEXT:    movl 8(%ebp), %eax
 ; X86-NOSSE-NEXT:    fildll (%eax)
 ; X86-NOSSE-NEXT:    fistpll {{[0-9]+}}(%esp)
@@ -90,6 +92,8 @@ define dso_local void @fadd_64r(ptr %loc, double %val) nounwind {
 ; X86-NOSSE-NEXT:    movl %ecx, (%esp)
 ; X86-NOSSE-NEXT:    fldl (%esp)
 ; X86-NOSSE-NEXT:    faddl 12(%ebp)
+; X86-NOSSE-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fstpl (%eax)
 ; X86-NOSSE-NEXT:    movl %ebp, %esp
 ; X86-NOSSE-NEXT:    popl %ebp
@@ -100,7 +104,7 @@ define dso_local void @fadd_64r(ptr %loc, double %val) nounwind {
 ; X86-SSE1-NEXT:    pushl %ebp
 ; X86-SSE1-NEXT:    movl %esp, %ebp
 ; X86-SSE1-NEXT:    andl $-8, %esp
-; X86-SSE1-NEXT:    subl $16, %esp
+; X86-SSE1-NEXT:    subl $24, %esp
 ; X86-SSE1-NEXT:    movl 8(%ebp), %eax
 ; X86-SSE1-NEXT:    xorps %xmm0, %xmm0
 ; X86-SSE1-NEXT:    movlps {{.*#+}} xmm0 = mem[0,1],xmm0[2,3]
@@ -109,6 +113,8 @@ define dso_local void @fadd_64r(ptr %loc, double %val) nounwind {
 ; X86-SSE1-NEXT:    movss %xmm0, {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fldl (%esp)
 ; X86-SSE1-NEXT:    faddl 12(%ebp)
+; X86-SSE1-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-SSE1-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fstpl (%eax)
 ; X86-SSE1-NEXT:    movl %ebp, %esp
 ; X86-SSE1-NEXT:    popl %ebp
@@ -168,15 +174,17 @@ define dso_local void @fadd_64r(ptr %loc, double %val) nounwind {
 define dso_local void @fadd_32g() nounwind {
 ; X86-NOSSE-LABEL: fadd_32g:
 ; X86-NOSSE:       # %bb.0:
-; X86-NOSSE-NEXT:    subl $8, %esp
+; X86-NOSSE-NEXT:    subl $12, %esp
 ; X86-NOSSE-NEXT:    movl glob32, %eax
-; X86-NOSSE-NEXT:    movl %eax, (%esp)
+; X86-NOSSE-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fld1
-; X86-NOSSE-NEXT:    fadds (%esp)
+; X86-NOSSE-NEXT:    fadds {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    fstps (%esp)
+; X86-NOSSE-NEXT:    flds (%esp)
 ; X86-NOSSE-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NOSSE-NEXT:    movl %eax, glob32
-; X86-NOSSE-NEXT:    addl $8, %esp
+; X86-NOSSE-NEXT:    addl $12, %esp
 ; X86-NOSSE-NEXT:    retl
 ;
 ; X86-SSE1-LABEL: fadd_32g:
@@ -233,7 +241,7 @@ define dso_local void @fadd_64g() nounwind {
 ; X86-NOSSE-NEXT:    pushl %ebp
 ; X86-NOSSE-NEXT:    movl %esp, %ebp
 ; X86-NOSSE-NEXT:    andl $-8, %esp
-; X86-NOSSE-NEXT:    subl $24, %esp
+; X86-NOSSE-NEXT:    subl $32, %esp
 ; X86-NOSSE-NEXT:    fildll glob64
 ; X86-NOSSE-NEXT:    fistpll {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
@@ -242,6 +250,8 @@ define dso_local void @fadd_64g() nounwind {
 ; X86-NOSSE-NEXT:    movl %eax, (%esp)
 ; X86-NOSSE-NEXT:    fld1
 ; X86-NOSSE-NEXT:    faddl (%esp)
+; X86-NOSSE-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fstpl glob64
 ; X86-NOSSE-NEXT:    movl %ebp, %esp
 ; X86-NOSSE-NEXT:    popl %ebp
@@ -252,7 +262,7 @@ define dso_local void @fadd_64g() nounwind {
 ; X86-SSE1-NEXT:    pushl %ebp
 ; X86-SSE1-NEXT:    movl %esp, %ebp
 ; X86-SSE1-NEXT:    andl $-8, %esp
-; X86-SSE1-NEXT:    subl $16, %esp
+; X86-SSE1-NEXT:    subl $24, %esp
 ; X86-SSE1-NEXT:    xorps %xmm0, %xmm0
 ; X86-SSE1-NEXT:    movlps {{.*#+}} xmm0 = mem[0,1],xmm0[2,3]
 ; X86-SSE1-NEXT:    movss %xmm0, (%esp)
@@ -260,6 +270,8 @@ define dso_local void @fadd_64g() nounwind {
 ; X86-SSE1-NEXT:    movss %xmm0, {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fld1
 ; X86-SSE1-NEXT:    faddl (%esp)
+; X86-SSE1-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-SSE1-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fstpl glob64
 ; X86-SSE1-NEXT:    movl %ebp, %esp
 ; X86-SSE1-NEXT:    popl %ebp
@@ -316,15 +328,17 @@ define dso_local void @fadd_64g() nounwind {
 define dso_local void @fadd_32imm() nounwind {
 ; X86-NOSSE-LABEL: fadd_32imm:
 ; X86-NOSSE:       # %bb.0:
-; X86-NOSSE-NEXT:    subl $8, %esp
+; X86-NOSSE-NEXT:    subl $12, %esp
 ; X86-NOSSE-NEXT:    movl -559038737, %eax
-; X86-NOSSE-NEXT:    movl %eax, (%esp)
+; X86-NOSSE-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fld1
-; X86-NOSSE-NEXT:    fadds (%esp)
+; X86-NOSSE-NEXT:    fadds {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    fstps (%esp)
+; X86-NOSSE-NEXT:    flds (%esp)
 ; X86-NOSSE-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NOSSE-NEXT:    movl %eax, -559038737
-; X86-NOSSE-NEXT:    addl $8, %esp
+; X86-NOSSE-NEXT:    addl $12, %esp
 ; X86-NOSSE-NEXT:    retl
 ;
 ; X86-SSE1-LABEL: fadd_32imm:
@@ -383,7 +397,7 @@ define dso_local void @fadd_64imm() nounwind {
 ; X86-NOSSE-NEXT:    pushl %ebp
 ; X86-NOSSE-NEXT:    movl %esp, %ebp
 ; X86-NOSSE-NEXT:    andl $-8, %esp
-; X86-NOSSE-NEXT:    subl $24, %esp
+; X86-NOSSE-NEXT:    subl $32, %esp
 ; X86-NOSSE-NEXT:    fildll -559038737
 ; X86-NOSSE-NEXT:    fistpll {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
@@ -392,6 +406,8 @@ define dso_local void @fadd_64imm() nounwind {
 ; X86-NOSSE-NEXT:    movl %eax, (%esp)
 ; X86-NOSSE-NEXT:    fld1
 ; X86-NOSSE-NEXT:    faddl (%esp)
+; X86-NOSSE-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fstpl -559038737
 ; X86-NOSSE-NEXT:    movl %ebp, %esp
 ; X86-NOSSE-NEXT:    popl %ebp
@@ -402,7 +418,7 @@ define dso_local void @fadd_64imm() nounwind {
 ; X86-SSE1-NEXT:    pushl %ebp
 ; X86-SSE1-NEXT:    movl %esp, %ebp
 ; X86-SSE1-NEXT:    andl $-8, %esp
-; X86-SSE1-NEXT:    subl $16, %esp
+; X86-SSE1-NEXT:    subl $24, %esp
 ; X86-SSE1-NEXT:    xorps %xmm0, %xmm0
 ; X86-SSE1-NEXT:    movlps {{.*#+}} xmm0 = mem[0,1],xmm0[2,3]
 ; X86-SSE1-NEXT:    movss %xmm0, (%esp)
@@ -410,6 +426,8 @@ define dso_local void @fadd_64imm() nounwind {
 ; X86-SSE1-NEXT:    movss %xmm0, {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fld1
 ; X86-SSE1-NEXT:    faddl (%esp)
+; X86-SSE1-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-SSE1-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fstpl -559038737
 ; X86-SSE1-NEXT:    movl %ebp, %esp
 ; X86-SSE1-NEXT:    popl %ebp
@@ -468,15 +486,17 @@ define dso_local void @fadd_64imm() nounwind {
 define dso_local void @fadd_32stack() nounwind {
 ; X86-NOSSE-LABEL: fadd_32stack:
 ; X86-NOSSE:       # %bb.0:
-; X86-NOSSE-NEXT:    subl $12, %esp
+; X86-NOSSE-NEXT:    subl $16, %esp
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NOSSE-NEXT:    movl %eax, (%esp)
+; X86-NOSSE-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fld1
-; X86-NOSSE-NEXT:    fadds (%esp)
+; X86-NOSSE-NEXT:    fadds {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    fstps (%esp)
+; X86-NOSSE-NEXT:    flds (%esp)
 ; X86-NOSSE-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NOSSE-NEXT:    movl %eax, {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    addl $12, %esp
+; X86-NOSSE-NEXT:    addl $16, %esp
 ; X86-NOSSE-NEXT:    retl
 ;
 ; X86-SSE1-LABEL: fadd_32stack:
@@ -538,7 +558,7 @@ define dso_local void @fadd_64stack() nounwind {
 ; X86-NOSSE-NEXT:    pushl %ebp
 ; X86-NOSSE-NEXT:    movl %esp, %ebp
 ; X86-NOSSE-NEXT:    andl $-8, %esp
-; X86-NOSSE-NEXT:    subl $32, %esp
+; X86-NOSSE-NEXT:    subl $40, %esp
 ; X86-NOSSE-NEXT:    fildll {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fistpll {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
@@ -548,6 +568,8 @@ define dso_local void @fadd_64stack() nounwind {
 ; X86-NOSSE-NEXT:    fld1
 ; X86-NOSSE-NEXT:    faddl (%esp)
 ; X86-NOSSE-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    fldl {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    fstpl {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl %ebp, %esp
 ; X86-NOSSE-NEXT:    popl %ebp
 ; X86-NOSSE-NEXT:    retl
@@ -557,7 +579,7 @@ define dso_local void @fadd_64stack() nounwind {
 ; X86-SSE1-NEXT:    pushl %ebp
 ; X86-SSE1-NEXT:    movl %esp, %ebp
 ; X86-SSE1-NEXT:    andl $-8, %esp
-; X86-SSE1-NEXT:    subl $24, %esp
+; X86-SSE1-NEXT:    subl $32, %esp
 ; X86-SSE1-NEXT:    xorps %xmm0, %xmm0
 ; X86-SSE1-NEXT:    movlps {{.*#+}} xmm0 = mem[0,1],xmm0[2,3]
 ; X86-SSE1-NEXT:    movss %xmm0, (%esp)
@@ -566,6 +588,8 @@ define dso_local void @fadd_64stack() nounwind {
 ; X86-SSE1-NEXT:    fld1
 ; X86-SSE1-NEXT:    faddl (%esp)
 ; X86-SSE1-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-SSE1-NEXT:    fldl {{[0-9]+}}(%esp)
+; X86-SSE1-NEXT:    fstpl {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    movl %ebp, %esp
 ; X86-SSE1-NEXT:    popl %ebp
 ; X86-SSE1-NEXT:    retl
@@ -625,7 +649,7 @@ define dso_local void @fadd_array(ptr %arg, double %arg1, i64 %arg2) nounwind {
 ; X86-NOSSE-NEXT:    movl %esp, %ebp
 ; X86-NOSSE-NEXT:    pushl %esi
 ; X86-NOSSE-NEXT:    andl $-8, %esp
-; X86-NOSSE-NEXT:    subl $32, %esp
+; X86-NOSSE-NEXT:    subl $40, %esp
 ; X86-NOSSE-NEXT:    movl 20(%ebp), %eax
 ; X86-NOSSE-NEXT:    movl 8(%ebp), %ecx
 ; X86-NOSSE-NEXT:    fildll (%ecx,%eax,8)
@@ -636,6 +660,8 @@ define dso_local void @fadd_array(ptr %arg, double %arg1, i64 %arg2) nounwind {
 ; X86-NOSSE-NEXT:    movl %edx, (%esp)
 ; X86-NOSSE-NEXT:    fldl (%esp)
 ; X86-NOSSE-NEXT:    faddl 12(%ebp)
+; X86-NOSSE-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fstpl (%ecx,%eax,8)
 ; X86-NOSSE-NEXT:    leal -4(%ebp), %esp
 ; X86-NOSSE-NEXT:    popl %esi
@@ -647,7 +673,7 @@ define dso_local void @fadd_array(ptr %arg, double %arg1, i64 %arg2) nounwind {
 ; X86-SSE1-NEXT:    pushl %ebp
 ; X86-SSE1-NEXT:    movl %esp, %ebp
 ; X86-SSE1-NEXT:    andl $-8, %esp
-; X86-SSE1-NEXT:    subl $16, %esp
+; X86-SSE1-NEXT:    subl $24, %esp
 ; X86-SSE1-NEXT:    movl 20(%ebp), %eax
 ; X86-SSE1-NEXT:    movl 8(%ebp), %ecx
 ; X86-SSE1-NEXT:    xorps %xmm0, %xmm0
@@ -657,6 +683,8 @@ define dso_local void @fadd_array(ptr %arg, double %arg1, i64 %arg2) nounwind {
 ; X86-SSE1-NEXT:    movss %xmm0, {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fldl (%esp)
 ; X86-SSE1-NEXT:    faddl 12(%ebp)
+; X86-SSE1-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-SSE1-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fstpl (%ecx,%eax,8)
 ; X86-SSE1-NEXT:    movl %ebp, %esp
 ; X86-SSE1-NEXT:    popl %ebp
@@ -718,16 +746,18 @@ bb:
 define dso_local void @fsub_32r(ptr %loc, float %val) nounwind {
 ; X86-NOSSE-LABEL: fsub_32r:
 ; X86-NOSSE:       # %bb.0:
-; X86-NOSSE-NEXT:    subl $8, %esp
+; X86-NOSSE-NEXT:    subl $12, %esp
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NOSSE-NEXT:    movl (%eax), %ecx
-; X86-NOSSE-NEXT:    movl %ecx, (%esp)
-; X86-NOSSE-NEXT:    flds (%esp)
+; X86-NOSSE-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    flds {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fsubs {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    fstps (%esp)
+; X86-NOSSE-NEXT:    flds (%esp)
 ; X86-NOSSE-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; X86-NOSSE-NEXT:    movl %ecx, (%eax)
-; X86-NOSSE-NEXT:    addl $8, %esp
+; X86-NOSSE-NEXT:    addl $12, %esp
 ; X86-NOSSE-NEXT:    retl
 ;
 ; X86-SSE1-LABEL: fsub_32r:
@@ -787,7 +817,7 @@ define dso_local void @fsub_64r(ptr %loc, double %val) nounwind {
 ; X86-NOSSE-NEXT:    pushl %ebp
 ; X86-NOSSE-NEXT:    movl %esp, %ebp
 ; X86-NOSSE-NEXT:    andl $-8, %esp
-; X86-NOSSE-NEXT:    subl $24, %esp
+; X86-NOSSE-NEXT:    subl $32, %esp
 ; X86-NOSSE-NEXT:    movl 8(%ebp), %eax
 ; X86-NOSSE-NEXT:    fildll (%eax)
 ; X86-NOSSE-NEXT:    fistpll {{[0-9]+}}(%esp)
@@ -797,6 +827,8 @@ define dso_local void @fsub_64r(ptr %loc, double %val) nounwind {
 ; X86-NOSSE-NEXT:    movl %ecx, (%esp)
 ; X86-NOSSE-NEXT:    fldl (%esp)
 ; X86-NOSSE-NEXT:    fsubl 12(%ebp)
+; X86-NOSSE-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fstpl (%eax)
 ; X86-NOSSE-NEXT:    movl %ebp, %esp
 ; X86-NOSSE-NEXT:    popl %ebp
@@ -807,7 +839,7 @@ define dso_local void @fsub_64r(ptr %loc, double %val) nounwind {
 ; X86-SSE1-NEXT:    pushl %ebp
 ; X86-SSE1-NEXT:    movl %esp, %ebp
 ; X86-SSE1-NEXT:    andl $-8, %esp
-; X86-SSE1-NEXT:    subl $16, %esp
+; X86-SSE1-NEXT:    subl $24, %esp
 ; X86-SSE1-NEXT:    movl 8(%ebp), %eax
 ; X86-SSE1-NEXT:    xorps %xmm0, %xmm0
 ; X86-SSE1-NEXT:    movlps {{.*#+}} xmm0 = mem[0,1],xmm0[2,3]
@@ -816,6 +848,8 @@ define dso_local void @fsub_64r(ptr %loc, double %val) nounwind {
 ; X86-SSE1-NEXT:    movss %xmm0, {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fldl (%esp)
 ; X86-SSE1-NEXT:    fsubl 12(%ebp)
+; X86-SSE1-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-SSE1-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fstpl (%eax)
 ; X86-SSE1-NEXT:    movl %ebp, %esp
 ; X86-SSE1-NEXT:    popl %ebp
@@ -874,16 +908,18 @@ define dso_local void @fsub_64r(ptr %loc, double %val) nounwind {
 define dso_local void @fsub_32g() nounwind {
 ; X86-NOSSE-LABEL: fsub_32g:
 ; X86-NOSSE:       # %bb.0:
-; X86-NOSSE-NEXT:    subl $8, %esp
+; X86-NOSSE-NEXT:    subl $12, %esp
 ; X86-NOSSE-NEXT:    movl glob32, %eax
-; X86-NOSSE-NEXT:    movl %eax, (%esp)
+; X86-NOSSE-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fld1
 ; X86-NOSSE-NEXT:    fchs
-; X86-NOSSE-NEXT:    fadds (%esp)
+; X86-NOSSE-NEXT:    fadds {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    fstps (%esp)
+; X86-NOSSE-NEXT:    flds (%esp)
 ; X86-NOSSE-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NOSSE-NEXT:    movl %eax, glob32
-; X86-NOSSE-NEXT:    addl $8, %esp
+; X86-NOSSE-NEXT:    addl $12, %esp
 ; X86-NOSSE-NEXT:    retl
 ;
 ; X86-SSE1-LABEL: fsub_32g:
@@ -940,7 +976,7 @@ define dso_local void @fsub_64g() nounwind {
 ; X86-NOSSE-NEXT:    pushl %ebp
 ; X86-NOSSE-NEXT:    movl %esp, %ebp
 ; X86-NOSSE-NEXT:    andl $-8, %esp
-; X86-NOSSE-NEXT:    subl $24, %esp
+; X86-NOSSE-NEXT:    subl $32, %esp
 ; X86-NOSSE-NEXT:    fildll glob64
 ; X86-NOSSE-NEXT:    fistpll {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
@@ -950,6 +986,8 @@ define dso_local void @fsub_64g() nounwind {
 ; X86-NOSSE-NEXT:    fld1
 ; X86-NOSSE-NEXT:    fchs
 ; X86-NOSSE-NEXT:    faddl (%esp)
+; X86-NOSSE-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fstpl glob64
 ; X86-NOSSE-NEXT:    movl %ebp, %esp
 ; X86-NOSSE-NEXT:    popl %ebp
@@ -960,7 +998,7 @@ define dso_local void @fsub_64g() nounwind {
 ; X86-SSE1-NEXT:    pushl %ebp
 ; X86-SSE1-NEXT:    movl %esp, %ebp
 ; X86-SSE1-NEXT:    andl $-8, %esp
-; X86-SSE1-NEXT:    subl $16, %esp
+; X86-SSE1-NEXT:    subl $24, %esp
 ; X86-SSE1-NEXT:    xorps %xmm0, %xmm0
 ; X86-SSE1-NEXT:    movlps {{.*#+}} xmm0 = mem[0,1],xmm0[2,3]
 ; X86-SSE1-NEXT:    movss %xmm0, (%esp)
@@ -969,6 +1007,8 @@ define dso_local void @fsub_64g() nounwind {
 ; X86-SSE1-NEXT:    fld1
 ; X86-SSE1-NEXT:    fchs
 ; X86-SSE1-NEXT:    faddl (%esp)
+; X86-SSE1-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-SSE1-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fstpl glob64
 ; X86-SSE1-NEXT:    movl %ebp, %esp
 ; X86-SSE1-NEXT:    popl %ebp
@@ -1025,16 +1065,18 @@ define dso_local void @fsub_64g() nounwind {
 define dso_local void @fsub_32imm() nounwind {
 ; X86-NOSSE-LABEL: fsub_32imm:
 ; X86-NOSSE:       # %bb.0:
-; X86-NOSSE-NEXT:    subl $8, %esp
+; X86-NOSSE-NEXT:    subl $12, %esp
 ; X86-NOSSE-NEXT:    movl -559038737, %eax
-; X86-NOSSE-NEXT:    movl %eax, (%esp)
+; X86-NOSSE-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fld1
 ; X86-NOSSE-NEXT:    fchs
-; X86-NOSSE-NEXT:    fadds (%esp)
+; X86-NOSSE-NEXT:    fadds {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    fstps (%esp)
+; X86-NOSSE-NEXT:    flds (%esp)
 ; X86-NOSSE-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NOSSE-NEXT:    movl %eax, -559038737
-; X86-NOSSE-NEXT:    addl $8, %esp
+; X86-NOSSE-NEXT:    addl $12, %esp
 ; X86-NOSSE-NEXT:    retl
 ;
 ; X86-SSE1-LABEL: fsub_32imm:
@@ -1093,7 +1135,7 @@ define dso_local void @fsub_64imm() nounwind {
 ; X86-NOSSE-NEXT:    pushl %ebp
 ; X86-NOSSE-NEXT:    movl %esp, %ebp
 ; X86-NOSSE-NEXT:    andl $-8, %esp
-; X86-NOSSE-NEXT:    subl $24, %esp
+; X86-NOSSE-NEXT:    subl $32, %esp
 ; X86-NOSSE-NEXT:    fildll -559038737
 ; X86-NOSSE-NEXT:    fistpll {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
@@ -1103,6 +1145,8 @@ define dso_local void @fsub_64imm() nounwind {
 ; X86-NOSSE-NEXT:    fld1
 ; X86-NOSSE-NEXT:    fchs
 ; X86-NOSSE-NEXT:    faddl (%esp)
+; X86-NOSSE-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fstpl -559038737
 ; X86-NOSSE-NEXT:    movl %ebp, %esp
 ; X86-NOSSE-NEXT:    popl %ebp
@@ -1113,7 +1157,7 @@ define dso_local void @fsub_64imm() nounwind {
 ; X86-SSE1-NEXT:    pushl %ebp
 ; X86-SSE1-NEXT:    movl %esp, %ebp
 ; X86-SSE1-NEXT:    andl $-8, %esp
-; X86-SSE1-NEXT:    subl $16, %esp
+; X86-SSE1-NEXT:    subl $24, %esp
 ; X86-SSE1-NEXT:    xorps %xmm0, %xmm0
 ; X86-SSE1-NEXT:    movlps {{.*#+}} xmm0 = mem[0,1],xmm0[2,3]
 ; X86-SSE1-NEXT:    movss %xmm0, (%esp)
@@ -1122,6 +1166,8 @@ define dso_local void @fsub_64imm() nounwind {
 ; X86-SSE1-NEXT:    fld1
 ; X86-SSE1-NEXT:    fchs
 ; X86-SSE1-NEXT:    faddl (%esp)
+; X86-SSE1-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-SSE1-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fstpl -559038737
 ; X86-SSE1-NEXT:    movl %ebp, %esp
 ; X86-SSE1-NEXT:    popl %ebp
@@ -1180,15 +1226,17 @@ define dso_local void @fsub_64imm() nounwind {
 define dso_local void @fsub_32stack() nounwind {
 ; X86-NOSSE-LABEL: fsub_32stack:
 ; X86-NOSSE:       # %bb.0:
-; X86-NOSSE-NEXT:    subl $12, %esp
+; X86-NOSSE-NEXT:    subl $16, %esp
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NOSSE-NEXT:    movl %eax, (%esp)
+; X86-NOSSE-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fld1
-; X86-NOSSE-NEXT:    fsubs (%esp)
+; X86-NOSSE-NEXT:    fsubs {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    fstps (%esp)
+; X86-NOSSE-NEXT:    flds (%esp)
 ; X86-NOSSE-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NOSSE-NEXT:    movl %eax, {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    addl $12, %esp
+; X86-NOSSE-NEXT:    addl $16, %esp
 ; X86-NOSSE-NEXT:    retl
 ;
 ; X86-SSE1-LABEL: fsub_32stack:
@@ -1250,7 +1298,7 @@ define dso_local void @fsub_64stack() nounwind {
 ; X86-NOSSE-NEXT:    pushl %ebp
 ; X86-NOSSE-NEXT:    movl %esp, %ebp
 ; X86-NOSSE-NEXT:    andl $-8, %esp
-; X86-NOSSE-NEXT:    subl $32, %esp
+; X86-NOSSE-NEXT:    subl $40, %esp
 ; X86-NOSSE-NEXT:    fildll {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fistpll {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
@@ -1260,6 +1308,8 @@ define dso_local void @fsub_64stack() nounwind {
 ; X86-NOSSE-NEXT:    fld1
 ; X86-NOSSE-NEXT:    fsubl (%esp)
 ; X86-NOSSE-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    fldl {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    fstpl {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl %ebp, %esp
 ; X86-NOSSE-NEXT:    popl %ebp
 ; X86-NOSSE-NEXT:    retl
@@ -1269,7 +1319,7 @@ define dso_local void @fsub_64stack() nounwind {
 ; X86-SSE1-NEXT:    pushl %ebp
 ; X86-SSE1-NEXT:    movl %esp, %ebp
 ; X86-SSE1-NEXT:    andl $-8, %esp
-; X86-SSE1-NEXT:    subl $24, %esp
+; X86-SSE1-NEXT:    subl $32, %esp
 ; X86-SSE1-NEXT:    xorps %xmm0, %xmm0
 ; X86-SSE1-NEXT:    movlps {{.*#+}} xmm0 = mem[0,1],xmm0[2,3]
 ; X86-SSE1-NEXT:    movss %xmm0, (%esp)
@@ -1278,6 +1328,8 @@ define dso_local void @fsub_64stack() nounwind {
 ; X86-SSE1-NEXT:    fld1
 ; X86-SSE1-NEXT:    fsubl (%esp)
 ; X86-SSE1-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-SSE1-NEXT:    fldl {{[0-9]+}}(%esp)
+; X86-SSE1-NEXT:    fstpl {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    movl %ebp, %esp
 ; X86-SSE1-NEXT:    popl %ebp
 ; X86-SSE1-NEXT:    retl
@@ -1339,7 +1391,7 @@ define dso_local void @fsub_array(ptr %arg, double %arg1, i64 %arg2) nounwind {
 ; X86-NOSSE-NEXT:    movl %esp, %ebp
 ; X86-NOSSE-NEXT:    pushl %esi
 ; X86-NOSSE-NEXT:    andl $-8, %esp
-; X86-NOSSE-NEXT:    subl $32, %esp
+; X86-NOSSE-NEXT:    subl $40, %esp
 ; X86-NOSSE-NEXT:    movl 20(%ebp), %eax
 ; X86-NOSSE-NEXT:    movl 8(%ebp), %ecx
 ; X86-NOSSE-NEXT:    fildll (%ecx,%eax,8)
@@ -1350,6 +1402,8 @@ define dso_local void @fsub_array(ptr %arg, double %arg1, i64 %arg2) nounwind {
 ; X86-NOSSE-NEXT:    movl %edx, (%esp)
 ; X86-NOSSE-NEXT:    fldl (%esp)
 ; X86-NOSSE-NEXT:    fsubl 12(%ebp)
+; X86-NOSSE-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fstpl (%ecx,%eax,8)
 ; X86-NOSSE-NEXT:    leal -4(%ebp), %esp
 ; X86-NOSSE-NEXT:    popl %esi
@@ -1361,7 +1415,7 @@ define dso_local void @fsub_array(ptr %arg, double %arg1, i64 %arg2) nounwind {
 ; X86-SSE1-NEXT:    pushl %ebp
 ; X86-SSE1-NEXT:    movl %esp, %ebp
 ; X86-SSE1-NEXT:    andl $-8, %esp
-; X86-SSE1-NEXT:    subl $16, %esp
+; X86-SSE1-NEXT:    subl $24, %esp
 ; X86-SSE1-NEXT:    movl 20(%ebp), %eax
 ; X86-SSE1-NEXT:    movl 8(%ebp), %ecx
 ; X86-SSE1-NEXT:    xorps %xmm0, %xmm0
@@ -1371,6 +1425,8 @@ define dso_local void @fsub_array(ptr %arg, double %arg1, i64 %arg2) nounwind {
 ; X86-SSE1-NEXT:    movss %xmm0, {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fldl (%esp)
 ; X86-SSE1-NEXT:    fsubl 12(%ebp)
+; X86-SSE1-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-SSE1-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fstpl (%ecx,%eax,8)
 ; X86-SSE1-NEXT:    movl %ebp, %esp
 ; X86-SSE1-NEXT:    popl %ebp
@@ -1434,16 +1490,18 @@ bb:
 define dso_local void @fmul_32r(ptr %loc, float %val) nounwind {
 ; X86-NOSSE-LABEL: fmul_32r:
 ; X86-NOSSE:       # %bb.0:
-; X86-NOSSE-NEXT:    subl $8, %esp
+; X86-NOSSE-NEXT:    subl $12, %esp
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NOSSE-NEXT:    movl (%eax), %ecx
-; X86-NOSSE-NEXT:    movl %ecx, (%esp)
-; X86-NOSSE-NEXT:    flds (%esp)
+; X86-NOSSE-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    flds {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fmuls {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    fstps (%esp)
+; X86-NOSSE-NEXT:    flds (%esp)
 ; X86-NOSSE-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; X86-NOSSE-NEXT:    movl %ecx, (%eax)
-; X86-NOSSE-NEXT:    addl $8, %esp
+; X86-NOSSE-NEXT:    addl $12, %esp
 ; X86-NOSSE-NEXT:    retl
 ;
 ; X86-SSE1-LABEL: fmul_32r:
@@ -1501,7 +1559,7 @@ define dso_local void @fmul_64r(ptr %loc, double %val) nounwind {
 ; X86-NOSSE-NEXT:    pushl %ebp
 ; X86-NOSSE-NEXT:    movl %esp, %ebp
 ; X86-NOSSE-NEXT:    andl $-8, %esp
-; X86-NOSSE-NEXT:    subl $24, %esp
+; X86-NOSSE-NEXT:    subl $32, %esp
 ; X86-NOSSE-NEXT:    movl 8(%ebp), %eax
 ; X86-NOSSE-NEXT:    fildll (%eax)
 ; X86-NOSSE-NEXT:    fistpll {{[0-9]+}}(%esp)
@@ -1511,6 +1569,8 @@ define dso_local void @fmul_64r(ptr %loc, double %val) nounwind {
 ; X86-NOSSE-NEXT:    movl %ecx, (%esp)
 ; X86-NOSSE-NEXT:    fldl (%esp)
 ; X86-NOSSE-NEXT:    fmull 12(%ebp)
+; X86-NOSSE-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fstpl (%eax)
 ; X86-NOSSE-NEXT:    movl %ebp, %esp
 ; X86-NOSSE-NEXT:    popl %ebp
@@ -1521,7 +1581,7 @@ define dso_local void @fmul_64r(ptr %loc, double %val) nounwind {
 ; X86-SSE1-NEXT:    pushl %ebp
 ; X86-SSE1-NEXT:    movl %esp, %ebp
 ; X86-SSE1-NEXT:    andl $-8, %esp
-; X86-SSE1-NEXT:    subl $16, %esp
+; X86-SSE1-NEXT:    subl $24, %esp
 ; X86-SSE1-NEXT:    movl 8(%ebp), %eax
 ; X86-SSE1-NEXT:    xorps %xmm0, %xmm0
 ; X86-SSE1-NEXT:    movlps {{.*#+}} xmm0 = mem[0,1],xmm0[2,3]
@@ -1530,6 +1590,8 @@ define dso_local void @fmul_64r(ptr %loc, double %val) nounwind {
 ; X86-SSE1-NEXT:    movss %xmm0, {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fldl (%esp)
 ; X86-SSE1-NEXT:    fmull 12(%ebp)
+; X86-SSE1-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-SSE1-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fstpl (%eax)
 ; X86-SSE1-NEXT:    movl %ebp, %esp
 ; X86-SSE1-NEXT:    popl %ebp
@@ -1586,15 +1648,17 @@ define dso_local void @fmul_64r(ptr %loc, double %val) nounwind {
 define dso_local void @fmul_32g() nounwind {
 ; X86-NOSSE-LABEL: fmul_32g:
 ; X86-NOSSE:       # %bb.0:
-; X86-NOSSE-NEXT:    subl $8, %esp
+; X86-NOSSE-NEXT:    subl $12, %esp
 ; X86-NOSSE-NEXT:    movl glob32, %eax
-; X86-NOSSE-NEXT:    movl %eax, (%esp)
-; X86-NOSSE-NEXT:    flds (%esp)
+; X86-NOSSE-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    flds {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
+; X86-NOSSE-NEXT:    fstps (%esp)
+; X86-NOSSE-NEXT:    flds (%esp)
 ; X86-NOSSE-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NOSSE-NEXT:    movl %eax, glob32
-; X86-NOSSE-NEXT:    addl $8, %esp
+; X86-NOSSE-NEXT:    addl $12, %esp
 ; X86-NOSSE-NEXT:    retl
 ;
 ; X86-SSE1-LABEL: fmul_32g:
@@ -1651,7 +1715,7 @@ define dso_local void @fmul_64g() nounwind {
 ; X86-NOSSE-NEXT:    pushl %ebp
 ; X86-NOSSE-NEXT:    movl %esp, %ebp
 ; X86-NOSSE-NEXT:    andl $-8, %esp
-; X86-NOSSE-NEXT:    subl $24, %esp
+; X86-NOSSE-NEXT:    subl $32, %esp
 ; X86-NOSSE-NEXT:    fildll glob64
 ; X86-NOSSE-NEXT:    fistpll {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
@@ -1660,6 +1724,8 @@ define dso_local void @fmul_64g() nounwind {
 ; X86-NOSSE-NEXT:    movl %eax, (%esp)
 ; X86-NOSSE-NEXT:    fldl (%esp)
 ; X86-NOSSE-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
+; X86-NOSSE-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fstpl glob64
 ; X86-NOSSE-NEXT:    movl %ebp, %esp
 ; X86-NOSSE-NEXT:    popl %ebp
@@ -1670,7 +1736,7 @@ define dso_local void @fmul_64g() nounwind {
 ; X86-SSE1-NEXT:    pushl %ebp
 ; X86-SSE1-NEXT:    movl %esp, %ebp
 ; X86-SSE1-NEXT:    andl $-8, %esp
-; X86-SSE1-NEXT:    subl $16, %esp
+; X86-SSE1-NEXT:    subl $24, %esp
 ; X86-SSE1-NEXT:    xorps %xmm0, %xmm0
 ; X86-SSE1-NEXT:    movlps {{.*#+}} xmm0 = mem[0,1],xmm0[2,3]
 ; X86-SSE1-NEXT:    movss %xmm0, (%esp)
@@ -1678,6 +1744,8 @@ define dso_local void @fmul_64g() nounwind {
 ; X86-SSE1-NEXT:    movss %xmm0, {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fldl (%esp)
 ; X86-SSE1-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
+; X86-SSE1-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-SSE1-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fstpl glob64
 ; X86-SSE1-NEXT:    movl %ebp, %esp
 ; X86-SSE1-NEXT:    popl %ebp
@@ -1734,15 +1802,17 @@ define dso_local void @fmul_64g() nounwind {
 define dso_local void @fmul_32imm() nounwind {
 ; X86-NOSSE-LABEL: fmul_32imm:
 ; X86-NOSSE:       # %bb.0:
-; X86-NOSSE-NEXT:    subl $8, %esp
+; X86-NOSSE-NEXT:    subl $12, %esp
 ; X86-NOSSE-NEXT:    movl -559038737, %eax
-; X86-NOSSE-NEXT:    movl %eax, (%esp)
-; X86-NOSSE-NEXT:    flds (%esp)
+; X86-NOSSE-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    flds {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
+; X86-NOSSE-NEXT:    fstps (%esp)
+; X86-NOSSE-NEXT:    flds (%esp)
 ; X86-NOSSE-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NOSSE-NEXT:    movl %eax, -559038737
-; X86-NOSSE-NEXT:    addl $8, %esp
+; X86-NOSSE-NEXT:    addl $12, %esp
 ; X86-NOSSE-NEXT:    retl
 ;
 ; X86-SSE1-LABEL: fmul_32imm:
@@ -1801,7 +1871,7 @@ define dso_local void @fmul_64imm() nounwind {
 ; X86-NOSSE-NEXT:    pushl %ebp
 ; X86-NOSSE-NEXT:    movl %esp, %ebp
 ; X86-NOSSE-NEXT:    andl $-8, %esp
-; X86-NOSSE-NEXT:    subl $24, %esp
+; X86-NOSSE-NEXT:    subl $32, %esp
 ; X86-NOSSE-NEXT:    fildll -559038737
 ; X86-NOSSE-NEXT:    fistpll {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
@@ -1810,6 +1880,8 @@ define dso_local void @fmul_64imm() nounwind {
 ; X86-NOSSE-NEXT:    movl %eax, (%esp)
 ; X86-NOSSE-NEXT:    fldl (%esp)
 ; X86-NOSSE-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
+; X86-NOSSE-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fstpl -559038737
 ; X86-NOSSE-NEXT:    movl %ebp, %esp
 ; X86-NOSSE-NEXT:    popl %ebp
@@ -1820,7 +1892,7 @@ define dso_local void @fmul_64imm() nounwind {
 ; X86-SSE1-NEXT:    pushl %ebp
 ; X86-SSE1-NEXT:    movl %esp, %ebp
 ; X86-SSE1-NEXT:    andl $-8, %esp
-; X86-SSE1-NEXT:    subl $16, %esp
+; X86-SSE1-NEXT:    subl $24, %esp
 ; X86-SSE1-NEXT:    xorps %xmm0, %xmm0
 ; X86-SSE1-NEXT:    movlps {{.*#+}} xmm0 = mem[0,1],xmm0[2,3]
 ; X86-SSE1-NEXT:    movss %xmm0, (%esp)
@@ -1828,6 +1900,8 @@ define dso_local void @fmul_64imm() nounwind {
 ; X86-SSE1-NEXT:    movss %xmm0, {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fldl (%esp)
 ; X86-SSE1-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
+; X86-SSE1-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-SSE1-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fstpl -559038737
 ; X86-SSE1-NEXT:    movl %ebp, %esp
 ; X86-SSE1-NEXT:    popl %ebp
@@ -1886,15 +1960,17 @@ define dso_local void @fmul_64imm() nounwind {
 define dso_local void @fmul_32stack() nounwind {
 ; X86-NOSSE-LABEL: fmul_32stack:
 ; X86-NOSSE:       # %bb.0:
-; X86-NOSSE-NEXT:    subl $12, %esp
+; X86-NOSSE-NEXT:    subl $16, %esp
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NOSSE-NEXT:    movl %eax, (%esp)
-; X86-NOSSE-NEXT:    flds (%esp)
+; X86-NOSSE-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    flds {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
+; X86-NOSSE-NEXT:    fstps (%esp)
+; X86-NOSSE-NEXT:    flds (%esp)
 ; X86-NOSSE-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NOSSE-NEXT:    movl %eax, {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    addl $12, %esp
+; X86-NOSSE-NEXT:    addl $16, %esp
 ; X86-NOSSE-NEXT:    retl
 ;
 ; X86-SSE1-LABEL: fmul_32stack:
@@ -1956,7 +2032,7 @@ define dso_local void @fmul_64stack() nounwind {
 ; X86-NOSSE-NEXT:    pushl %ebp
 ; X86-NOSSE-NEXT:    movl %esp, %ebp
 ; X86-NOSSE-NEXT:    andl $-8, %esp
-; X86-NOSSE-NEXT:    subl $32, %esp
+; X86-NOSSE-NEXT:    subl $40, %esp
 ; X86-NOSSE-NEXT:    fildll {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fistpll {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
@@ -1966,6 +2042,8 @@ define dso_local void @fmul_64stack() nounwind {
 ; X86-NOSSE-NEXT:    fldl (%esp)
 ; X86-NOSSE-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
 ; X86-NOSSE-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    fldl {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    fstpl {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl %ebp, %esp
 ; X86-NOSSE-NEXT:    popl %ebp
 ; X86-NOSSE-NEXT:    retl
@@ -1975,7 +2053,7 @@ define dso_local void @fmul_64stack() nounwind {
 ; X86-SSE1-NEXT:    pushl %ebp
 ; X86-SSE1-NEXT:    movl %esp, %ebp
 ; X86-SSE1-NEXT:    andl $-8, %esp
-; X86-SSE1-NEXT:    subl $24, %esp
+; X86-SSE1-NEXT:    subl $32, %esp
 ; X86-SSE1-NEXT:    xorps %xmm0, %xmm0
 ; X86-SSE1-NEXT:    movlps {{.*#+}} xmm0 = mem[0,1],xmm0[2,3]
 ; X86-SSE1-NEXT:    movss %xmm0, (%esp)
@@ -1984,6 +2062,8 @@ define dso_local void @fmul_64stack() nounwind {
 ; X86-SSE1-NEXT:    fldl (%esp)
 ; X86-SSE1-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
 ; X86-SSE1-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-SSE1-NEXT:    fldl {{[0-9]+}}(%esp)
+; X86-SSE1-NEXT:    fstpl {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    movl %ebp, %esp
 ; X86-SSE1-NEXT:    popl %ebp
 ; X86-SSE1-NEXT:    retl
@@ -2043,7 +2123,7 @@ define dso_local void @fmul_array(ptr %arg, double %arg1, i64 %arg2) nounwind {
 ; X86-NOSSE-NEXT:    movl %esp, %ebp
 ; X86-NOSSE-NEXT:    pushl %esi
 ; X86-NOSSE-NEXT:    andl $-8, %esp
-; X86-NOSSE-NEXT:    subl $32, %esp
+; X86-NOSSE-NEXT:    subl $40, %esp
 ; X86-NOSSE-NEXT:    movl 20(%ebp), %eax
 ; X86-NOSSE-NEXT:    movl 8(%ebp), %ecx
 ; X86-NOSSE-NEXT:    fildll (%ecx,%eax,8)
@@ -2054,6 +2134,8 @@ define dso_local void @fmul_array(ptr %arg, double %arg1, i64 %arg2) nounwind {
 ; X86-NOSSE-NEXT:    movl %edx, (%esp)
 ; X86-NOSSE-NEXT:    fldl (%esp)
 ; X86-NOSSE-NEXT:    fmull 12(%ebp)
+; X86-NOSSE-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fstpl (%ecx,%eax,8)
 ; X86-NOSSE-NEXT:    leal -4(%ebp), %esp
 ; X86-NOSSE-NEXT:    popl %esi
@@ -2065,7 +2147,7 @@ define dso_local void @fmul_array(ptr %arg, double %arg1, i64 %arg2) nounwind {
 ; X86-SSE1-NEXT:    pushl %ebp
 ; X86-SSE1-NEXT:    movl %esp, %ebp
 ; X86-SSE1-NEXT:    andl $-8, %esp
-; X86-SSE1-NEXT:    subl $16, %esp
+; X86-SSE1-NEXT:    subl $24, %esp
 ; X86-SSE1-NEXT:    movl 20(%ebp), %eax
 ; X86-SSE1-NEXT:    movl 8(%ebp), %ecx
 ; X86-SSE1-NEXT:    xorps %xmm0, %xmm0
@@ -2075,6 +2157,8 @@ define dso_local void @fmul_array(ptr %arg, double %arg1, i64 %arg2) nounwind {
 ; X86-SSE1-NEXT:    movss %xmm0, {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fldl (%esp)
 ; X86-SSE1-NEXT:    fmull 12(%ebp)
+; X86-SSE1-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-SSE1-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fstpl (%ecx,%eax,8)
 ; X86-SSE1-NEXT:    movl %ebp, %esp
 ; X86-SSE1-NEXT:    popl %ebp
@@ -2136,16 +2220,18 @@ bb:
 define dso_local void @fdiv_32r(ptr %loc, float %val) nounwind {
 ; X86-NOSSE-LABEL: fdiv_32r:
 ; X86-NOSSE:       # %bb.0:
-; X86-NOSSE-NEXT:    subl $8, %esp
+; X86-NOSSE-NEXT:    subl $12, %esp
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NOSSE-NEXT:    movl (%eax), %ecx
-; X86-NOSSE-NEXT:    movl %ecx, (%esp)
-; X86-NOSSE-NEXT:    flds (%esp)
+; X86-NOSSE-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    flds {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fdivs {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    fstps (%esp)
+; X86-NOSSE-NEXT:    flds (%esp)
 ; X86-NOSSE-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; X86-NOSSE-NEXT:    movl %ecx, (%eax)
-; X86-NOSSE-NEXT:    addl $8, %esp
+; X86-NOSSE-NEXT:    addl $12, %esp
 ; X86-NOSSE-NEXT:    retl
 ;
 ; X86-SSE1-LABEL: fdiv_32r:
@@ -2205,7 +2291,7 @@ define dso_local void @fdiv_64r(ptr %loc, double %val) nounwind {
 ; X86-NOSSE-NEXT:    pushl %ebp
 ; X86-NOSSE-NEXT:    movl %esp, %ebp
 ; X86-NOSSE-NEXT:    andl $-8, %esp
-; X86-NOSSE-NEXT:    subl $24, %esp
+; X86-NOSSE-NEXT:    subl $32, %esp
 ; X86-NOSSE-NEXT:    movl 8(%ebp), %eax
 ; X86-NOSSE-NEXT:    fildll (%eax)
 ; X86-NOSSE-NEXT:    fistpll {{[0-9]+}}(%esp)
@@ -2215,6 +2301,8 @@ define dso_local void @fdiv_64r(ptr %loc, double %val) nounwind {
 ; X86-NOSSE-NEXT:    movl %ecx, (%esp)
 ; X86-NOSSE-NEXT:    fldl (%esp)
 ; X86-NOSSE-NEXT:    fdivl 12(%ebp)
+; X86-NOSSE-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fstpl (%eax)
 ; X86-NOSSE-NEXT:    movl %ebp, %esp
 ; X86-NOSSE-NEXT:    popl %ebp
@@ -2225,7 +2313,7 @@ define dso_local void @fdiv_64r(ptr %loc, double %val) nounwind {
 ; X86-SSE1-NEXT:    pushl %ebp
 ; X86-SSE1-NEXT:    movl %esp, %ebp
 ; X86-SSE1-NEXT:    andl $-8, %esp
-; X86-SSE1-NEXT:    subl $16, %esp
+; X86-SSE1-NEXT:    subl $24, %esp
 ; X86-SSE1-NEXT:    movl 8(%ebp), %eax
 ; X86-SSE1-NEXT:    xorps %xmm0, %xmm0
 ; X86-SSE1-NEXT:    movlps {{.*#+}} xmm0 = mem[0,1],xmm0[2,3]
@@ -2234,6 +2322,8 @@ define dso_local void @fdiv_64r(ptr %loc, double %val) nounwind {
 ; X86-SSE1-NEXT:    movss %xmm0, {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fldl (%esp)
 ; X86-SSE1-NEXT:    fdivl 12(%ebp)
+; X86-SSE1-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-SSE1-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fstpl (%eax)
 ; X86-SSE1-NEXT:    movl %ebp, %esp
 ; X86-SSE1-NEXT:    popl %ebp
@@ -2292,15 +2382,17 @@ define dso_local void @fdiv_64r(ptr %loc, double %val) nounwind {
 define dso_local void @fdiv_32g() nounwind {
 ; X86-NOSSE-LABEL: fdiv_32g:
 ; X86-NOSSE:       # %bb.0:
-; X86-NOSSE-NEXT:    subl $8, %esp
+; X86-NOSSE-NEXT:    subl $12, %esp
 ; X86-NOSSE-NEXT:    movl glob32, %eax
-; X86-NOSSE-NEXT:    movl %eax, (%esp)
-; X86-NOSSE-NEXT:    flds (%esp)
+; X86-NOSSE-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    flds {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fdivs {{\.?LCPI[0-9]+_[0-9]+}}
+; X86-NOSSE-NEXT:    fstps (%esp)
+; X86-NOSSE-NEXT:    flds (%esp)
 ; X86-NOSSE-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NOSSE-NEXT:    movl %eax, glob32
-; X86-NOSSE-NEXT:    addl $8, %esp
+; X86-NOSSE-NEXT:    addl $12, %esp
 ; X86-NOSSE-NEXT:    retl
 ;
 ; X86-SSE1-LABEL: fdiv_32g:
@@ -2357,7 +2449,7 @@ define dso_local void @fdiv_64g() nounwind {
 ; X86-NOSSE-NEXT:    pushl %ebp
 ; X86-NOSSE-NEXT:    movl %esp, %ebp
 ; X86-NOSSE-NEXT:    andl $-8, %esp
-; X86-NOSSE-NEXT:    subl $24, %esp
+; X86-NOSSE-NEXT:    subl $32, %esp
 ; X86-NOSSE-NEXT:    fildll glob64
 ; X86-NOSSE-NEXT:    fistpll {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
@@ -2366,6 +2458,8 @@ define dso_local void @fdiv_64g() nounwind {
 ; X86-NOSSE-NEXT:    movl %eax, (%esp)
 ; X86-NOSSE-NEXT:    fldl (%esp)
 ; X86-NOSSE-NEXT:    fdivs {{\.?LCPI[0-9]+_[0-9]+}}
+; X86-NOSSE-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fstpl glob64
 ; X86-NOSSE-NEXT:    movl %ebp, %esp
 ; X86-NOSSE-NEXT:    popl %ebp
@@ -2376,7 +2470,7 @@ define dso_local void @fdiv_64g() nounwind {
 ; X86-SSE1-NEXT:    pushl %ebp
 ; X86-SSE1-NEXT:    movl %esp, %ebp
 ; X86-SSE1-NEXT:    andl $-8, %esp
-; X86-SSE1-NEXT:    subl $16, %esp
+; X86-SSE1-NEXT:    subl $24, %esp
 ; X86-SSE1-NEXT:    xorps %xmm0, %xmm0
 ; X86-SSE1-NEXT:    movlps {{.*#+}} xmm0 = mem[0,1],xmm0[2,3]
 ; X86-SSE1-NEXT:    movss %xmm0, (%esp)
@@ -2384,6 +2478,8 @@ define dso_local void @fdiv_64g() nounwind {
 ; X86-SSE1-NEXT:    movss %xmm0, {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fldl (%esp)
 ; X86-SSE1-NEXT:    fdivs {{\.?LCPI[0-9]+_[0-9]+}}
+; X86-SSE1-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-SSE1-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fstpl glob64
 ; X86-SSE1-NEXT:    movl %ebp, %esp
 ; X86-SSE1-NEXT:    popl %ebp
@@ -2440,15 +2536,17 @@ define dso_local void @fdiv_64g() nounwind {
 define dso_local void @fdiv_32imm() nounwind {
 ; X86-NOSSE-LABEL: fdiv_32imm:
 ; X86-NOSSE:       # %bb.0:
-; X86-NOSSE-NEXT:    subl $8, %esp
+; X86-NOSSE-NEXT:    subl $12, %esp
 ; X86-NOSSE-NEXT:    movl -559038737, %eax
-; X86-NOSSE-NEXT:    movl %eax, (%esp)
-; X86-NOSSE-NEXT:    flds (%esp)
+; X86-NOSSE-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    flds {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fdivs {{\.?LCPI[0-9]+_[0-9]+}}
+; X86-NOSSE-NEXT:    fstps (%esp)
+; X86-NOSSE-NEXT:    flds (%esp)
 ; X86-NOSSE-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NOSSE-NEXT:    movl %eax, -559038737
-; X86-NOSSE-NEXT:    addl $8, %esp
+; X86-NOSSE-NEXT:    addl $12, %esp
 ; X86-NOSSE-NEXT:    retl
 ;
 ; X86-SSE1-LABEL: fdiv_32imm:
@@ -2507,7 +2605,7 @@ define dso_local void @fdiv_64imm() nounwind {
 ; X86-NOSSE-NEXT:    pushl %ebp
 ; X86-NOSSE-NEXT:    movl %esp, %ebp
 ; X86-NOSSE-NEXT:    andl $-8, %esp
-; X86-NOSSE-NEXT:    subl $24, %esp
+; X86-NOSSE-NEXT:    subl $32, %esp
 ; X86-NOSSE-NEXT:    fildll -559038737
 ; X86-NOSSE-NEXT:    fistpll {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
@@ -2516,6 +2614,8 @@ define dso_local void @fdiv_64imm() nounwind {
 ; X86-NOSSE-NEXT:    movl %eax, (%esp)
 ; X86-NOSSE-NEXT:    fldl (%esp)
 ; X86-NOSSE-NEXT:    fdivs {{\.?LCPI[0-9]+_[0-9]+}}
+; X86-NOSSE-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fstpl -559038737
 ; X86-NOSSE-NEXT:    movl %ebp, %esp
 ; X86-NOSSE-NEXT:    popl %ebp
@@ -2526,7 +2626,7 @@ define dso_local void @fdiv_64imm() nounwind {
 ; X86-SSE1-NEXT:    pushl %ebp
 ; X86-SSE1-NEXT:    movl %esp, %ebp
 ; X86-SSE1-NEXT:    andl $-8, %esp
-; X86-SSE1-NEXT:    subl $16, %esp
+; X86-SSE1-NEXT:    subl $24, %esp
 ; X86-SSE1-NEXT:    xorps %xmm0, %xmm0
 ; X86-SSE1-NEXT:    movlps {{.*#+}} xmm0 = mem[0,1],xmm0[2,3]
 ; X86-SSE1-NEXT:    movss %xmm0, (%esp)
@@ -2534,6 +2634,8 @@ define dso_local void @fdiv_64imm() nounwind {
 ; X86-SSE1-NEXT:    movss %xmm0, {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fldl (%esp)
 ; X86-SSE1-NEXT:    fdivs {{\.?LCPI[0-9]+_[0-9]+}}
+; X86-SSE1-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-SSE1-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fstpl -559038737
 ; X86-SSE1-NEXT:    movl %ebp, %esp
 ; X86-SSE1-NEXT:    popl %ebp
@@ -2592,15 +2694,17 @@ define dso_local void @fdiv_64imm() nounwind {
 define dso_local void @fdiv_32stack() nounwind {
 ; X86-NOSSE-LABEL: fdiv_32stack:
 ; X86-NOSSE:       # %bb.0:
-; X86-NOSSE-NEXT:    subl $12, %esp
+; X86-NOSSE-NEXT:    subl $16, %esp
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NOSSE-NEXT:    movl %eax, (%esp)
+; X86-NOSSE-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fld1
-; X86-NOSSE-NEXT:    fdivs (%esp)
+; X86-NOSSE-NEXT:    fdivs {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    fstps (%esp)
+; X86-NOSSE-NEXT:    flds (%esp)
 ; X86-NOSSE-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NOSSE-NEXT:    movl %eax, {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    addl $12, %esp
+; X86-NOSSE-NEXT:    addl $16, %esp
 ; X86-NOSSE-NEXT:    retl
 ;
 ; X86-SSE1-LABEL: fdiv_32stack:
@@ -2662,7 +2766,7 @@ define dso_local void @fdiv_64stack() nounwind {
 ; X86-NOSSE-NEXT:    pushl %ebp
 ; X86-NOSSE-NEXT:    movl %esp, %ebp
 ; X86-NOSSE-NEXT:    andl $-8, %esp
-; X86-NOSSE-NEXT:    subl $32, %esp
+; X86-NOSSE-NEXT:    subl $40, %esp
 ; X86-NOSSE-NEXT:    fildll {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fistpll {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
@@ -2672,6 +2776,8 @@ define dso_local void @fdiv_64stack() nounwind {
 ; X86-NOSSE-NEXT:    fld1
 ; X86-NOSSE-NEXT:    fdivl (%esp)
 ; X86-NOSSE-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    fldl {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    fstpl {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl %ebp, %esp
 ; X86-NOSSE-NEXT:    popl %ebp
 ; X86-NOSSE-NEXT:    retl
@@ -2681,7 +2787,7 @@ define dso_local void @fdiv_64stack() nounwind {
 ; X86-SSE1-NEXT:    pushl %ebp
 ; X86-SSE1-NEXT:    movl %esp, %ebp
 ; X86-SSE1-NEXT:    andl $-8, %esp
-; X86-SSE1-NEXT:    subl $24, %esp
+; X86-SSE1-NEXT:    subl $32, %esp
 ; X86-SSE1-NEXT:    xorps %xmm0, %xmm0
 ; X86-SSE1-NEXT:    movlps {{.*#+}} xmm0 = mem[0,1],xmm0[2,3]
 ; X86-SSE1-NEXT:    movss %xmm0, (%esp)
@@ -2690,6 +2796,8 @@ define dso_local void @fdiv_64stack() nounwind {
 ; X86-SSE1-NEXT:    fld1
 ; X86-SSE1-NEXT:    fdivl (%esp)
 ; X86-SSE1-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-SSE1-NEXT:    fldl {{[0-9]+}}(%esp)
+; X86-SSE1-NEXT:    fstpl {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    movl %ebp, %esp
 ; X86-SSE1-NEXT:    popl %ebp
 ; X86-SSE1-NEXT:    retl
@@ -2751,7 +2859,7 @@ define dso_local void @fdiv_array(ptr %arg, double %arg1, i64 %arg2) nounwind {
 ; X86-NOSSE-NEXT:    movl %esp, %ebp
 ; X86-NOSSE-NEXT:    pushl %esi
 ; X86-NOSSE-NEXT:    andl $-8, %esp
-; X86-NOSSE-NEXT:    subl $32, %esp
+; X86-NOSSE-NEXT:    subl $40, %esp
 ; X86-NOSSE-NEXT:    movl 20(%ebp), %eax
 ; X86-NOSSE-NEXT:    movl 8(%ebp), %ecx
 ; X86-NOSSE-NEXT:    fildll (%ecx,%eax,8)
@@ -2762,6 +2870,8 @@ define dso_local void @fdiv_array(ptr %arg, double %arg1, i64 %arg2) nounwind {
 ; X86-NOSSE-NEXT:    movl %edx, (%esp)
 ; X86-NOSSE-NEXT:    fldl (%esp)
 ; X86-NOSSE-NEXT:    fdivl 12(%ebp)
+; X86-NOSSE-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fstpl (%ecx,%eax,8)
 ; X86-NOSSE-NEXT:    leal -4(%ebp), %esp
 ; X86-NOSSE-NEXT:    popl %esi
@@ -2773,7 +2883,7 @@ define dso_local void @fdiv_array(ptr %arg, double %arg1, i64 %arg2) nounwind {
 ; X86-SSE1-NEXT:    pushl %ebp
 ; X86-SSE1-NEXT:    movl %esp, %ebp
 ; X86-SSE1-NEXT:    andl $-8, %esp
-; X86-SSE1-NEXT:    subl $16, %esp
+; X86-SSE1-NEXT:    subl $24, %esp
 ; X86-SSE1-NEXT:    movl 20(%ebp), %eax
 ; X86-SSE1-NEXT:    movl 8(%ebp), %ecx
 ; X86-SSE1-NEXT:    xorps %xmm0, %xmm0
@@ -2783,6 +2893,8 @@ define dso_local void @fdiv_array(ptr %arg, double %arg1, i64 %arg2) nounwind {
 ; X86-SSE1-NEXT:    movss %xmm0, {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fldl (%esp)
 ; X86-SSE1-NEXT:    fdivl 12(%ebp)
+; X86-SSE1-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-SSE1-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fstpl (%ecx,%eax,8)
 ; X86-SSE1-NEXT:    movl %ebp, %esp
 ; X86-SSE1-NEXT:    popl %ebp
diff --git a/llvm/test/CodeGen/X86/bfloat-int64-cvt-i686.ll b/llvm/test/CodeGen/X86/bfloat-int64-cvt-i686.ll
index a205dcb8987eb..b829b4128d107 100644
--- a/llvm/test/CodeGen/X86/bfloat-int64-cvt-i686.ll
+++ b/llvm/test/CodeGen/X86/bfloat-int64-cvt-i686.ll
@@ -132,6 +132,8 @@ define bfloat @uitofp_i64_to_bf16(i64 %a) nounwind {
 ; X87-NEXT:    shrl $31, %ecx
 ; X87-NEXT:    fildll {{[0-9]+}}(%esp)
 ; X87-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}(,%ecx,4)
+; X87-NEXT:    fstps {{[0-9]+}}(%esp)
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    fstps (%esp)
 ; X87-NEXT:    calll __truncsfbf2
 ; X87-NEXT:    # kill: def $ax killed $ax def $eax
@@ -201,6 +203,8 @@ define bfloat @uitofp_load_i64_to_bf16(ptr %p) nounwind {
 ; X87-NEXT:    shrl $31, %eax
 ; X87-NEXT:    fildll {{[0-9]+}}(%esp)
 ; X87-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}(,%eax,4)
+; X87-NEXT:    fstps {{[0-9]+}}(%esp)
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    fstps (%esp)
 ; X87-NEXT:    calll __truncsfbf2
 ; X87-NEXT:    # kill: def $ax killed $ax def $eax
diff --git a/llvm/test/CodeGen/X86/canonicalize-vars.ll b/llvm/test/CodeGen/X86/canonicalize-vars.ll
index 4e53d1e20a670..51e5ae395a90c 100644
--- a/llvm/test/CodeGen/X86/canonicalize-vars.ll
+++ b/llvm/test/CodeGen/X86/canonicalize-vars.ll
@@ -174,15 +174,10 @@ entry:
 define double @canonicalize_fp64(double %a, double %b) unnamed_addr #0 {
 ; X87-LABEL: canonicalize_fp64:
 ; X87:       # %bb.0: # %start
-; X87-NEXT:    pushl %ebp
-; X87-NEXT:    .cfi_def_cfa_offset 8
-; X87-NEXT:    .cfi_offset %ebp, -8
-; X87-NEXT:    movl %esp, %ebp
-; X87-NEXT:    .cfi_def_cfa_register %ebp
-; X87-NEXT:    andl $-8, %esp
 ; X87-NEXT:    subl $8, %esp
-; X87-NEXT:    fldl 8(%ebp)
-; X87-NEXT:    fldl 16(%ebp)
+; X87-NEXT:    .cfi_def_cfa_offset 12
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    fucom %st(1)
 ; X87-NEXT:    fnstsw %ax
 ; X87-NEXT:    # kill: def $ah killed $ah killed $ax
@@ -210,9 +205,8 @@ define double @canonicalize_fp64(double %a, double %b) unnamed_addr #0 {
 ; X87-NEXT:    fmulp %st, %st(1)
 ; X87-NEXT:    fstpl (%esp)
 ; X87-NEXT:    fldl (%esp)
-; X87-NEXT:    movl %ebp, %esp
-; X87-NEXT:    popl %ebp
-; X87-NEXT:    .cfi_def_cfa %esp, 4
+; X87-NEXT:    addl $8, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl
 ;
 ; X86-SSE-LABEL: canonicalize_fp64:
@@ -530,23 +524,17 @@ define void @v_test_canonicalize_x86_fp80(x86_fp80 addrspace(1)* %out) #1 {
 define void @v_test_canonicalize_var_f64(double addrspace(1)* %out) #1 {
 ; X87-LABEL: v_test_canonicalize_var_f64:
 ; X87:       # %bb.0:
-; X87-NEXT:    pushl %ebp
-; X87-NEXT:    .cfi_def_cfa_offset 8
-; X87-NEXT:    .cfi_offset %ebp, -8
-; X87-NEXT:    movl %esp, %ebp
-; X87-NEXT:    .cfi_def_cfa_register %ebp
-; X87-NEXT:    andl $-8, %esp
 ; X87-NEXT:    subl $8, %esp
-; X87-NEXT:    movl 8(%ebp), %eax
+; X87-NEXT:    .cfi_def_cfa_offset 12
+; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X87-NEXT:    fldl (%eax)
 ; X87-NEXT:    fld1
 ; X87-NEXT:    fmulp %st, %st(1)
 ; X87-NEXT:    fstpl (%esp)
 ; X87-NEXT:    fldl (%esp)
 ; X87-NEXT:    fstpl (%eax)
-; X87-NEXT:    movl %ebp, %esp
-; X87-NEXT:    popl %ebp
-; X87-NEXT:    .cfi_def_cfa %esp, 4
+; X87-NEXT:    addl $8, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl
 ;
 ; X86-SSE-LABEL: v_test_canonicalize_var_f64:
@@ -635,7 +623,7 @@ define <4 x float> @canon_fp32_varargsv4f32(<4 x float> %a) {
 ; X87-NEXT:    fld1
 ; X87-NEXT:    fmul %st, %st(1)
 ; X87-NEXT:    fxch %st(1)
-; X87-NEXT:    fstps {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps (%esp)
 ; X87-NEXT:    fmul %st, %st(1)
 ; X87-NEXT:    fxch %st(1)
 ; X87-NEXT:    fstps {{[0-9]+}}(%esp)
@@ -643,11 +631,11 @@ define <4 x float> @canon_fp32_varargsv4f32(<4 x float> %a) {
 ; X87-NEXT:    fxch %st(1)
 ; X87-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X87-NEXT:    fmulp %st, %st(1)
-; X87-NEXT:    fstps (%esp)
+; X87-NEXT:    fstps {{[0-9]+}}(%esp)
+; X87-NEXT:    flds (%esp)
 ; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    flds {{[0-9]+}}(%esp)
-; X87-NEXT:    flds (%esp)
 ; X87-NEXT:    fstps 12(%eax)
 ; X87-NEXT:    fstps 8(%eax)
 ; X87-NEXT:    fstps 4(%eax)
@@ -694,22 +682,17 @@ define <4 x float> @canon_fp32_varargsv4f32(<4 x float> %a) {
 define <4 x double> @canon_fp64_varargsv4f64(<4 x double> %a) {
 ; X87-LABEL: canon_fp64_varargsv4f64:
 ; X87:       # %bb.0:
-; X87-NEXT:    pushl %ebp
-; X87-NEXT:    .cfi_def_cfa_offset 8
-; X87-NEXT:    .cfi_offset %ebp, -8
-; X87-NEXT:    movl %esp, %ebp
-; X87-NEXT:    .cfi_def_cfa_register %ebp
-; X87-NEXT:    andl $-8, %esp
 ; X87-NEXT:    subl $32, %esp
-; X87-NEXT:    movl 8(%ebp), %eax
-; X87-NEXT:    fldl 36(%ebp)
-; X87-NEXT:    fldl 28(%ebp)
-; X87-NEXT:    fldl 20(%ebp)
-; X87-NEXT:    fldl 12(%ebp)
+; X87-NEXT:    .cfi_def_cfa_offset 36
+; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    fld1
 ; X87-NEXT:    fmul %st, %st(1)
 ; X87-NEXT:    fxch %st(1)
-; X87-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X87-NEXT:    fstpl (%esp)
 ; X87-NEXT:    fmul %st, %st(1)
 ; X87-NEXT:    fxch %st(1)
 ; X87-NEXT:    fstpl {{[0-9]+}}(%esp)
@@ -717,18 +700,17 @@ define <4 x double> @canon_fp64_varargsv4f64(<4 x double> %a) {
 ; X87-NEXT:    fxch %st(1)
 ; X87-NEXT:    fstpl {{[0-9]+}}(%esp)
 ; X87-NEXT:    fmulp %st, %st(1)
-; X87-NEXT:    fstpl (%esp)
+; X87-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X87-NEXT:    fldl (%esp)
 ; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    fldl {{[0-9]+}}(%esp)
-; X87-NEXT:    fldl (%esp)
 ; X87-NEXT:    fstpl 24(%eax)
 ; X87-NEXT:    fstpl 16(%eax)
 ; X87-NEXT:    fstpl 8(%eax)
 ; X87-NEXT:    fstpl (%eax)
-; X87-NEXT:    movl %ebp, %esp
-; X87-NEXT:    popl %ebp
-; X87-NEXT:    .cfi_def_cfa %esp, 4
+; X87-NEXT:    addl $32, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl $4
 ;
 ; X86-SSE-LABEL: canon_fp64_varargsv4f64:
@@ -837,18 +819,18 @@ define void @vec_canonicalize_var_v4f32(<4 x float> addrspace(1)* %out) #1 {
 ; X87-NEXT:    fld1
 ; X87-NEXT:    fmul %st, %st(1)
 ; X87-NEXT:    fxch %st(1)
-; X87-NEXT:    fstps {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps (%esp)
 ; X87-NEXT:    fmul %st, %st(1)
 ; X87-NEXT:    fxch %st(1)
 ; X87-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X87-NEXT:    fmul %st, %st(1)
 ; X87-NEXT:    fxch %st(1)
-; X87-NEXT:    fstps (%esp)
+; X87-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X87-NEXT:    fmulp %st, %st(1)
 ; X87-NEXT:    fstps {{[0-9]+}}(%esp)
+; X87-NEXT:    flds (%esp)
 ; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    flds {{[0-9]+}}(%esp)
-; X87-NEXT:    flds (%esp)
 ; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    fstps 12(%eax)
 ; X87-NEXT:    fstps 8(%eax)
@@ -910,14 +892,9 @@ define void @vec_canonicalize_var_v4f32(<4 x float> addrspace(1)* %out) #1 {
 define void @vec_canonicalize_var_v4f64(<4 x double> addrspace(1)* %out) #1 {
 ; X87-LABEL: vec_canonicalize_var_v4f64:
 ; X87:       # %bb.0:
-; X87-NEXT:    pushl %ebp
-; X87-NEXT:    .cfi_def_cfa_offset 8
-; X87-NEXT:    .cfi_offset %ebp, -8
-; X87-NEXT:    movl %esp, %ebp
-; X87-NEXT:    .cfi_def_cfa_register %ebp
-; X87-NEXT:    andl $-8, %esp
 ; X87-NEXT:    subl $32, %esp
-; X87-NEXT:    movl 8(%ebp), %eax
+; X87-NEXT:    .cfi_def_cfa_offset 36
+; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X87-NEXT:    fldl 24(%eax)
 ; X87-NEXT:    fldl 16(%eax)
 ; X87-NEXT:    fldl 8(%eax)
@@ -925,26 +902,25 @@ define void @vec_canonicalize_var_v4f64(<4 x double> addrspace(1)* %out) #1 {
 ; X87-NEXT:    fld1
 ; X87-NEXT:    fmul %st, %st(1)
 ; X87-NEXT:    fxch %st(1)
-; X87-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X87-NEXT:    fstpl (%esp)
 ; X87-NEXT:    fmul %st, %st(1)
 ; X87-NEXT:    fxch %st(1)
 ; X87-NEXT:    fstpl {{[0-9]+}}(%esp)
 ; X87-NEXT:    fmul %st, %st(1)
 ; X87-NEXT:    fxch %st(1)
-; X87-NEXT:    fstpl (%esp)
+; X87-NEXT:    fstpl {{[0-9]+}}(%esp)
 ; X87-NEXT:    fmulp %st, %st(1)
 ; X87-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X87-NEXT:    fldl (%esp)
 ; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    fldl {{[0-9]+}}(%esp)
-; X87-NEXT:    fldl (%esp)
 ; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    fstpl 24(%eax)
 ; X87-NEXT:    fstpl 16(%eax)
 ; X87-NEXT:    fstpl 8(%eax)
 ; X87-NEXT:    fstpl (%eax)
-; X87-NEXT:    movl %ebp, %esp
-; X87-NEXT:    popl %ebp
-; X87-NEXT:    .cfi_def_cfa %esp, 4
+; X87-NEXT:    addl $32, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl
 ;
 ; X86-SSE-LABEL: vec_canonicalize_var_v4f64:
diff --git a/llvm/test/CodeGen/X86/fmf-flags.ll b/llvm/test/CodeGen/X86/fmf-flags.ll
index bd71da43eaeb0..29920eedc21e5 100644
--- a/llvm/test/CodeGen/X86/fmf-flags.ll
+++ b/llvm/test/CodeGen/X86/fmf-flags.ll
@@ -17,15 +17,16 @@ define dso_local float @fast_recip_sqrt(float %x) {
 ;
 ; X86-LABEL: fast_recip_sqrt:
 ; X86:       # %bb.0:
-; X86-NEXT:    pushl %eax
-; X86-NEXT:    .cfi_def_cfa_offset 8
+; X86-NEXT:    subl $8, %esp
+; X86-NEXT:    .cfi_def_cfa_offset 12
 ; X86-NEXT:    flds {{[0-9]+}}(%esp)
 ; X86-NEXT:    fsqrt
+; X86-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-NEXT:    fld1
-; X86-NEXT:    fdivp %st, %st(1)
+; X86-NEXT:    fdivs {{[0-9]+}}(%esp)
 ; X86-NEXT:    fstps (%esp)
 ; X86-NEXT:    flds (%esp)
-; X86-NEXT:    popl %eax
+; X86-NEXT:    addl $8, %esp
 ; X86-NEXT:    .cfi_def_cfa_offset 4
 ; X86-NEXT:    retl
   %y = call fast float @llvm.sqrt.f32(float %x)
@@ -71,25 +72,21 @@ define dso_local double @not_so_fast_mul_add(double %x) {
 ;
 ; X86-LABEL: not_so_fast_mul_add:
 ; X86:       # %bb.0:
-; X86-NEXT:    pushl %ebp
-; X86-NEXT:    .cfi_def_cfa_offset 8
-; X86-NEXT:    .cfi_offset %ebp, -8
-; X86-NEXT:    movl %esp, %ebp
-; X86-NEXT:    .cfi_def_cfa_register %ebp
-; X86-NEXT:    andl $-8, %esp
-; X86-NEXT:    subl $8, %esp
-; X86-NEXT:    fldl 8(%ebp)
+; X86-NEXT:    subl $16, %esp
+; X86-NEXT:    .cfi_def_cfa_offset 20
+; X86-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-NEXT:    fld %st(0)
 ; X86-NEXT:    fmull {{\.?LCPI[0-9]+_[0-9]+}}
-; X86-NEXT:    fxch %st(1)
-; X86-NEXT:    fmull {{\.?LCPI[0-9]+_[0-9]+}}
 ; X86-NEXT:    fstpl (%esp)
 ; X86-NEXT:    fldl (%esp)
 ; X86-NEXT:    fxch %st(1)
+; X86-NEXT:    fmull {{\.?LCPI[0-9]+_[0-9]+}}
+; X86-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-NEXT:    fldl {{[0-9]+}}(%esp)
+; X86-NEXT:    fxch %st(1)
 ; X86-NEXT:    fstpl mul1
-; X86-NEXT:    movl %ebp, %esp
-; X86-NEXT:    popl %ebp
-; X86-NEXT:    .cfi_def_cfa %esp, 4
+; X86-NEXT:    addl $16, %esp
+; X86-NEXT:    .cfi_def_cfa_offset 4
 ; X86-NEXT:    retl
   %m = fmul double %x, 4.2
   %a = fadd fast double %m, %x
@@ -120,12 +117,12 @@ define dso_local float @not_so_fast_recip_sqrt(float %x) {
 ; X86-NEXT:    .cfi_def_cfa_offset 12
 ; X86-NEXT:    flds {{[0-9]+}}(%esp)
 ; X86-NEXT:    fsqrt
-; X86-NEXT:    fstps (%esp)
-; X86-NEXT:    flds (%esp)
-; X86-NEXT:    fld1
-; X86-NEXT:    fdiv %st(1), %st
 ; X86-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-NEXT:    flds {{[0-9]+}}(%esp)
+; X86-NEXT:    fld1
+; X86-NEXT:    fdiv %st(1), %st
+; X86-NEXT:    fstps (%esp)
+; X86-NEXT:    flds (%esp)
 ; X86-NEXT:    fxch %st(1)
 ; X86-NEXT:    fstps sqrt1
 ; X86-NEXT:    addl $8, %esp
@@ -152,18 +149,20 @@ define dso_local float @div_arcp_by_const(half %x) {
 ;
 ; X86-LABEL: div_arcp_by_const:
 ; X86:       # %bb.0:
-; X86-NEXT:    pushl %eax
-; X86-NEXT:    .cfi_def_cfa_offset 8
+; X86-NEXT:    subl $8, %esp
+; X86-NEXT:    .cfi_def_cfa_offset 12
 ; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
 ; X86-NEXT:    movl %eax, (%esp)
 ; X86-NEXT:    calll __extendhfsf2
 ; X86-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
+; X86-NEXT:    fstps {{[0-9]+}}(%esp)
+; X86-NEXT:    flds {{[0-9]+}}(%esp)
 ; X86-NEXT:    fstps (%esp)
 ; X86-NEXT:    calll __truncsfhf2
 ; X86-NEXT:    movzwl %ax, %eax
 ; X86-NEXT:    movl %eax, (%esp)
 ; X86-NEXT:    calll __extendhfsf2
-; X86-NEXT:    popl %eax
+; X86-NEXT:    addl $8, %esp
 ; X86-NEXT:    .cfi_def_cfa_offset 4
 ; X86-NEXT:    retl
   %rcp = fdiv arcp half %x, 10.0
diff --git a/llvm/test/CodeGen/X86/fminimum-fmaximum-i686.ll b/llvm/test/CodeGen/X86/fminimum-fmaximum-i686.ll
index 7021b7fcef085..8ad3840712019 100644
--- a/llvm/test/CodeGen/X86/fminimum-fmaximum-i686.ll
+++ b/llvm/test/CodeGen/X86/fminimum-fmaximum-i686.ll
@@ -122,10 +122,10 @@ define double @maximum_double(double %x, double %y) nounwind {
 ; CHECK-NEXT:    subl $8, %esp
 ; CHECK-NEXT:    fldl {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    fldl {{[0-9]+}}(%esp)
-; CHECK-NEXT:    fsts (%esp)
-; CHECK-NEXT:    flds (%esp)
-; CHECK-NEXT:    fstps {{[0-9]+}}(%esp)
-; CHECK-NEXT:    cmpl $0, {{[0-9]+}}(%esp)
+; CHECK-NEXT:    fsts {{[0-9]+}}(%esp)
+; CHECK-NEXT:    flds {{[0-9]+}}(%esp)
+; CHECK-NEXT:    fstps (%esp)
+; CHECK-NEXT:    cmpl $0, (%esp)
 ; CHECK-NEXT:    fld %st(0)
 ; CHECK-NEXT:    je .LBB2_2
 ; CHECK-NEXT:  # %bb.1:
@@ -301,11 +301,11 @@ define double @minimum_double(double %x, double %y) nounwind {
 ; CHECK-NEXT:    subl $8, %esp
 ; CHECK-NEXT:    fldl {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    fldl {{[0-9]+}}(%esp)
-; CHECK-NEXT:    fsts (%esp)
-; CHECK-NEXT:    flds (%esp)
-; CHECK-NEXT:    fstps {{[0-9]+}}(%esp)
+; CHECK-NEXT:    fsts {{[0-9]+}}(%esp)
+; CHECK-NEXT:    flds {{[0-9]+}}(%esp)
+; CHECK-NEXT:    fstps (%esp)
 ; CHECK-NEXT:    xorl %eax, %eax
-; CHECK-NEXT:    cmpl {{[0-9]+}}(%esp), %eax
+; CHECK-NEXT:    cmpl (%esp), %eax
 ; CHECK-NEXT:    fld %st(0)
 ; CHECK-NEXT:    jo .LBB5_2
 ; CHECK-NEXT:  # %bb.1:
diff --git a/llvm/test/CodeGen/X86/fp-intrinsics.ll b/llvm/test/CodeGen/X86/fp-intrinsics.ll
index 9a5e678a1d85f..176acb891c22f 100644
--- a/llvm/test/CodeGen/X86/fp-intrinsics.ll
+++ b/llvm/test/CodeGen/X86/fp-intrinsics.ll
@@ -17,15 +17,15 @@
 define double @f1() #0 {
 ; X87-LABEL: f1:
 ; X87:       # %bb.0: # %entry
-; X87-NEXT:    subl $12, %esp
-; X87-NEXT:    .cfi_def_cfa_offset 16
+; X87-NEXT:    subl $8, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 12
 ; X87-NEXT:    flds {{\.?LCPI[0-9]+_[0-9]+}}
 ; X87-NEXT:    fld1
 ; X87-NEXT:    fdivp %st, %st(1)
 ; X87-NEXT:    fstpl (%esp)
 ; X87-NEXT:    fldl (%esp)
 ; X87-NEXT:    wait
-; X87-NEXT:    addl $12, %esp
+; X87-NEXT:    addl $8, %esp
 ; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl
 ;
@@ -73,15 +73,15 @@ entry:
 define double @f2(double %a) #0 {
 ; X87-LABEL: f2:
 ; X87:       # %bb.0: # %entry
-; X87-NEXT:    subl $12, %esp
-; X87-NEXT:    .cfi_def_cfa_offset 16
+; X87-NEXT:    subl $8, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 12
 ; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    fldz
 ; X87-NEXT:    fsubrp %st, %st(1)
 ; X87-NEXT:    fstpl (%esp)
 ; X87-NEXT:    fldl (%esp)
 ; X87-NEXT:    wait
-; X87-NEXT:    addl $12, %esp
+; X87-NEXT:    addl $8, %esp
 ; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl
 ;
@@ -131,25 +131,25 @@ entry:
 define double @f3(double %a, double %b) #0 {
 ; X87-LABEL: f3:
 ; X87:       # %bb.0: # %entry
-; X87-NEXT:    subl $28, %esp
-; X87-NEXT:    .cfi_def_cfa_offset 32
+; X87-NEXT:    subl $24, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 28
 ; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    fldz
 ; X87-NEXT:    fchs
 ; X87-NEXT:    fsub %st, %st(1)
 ; X87-NEXT:    fxch %st(1)
-; X87-NEXT:    fstpl (%esp)
-; X87-NEXT:    fldl (%esp)
+; X87-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    fmulp %st, %st(2)
 ; X87-NEXT:    fxch %st(1)
 ; X87-NEXT:    fstpl {{[0-9]+}}(%esp)
 ; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    fsubrp %st, %st(1)
-; X87-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X87-NEXT:    fldl {{[0-9]+}}(%esp)
+; X87-NEXT:    fstpl (%esp)
+; X87-NEXT:    fldl (%esp)
 ; X87-NEXT:    wait
-; X87-NEXT:    addl $28, %esp
+; X87-NEXT:    addl $24, %esp
 ; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl
 ;
@@ -217,8 +217,8 @@ entry:
 define double @f4(i32 %n, double %a) #0 {
 ; X87-LABEL: f4:
 ; X87:       # %bb.0: # %entry
-; X87-NEXT:    subl $12, %esp
-; X87-NEXT:    .cfi_def_cfa_offset 16
+; X87-NEXT:    subl $8, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 12
 ; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    wait
 ; X87-NEXT:    cmpl $0, {{[0-9]+}}(%esp)
@@ -230,7 +230,7 @@ define double @f4(i32 %n, double %a) #0 {
 ; X87-NEXT:    fldl (%esp)
 ; X87-NEXT:    wait
 ; X87-NEXT:  .LBB3_2: # %if.end
-; X87-NEXT:    addl $12, %esp
+; X87-NEXT:    addl $8, %esp
 ; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl
 ;
@@ -288,14 +288,14 @@ if.end:
 define double @f5() #0 {
 ; X87-LABEL: f5:
 ; X87:       # %bb.0: # %entry
-; X87-NEXT:    subl $12, %esp
-; X87-NEXT:    .cfi_def_cfa_offset 16
+; X87-NEXT:    subl $8, %esp
+; X87-NEXT:    .cfi_def_cfa_offset 12
 ; X87-NEXT:    flds {{\.?LCPI[0-9]+_[0-9]+}}
 ; X87-NEXT:    fsqrt
 ; X87-NEXT:    fstpl (%esp)
 ; X87-NEXT:    fldl (%esp)
 ; X87-NEXT:    wait
-; X87-NEXT:    addl $12, %esp
+; X87-NEXT:    addl $8, %esp
 ; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl
 ;
diff --git a/llvm/test/CodeGen/X86/fp-strict-scalar.ll b/llvm/test/CodeGen/X86/fp-strict-scalar.ll
index c04c6f5b5c279..25f6a0aec84dd 100644
--- a/llvm/test/CodeGen/X86/fp-strict-scalar.ll
+++ b/llvm/test/CodeGen/X86/fp-strict-scalar.ll
@@ -65,18 +65,14 @@ define double @fadd_f64(double %a, double %b) nounwind strictfp {
 ;
 ; X87-LABEL: fadd_f64:
 ; X87:       # %bb.0:
-; X87-NEXT:    pushl %ebp
-; X87-NEXT:    movl %esp, %ebp
-; X87-NEXT:    andl $-8, %esp
 ; X87-NEXT:    subl $8, %esp
-; X87-NEXT:    fldl 8(%ebp)
-; X87-NEXT:    fldl 16(%ebp)
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    faddp %st, %st(1)
 ; X87-NEXT:    fstpl (%esp)
 ; X87-NEXT:    fldl (%esp)
 ; X87-NEXT:    wait
-; X87-NEXT:    movl %ebp, %esp
-; X87-NEXT:    popl %ebp
+; X87-NEXT:    addl $8, %esp
 ; X87-NEXT:    retl
   %ret = call double @llvm.experimental.constrained.fadd.f64(double %a, double %b,
                                                              metadata !"round.dynamic",
@@ -177,18 +173,14 @@ define double @fsub_f64(double %a, double %b) nounwind strictfp {
 ;
 ; X87-LABEL: fsub_f64:
 ; X87:       # %bb.0:
-; X87-NEXT:    pushl %ebp
-; X87-NEXT:    movl %esp, %ebp
-; X87-NEXT:    andl $-8, %esp
 ; X87-NEXT:    subl $8, %esp
-; X87-NEXT:    fldl 8(%ebp)
-; X87-NEXT:    fldl 16(%ebp)
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    fsubrp %st, %st(1)
 ; X87-NEXT:    fstpl (%esp)
 ; X87-NEXT:    fldl (%esp)
 ; X87-NEXT:    wait
-; X87-NEXT:    movl %ebp, %esp
-; X87-NEXT:    popl %ebp
+; X87-NEXT:    addl $8, %esp
 ; X87-NEXT:    retl
   %ret = call double @llvm.experimental.constrained.fsub.f64(double %a, double %b,
                                                              metadata !"round.dynamic",
@@ -289,18 +281,14 @@ define double @fmul_f64(double %a, double %b) nounwind strictfp {
 ;
 ; X87-LABEL: fmul_f64:
 ; X87:       # %bb.0:
-; X87-NEXT:    pushl %ebp
-; X87-NEXT:    movl %esp, %ebp
-; X87-NEXT:    andl $-8, %esp
 ; X87-NEXT:    subl $8, %esp
-; X87-NEXT:    fldl 8(%ebp)
-; X87-NEXT:    fldl 16(%ebp)
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    fmulp %st, %st(1)
 ; X87-NEXT:    fstpl (%esp)
 ; X87-NEXT:    fldl (%esp)
 ; X87-NEXT:    wait
-; X87-NEXT:    movl %ebp, %esp
-; X87-NEXT:    popl %ebp
+; X87-NEXT:    addl $8, %esp
 ; X87-NEXT:    retl
   %ret = call double @llvm.experimental.constrained.fmul.f64(double %a, double %b,
                                                              metadata !"round.dynamic",
@@ -401,18 +389,14 @@ define double @fdiv_f64(double %a, double %b) nounwind strictfp {
 ;
 ; X87-LABEL: fdiv_f64:
 ; X87:       # %bb.0:
-; X87-NEXT:    pushl %ebp
-; X87-NEXT:    movl %esp, %ebp
-; X87-NEXT:    andl $-8, %esp
 ; X87-NEXT:    subl $8, %esp
-; X87-NEXT:    fldl 8(%ebp)
-; X87-NEXT:    fldl 16(%ebp)
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    fdivrp %st, %st(1)
 ; X87-NEXT:    fstpl (%esp)
 ; X87-NEXT:    fldl (%esp)
 ; X87-NEXT:    wait
-; X87-NEXT:    movl %ebp, %esp
-; X87-NEXT:    popl %ebp
+; X87-NEXT:    addl $8, %esp
 ; X87-NEXT:    retl
   %ret = call double @llvm.experimental.constrained.fdiv.f64(double %a, double %b,
                                                              metadata !"round.dynamic",
@@ -604,19 +588,15 @@ define void @fsqrt_f64(ptr %a) nounwind strictfp {
 ;
 ; X87-LABEL: fsqrt_f64:
 ; X87:       # %bb.0:
-; X87-NEXT:    pushl %ebp
-; X87-NEXT:    movl %esp, %ebp
-; X87-NEXT:    andl $-8, %esp
 ; X87-NEXT:    subl $8, %esp
-; X87-NEXT:    movl 8(%ebp), %eax
+; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X87-NEXT:    fldl (%eax)
 ; X87-NEXT:    fsqrt
 ; X87-NEXT:    fstpl (%esp)
 ; X87-NEXT:    fldl (%esp)
 ; X87-NEXT:    fstpl (%eax)
 ; X87-NEXT:    wait
-; X87-NEXT:    movl %ebp, %esp
-; X87-NEXT:    popl %ebp
+; X87-NEXT:    addl $8, %esp
 ; X87-NEXT:    retl
   %1 = load double, ptr %a, align 8
   %res = call double @llvm.experimental.constrained.sqrt.f64(double %1,
diff --git a/llvm/test/CodeGen/X86/fp80-strict-scalar.ll b/llvm/test/CodeGen/X86/fp80-strict-scalar.ll
index b9b1ae60d479e..926747adcdc71 100644
--- a/llvm/test/CodeGen/X86/fp80-strict-scalar.ll
+++ b/llvm/test/CodeGen/X86/fp80-strict-scalar.ll
@@ -183,16 +183,12 @@ define float @fptrunc_fp80_to_f32(x86_fp80 %a) nounwind strictfp {
 define double @fptrunc_fp80_to_f64(x86_fp80 %a) nounwind strictfp {
 ; X86-LABEL: fptrunc_fp80_to_f64:
 ; X86:       # %bb.0:
-; X86-NEXT:    pushl %ebp
-; X86-NEXT:    movl %esp, %ebp
-; X86-NEXT:    andl $-8, %esp
 ; X86-NEXT:    subl $8, %esp
-; X86-NEXT:    fldt 8(%ebp)
+; X86-NEXT:    fldt {{[0-9]+}}(%esp)
 ; X86-NEXT:    fstpl (%esp)
 ; X86-NEXT:    fldl (%esp)
 ; X86-NEXT:    wait
-; X86-NEXT:    movl %ebp, %esp
-; X86-NEXT:    popl %ebp
+; X86-NEXT:    addl $8, %esp
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: fptrunc_fp80_to_f64:
diff --git a/llvm/test/CodeGen/X86/fp_constant_op.ll b/llvm/test/CodeGen/X86/fp_constant_op.ll
index df69e6aa2fdd1..d325b0a844322 100644
--- a/llvm/test/CodeGen/X86/fp_constant_op.ll
+++ b/llvm/test/CodeGen/X86/fp_constant_op.ll
@@ -7,20 +7,14 @@
 define double @foo_add(double %P) {
 ; CHECK-LABEL: foo_add:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    push ebp
-; CHECK-NEXT:    .cfi_def_cfa_offset 8
-; CHECK-NEXT:    .cfi_offset ebp, -8
-; CHECK-NEXT:    mov ebp, esp
-; CHECK-NEXT:    .cfi_def_cfa_register ebp
-; CHECK-NEXT:    and esp, -8
 ; CHECK-NEXT:    sub esp, 8
-; CHECK-NEXT:    fld qword ptr [ebp + 8]
+; CHECK-NEXT:    .cfi_def_cfa_offset 12
+; CHECK-NEXT:    fld qword ptr [esp + 12]
 ; CHECK-NEXT:    fadd dword ptr [{{\.?LCPI[0-9]+_[0-9]+}}]
 ; CHECK-NEXT:    fstp qword ptr [esp]
 ; CHECK-NEXT:    fld qword ptr [esp]
-; CHECK-NEXT:    mov esp, ebp
-; CHECK-NEXT:    pop ebp
-; CHECK-NEXT:    .cfi_def_cfa esp, 4
+; CHECK-NEXT:    add esp, 8
+; CHECK-NEXT:    .cfi_def_cfa_offset 4
 ; CHECK-NEXT:    ret
 	%tmp.1 = fadd double %P, 1.230000e+02		; <double> [#uses=1]
 	ret double %tmp.1
@@ -29,20 +23,14 @@ define double @foo_add(double %P) {
 define double @foo_mul(double %P) {
 ; CHECK-LABEL: foo_mul:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    push ebp
-; CHECK-NEXT:    .cfi_def_cfa_offset 8
-; CHECK-NEXT:    .cfi_offset ebp, -8
-; CHECK-NEXT:    mov ebp, esp
-; CHECK-NEXT:    .cfi_def_cfa_register ebp
-; CHECK-NEXT:    and esp, -8
 ; CHECK-NEXT:    sub esp, 8
-; CHECK-NEXT:    fld qword ptr [ebp + 8]
+; CHECK-NEXT:    .cfi_def_cfa_offset 12
+; CHECK-NEXT:    fld qword ptr [esp + 12]
 ; CHECK-NEXT:    fmul dword ptr [{{\.?LCPI[0-9]+_[0-9]+}}]
 ; CHECK-NEXT:    fstp qword ptr [esp]
 ; CHECK-NEXT:    fld qword ptr [esp]
-; CHECK-NEXT:    mov esp, ebp
-; CHECK-NEXT:    pop ebp
-; CHECK-NEXT:    .cfi_def_cfa esp, 4
+; CHECK-NEXT:    add esp, 8
+; CHECK-NEXT:    .cfi_def_cfa_offset 4
 ; CHECK-NEXT:    ret
 	%tmp.1 = fmul double %P, 1.230000e+02		; <double> [#uses=1]
 	ret double %tmp.1
@@ -51,20 +39,14 @@ define double @foo_mul(double %P) {
 define double @foo_sub(double %P) {
 ; CHECK-LABEL: foo_sub:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    push ebp
-; CHECK-NEXT:    .cfi_def_cfa_offset 8
-; CHECK-NEXT:    .cfi_offset ebp, -8
-; CHECK-NEXT:    mov ebp, esp
-; CHECK-NEXT:    .cfi_def_cfa_register ebp
-; CHECK-NEXT:    and esp, -8
 ; CHECK-NEXT:    sub esp, 8
-; CHECK-NEXT:    fld qword ptr [ebp + 8]
+; CHECK-NEXT:    .cfi_def_cfa_offset 12
+; CHECK-NEXT:    fld qword ptr [esp + 12]
 ; CHECK-NEXT:    fadd dword ptr [{{\.?LCPI[0-9]+_[0-9]+}}]
 ; CHECK-NEXT:    fstp qword ptr [esp]
 ; CHECK-NEXT:    fld qword ptr [esp]
-; CHECK-NEXT:    mov esp, ebp
-; CHECK-NEXT:    pop ebp
-; CHECK-NEXT:    .cfi_def_cfa esp, 4
+; CHECK-NEXT:    add esp, 8
+; CHECK-NEXT:    .cfi_def_cfa_offset 4
 ; CHECK-NEXT:    ret
 	%tmp.1 = fsub double %P, 1.230000e+02		; <double> [#uses=1]
 	ret double %tmp.1
@@ -73,20 +55,14 @@ define double @foo_sub(double %P) {
 define double @foo_subr(double %P) {
 ; CHECK-LABEL: foo_subr:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    push ebp
-; CHECK-NEXT:    .cfi_def_cfa_offset 8
-; CHECK-NEXT:    .cfi_offset ebp, -8
-; CHECK-NEXT:    mov ebp, esp
-; CHECK-NEXT:    .cfi_def_cfa_register ebp
-; CHECK-NEXT:    and esp, -8
 ; CHECK-NEXT:    sub esp, 8
+; CHECK-NEXT:    .cfi_def_cfa_offset 12
 ; CHECK-NEXT:    fld dword ptr [{{\.?LCPI[0-9]+_[0-9]+}}]
-; CHECK-NEXT:    fsub qword ptr [ebp + 8]
+; CHECK-NEXT:    fsub qword ptr [esp + 12]
 ; CHECK-NEXT:    fstp qword ptr [esp]
 ; CHECK-NEXT:    fld qword ptr [esp]
-; CHECK-NEXT:    mov esp, ebp
-; CHECK-NEXT:    pop ebp
-; CHECK-NEXT:    .cfi_def_cfa esp, 4
+; CHECK-NEXT:    add esp, 8
+; CHECK-NEXT:    .cfi_def_cfa_offset 4
 ; CHECK-NEXT:    ret
 	%tmp.1 = fsub double 1.230000e+02, %P		; <double> [#uses=1]
 	ret double %tmp.1
@@ -95,20 +71,14 @@ define double @foo_subr(double %P) {
 define double @foo_div(double %P) {
 ; CHECK-LABEL: foo_div:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    push ebp
-; CHECK-NEXT:    .cfi_def_cfa_offset 8
-; CHECK-NEXT:    .cfi_offset ebp, -8
-; CHECK-NEXT:    mov ebp, esp
-; CHECK-NEXT:    .cfi_def_cfa_register ebp
-; CHECK-NEXT:    and esp, -8
 ; CHECK-NEXT:    sub esp, 8
-; CHECK-NEXT:    fld qword ptr [ebp + 8]
+; CHECK-NEXT:    .cfi_def_cfa_offset 12
+; CHECK-NEXT:    fld qword ptr [esp + 12]
 ; CHECK-NEXT:    fdiv dword ptr [{{\.?LCPI[0-9]+_[0-9]+}}]
 ; CHECK-NEXT:    fstp qword ptr [esp]
 ; CHECK-NEXT:    fld qword ptr [esp]
-; CHECK-NEXT:    mov esp, ebp
-; CHECK-NEXT:    pop ebp
-; CHECK-NEXT:    .cfi_def_cfa esp, 4
+; CHECK-NEXT:    add esp, 8
+; CHECK-NEXT:    .cfi_def_cfa_offset 4
 ; CHECK-NEXT:    ret
 	%tmp.1 = fdiv double %P, 1.230000e+02		; <double> [#uses=1]
 	ret double %tmp.1
@@ -117,20 +87,14 @@ define double @foo_div(double %P) {
 define double @foo_divr(double %P) {
 ; CHECK-LABEL: foo_divr:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    push ebp
-; CHECK-NEXT:    .cfi_def_cfa_offset 8
-; CHECK-NEXT:    .cfi_offset ebp, -8
-; CHECK-NEXT:    mov ebp, esp
-; CHECK-NEXT:    .cfi_def_cfa_register ebp
-; CHECK-NEXT:    and esp, -8
 ; CHECK-NEXT:    sub esp, 8
+; CHECK-NEXT:    .cfi_def_cfa_offset 12
 ; CHECK-NEXT:    fld dword ptr [{{\.?LCPI[0-9]+_[0-9]+}}]
-; CHECK-NEXT:    fdiv qword ptr [ebp + 8]
+; CHECK-NEXT:    fdiv qword ptr [esp + 12]
 ; CHECK-NEXT:    fstp qword ptr [esp]
 ; CHECK-NEXT:    fld qword ptr [esp]
-; CHECK-NEXT:    mov esp, ebp
-; CHECK-NEXT:    pop ebp
-; CHECK-NEXT:    .cfi_def_cfa esp, 4
+; CHECK-NEXT:    add esp, 8
+; CHECK-NEXT:    .cfi_def_cfa_offset 4
 ; CHECK-NEXT:    ret
 	%tmp.1 = fdiv double 1.230000e+02, %P		; <double> [#uses=1]
 	ret double %tmp.1
diff --git a/llvm/test/CodeGen/X86/fp_load_fold.ll b/llvm/test/CodeGen/X86/fp_load_fold.ll
index 38b1562661005..52063c2d41499 100644
--- a/llvm/test/CodeGen/X86/fp_load_fold.ll
+++ b/llvm/test/CodeGen/X86/fp_load_fold.ll
@@ -6,21 +6,15 @@
 define double @test_add(double %X, ptr %P) {
 ; CHECK-LABEL: test_add:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    push ebp
-; CHECK-NEXT:    .cfi_def_cfa_offset 8
-; CHECK-NEXT:    .cfi_offset ebp, -8
-; CHECK-NEXT:    mov ebp, esp
-; CHECK-NEXT:    .cfi_def_cfa_register ebp
-; CHECK-NEXT:    and esp, -8
 ; CHECK-NEXT:    sub esp, 8
-; CHECK-NEXT:    mov eax, dword ptr [ebp + 16]
-; CHECK-NEXT:    fld qword ptr [ebp + 8]
+; CHECK-NEXT:    .cfi_def_cfa_offset 12
+; CHECK-NEXT:    mov eax, dword ptr [esp + 20]
+; CHECK-NEXT:    fld qword ptr [esp + 12]
 ; CHECK-NEXT:    fadd qword ptr [eax]
 ; CHECK-NEXT:    fstp qword ptr [esp]
 ; CHECK-NEXT:    fld qword ptr [esp]
-; CHECK-NEXT:    mov esp, ebp
-; CHECK-NEXT:    pop ebp
-; CHECK-NEXT:    .cfi_def_cfa esp, 4
+; CHECK-NEXT:    add esp, 8
+; CHECK-NEXT:    .cfi_def_cfa_offset 4
 ; CHECK-NEXT:    ret
 	%Y = load double, ptr %P		; <double> [#uses=1]
 	%R = fadd double %X, %Y		; <double> [#uses=1]
@@ -30,21 +24,15 @@ define double @test_add(double %X, ptr %P) {
 define double @test_mul(double %X, ptr %P) {
 ; CHECK-LABEL: test_mul:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    push ebp
-; CHECK-NEXT:    .cfi_def_cfa_offset 8
-; CHECK-NEXT:    .cfi_offset ebp, -8
-; CHECK-NEXT:    mov ebp, esp
-; CHECK-NEXT:    .cfi_def_cfa_register ebp
-; CHECK-NEXT:    and esp, -8
 ; CHECK-NEXT:    sub esp, 8
-; CHECK-NEXT:    mov eax, dword ptr [ebp + 16]
-; CHECK-NEXT:    fld qword ptr [ebp + 8]
+; CHECK-NEXT:    .cfi_def_cfa_offset 12
+; CHECK-NEXT:    mov eax, dword ptr [esp + 20]
+; CHECK-NEXT:    fld qword ptr [esp + 12]
 ; CHECK-NEXT:    fmul qword ptr [eax]
 ; CHECK-NEXT:    fstp qword ptr [esp]
 ; CHECK-NEXT:    fld qword ptr [esp]
-; CHECK-NEXT:    mov esp, ebp
-; CHECK-NEXT:    pop ebp
-; CHECK-NEXT:    .cfi_def_cfa esp, 4
+; CHECK-NEXT:    add esp, 8
+; CHECK-NEXT:    .cfi_def_cfa_offset 4
 ; CHECK-NEXT:    ret
 	%Y = load double, ptr %P		; <double> [#uses=1]
 	%R = fmul double %X, %Y		; <double> [#uses=1]
@@ -54,21 +42,15 @@ define double @test_mul(double %X, ptr %P) {
 define double @test_sub(double %X, ptr %P) {
 ; CHECK-LABEL: test_sub:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    push ebp
-; CHECK-NEXT:    .cfi_def_cfa_offset 8
-; CHECK-NEXT:    .cfi_offset ebp, -8
-; CHECK-NEXT:    mov ebp, esp
-; CHECK-NEXT:    .cfi_def_cfa_register ebp
-; CHECK-NEXT:    and esp, -8
 ; CHECK-NEXT:    sub esp, 8
-; CHECK-NEXT:    mov eax, dword ptr [ebp + 16]
-; CHECK-NEXT:    fld qword ptr [ebp + 8]
+; CHECK-NEXT:    .cfi_def_cfa_offset 12
+; CHECK-NEXT:    mov eax, dword ptr [esp + 20]
+; CHECK-NEXT:    fld qword ptr [esp + 12]
 ; CHECK-NEXT:    fsub qword ptr [eax]
 ; CHECK-NEXT:    fstp qword ptr [esp]
 ; CHECK-NEXT:    fld qword ptr [esp]
-; CHECK-NEXT:    mov esp, ebp
-; CHECK-NEXT:    pop ebp
-; CHECK-NEXT:    .cfi_def_cfa esp, 4
+; CHECK-NEXT:    add esp, 8
+; CHECK-NEXT:    .cfi_def_cfa_offset 4
 ; CHECK-NEXT:    ret
 	%Y = load double, ptr %P		; <double> [#uses=1]
 	%R = fsub double %X, %Y		; <double> [#uses=1]
@@ -78,21 +60,15 @@ define double @test_sub(double %X, ptr %P) {
 define double @test_subr(double %X, ptr %P) {
 ; CHECK-LABEL: test_subr:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    push ebp
-; CHECK-NEXT:    .cfi_def_cfa_offset 8
-; CHECK-NEXT:    .cfi_offset ebp, -8
-; CHECK-NEXT:    mov ebp, esp
-; CHECK-NEXT:    .cfi_def_cfa_register ebp
-; CHECK-NEXT:    and esp, -8
 ; CHECK-NEXT:    sub esp, 8
-; CHECK-NEXT:    mov eax, dword ptr [ebp + 16]
+; CHECK-NEXT:    .cfi_def_cfa_offset 12
+; CHECK-NEXT:    mov eax, dword ptr [esp + 20]
 ; CHECK-NEXT:    fld qword ptr [eax]
-; CHECK-NEXT:    fsub qword ptr [ebp + 8]
+; CHECK-NEXT:    fsub qword ptr [esp + 12]
 ; CHECK-NEXT:    fstp qword ptr [esp]
 ; CHECK-NEXT:    fld qword ptr [esp]
-; CHECK-NEXT:    mov esp, ebp
-; CHECK-NEXT:    pop ebp
-; CHECK-NEXT:    .cfi_def_cfa esp, 4
+; CHECK-NEXT:    add esp, 8
+; CHECK-NEXT:    .cfi_def_cfa_offset 4
 ; CHECK-NEXT:    ret
 	%Y = load double, ptr %P		; <double> [#uses=1]
 	%R = fsub double %Y, %X		; <double> [#uses=1]
@@ -102,21 +78,15 @@ define double @test_subr(double %X, ptr %P) {
 define double @test_div(double %X, ptr %P) {
 ; CHECK-LABEL: test_div:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    push ebp
-; CHECK-NEXT:    .cfi_def_cfa_offset 8
-; CHECK-NEXT:    .cfi_offset ebp, -8
-; CHECK-NEXT:    mov ebp, esp
-; CHECK-NEXT:    .cfi_def_cfa_register ebp
-; CHECK-NEXT:    and esp, -8
 ; CHECK-NEXT:    sub esp, 8
-; CHECK-NEXT:    mov eax, dword ptr [ebp + 16]
-; CHECK-NEXT:    fld qword ptr [ebp + 8]
+; CHECK-NEXT:    .cfi_def_cfa_offset 12
+; CHECK-NEXT:    mov eax, dword ptr [esp + 20]
+; CHECK-NEXT:    fld qword ptr [esp + 12]
 ; CHECK-NEXT:    fdiv qword ptr [eax]
 ; CHECK-NEXT:    fstp qword ptr [esp]
 ; CHECK-NEXT:    fld qword ptr [esp]
-; CHECK-NEXT:    mov esp, ebp
-; CHECK-NEXT:    pop ebp
-; CHECK-NEXT:    .cfi_def_cfa esp, 4
+; CHECK-NEXT:    add esp, 8
+; CHECK-NEXT:    .cfi_def_cfa_offset 4
 ; CHECK-NEXT:    ret
 	%Y = load double, ptr %P		; <double> [#uses=1]
 	%R = fdiv double %X, %Y		; <double> [#uses=1]
@@ -126,21 +96,15 @@ define double @test_div(double %X, ptr %P) {
 define double @test_divr(double %X, ptr %P) {
 ; CHECK-LABEL: test_divr:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    push ebp
-; CHECK-NEXT:    .cfi_def_cfa_offset 8
-; CHECK-NEXT:    .cfi_offset ebp, -8
-; CHECK-NEXT:    mov ebp, esp
-; CHECK-NEXT:    .cfi_def_cfa_register ebp
-; CHECK-NEXT:    and esp, -8
 ; CHECK-NEXT:    sub esp, 8
-; CHECK-NEXT:    mov eax, dword ptr [ebp + 16]
+; CHECK-NEXT:    .cfi_def_cfa_offset 12
+; CHECK-NEXT:    mov eax, dword ptr [esp + 20]
 ; CHECK-NEXT:    fld qword ptr [eax]
-; CHECK-NEXT:    fdiv qword ptr [ebp + 8]
+; CHECK-NEXT:    fdiv qword ptr [esp + 12]
 ; CHECK-NEXT:    fstp qword ptr [esp]
 ; CHECK-NEXT:    fld qword ptr [esp]
-; CHECK-NEXT:    mov esp, ebp
-; CHECK-NEXT:    pop ebp
-; CHECK-NEXT:    .cfi_def_cfa esp, 4
+; CHECK-NEXT:    add esp, 8
+; CHECK-NEXT:    .cfi_def_cfa_offset 4
 ; CHECK-NEXT:    ret
 	%Y = load double, ptr %P		; <double> [#uses=1]
 	%R = fdiv double %Y, %X		; <double> [#uses=1]
diff --git a/llvm/test/CodeGen/X86/inline-asm-fpstack.ll b/llvm/test/CodeGen/X86/inline-asm-fpstack.ll
index bc0c9c9229488..31d93f16ae0ea 100644
--- a/llvm/test/CodeGen/X86/inline-asm-fpstack.ll
+++ b/llvm/test/CodeGen/X86/inline-asm-fpstack.ll
@@ -16,9 +16,13 @@ define x86_fp80 @test1() nounwind {
 define double @test2() nounwind {
 ; CHECK-LABEL: test2:
 ; CHECK:       ## %bb.0:
+; CHECK-NEXT:    subl $8, %esp
 ; CHECK-NEXT:    ## InlineAsm Start
 ; CHECK-NEXT:    fld0
 ; CHECK-NEXT:    ## InlineAsm End
+; CHECK-NEXT:    fstpl (%esp)
+; CHECK-NEXT:    fldl (%esp)
+; CHECK-NEXT:    addl $8, %esp
 ; CHECK-NEXT:    retl
   %tmp85 = call double asm sideeffect "fld0", "={st(0)}"()
   ret double %tmp85
@@ -55,7 +59,7 @@ define void @test4(double %X) nounwind {
 define void @test5(double %X) nounwind {
 ; CHECK-LABEL: test5:
 ; CHECK:       ## %bb.0:
-; CHECK-NEXT:    subl $12, %esp
+; CHECK-NEXT:    subl $8, %esp
 ; CHECK-NEXT:    fldl {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; CHECK-NEXT:    fstpl (%esp)
@@ -63,7 +67,7 @@ define void @test5(double %X) nounwind {
 ; CHECK-NEXT:    ## InlineAsm Start
 ; CHECK-NEXT:    frob
 ; CHECK-NEXT:    ## InlineAsm End
-; CHECK-NEXT:    addl $12, %esp
+; CHECK-NEXT:    addl $8, %esp
 ; CHECK-NEXT:    retl
   %Y = fadd double %X, 123.0
   call void asm sideeffect "frob ", "{st(0)},~{st},~{dirflag},~{fpsr},~{flags}"( double %Y)
@@ -351,11 +355,15 @@ entry:
 define float @sincos1(float %x) nounwind ssp {
 ; CHECK-LABEL: sincos1:
 ; CHECK:       ## %bb.0: ## %entry
+; CHECK-NEXT:    pushl %eax
 ; CHECK-NEXT:    flds {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    ## InlineAsm Start
 ; CHECK-NEXT:    sincos
 ; CHECK-NEXT:    ## InlineAsm End
 ; CHECK-NEXT:    fstp %st(1)
+; CHECK-NEXT:    fstps (%esp)
+; CHECK-NEXT:    flds (%esp)
+; CHECK-NEXT:    popl %eax
 ; CHECK-NEXT:    retl
 entry:
   %0 = tail call %complex asm "sincos", "={st},={st(1)},0,~{dirflag},~{fpsr},~{flags}"(float %x) nounwind
@@ -367,11 +375,15 @@ entry:
 define float @sincos2(float %x) nounwind ssp {
 ; CHECK-LABEL: sincos2:
 ; CHECK:       ## %bb.0: ## %entry
+; CHECK-NEXT:    pushl %eax
 ; CHECK-NEXT:    flds {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    ## InlineAsm Start
 ; CHECK-NEXT:    sincos
 ; CHECK-NEXT:    ## InlineAsm End
 ; CHECK-NEXT:    fstp %st(1)
+; CHECK-NEXT:    fstps (%esp)
+; CHECK-NEXT:    flds (%esp)
+; CHECK-NEXT:    popl %eax
 ; CHECK-NEXT:    retl
 entry:
   %0 = tail call %complex asm "sincos", "={st(1)},={st},1,~{dirflag},~{fpsr},~{flags}"(float %x) nounwind
@@ -387,18 +399,22 @@ entry:
 define float @sincos3(float %x) nounwind ssp {
 ; CHECK-LABEL: sincos3:
 ; CHECK:       ## %bb.0: ## %entry
+; CHECK-NEXT:    pushl %eax
 ; CHECK-NEXT:    flds {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    fld %st(0)
 ; CHECK-NEXT:    ## InlineAsm Start
 ; CHECK-NEXT:    sincos
 ; CHECK-NEXT:    ## InlineAsm End
 ; CHECK-NEXT:    fstp %st(0)
+; CHECK-NEXT:    fstps (%esp)
+; CHECK-NEXT:    flds (%esp)
 ; CHECK-NEXT:    fxch %st(1)
 ; CHECK-NEXT:    ## InlineAsm Start
 ; CHECK-NEXT:    sincos
 ; CHECK-NEXT:    ## InlineAsm End
 ; CHECK-NEXT:    fstp %st(1)
 ; CHECK-NEXT:    fstp %st(0)
+; CHECK-NEXT:    popl %eax
 ; CHECK-NEXT:    retl
 entry:
   %0 = tail call %complex asm sideeffect "sincos", "={st(1)},={st},1,~{dirflag},~{fpsr},~{flags}"(float %x) nounwind
@@ -495,14 +511,17 @@ return:
 define double @test_operand_rewrite() nounwind {
 ; CHECK-LABEL: test_operand_rewrite:
 ; CHECK:       ## %bb.0: ## %entry
-; CHECK-NEXT:    subl $12, %esp
+; CHECK-NEXT:    subl $24, %esp
 ; CHECK-NEXT:    ## InlineAsm Start
 ; CHECK-NEXT:    foo %st, %st(1)
 ; CHECK-NEXT:    ## InlineAsm End
-; CHECK-NEXT:    fsubp %st, %st(1)
+; CHECK-NEXT:    fstpl {{[0-9]+}}(%esp)
+; CHECK-NEXT:    fstpl {{[0-9]+}}(%esp)
+; CHECK-NEXT:    fldl {{[0-9]+}}(%esp)
+; CHECK-NEXT:    fsubl {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    fstpl (%esp)
 ; CHECK-NEXT:    fldl (%esp)
-; CHECK-NEXT:    addl $12, %esp
+; CHECK-NEXT:    addl $24, %esp
 ; CHECK-NEXT:    retl
 entry:
   %0 = tail call { double, double } asm sideeffect "foo $0, $1", "={st},={st(1)},~{dirflag},~{fpsr},~{flags}"()
diff --git a/llvm/test/CodeGen/X86/isel-fadd.ll b/llvm/test/CodeGen/X86/isel-fadd.ll
index 659d0d8f43386..b45510888098f 100644
--- a/llvm/test/CodeGen/X86/isel-fadd.ll
+++ b/llvm/test/CodeGen/X86/isel-fadd.ll
@@ -60,57 +60,39 @@ define float @test_fadd_f32(float %arg1, float %arg2) {
 define double @test_fadd_f64(double %arg1, double %arg2) {
 ; SDAG-X86-LABEL: test_fadd_f64:
 ; SDAG-X86:       # %bb.0:
-; SDAG-X86-NEXT:    pushl %ebp
-; SDAG-X86-NEXT:    .cfi_def_cfa_offset 8
-; SDAG-X86-NEXT:    .cfi_offset %ebp, -8
-; SDAG-X86-NEXT:    movl %esp, %ebp
-; SDAG-X86-NEXT:    .cfi_def_cfa_register %ebp
-; SDAG-X86-NEXT:    andl $-8, %esp
 ; SDAG-X86-NEXT:    subl $8, %esp
-; SDAG-X86-NEXT:    fldl 8(%ebp)
-; SDAG-X86-NEXT:    faddl 16(%ebp)
+; SDAG-X86-NEXT:    .cfi_def_cfa_offset 12
+; SDAG-X86-NEXT:    fldl {{[0-9]+}}(%esp)
+; SDAG-X86-NEXT:    faddl {{[0-9]+}}(%esp)
 ; SDAG-X86-NEXT:    fstpl (%esp)
 ; SDAG-X86-NEXT:    fldl (%esp)
-; SDAG-X86-NEXT:    movl %ebp, %esp
-; SDAG-X86-NEXT:    popl %ebp
-; SDAG-X86-NEXT:    .cfi_def_cfa %esp, 4
+; SDAG-X86-NEXT:    addl $8, %esp
+; SDAG-X86-NEXT:    .cfi_def_cfa_offset 4
 ; SDAG-X86-NEXT:    retl
 ;
 ; FASTISEL-X86-LABEL: test_fadd_f64:
 ; FASTISEL-X86:       # %bb.0:
-; FASTISEL-X86-NEXT:    pushl %ebp
-; FASTISEL-X86-NEXT:    .cfi_def_cfa_offset 8
-; FASTISEL-X86-NEXT:    .cfi_offset %ebp, -8
-; FASTISEL-X86-NEXT:    movl %esp, %ebp
-; FASTISEL-X86-NEXT:    .cfi_def_cfa_register %ebp
-; FASTISEL-X86-NEXT:    andl $-8, %esp
 ; FASTISEL-X86-NEXT:    subl $8, %esp
-; FASTISEL-X86-NEXT:    fldl 16(%ebp)
-; FASTISEL-X86-NEXT:    fldl 8(%ebp)
+; FASTISEL-X86-NEXT:    .cfi_def_cfa_offset 12
+; FASTISEL-X86-NEXT:    fldl {{[0-9]+}}(%esp)
+; FASTISEL-X86-NEXT:    fldl {{[0-9]+}}(%esp)
 ; FASTISEL-X86-NEXT:    faddp %st, %st(1)
 ; FASTISEL-X86-NEXT:    fstpl (%esp)
 ; FASTISEL-X86-NEXT:    fldl (%esp)
-; FASTISEL-X86-NEXT:    movl %ebp, %esp
-; FASTISEL-X86-NEXT:    popl %ebp
-; FASTISEL-X86-NEXT:    .cfi_def_cfa %esp, 4
+; FASTISEL-X86-NEXT:    addl $8, %esp
+; FASTISEL-X86-NEXT:    .cfi_def_cfa_offset 4
 ; FASTISEL-X86-NEXT:    retl
 ;
 ; GISEL-X86-LABEL: test_fadd_f64:
 ; GISEL-X86:       # %bb.0:
-; GISEL-X86-NEXT:    pushl %ebp
-; GISEL-X86-NEXT:    .cfi_def_cfa_offset 8
-; GISEL-X86-NEXT:    .cfi_offset %ebp, -8
-; GISEL-X86-NEXT:    movl %esp, %ebp
-; GISEL-X86-NEXT:    .cfi_def_cfa_register %ebp
-; GISEL-X86-NEXT:    andl $-8, %esp
 ; GISEL-X86-NEXT:    subl $8, %esp
-; GISEL-X86-NEXT:    fldl 8(%ebp)
-; GISEL-X86-NEXT:    faddl 16(%ebp)
+; GISEL-X86-NEXT:    .cfi_def_cfa_offset 12
+; GISEL-X86-NEXT:    fldl {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    faddl {{[0-9]+}}(%esp)
 ; GISEL-X86-NEXT:    fstpl (%esp)
 ; GISEL-X86-NEXT:    fldl (%esp)
-; GISEL-X86-NEXT:    movl %ebp, %esp
-; GISEL-X86-NEXT:    popl %ebp
-; GISEL-X86-NEXT:    .cfi_def_cfa %esp, 4
+; GISEL-X86-NEXT:    addl $8, %esp
+; GISEL-X86-NEXT:    .cfi_def_cfa_offset 4
 ; GISEL-X86-NEXT:    retl
 ;
 ; SSE-LABEL: test_fadd_f64:
diff --git a/llvm/test/CodeGen/X86/isel-fdiv.ll b/llvm/test/CodeGen/X86/isel-fdiv.ll
index ad3f9cc353167..2f1f1639386dc 100644
--- a/llvm/test/CodeGen/X86/isel-fdiv.ll
+++ b/llvm/test/CodeGen/X86/isel-fdiv.ll
@@ -60,57 +60,39 @@ define float @test_fdiv_f32(float %arg1, float %arg2) {
 define double @test_fdiv_f64(double %arg1, double %arg2) {
 ; SDAG-X86-LABEL: test_fdiv_f64:
 ; SDAG-X86:       # %bb.0:
-; SDAG-X86-NEXT:    pushl %ebp
-; SDAG-X86-NEXT:    .cfi_def_cfa_offset 8
-; SDAG-X86-NEXT:    .cfi_offset %ebp, -8
-; SDAG-X86-NEXT:    movl %esp, %ebp
-; SDAG-X86-NEXT:    .cfi_def_cfa_register %ebp
-; SDAG-X86-NEXT:    andl $-8, %esp
 ; SDAG-X86-NEXT:    subl $8, %esp
-; SDAG-X86-NEXT:    fldl 8(%ebp)
-; SDAG-X86-NEXT:    fdivl 16(%ebp)
+; SDAG-X86-NEXT:    .cfi_def_cfa_offset 12
+; SDAG-X86-NEXT:    fldl {{[0-9]+}}(%esp)
+; SDAG-X86-NEXT:    fdivl {{[0-9]+}}(%esp)
 ; SDAG-X86-NEXT:    fstpl (%esp)
 ; SDAG-X86-NEXT:    fldl (%esp)
-; SDAG-X86-NEXT:    movl %ebp, %esp
-; SDAG-X86-NEXT:    popl %ebp
-; SDAG-X86-NEXT:    .cfi_def_cfa %esp, 4
+; SDAG-X86-NEXT:    addl $8, %esp
+; SDAG-X86-NEXT:    .cfi_def_cfa_offset 4
 ; SDAG-X86-NEXT:    retl
 ;
 ; FASTISEL-X86-LABEL: test_fdiv_f64:
 ; FASTISEL-X86:       # %bb.0:
-; FASTISEL-X86-NEXT:    pushl %ebp
-; FASTISEL-X86-NEXT:    .cfi_def_cfa_offset 8
-; FASTISEL-X86-NEXT:    .cfi_offset %ebp, -8
-; FASTISEL-X86-NEXT:    movl %esp, %ebp
-; FASTISEL-X86-NEXT:    .cfi_def_cfa_register %ebp
-; FASTISEL-X86-NEXT:    andl $-8, %esp
 ; FASTISEL-X86-NEXT:    subl $8, %esp
-; FASTISEL-X86-NEXT:    fldl 16(%ebp)
-; FASTISEL-X86-NEXT:    fldl 8(%ebp)
+; FASTISEL-X86-NEXT:    .cfi_def_cfa_offset 12
+; FASTISEL-X86-NEXT:    fldl {{[0-9]+}}(%esp)
+; FASTISEL-X86-NEXT:    fldl {{[0-9]+}}(%esp)
 ; FASTISEL-X86-NEXT:    fdivp %st, %st(1)
 ; FASTISEL-X86-NEXT:    fstpl (%esp)
 ; FASTISEL-X86-NEXT:    fldl (%esp)
-; FASTISEL-X86-NEXT:    movl %ebp, %esp
-; FASTISEL-X86-NEXT:    popl %ebp
-; FASTISEL-X86-NEXT:    .cfi_def_cfa %esp, 4
+; FASTISEL-X86-NEXT:    addl $8, %esp
+; FASTISEL-X86-NEXT:    .cfi_def_cfa_offset 4
 ; FASTISEL-X86-NEXT:    retl
 ;
 ; GISEL-X86-LABEL: test_fdiv_f64:
 ; GISEL-X86:       # %bb.0:
-; GISEL-X86-NEXT:    pushl %ebp
-; GISEL-X86-NEXT:    .cfi_def_cfa_offset 8
-; GISEL-X86-NEXT:    .cfi_offset %ebp, -8
-; GISEL-X86-NEXT:    movl %esp, %ebp
-; GISEL-X86-NEXT:    .cfi_def_cfa_register %ebp
-; GISEL-X86-NEXT:    andl $-8, %esp
 ; GISEL-X86-NEXT:    subl $8, %esp
-; GISEL-X86-NEXT:    fldl 8(%ebp)
-; GISEL-X86-NEXT:    fdivl 16(%ebp)
+; GISEL-X86-NEXT:    .cfi_def_cfa_offset 12
+; GISEL-X86-NEXT:    fldl {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    fdivl {{[0-9]+}}(%esp)
 ; GISEL-X86-NEXT:    fstpl (%esp)
 ; GISEL-X86-NEXT:    fldl (%esp)
-; GISEL-X86-NEXT:    movl %ebp, %esp
-; GISEL-X86-NEXT:    popl %ebp
-; GISEL-X86-NEXT:    .cfi_def_cfa %esp, 4
+; GISEL-X86-NEXT:    addl $8, %esp
+; GISEL-X86-NEXT:    .cfi_def_cfa_offset 4
 ; GISEL-X86-NEXT:    retl
 ;
 ; SSE-LABEL: test_fdiv_f64:
diff --git a/llvm/test/CodeGen/X86/isel-fmul.ll b/llvm/test/CodeGen/X86/isel-fmul.ll
index 0453acf4801a9..92fff53804ee8 100644
--- a/llvm/test/CodeGen/X86/isel-fmul.ll
+++ b/llvm/test/CodeGen/X86/isel-fmul.ll
@@ -60,57 +60,39 @@ define float @test_fmul_f32(float %arg1, float %arg2) {
 define double @test_fmul_f64(double %arg1, double %arg2) {
 ; SDAG-X86-LABEL: test_fmul_f64:
 ; SDAG-X86:       # %bb.0:
-; SDAG-X86-NEXT:    pushl %ebp
-; SDAG-X86-NEXT:    .cfi_def_cfa_offset 8
-; SDAG-X86-NEXT:    .cfi_offset %ebp, -8
-; SDAG-X86-NEXT:    movl %esp, %ebp
-; SDAG-X86-NEXT:    .cfi_def_cfa_register %ebp
-; SDAG-X86-NEXT:    andl $-8, %esp
 ; SDAG-X86-NEXT:    subl $8, %esp
-; SDAG-X86-NEXT:    fldl 8(%ebp)
-; SDAG-X86-NEXT:    fmull 16(%ebp)
+; SDAG-X86-NEXT:    .cfi_def_cfa_offset 12
+; SDAG-X86-NEXT:    fldl {{[0-9]+}}(%esp)
+; SDAG-X86-NEXT:    fmull {{[0-9]+}}(%esp)
 ; SDAG-X86-NEXT:    fstpl (%esp)
 ; SDAG-X86-NEXT:    fldl (%esp)
-; SDAG-X86-NEXT:    movl %ebp, %esp
-; SDAG-X86-NEXT:    popl %ebp
-; SDAG-X86-NEXT:    .cfi_def_cfa %esp, 4
+; SDAG-X86-NEXT:    addl $8, %esp
+; SDAG-X86-NEXT:    .cfi_def_cfa_offset 4
 ; SDAG-X86-NEXT:    retl
 ;
 ; FASTISEL-X86-LABEL: test_fmul_f64:
 ; FASTISEL-X86:       # %bb.0:
-; FASTISEL-X86-NEXT:    pushl %ebp
-; FASTISEL-X86-NEXT:    .cfi_def_cfa_offset 8
-; FASTISEL-X86-NEXT:    .cfi_offset %ebp, -8
-; FASTISEL-X86-NEXT:    movl %esp, %ebp
-; FASTISEL-X86-NEXT:    .cfi_def_cfa_register %ebp
-; FASTISEL-X86-NEXT:    andl $-8, %esp
 ; FASTISEL-X86-NEXT:    subl $8, %esp
-; FASTISEL-X86-NEXT:    fldl 16(%ebp)
-; FASTISEL-X86-NEXT:    fldl 8(%ebp)
+; FASTISEL-X86-NEXT:    .cfi_def_cfa_offset 12
+; FASTISEL-X86-NEXT:    fldl {{[0-9]+}}(%esp)
+; FASTISEL-X86-NEXT:    fldl {{[0-9]+}}(%esp)
 ; FASTISEL-X86-NEXT:    fmulp %st, %st(1)
 ; FASTISEL-X86-NEXT:    fstpl (%esp)
 ; FASTISEL-X86-NEXT:    fldl (%esp)
-; FASTISEL-X86-NEXT:    movl %ebp, %esp
-; FASTISEL-X86-NEXT:    popl %ebp
-; FASTISEL-X86-NEXT:    .cfi_def_cfa %esp, 4
+; FASTISEL-X86-NEXT:    addl $8, %esp
+; FASTISEL-X86-NEXT:    .cfi_def_cfa_offset 4
 ; FASTISEL-X86-NEXT:    retl
 ;
 ; GISEL-X86-LABEL: test_fmul_f64:
 ; GISEL-X86:       # %bb.0:
-; GISEL-X86-NEXT:    pushl %ebp
-; GISEL-X86-NEXT:    .cfi_def_cfa_offset 8
-; GISEL-X86-NEXT:    .cfi_offset %ebp, -8
-; GISEL-X86-NEXT:    movl %esp, %ebp
-; GISEL-X86-NEXT:    .cfi_def_cfa_register %ebp
-; GISEL-X86-NEXT:    andl $-8, %esp
 ; GISEL-X86-NEXT:    subl $8, %esp
-; GISEL-X86-NEXT:    fldl 8(%ebp)
-; GISEL-X86-NEXT:    fmull 16(%ebp)
+; GISEL-X86-NEXT:    .cfi_def_cfa_offset 12
+; GISEL-X86-NEXT:    fldl {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    fmull {{[0-9]+}}(%esp)
 ; GISEL-X86-NEXT:    fstpl (%esp)
 ; GISEL-X86-NEXT:    fldl (%esp)
-; GISEL-X86-NEXT:    movl %ebp, %esp
-; GISEL-X86-NEXT:    popl %ebp
-; GISEL-X86-NEXT:    .cfi_def_cfa %esp, 4
+; GISEL-X86-NEXT:    addl $8, %esp
+; GISEL-X86-NEXT:    .cfi_def_cfa_offset 4
 ; GISEL-X86-NEXT:    retl
 ;
 ; SSE-LABEL: test_fmul_f64:
diff --git a/llvm/test/CodeGen/X86/isel-fptrunc-fpext.ll b/llvm/test/CodeGen/X86/isel-fptrunc-fpext.ll
index 7f58fffe2b5ed..7001f3ef7028d 100644
--- a/llvm/test/CodeGen/X86/isel-fptrunc-fpext.ll
+++ b/llvm/test/CodeGen/X86/isel-fptrunc-fpext.ll
@@ -207,15 +207,11 @@ define float @fptrunc_x86_fp80_to_float(x86_fp80 %x) nounwind {
 define double @fptrunc_x86_fp80_to_double(x86_fp80 %x) nounwind {
 ; X86-LABEL: fptrunc_x86_fp80_to_double:
 ; X86:       # %bb.0:
-; X86-NEXT:    pushl %ebp
-; X86-NEXT:    movl %esp, %ebp
-; X86-NEXT:    andl $-8, %esp
 ; X86-NEXT:    subl $8, %esp
-; X86-NEXT:    fldt 8(%ebp)
+; X86-NEXT:    fldt {{[0-9]+}}(%esp)
 ; X86-NEXT:    fstpl (%esp)
 ; X86-NEXT:    fldl (%esp)
-; X86-NEXT:    movl %ebp, %esp
-; X86-NEXT:    popl %ebp
+; X86-NEXT:    addl $8, %esp
 ; X86-NEXT:    retl
 ;
 ; FASTSDAG-SSE-LABEL: fptrunc_x86_fp80_to_double:
diff --git a/llvm/test/CodeGen/X86/isel-fsub.ll b/llvm/test/CodeGen/X86/isel-fsub.ll
index 090a8a45cb424..98a0129c40d56 100644
--- a/llvm/test/CodeGen/X86/isel-fsub.ll
+++ b/llvm/test/CodeGen/X86/isel-fsub.ll
@@ -60,57 +60,39 @@ define float @test_fsub_f32(float %arg1, float %arg2) {
 define double @test_fsub_f64(double %arg1, double %arg2) {
 ; SDAG-X86-LABEL: test_fsub_f64:
 ; SDAG-X86:       # %bb.0:
-; SDAG-X86-NEXT:    pushl %ebp
-; SDAG-X86-NEXT:    .cfi_def_cfa_offset 8
-; SDAG-X86-NEXT:    .cfi_offset %ebp, -8
-; SDAG-X86-NEXT:    movl %esp, %ebp
-; SDAG-X86-NEXT:    .cfi_def_cfa_register %ebp
-; SDAG-X86-NEXT:    andl $-8, %esp
 ; SDAG-X86-NEXT:    subl $8, %esp
-; SDAG-X86-NEXT:    fldl 8(%ebp)
-; SDAG-X86-NEXT:    fsubl 16(%ebp)
+; SDAG-X86-NEXT:    .cfi_def_cfa_offset 12
+; SDAG-X86-NEXT:    fldl {{[0-9]+}}(%esp)
+; SDAG-X86-NEXT:    fsubl {{[0-9]+}}(%esp)
 ; SDAG-X86-NEXT:    fstpl (%esp)
 ; SDAG-X86-NEXT:    fldl (%esp)
-; SDAG-X86-NEXT:    movl %ebp, %esp
-; SDAG-X86-NEXT:    popl %ebp
-; SDAG-X86-NEXT:    .cfi_def_cfa %esp, 4
+; SDAG-X86-NEXT:    addl $8, %esp
+; SDAG-X86-NEXT:    .cfi_def_cfa_offset 4
 ; SDAG-X86-NEXT:    retl
 ;
 ; FASTISEL-X86-LABEL: test_fsub_f64:
 ; FASTISEL-X86:       # %bb.0:
-; FASTISEL-X86-NEXT:    pushl %ebp
-; FASTISEL-X86-NEXT:    .cfi_def_cfa_offset 8
-; FASTISEL-X86-NEXT:    .cfi_offset %ebp, -8
-; FASTISEL-X86-NEXT:    movl %esp, %ebp
-; FASTISEL-X86-NEXT:    .cfi_def_cfa_register %ebp
-; FASTISEL-X86-NEXT:    andl $-8, %esp
 ; FASTISEL-X86-NEXT:    subl $8, %esp
-; FASTISEL-X86-NEXT:    fldl 16(%ebp)
-; FASTISEL-X86-NEXT:    fldl 8(%ebp)
+; FASTISEL-X86-NEXT:    .cfi_def_cfa_offset 12
+; FASTISEL-X86-NEXT:    fldl {{[0-9]+}}(%esp)
+; FASTISEL-X86-NEXT:    fldl {{[0-9]+}}(%esp)
 ; FASTISEL-X86-NEXT:    fsubp %st, %st(1)
 ; FASTISEL-X86-NEXT:    fstpl (%esp)
 ; FASTISEL-X86-NEXT:    fldl (%esp)
-; FASTISEL-X86-NEXT:    movl %ebp, %esp
-; FASTISEL-X86-NEXT:    popl %ebp
-; FASTISEL-X86-NEXT:    .cfi_def_cfa %esp, 4
+; FASTISEL-X86-NEXT:    addl $8, %esp
+; FASTISEL-X86-NEXT:    .cfi_def_cfa_offset 4
 ; FASTISEL-X86-NEXT:    retl
 ;
 ; GISEL-X86-LABEL: test_fsub_f64:
 ; GISEL-X86:       # %bb.0:
-; GISEL-X86-NEXT:    pushl %ebp
-; GISEL-X86-NEXT:    .cfi_def_cfa_offset 8
-; GISEL-X86-NEXT:    .cfi_offset %ebp, -8
-; GISEL-X86-NEXT:    movl %esp, %ebp
-; GISEL-X86-NEXT:    .cfi_def_cfa_register %ebp
-; GISEL-X86-NEXT:    andl $-8, %esp
 ; GISEL-X86-NEXT:    subl $8, %esp
-; GISEL-X86-NEXT:    fldl 8(%ebp)
-; GISEL-X86-NEXT:    fsubl 16(%ebp)
+; GISEL-X86-NEXT:    .cfi_def_cfa_offset 12
+; GISEL-X86-NEXT:    fldl {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    fsubl {{[0-9]+}}(%esp)
 ; GISEL-X86-NEXT:    fstpl (%esp)
 ; GISEL-X86-NEXT:    fldl (%esp)
-; GISEL-X86-NEXT:    movl %ebp, %esp
-; GISEL-X86-NEXT:    popl %ebp
-; GISEL-X86-NEXT:    .cfi_def_cfa %esp, 4
+; GISEL-X86-NEXT:    addl $8, %esp
+; GISEL-X86-NEXT:    .cfi_def_cfa_offset 4
 ; GISEL-X86-NEXT:    retl
 ;
 ; SSE-LABEL: test_fsub_f64:
diff --git a/llvm/test/CodeGen/X86/isel-sqrt.ll b/llvm/test/CodeGen/X86/isel-sqrt.ll
index 6d742da2129f6..e25ebedbe38ce 100644
--- a/llvm/test/CodeGen/X86/isel-sqrt.ll
+++ b/llvm/test/CodeGen/X86/isel-sqrt.ll
@@ -68,13 +68,13 @@ define double @test_sqrt_f64(double %a) {
 ;
 ; X86-LABEL: test_sqrt_f64:
 ; X86:       # %bb.0:
-; X86-NEXT:    subl $12, %esp
-; X86-NEXT:    .cfi_def_cfa_offset 16
+; X86-NEXT:    subl $8, %esp
+; X86-NEXT:    .cfi_def_cfa_offset 12
 ; X86-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-NEXT:    fsqrt
 ; X86-NEXT:    fstpl (%esp)
 ; X86-NEXT:    fldl (%esp)
-; X86-NEXT:    addl $12, %esp
+; X86-NEXT:    addl $8, %esp
 ; X86-NEXT:    .cfi_def_cfa_offset 4
 ; X86-NEXT:    retl
   %res = call double @llvm.sqrt.f64(double %a)
diff --git a/llvm/test/CodeGen/X86/isel-x87.ll b/llvm/test/CodeGen/X86/isel-x87.ll
index 492faaa19cd66..b4da44d3eaf4e 100644
--- a/llvm/test/CodeGen/X86/isel-x87.ll
+++ b/llvm/test/CodeGen/X86/isel-x87.ll
@@ -192,11 +192,15 @@ define void @f6(ptr %a, ptr %b) nounwind {
 ;
 ; SDAG_X86-LABEL: f6:
 ; SDAG_X86:       # %bb.0:
+; SDAG_X86-NEXT:    pushl %eax
 ; SDAG_X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; SDAG_X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; SDAG_X86-NEXT:    flds (%ecx)
 ; SDAG_X86-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; SDAG_X86-NEXT:    fstps (%esp)
+; SDAG_X86-NEXT:    flds (%esp)
 ; SDAG_X86-NEXT:    fstps (%eax)
+; SDAG_X86-NEXT:    popl %eax
 ; SDAG_X86-NEXT:    retl
 ;
 ; GISEL_X64-LABEL: f6:
@@ -210,6 +214,8 @@ define void @f6(ptr %a, ptr %b) nounwind {
 ; SDAG_X64:       # %bb.0:
 ; SDAG_X64-NEXT:    flds (%rdi)
 ; SDAG_X64-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}(%rip)
+; SDAG_X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
+; SDAG_X64-NEXT:    flds -{{[0-9]+}}(%rsp)
 ; SDAG_X64-NEXT:    fstps (%rsi)
 ; SDAG_X64-NEXT:    retq
   %load1 = load float, ptr %a
diff --git a/llvm/test/CodeGen/X86/limited-prec.ll b/llvm/test/CodeGen/X86/limited-prec.ll
index 203260e606a5b..e2a651aefd35e 100644
--- a/llvm/test/CodeGen/X86/limited-prec.ll
+++ b/llvm/test/CodeGen/X86/limited-prec.ll
@@ -6,7 +6,7 @@
 define float @f1(float %x) nounwind noinline {
 ; precision6-LABEL: f1:
 ; precision6:       # %bb.0: # %entry
-; precision6-NEXT:    subl $44, %esp
+; precision6-NEXT:    subl $48, %esp
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
@@ -31,22 +31,23 @@ define float @f1(float %x) nounwind noinline {
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision6-NEXT:    flds {{[0-9]+}}(%esp)
-; precision6-NEXT:    fmulp %st, %st(1)
+; precision6-NEXT:    fmuls {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision6-NEXT:    flds {{[0-9]+}}(%esp)
+; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision6-NEXT:    shll $23, %eax
 ; precision6-NEXT:    addl {{[0-9]+}}(%esp), %eax
 ; precision6-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
-; precision6-NEXT:    addl $44, %esp
+; precision6-NEXT:    addl $48, %esp
 ; precision6-NEXT:    retl
 ;
 ; precision12-LABEL: f1:
 ; precision12:       # %bb.0: # %entry
-; precision12-NEXT:    subl $52, %esp
+; precision12-NEXT:    subl $56, %esp
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
@@ -71,28 +72,29 @@ define float @f1(float %x) nounwind noinline {
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision12-NEXT:    flds {{[0-9]+}}(%esp)
-; precision12-NEXT:    fmul %st(1), %st
+; precision12-NEXT:    fld %st(0)
+; precision12-NEXT:    fmuls {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision12-NEXT:    flds {{[0-9]+}}(%esp)
-; precision12-NEXT:    fmulp %st, %st(1)
+; precision12-NEXT:    fmuls {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision12-NEXT:    shll $23, %eax
 ; precision12-NEXT:    addl {{[0-9]+}}(%esp), %eax
 ; precision12-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
-; precision12-NEXT:    addl $52, %esp
+; precision12-NEXT:    addl $56, %esp
 ; precision12-NEXT:    retl
 ;
 ; precision18-LABEL: f1:
 ; precision18:       # %bb.0: # %entry
-; precision18-NEXT:    subl $76, %esp
+; precision18-NEXT:    subl $80, %esp
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
@@ -117,42 +119,42 @@ define float @f1(float %x) nounwind noinline {
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    fmul %st(1), %st
+; precision18-NEXT:    fld %st(0)
+; precision18-NEXT:    fmuls {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    fmul %st(1), %st
+; precision18-NEXT:    fld %st(0)
+; precision18-NEXT:    fmuls {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    fmul %st(1), %st
+; precision18-NEXT:    fld %st(0)
+; precision18-NEXT:    fmuls {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    fmul %st(1), %st
+; precision18-NEXT:    fld %st(0)
+; precision18-NEXT:    fmuls {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    fmulp %st, %st(1)
+; precision18-NEXT:    fmuls {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fld1
-; precision18-NEXT:    faddp %st, %st(1)
+; precision18-NEXT:    fadds {{[0-9]+}}(%esp)
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    shll $23, %eax
 ; precision18-NEXT:    addl {{[0-9]+}}(%esp), %eax
 ; precision18-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    addl $76, %esp
+; precision18-NEXT:    addl $80, %esp
 ; precision18-NEXT:    retl
 entry:
 	%"alloca point" = bitcast i32 0 to i32		; <i32> [#uses=0]
@@ -165,7 +167,7 @@ declare float @llvm.exp.f32(float) nounwind readonly
 define float @f2(float %x) nounwind noinline {
 ; precision6-LABEL: f2:
 ; precision6:       # %bb.0: # %entry
-; precision6-NEXT:    subl $40, %esp
+; precision6-NEXT:    subl $44, %esp
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fnstcw (%esp)
 ; precision6-NEXT:    movzwl (%esp), %eax
@@ -187,22 +189,23 @@ define float @f2(float %x) nounwind noinline {
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision6-NEXT:    flds {{[0-9]+}}(%esp)
-; precision6-NEXT:    fmulp %st, %st(1)
+; precision6-NEXT:    fmuls {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision6-NEXT:    flds {{[0-9]+}}(%esp)
+; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision6-NEXT:    shll $23, %eax
 ; precision6-NEXT:    addl {{[0-9]+}}(%esp), %eax
 ; precision6-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
-; precision6-NEXT:    addl $40, %esp
+; precision6-NEXT:    addl $44, %esp
 ; precision6-NEXT:    retl
 ;
 ; precision12-LABEL: f2:
 ; precision12:       # %bb.0: # %entry
-; precision12-NEXT:    subl $48, %esp
+; precision12-NEXT:    subl $52, %esp
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fnstcw (%esp)
 ; precision12-NEXT:    movzwl (%esp), %eax
@@ -224,28 +227,29 @@ define float @f2(float %x) nounwind noinline {
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision12-NEXT:    flds {{[0-9]+}}(%esp)
-; precision12-NEXT:    fmul %st(1), %st
+; precision12-NEXT:    fld %st(0)
+; precision12-NEXT:    fmuls {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision12-NEXT:    flds {{[0-9]+}}(%esp)
-; precision12-NEXT:    fmulp %st, %st(1)
+; precision12-NEXT:    fmuls {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision12-NEXT:    shll $23, %eax
 ; precision12-NEXT:    addl {{[0-9]+}}(%esp), %eax
 ; precision12-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
-; precision12-NEXT:    addl $48, %esp
+; precision12-NEXT:    addl $52, %esp
 ; precision12-NEXT:    retl
 ;
 ; precision18-LABEL: f2:
 ; precision18:       # %bb.0: # %entry
-; precision18-NEXT:    subl $72, %esp
+; precision18-NEXT:    subl $76, %esp
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fnstcw (%esp)
 ; precision18-NEXT:    movzwl (%esp), %eax
@@ -267,42 +271,42 @@ define float @f2(float %x) nounwind noinline {
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    fmul %st(1), %st
+; precision18-NEXT:    fld %st(0)
+; precision18-NEXT:    fmuls {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    fmul %st(1), %st
+; precision18-NEXT:    fld %st(0)
+; precision18-NEXT:    fmuls {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    fmul %st(1), %st
+; precision18-NEXT:    fld %st(0)
+; precision18-NEXT:    fmuls {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    fmul %st(1), %st
+; precision18-NEXT:    fld %st(0)
+; precision18-NEXT:    fmuls {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    fmulp %st, %st(1)
+; precision18-NEXT:    fmuls {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fld1
-; precision18-NEXT:    faddp %st, %st(1)
+; precision18-NEXT:    fadds {{[0-9]+}}(%esp)
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    shll $23, %eax
 ; precision18-NEXT:    addl {{[0-9]+}}(%esp), %eax
 ; precision18-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    addl $72, %esp
+; precision18-NEXT:    addl $76, %esp
 ; precision18-NEXT:    retl
 entry:
 	%"alloca point" = bitcast i32 0 to i32		; <i32> [#uses=0]
@@ -315,7 +319,7 @@ declare float @llvm.exp2.f32(float) nounwind readonly
 define float @f3(float %x) nounwind noinline {
 ; precision6-LABEL: f3:
 ; precision6:       # %bb.0: # %entry
-; precision6-NEXT:    subl $44, %esp
+; precision6-NEXT:    subl $48, %esp
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
@@ -340,22 +344,23 @@ define float @f3(float %x) nounwind noinline {
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision6-NEXT:    flds {{[0-9]+}}(%esp)
-; precision6-NEXT:    fmulp %st, %st(1)
+; precision6-NEXT:    fmuls {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision6-NEXT:    flds {{[0-9]+}}(%esp)
+; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision6-NEXT:    shll $23, %eax
 ; precision6-NEXT:    addl {{[0-9]+}}(%esp), %eax
 ; precision6-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
-; precision6-NEXT:    addl $44, %esp
+; precision6-NEXT:    addl $48, %esp
 ; precision6-NEXT:    retl
 ;
 ; precision12-LABEL: f3:
 ; precision12:       # %bb.0: # %entry
-; precision12-NEXT:    subl $52, %esp
+; precision12-NEXT:    subl $56, %esp
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
@@ -380,28 +385,29 @@ define float @f3(float %x) nounwind noinline {
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision12-NEXT:    flds {{[0-9]+}}(%esp)
-; precision12-NEXT:    fmul %st(1), %st
+; precision12-NEXT:    fld %st(0)
+; precision12-NEXT:    fmuls {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision12-NEXT:    flds {{[0-9]+}}(%esp)
-; precision12-NEXT:    fmulp %st, %st(1)
+; precision12-NEXT:    fmuls {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    flds {{[0-9]+}}(%esp)
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision12-NEXT:    shll $23, %eax
 ; precision12-NEXT:    addl {{[0-9]+}}(%esp), %eax
 ; precision12-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
-; precision12-NEXT:    addl $52, %esp
+; precision12-NEXT:    addl $56, %esp
 ; precision12-NEXT:    retl
 ;
 ; precision18-LABEL: f3:
 ; precision18:       # %bb.0: # %entry
-; precision18-NEXT:    subl $76, %esp
+; precision18-NEXT:    subl $80, %esp
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
@@ -426,42 +432,42 @@ define float @f3(float %x) nounwind noinline {
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    fmul %st(1), %st
+; precision18-NEXT:    fld %st(0)
+; precision18-NEXT:    fmuls {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    fmul %st(1), %st
+; precision18-NEXT:    fld %st(0)
+; precision18-NEXT:    fmuls {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    fmul %st(1), %st
+; precision18-NEXT:    fld %st(0)
+; precision18-NEXT:    fmuls {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    fmul %st(1), %st
+; precision18-NEXT:    fld %st(0)
+; precision18-NEXT:    fmuls {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    fmulp %st, %st(1)
+; precision18-NEXT:    fmuls {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fld1
-; precision18-NEXT:    faddp %st, %st(1)
+; precision18-NEXT:    fadds {{[0-9]+}}(%esp)
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    shll $23, %eax
 ; precision18-NEXT:    addl {{[0-9]+}}(%esp), %eax
 ; precision18-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    addl $76, %esp
+; precision18-NEXT:    addl $80, %esp
 ; precision18-NEXT:    retl
 entry:
 	%"alloca point" = bitcast i32 0 to i32		; <i32> [#uses=0]
@@ -483,18 +489,17 @@ define float @f4(float %x) nounwind noinline {
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fld %st(0)
 ; precision6-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
-; precision6-NEXT:    fstps (%esp)
+; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision6-NEXT:    andl $2139095040, %eax # imm = 0x7F800000
 ; precision6-NEXT:    shrl $23, %eax
 ; precision6-NEXT:    addl $-127, %eax
 ; precision6-NEXT:    movl %eax, {{[0-9]+}}(%esp)
-; precision6-NEXT:    flds (%esp)
+; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fildl {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision6-NEXT:    flds {{[0-9]+}}(%esp)
-; precision6-NEXT:    fmulp %st, %st(1)
+; precision6-NEXT:    fmuls {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
@@ -503,10 +508,9 @@ define float @f4(float %x) nounwind noinline {
 ; precision6-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
-; precision6-NEXT:    flds {{[0-9]+}}(%esp)
-; precision6-NEXT:    faddp %st, %st(1)
-; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision6-NEXT:    flds {{[0-9]+}}(%esp)
+; precision6-NEXT:    fadds {{[0-9]+}}(%esp)
+; precision6-NEXT:    fstps (%esp)
+; precision6-NEXT:    flds (%esp)
 ; precision6-NEXT:    addl $36, %esp
 ; precision6-NEXT:    retl
 ;
@@ -521,18 +525,18 @@ define float @f4(float %x) nounwind noinline {
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fld %st(0)
 ; precision12-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
-; precision12-NEXT:    fstps (%esp)
-; precision12-NEXT:    flds (%esp)
-; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
-; precision12-NEXT:    fmul %st(1), %st
+; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    fld %st(0)
+; precision12-NEXT:    fmuls {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision12-NEXT:    flds {{[0-9]+}}(%esp)
-; precision12-NEXT:    fmul %st(1), %st
+; precision12-NEXT:    fld %st(0)
+; precision12-NEXT:    fmuls {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision12-NEXT:    andl $2139095040, %eax # imm = 0x7F800000
 ; precision12-NEXT:    shrl $23, %eax
@@ -543,8 +547,7 @@ define float @f4(float %x) nounwind noinline {
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fildl {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision12-NEXT:    flds {{[0-9]+}}(%esp)
-; precision12-NEXT:    fmulp %st, %st(1)
+; precision12-NEXT:    fmuls {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
@@ -553,10 +556,9 @@ define float @f4(float %x) nounwind noinline {
 ; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
-; precision12-NEXT:    flds {{[0-9]+}}(%esp)
-; precision12-NEXT:    faddp %st, %st(1)
-; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision12-NEXT:    flds {{[0-9]+}}(%esp)
+; precision12-NEXT:    fadds {{[0-9]+}}(%esp)
+; precision12-NEXT:    fstps (%esp)
+; precision12-NEXT:    flds (%esp)
 ; precision12-NEXT:    addl $52, %esp
 ; precision12-NEXT:    retl
 ;
@@ -571,30 +573,30 @@ define float @f4(float %x) nounwind noinline {
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fld %st(0)
 ; precision18-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
-; precision18-NEXT:    fstps (%esp)
-; precision18-NEXT:    flds (%esp)
-; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    fmul %st(1), %st
+; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    fld %st(0)
+; precision18-NEXT:    fmuls {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    fmul %st(1), %st
+; precision18-NEXT:    fld %st(0)
+; precision18-NEXT:    fmuls {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    fmul %st(1), %st
+; precision18-NEXT:    fld %st(0)
+; precision18-NEXT:    fmuls {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    fmul %st(1), %st
+; precision18-NEXT:    fld %st(0)
+; precision18-NEXT:    fmuls {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    andl $2139095040, %eax # imm = 0x7F800000
 ; precision18-NEXT:    shrl $23, %eax
@@ -605,8 +607,7 @@ define float @f4(float %x) nounwind noinline {
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fildl {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    fmulp %st, %st(1)
+; precision18-NEXT:    fmuls {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
@@ -615,10 +616,9 @@ define float @f4(float %x) nounwind noinline {
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    faddp %st, %st(1)
-; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision18-NEXT:    flds {{[0-9]+}}(%esp)
+; precision18-NEXT:    fadds {{[0-9]+}}(%esp)
+; precision18-NEXT:    fstps (%esp)
+; precision18-NEXT:    flds (%esp)
 ; precision18-NEXT:    addl $68, %esp
 ; precision18-NEXT:    retl
 entry:
@@ -641,26 +641,25 @@ define float @f5(float %x) nounwind noinline {
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fld %st(0)
 ; precision6-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
-; precision6-NEXT:    fstps (%esp)
-; precision6-NEXT:    flds (%esp)
-; precision6-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
-; precision6-NEXT:    fmulp %st, %st(1)
+; precision6-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision6-NEXT:    andl $2139095040, %eax # imm = 0x7F800000
 ; precision6-NEXT:    shrl $23, %eax
 ; precision6-NEXT:    addl $-127, %eax
 ; precision6-NEXT:    movl %eax, {{[0-9]+}}(%esp)
-; precision6-NEXT:    flds {{[0-9]+}}(%esp)
-; precision6-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision6-NEXT:    fmuls {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fildl {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
-; precision6-NEXT:    fadds {{[0-9]+}}(%esp)
+; precision6-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
+; precision6-NEXT:    fadds {{[0-9]+}}(%esp)
+; precision6-NEXT:    fstps (%esp)
+; precision6-NEXT:    flds (%esp)
 ; precision6-NEXT:    addl $32, %esp
 ; precision6-NEXT:    retl
 ;
@@ -675,38 +674,37 @@ define float @f5(float %x) nounwind noinline {
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fld %st(0)
 ; precision12-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
-; precision12-NEXT:    fstps (%esp)
-; precision12-NEXT:    flds (%esp)
-; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
-; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision12-NEXT:    flds {{[0-9]+}}(%esp)
-; precision12-NEXT:    fmul %st(1), %st
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision12-NEXT:    flds {{[0-9]+}}(%esp)
-; precision12-NEXT:    fmul %st(1), %st
+; precision12-NEXT:    fld %st(0)
+; precision12-NEXT:    fmuls {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    fld %st(0)
+; precision12-NEXT:    fmuls {{[0-9]+}}(%esp)
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
-; precision12-NEXT:    fmulp %st, %st(1)
+; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision12-NEXT:    andl $2139095040, %eax # imm = 0x7F800000
 ; precision12-NEXT:    shrl $23, %eax
 ; precision12-NEXT:    addl $-127, %eax
 ; precision12-NEXT:    movl %eax, {{[0-9]+}}(%esp)
-; precision12-NEXT:    flds {{[0-9]+}}(%esp)
-; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision12-NEXT:    fmuls {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fildl {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
-; precision12-NEXT:    fadds {{[0-9]+}}(%esp)
+; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
+; precision12-NEXT:    fadds {{[0-9]+}}(%esp)
+; precision12-NEXT:    fstps (%esp)
+; precision12-NEXT:    flds (%esp)
 ; precision12-NEXT:    addl $48, %esp
 ; precision12-NEXT:    retl
 ;
@@ -721,50 +719,49 @@ define float @f5(float %x) nounwind noinline {
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fld %st(0)
 ; precision18-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
-; precision18-NEXT:    fstps (%esp)
-; precision18-NEXT:    flds (%esp)
-; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
-; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    fmul %st(1), %st
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    fmul %st(1), %st
+; precision18-NEXT:    fld %st(0)
+; precision18-NEXT:    fmuls {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    fmul %st(1), %st
+; precision18-NEXT:    fld %st(0)
+; precision18-NEXT:    fmuls {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    fmul %st(1), %st
+; precision18-NEXT:    fld %st(0)
+; precision18-NEXT:    fmuls {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    fld %st(0)
+; precision18-NEXT:    fmuls {{[0-9]+}}(%esp)
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    fmulp %st, %st(1)
+; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    andl $2139095040, %eax # imm = 0x7F800000
 ; precision18-NEXT:    shrl $23, %eax
 ; precision18-NEXT:    addl $-127, %eax
 ; precision18-NEXT:    movl %eax, {{[0-9]+}}(%esp)
-; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision18-NEXT:    fmuls {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fildl {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    fadds {{[0-9]+}}(%esp)
+; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
+; precision18-NEXT:    fadds {{[0-9]+}}(%esp)
+; precision18-NEXT:    fstps (%esp)
+; precision18-NEXT:    flds (%esp)
 ; precision18-NEXT:    addl $64, %esp
 ; precision18-NEXT:    retl
 entry:
@@ -787,18 +784,17 @@ define float @f6(float %x) nounwind noinline {
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fld %st(0)
 ; precision6-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
-; precision6-NEXT:    fstps (%esp)
+; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision6-NEXT:    andl $2139095040, %eax # imm = 0x7F800000
 ; precision6-NEXT:    shrl $23, %eax
 ; precision6-NEXT:    addl $-127, %eax
 ; precision6-NEXT:    movl %eax, {{[0-9]+}}(%esp)
-; precision6-NEXT:    flds (%esp)
+; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fildl {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision6-NEXT:    flds {{[0-9]+}}(%esp)
-; precision6-NEXT:    fmulp %st, %st(1)
+; precision6-NEXT:    fmuls {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
@@ -807,10 +803,9 @@ define float @f6(float %x) nounwind noinline {
 ; precision6-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
-; precision6-NEXT:    flds {{[0-9]+}}(%esp)
-; precision6-NEXT:    faddp %st, %st(1)
-; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision6-NEXT:    flds {{[0-9]+}}(%esp)
+; precision6-NEXT:    fadds {{[0-9]+}}(%esp)
+; precision6-NEXT:    fstps (%esp)
+; precision6-NEXT:    flds (%esp)
 ; precision6-NEXT:    addl $36, %esp
 ; precision6-NEXT:    retl
 ;
@@ -825,12 +820,12 @@ define float @f6(float %x) nounwind noinline {
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fld %st(0)
 ; precision12-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
-; precision12-NEXT:    fstps (%esp)
-; precision12-NEXT:    flds (%esp)
-; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
-; precision12-NEXT:    fmul %st(1), %st
+; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision12-NEXT:    fld %st(0)
+; precision12-NEXT:    fmuls {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision12-NEXT:    andl $2139095040, %eax # imm = 0x7F800000
 ; precision12-NEXT:    shrl $23, %eax
@@ -841,8 +836,7 @@ define float @f6(float %x) nounwind noinline {
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fildl {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision12-NEXT:    flds {{[0-9]+}}(%esp)
-; precision12-NEXT:    fmulp %st, %st(1)
+; precision12-NEXT:    fmuls {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
@@ -851,10 +845,9 @@ define float @f6(float %x) nounwind noinline {
 ; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
-; precision12-NEXT:    flds {{[0-9]+}}(%esp)
-; precision12-NEXT:    faddp %st, %st(1)
-; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision12-NEXT:    flds {{[0-9]+}}(%esp)
+; precision12-NEXT:    fadds {{[0-9]+}}(%esp)
+; precision12-NEXT:    fstps (%esp)
+; precision12-NEXT:    flds (%esp)
 ; precision12-NEXT:    addl $44, %esp
 ; precision12-NEXT:    retl
 ;
@@ -869,24 +862,24 @@ define float @f6(float %x) nounwind noinline {
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fld %st(0)
 ; precision18-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
-; precision18-NEXT:    fstps (%esp)
-; precision18-NEXT:    flds (%esp)
-; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    fmul %st(1), %st
+; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
+; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
+; precision18-NEXT:    fld %st(0)
+; precision18-NEXT:    fmuls {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    fmul %st(1), %st
+; precision18-NEXT:    fld %st(0)
+; precision18-NEXT:    fmuls {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    fmul %st(1), %st
+; precision18-NEXT:    fld %st(0)
+; precision18-NEXT:    fmuls {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    andl $2139095040, %eax # imm = 0x7F800000
 ; precision18-NEXT:    shrl $23, %eax
@@ -897,8 +890,7 @@ define float @f6(float %x) nounwind noinline {
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fildl {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    fmulp %st, %st(1)
+; precision18-NEXT:    fmuls {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
@@ -907,10 +899,9 @@ define float @f6(float %x) nounwind noinline {
 ; precision18-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    faddp %st, %st(1)
-; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision18-NEXT:    flds {{[0-9]+}}(%esp)
+; precision18-NEXT:    fadds {{[0-9]+}}(%esp)
+; precision18-NEXT:    fstps (%esp)
+; precision18-NEXT:    flds (%esp)
 ; precision18-NEXT:    addl $60, %esp
 ; precision18-NEXT:    retl
 entry:
diff --git a/llvm/test/CodeGen/X86/negate-add-zero.ll b/llvm/test/CodeGen/X86/negate-add-zero.ll
index 5623fdb50fb25..77f0818f09060 100644
--- a/llvm/test/CodeGen/X86/negate-add-zero.ll
+++ b/llvm/test/CodeGen/X86/negate-add-zero.ll
@@ -827,8 +827,8 @@ declare void @_ZN21HNodeTranslateRotate311toCartesianEv(ptr)
 define linkonce void @_ZN21HNodeTranslateRotate36setVelERK9CDSVectorIdLi1EN3CDS12DefaultAllocEE(ptr %this, ptr %velv) {
 ; CHECK-LABEL: _ZN21HNodeTranslateRotate36setVelERK9CDSVectorIdLi1EN3CDS12DefaultAllocEE:
 ; CHECK:       ## %bb.0:
-; CHECK-NEXT:    subl $100, %esp
-; CHECK-NEXT:    .cfi_def_cfa_offset 104
+; CHECK-NEXT:    subl $120, %esp
+; CHECK-NEXT:    .cfi_def_cfa_offset 124
 ; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; CHECK-NEXT:    fldl 0
@@ -840,55 +840,55 @@ define linkonce void @_ZN21HNodeTranslateRotate36setVelERK9CDSVectorIdLi1EN3CDS1
 ; CHECK-NEXT:    fld %st(1)
 ; CHECK-NEXT:    fadd %st(1), %st
 ; CHECK-NEXT:    fstpl {{[0-9]+}}(%esp)
-; CHECK-NEXT:    fldl {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    fldl 3184(%ecx)
 ; CHECK-NEXT:    fld %st(0)
-; CHECK-NEXT:    fmul %st(5), %st
+; CHECK-NEXT:    fmul %st(4), %st
 ; CHECK-NEXT:    fstpl {{[0-9]+}}(%esp)
-; CHECK-NEXT:    fldl {{[0-9]+}}(%esp)
-; CHECK-NEXT:    fadd %st(3), %st
+; CHECK-NEXT:    fld %st(1)
+; CHECK-NEXT:    faddl {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    fstpl {{[0-9]+}}(%esp)
-; CHECK-NEXT:    fldl {{[0-9]+}}(%esp)
-; CHECK-NEXT:    fxch %st(5)
+; CHECK-NEXT:    fxch %st(3)
 ; CHECK-NEXT:    fmul %st, %st(0)
-; CHECK-NEXT:    fstpl (%esp)
-; CHECK-NEXT:    fldl (%esp)
-; CHECK-NEXT:    fadd %st, %st(5)
-; CHECK-NEXT:    fxch %st(5)
 ; CHECK-NEXT:    fstpl {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    fldl {{[0-9]+}}(%esp)
-; CHECK-NEXT:    fsub %st(5), %st
+; CHECK-NEXT:    fld %st(0)
+; CHECK-NEXT:    faddl {{[0-9]+}}(%esp)
+; CHECK-NEXT:    fstpl {{[0-9]+}}(%esp)
+; CHECK-NEXT:    fld %st(0)
+; CHECK-NEXT:    fsubrl {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    fstpl {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    fldl {{[0-9]+}}(%esp)
-; CHECK-NEXT:    fxch %st(1)
+; CHECK-NEXT:    fxch %st(4)
 ; CHECK-NEXT:    fmull -8
-; CHECK-NEXT:    fxch %st(1)
+; CHECK-NEXT:    fxch %st(4)
 ; CHECK-NEXT:    fstl 8
-; CHECK-NEXT:    fxch %st(1)
+; CHECK-NEXT:    fxch %st(4)
 ; CHECK-NEXT:    fstpl {{[0-9]+}}(%esp)
-; CHECK-NEXT:    fldl {{[0-9]+}}(%esp)
-; CHECK-NEXT:    fsubrp %st, %st(3)
-; CHECK-NEXT:    fxch %st(2)
+; CHECK-NEXT:    fxch %st(1)
+; CHECK-NEXT:    fsubl {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    fstpl {{[0-9]+}}(%esp)
-; CHECK-NEXT:    fldl {{[0-9]+}}(%esp)
-; CHECK-NEXT:    fsubp %st, %st(3)
-; CHECK-NEXT:    fxch %st(2)
+; CHECK-NEXT:    fxch %st(1)
+; CHECK-NEXT:    fsubrl {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    fstpl {{[0-9]+}}(%esp)
-; CHECK-NEXT:    fldl {{[0-9]+}}(%esp)
-; CHECK-NEXT:    fadd %st(3), %st
+; CHECK-NEXT:    fld %st(0)
+; CHECK-NEXT:    faddl {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    fstpl {{[0-9]+}}(%esp)
-; CHECK-NEXT:    fldl {{[0-9]+}}(%esp)
-; CHECK-NEXT:    faddp %st, %st(3)
-; CHECK-NEXT:    fxch %st(2)
+; CHECK-NEXT:    faddl {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    fstpl {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    fldl {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    fstl 16
-; CHECK-NEXT:    fxch %st(1)
+; CHECK-NEXT:    fldl {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    fadd %st, %st(0)
+; CHECK-NEXT:    fstpl {{[0-9]+}}(%esp)
+; CHECK-NEXT:    fldl {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    fxch %st(2)
 ; CHECK-NEXT:    fadd %st, %st(0)
+; CHECK-NEXT:    fstpl {{[0-9]+}}(%esp)
+; CHECK-NEXT:    fldl {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    fxch %st(1)
 ; CHECK-NEXT:    fadd %st, %st(0)
+; CHECK-NEXT:    fstpl (%esp)
+; CHECK-NEXT:    fldl (%esp)
 ; CHECK-NEXT:    fxch %st(2)
 ; CHECK-NEXT:    fstpl 2056(%ecx)
 ; CHECK-NEXT:    fstpl 2064(%ecx)
diff --git a/llvm/test/CodeGen/X86/no-ret-in-x87-reg.ll b/llvm/test/CodeGen/X86/no-ret-in-x87-reg.ll
index 89ffbd76071ef..872479328f9c6 100644
--- a/llvm/test/CodeGen/X86/no-ret-in-x87-reg.ll
+++ b/llvm/test/CodeGen/X86/no-ret-in-x87-reg.ll
@@ -88,16 +88,12 @@ entry:
 define double @f5(double %a, double %b) nounwind {
 ; X87-LABEL: f5:
 ; X87:       # %bb.0: # %entry
-; X87-NEXT:    pushl %ebp
-; X87-NEXT:    movl %esp, %ebp
-; X87-NEXT:    andl $-8, %esp
 ; X87-NEXT:    subl $8, %esp
-; X87-NEXT:    fldl 8(%ebp)
-; X87-NEXT:    faddl 16(%ebp)
+; X87-NEXT:    fldl {{[0-9]+}}(%esp)
+; X87-NEXT:    faddl {{[0-9]+}}(%esp)
 ; X87-NEXT:    fstpl (%esp)
 ; X87-NEXT:    fldl (%esp)
-; X87-NEXT:    movl %ebp, %esp
-; X87-NEXT:    popl %ebp
+; X87-NEXT:    addl $8, %esp
 ; X87-NEXT:    retl
 ;
 ; NOSSE-NOX87-LABEL: f5:
diff --git a/llvm/test/CodeGen/X86/nosse-vector.ll b/llvm/test/CodeGen/X86/nosse-vector.ll
index 746c91af19a39..dbc64997f74fc 100644
--- a/llvm/test/CodeGen/X86/nosse-vector.ll
+++ b/llvm/test/CodeGen/X86/nosse-vector.ll
@@ -5,23 +5,33 @@
 define void @fadd_2f64_mem(ptr %p0, ptr %p1, ptr %p2) nounwind {
 ; X32-LABEL: fadd_2f64_mem:
 ; X32:       # %bb.0:
+; X32-NEXT:    subl $16, %esp
 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx
 ; X32-NEXT:    fldl (%edx)
 ; X32-NEXT:    faddl (%ecx)
+; X32-NEXT:    fstpl {{[0-9]+}}(%esp)
 ; X32-NEXT:    fldl 8(%edx)
 ; X32-NEXT:    faddl 8(%ecx)
+; X32-NEXT:    fstpl (%esp)
+; X32-NEXT:    fldl {{[0-9]+}}(%esp)
+; X32-NEXT:    fldl (%esp)
 ; X32-NEXT:    fstpl 8(%eax)
 ; X32-NEXT:    fstpl (%eax)
+; X32-NEXT:    addl $16, %esp
 ; X32-NEXT:    retl
 ;
 ; X64-LABEL: fadd_2f64_mem:
 ; X64:       # %bb.0:
 ; X64-NEXT:    fldl (%rdi)
 ; X64-NEXT:    faddl (%rsi)
+; X64-NEXT:    fstpl -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    fldl 8(%rdi)
 ; X64-NEXT:    faddl 8(%rsi)
+; X64-NEXT:    fstpl -{{[0-9]+}}(%rsp)
+; X64-NEXT:    fldl -{{[0-9]+}}(%rsp)
+; X64-NEXT:    fldl -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    fstpl 8(%rdx)
 ; X64-NEXT:    fstpl (%rdx)
 ; X64-NEXT:    retq
@@ -35,33 +45,51 @@ define void @fadd_2f64_mem(ptr %p0, ptr %p1, ptr %p2) nounwind {
 define void @fadd_4f32_mem(ptr %p0, ptr %p1, ptr %p2) nounwind {
 ; X32-LABEL: fadd_4f32_mem:
 ; X32:       # %bb.0:
+; X32-NEXT:    subl $16, %esp
 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx
 ; X32-NEXT:    flds (%edx)
 ; X32-NEXT:    fadds (%ecx)
+; X32-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X32-NEXT:    flds 4(%edx)
 ; X32-NEXT:    fadds 4(%ecx)
+; X32-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X32-NEXT:    flds 8(%edx)
 ; X32-NEXT:    fadds 8(%ecx)
+; X32-NEXT:    fstps (%esp)
 ; X32-NEXT:    flds 12(%edx)
 ; X32-NEXT:    fadds 12(%ecx)
+; X32-NEXT:    fstps {{[0-9]+}}(%esp)
+; X32-NEXT:    flds {{[0-9]+}}(%esp)
+; X32-NEXT:    flds {{[0-9]+}}(%esp)
+; X32-NEXT:    flds (%esp)
+; X32-NEXT:    flds {{[0-9]+}}(%esp)
 ; X32-NEXT:    fstps 12(%eax)
 ; X32-NEXT:    fstps 8(%eax)
 ; X32-NEXT:    fstps 4(%eax)
 ; X32-NEXT:    fstps (%eax)
+; X32-NEXT:    addl $16, %esp
 ; X32-NEXT:    retl
 ;
 ; X64-LABEL: fadd_4f32_mem:
 ; X64:       # %bb.0:
 ; X64-NEXT:    flds (%rdi)
 ; X64-NEXT:    fadds (%rsi)
+; X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    flds 4(%rdi)
 ; X64-NEXT:    fadds 4(%rsi)
+; X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    flds 8(%rdi)
 ; X64-NEXT:    fadds 8(%rsi)
+; X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    flds 12(%rdi)
 ; X64-NEXT:    fadds 12(%rsi)
+; X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
+; X64-NEXT:    flds -{{[0-9]+}}(%rsp)
+; X64-NEXT:    flds -{{[0-9]+}}(%rsp)
+; X64-NEXT:    flds -{{[0-9]+}}(%rsp)
+; X64-NEXT:    flds -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    fstps 12(%rdx)
 ; X64-NEXT:    fstps 8(%rdx)
 ; X64-NEXT:    fstps 4(%rdx)
@@ -77,33 +105,51 @@ define void @fadd_4f32_mem(ptr %p0, ptr %p1, ptr %p2) nounwind {
 define void @fdiv_4f32_mem(ptr %p0, ptr %p1, ptr %p2) nounwind {
 ; X32-LABEL: fdiv_4f32_mem:
 ; X32:       # %bb.0:
+; X32-NEXT:    subl $16, %esp
 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx
 ; X32-NEXT:    flds (%edx)
 ; X32-NEXT:    fdivs (%ecx)
+; X32-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X32-NEXT:    flds 4(%edx)
 ; X32-NEXT:    fdivs 4(%ecx)
+; X32-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X32-NEXT:    flds 8(%edx)
 ; X32-NEXT:    fdivs 8(%ecx)
+; X32-NEXT:    fstps (%esp)
 ; X32-NEXT:    flds 12(%edx)
 ; X32-NEXT:    fdivs 12(%ecx)
+; X32-NEXT:    fstps {{[0-9]+}}(%esp)
+; X32-NEXT:    flds {{[0-9]+}}(%esp)
+; X32-NEXT:    flds {{[0-9]+}}(%esp)
+; X32-NEXT:    flds (%esp)
+; X32-NEXT:    flds {{[0-9]+}}(%esp)
 ; X32-NEXT:    fstps 12(%eax)
 ; X32-NEXT:    fstps 8(%eax)
 ; X32-NEXT:    fstps 4(%eax)
 ; X32-NEXT:    fstps (%eax)
+; X32-NEXT:    addl $16, %esp
 ; X32-NEXT:    retl
 ;
 ; X64-LABEL: fdiv_4f32_mem:
 ; X64:       # %bb.0:
 ; X64-NEXT:    flds (%rdi)
 ; X64-NEXT:    fdivs (%rsi)
+; X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    flds 4(%rdi)
 ; X64-NEXT:    fdivs 4(%rsi)
+; X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    flds 8(%rdi)
 ; X64-NEXT:    fdivs 8(%rsi)
+; X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    flds 12(%rdi)
 ; X64-NEXT:    fdivs 12(%rsi)
+; X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
+; X64-NEXT:    flds -{{[0-9]+}}(%rsp)
+; X64-NEXT:    flds -{{[0-9]+}}(%rsp)
+; X64-NEXT:    flds -{{[0-9]+}}(%rsp)
+; X64-NEXT:    flds -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    fstps 12(%rdx)
 ; X64-NEXT:    fstps 8(%rdx)
 ; X64-NEXT:    fstps 4(%rdx)
diff --git a/llvm/test/CodeGen/X86/peep-test-1.ll b/llvm/test/CodeGen/X86/peep-test-1.ll
index 730a7fdccbd7c..25ed22c6d7bb6 100644
--- a/llvm/test/CodeGen/X86/peep-test-1.ll
+++ b/llvm/test/CodeGen/X86/peep-test-1.ll
@@ -4,6 +4,7 @@
 define void @foo(i32 %n, ptr nocapture %p) nounwind {
 ; CHECK-LABEL: foo:
 ; CHECK:       # %bb.0:
+; CHECK-NEXT:    subl $8, %esp
 ; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; CHECK-NEXT:    .p2align 4
@@ -11,10 +12,13 @@ define void @foo(i32 %n, ptr nocapture %p) nounwind {
 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
 ; CHECK-NEXT:    fldl (%eax,%ecx,8)
 ; CHECK-NEXT:    fmull {{\.?LCPI[0-9]+_[0-9]+}}
+; CHECK-NEXT:    fstpl (%esp)
+; CHECK-NEXT:    fldl (%esp)
 ; CHECK-NEXT:    fstpl (%eax,%ecx,8)
 ; CHECK-NEXT:    decl %ecx
 ; CHECK-NEXT:    js .LBB0_1
 ; CHECK-NEXT:  # %bb.2: # %return
+; CHECK-NEXT:    addl $8, %esp
 ; CHECK-NEXT:    retl
 	br label %bb
 
diff --git a/llvm/test/CodeGen/X86/powi-const.ll b/llvm/test/CodeGen/X86/powi-const.ll
index 594e252d5f7ec..1b1735dac7f5b 100644
--- a/llvm/test/CodeGen/X86/powi-const.ll
+++ b/llvm/test/CodeGen/X86/powi-const.ll
@@ -8,34 +8,28 @@
 define double @pow_wrapper(double %a) nounwind readonly ssp noredzone {
 ; X86-X87-LABEL: pow_wrapper:
 ; X86-X87:       # %bb.0:
-; X86-X87-NEXT:    pushl %ebp
-; X86-X87-NEXT:    movl %esp, %ebp
-; X86-X87-NEXT:    andl $-8, %esp
 ; X86-X87-NEXT:    subl $48, %esp
-; X86-X87-NEXT:    fldl 8(%ebp)
-; X86-X87-NEXT:    fld %st(0)
-; X86-X87-NEXT:    fmul %st(1), %st
-; X86-X87-NEXT:    fstpl (%esp)
-; X86-X87-NEXT:    fldl (%esp)
+; X86-X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-X87-NEXT:    fld %st(0)
 ; X86-X87-NEXT:    fmul %st(1), %st
 ; X86-X87-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X86-X87-NEXT:    fmulp %st, %st(1)
-; X86-X87-NEXT:    fstpl {{[0-9]+}}(%esp)
 ; X86-X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-X87-NEXT:    fld %st(0)
 ; X86-X87-NEXT:    fmul %st(1), %st
 ; X86-X87-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X86-X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-X87-NEXT:    fmulp %st, %st(1)
 ; X86-X87-NEXT:    fstpl {{[0-9]+}}(%esp)
 ; X86-X87-NEXT:    fldl {{[0-9]+}}(%esp)
-; X86-X87-NEXT:    fldl {{[0-9]+}}(%esp)
-; X86-X87-NEXT:    fmulp %st, %st(1)
+; X86-X87-NEXT:    fld %st(0)
+; X86-X87-NEXT:    fmull {{[0-9]+}}(%esp)
+; X86-X87-NEXT:    fstpl {{[0-9]+}}(%esp)
+; X86-X87-NEXT:    fmul %st, %st(0)
 ; X86-X87-NEXT:    fstpl {{[0-9]+}}(%esp)
 ; X86-X87-NEXT:    fldl {{[0-9]+}}(%esp)
-; X86-X87-NEXT:    movl %ebp, %esp
-; X86-X87-NEXT:    popl %ebp
+; X86-X87-NEXT:    fmull {{[0-9]+}}(%esp)
+; X86-X87-NEXT:    fstpl (%esp)
+; X86-X87-NEXT:    fldl (%esp)
+; X86-X87-NEXT:    addl $48, %esp
 ; X86-X87-NEXT:    retl
 ;
 ; X86-SSE-LABEL: pow_wrapper:
diff --git a/llvm/test/CodeGen/X86/pr1505b.ll b/llvm/test/CodeGen/X86/pr1505b.ll
index 4e2383da38789..3f6e6d938c6eb 100644
--- a/llvm/test/CodeGen/X86/pr1505b.ll
+++ b/llvm/test/CodeGen/X86/pr1505b.ll
@@ -34,22 +34,20 @@ define i32 @main() nounwind {
 ; CHECK-LABEL: main:
 ; CHECK:       ## %bb.0: ## %entry
 ; CHECK-NEXT:    pushl %esi
-; CHECK-NEXT:    subl $40, %esp
+; CHECK-NEXT:    subl $24, %esp
 ; CHECK-NEXT:    flds _a
 ; CHECK-NEXT:    fstps (%esp)
 ; CHECK-NEXT:    calll _tanf
-; CHECK-NEXT:    fstpl 24(%esp) ## 8-byte Folded Spill
+; CHECK-NEXT:    fstpl 16(%esp) ## 8-byte Folded Spill
 ; CHECK-NEXT:    fldl _b
 ; CHECK-NEXT:    fstpl (%esp)
 ; CHECK-NEXT:    calll _tan
-; CHECK-NEXT:    fstps 20(%esp)
-; CHECK-NEXT:    flds 20(%esp)
-; CHECK-NEXT:    fstpl 32(%esp) ## 8-byte Folded Spill
+; CHECK-NEXT:    fstps 12(%esp)
 ; CHECK-NEXT:    movl L__ZSt4cout$non_lazy_ptr, %esi
 ; CHECK-NEXT:    movl %esi, (%esp)
 ; CHECK-NEXT:    movl $_.str, 4(%esp)
 ; CHECK-NEXT:    calll __ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
-; CHECK-NEXT:    fldl 24(%esp) ## 8-byte Folded Reload
+; CHECK-NEXT:    fldl 16(%esp) ## 8-byte Folded Reload
 ; CHECK-NEXT:    fstpl 4(%esp)
 ; CHECK-NEXT:    movl %eax, (%esp)
 ; CHECK-NEXT:    calll __ZNSolsEd
@@ -58,14 +56,14 @@ define i32 @main() nounwind {
 ; CHECK-NEXT:    movl %esi, (%esp)
 ; CHECK-NEXT:    movl $_.str1, 4(%esp)
 ; CHECK-NEXT:    calll __ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
-; CHECK-NEXT:    fldl 32(%esp) ## 8-byte Folded Reload
+; CHECK-NEXT:    flds 12(%esp)
 ; CHECK-NEXT:    fstpl 4(%esp)
 ; CHECK-NEXT:    movl %eax, (%esp)
 ; CHECK-NEXT:    calll __ZNSolsEd
 ; CHECK-NEXT:    movl %eax, (%esp)
 ; CHECK-NEXT:    calll __ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
 ; CHECK-NEXT:    xorl %eax, %eax
-; CHECK-NEXT:    addl $40, %esp
+; CHECK-NEXT:    addl $24, %esp
 ; CHECK-NEXT:    popl %esi
 ; CHECK-NEXT:    retl
 entry:
diff --git a/llvm/test/CodeGen/X86/pr50782.ll b/llvm/test/CodeGen/X86/pr50782.ll
index 7e6c971e32b2a..cf4e51ad11c21 100644
--- a/llvm/test/CodeGen/X86/pr50782.ll
+++ b/llvm/test/CodeGen/X86/pr50782.ll
@@ -70,14 +70,14 @@ define void @h(float %i) {
 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
 ; CHECK-NEXT:    fld %st(5)
 ; CHECK-NEXT:    fmul %st(2), %st
+; CHECK-NEXT:    fstps 20(%esi)
+; CHECK-NEXT:    fld %st(4)
+; CHECK-NEXT:    fdivrs 20(%esi)
+; CHECK-NEXT:    fstps 16(%esi)
+; CHECK-NEXT:    fld %st(3)
+; CHECK-NEXT:    fadds 16(%esi)
 ; CHECK-NEXT:    fstps 12(%esi)
 ; CHECK-NEXT:    flds 12(%esi)
-; CHECK-NEXT:    fdiv %st(5), %st
-; CHECK-NEXT:    fstps 16(%esi)
-; CHECK-NEXT:    flds 16(%esi)
-; CHECK-NEXT:    fadd %st(4), %st
-; CHECK-NEXT:    fstps 20(%esi)
-; CHECK-NEXT:    flds 20(%esi)
 ; CHECK-NEXT:    fsts _g
 ; CHECK-NEXT:    fxch %st(3)
 ; CHECK-NEXT:    fucom %st(3)
diff --git a/llvm/test/CodeGen/X86/select.ll b/llvm/test/CodeGen/X86/select.ll
index 376615258ea20..eb63b4ed4693e 100644
--- a/llvm/test/CodeGen/X86/select.ll
+++ b/llvm/test/CodeGen/X86/select.ll
@@ -305,14 +305,14 @@ define void @test6(i32 %C, ptr %A, ptr %B) nounwind {
 ; ATHLON-NEXT:    fstps {{[0-9]+}}(%esp)
 ; ATHLON-NEXT:    flds 8(%ecx)
 ; ATHLON-NEXT:    fmul %st, %st(0)
-; ATHLON-NEXT:    fstps {{[0-9]+}}(%esp)
+; ATHLON-NEXT:    fstps (%esp)
 ; ATHLON-NEXT:    flds 4(%ecx)
 ; ATHLON-NEXT:    fmul %st, %st(0)
 ; ATHLON-NEXT:    fstps {{[0-9]+}}(%esp)
 ; ATHLON-NEXT:    flds (%ecx)
 ; ATHLON-NEXT:    fmul %st, %st(0)
-; ATHLON-NEXT:    fstps (%esp)
-; ATHLON-NEXT:    flds (%esp)
+; ATHLON-NEXT:    fstps {{[0-9]+}}(%esp)
+; ATHLON-NEXT:    flds {{[0-9]+}}(%esp)
 ; ATHLON-NEXT:    cmpl $0, {{[0-9]+}}(%esp)
 ; ATHLON-NEXT:    fxch %st(1)
 ; ATHLON-NEXT:    fcmove %st(1), %st
@@ -321,7 +321,7 @@ define void @test6(i32 %C, ptr %A, ptr %B) nounwind {
 ; ATHLON-NEXT:    fxch %st(2)
 ; ATHLON-NEXT:    fcmove %st(2), %st
 ; ATHLON-NEXT:    fstp %st(2)
-; ATHLON-NEXT:    flds {{[0-9]+}}(%esp)
+; ATHLON-NEXT:    flds (%esp)
 ; ATHLON-NEXT:    fxch %st(3)
 ; ATHLON-NEXT:    fcmove %st(3), %st
 ; ATHLON-NEXT:    fstp %st(3)
diff --git a/llvm/test/CodeGen/X86/sincos-stack-args.ll b/llvm/test/CodeGen/X86/sincos-stack-args.ll
index 42c05a3e7a9be..e94bb91b9c606 100644
--- a/llvm/test/CodeGen/X86/sincos-stack-args.ll
+++ b/llvm/test/CodeGen/X86/sincos-stack-args.ll
@@ -12,15 +12,17 @@ define double @negative_sincos_with_stores_within_call_sequence(double %a) nounw
 ; CHECK:       # %bb.0: # %entry
 ; CHECK-NEXT:    subl $44, %esp
 ; CHECK-NEXT:    fldl 48(%esp)
-; CHECK-NEXT:    leal 24(%esp), %eax
+; CHECK-NEXT:    leal 16(%esp), %eax
 ; CHECK-NEXT:    movl %eax, 12(%esp)
-; CHECK-NEXT:    leal 32(%esp), %eax
+; CHECK-NEXT:    leal 24(%esp), %eax
 ; CHECK-NEXT:    movl %eax, 8(%esp)
 ; CHECK-NEXT:    fstpl (%esp)
 ; CHECK-NEXT:    calll sincos
-; CHECK-NEXT:    fldl 32(%esp)
 ; CHECK-NEXT:    fldl 24(%esp)
+; CHECK-NEXT:    fldl 16(%esp)
 ; CHECK-NEXT:    faddl {{\.?LCPI[0-9]+_[0-9]+}}
+; CHECK-NEXT:    fstpl 36(%esp)
+; CHECK-NEXT:    fldl 36(%esp)
 ; CHECK-NEXT:    fxch %st(1)
 ; CHECK-NEXT:    fstpl 8(%esp)
 ; CHECK-NEXT:    fstpl (%esp)
diff --git a/llvm/test/CodeGen/X86/x87-round-to-type.ll b/llvm/test/CodeGen/X86/x87-round-to-type.ll
index 468cc362b2444..cdfbd661bb7eb 100644
--- a/llvm/test/CodeGen/X86/x87-round-to-type.ll
+++ b/llvm/test/CodeGen/X86/x87-round-to-type.ll
@@ -43,7 +43,7 @@ define i32 @cmp_reload_f32(float %a, float %b, ptr %p) nounwind {
 define i32 @cmp_reload_f64(double %a, double %b, ptr %p) nounwind {
 ; X87-LABEL: cmp_reload_f64:
 ; X87:       # %bb.0:
-; X87-NEXT:    subl $12, %esp
+; X87-NEXT:    subl $8, %esp
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    faddl {{[0-9]+}}(%esp)
@@ -60,7 +60,7 @@ define i32 @cmp_reload_f64(double %a, double %b, ptr %p) nounwind {
 ; X87-NEXT:    sete %cl
 ; X87-NEXT:    andb %al, %cl
 ; X87-NEXT:    movzbl %cl, %eax
-; X87-NEXT:    addl $12, %esp
+; X87-NEXT:    addl $8, %esp
 ; X87-NEXT:    retl
   %add = fadd double %a, %b
   store volatile double %add, ptr %p
@@ -145,12 +145,12 @@ define float @fsqrt_f32(float %a) nounwind {
 define double @fadd_f64(double %a, double %b) nounwind {
 ; X87-LABEL: fadd_f64:
 ; X87:       # %bb.0:
-; X87-NEXT:    subl $12, %esp
+; X87-NEXT:    subl $8, %esp
 ; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    faddl {{[0-9]+}}(%esp)
 ; X87-NEXT:    fstpl (%esp)
 ; X87-NEXT:    fldl (%esp)
-; X87-NEXT:    addl $12, %esp
+; X87-NEXT:    addl $8, %esp
 ; X87-NEXT:    retl
   %r = fadd double %a, %b
   ret double %r
@@ -159,12 +159,12 @@ define double @fadd_f64(double %a, double %b) nounwind {
 define double @fsqrt_f64(double %a) nounwind {
 ; X87-LABEL: fsqrt_f64:
 ; X87:       # %bb.0:
-; X87-NEXT:    subl $12, %esp
+; X87-NEXT:    subl $8, %esp
 ; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    fsqrt
 ; X87-NEXT:    fstpl (%esp)
 ; X87-NEXT:    fldl (%esp)
-; X87-NEXT:    addl $12, %esp
+; X87-NEXT:    addl $8, %esp
 ; X87-NEXT:    retl
   %r = call double @llvm.sqrt.f64(double %a)
   ret double %r
@@ -226,10 +226,14 @@ define float @fabs_f32(float %a) nounwind {
 define void @store_only_f32(float %a, float %b, ptr %p) nounwind {
 ; X87-LABEL: store_only_f32:
 ; X87:       # %bb.0:
+; X87-NEXT:    pushl %eax
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    fadds {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps (%esp)
+; X87-NEXT:    flds (%esp)
 ; X87-NEXT:    fstps (%eax)
+; X87-NEXT:    popl %eax
 ; X87-NEXT:    retl
   %r = fadd float %a, %b
   store float %r, ptr %p
@@ -239,10 +243,14 @@ define void @store_only_f32(float %a, float %b, ptr %p) nounwind {
 define void @store_only_f64(double %a, double %b, ptr %p) nounwind {
 ; X87-LABEL: store_only_f64:
 ; X87:       # %bb.0:
+; X87-NEXT:    subl $8, %esp
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    faddl {{[0-9]+}}(%esp)
+; X87-NEXT:    fstpl (%esp)
+; X87-NEXT:    fldl (%esp)
 ; X87-NEXT:    fstpl (%eax)
+; X87-NEXT:    addl $8, %esp
 ; X87-NEXT:    retl
   %r = fadd double %a, %b
   store double %r, ptr %p
@@ -292,16 +300,16 @@ define float @store_and_use_f32(float %a, float %b, ptr %p) nounwind {
 define void @store_narrower_f32(double %a, double %b, ptr %p) nounwind {
 ; X87-LABEL: store_narrower_f32:
 ; X87:       # %bb.0:
-; X87-NEXT:    subl $20, %esp
+; X87-NEXT:    subl $12, %esp
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    faddl {{[0-9]+}}(%esp)
 ; X87-NEXT:    fstpl {{[0-9]+}}(%esp)
 ; X87-NEXT:    fldl {{[0-9]+}}(%esp)
-; X87-NEXT:    fstps {{[0-9]+}}(%esp)
-; X87-NEXT:    flds {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps (%esp)
+; X87-NEXT:    flds (%esp)
 ; X87-NEXT:    fstps (%eax)
-; X87-NEXT:    addl $20, %esp
+; X87-NEXT:    addl $12, %esp
 ; X87-NEXT:    retl
   %r = fadd double %a, %b
   %t = fptrunc double %r to float
@@ -484,11 +492,11 @@ define float @fptrunc_f80_f32(x86_fp80 %a) nounwind {
 define double @fptrunc_f80_f64(x86_fp80 %a) nounwind {
 ; X87-LABEL: fptrunc_f80_f64:
 ; X87:       # %bb.0:
-; X87-NEXT:    subl $12, %esp
+; X87-NEXT:    subl $8, %esp
 ; X87-NEXT:    fldt {{[0-9]+}}(%esp)
 ; X87-NEXT:    fstpl (%esp)
 ; X87-NEXT:    fldl (%esp)
-; X87-NEXT:    addl $12, %esp
+; X87-NEXT:    addl $8, %esp
 ; X87-NEXT:    retl
   %r = fptrunc x86_fp80 %a to double
   ret double %r
@@ -545,15 +553,14 @@ define float @chain_f32(float %a, float %b, float %c, float %d) nounwind {
 ; X87-NEXT:    subl $12, %esp
 ; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    fmuls {{[0-9]+}}(%esp)
-; X87-NEXT:    fstps (%esp)
-; X87-NEXT:    flds (%esp)
-; X87-NEXT:    flds {{[0-9]+}}(%esp)
-; X87-NEXT:    fmuls {{[0-9]+}}(%esp)
 ; X87-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X87-NEXT:    flds {{[0-9]+}}(%esp)
-; X87-NEXT:    faddp %st, %st(1)
+; X87-NEXT:    fmuls {{[0-9]+}}(%esp)
 ; X87-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X87-NEXT:    flds {{[0-9]+}}(%esp)
+; X87-NEXT:    fadds {{[0-9]+}}(%esp)
+; X87-NEXT:    fstps (%esp)
+; X87-NEXT:    flds (%esp)
 ; X87-NEXT:    addl $12, %esp
 ; X87-NEXT:    retl
   %ab = fmul float %a, %b

>From 5824948685645c947bd22bb41f794eb660396fab Mon Sep 17 00:00:00 2001
From: Dennis Duda <git at seri.tools>
Date: Sun, 9 Aug 2026 01:13:42 +0200
Subject: [PATCH 06/15] [X86] Combine store(fp_round X) -> fst X

If all users of a round are stores to the same type we just rounded already, replace the rounds with those stores: `fst` rounds on the way to memory for every width the x87 stack can hold.

Use `fst` rather than a generic truncating store, which cannot express the f64 -> f32 case: X86 expands that one, because with SSE2 it takes a `cvtsd2ss` first, while on the x87 stack `ST_Fp64m32` does it in one instruction.

Only after legalization: before it, the round is still a generic one the combiner may want to fold away.

Co-authored-by: Claude (Claude-Opus-5) <noreply at anthropic.com>
---
 llvm/lib/Target/X86/X86ISelLowering.cpp       |  51 +++
 llvm/test/CodeGen/X86/atomic-fp.ll            | 320 ++++++------------
 .../test/CodeGen/X86/bfloat-int64-cvt-i686.ll |   4 -
 llvm/test/CodeGen/X86/canonicalize-vars.ll    | 104 ++----
 llvm/test/CodeGen/X86/fmf-flags.ll            |  20 +-
 llvm/test/CodeGen/X86/isel-x87.ll             |   6 -
 llvm/test/CodeGen/X86/ldexp.ll                |  30 +-
 llvm/test/CodeGen/X86/limited-prec.ll         |  54 +--
 llvm/test/CodeGen/X86/llvm.frexp.ll           |  58 ++--
 llvm/test/CodeGen/X86/negate-add-zero.ll      |  14 +-
 llvm/test/CodeGen/X86/nosse-vector.ll         |  46 ---
 llvm/test/CodeGen/X86/peep-test-1.ll          |   4 -
 llvm/test/CodeGen/X86/pr59305.ll              |  10 +-
 llvm/test/CodeGen/X86/sincos-stack-args.ll    |   8 +-
 llvm/test/CodeGen/X86/x87-round-to-type.ll    |  22 +-
 15 files changed, 244 insertions(+), 507 deletions(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 70551556aeb6b..857af81b1718a 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -22872,6 +22872,21 @@ SDValue X86TargetLowering::LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const {
   return DAG.getNode(X86ISD::VFPEXT, DL, VT, Res);
 }
 
+/// Returns true if every user of \p Op is a store that writes exactly \p Op's
+/// own type. FST rounds on the way to memory, so such a store already performs
+/// the rounding an x87 FP_ROUND stands for; combineStore turns each of them
+/// into a truncating store, which leaves the round dead.
+static bool isX87RoundDoneByStores(SDValue Op) {
+  EVT VT = Op.getValueType();
+  // A truncating store, or one of a narrower type, would round past VT instead,
+  // which is not the same as rounding to VT first.
+  return !Op->use_empty() && all_of(Op->users(), [&](SDNode *U) {
+    auto *St = dyn_cast<StoreSDNode>(U);
+    return St && !St->isTruncatingStore() && St->getMemoryVT() == VT &&
+           St->getValue() == Op;
+  });
+}
+
 SDValue X86TargetLowering::LowerFP_ROUND(SDValue Op, SelectionDAG &DAG) const {
   bool IsStrict = Op->isStrictFPOpcode();
 
@@ -22967,6 +22982,11 @@ SDValue X86TargetLowering::LowerFP_ROUND(SDValue Op, SelectionDAG &DAG) const {
   }
 
   if (needsX87RoundToType(VT) && isScalarFPTypeOnX87Stack(SVT)) {
+    // Leave the round alone when the stores that consume it already do it;
+    // combineStore turns those into truncating stores.
+    if (isX87RoundDoneByStores(Op))
+      return Op;
+
     SDValue Res;
     Chain = IsStrict ? Op.getOperand(0) : DAG.getEntryNode();
     std::tie(Res, Chain) = RoundX87ToType(VT, DL, Chain, In, DAG);
@@ -55381,6 +55401,37 @@ static SDValue combineStore(SDNode *N, SelectionDAG &DAG,
   EVT VT = StoredVal.getValueType();
   const TargetLowering &TLI = DAG.getTargetLoweringInfo();
 
+  // store (fp_round X) -> fst X, when the round exists only to force an x87
+  // value to its own type: fst already rounds on the way to memory.
+  // LowerFP_ROUND only leaves such a round in the DAG when every one of its
+  // users is a store like this one.
+  // Only after legalization: before it, the rounds are still the generic ones
+  // the combiner is free to fold away - a constant one folds to the narrow
+  // type, which beats materializing the wide value and rounding it here.
+  bool IsX87Round = DCI.isAfterLegalizeDAG() &&
+                    (StoredVal.getOpcode() == ISD::FP_ROUND ||
+                     StoredVal.getOpcode() == ISD::STRICT_FP_ROUND);
+  if (IsX87Round && St->isUnindexed() && !St->isTruncatingStore() &&
+      VT == StVT) {
+    const X86TargetLowering &XTLI = *Subtarget.getTargetLowering();
+    bool IsStrict = StoredVal->isStrictFPOpcode();
+    SDValue Src = StoredVal.getOperand(IsStrict ? 1 : 0);
+    if (XTLI.needsX87RoundToType(VT) &&
+        XTLI.isScalarFPTypeOnX87Stack(Src.getValueType())) {
+      // A strict round is ordered, so a store that took its chain from the
+      // round has to take the round's own input chain instead once the round
+      // goes away. A store ordered after a sibling store keeps its chain.
+      SDValue Chain = St->getChain();
+      if (IsStrict && Chain == StoredVal.getValue(1))
+        Chain = StoredVal.getOperand(0);
+      // Not a truncating store: f64 -> f32 is expanded for SSE, but on the x87
+      // stack ST_Fp64m32 does it in one instruction.
+      return DAG.getMemIntrinsicNode(X86ISD::FST, dl, DAG.getVTList(MVT::Other),
+                                     {Chain, Src, St->getBasePtr()}, VT,
+                                     St->getMemOperand());
+    }
+  }
+
   // Pattern: store(trunc(load vXiY) to vXiZ) optimization
   SDValue Src;
   if (!St->isTruncatingStore() && Subtarget.hasAVX512()) {
diff --git a/llvm/test/CodeGen/X86/atomic-fp.ll b/llvm/test/CodeGen/X86/atomic-fp.ll
index 37ff7cfed7a58..2dee1d12e7255 100644
--- a/llvm/test/CodeGen/X86/atomic-fp.ll
+++ b/llvm/test/CodeGen/X86/atomic-fp.ll
@@ -13,18 +13,16 @@
 define dso_local void @fadd_32r(ptr %loc, float %val) nounwind {
 ; X86-NOSSE-LABEL: fadd_32r:
 ; X86-NOSSE:       # %bb.0:
-; X86-NOSSE-NEXT:    subl $12, %esp
+; X86-NOSSE-NEXT:    subl $8, %esp
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NOSSE-NEXT:    movl (%eax), %ecx
-; X86-NOSSE-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    flds {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    fadds {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    fstps (%esp)
+; X86-NOSSE-NEXT:    movl %ecx, (%esp)
 ; X86-NOSSE-NEXT:    flds (%esp)
+; X86-NOSSE-NEXT:    fadds {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; X86-NOSSE-NEXT:    movl %ecx, (%eax)
-; X86-NOSSE-NEXT:    addl $12, %esp
+; X86-NOSSE-NEXT:    addl $8, %esp
 ; X86-NOSSE-NEXT:    retl
 ;
 ; X86-SSE1-LABEL: fadd_32r:
@@ -82,7 +80,7 @@ define dso_local void @fadd_64r(ptr %loc, double %val) nounwind {
 ; X86-NOSSE-NEXT:    pushl %ebp
 ; X86-NOSSE-NEXT:    movl %esp, %ebp
 ; X86-NOSSE-NEXT:    andl $-8, %esp
-; X86-NOSSE-NEXT:    subl $32, %esp
+; X86-NOSSE-NEXT:    subl $24, %esp
 ; X86-NOSSE-NEXT:    movl 8(%ebp), %eax
 ; X86-NOSSE-NEXT:    fildll (%eax)
 ; X86-NOSSE-NEXT:    fistpll {{[0-9]+}}(%esp)
@@ -92,8 +90,6 @@ define dso_local void @fadd_64r(ptr %loc, double %val) nounwind {
 ; X86-NOSSE-NEXT:    movl %ecx, (%esp)
 ; X86-NOSSE-NEXT:    fldl (%esp)
 ; X86-NOSSE-NEXT:    faddl 12(%ebp)
-; X86-NOSSE-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fstpl (%eax)
 ; X86-NOSSE-NEXT:    movl %ebp, %esp
 ; X86-NOSSE-NEXT:    popl %ebp
@@ -104,7 +100,7 @@ define dso_local void @fadd_64r(ptr %loc, double %val) nounwind {
 ; X86-SSE1-NEXT:    pushl %ebp
 ; X86-SSE1-NEXT:    movl %esp, %ebp
 ; X86-SSE1-NEXT:    andl $-8, %esp
-; X86-SSE1-NEXT:    subl $24, %esp
+; X86-SSE1-NEXT:    subl $16, %esp
 ; X86-SSE1-NEXT:    movl 8(%ebp), %eax
 ; X86-SSE1-NEXT:    xorps %xmm0, %xmm0
 ; X86-SSE1-NEXT:    movlps {{.*#+}} xmm0 = mem[0,1],xmm0[2,3]
@@ -113,8 +109,6 @@ define dso_local void @fadd_64r(ptr %loc, double %val) nounwind {
 ; X86-SSE1-NEXT:    movss %xmm0, {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fldl (%esp)
 ; X86-SSE1-NEXT:    faddl 12(%ebp)
-; X86-SSE1-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X86-SSE1-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fstpl (%eax)
 ; X86-SSE1-NEXT:    movl %ebp, %esp
 ; X86-SSE1-NEXT:    popl %ebp
@@ -174,17 +168,15 @@ define dso_local void @fadd_64r(ptr %loc, double %val) nounwind {
 define dso_local void @fadd_32g() nounwind {
 ; X86-NOSSE-LABEL: fadd_32g:
 ; X86-NOSSE:       # %bb.0:
-; X86-NOSSE-NEXT:    subl $12, %esp
+; X86-NOSSE-NEXT:    subl $8, %esp
 ; X86-NOSSE-NEXT:    movl glob32, %eax
-; X86-NOSSE-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    movl %eax, (%esp)
 ; X86-NOSSE-NEXT:    fld1
-; X86-NOSSE-NEXT:    fadds {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    fstps (%esp)
-; X86-NOSSE-NEXT:    flds (%esp)
+; X86-NOSSE-NEXT:    fadds (%esp)
 ; X86-NOSSE-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NOSSE-NEXT:    movl %eax, glob32
-; X86-NOSSE-NEXT:    addl $12, %esp
+; X86-NOSSE-NEXT:    addl $8, %esp
 ; X86-NOSSE-NEXT:    retl
 ;
 ; X86-SSE1-LABEL: fadd_32g:
@@ -241,7 +233,7 @@ define dso_local void @fadd_64g() nounwind {
 ; X86-NOSSE-NEXT:    pushl %ebp
 ; X86-NOSSE-NEXT:    movl %esp, %ebp
 ; X86-NOSSE-NEXT:    andl $-8, %esp
-; X86-NOSSE-NEXT:    subl $32, %esp
+; X86-NOSSE-NEXT:    subl $24, %esp
 ; X86-NOSSE-NEXT:    fildll glob64
 ; X86-NOSSE-NEXT:    fistpll {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
@@ -250,8 +242,6 @@ define dso_local void @fadd_64g() nounwind {
 ; X86-NOSSE-NEXT:    movl %eax, (%esp)
 ; X86-NOSSE-NEXT:    fld1
 ; X86-NOSSE-NEXT:    faddl (%esp)
-; X86-NOSSE-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fstpl glob64
 ; X86-NOSSE-NEXT:    movl %ebp, %esp
 ; X86-NOSSE-NEXT:    popl %ebp
@@ -262,7 +252,7 @@ define dso_local void @fadd_64g() nounwind {
 ; X86-SSE1-NEXT:    pushl %ebp
 ; X86-SSE1-NEXT:    movl %esp, %ebp
 ; X86-SSE1-NEXT:    andl $-8, %esp
-; X86-SSE1-NEXT:    subl $24, %esp
+; X86-SSE1-NEXT:    subl $16, %esp
 ; X86-SSE1-NEXT:    xorps %xmm0, %xmm0
 ; X86-SSE1-NEXT:    movlps {{.*#+}} xmm0 = mem[0,1],xmm0[2,3]
 ; X86-SSE1-NEXT:    movss %xmm0, (%esp)
@@ -270,8 +260,6 @@ define dso_local void @fadd_64g() nounwind {
 ; X86-SSE1-NEXT:    movss %xmm0, {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fld1
 ; X86-SSE1-NEXT:    faddl (%esp)
-; X86-SSE1-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X86-SSE1-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fstpl glob64
 ; X86-SSE1-NEXT:    movl %ebp, %esp
 ; X86-SSE1-NEXT:    popl %ebp
@@ -328,17 +316,15 @@ define dso_local void @fadd_64g() nounwind {
 define dso_local void @fadd_32imm() nounwind {
 ; X86-NOSSE-LABEL: fadd_32imm:
 ; X86-NOSSE:       # %bb.0:
-; X86-NOSSE-NEXT:    subl $12, %esp
+; X86-NOSSE-NEXT:    subl $8, %esp
 ; X86-NOSSE-NEXT:    movl -559038737, %eax
-; X86-NOSSE-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    movl %eax, (%esp)
 ; X86-NOSSE-NEXT:    fld1
-; X86-NOSSE-NEXT:    fadds {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    fstps (%esp)
-; X86-NOSSE-NEXT:    flds (%esp)
+; X86-NOSSE-NEXT:    fadds (%esp)
 ; X86-NOSSE-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NOSSE-NEXT:    movl %eax, -559038737
-; X86-NOSSE-NEXT:    addl $12, %esp
+; X86-NOSSE-NEXT:    addl $8, %esp
 ; X86-NOSSE-NEXT:    retl
 ;
 ; X86-SSE1-LABEL: fadd_32imm:
@@ -397,7 +383,7 @@ define dso_local void @fadd_64imm() nounwind {
 ; X86-NOSSE-NEXT:    pushl %ebp
 ; X86-NOSSE-NEXT:    movl %esp, %ebp
 ; X86-NOSSE-NEXT:    andl $-8, %esp
-; X86-NOSSE-NEXT:    subl $32, %esp
+; X86-NOSSE-NEXT:    subl $24, %esp
 ; X86-NOSSE-NEXT:    fildll -559038737
 ; X86-NOSSE-NEXT:    fistpll {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
@@ -406,8 +392,6 @@ define dso_local void @fadd_64imm() nounwind {
 ; X86-NOSSE-NEXT:    movl %eax, (%esp)
 ; X86-NOSSE-NEXT:    fld1
 ; X86-NOSSE-NEXT:    faddl (%esp)
-; X86-NOSSE-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fstpl -559038737
 ; X86-NOSSE-NEXT:    movl %ebp, %esp
 ; X86-NOSSE-NEXT:    popl %ebp
@@ -418,7 +402,7 @@ define dso_local void @fadd_64imm() nounwind {
 ; X86-SSE1-NEXT:    pushl %ebp
 ; X86-SSE1-NEXT:    movl %esp, %ebp
 ; X86-SSE1-NEXT:    andl $-8, %esp
-; X86-SSE1-NEXT:    subl $24, %esp
+; X86-SSE1-NEXT:    subl $16, %esp
 ; X86-SSE1-NEXT:    xorps %xmm0, %xmm0
 ; X86-SSE1-NEXT:    movlps {{.*#+}} xmm0 = mem[0,1],xmm0[2,3]
 ; X86-SSE1-NEXT:    movss %xmm0, (%esp)
@@ -426,8 +410,6 @@ define dso_local void @fadd_64imm() nounwind {
 ; X86-SSE1-NEXT:    movss %xmm0, {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fld1
 ; X86-SSE1-NEXT:    faddl (%esp)
-; X86-SSE1-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X86-SSE1-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fstpl -559038737
 ; X86-SSE1-NEXT:    movl %ebp, %esp
 ; X86-SSE1-NEXT:    popl %ebp
@@ -486,17 +468,15 @@ define dso_local void @fadd_64imm() nounwind {
 define dso_local void @fadd_32stack() nounwind {
 ; X86-NOSSE-LABEL: fadd_32stack:
 ; X86-NOSSE:       # %bb.0:
-; X86-NOSSE-NEXT:    subl $16, %esp
+; X86-NOSSE-NEXT:    subl $12, %esp
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NOSSE-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    movl %eax, (%esp)
 ; X86-NOSSE-NEXT:    fld1
-; X86-NOSSE-NEXT:    fadds {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    fstps (%esp)
-; X86-NOSSE-NEXT:    flds (%esp)
+; X86-NOSSE-NEXT:    fadds (%esp)
 ; X86-NOSSE-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NOSSE-NEXT:    movl %eax, {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    addl $16, %esp
+; X86-NOSSE-NEXT:    addl $12, %esp
 ; X86-NOSSE-NEXT:    retl
 ;
 ; X86-SSE1-LABEL: fadd_32stack:
@@ -558,7 +538,7 @@ define dso_local void @fadd_64stack() nounwind {
 ; X86-NOSSE-NEXT:    pushl %ebp
 ; X86-NOSSE-NEXT:    movl %esp, %ebp
 ; X86-NOSSE-NEXT:    andl $-8, %esp
-; X86-NOSSE-NEXT:    subl $40, %esp
+; X86-NOSSE-NEXT:    subl $32, %esp
 ; X86-NOSSE-NEXT:    fildll {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fistpll {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
@@ -568,8 +548,6 @@ define dso_local void @fadd_64stack() nounwind {
 ; X86-NOSSE-NEXT:    fld1
 ; X86-NOSSE-NEXT:    faddl (%esp)
 ; X86-NOSSE-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    fldl {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    fstpl {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl %ebp, %esp
 ; X86-NOSSE-NEXT:    popl %ebp
 ; X86-NOSSE-NEXT:    retl
@@ -579,7 +557,7 @@ define dso_local void @fadd_64stack() nounwind {
 ; X86-SSE1-NEXT:    pushl %ebp
 ; X86-SSE1-NEXT:    movl %esp, %ebp
 ; X86-SSE1-NEXT:    andl $-8, %esp
-; X86-SSE1-NEXT:    subl $32, %esp
+; X86-SSE1-NEXT:    subl $24, %esp
 ; X86-SSE1-NEXT:    xorps %xmm0, %xmm0
 ; X86-SSE1-NEXT:    movlps {{.*#+}} xmm0 = mem[0,1],xmm0[2,3]
 ; X86-SSE1-NEXT:    movss %xmm0, (%esp)
@@ -588,8 +566,6 @@ define dso_local void @fadd_64stack() nounwind {
 ; X86-SSE1-NEXT:    fld1
 ; X86-SSE1-NEXT:    faddl (%esp)
 ; X86-SSE1-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X86-SSE1-NEXT:    fldl {{[0-9]+}}(%esp)
-; X86-SSE1-NEXT:    fstpl {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    movl %ebp, %esp
 ; X86-SSE1-NEXT:    popl %ebp
 ; X86-SSE1-NEXT:    retl
@@ -649,7 +625,7 @@ define dso_local void @fadd_array(ptr %arg, double %arg1, i64 %arg2) nounwind {
 ; X86-NOSSE-NEXT:    movl %esp, %ebp
 ; X86-NOSSE-NEXT:    pushl %esi
 ; X86-NOSSE-NEXT:    andl $-8, %esp
-; X86-NOSSE-NEXT:    subl $40, %esp
+; X86-NOSSE-NEXT:    subl $32, %esp
 ; X86-NOSSE-NEXT:    movl 20(%ebp), %eax
 ; X86-NOSSE-NEXT:    movl 8(%ebp), %ecx
 ; X86-NOSSE-NEXT:    fildll (%ecx,%eax,8)
@@ -660,8 +636,6 @@ define dso_local void @fadd_array(ptr %arg, double %arg1, i64 %arg2) nounwind {
 ; X86-NOSSE-NEXT:    movl %edx, (%esp)
 ; X86-NOSSE-NEXT:    fldl (%esp)
 ; X86-NOSSE-NEXT:    faddl 12(%ebp)
-; X86-NOSSE-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fstpl (%ecx,%eax,8)
 ; X86-NOSSE-NEXT:    leal -4(%ebp), %esp
 ; X86-NOSSE-NEXT:    popl %esi
@@ -673,7 +647,7 @@ define dso_local void @fadd_array(ptr %arg, double %arg1, i64 %arg2) nounwind {
 ; X86-SSE1-NEXT:    pushl %ebp
 ; X86-SSE1-NEXT:    movl %esp, %ebp
 ; X86-SSE1-NEXT:    andl $-8, %esp
-; X86-SSE1-NEXT:    subl $24, %esp
+; X86-SSE1-NEXT:    subl $16, %esp
 ; X86-SSE1-NEXT:    movl 20(%ebp), %eax
 ; X86-SSE1-NEXT:    movl 8(%ebp), %ecx
 ; X86-SSE1-NEXT:    xorps %xmm0, %xmm0
@@ -683,8 +657,6 @@ define dso_local void @fadd_array(ptr %arg, double %arg1, i64 %arg2) nounwind {
 ; X86-SSE1-NEXT:    movss %xmm0, {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fldl (%esp)
 ; X86-SSE1-NEXT:    faddl 12(%ebp)
-; X86-SSE1-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X86-SSE1-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fstpl (%ecx,%eax,8)
 ; X86-SSE1-NEXT:    movl %ebp, %esp
 ; X86-SSE1-NEXT:    popl %ebp
@@ -746,18 +718,16 @@ bb:
 define dso_local void @fsub_32r(ptr %loc, float %val) nounwind {
 ; X86-NOSSE-LABEL: fsub_32r:
 ; X86-NOSSE:       # %bb.0:
-; X86-NOSSE-NEXT:    subl $12, %esp
+; X86-NOSSE-NEXT:    subl $8, %esp
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NOSSE-NEXT:    movl (%eax), %ecx
-; X86-NOSSE-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    flds {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    fsubs {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    fstps (%esp)
+; X86-NOSSE-NEXT:    movl %ecx, (%esp)
 ; X86-NOSSE-NEXT:    flds (%esp)
+; X86-NOSSE-NEXT:    fsubs {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; X86-NOSSE-NEXT:    movl %ecx, (%eax)
-; X86-NOSSE-NEXT:    addl $12, %esp
+; X86-NOSSE-NEXT:    addl $8, %esp
 ; X86-NOSSE-NEXT:    retl
 ;
 ; X86-SSE1-LABEL: fsub_32r:
@@ -817,7 +787,7 @@ define dso_local void @fsub_64r(ptr %loc, double %val) nounwind {
 ; X86-NOSSE-NEXT:    pushl %ebp
 ; X86-NOSSE-NEXT:    movl %esp, %ebp
 ; X86-NOSSE-NEXT:    andl $-8, %esp
-; X86-NOSSE-NEXT:    subl $32, %esp
+; X86-NOSSE-NEXT:    subl $24, %esp
 ; X86-NOSSE-NEXT:    movl 8(%ebp), %eax
 ; X86-NOSSE-NEXT:    fildll (%eax)
 ; X86-NOSSE-NEXT:    fistpll {{[0-9]+}}(%esp)
@@ -827,8 +797,6 @@ define dso_local void @fsub_64r(ptr %loc, double %val) nounwind {
 ; X86-NOSSE-NEXT:    movl %ecx, (%esp)
 ; X86-NOSSE-NEXT:    fldl (%esp)
 ; X86-NOSSE-NEXT:    fsubl 12(%ebp)
-; X86-NOSSE-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fstpl (%eax)
 ; X86-NOSSE-NEXT:    movl %ebp, %esp
 ; X86-NOSSE-NEXT:    popl %ebp
@@ -839,7 +807,7 @@ define dso_local void @fsub_64r(ptr %loc, double %val) nounwind {
 ; X86-SSE1-NEXT:    pushl %ebp
 ; X86-SSE1-NEXT:    movl %esp, %ebp
 ; X86-SSE1-NEXT:    andl $-8, %esp
-; X86-SSE1-NEXT:    subl $24, %esp
+; X86-SSE1-NEXT:    subl $16, %esp
 ; X86-SSE1-NEXT:    movl 8(%ebp), %eax
 ; X86-SSE1-NEXT:    xorps %xmm0, %xmm0
 ; X86-SSE1-NEXT:    movlps {{.*#+}} xmm0 = mem[0,1],xmm0[2,3]
@@ -848,8 +816,6 @@ define dso_local void @fsub_64r(ptr %loc, double %val) nounwind {
 ; X86-SSE1-NEXT:    movss %xmm0, {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fldl (%esp)
 ; X86-SSE1-NEXT:    fsubl 12(%ebp)
-; X86-SSE1-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X86-SSE1-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fstpl (%eax)
 ; X86-SSE1-NEXT:    movl %ebp, %esp
 ; X86-SSE1-NEXT:    popl %ebp
@@ -908,18 +874,16 @@ define dso_local void @fsub_64r(ptr %loc, double %val) nounwind {
 define dso_local void @fsub_32g() nounwind {
 ; X86-NOSSE-LABEL: fsub_32g:
 ; X86-NOSSE:       # %bb.0:
-; X86-NOSSE-NEXT:    subl $12, %esp
+; X86-NOSSE-NEXT:    subl $8, %esp
 ; X86-NOSSE-NEXT:    movl glob32, %eax
-; X86-NOSSE-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    movl %eax, (%esp)
 ; X86-NOSSE-NEXT:    fld1
 ; X86-NOSSE-NEXT:    fchs
-; X86-NOSSE-NEXT:    fadds {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    fstps (%esp)
-; X86-NOSSE-NEXT:    flds (%esp)
+; X86-NOSSE-NEXT:    fadds (%esp)
 ; X86-NOSSE-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NOSSE-NEXT:    movl %eax, glob32
-; X86-NOSSE-NEXT:    addl $12, %esp
+; X86-NOSSE-NEXT:    addl $8, %esp
 ; X86-NOSSE-NEXT:    retl
 ;
 ; X86-SSE1-LABEL: fsub_32g:
@@ -976,7 +940,7 @@ define dso_local void @fsub_64g() nounwind {
 ; X86-NOSSE-NEXT:    pushl %ebp
 ; X86-NOSSE-NEXT:    movl %esp, %ebp
 ; X86-NOSSE-NEXT:    andl $-8, %esp
-; X86-NOSSE-NEXT:    subl $32, %esp
+; X86-NOSSE-NEXT:    subl $24, %esp
 ; X86-NOSSE-NEXT:    fildll glob64
 ; X86-NOSSE-NEXT:    fistpll {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
@@ -986,8 +950,6 @@ define dso_local void @fsub_64g() nounwind {
 ; X86-NOSSE-NEXT:    fld1
 ; X86-NOSSE-NEXT:    fchs
 ; X86-NOSSE-NEXT:    faddl (%esp)
-; X86-NOSSE-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fstpl glob64
 ; X86-NOSSE-NEXT:    movl %ebp, %esp
 ; X86-NOSSE-NEXT:    popl %ebp
@@ -998,7 +960,7 @@ define dso_local void @fsub_64g() nounwind {
 ; X86-SSE1-NEXT:    pushl %ebp
 ; X86-SSE1-NEXT:    movl %esp, %ebp
 ; X86-SSE1-NEXT:    andl $-8, %esp
-; X86-SSE1-NEXT:    subl $24, %esp
+; X86-SSE1-NEXT:    subl $16, %esp
 ; X86-SSE1-NEXT:    xorps %xmm0, %xmm0
 ; X86-SSE1-NEXT:    movlps {{.*#+}} xmm0 = mem[0,1],xmm0[2,3]
 ; X86-SSE1-NEXT:    movss %xmm0, (%esp)
@@ -1007,8 +969,6 @@ define dso_local void @fsub_64g() nounwind {
 ; X86-SSE1-NEXT:    fld1
 ; X86-SSE1-NEXT:    fchs
 ; X86-SSE1-NEXT:    faddl (%esp)
-; X86-SSE1-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X86-SSE1-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fstpl glob64
 ; X86-SSE1-NEXT:    movl %ebp, %esp
 ; X86-SSE1-NEXT:    popl %ebp
@@ -1065,18 +1025,16 @@ define dso_local void @fsub_64g() nounwind {
 define dso_local void @fsub_32imm() nounwind {
 ; X86-NOSSE-LABEL: fsub_32imm:
 ; X86-NOSSE:       # %bb.0:
-; X86-NOSSE-NEXT:    subl $12, %esp
+; X86-NOSSE-NEXT:    subl $8, %esp
 ; X86-NOSSE-NEXT:    movl -559038737, %eax
-; X86-NOSSE-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    movl %eax, (%esp)
 ; X86-NOSSE-NEXT:    fld1
 ; X86-NOSSE-NEXT:    fchs
-; X86-NOSSE-NEXT:    fadds {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    fstps (%esp)
-; X86-NOSSE-NEXT:    flds (%esp)
+; X86-NOSSE-NEXT:    fadds (%esp)
 ; X86-NOSSE-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NOSSE-NEXT:    movl %eax, -559038737
-; X86-NOSSE-NEXT:    addl $12, %esp
+; X86-NOSSE-NEXT:    addl $8, %esp
 ; X86-NOSSE-NEXT:    retl
 ;
 ; X86-SSE1-LABEL: fsub_32imm:
@@ -1135,7 +1093,7 @@ define dso_local void @fsub_64imm() nounwind {
 ; X86-NOSSE-NEXT:    pushl %ebp
 ; X86-NOSSE-NEXT:    movl %esp, %ebp
 ; X86-NOSSE-NEXT:    andl $-8, %esp
-; X86-NOSSE-NEXT:    subl $32, %esp
+; X86-NOSSE-NEXT:    subl $24, %esp
 ; X86-NOSSE-NEXT:    fildll -559038737
 ; X86-NOSSE-NEXT:    fistpll {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
@@ -1145,8 +1103,6 @@ define dso_local void @fsub_64imm() nounwind {
 ; X86-NOSSE-NEXT:    fld1
 ; X86-NOSSE-NEXT:    fchs
 ; X86-NOSSE-NEXT:    faddl (%esp)
-; X86-NOSSE-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fstpl -559038737
 ; X86-NOSSE-NEXT:    movl %ebp, %esp
 ; X86-NOSSE-NEXT:    popl %ebp
@@ -1157,7 +1113,7 @@ define dso_local void @fsub_64imm() nounwind {
 ; X86-SSE1-NEXT:    pushl %ebp
 ; X86-SSE1-NEXT:    movl %esp, %ebp
 ; X86-SSE1-NEXT:    andl $-8, %esp
-; X86-SSE1-NEXT:    subl $24, %esp
+; X86-SSE1-NEXT:    subl $16, %esp
 ; X86-SSE1-NEXT:    xorps %xmm0, %xmm0
 ; X86-SSE1-NEXT:    movlps {{.*#+}} xmm0 = mem[0,1],xmm0[2,3]
 ; X86-SSE1-NEXT:    movss %xmm0, (%esp)
@@ -1166,8 +1122,6 @@ define dso_local void @fsub_64imm() nounwind {
 ; X86-SSE1-NEXT:    fld1
 ; X86-SSE1-NEXT:    fchs
 ; X86-SSE1-NEXT:    faddl (%esp)
-; X86-SSE1-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X86-SSE1-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fstpl -559038737
 ; X86-SSE1-NEXT:    movl %ebp, %esp
 ; X86-SSE1-NEXT:    popl %ebp
@@ -1226,17 +1180,15 @@ define dso_local void @fsub_64imm() nounwind {
 define dso_local void @fsub_32stack() nounwind {
 ; X86-NOSSE-LABEL: fsub_32stack:
 ; X86-NOSSE:       # %bb.0:
-; X86-NOSSE-NEXT:    subl $16, %esp
+; X86-NOSSE-NEXT:    subl $12, %esp
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NOSSE-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    movl %eax, (%esp)
 ; X86-NOSSE-NEXT:    fld1
-; X86-NOSSE-NEXT:    fsubs {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    fstps (%esp)
-; X86-NOSSE-NEXT:    flds (%esp)
+; X86-NOSSE-NEXT:    fsubs (%esp)
 ; X86-NOSSE-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NOSSE-NEXT:    movl %eax, {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    addl $16, %esp
+; X86-NOSSE-NEXT:    addl $12, %esp
 ; X86-NOSSE-NEXT:    retl
 ;
 ; X86-SSE1-LABEL: fsub_32stack:
@@ -1298,7 +1250,7 @@ define dso_local void @fsub_64stack() nounwind {
 ; X86-NOSSE-NEXT:    pushl %ebp
 ; X86-NOSSE-NEXT:    movl %esp, %ebp
 ; X86-NOSSE-NEXT:    andl $-8, %esp
-; X86-NOSSE-NEXT:    subl $40, %esp
+; X86-NOSSE-NEXT:    subl $32, %esp
 ; X86-NOSSE-NEXT:    fildll {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fistpll {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
@@ -1308,8 +1260,6 @@ define dso_local void @fsub_64stack() nounwind {
 ; X86-NOSSE-NEXT:    fld1
 ; X86-NOSSE-NEXT:    fsubl (%esp)
 ; X86-NOSSE-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    fldl {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    fstpl {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl %ebp, %esp
 ; X86-NOSSE-NEXT:    popl %ebp
 ; X86-NOSSE-NEXT:    retl
@@ -1319,7 +1269,7 @@ define dso_local void @fsub_64stack() nounwind {
 ; X86-SSE1-NEXT:    pushl %ebp
 ; X86-SSE1-NEXT:    movl %esp, %ebp
 ; X86-SSE1-NEXT:    andl $-8, %esp
-; X86-SSE1-NEXT:    subl $32, %esp
+; X86-SSE1-NEXT:    subl $24, %esp
 ; X86-SSE1-NEXT:    xorps %xmm0, %xmm0
 ; X86-SSE1-NEXT:    movlps {{.*#+}} xmm0 = mem[0,1],xmm0[2,3]
 ; X86-SSE1-NEXT:    movss %xmm0, (%esp)
@@ -1328,8 +1278,6 @@ define dso_local void @fsub_64stack() nounwind {
 ; X86-SSE1-NEXT:    fld1
 ; X86-SSE1-NEXT:    fsubl (%esp)
 ; X86-SSE1-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X86-SSE1-NEXT:    fldl {{[0-9]+}}(%esp)
-; X86-SSE1-NEXT:    fstpl {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    movl %ebp, %esp
 ; X86-SSE1-NEXT:    popl %ebp
 ; X86-SSE1-NEXT:    retl
@@ -1391,7 +1339,7 @@ define dso_local void @fsub_array(ptr %arg, double %arg1, i64 %arg2) nounwind {
 ; X86-NOSSE-NEXT:    movl %esp, %ebp
 ; X86-NOSSE-NEXT:    pushl %esi
 ; X86-NOSSE-NEXT:    andl $-8, %esp
-; X86-NOSSE-NEXT:    subl $40, %esp
+; X86-NOSSE-NEXT:    subl $32, %esp
 ; X86-NOSSE-NEXT:    movl 20(%ebp), %eax
 ; X86-NOSSE-NEXT:    movl 8(%ebp), %ecx
 ; X86-NOSSE-NEXT:    fildll (%ecx,%eax,8)
@@ -1402,8 +1350,6 @@ define dso_local void @fsub_array(ptr %arg, double %arg1, i64 %arg2) nounwind {
 ; X86-NOSSE-NEXT:    movl %edx, (%esp)
 ; X86-NOSSE-NEXT:    fldl (%esp)
 ; X86-NOSSE-NEXT:    fsubl 12(%ebp)
-; X86-NOSSE-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fstpl (%ecx,%eax,8)
 ; X86-NOSSE-NEXT:    leal -4(%ebp), %esp
 ; X86-NOSSE-NEXT:    popl %esi
@@ -1415,7 +1361,7 @@ define dso_local void @fsub_array(ptr %arg, double %arg1, i64 %arg2) nounwind {
 ; X86-SSE1-NEXT:    pushl %ebp
 ; X86-SSE1-NEXT:    movl %esp, %ebp
 ; X86-SSE1-NEXT:    andl $-8, %esp
-; X86-SSE1-NEXT:    subl $24, %esp
+; X86-SSE1-NEXT:    subl $16, %esp
 ; X86-SSE1-NEXT:    movl 20(%ebp), %eax
 ; X86-SSE1-NEXT:    movl 8(%ebp), %ecx
 ; X86-SSE1-NEXT:    xorps %xmm0, %xmm0
@@ -1425,8 +1371,6 @@ define dso_local void @fsub_array(ptr %arg, double %arg1, i64 %arg2) nounwind {
 ; X86-SSE1-NEXT:    movss %xmm0, {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fldl (%esp)
 ; X86-SSE1-NEXT:    fsubl 12(%ebp)
-; X86-SSE1-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X86-SSE1-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fstpl (%ecx,%eax,8)
 ; X86-SSE1-NEXT:    movl %ebp, %esp
 ; X86-SSE1-NEXT:    popl %ebp
@@ -1490,18 +1434,16 @@ bb:
 define dso_local void @fmul_32r(ptr %loc, float %val) nounwind {
 ; X86-NOSSE-LABEL: fmul_32r:
 ; X86-NOSSE:       # %bb.0:
-; X86-NOSSE-NEXT:    subl $12, %esp
+; X86-NOSSE-NEXT:    subl $8, %esp
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NOSSE-NEXT:    movl (%eax), %ecx
-; X86-NOSSE-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    flds {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    fmuls {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    fstps (%esp)
+; X86-NOSSE-NEXT:    movl %ecx, (%esp)
 ; X86-NOSSE-NEXT:    flds (%esp)
+; X86-NOSSE-NEXT:    fmuls {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; X86-NOSSE-NEXT:    movl %ecx, (%eax)
-; X86-NOSSE-NEXT:    addl $12, %esp
+; X86-NOSSE-NEXT:    addl $8, %esp
 ; X86-NOSSE-NEXT:    retl
 ;
 ; X86-SSE1-LABEL: fmul_32r:
@@ -1559,7 +1501,7 @@ define dso_local void @fmul_64r(ptr %loc, double %val) nounwind {
 ; X86-NOSSE-NEXT:    pushl %ebp
 ; X86-NOSSE-NEXT:    movl %esp, %ebp
 ; X86-NOSSE-NEXT:    andl $-8, %esp
-; X86-NOSSE-NEXT:    subl $32, %esp
+; X86-NOSSE-NEXT:    subl $24, %esp
 ; X86-NOSSE-NEXT:    movl 8(%ebp), %eax
 ; X86-NOSSE-NEXT:    fildll (%eax)
 ; X86-NOSSE-NEXT:    fistpll {{[0-9]+}}(%esp)
@@ -1569,8 +1511,6 @@ define dso_local void @fmul_64r(ptr %loc, double %val) nounwind {
 ; X86-NOSSE-NEXT:    movl %ecx, (%esp)
 ; X86-NOSSE-NEXT:    fldl (%esp)
 ; X86-NOSSE-NEXT:    fmull 12(%ebp)
-; X86-NOSSE-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fstpl (%eax)
 ; X86-NOSSE-NEXT:    movl %ebp, %esp
 ; X86-NOSSE-NEXT:    popl %ebp
@@ -1581,7 +1521,7 @@ define dso_local void @fmul_64r(ptr %loc, double %val) nounwind {
 ; X86-SSE1-NEXT:    pushl %ebp
 ; X86-SSE1-NEXT:    movl %esp, %ebp
 ; X86-SSE1-NEXT:    andl $-8, %esp
-; X86-SSE1-NEXT:    subl $24, %esp
+; X86-SSE1-NEXT:    subl $16, %esp
 ; X86-SSE1-NEXT:    movl 8(%ebp), %eax
 ; X86-SSE1-NEXT:    xorps %xmm0, %xmm0
 ; X86-SSE1-NEXT:    movlps {{.*#+}} xmm0 = mem[0,1],xmm0[2,3]
@@ -1590,8 +1530,6 @@ define dso_local void @fmul_64r(ptr %loc, double %val) nounwind {
 ; X86-SSE1-NEXT:    movss %xmm0, {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fldl (%esp)
 ; X86-SSE1-NEXT:    fmull 12(%ebp)
-; X86-SSE1-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X86-SSE1-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fstpl (%eax)
 ; X86-SSE1-NEXT:    movl %ebp, %esp
 ; X86-SSE1-NEXT:    popl %ebp
@@ -1648,17 +1586,15 @@ define dso_local void @fmul_64r(ptr %loc, double %val) nounwind {
 define dso_local void @fmul_32g() nounwind {
 ; X86-NOSSE-LABEL: fmul_32g:
 ; X86-NOSSE:       # %bb.0:
-; X86-NOSSE-NEXT:    subl $12, %esp
+; X86-NOSSE-NEXT:    subl $8, %esp
 ; X86-NOSSE-NEXT:    movl glob32, %eax
-; X86-NOSSE-NEXT:    movl %eax, {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    flds {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
-; X86-NOSSE-NEXT:    fstps (%esp)
+; X86-NOSSE-NEXT:    movl %eax, (%esp)
 ; X86-NOSSE-NEXT:    flds (%esp)
+; X86-NOSSE-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
 ; X86-NOSSE-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NOSSE-NEXT:    movl %eax, glob32
-; X86-NOSSE-NEXT:    addl $12, %esp
+; X86-NOSSE-NEXT:    addl $8, %esp
 ; X86-NOSSE-NEXT:    retl
 ;
 ; X86-SSE1-LABEL: fmul_32g:
@@ -1715,7 +1651,7 @@ define dso_local void @fmul_64g() nounwind {
 ; X86-NOSSE-NEXT:    pushl %ebp
 ; X86-NOSSE-NEXT:    movl %esp, %ebp
 ; X86-NOSSE-NEXT:    andl $-8, %esp
-; X86-NOSSE-NEXT:    subl $32, %esp
+; X86-NOSSE-NEXT:    subl $24, %esp
 ; X86-NOSSE-NEXT:    fildll glob64
 ; X86-NOSSE-NEXT:    fistpll {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
@@ -1724,8 +1660,6 @@ define dso_local void @fmul_64g() nounwind {
 ; X86-NOSSE-NEXT:    movl %eax, (%esp)
 ; X86-NOSSE-NEXT:    fldl (%esp)
 ; X86-NOSSE-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
-; X86-NOSSE-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fstpl glob64
 ; X86-NOSSE-NEXT:    movl %ebp, %esp
 ; X86-NOSSE-NEXT:    popl %ebp
@@ -1736,7 +1670,7 @@ define dso_local void @fmul_64g() nounwind {
 ; X86-SSE1-NEXT:    pushl %ebp
 ; X86-SSE1-NEXT:    movl %esp, %ebp
 ; X86-SSE1-NEXT:    andl $-8, %esp
-; X86-SSE1-NEXT:    subl $24, %esp
+; X86-SSE1-NEXT:    subl $16, %esp
 ; X86-SSE1-NEXT:    xorps %xmm0, %xmm0
 ; X86-SSE1-NEXT:    movlps {{.*#+}} xmm0 = mem[0,1],xmm0[2,3]
 ; X86-SSE1-NEXT:    movss %xmm0, (%esp)
@@ -1744,8 +1678,6 @@ define dso_local void @fmul_64g() nounwind {
 ; X86-SSE1-NEXT:    movss %xmm0, {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fldl (%esp)
 ; X86-SSE1-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
-; X86-SSE1-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X86-SSE1-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fstpl glob64
 ; X86-SSE1-NEXT:    movl %ebp, %esp
 ; X86-SSE1-NEXT:    popl %ebp
@@ -1802,17 +1734,15 @@ define dso_local void @fmul_64g() nounwind {
 define dso_local void @fmul_32imm() nounwind {
 ; X86-NOSSE-LABEL: fmul_32imm:
 ; X86-NOSSE:       # %bb.0:
-; X86-NOSSE-NEXT:    subl $12, %esp
+; X86-NOSSE-NEXT:    subl $8, %esp
 ; X86-NOSSE-NEXT:    movl -559038737, %eax
-; X86-NOSSE-NEXT:    movl %eax, {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    flds {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
-; X86-NOSSE-NEXT:    fstps (%esp)
+; X86-NOSSE-NEXT:    movl %eax, (%esp)
 ; X86-NOSSE-NEXT:    flds (%esp)
+; X86-NOSSE-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
 ; X86-NOSSE-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NOSSE-NEXT:    movl %eax, -559038737
-; X86-NOSSE-NEXT:    addl $12, %esp
+; X86-NOSSE-NEXT:    addl $8, %esp
 ; X86-NOSSE-NEXT:    retl
 ;
 ; X86-SSE1-LABEL: fmul_32imm:
@@ -1871,7 +1801,7 @@ define dso_local void @fmul_64imm() nounwind {
 ; X86-NOSSE-NEXT:    pushl %ebp
 ; X86-NOSSE-NEXT:    movl %esp, %ebp
 ; X86-NOSSE-NEXT:    andl $-8, %esp
-; X86-NOSSE-NEXT:    subl $32, %esp
+; X86-NOSSE-NEXT:    subl $24, %esp
 ; X86-NOSSE-NEXT:    fildll -559038737
 ; X86-NOSSE-NEXT:    fistpll {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
@@ -1880,8 +1810,6 @@ define dso_local void @fmul_64imm() nounwind {
 ; X86-NOSSE-NEXT:    movl %eax, (%esp)
 ; X86-NOSSE-NEXT:    fldl (%esp)
 ; X86-NOSSE-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
-; X86-NOSSE-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fstpl -559038737
 ; X86-NOSSE-NEXT:    movl %ebp, %esp
 ; X86-NOSSE-NEXT:    popl %ebp
@@ -1892,7 +1820,7 @@ define dso_local void @fmul_64imm() nounwind {
 ; X86-SSE1-NEXT:    pushl %ebp
 ; X86-SSE1-NEXT:    movl %esp, %ebp
 ; X86-SSE1-NEXT:    andl $-8, %esp
-; X86-SSE1-NEXT:    subl $24, %esp
+; X86-SSE1-NEXT:    subl $16, %esp
 ; X86-SSE1-NEXT:    xorps %xmm0, %xmm0
 ; X86-SSE1-NEXT:    movlps {{.*#+}} xmm0 = mem[0,1],xmm0[2,3]
 ; X86-SSE1-NEXT:    movss %xmm0, (%esp)
@@ -1900,8 +1828,6 @@ define dso_local void @fmul_64imm() nounwind {
 ; X86-SSE1-NEXT:    movss %xmm0, {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fldl (%esp)
 ; X86-SSE1-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
-; X86-SSE1-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X86-SSE1-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fstpl -559038737
 ; X86-SSE1-NEXT:    movl %ebp, %esp
 ; X86-SSE1-NEXT:    popl %ebp
@@ -1960,17 +1886,15 @@ define dso_local void @fmul_64imm() nounwind {
 define dso_local void @fmul_32stack() nounwind {
 ; X86-NOSSE-LABEL: fmul_32stack:
 ; X86-NOSSE:       # %bb.0:
-; X86-NOSSE-NEXT:    subl $16, %esp
+; X86-NOSSE-NEXT:    subl $12, %esp
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NOSSE-NEXT:    movl %eax, {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    flds {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
-; X86-NOSSE-NEXT:    fstps (%esp)
+; X86-NOSSE-NEXT:    movl %eax, (%esp)
 ; X86-NOSSE-NEXT:    flds (%esp)
+; X86-NOSSE-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
 ; X86-NOSSE-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NOSSE-NEXT:    movl %eax, {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    addl $16, %esp
+; X86-NOSSE-NEXT:    addl $12, %esp
 ; X86-NOSSE-NEXT:    retl
 ;
 ; X86-SSE1-LABEL: fmul_32stack:
@@ -2032,7 +1956,7 @@ define dso_local void @fmul_64stack() nounwind {
 ; X86-NOSSE-NEXT:    pushl %ebp
 ; X86-NOSSE-NEXT:    movl %esp, %ebp
 ; X86-NOSSE-NEXT:    andl $-8, %esp
-; X86-NOSSE-NEXT:    subl $40, %esp
+; X86-NOSSE-NEXT:    subl $32, %esp
 ; X86-NOSSE-NEXT:    fildll {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fistpll {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
@@ -2042,8 +1966,6 @@ define dso_local void @fmul_64stack() nounwind {
 ; X86-NOSSE-NEXT:    fldl (%esp)
 ; X86-NOSSE-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
 ; X86-NOSSE-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    fldl {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    fstpl {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl %ebp, %esp
 ; X86-NOSSE-NEXT:    popl %ebp
 ; X86-NOSSE-NEXT:    retl
@@ -2053,7 +1975,7 @@ define dso_local void @fmul_64stack() nounwind {
 ; X86-SSE1-NEXT:    pushl %ebp
 ; X86-SSE1-NEXT:    movl %esp, %ebp
 ; X86-SSE1-NEXT:    andl $-8, %esp
-; X86-SSE1-NEXT:    subl $32, %esp
+; X86-SSE1-NEXT:    subl $24, %esp
 ; X86-SSE1-NEXT:    xorps %xmm0, %xmm0
 ; X86-SSE1-NEXT:    movlps {{.*#+}} xmm0 = mem[0,1],xmm0[2,3]
 ; X86-SSE1-NEXT:    movss %xmm0, (%esp)
@@ -2062,8 +1984,6 @@ define dso_local void @fmul_64stack() nounwind {
 ; X86-SSE1-NEXT:    fldl (%esp)
 ; X86-SSE1-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
 ; X86-SSE1-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X86-SSE1-NEXT:    fldl {{[0-9]+}}(%esp)
-; X86-SSE1-NEXT:    fstpl {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    movl %ebp, %esp
 ; X86-SSE1-NEXT:    popl %ebp
 ; X86-SSE1-NEXT:    retl
@@ -2123,7 +2043,7 @@ define dso_local void @fmul_array(ptr %arg, double %arg1, i64 %arg2) nounwind {
 ; X86-NOSSE-NEXT:    movl %esp, %ebp
 ; X86-NOSSE-NEXT:    pushl %esi
 ; X86-NOSSE-NEXT:    andl $-8, %esp
-; X86-NOSSE-NEXT:    subl $40, %esp
+; X86-NOSSE-NEXT:    subl $32, %esp
 ; X86-NOSSE-NEXT:    movl 20(%ebp), %eax
 ; X86-NOSSE-NEXT:    movl 8(%ebp), %ecx
 ; X86-NOSSE-NEXT:    fildll (%ecx,%eax,8)
@@ -2134,8 +2054,6 @@ define dso_local void @fmul_array(ptr %arg, double %arg1, i64 %arg2) nounwind {
 ; X86-NOSSE-NEXT:    movl %edx, (%esp)
 ; X86-NOSSE-NEXT:    fldl (%esp)
 ; X86-NOSSE-NEXT:    fmull 12(%ebp)
-; X86-NOSSE-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fstpl (%ecx,%eax,8)
 ; X86-NOSSE-NEXT:    leal -4(%ebp), %esp
 ; X86-NOSSE-NEXT:    popl %esi
@@ -2147,7 +2065,7 @@ define dso_local void @fmul_array(ptr %arg, double %arg1, i64 %arg2) nounwind {
 ; X86-SSE1-NEXT:    pushl %ebp
 ; X86-SSE1-NEXT:    movl %esp, %ebp
 ; X86-SSE1-NEXT:    andl $-8, %esp
-; X86-SSE1-NEXT:    subl $24, %esp
+; X86-SSE1-NEXT:    subl $16, %esp
 ; X86-SSE1-NEXT:    movl 20(%ebp), %eax
 ; X86-SSE1-NEXT:    movl 8(%ebp), %ecx
 ; X86-SSE1-NEXT:    xorps %xmm0, %xmm0
@@ -2157,8 +2075,6 @@ define dso_local void @fmul_array(ptr %arg, double %arg1, i64 %arg2) nounwind {
 ; X86-SSE1-NEXT:    movss %xmm0, {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fldl (%esp)
 ; X86-SSE1-NEXT:    fmull 12(%ebp)
-; X86-SSE1-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X86-SSE1-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fstpl (%ecx,%eax,8)
 ; X86-SSE1-NEXT:    movl %ebp, %esp
 ; X86-SSE1-NEXT:    popl %ebp
@@ -2220,18 +2136,16 @@ bb:
 define dso_local void @fdiv_32r(ptr %loc, float %val) nounwind {
 ; X86-NOSSE-LABEL: fdiv_32r:
 ; X86-NOSSE:       # %bb.0:
-; X86-NOSSE-NEXT:    subl $12, %esp
+; X86-NOSSE-NEXT:    subl $8, %esp
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NOSSE-NEXT:    movl (%eax), %ecx
-; X86-NOSSE-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    flds {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    fdivs {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    fstps (%esp)
+; X86-NOSSE-NEXT:    movl %ecx, (%esp)
 ; X86-NOSSE-NEXT:    flds (%esp)
+; X86-NOSSE-NEXT:    fdivs {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; X86-NOSSE-NEXT:    movl %ecx, (%eax)
-; X86-NOSSE-NEXT:    addl $12, %esp
+; X86-NOSSE-NEXT:    addl $8, %esp
 ; X86-NOSSE-NEXT:    retl
 ;
 ; X86-SSE1-LABEL: fdiv_32r:
@@ -2291,7 +2205,7 @@ define dso_local void @fdiv_64r(ptr %loc, double %val) nounwind {
 ; X86-NOSSE-NEXT:    pushl %ebp
 ; X86-NOSSE-NEXT:    movl %esp, %ebp
 ; X86-NOSSE-NEXT:    andl $-8, %esp
-; X86-NOSSE-NEXT:    subl $32, %esp
+; X86-NOSSE-NEXT:    subl $24, %esp
 ; X86-NOSSE-NEXT:    movl 8(%ebp), %eax
 ; X86-NOSSE-NEXT:    fildll (%eax)
 ; X86-NOSSE-NEXT:    fistpll {{[0-9]+}}(%esp)
@@ -2301,8 +2215,6 @@ define dso_local void @fdiv_64r(ptr %loc, double %val) nounwind {
 ; X86-NOSSE-NEXT:    movl %ecx, (%esp)
 ; X86-NOSSE-NEXT:    fldl (%esp)
 ; X86-NOSSE-NEXT:    fdivl 12(%ebp)
-; X86-NOSSE-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fstpl (%eax)
 ; X86-NOSSE-NEXT:    movl %ebp, %esp
 ; X86-NOSSE-NEXT:    popl %ebp
@@ -2313,7 +2225,7 @@ define dso_local void @fdiv_64r(ptr %loc, double %val) nounwind {
 ; X86-SSE1-NEXT:    pushl %ebp
 ; X86-SSE1-NEXT:    movl %esp, %ebp
 ; X86-SSE1-NEXT:    andl $-8, %esp
-; X86-SSE1-NEXT:    subl $24, %esp
+; X86-SSE1-NEXT:    subl $16, %esp
 ; X86-SSE1-NEXT:    movl 8(%ebp), %eax
 ; X86-SSE1-NEXT:    xorps %xmm0, %xmm0
 ; X86-SSE1-NEXT:    movlps {{.*#+}} xmm0 = mem[0,1],xmm0[2,3]
@@ -2322,8 +2234,6 @@ define dso_local void @fdiv_64r(ptr %loc, double %val) nounwind {
 ; X86-SSE1-NEXT:    movss %xmm0, {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fldl (%esp)
 ; X86-SSE1-NEXT:    fdivl 12(%ebp)
-; X86-SSE1-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X86-SSE1-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fstpl (%eax)
 ; X86-SSE1-NEXT:    movl %ebp, %esp
 ; X86-SSE1-NEXT:    popl %ebp
@@ -2382,17 +2292,15 @@ define dso_local void @fdiv_64r(ptr %loc, double %val) nounwind {
 define dso_local void @fdiv_32g() nounwind {
 ; X86-NOSSE-LABEL: fdiv_32g:
 ; X86-NOSSE:       # %bb.0:
-; X86-NOSSE-NEXT:    subl $12, %esp
+; X86-NOSSE-NEXT:    subl $8, %esp
 ; X86-NOSSE-NEXT:    movl glob32, %eax
-; X86-NOSSE-NEXT:    movl %eax, {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    flds {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    fdivs {{\.?LCPI[0-9]+_[0-9]+}}
-; X86-NOSSE-NEXT:    fstps (%esp)
+; X86-NOSSE-NEXT:    movl %eax, (%esp)
 ; X86-NOSSE-NEXT:    flds (%esp)
+; X86-NOSSE-NEXT:    fdivs {{\.?LCPI[0-9]+_[0-9]+}}
 ; X86-NOSSE-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NOSSE-NEXT:    movl %eax, glob32
-; X86-NOSSE-NEXT:    addl $12, %esp
+; X86-NOSSE-NEXT:    addl $8, %esp
 ; X86-NOSSE-NEXT:    retl
 ;
 ; X86-SSE1-LABEL: fdiv_32g:
@@ -2449,7 +2357,7 @@ define dso_local void @fdiv_64g() nounwind {
 ; X86-NOSSE-NEXT:    pushl %ebp
 ; X86-NOSSE-NEXT:    movl %esp, %ebp
 ; X86-NOSSE-NEXT:    andl $-8, %esp
-; X86-NOSSE-NEXT:    subl $32, %esp
+; X86-NOSSE-NEXT:    subl $24, %esp
 ; X86-NOSSE-NEXT:    fildll glob64
 ; X86-NOSSE-NEXT:    fistpll {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
@@ -2458,8 +2366,6 @@ define dso_local void @fdiv_64g() nounwind {
 ; X86-NOSSE-NEXT:    movl %eax, (%esp)
 ; X86-NOSSE-NEXT:    fldl (%esp)
 ; X86-NOSSE-NEXT:    fdivs {{\.?LCPI[0-9]+_[0-9]+}}
-; X86-NOSSE-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fstpl glob64
 ; X86-NOSSE-NEXT:    movl %ebp, %esp
 ; X86-NOSSE-NEXT:    popl %ebp
@@ -2470,7 +2376,7 @@ define dso_local void @fdiv_64g() nounwind {
 ; X86-SSE1-NEXT:    pushl %ebp
 ; X86-SSE1-NEXT:    movl %esp, %ebp
 ; X86-SSE1-NEXT:    andl $-8, %esp
-; X86-SSE1-NEXT:    subl $24, %esp
+; X86-SSE1-NEXT:    subl $16, %esp
 ; X86-SSE1-NEXT:    xorps %xmm0, %xmm0
 ; X86-SSE1-NEXT:    movlps {{.*#+}} xmm0 = mem[0,1],xmm0[2,3]
 ; X86-SSE1-NEXT:    movss %xmm0, (%esp)
@@ -2478,8 +2384,6 @@ define dso_local void @fdiv_64g() nounwind {
 ; X86-SSE1-NEXT:    movss %xmm0, {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fldl (%esp)
 ; X86-SSE1-NEXT:    fdivs {{\.?LCPI[0-9]+_[0-9]+}}
-; X86-SSE1-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X86-SSE1-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fstpl glob64
 ; X86-SSE1-NEXT:    movl %ebp, %esp
 ; X86-SSE1-NEXT:    popl %ebp
@@ -2536,17 +2440,15 @@ define dso_local void @fdiv_64g() nounwind {
 define dso_local void @fdiv_32imm() nounwind {
 ; X86-NOSSE-LABEL: fdiv_32imm:
 ; X86-NOSSE:       # %bb.0:
-; X86-NOSSE-NEXT:    subl $12, %esp
+; X86-NOSSE-NEXT:    subl $8, %esp
 ; X86-NOSSE-NEXT:    movl -559038737, %eax
-; X86-NOSSE-NEXT:    movl %eax, {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    flds {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    fdivs {{\.?LCPI[0-9]+_[0-9]+}}
-; X86-NOSSE-NEXT:    fstps (%esp)
+; X86-NOSSE-NEXT:    movl %eax, (%esp)
 ; X86-NOSSE-NEXT:    flds (%esp)
+; X86-NOSSE-NEXT:    fdivs {{\.?LCPI[0-9]+_[0-9]+}}
 ; X86-NOSSE-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NOSSE-NEXT:    movl %eax, -559038737
-; X86-NOSSE-NEXT:    addl $12, %esp
+; X86-NOSSE-NEXT:    addl $8, %esp
 ; X86-NOSSE-NEXT:    retl
 ;
 ; X86-SSE1-LABEL: fdiv_32imm:
@@ -2605,7 +2507,7 @@ define dso_local void @fdiv_64imm() nounwind {
 ; X86-NOSSE-NEXT:    pushl %ebp
 ; X86-NOSSE-NEXT:    movl %esp, %ebp
 ; X86-NOSSE-NEXT:    andl $-8, %esp
-; X86-NOSSE-NEXT:    subl $32, %esp
+; X86-NOSSE-NEXT:    subl $24, %esp
 ; X86-NOSSE-NEXT:    fildll -559038737
 ; X86-NOSSE-NEXT:    fistpll {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
@@ -2614,8 +2516,6 @@ define dso_local void @fdiv_64imm() nounwind {
 ; X86-NOSSE-NEXT:    movl %eax, (%esp)
 ; X86-NOSSE-NEXT:    fldl (%esp)
 ; X86-NOSSE-NEXT:    fdivs {{\.?LCPI[0-9]+_[0-9]+}}
-; X86-NOSSE-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fstpl -559038737
 ; X86-NOSSE-NEXT:    movl %ebp, %esp
 ; X86-NOSSE-NEXT:    popl %ebp
@@ -2626,7 +2526,7 @@ define dso_local void @fdiv_64imm() nounwind {
 ; X86-SSE1-NEXT:    pushl %ebp
 ; X86-SSE1-NEXT:    movl %esp, %ebp
 ; X86-SSE1-NEXT:    andl $-8, %esp
-; X86-SSE1-NEXT:    subl $24, %esp
+; X86-SSE1-NEXT:    subl $16, %esp
 ; X86-SSE1-NEXT:    xorps %xmm0, %xmm0
 ; X86-SSE1-NEXT:    movlps {{.*#+}} xmm0 = mem[0,1],xmm0[2,3]
 ; X86-SSE1-NEXT:    movss %xmm0, (%esp)
@@ -2634,8 +2534,6 @@ define dso_local void @fdiv_64imm() nounwind {
 ; X86-SSE1-NEXT:    movss %xmm0, {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fldl (%esp)
 ; X86-SSE1-NEXT:    fdivs {{\.?LCPI[0-9]+_[0-9]+}}
-; X86-SSE1-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X86-SSE1-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fstpl -559038737
 ; X86-SSE1-NEXT:    movl %ebp, %esp
 ; X86-SSE1-NEXT:    popl %ebp
@@ -2694,17 +2592,15 @@ define dso_local void @fdiv_64imm() nounwind {
 define dso_local void @fdiv_32stack() nounwind {
 ; X86-NOSSE-LABEL: fdiv_32stack:
 ; X86-NOSSE:       # %bb.0:
-; X86-NOSSE-NEXT:    subl $16, %esp
+; X86-NOSSE-NEXT:    subl $12, %esp
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NOSSE-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; X86-NOSSE-NEXT:    movl %eax, (%esp)
 ; X86-NOSSE-NEXT:    fld1
-; X86-NOSSE-NEXT:    fdivs {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    fstps (%esp)
-; X86-NOSSE-NEXT:    flds (%esp)
+; X86-NOSSE-NEXT:    fdivs (%esp)
 ; X86-NOSSE-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NOSSE-NEXT:    movl %eax, {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    addl $16, %esp
+; X86-NOSSE-NEXT:    addl $12, %esp
 ; X86-NOSSE-NEXT:    retl
 ;
 ; X86-SSE1-LABEL: fdiv_32stack:
@@ -2766,7 +2662,7 @@ define dso_local void @fdiv_64stack() nounwind {
 ; X86-NOSSE-NEXT:    pushl %ebp
 ; X86-NOSSE-NEXT:    movl %esp, %ebp
 ; X86-NOSSE-NEXT:    andl $-8, %esp
-; X86-NOSSE-NEXT:    subl $40, %esp
+; X86-NOSSE-NEXT:    subl $32, %esp
 ; X86-NOSSE-NEXT:    fildll {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fistpll {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
@@ -2776,8 +2672,6 @@ define dso_local void @fdiv_64stack() nounwind {
 ; X86-NOSSE-NEXT:    fld1
 ; X86-NOSSE-NEXT:    fdivl (%esp)
 ; X86-NOSSE-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    fldl {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    fstpl {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    movl %ebp, %esp
 ; X86-NOSSE-NEXT:    popl %ebp
 ; X86-NOSSE-NEXT:    retl
@@ -2787,7 +2681,7 @@ define dso_local void @fdiv_64stack() nounwind {
 ; X86-SSE1-NEXT:    pushl %ebp
 ; X86-SSE1-NEXT:    movl %esp, %ebp
 ; X86-SSE1-NEXT:    andl $-8, %esp
-; X86-SSE1-NEXT:    subl $32, %esp
+; X86-SSE1-NEXT:    subl $24, %esp
 ; X86-SSE1-NEXT:    xorps %xmm0, %xmm0
 ; X86-SSE1-NEXT:    movlps {{.*#+}} xmm0 = mem[0,1],xmm0[2,3]
 ; X86-SSE1-NEXT:    movss %xmm0, (%esp)
@@ -2796,8 +2690,6 @@ define dso_local void @fdiv_64stack() nounwind {
 ; X86-SSE1-NEXT:    fld1
 ; X86-SSE1-NEXT:    fdivl (%esp)
 ; X86-SSE1-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X86-SSE1-NEXT:    fldl {{[0-9]+}}(%esp)
-; X86-SSE1-NEXT:    fstpl {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    movl %ebp, %esp
 ; X86-SSE1-NEXT:    popl %ebp
 ; X86-SSE1-NEXT:    retl
@@ -2859,7 +2751,7 @@ define dso_local void @fdiv_array(ptr %arg, double %arg1, i64 %arg2) nounwind {
 ; X86-NOSSE-NEXT:    movl %esp, %ebp
 ; X86-NOSSE-NEXT:    pushl %esi
 ; X86-NOSSE-NEXT:    andl $-8, %esp
-; X86-NOSSE-NEXT:    subl $40, %esp
+; X86-NOSSE-NEXT:    subl $32, %esp
 ; X86-NOSSE-NEXT:    movl 20(%ebp), %eax
 ; X86-NOSSE-NEXT:    movl 8(%ebp), %ecx
 ; X86-NOSSE-NEXT:    fildll (%ecx,%eax,8)
@@ -2870,8 +2762,6 @@ define dso_local void @fdiv_array(ptr %arg, double %arg1, i64 %arg2) nounwind {
 ; X86-NOSSE-NEXT:    movl %edx, (%esp)
 ; X86-NOSSE-NEXT:    fldl (%esp)
 ; X86-NOSSE-NEXT:    fdivl 12(%ebp)
-; X86-NOSSE-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X86-NOSSE-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-NOSSE-NEXT:    fstpl (%ecx,%eax,8)
 ; X86-NOSSE-NEXT:    leal -4(%ebp), %esp
 ; X86-NOSSE-NEXT:    popl %esi
@@ -2883,7 +2773,7 @@ define dso_local void @fdiv_array(ptr %arg, double %arg1, i64 %arg2) nounwind {
 ; X86-SSE1-NEXT:    pushl %ebp
 ; X86-SSE1-NEXT:    movl %esp, %ebp
 ; X86-SSE1-NEXT:    andl $-8, %esp
-; X86-SSE1-NEXT:    subl $24, %esp
+; X86-SSE1-NEXT:    subl $16, %esp
 ; X86-SSE1-NEXT:    movl 20(%ebp), %eax
 ; X86-SSE1-NEXT:    movl 8(%ebp), %ecx
 ; X86-SSE1-NEXT:    xorps %xmm0, %xmm0
@@ -2893,8 +2783,6 @@ define dso_local void @fdiv_array(ptr %arg, double %arg1, i64 %arg2) nounwind {
 ; X86-SSE1-NEXT:    movss %xmm0, {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fldl (%esp)
 ; X86-SSE1-NEXT:    fdivl 12(%ebp)
-; X86-SSE1-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X86-SSE1-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-SSE1-NEXT:    fstpl (%ecx,%eax,8)
 ; X86-SSE1-NEXT:    movl %ebp, %esp
 ; X86-SSE1-NEXT:    popl %ebp
diff --git a/llvm/test/CodeGen/X86/bfloat-int64-cvt-i686.ll b/llvm/test/CodeGen/X86/bfloat-int64-cvt-i686.ll
index b829b4128d107..a205dcb8987eb 100644
--- a/llvm/test/CodeGen/X86/bfloat-int64-cvt-i686.ll
+++ b/llvm/test/CodeGen/X86/bfloat-int64-cvt-i686.ll
@@ -132,8 +132,6 @@ define bfloat @uitofp_i64_to_bf16(i64 %a) nounwind {
 ; X87-NEXT:    shrl $31, %ecx
 ; X87-NEXT:    fildll {{[0-9]+}}(%esp)
 ; X87-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}(,%ecx,4)
-; X87-NEXT:    fstps {{[0-9]+}}(%esp)
-; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    fstps (%esp)
 ; X87-NEXT:    calll __truncsfbf2
 ; X87-NEXT:    # kill: def $ax killed $ax def $eax
@@ -203,8 +201,6 @@ define bfloat @uitofp_load_i64_to_bf16(ptr %p) nounwind {
 ; X87-NEXT:    shrl $31, %eax
 ; X87-NEXT:    fildll {{[0-9]+}}(%esp)
 ; X87-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}(,%eax,4)
-; X87-NEXT:    fstps {{[0-9]+}}(%esp)
-; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    fstps (%esp)
 ; X87-NEXT:    calll __truncsfbf2
 ; X87-NEXT:    # kill: def $ax killed $ax def $eax
diff --git a/llvm/test/CodeGen/X86/canonicalize-vars.ll b/llvm/test/CodeGen/X86/canonicalize-vars.ll
index 51e5ae395a90c..1ee972d1bce5f 100644
--- a/llvm/test/CodeGen/X86/canonicalize-vars.ll
+++ b/llvm/test/CodeGen/X86/canonicalize-vars.ll
@@ -424,17 +424,11 @@ start:
 define void @v_test_canonicalize_var_f32(float addrspace(1)* %out) #1 {
 ; X87-LABEL: v_test_canonicalize_var_f32:
 ; X87:       # %bb.0:
-; X87-NEXT:    pushl %eax
-; X87-NEXT:    .cfi_def_cfa_offset 8
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X87-NEXT:    flds (%eax)
 ; X87-NEXT:    fld1
 ; X87-NEXT:    fmulp %st, %st(1)
-; X87-NEXT:    fstps (%esp)
-; X87-NEXT:    flds (%esp)
 ; X87-NEXT:    fstps (%eax)
-; X87-NEXT:    popl %eax
-; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl
 ;
 ; X86-SSE-LABEL: v_test_canonicalize_var_f32:
@@ -524,17 +518,11 @@ define void @v_test_canonicalize_x86_fp80(x86_fp80 addrspace(1)* %out) #1 {
 define void @v_test_canonicalize_var_f64(double addrspace(1)* %out) #1 {
 ; X87-LABEL: v_test_canonicalize_var_f64:
 ; X87:       # %bb.0:
-; X87-NEXT:    subl $8, %esp
-; X87-NEXT:    .cfi_def_cfa_offset 12
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X87-NEXT:    fldl (%eax)
 ; X87-NEXT:    fld1
 ; X87-NEXT:    fmulp %st, %st(1)
-; X87-NEXT:    fstpl (%esp)
-; X87-NEXT:    fldl (%esp)
 ; X87-NEXT:    fstpl (%eax)
-; X87-NEXT:    addl $8, %esp
-; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl
 ;
 ; X86-SSE-LABEL: v_test_canonicalize_var_f64:
@@ -613,8 +601,6 @@ define void @canonicalize_undef(double addrspace(1)* %out) {
 define <4 x float> @canon_fp32_varargsv4f32(<4 x float> %a) {
 ; X87-LABEL: canon_fp32_varargsv4f32:
 ; X87:       # %bb.0:
-; X87-NEXT:    subl $16, %esp
-; X87-NEXT:    .cfi_def_cfa_offset 20
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    flds {{[0-9]+}}(%esp)
@@ -622,26 +608,15 @@ define <4 x float> @canon_fp32_varargsv4f32(<4 x float> %a) {
 ; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    fld1
 ; X87-NEXT:    fmul %st, %st(1)
-; X87-NEXT:    fxch %st(1)
-; X87-NEXT:    fstps (%esp)
-; X87-NEXT:    fmul %st, %st(1)
-; X87-NEXT:    fxch %st(1)
-; X87-NEXT:    fstps {{[0-9]+}}(%esp)
-; X87-NEXT:    fmul %st, %st(1)
-; X87-NEXT:    fxch %st(1)
-; X87-NEXT:    fstps {{[0-9]+}}(%esp)
-; X87-NEXT:    fmulp %st, %st(1)
-; X87-NEXT:    fstps {{[0-9]+}}(%esp)
-; X87-NEXT:    flds (%esp)
-; X87-NEXT:    flds {{[0-9]+}}(%esp)
-; X87-NEXT:    flds {{[0-9]+}}(%esp)
-; X87-NEXT:    flds {{[0-9]+}}(%esp)
+; X87-NEXT:    fmul %st, %st(2)
+; X87-NEXT:    fmul %st, %st(3)
+; X87-NEXT:    fmulp %st, %st(4)
+; X87-NEXT:    fxch %st(3)
 ; X87-NEXT:    fstps 12(%eax)
+; X87-NEXT:    fxch %st(1)
 ; X87-NEXT:    fstps 8(%eax)
 ; X87-NEXT:    fstps 4(%eax)
 ; X87-NEXT:    fstps (%eax)
-; X87-NEXT:    addl $16, %esp
-; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl $4
 ;
 ; X86-SSE-LABEL: canon_fp32_varargsv4f32:
@@ -682,8 +657,6 @@ define <4 x float> @canon_fp32_varargsv4f32(<4 x float> %a) {
 define <4 x double> @canon_fp64_varargsv4f64(<4 x double> %a) {
 ; X87-LABEL: canon_fp64_varargsv4f64:
 ; X87:       # %bb.0:
-; X87-NEXT:    subl $32, %esp
-; X87-NEXT:    .cfi_def_cfa_offset 36
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    fldl {{[0-9]+}}(%esp)
@@ -691,26 +664,15 @@ define <4 x double> @canon_fp64_varargsv4f64(<4 x double> %a) {
 ; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    fld1
 ; X87-NEXT:    fmul %st, %st(1)
-; X87-NEXT:    fxch %st(1)
-; X87-NEXT:    fstpl (%esp)
-; X87-NEXT:    fmul %st, %st(1)
-; X87-NEXT:    fxch %st(1)
-; X87-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X87-NEXT:    fmul %st, %st(1)
-; X87-NEXT:    fxch %st(1)
-; X87-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X87-NEXT:    fmulp %st, %st(1)
-; X87-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X87-NEXT:    fldl (%esp)
-; X87-NEXT:    fldl {{[0-9]+}}(%esp)
-; X87-NEXT:    fldl {{[0-9]+}}(%esp)
-; X87-NEXT:    fldl {{[0-9]+}}(%esp)
+; X87-NEXT:    fmul %st, %st(2)
+; X87-NEXT:    fmul %st, %st(3)
+; X87-NEXT:    fmulp %st, %st(4)
+; X87-NEXT:    fxch %st(3)
 ; X87-NEXT:    fstpl 24(%eax)
+; X87-NEXT:    fxch %st(1)
 ; X87-NEXT:    fstpl 16(%eax)
 ; X87-NEXT:    fstpl 8(%eax)
 ; X87-NEXT:    fstpl (%eax)
-; X87-NEXT:    addl $32, %esp
-; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl $4
 ;
 ; X86-SSE-LABEL: canon_fp64_varargsv4f64:
@@ -809,8 +771,6 @@ define <2 x x86_fp80> @canon_fp80_varargsv2fp80(<2 x x86_fp80> %a) {
 define void @vec_canonicalize_var_v4f32(<4 x float> addrspace(1)* %out) #1 {
 ; X87-LABEL: vec_canonicalize_var_v4f32:
 ; X87:       # %bb.0:
-; X87-NEXT:    subl $16, %esp
-; X87-NEXT:    .cfi_def_cfa_offset 20
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X87-NEXT:    flds 12(%eax)
 ; X87-NEXT:    flds 8(%eax)
@@ -818,26 +778,15 @@ define void @vec_canonicalize_var_v4f32(<4 x float> addrspace(1)* %out) #1 {
 ; X87-NEXT:    flds (%eax)
 ; X87-NEXT:    fld1
 ; X87-NEXT:    fmul %st, %st(1)
-; X87-NEXT:    fxch %st(1)
-; X87-NEXT:    fstps (%esp)
-; X87-NEXT:    fmul %st, %st(1)
-; X87-NEXT:    fxch %st(1)
-; X87-NEXT:    fstps {{[0-9]+}}(%esp)
-; X87-NEXT:    fmul %st, %st(1)
-; X87-NEXT:    fxch %st(1)
-; X87-NEXT:    fstps {{[0-9]+}}(%esp)
-; X87-NEXT:    fmulp %st, %st(1)
-; X87-NEXT:    fstps {{[0-9]+}}(%esp)
-; X87-NEXT:    flds (%esp)
-; X87-NEXT:    flds {{[0-9]+}}(%esp)
-; X87-NEXT:    flds {{[0-9]+}}(%esp)
-; X87-NEXT:    flds {{[0-9]+}}(%esp)
+; X87-NEXT:    fmul %st, %st(2)
+; X87-NEXT:    fmul %st, %st(3)
+; X87-NEXT:    fmulp %st, %st(4)
+; X87-NEXT:    fxch %st(3)
 ; X87-NEXT:    fstps 12(%eax)
+; X87-NEXT:    fxch %st(1)
 ; X87-NEXT:    fstps 8(%eax)
 ; X87-NEXT:    fstps 4(%eax)
 ; X87-NEXT:    fstps (%eax)
-; X87-NEXT:    addl $16, %esp
-; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl
 ;
 ; X86-SSE-LABEL: vec_canonicalize_var_v4f32:
@@ -892,8 +841,6 @@ define void @vec_canonicalize_var_v4f32(<4 x float> addrspace(1)* %out) #1 {
 define void @vec_canonicalize_var_v4f64(<4 x double> addrspace(1)* %out) #1 {
 ; X87-LABEL: vec_canonicalize_var_v4f64:
 ; X87:       # %bb.0:
-; X87-NEXT:    subl $32, %esp
-; X87-NEXT:    .cfi_def_cfa_offset 36
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X87-NEXT:    fldl 24(%eax)
 ; X87-NEXT:    fldl 16(%eax)
@@ -901,26 +848,15 @@ define void @vec_canonicalize_var_v4f64(<4 x double> addrspace(1)* %out) #1 {
 ; X87-NEXT:    fldl (%eax)
 ; X87-NEXT:    fld1
 ; X87-NEXT:    fmul %st, %st(1)
-; X87-NEXT:    fxch %st(1)
-; X87-NEXT:    fstpl (%esp)
-; X87-NEXT:    fmul %st, %st(1)
-; X87-NEXT:    fxch %st(1)
-; X87-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X87-NEXT:    fmul %st, %st(1)
-; X87-NEXT:    fxch %st(1)
-; X87-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X87-NEXT:    fmulp %st, %st(1)
-; X87-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X87-NEXT:    fldl (%esp)
-; X87-NEXT:    fldl {{[0-9]+}}(%esp)
-; X87-NEXT:    fldl {{[0-9]+}}(%esp)
-; X87-NEXT:    fldl {{[0-9]+}}(%esp)
+; X87-NEXT:    fmul %st, %st(2)
+; X87-NEXT:    fmul %st, %st(3)
+; X87-NEXT:    fmulp %st, %st(4)
+; X87-NEXT:    fxch %st(3)
 ; X87-NEXT:    fstpl 24(%eax)
+; X87-NEXT:    fxch %st(1)
 ; X87-NEXT:    fstpl 16(%eax)
 ; X87-NEXT:    fstpl 8(%eax)
 ; X87-NEXT:    fstpl (%eax)
-; X87-NEXT:    addl $32, %esp
-; X87-NEXT:    .cfi_def_cfa_offset 4
 ; X87-NEXT:    retl
 ;
 ; X86-SSE-LABEL: vec_canonicalize_var_v4f64:
diff --git a/llvm/test/CodeGen/X86/fmf-flags.ll b/llvm/test/CodeGen/X86/fmf-flags.ll
index 29920eedc21e5..2b28722fd1c69 100644
--- a/llvm/test/CodeGen/X86/fmf-flags.ll
+++ b/llvm/test/CodeGen/X86/fmf-flags.ll
@@ -72,20 +72,18 @@ define dso_local double @not_so_fast_mul_add(double %x) {
 ;
 ; X86-LABEL: not_so_fast_mul_add:
 ; X86:       # %bb.0:
-; X86-NEXT:    subl $16, %esp
-; X86-NEXT:    .cfi_def_cfa_offset 20
+; X86-NEXT:    subl $8, %esp
+; X86-NEXT:    .cfi_def_cfa_offset 12
 ; X86-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-NEXT:    fld %st(0)
 ; X86-NEXT:    fmull {{\.?LCPI[0-9]+_[0-9]+}}
-; X86-NEXT:    fstpl (%esp)
-; X86-NEXT:    fldl (%esp)
 ; X86-NEXT:    fxch %st(1)
 ; X86-NEXT:    fmull {{\.?LCPI[0-9]+_[0-9]+}}
-; X86-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X86-NEXT:    fldl {{[0-9]+}}(%esp)
+; X86-NEXT:    fstpl (%esp)
+; X86-NEXT:    fldl (%esp)
 ; X86-NEXT:    fxch %st(1)
 ; X86-NEXT:    fstpl mul1
-; X86-NEXT:    addl $16, %esp
+; X86-NEXT:    addl $8, %esp
 ; X86-NEXT:    .cfi_def_cfa_offset 4
 ; X86-NEXT:    retl
   %m = fmul double %x, 4.2
@@ -149,20 +147,18 @@ define dso_local float @div_arcp_by_const(half %x) {
 ;
 ; X86-LABEL: div_arcp_by_const:
 ; X86:       # %bb.0:
-; X86-NEXT:    subl $8, %esp
-; X86-NEXT:    .cfi_def_cfa_offset 12
+; X86-NEXT:    pushl %eax
+; X86-NEXT:    .cfi_def_cfa_offset 8
 ; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
 ; X86-NEXT:    movl %eax, (%esp)
 ; X86-NEXT:    calll __extendhfsf2
 ; X86-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
-; X86-NEXT:    fstps {{[0-9]+}}(%esp)
-; X86-NEXT:    flds {{[0-9]+}}(%esp)
 ; X86-NEXT:    fstps (%esp)
 ; X86-NEXT:    calll __truncsfhf2
 ; X86-NEXT:    movzwl %ax, %eax
 ; X86-NEXT:    movl %eax, (%esp)
 ; X86-NEXT:    calll __extendhfsf2
-; X86-NEXT:    addl $8, %esp
+; X86-NEXT:    popl %eax
 ; X86-NEXT:    .cfi_def_cfa_offset 4
 ; X86-NEXT:    retl
   %rcp = fdiv arcp half %x, 10.0
diff --git a/llvm/test/CodeGen/X86/isel-x87.ll b/llvm/test/CodeGen/X86/isel-x87.ll
index b4da44d3eaf4e..492faaa19cd66 100644
--- a/llvm/test/CodeGen/X86/isel-x87.ll
+++ b/llvm/test/CodeGen/X86/isel-x87.ll
@@ -192,15 +192,11 @@ define void @f6(ptr %a, ptr %b) nounwind {
 ;
 ; SDAG_X86-LABEL: f6:
 ; SDAG_X86:       # %bb.0:
-; SDAG_X86-NEXT:    pushl %eax
 ; SDAG_X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; SDAG_X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; SDAG_X86-NEXT:    flds (%ecx)
 ; SDAG_X86-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
-; SDAG_X86-NEXT:    fstps (%esp)
-; SDAG_X86-NEXT:    flds (%esp)
 ; SDAG_X86-NEXT:    fstps (%eax)
-; SDAG_X86-NEXT:    popl %eax
 ; SDAG_X86-NEXT:    retl
 ;
 ; GISEL_X64-LABEL: f6:
@@ -214,8 +210,6 @@ define void @f6(ptr %a, ptr %b) nounwind {
 ; SDAG_X64:       # %bb.0:
 ; SDAG_X64-NEXT:    flds (%rdi)
 ; SDAG_X64-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}(%rip)
-; SDAG_X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
-; SDAG_X64-NEXT:    flds -{{[0-9]+}}(%rsp)
 ; SDAG_X64-NEXT:    fstps (%rsi)
 ; SDAG_X64-NEXT:    retq
   %load1 = load float, ptr %a
diff --git a/llvm/test/CodeGen/X86/ldexp.ll b/llvm/test/CodeGen/X86/ldexp.ll
index b6f2793c4b1f7..2a76079cbcd75 100644
--- a/llvm/test/CodeGen/X86/ldexp.ll
+++ b/llvm/test/CodeGen/X86/ldexp.ll
@@ -25,17 +25,15 @@ define half @ldexp_f16(i8 zeroext %x) nounwind {
 ;
 ; WIN32-LABEL: ldexp_f16:
 ; WIN32:       # %bb.0:
-; WIN32-NEXT:    subl $16, %esp
+; WIN32-NEXT:    subl $12, %esp
 ; WIN32-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
 ; WIN32-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; WIN32-NEXT:    fld1
 ; 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 ___truncsfhf2
-; WIN32-NEXT:    addl $16, %esp
+; WIN32-NEXT:    addl $12, %esp
 ; WIN32-NEXT:    retl
   %zext = zext i8 %x to i32
   %ldexp = call half @llvm.ldexp.f16.i32(half 1.000000e+00, i32 %zext)
@@ -65,21 +63,19 @@ define bfloat @ldexp_bf16(i8 zeroext %x) nounwind {
 ;
 ; WIN32-LABEL: ldexp_bf16:
 ; WIN32:       # %bb.0:
-; WIN32-NEXT:    subl $20, %esp
+; WIN32-NEXT:    subl $16, %esp
 ; WIN32-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
 ; WIN32-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; WIN32-NEXT:    fld1
 ; 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 ___truncsfbf2
 ; WIN32-NEXT:    # kill: def $ax killed $ax def $eax
 ; WIN32-NEXT:    shll $16, %eax
 ; WIN32-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
-; WIN32-NEXT:    addl $20, %esp
+; WIN32-NEXT:    addl $16, %esp
 ; WIN32-NEXT:    retl
   %zext = zext i8 %x to i32
   %ldexp = call bfloat @llvm.ldexp.bf16.i32(bfloat 1.000000e+00, i32 %zext)
@@ -331,7 +327,7 @@ define <4 x float> @ldexp_v4f32(<4 x float> %val, <4 x i32> %exp) nounwind {
 ; WIN32-NEXT:    pushl %ebx
 ; WIN32-NEXT:    pushl %edi
 ; WIN32-NEXT:    pushl %esi
-; WIN32-NEXT:    subl $44, %esp
+; WIN32-NEXT:    subl $36, %esp
 ; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %esi
 ; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %edi
 ; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %ebx
@@ -351,26 +347,20 @@ define <4 x float> @ldexp_v4f32(<4 x float> %val, <4 x i32> %exp) nounwind {
 ; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
 ; WIN32-NEXT:    fstpl (%esp)
 ; WIN32-NEXT:    calll _ldexp
+; WIN32-NEXT:    fstpl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Spill
 ; WIN32-NEXT:    movl %edi, {{[0-9]+}}(%esp)
 ; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
 ; 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:    fldl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Reload
 ; WIN32-NEXT:    fstps 8(%esi)
+; WIN32-NEXT:    fldl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Reload
 ; WIN32-NEXT:    fstps 4(%esi)
+; WIN32-NEXT:    fldl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Reload
 ; WIN32-NEXT:    fstps (%esi)
 ; WIN32-NEXT:    movl %esi, %eax
-; WIN32-NEXT:    addl $44, %esp
+; WIN32-NEXT:    addl $36, %esp
 ; WIN32-NEXT:    popl %esi
 ; WIN32-NEXT:    popl %edi
 ; WIN32-NEXT:    popl %ebx
diff --git a/llvm/test/CodeGen/X86/limited-prec.ll b/llvm/test/CodeGen/X86/limited-prec.ll
index e2a651aefd35e..de9c43469daf9 100644
--- a/llvm/test/CodeGen/X86/limited-prec.ll
+++ b/llvm/test/CodeGen/X86/limited-prec.ll
@@ -6,7 +6,7 @@
 define float @f1(float %x) nounwind noinline {
 ; precision6-LABEL: f1:
 ; precision6:       # %bb.0: # %entry
-; precision6-NEXT:    subl $48, %esp
+; precision6-NEXT:    subl $44, %esp
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
@@ -36,18 +36,16 @@ define float @f1(float %x) nounwind noinline {
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision6-NEXT:    flds {{[0-9]+}}(%esp)
-; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision6-NEXT:    shll $23, %eax
 ; precision6-NEXT:    addl {{[0-9]+}}(%esp), %eax
 ; precision6-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
-; precision6-NEXT:    addl $48, %esp
+; precision6-NEXT:    addl $44, %esp
 ; precision6-NEXT:    retl
 ;
 ; precision12-LABEL: f1:
 ; precision12:       # %bb.0: # %entry
-; precision12-NEXT:    subl $56, %esp
+; precision12-NEXT:    subl $52, %esp
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
@@ -83,18 +81,16 @@ define float @f1(float %x) nounwind noinline {
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision12-NEXT:    flds {{[0-9]+}}(%esp)
-; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision12-NEXT:    shll $23, %eax
 ; precision12-NEXT:    addl {{[0-9]+}}(%esp), %eax
 ; precision12-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
-; precision12-NEXT:    addl $56, %esp
+; precision12-NEXT:    addl $52, %esp
 ; precision12-NEXT:    retl
 ;
 ; precision18-LABEL: f1:
 ; precision18:       # %bb.0: # %entry
-; precision18-NEXT:    subl $80, %esp
+; precision18-NEXT:    subl $76, %esp
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
@@ -148,13 +144,11 @@ define float @f1(float %x) nounwind noinline {
 ; precision18-NEXT:    fld1
 ; precision18-NEXT:    fadds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    shll $23, %eax
 ; precision18-NEXT:    addl {{[0-9]+}}(%esp), %eax
 ; precision18-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    addl $80, %esp
+; precision18-NEXT:    addl $76, %esp
 ; precision18-NEXT:    retl
 entry:
 	%"alloca point" = bitcast i32 0 to i32		; <i32> [#uses=0]
@@ -167,7 +161,7 @@ declare float @llvm.exp.f32(float) nounwind readonly
 define float @f2(float %x) nounwind noinline {
 ; precision6-LABEL: f2:
 ; precision6:       # %bb.0: # %entry
-; precision6-NEXT:    subl $44, %esp
+; precision6-NEXT:    subl $40, %esp
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fnstcw (%esp)
 ; precision6-NEXT:    movzwl (%esp), %eax
@@ -194,18 +188,16 @@ define float @f2(float %x) nounwind noinline {
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision6-NEXT:    flds {{[0-9]+}}(%esp)
-; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision6-NEXT:    shll $23, %eax
 ; precision6-NEXT:    addl {{[0-9]+}}(%esp), %eax
 ; precision6-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
-; precision6-NEXT:    addl $44, %esp
+; precision6-NEXT:    addl $40, %esp
 ; precision6-NEXT:    retl
 ;
 ; precision12-LABEL: f2:
 ; precision12:       # %bb.0: # %entry
-; precision12-NEXT:    subl $52, %esp
+; precision12-NEXT:    subl $48, %esp
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fnstcw (%esp)
 ; precision12-NEXT:    movzwl (%esp), %eax
@@ -238,18 +230,16 @@ define float @f2(float %x) nounwind noinline {
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision12-NEXT:    flds {{[0-9]+}}(%esp)
-; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision12-NEXT:    shll $23, %eax
 ; precision12-NEXT:    addl {{[0-9]+}}(%esp), %eax
 ; precision12-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
-; precision12-NEXT:    addl $52, %esp
+; precision12-NEXT:    addl $48, %esp
 ; precision12-NEXT:    retl
 ;
 ; precision18-LABEL: f2:
 ; precision18:       # %bb.0: # %entry
-; precision18-NEXT:    subl $76, %esp
+; precision18-NEXT:    subl $72, %esp
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fnstcw (%esp)
 ; precision18-NEXT:    movzwl (%esp), %eax
@@ -300,13 +290,11 @@ define float @f2(float %x) nounwind noinline {
 ; precision18-NEXT:    fld1
 ; precision18-NEXT:    fadds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    shll $23, %eax
 ; precision18-NEXT:    addl {{[0-9]+}}(%esp), %eax
 ; precision18-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    addl $76, %esp
+; precision18-NEXT:    addl $72, %esp
 ; precision18-NEXT:    retl
 entry:
 	%"alloca point" = bitcast i32 0 to i32		; <i32> [#uses=0]
@@ -319,7 +307,7 @@ declare float @llvm.exp2.f32(float) nounwind readonly
 define float @f3(float %x) nounwind noinline {
 ; precision6-LABEL: f3:
 ; precision6:       # %bb.0: # %entry
-; precision6-NEXT:    subl $48, %esp
+; precision6-NEXT:    subl $44, %esp
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
@@ -349,18 +337,16 @@ define float @f3(float %x) nounwind noinline {
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision6-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision6-NEXT:    flds {{[0-9]+}}(%esp)
-; precision6-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision6-NEXT:    shll $23, %eax
 ; precision6-NEXT:    addl {{[0-9]+}}(%esp), %eax
 ; precision6-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; precision6-NEXT:    flds {{[0-9]+}}(%esp)
-; precision6-NEXT:    addl $48, %esp
+; precision6-NEXT:    addl $44, %esp
 ; precision6-NEXT:    retl
 ;
 ; precision12-LABEL: f3:
 ; precision12:       # %bb.0: # %entry
-; precision12-NEXT:    subl $56, %esp
+; precision12-NEXT:    subl $52, %esp
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
@@ -396,18 +382,16 @@ define float @f3(float %x) nounwind noinline {
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision12-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision12-NEXT:    flds {{[0-9]+}}(%esp)
-; precision12-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision12-NEXT:    shll $23, %eax
 ; precision12-NEXT:    addl {{[0-9]+}}(%esp), %eax
 ; precision12-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; precision12-NEXT:    flds {{[0-9]+}}(%esp)
-; precision12-NEXT:    addl $56, %esp
+; precision12-NEXT:    addl $52, %esp
 ; precision12-NEXT:    retl
 ;
 ; precision18-LABEL: f3:
 ; precision18:       # %bb.0: # %entry
-; precision18-NEXT:    subl $80, %esp
+; precision18-NEXT:    subl $76, %esp
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fmuls {{\.?LCPI[0-9]+_[0-9]+}}
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
@@ -461,13 +445,11 @@ define float @f3(float %x) nounwind noinline {
 ; precision18-NEXT:    fld1
 ; precision18-NEXT:    fadds {{[0-9]+}}(%esp)
 ; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
-; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    fstps {{[0-9]+}}(%esp)
 ; precision18-NEXT:    shll $23, %eax
 ; precision18-NEXT:    addl {{[0-9]+}}(%esp), %eax
 ; precision18-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; precision18-NEXT:    flds {{[0-9]+}}(%esp)
-; precision18-NEXT:    addl $80, %esp
+; precision18-NEXT:    addl $76, %esp
 ; precision18-NEXT:    retl
 entry:
 	%"alloca point" = bitcast i32 0 to i32		; <i32> [#uses=0]
diff --git a/llvm/test/CodeGen/X86/llvm.frexp.ll b/llvm/test/CodeGen/X86/llvm.frexp.ll
index fb778add339fb..5d86a813bee83 100644
--- a/llvm/test/CodeGen/X86/llvm.frexp.ll
+++ b/llvm/test/CodeGen/X86/llvm.frexp.ll
@@ -17,7 +17,7 @@ define { half, i32 } @test_frexp_f16_i32(half %a) nounwind {
 ; WIN32-LABEL: test_frexp_f16_i32:
 ; WIN32:       # %bb.0:
 ; WIN32-NEXT:    pushl %esi
-; WIN32-NEXT:    subl $20, %esp
+; WIN32-NEXT:    subl $16, %esp
 ; WIN32-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
 ; WIN32-NEXT:    movl %eax, (%esp)
 ; WIN32-NEXT:    calll ___extendhfsf2
@@ -25,13 +25,11 @@ define { half, i32 } @test_frexp_f16_i32(half %a) nounwind {
 ; WIN32-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; WIN32-NEXT:    fstpl (%esp)
 ; WIN32-NEXT:    calll _frexp
-; WIN32-NEXT:    fstps {{[0-9]+}}(%esp)
-; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
 ; WIN32-NEXT:    fstps (%esp)
 ; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %esi
 ; WIN32-NEXT:    calll ___truncsfhf2
 ; WIN32-NEXT:    movl %esi, %edx
-; WIN32-NEXT:    addl $20, %esp
+; WIN32-NEXT:    addl $16, %esp
 ; WIN32-NEXT:    popl %esi
 ; WIN32-NEXT:    retl
   %result = call { half, i32 } @llvm.frexp.f16.i32(half %a)
@@ -51,7 +49,7 @@ define half @test_frexp_f16_i32_only_use_fract(half %a) nounwind {
 ;
 ; WIN32-LABEL: test_frexp_f16_i32_only_use_fract:
 ; WIN32:       # %bb.0:
-; WIN32-NEXT:    subl $20, %esp
+; WIN32-NEXT:    subl $16, %esp
 ; WIN32-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
 ; WIN32-NEXT:    movl %eax, (%esp)
 ; WIN32-NEXT:    calll ___extendhfsf2
@@ -59,11 +57,9 @@ define half @test_frexp_f16_i32_only_use_fract(half %a) nounwind {
 ; WIN32-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; WIN32-NEXT:    fstpl (%esp)
 ; WIN32-NEXT:    calll _frexp
-; WIN32-NEXT:    fstps {{[0-9]+}}(%esp)
-; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
 ; WIN32-NEXT:    fstps (%esp)
 ; WIN32-NEXT:    calll ___truncsfhf2
-; WIN32-NEXT:    addl $20, %esp
+; WIN32-NEXT:    addl $16, %esp
 ; WIN32-NEXT:    retl
   %result = call { half, i32 } @llvm.frexp.f16.i32(half %a)
   %result.0 = extractvalue { half, i32 } %result, 0
@@ -133,7 +129,7 @@ define { bfloat, i32 } @test_frexp_bf16_i32(bfloat %a) nounwind {
 ; WIN32-LABEL: test_frexp_bf16_i32:
 ; WIN32:       # %bb.0:
 ; WIN32-NEXT:    pushl %esi
-; WIN32-NEXT:    subl $28, %esp
+; WIN32-NEXT:    subl $24, %esp
 ; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
 ; WIN32-NEXT:    fstps (%esp)
 ; WIN32-NEXT:    calll ___truncsfbf2
@@ -145,8 +141,6 @@ define { bfloat, i32 } @test_frexp_bf16_i32(bfloat %a) nounwind {
 ; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
 ; WIN32-NEXT:    fstpl (%esp)
 ; WIN32-NEXT:    calll _frexp
-; WIN32-NEXT:    fstps {{[0-9]+}}(%esp)
-; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
 ; WIN32-NEXT:    fstps (%esp)
 ; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %esi
 ; WIN32-NEXT:    calll ___truncsfbf2
@@ -155,7 +149,7 @@ define { bfloat, i32 } @test_frexp_bf16_i32(bfloat %a) nounwind {
 ; WIN32-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
 ; WIN32-NEXT:    movl %esi, %eax
-; WIN32-NEXT:    addl $28, %esp
+; WIN32-NEXT:    addl $24, %esp
 ; WIN32-NEXT:    popl %esi
 ; WIN32-NEXT:    retl
   %result = call { bfloat, i32 } @llvm.frexp.bf16.i32(bfloat %a)
@@ -302,9 +296,9 @@ define { <4 x float>, <4 x i32> } @test_frexp_v4f32_v4i32(<4 x float> %a) nounwi
 ; WIN32-LABEL: test_frexp_v4f32_v4i32:
 ; WIN32:       # %bb.0:
 ; WIN32-NEXT:    pushl %esi
-; WIN32-NEXT:    subl $44, %esp
+; WIN32-NEXT:    subl $36, %esp
 ; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %esi
-; WIN32-NEXT:    leal 24(%esi), %eax
+; WIN32-NEXT:    leal 16(%esi), %eax
 ; WIN32-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
 ; WIN32-NEXT:    fstpl (%esp)
@@ -316,32 +310,26 @@ define { <4 x float>, <4 x i32> } @test_frexp_v4f32_v4i32(<4 x float> %a) nounwi
 ; WIN32-NEXT:    fstpl (%esp)
 ; WIN32-NEXT:    calll _frexp
 ; WIN32-NEXT:    fstpl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Spill
-; WIN32-NEXT:    leal 16(%esi), %eax
+; WIN32-NEXT:    leal 24(%esi), %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 28(%esi), %eax
 ; WIN32-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; WIN32-NEXT:    flds {{[0-9]+}}(%esp)
 ; 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:    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:    fldl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Reload
 ; WIN32-NEXT:    fstps 8(%esi)
+; WIN32-NEXT:    fldl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Reload
 ; WIN32-NEXT:    fstps 4(%esi)
+; WIN32-NEXT:    fldl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Reload
 ; WIN32-NEXT:    fstps (%esi)
 ; WIN32-NEXT:    movl %esi, %eax
-; WIN32-NEXT:    addl $44, %esp
+; WIN32-NEXT:    addl $36, %esp
 ; WIN32-NEXT:    popl %esi
 ; WIN32-NEXT:    retl
   %result = call { <4 x float>, <4 x i32> } @llvm.frexp.v4f32.v4i32(<4 x float> %a)
@@ -383,7 +371,7 @@ define <4 x float> @test_frexp_v4f32_v4i32_only_use_fract(<4 x float> %a) nounwi
 ; WIN32-LABEL: test_frexp_v4f32_v4i32_only_use_fract:
 ; WIN32:       # %bb.0:
 ; WIN32-NEXT:    pushl %esi
-; WIN32-NEXT:    subl $60, %esp
+; WIN32-NEXT:    subl $52, %esp
 ; WIN32-NEXT:    movl {{[0-9]+}}(%esp), %esi
 ; WIN32-NEXT:    leal {{[0-9]+}}(%esp), %eax
 ; WIN32-NEXT:    movl %eax, {{[0-9]+}}(%esp)
@@ -402,27 +390,21 @@ define <4 x float> @test_frexp_v4f32_v4i32_only_use_fract(<4 x float> %a) nounwi
 ; 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:    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:    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:    fldl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Reload
 ; WIN32-NEXT:    fstps 8(%esi)
+; WIN32-NEXT:    fldl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Reload
 ; WIN32-NEXT:    fstps 4(%esi)
+; WIN32-NEXT:    fldl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Reload
 ; WIN32-NEXT:    fstps (%esi)
 ; WIN32-NEXT:    movl %esi, %eax
-; WIN32-NEXT:    addl $60, %esp
+; WIN32-NEXT:    addl $52, %esp
 ; WIN32-NEXT:    popl %esi
 ; WIN32-NEXT:    retl
   %result = call { <4 x float>, <4 x i32> } @llvm.frexp.v4f32.v4i32(<4 x float> %a)
diff --git a/llvm/test/CodeGen/X86/negate-add-zero.ll b/llvm/test/CodeGen/X86/negate-add-zero.ll
index 77f0818f09060..574fc1114bef6 100644
--- a/llvm/test/CodeGen/X86/negate-add-zero.ll
+++ b/llvm/test/CodeGen/X86/negate-add-zero.ll
@@ -827,8 +827,8 @@ declare void @_ZN21HNodeTranslateRotate311toCartesianEv(ptr)
 define linkonce void @_ZN21HNodeTranslateRotate36setVelERK9CDSVectorIdLi1EN3CDS12DefaultAllocEE(ptr %this, ptr %velv) {
 ; CHECK-LABEL: _ZN21HNodeTranslateRotate36setVelERK9CDSVectorIdLi1EN3CDS12DefaultAllocEE:
 ; CHECK:       ## %bb.0:
-; CHECK-NEXT:    subl $120, %esp
-; CHECK-NEXT:    .cfi_def_cfa_offset 124
+; CHECK-NEXT:    subl $96, %esp
+; CHECK-NEXT:    .cfi_def_cfa_offset 100
 ; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; CHECK-NEXT:    fldl 0
@@ -874,21 +874,15 @@ define linkonce void @_ZN21HNodeTranslateRotate36setVelERK9CDSVectorIdLi1EN3CDS1
 ; CHECK-NEXT:    faddl {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    fstpl {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    faddl {{[0-9]+}}(%esp)
-; CHECK-NEXT:    fstpl {{[0-9]+}}(%esp)
-; CHECK-NEXT:    fldl {{[0-9]+}}(%esp)
+; CHECK-NEXT:    fstpl (%esp)
+; CHECK-NEXT:    fldl (%esp)
 ; CHECK-NEXT:    fstl 16
 ; CHECK-NEXT:    fldl {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    fadd %st, %st(0)
-; CHECK-NEXT:    fstpl {{[0-9]+}}(%esp)
-; CHECK-NEXT:    fldl {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    fxch %st(2)
 ; CHECK-NEXT:    fadd %st, %st(0)
-; CHECK-NEXT:    fstpl {{[0-9]+}}(%esp)
-; CHECK-NEXT:    fldl {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    fxch %st(1)
 ; CHECK-NEXT:    fadd %st, %st(0)
-; CHECK-NEXT:    fstpl (%esp)
-; CHECK-NEXT:    fldl (%esp)
 ; CHECK-NEXT:    fxch %st(2)
 ; CHECK-NEXT:    fstpl 2056(%ecx)
 ; CHECK-NEXT:    fstpl 2064(%ecx)
diff --git a/llvm/test/CodeGen/X86/nosse-vector.ll b/llvm/test/CodeGen/X86/nosse-vector.ll
index dbc64997f74fc..746c91af19a39 100644
--- a/llvm/test/CodeGen/X86/nosse-vector.ll
+++ b/llvm/test/CodeGen/X86/nosse-vector.ll
@@ -5,33 +5,23 @@
 define void @fadd_2f64_mem(ptr %p0, ptr %p1, ptr %p2) nounwind {
 ; X32-LABEL: fadd_2f64_mem:
 ; X32:       # %bb.0:
-; X32-NEXT:    subl $16, %esp
 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx
 ; X32-NEXT:    fldl (%edx)
 ; X32-NEXT:    faddl (%ecx)
-; X32-NEXT:    fstpl {{[0-9]+}}(%esp)
 ; X32-NEXT:    fldl 8(%edx)
 ; X32-NEXT:    faddl 8(%ecx)
-; X32-NEXT:    fstpl (%esp)
-; X32-NEXT:    fldl {{[0-9]+}}(%esp)
-; X32-NEXT:    fldl (%esp)
 ; X32-NEXT:    fstpl 8(%eax)
 ; X32-NEXT:    fstpl (%eax)
-; X32-NEXT:    addl $16, %esp
 ; X32-NEXT:    retl
 ;
 ; X64-LABEL: fadd_2f64_mem:
 ; X64:       # %bb.0:
 ; X64-NEXT:    fldl (%rdi)
 ; X64-NEXT:    faddl (%rsi)
-; X64-NEXT:    fstpl -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    fldl 8(%rdi)
 ; X64-NEXT:    faddl 8(%rsi)
-; X64-NEXT:    fstpl -{{[0-9]+}}(%rsp)
-; X64-NEXT:    fldl -{{[0-9]+}}(%rsp)
-; X64-NEXT:    fldl -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    fstpl 8(%rdx)
 ; X64-NEXT:    fstpl (%rdx)
 ; X64-NEXT:    retq
@@ -45,51 +35,33 @@ define void @fadd_2f64_mem(ptr %p0, ptr %p1, ptr %p2) nounwind {
 define void @fadd_4f32_mem(ptr %p0, ptr %p1, ptr %p2) nounwind {
 ; X32-LABEL: fadd_4f32_mem:
 ; X32:       # %bb.0:
-; X32-NEXT:    subl $16, %esp
 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx
 ; X32-NEXT:    flds (%edx)
 ; X32-NEXT:    fadds (%ecx)
-; X32-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X32-NEXT:    flds 4(%edx)
 ; X32-NEXT:    fadds 4(%ecx)
-; X32-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X32-NEXT:    flds 8(%edx)
 ; X32-NEXT:    fadds 8(%ecx)
-; X32-NEXT:    fstps (%esp)
 ; X32-NEXT:    flds 12(%edx)
 ; X32-NEXT:    fadds 12(%ecx)
-; X32-NEXT:    fstps {{[0-9]+}}(%esp)
-; X32-NEXT:    flds {{[0-9]+}}(%esp)
-; X32-NEXT:    flds {{[0-9]+}}(%esp)
-; X32-NEXT:    flds (%esp)
-; X32-NEXT:    flds {{[0-9]+}}(%esp)
 ; X32-NEXT:    fstps 12(%eax)
 ; X32-NEXT:    fstps 8(%eax)
 ; X32-NEXT:    fstps 4(%eax)
 ; X32-NEXT:    fstps (%eax)
-; X32-NEXT:    addl $16, %esp
 ; X32-NEXT:    retl
 ;
 ; X64-LABEL: fadd_4f32_mem:
 ; X64:       # %bb.0:
 ; X64-NEXT:    flds (%rdi)
 ; X64-NEXT:    fadds (%rsi)
-; X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    flds 4(%rdi)
 ; X64-NEXT:    fadds 4(%rsi)
-; X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    flds 8(%rdi)
 ; X64-NEXT:    fadds 8(%rsi)
-; X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    flds 12(%rdi)
 ; X64-NEXT:    fadds 12(%rsi)
-; X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
-; X64-NEXT:    flds -{{[0-9]+}}(%rsp)
-; X64-NEXT:    flds -{{[0-9]+}}(%rsp)
-; X64-NEXT:    flds -{{[0-9]+}}(%rsp)
-; X64-NEXT:    flds -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    fstps 12(%rdx)
 ; X64-NEXT:    fstps 8(%rdx)
 ; X64-NEXT:    fstps 4(%rdx)
@@ -105,51 +77,33 @@ define void @fadd_4f32_mem(ptr %p0, ptr %p1, ptr %p2) nounwind {
 define void @fdiv_4f32_mem(ptr %p0, ptr %p1, ptr %p2) nounwind {
 ; X32-LABEL: fdiv_4f32_mem:
 ; X32:       # %bb.0:
-; X32-NEXT:    subl $16, %esp
 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx
 ; X32-NEXT:    flds (%edx)
 ; X32-NEXT:    fdivs (%ecx)
-; X32-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X32-NEXT:    flds 4(%edx)
 ; X32-NEXT:    fdivs 4(%ecx)
-; X32-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X32-NEXT:    flds 8(%edx)
 ; X32-NEXT:    fdivs 8(%ecx)
-; X32-NEXT:    fstps (%esp)
 ; X32-NEXT:    flds 12(%edx)
 ; X32-NEXT:    fdivs 12(%ecx)
-; X32-NEXT:    fstps {{[0-9]+}}(%esp)
-; X32-NEXT:    flds {{[0-9]+}}(%esp)
-; X32-NEXT:    flds {{[0-9]+}}(%esp)
-; X32-NEXT:    flds (%esp)
-; X32-NEXT:    flds {{[0-9]+}}(%esp)
 ; X32-NEXT:    fstps 12(%eax)
 ; X32-NEXT:    fstps 8(%eax)
 ; X32-NEXT:    fstps 4(%eax)
 ; X32-NEXT:    fstps (%eax)
-; X32-NEXT:    addl $16, %esp
 ; X32-NEXT:    retl
 ;
 ; X64-LABEL: fdiv_4f32_mem:
 ; X64:       # %bb.0:
 ; X64-NEXT:    flds (%rdi)
 ; X64-NEXT:    fdivs (%rsi)
-; X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    flds 4(%rdi)
 ; X64-NEXT:    fdivs 4(%rsi)
-; X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    flds 8(%rdi)
 ; X64-NEXT:    fdivs 8(%rsi)
-; X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    flds 12(%rdi)
 ; X64-NEXT:    fdivs 12(%rsi)
-; X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
-; X64-NEXT:    flds -{{[0-9]+}}(%rsp)
-; X64-NEXT:    flds -{{[0-9]+}}(%rsp)
-; X64-NEXT:    flds -{{[0-9]+}}(%rsp)
-; X64-NEXT:    flds -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    fstps 12(%rdx)
 ; X64-NEXT:    fstps 8(%rdx)
 ; X64-NEXT:    fstps 4(%rdx)
diff --git a/llvm/test/CodeGen/X86/peep-test-1.ll b/llvm/test/CodeGen/X86/peep-test-1.ll
index 25ed22c6d7bb6..730a7fdccbd7c 100644
--- a/llvm/test/CodeGen/X86/peep-test-1.ll
+++ b/llvm/test/CodeGen/X86/peep-test-1.ll
@@ -4,7 +4,6 @@
 define void @foo(i32 %n, ptr nocapture %p) nounwind {
 ; CHECK-LABEL: foo:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    subl $8, %esp
 ; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; CHECK-NEXT:    .p2align 4
@@ -12,13 +11,10 @@ define void @foo(i32 %n, ptr nocapture %p) nounwind {
 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
 ; CHECK-NEXT:    fldl (%eax,%ecx,8)
 ; CHECK-NEXT:    fmull {{\.?LCPI[0-9]+_[0-9]+}}
-; CHECK-NEXT:    fstpl (%esp)
-; CHECK-NEXT:    fldl (%esp)
 ; CHECK-NEXT:    fstpl (%eax,%ecx,8)
 ; CHECK-NEXT:    decl %ecx
 ; CHECK-NEXT:    js .LBB0_1
 ; CHECK-NEXT:  # %bb.2: # %return
-; CHECK-NEXT:    addl $8, %esp
 ; CHECK-NEXT:    retl
 	br label %bb
 
diff --git a/llvm/test/CodeGen/X86/pr59305.ll b/llvm/test/CodeGen/X86/pr59305.ll
index d203f3037c807..10d7d24f96f48 100644
--- a/llvm/test/CodeGen/X86/pr59305.ll
+++ b/llvm/test/CodeGen/X86/pr59305.ll
@@ -61,12 +61,10 @@ define double @foo(double %0) #0 {
 ; X86-NEXT:    fldt {{[-0-9]+}}(%e{{[sb]}}p) # 10-byte Folded Reload
 ; X86-NEXT:    fdivp %st, %st(1)
 ; X86-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X86-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-NEXT:    fldl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Reload
 ; X86-NEXT:    fstpl {{[0-9]+}}(%esp)
 ; X86-NEXT:    fldl {{[-0-9]+}}(%e{{[sb]}}p) # 8-byte Folded Reload
 ; X86-NEXT:    fstpl (%esp)
-; X86-NEXT:    fstpl {{[0-9]+}}(%esp)
 ; X86-NEXT:    wait
 ; X86-NEXT:    calll fma
 ; X86-NEXT:    addl $92, %esp
@@ -107,7 +105,7 @@ define double @bar(double %0) #0 {
 ;
 ; X86-LABEL: bar:
 ; X86:       # %bb.0:
-; X86-NEXT:    subl $60, %esp
+; X86-NEXT:    subl $44, %esp
 ; X86-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-NEXT:    wait
 ; X86-NEXT:    #APP
@@ -134,15 +132,11 @@ define double @bar(double %0) #0 {
 ; X86-NEXT:    fdivp %st, %st(3)
 ; X86-NEXT:    fxch %st(2)
 ; X86-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X86-NEXT:    fldl {{[0-9]+}}(%esp)
-; X86-NEXT:    fxch %st(1)
 ; X86-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X86-NEXT:    fxch %st(1)
 ; X86-NEXT:    fstpl (%esp)
-; X86-NEXT:    fstpl {{[0-9]+}}(%esp)
 ; X86-NEXT:    wait
 ; X86-NEXT:    calll fma
-; X86-NEXT:    addl $60, %esp
+; X86-NEXT:    addl $44, %esp
 ; X86-NEXT:    retl
     call void asm sideeffect "SETROUND $0", "*m,~{dirflag},~{fpsr},~{flags}"(ptr elementtype(i32) null)
     %2 = call double @llvm.experimental.constrained.fdiv.f64(double 1.000000e+00, double %0, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
diff --git a/llvm/test/CodeGen/X86/sincos-stack-args.ll b/llvm/test/CodeGen/X86/sincos-stack-args.ll
index e94bb91b9c606..42c05a3e7a9be 100644
--- a/llvm/test/CodeGen/X86/sincos-stack-args.ll
+++ b/llvm/test/CodeGen/X86/sincos-stack-args.ll
@@ -12,17 +12,15 @@ define double @negative_sincos_with_stores_within_call_sequence(double %a) nounw
 ; CHECK:       # %bb.0: # %entry
 ; CHECK-NEXT:    subl $44, %esp
 ; CHECK-NEXT:    fldl 48(%esp)
-; CHECK-NEXT:    leal 16(%esp), %eax
-; CHECK-NEXT:    movl %eax, 12(%esp)
 ; CHECK-NEXT:    leal 24(%esp), %eax
+; CHECK-NEXT:    movl %eax, 12(%esp)
+; CHECK-NEXT:    leal 32(%esp), %eax
 ; CHECK-NEXT:    movl %eax, 8(%esp)
 ; CHECK-NEXT:    fstpl (%esp)
 ; CHECK-NEXT:    calll sincos
+; CHECK-NEXT:    fldl 32(%esp)
 ; CHECK-NEXT:    fldl 24(%esp)
-; CHECK-NEXT:    fldl 16(%esp)
 ; CHECK-NEXT:    faddl {{\.?LCPI[0-9]+_[0-9]+}}
-; CHECK-NEXT:    fstpl 36(%esp)
-; CHECK-NEXT:    fldl 36(%esp)
 ; CHECK-NEXT:    fxch %st(1)
 ; CHECK-NEXT:    fstpl 8(%esp)
 ; CHECK-NEXT:    fstpl (%esp)
diff --git a/llvm/test/CodeGen/X86/x87-round-to-type.ll b/llvm/test/CodeGen/X86/x87-round-to-type.ll
index cdfbd661bb7eb..920cd861e8e97 100644
--- a/llvm/test/CodeGen/X86/x87-round-to-type.ll
+++ b/llvm/test/CodeGen/X86/x87-round-to-type.ll
@@ -226,14 +226,10 @@ define float @fabs_f32(float %a) nounwind {
 define void @store_only_f32(float %a, float %b, ptr %p) nounwind {
 ; X87-LABEL: store_only_f32:
 ; X87:       # %bb.0:
-; X87-NEXT:    pushl %eax
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    fadds {{[0-9]+}}(%esp)
-; X87-NEXT:    fstps (%esp)
-; X87-NEXT:    flds (%esp)
 ; X87-NEXT:    fstps (%eax)
-; X87-NEXT:    popl %eax
 ; X87-NEXT:    retl
   %r = fadd float %a, %b
   store float %r, ptr %p
@@ -243,14 +239,10 @@ define void @store_only_f32(float %a, float %b, ptr %p) nounwind {
 define void @store_only_f64(double %a, double %b, ptr %p) nounwind {
 ; X87-LABEL: store_only_f64:
 ; X87:       # %bb.0:
-; X87-NEXT:    subl $8, %esp
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    faddl {{[0-9]+}}(%esp)
-; X87-NEXT:    fstpl (%esp)
-; X87-NEXT:    fldl (%esp)
 ; X87-NEXT:    fstpl (%eax)
-; X87-NEXT:    addl $8, %esp
 ; X87-NEXT:    retl
   %r = fadd double %a, %b
   store double %r, ptr %p
@@ -261,16 +253,12 @@ define void @store_only_f64(double %a, double %b, ptr %p) nounwind {
 define void @store_twice_f32(float %a, float %b, ptr %p, ptr %q) nounwind {
 ; X87-LABEL: store_twice_f32:
 ; X87:       # %bb.0:
-; X87-NEXT:    pushl %eax
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    fadds {{[0-9]+}}(%esp)
-; X87-NEXT:    fstps (%esp)
-; X87-NEXT:    flds (%esp)
 ; X87-NEXT:    fsts (%ecx)
 ; X87-NEXT:    fstps (%eax)
-; X87-NEXT:    popl %eax
 ; X87-NEXT:    retl
   %r = fadd float %a, %b
   store float %r, ptr %p
@@ -300,16 +288,14 @@ define float @store_and_use_f32(float %a, float %b, ptr %p) nounwind {
 define void @store_narrower_f32(double %a, double %b, ptr %p) nounwind {
 ; X87-LABEL: store_narrower_f32:
 ; X87:       # %bb.0:
-; X87-NEXT:    subl $12, %esp
+; X87-NEXT:    subl $8, %esp
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    faddl {{[0-9]+}}(%esp)
-; X87-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X87-NEXT:    fldl {{[0-9]+}}(%esp)
-; X87-NEXT:    fstps (%esp)
-; X87-NEXT:    flds (%esp)
+; X87-NEXT:    fstpl (%esp)
+; X87-NEXT:    fldl (%esp)
 ; X87-NEXT:    fstps (%eax)
-; X87-NEXT:    addl $12, %esp
+; X87-NEXT:    addl $8, %esp
 ; X87-NEXT:    retl
   %r = fadd double %a, %b
   %t = fptrunc double %r to float

>From c9d2cc96185c562786089949eed5b1e6b36bf1e0 Mon Sep 17 00:00:00 2001
From: Dennis Duda <git at seri.tools>
Date: Thu, 27 Aug 2026 01:16:59 +0200
Subject: [PATCH 07/15] [X86] Combine store(load(fst X)) -> fst X

A round that `BuildFILD` or `LowerFP_ROUND` has already turned into a stack roundtrip is redundant once every user of the reload is a store of that same type: `fst` rounds on the way to memory, and two `fst`s of one source round to the same value, so each store can round the source itself and the roundtrip falls dead.

Unlike the `store(fp_round X)` fold this fires after the fact, which is what it takes to reach the `fild` cases: when `SINT_TO_FP` is lowered the users are still bitcasts, and only `LegalizeDAG` turns those into the stores a round can be folded into.

Skipped for `strictfp` functions: the stores need not be chained to the round, so folding moves the rounding to wherever a store ends up, past a rounding mode change with it.

Co-authored-by: Claude (Claude-Opus-5) <noreply at anthropic.com>
---
 llvm/lib/Target/X86/X86ISelLowering.cpp       |  57 +++++++
 .../test/CodeGen/X86/bfloat-int64-cvt-i686.ll |   4 -
 .../CodeGen/X86/fminimum-fmaximum-i686.ll     |   8 +-
 llvm/test/CodeGen/X86/int-to-fp-demanded.ll   |  40 ++---
 llvm/test/CodeGen/X86/isel-sint-to-fp-x87.ll  | 150 +++++-------------
 llvm/test/CodeGen/X86/nosse-vector.ll         |  36 +----
 llvm/test/CodeGen/X86/x87-round-to-type.ll    |  12 +-
 7 files changed, 113 insertions(+), 194 deletions(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 857af81b1718a..0d28204f98fc9 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -55390,6 +55390,45 @@ static SDValue combineScalarMinMaxAbsStore(StoreSDNode *St, const SDLoc &DL,
                       St->getMemOperand()->getFlags());
 }
 
+/// Matches the memory round-trip RoundX87ToType builds for \p St's value: an
+/// x87 FST that rounds to \p VT, reloaded straight back. Returns the value that
+/// FST rounded, which \p St can round for itself - two FSTs of one source round
+/// to the same \p VT value, so the reload buys nothing.
+static SDValue getX87RoundTripSource(const X86TargetLowering &XTLI,
+                                     StoreSDNode *St, EVT VT) {
+  auto *Ld = dyn_cast<LoadSDNode>(St->getValue());
+  if (!Ld || !Ld->isSimple() || !Ld->isUnindexed() ||
+      Ld->getExtensionType() != ISD::NON_EXTLOAD || Ld->getMemoryVT() != VT)
+    return SDValue();
+
+  // Taking the chain straight from the FST is what rules out a write to the
+  // slot in between: an aliasing store would sit between the two.
+  auto *Fst = dyn_cast<MemIntrinsicSDNode>(Ld->getChain());
+  if (!Fst || Fst->getOpcode() != X86ISD::FST || Fst->getMemoryVT() != VT ||
+      Fst->getOperand(2) != Ld->getBasePtr())
+    return SDValue();
+
+  SDValue Src = Fst->getOperand(1);
+  if (!XTLI.isScalarFPTypeOnX87Stack(Src.getValueType()))
+    return SDValue();
+
+  // Only pays off once every use of the reload rounds for itself, which leaves
+  // the reload and the FST that fed it dead. Otherwise the source has to stay
+  // on the x87 stack alongside the reload, and the exchanges that costs eat
+  // what the fold saves.
+  for (SDUse &Use : Ld->uses()) {
+    // Result 0 of the node is the loaded value; the chain follows it out.
+    if (Use.getResNo() != 0)
+      continue;
+    auto *User = dyn_cast<StoreSDNode>(Use.getUser());
+    if (!User || !User->isSimple() || !User->isUnindexed() ||
+        User->isTruncatingStore() || User->getMemoryVT() != VT)
+      return SDValue();
+  }
+
+  return Src;
+}
+
 static SDValue combineStore(SDNode *N, SelectionDAG &DAG,
                             TargetLowering::DAGCombinerInfo &DCI,
                             const X86Subtarget &Subtarget) {
@@ -55432,6 +55471,24 @@ static SDValue combineStore(SDNode *N, SelectionDAG &DAG,
     }
   }
 
+  // store (load (fst X)) -> fst X: rounding X through a stack slot and reading
+  // it back is what BuildFILD and LowerFP_ROUND emit when a round has to
+  // happen; a store of the result rounds X just as well on its own.
+  // The store need not be chained to the round, so this moves the rounding to
+  // wherever the store ends up - only sound while the rounding mode is the
+  // default one throughout.
+  if (DCI.isAfterLegalizeDAG() && St->isUnindexed() && St->isSimple() &&
+      !St->isTruncatingStore() && VT == StVT &&
+      Subtarget.getTargetLowering()->needsX87RoundToType(VT) &&
+      !DAG.getMachineFunction().getFunction().hasFnAttribute(
+          Attribute::StrictFP)) {
+    if (SDValue Src =
+            getX87RoundTripSource(*Subtarget.getTargetLowering(), St, VT))
+      return DAG.getMemIntrinsicNode(X86ISD::FST, dl, DAG.getVTList(MVT::Other),
+                                     {St->getChain(), Src, St->getBasePtr()},
+                                     VT, St->getMemOperand());
+  }
+
   // Pattern: store(trunc(load vXiY) to vXiZ) optimization
   SDValue Src;
   if (!St->isTruncatingStore() && Subtarget.hasAVX512()) {
diff --git a/llvm/test/CodeGen/X86/bfloat-int64-cvt-i686.ll b/llvm/test/CodeGen/X86/bfloat-int64-cvt-i686.ll
index a205dcb8987eb..655312cb25cfc 100644
--- a/llvm/test/CodeGen/X86/bfloat-int64-cvt-i686.ll
+++ b/llvm/test/CodeGen/X86/bfloat-int64-cvt-i686.ll
@@ -16,8 +16,6 @@ define bfloat @sitofp_i64_to_bf16(i64 %a) nounwind {
 ; X87-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
 ; X87-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; X87-NEXT:    fildll {{[0-9]+}}(%esp)
-; X87-NEXT:    fstps {{[0-9]+}}(%esp)
-; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    fstps (%esp)
 ; X87-NEXT:    calll __truncsfbf2
 ; X87-NEXT:    # kill: def $ax killed $ax def $eax
@@ -72,8 +70,6 @@ define bfloat @sitofp_load_i64_to_bf16(ptr %p) nounwind {
 ; X87-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; X87-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
 ; X87-NEXT:    fildll {{[0-9]+}}(%esp)
-; X87-NEXT:    fstps {{[0-9]+}}(%esp)
-; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    fstps (%esp)
 ; X87-NEXT:    calll __truncsfbf2
 ; X87-NEXT:    # kill: def $ax killed $ax def $eax
diff --git a/llvm/test/CodeGen/X86/fminimum-fmaximum-i686.ll b/llvm/test/CodeGen/X86/fminimum-fmaximum-i686.ll
index 8ad3840712019..aa6c8d39ef06e 100644
--- a/llvm/test/CodeGen/X86/fminimum-fmaximum-i686.ll
+++ b/llvm/test/CodeGen/X86/fminimum-fmaximum-i686.ll
@@ -122,9 +122,7 @@ define double @maximum_double(double %x, double %y) nounwind {
 ; CHECK-NEXT:    subl $8, %esp
 ; CHECK-NEXT:    fldl {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    fldl {{[0-9]+}}(%esp)
-; CHECK-NEXT:    fsts {{[0-9]+}}(%esp)
-; CHECK-NEXT:    flds {{[0-9]+}}(%esp)
-; CHECK-NEXT:    fstps (%esp)
+; CHECK-NEXT:    fsts (%esp)
 ; CHECK-NEXT:    cmpl $0, (%esp)
 ; CHECK-NEXT:    fld %st(0)
 ; CHECK-NEXT:    je .LBB2_2
@@ -301,9 +299,7 @@ define double @minimum_double(double %x, double %y) nounwind {
 ; CHECK-NEXT:    subl $8, %esp
 ; CHECK-NEXT:    fldl {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    fldl {{[0-9]+}}(%esp)
-; CHECK-NEXT:    fsts {{[0-9]+}}(%esp)
-; CHECK-NEXT:    flds {{[0-9]+}}(%esp)
-; CHECK-NEXT:    fstps (%esp)
+; CHECK-NEXT:    fsts (%esp)
 ; CHECK-NEXT:    xorl %eax, %eax
 ; CHECK-NEXT:    cmpl (%esp), %eax
 ; CHECK-NEXT:    fld %st(0)
diff --git a/llvm/test/CodeGen/X86/int-to-fp-demanded.ll b/llvm/test/CodeGen/X86/int-to-fp-demanded.ll
index 80dcdf5ec34f4..323f08631988e 100644
--- a/llvm/test/CodeGen/X86/int-to-fp-demanded.ll
+++ b/llvm/test/CodeGen/X86/int-to-fp-demanded.ll
@@ -9,10 +9,8 @@ define i32 @sitofp_signbit_only(i32 %i_in) nounwind {
 ; X86:       # %bb.0:
 ; X86-NEXT:    subl $12, %esp
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    movl %eax, {{[0-9]+}}(%esp)
-; X86-NEXT:    fildl {{[0-9]+}}(%esp)
-; X86-NEXT:    fstps (%esp)
-; X86-NEXT:    flds (%esp)
+; X86-NEXT:    movl %eax, (%esp)
+; X86-NEXT:    fildl (%esp)
 ; X86-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-NEXT:    movl $-2147483648, %eax # imm = 0x80000000
 ; X86-NEXT:    andl {{[0-9]+}}(%esp), %eax
@@ -39,8 +37,6 @@ define i32 @sitofp_signbit_only_okay_width(i16 %i_in) nounwind {
 ; X86-NEXT:    movw %ax, {{[0-9]+}}(%esp)
 ; X86-NEXT:    filds {{[0-9]+}}(%esp)
 ; X86-NEXT:    fstps {{[0-9]+}}(%esp)
-; X86-NEXT:    flds {{[0-9]+}}(%esp)
-; X86-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-NEXT:    movl $-2147483648, %eax # imm = 0x80000000
 ; X86-NEXT:    andl {{[0-9]+}}(%esp), %eax
 ; X86-NEXT:    addl $12, %esp
@@ -87,10 +83,8 @@ define <2 x i16> @sitofp_signbit_only_fail_bad_width2(i32 %i_in) nounwind {
 ; X86:       # %bb.0:
 ; X86-NEXT:    subl $12, %esp
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    movl %eax, {{[0-9]+}}(%esp)
-; X86-NEXT:    fildl {{[0-9]+}}(%esp)
-; X86-NEXT:    fstps (%esp)
-; X86-NEXT:    flds (%esp)
+; X86-NEXT:    movl %eax, (%esp)
+; X86-NEXT:    fildl (%esp)
 ; X86-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NEXT:    movl %eax, %edx
@@ -118,10 +112,8 @@ define i32 @sitofp_many_bits_fail(i32 %i_in) nounwind {
 ; X86:       # %bb.0:
 ; X86-NEXT:    subl $12, %esp
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    movl %eax, {{[0-9]+}}(%esp)
-; X86-NEXT:    fildl {{[0-9]+}}(%esp)
-; X86-NEXT:    fstps (%esp)
-; X86-NEXT:    flds (%esp)
+; X86-NEXT:    movl %eax, (%esp)
+; X86-NEXT:    fildl (%esp)
 ; X86-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-NEXT:    movl $-2147483647, %eax # imm = 0x80000001
 ; X86-NEXT:    andl {{[0-9]+}}(%esp), %eax
@@ -147,8 +139,6 @@ define i32 @sitofp_multiuse_fail(i32 %i_in) nounwind {
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; X86-NEXT:    fildl {{[0-9]+}}(%esp)
-; X86-NEXT:    fstps {{[0-9]+}}(%esp)
-; X86-NEXT:    flds {{[0-9]+}}(%esp)
 ; X86-NEXT:    fsts {{[0-9]+}}(%esp)
 ; X86-NEXT:    fstps (%esp)
 ; X86-NEXT:    calll use.i32 at PLT
@@ -182,8 +172,6 @@ define i32 @sitofp_multiuse_okay(i32 %i_in) nounwind {
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; X86-NEXT:    fildl {{[0-9]+}}(%esp)
-; X86-NEXT:    fstps {{[0-9]+}}(%esp)
-; X86-NEXT:    flds {{[0-9]+}}(%esp)
 ; X86-NEXT:    fsts {{[0-9]+}}(%esp)
 ; X86-NEXT:    fstps (%esp)
 ; X86-NEXT:    calll use.i1 at PLT
@@ -265,13 +253,11 @@ define <2 x i16> @uitofp_signbit_only_fail_bad_width2(i32 %i_in) nounwind {
 ; X86-NEXT:    pushl %ebp
 ; X86-NEXT:    movl %esp, %ebp
 ; X86-NEXT:    andl $-8, %esp
-; X86-NEXT:    subl $16, %esp
+; X86-NEXT:    subl $24, %esp
 ; X86-NEXT:    movl 8(%ebp), %eax
 ; X86-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; X86-NEXT:    movl $0, {{[0-9]+}}(%esp)
 ; X86-NEXT:    fildll {{[0-9]+}}(%esp)
-; X86-NEXT:    fstps (%esp)
-; X86-NEXT:    flds (%esp)
 ; X86-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-NEXT:    movl $32768, %eax # imm = 0x8000
 ; X86-NEXT:    andl {{[0-9]+}}(%esp), %eax
@@ -299,13 +285,11 @@ define i32 @uitofp_many_bits_fail(i32 %i_in) nounwind {
 ; X86-NEXT:    pushl %ebp
 ; X86-NEXT:    movl %esp, %ebp
 ; X86-NEXT:    andl $-8, %esp
-; X86-NEXT:    subl $16, %esp
+; X86-NEXT:    subl $24, %esp
 ; X86-NEXT:    movl 8(%ebp), %eax
 ; X86-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; X86-NEXT:    movl $0, {{[0-9]+}}(%esp)
 ; X86-NEXT:    fildll {{[0-9]+}}(%esp)
-; X86-NEXT:    fstps (%esp)
-; X86-NEXT:    flds (%esp)
 ; X86-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NEXT:    andl $1, %eax
@@ -332,13 +316,11 @@ define i32 @uitofp_multiuse_fail(i32 %i_in) nounwind {
 ; X86-NEXT:    pushl %ebp
 ; X86-NEXT:    movl %esp, %ebp
 ; X86-NEXT:    andl $-8, %esp
-; X86-NEXT:    subl $16, %esp
+; X86-NEXT:    subl $24, %esp
 ; X86-NEXT:    movl 8(%ebp), %eax
 ; X86-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; X86-NEXT:    movl $0, {{[0-9]+}}(%esp)
 ; X86-NEXT:    fildll {{[0-9]+}}(%esp)
-; X86-NEXT:    fstps {{[0-9]+}}(%esp)
-; X86-NEXT:    flds {{[0-9]+}}(%esp)
 ; X86-NEXT:    fstps (%esp)
 ; X86-NEXT:    calll use.i32 at PLT
 ; X86-NEXT:    xorl %eax, %eax
@@ -369,13 +351,11 @@ define i32 @uitofp_multiuse_okay(i32 %i_in) nounwind {
 ; X86-NEXT:    pushl %ebp
 ; X86-NEXT:    movl %esp, %ebp
 ; X86-NEXT:    andl $-8, %esp
-; X86-NEXT:    subl $16, %esp
+; X86-NEXT:    subl $24, %esp
 ; X86-NEXT:    movl 8(%ebp), %eax
 ; X86-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; X86-NEXT:    movl $0, {{[0-9]+}}(%esp)
 ; X86-NEXT:    fildll {{[0-9]+}}(%esp)
-; X86-NEXT:    fstps {{[0-9]+}}(%esp)
-; X86-NEXT:    flds {{[0-9]+}}(%esp)
 ; X86-NEXT:    fstps (%esp)
 ; X86-NEXT:    calll use.i1 at PLT
 ; X86-NEXT:    xorl %eax, %eax
diff --git a/llvm/test/CodeGen/X86/isel-sint-to-fp-x87.ll b/llvm/test/CodeGen/X86/isel-sint-to-fp-x87.ll
index 3aadd487b62a9..c2c2f994d22b6 100644
--- a/llvm/test/CodeGen/X86/isel-sint-to-fp-x87.ll
+++ b/llvm/test/CodeGen/X86/isel-sint-to-fp-x87.ll
@@ -14,8 +14,6 @@ define void @test_int8_to_float(i8 %x, ptr %p) nounwind {
 ; SDAG-X64-NEXT:    movsbl %dil, %eax
 ; SDAG-X64-NEXT:    movw %ax, -{{[0-9]+}}(%rsp)
 ; SDAG-X64-NEXT:    filds -{{[0-9]+}}(%rsp)
-; SDAG-X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
-; SDAG-X64-NEXT:    flds -{{[0-9]+}}(%rsp)
 ; SDAG-X64-NEXT:    fstps (%rsi)
 ; SDAG-X64-NEXT:    retq
 ;
@@ -35,8 +33,6 @@ define void @test_int8_to_float(i8 %x, ptr %p) nounwind {
 ; SDAG-X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; SDAG-X86-NEXT:    movw %ax, {{[0-9]+}}(%esp)
 ; SDAG-X86-NEXT:    filds {{[0-9]+}}(%esp)
-; SDAG-X86-NEXT:    fstps {{[0-9]+}}(%esp)
-; SDAG-X86-NEXT:    flds {{[0-9]+}}(%esp)
 ; SDAG-X86-NEXT:    fstps (%ecx)
 ; SDAG-X86-NEXT:    addl $8, %esp
 ; SDAG-X86-NEXT:    retl
@@ -60,21 +56,12 @@ entry:
 }
 
 define void @test_int16_to_float(i16 %x, ptr %p) nounwind {
-; SDAG-X64-LABEL: test_int16_to_float:
-; SDAG-X64:       # %bb.0: # %entry
-; SDAG-X64-NEXT:    movw %di, -{{[0-9]+}}(%rsp)
-; SDAG-X64-NEXT:    filds -{{[0-9]+}}(%rsp)
-; SDAG-X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
-; SDAG-X64-NEXT:    flds -{{[0-9]+}}(%rsp)
-; SDAG-X64-NEXT:    fstps (%rsi)
-; SDAG-X64-NEXT:    retq
-;
-; GISEL-X64-LABEL: test_int16_to_float:
-; GISEL-X64:       # %bb.0: # %entry
-; GISEL-X64-NEXT:    movw %di, -{{[0-9]+}}(%rsp)
-; GISEL-X64-NEXT:    filds -{{[0-9]+}}(%rsp)
-; GISEL-X64-NEXT:    fstps (%rsi)
-; GISEL-X64-NEXT:    retq
+; X64-LABEL: test_int16_to_float:
+; X64:       # %bb.0: # %entry
+; X64-NEXT:    movw %di, -{{[0-9]+}}(%rsp)
+; X64-NEXT:    filds -{{[0-9]+}}(%rsp)
+; X64-NEXT:    fstps (%rsi)
+; X64-NEXT:    retq
 ;
 ; SDAG-X86-LABEL: test_int16_to_float:
 ; SDAG-X86:       # %bb.0: # %entry
@@ -83,8 +70,6 @@ define void @test_int16_to_float(i16 %x, ptr %p) nounwind {
 ; SDAG-X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
 ; SDAG-X86-NEXT:    movw %cx, {{[0-9]+}}(%esp)
 ; SDAG-X86-NEXT:    filds {{[0-9]+}}(%esp)
-; SDAG-X86-NEXT:    fstps {{[0-9]+}}(%esp)
-; SDAG-X86-NEXT:    flds {{[0-9]+}}(%esp)
 ; SDAG-X86-NEXT:    fstps (%eax)
 ; SDAG-X86-NEXT:    addl $8, %esp
 ; SDAG-X86-NEXT:    retl
@@ -106,31 +91,20 @@ entry:
 }
 
 define void @test_int32_to_float(i32 %x, ptr %p) nounwind {
-; SDAG-X64-LABEL: test_int32_to_float:
-; SDAG-X64:       # %bb.0: # %entry
-; SDAG-X64-NEXT:    movl %edi, -{{[0-9]+}}(%rsp)
-; SDAG-X64-NEXT:    fildl -{{[0-9]+}}(%rsp)
-; SDAG-X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
-; SDAG-X64-NEXT:    flds -{{[0-9]+}}(%rsp)
-; SDAG-X64-NEXT:    fstps (%rsi)
-; SDAG-X64-NEXT:    retq
-;
-; GISEL-X64-LABEL: test_int32_to_float:
-; GISEL-X64:       # %bb.0: # %entry
-; GISEL-X64-NEXT:    movl %edi, -{{[0-9]+}}(%rsp)
-; GISEL-X64-NEXT:    fildl -{{[0-9]+}}(%rsp)
-; GISEL-X64-NEXT:    fstps (%rsi)
-; GISEL-X64-NEXT:    retq
+; X64-LABEL: test_int32_to_float:
+; X64:       # %bb.0: # %entry
+; X64-NEXT:    movl %edi, -{{[0-9]+}}(%rsp)
+; X64-NEXT:    fildl -{{[0-9]+}}(%rsp)
+; X64-NEXT:    fstps (%rsi)
+; X64-NEXT:    retq
 ;
 ; SDAG-X86-LABEL: test_int32_to_float:
 ; SDAG-X86:       # %bb.0: # %entry
 ; SDAG-X86-NEXT:    subl $8, %esp
 ; SDAG-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; SDAG-X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; SDAG-X86-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
-; SDAG-X86-NEXT:    fildl {{[0-9]+}}(%esp)
-; SDAG-X86-NEXT:    fstps (%esp)
-; SDAG-X86-NEXT:    flds (%esp)
+; SDAG-X86-NEXT:    movl %ecx, (%esp)
+; SDAG-X86-NEXT:    fildl (%esp)
 ; SDAG-X86-NEXT:    fstps (%eax)
 ; SDAG-X86-NEXT:    addl $8, %esp
 ; SDAG-X86-NEXT:    retl
@@ -152,29 +126,18 @@ entry:
 }
 
 define void @test_int64_to_float(i64 %x, ptr %p) nounwind {
-; SDAG-X64-LABEL: test_int64_to_float:
-; SDAG-X64:       # %bb.0: # %entry
-; SDAG-X64-NEXT:    movq %rdi, -{{[0-9]+}}(%rsp)
-; SDAG-X64-NEXT:    fildll -{{[0-9]+}}(%rsp)
-; SDAG-X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
-; SDAG-X64-NEXT:    flds -{{[0-9]+}}(%rsp)
-; SDAG-X64-NEXT:    fstps (%rsi)
-; SDAG-X64-NEXT:    retq
-;
-; GISEL-X64-LABEL: test_int64_to_float:
-; GISEL-X64:       # %bb.0: # %entry
-; GISEL-X64-NEXT:    movq %rdi, -{{[0-9]+}}(%rsp)
-; GISEL-X64-NEXT:    fildll -{{[0-9]+}}(%rsp)
-; GISEL-X64-NEXT:    fstps (%rsi)
-; GISEL-X64-NEXT:    retq
+; X64-LABEL: test_int64_to_float:
+; X64:       # %bb.0: # %entry
+; X64-NEXT:    movq %rdi, -{{[0-9]+}}(%rsp)
+; X64-NEXT:    fildll -{{[0-9]+}}(%rsp)
+; X64-NEXT:    fstps (%rsi)
+; X64-NEXT:    retq
 ;
 ; X86-LABEL: test_int64_to_float:
 ; X86:       # %bb.0: # %entry
 ; X86-NEXT:    pushl %eax
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NEXT:    fildll {{[0-9]+}}(%esp)
-; X86-NEXT:    fstps (%esp)
-; X86-NEXT:    flds (%esp)
 ; X86-NEXT:    fstps (%eax)
 ; X86-NEXT:    popl %eax
 ; X86-NEXT:    retl
@@ -283,8 +246,6 @@ define void @test_int8to_double(i8 %x, ptr %p) nounwind {
 ; SDAG-X64-NEXT:    movsbl %dil, %eax
 ; SDAG-X64-NEXT:    movw %ax, -{{[0-9]+}}(%rsp)
 ; SDAG-X64-NEXT:    filds -{{[0-9]+}}(%rsp)
-; SDAG-X64-NEXT:    fstpl -{{[0-9]+}}(%rsp)
-; SDAG-X64-NEXT:    fldl -{{[0-9]+}}(%rsp)
 ; SDAG-X64-NEXT:    fstpl (%rsi)
 ; SDAG-X64-NEXT:    retq
 ;
@@ -304,8 +265,6 @@ define void @test_int8to_double(i8 %x, ptr %p) nounwind {
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; X86-NEXT:    movw %ax, {{[0-9]+}}(%esp)
 ; X86-NEXT:    filds {{[0-9]+}}(%esp)
-; X86-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X86-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-NEXT:    fstpl (%ecx)
 ; X86-NEXT:    addl $12, %esp
 ; X86-NEXT:    retl
@@ -316,21 +275,12 @@ entry:
 }
 
 define void @test_int16_to_double(i16 %x, ptr %p) nounwind {
-; SDAG-X64-LABEL: test_int16_to_double:
-; SDAG-X64:       # %bb.0: # %entry
-; SDAG-X64-NEXT:    movw %di, -{{[0-9]+}}(%rsp)
-; SDAG-X64-NEXT:    filds -{{[0-9]+}}(%rsp)
-; SDAG-X64-NEXT:    fstpl -{{[0-9]+}}(%rsp)
-; SDAG-X64-NEXT:    fldl -{{[0-9]+}}(%rsp)
-; SDAG-X64-NEXT:    fstpl (%rsi)
-; SDAG-X64-NEXT:    retq
-;
-; GISEL-X64-LABEL: test_int16_to_double:
-; GISEL-X64:       # %bb.0: # %entry
-; GISEL-X64-NEXT:    movw %di, -{{[0-9]+}}(%rsp)
-; GISEL-X64-NEXT:    filds -{{[0-9]+}}(%rsp)
-; GISEL-X64-NEXT:    fstpl (%rsi)
-; GISEL-X64-NEXT:    retq
+; X64-LABEL: test_int16_to_double:
+; X64:       # %bb.0: # %entry
+; X64-NEXT:    movw %di, -{{[0-9]+}}(%rsp)
+; X64-NEXT:    filds -{{[0-9]+}}(%rsp)
+; X64-NEXT:    fstpl (%rsi)
+; X64-NEXT:    retq
 ;
 ; X86-LABEL: test_int16_to_double:
 ; X86:       # %bb.0: # %entry
@@ -339,8 +289,6 @@ define void @test_int16_to_double(i16 %x, ptr %p) nounwind {
 ; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
 ; X86-NEXT:    movw %cx, {{[0-9]+}}(%esp)
 ; X86-NEXT:    filds {{[0-9]+}}(%esp)
-; X86-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X86-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-NEXT:    fstpl (%eax)
 ; X86-NEXT:    addl $12, %esp
 ; X86-NEXT:    retl
@@ -351,21 +299,12 @@ entry:
 }
 
 define void @test_int32_to_double(i32 %x, ptr %p) nounwind {
-; SDAG-X64-LABEL: test_int32_to_double:
-; SDAG-X64:       # %bb.0: # %entry
-; SDAG-X64-NEXT:    movl %edi, -{{[0-9]+}}(%rsp)
-; SDAG-X64-NEXT:    fildl -{{[0-9]+}}(%rsp)
-; SDAG-X64-NEXT:    fstpl -{{[0-9]+}}(%rsp)
-; SDAG-X64-NEXT:    fldl -{{[0-9]+}}(%rsp)
-; SDAG-X64-NEXT:    fstpl (%rsi)
-; SDAG-X64-NEXT:    retq
-;
-; GISEL-X64-LABEL: test_int32_to_double:
-; GISEL-X64:       # %bb.0: # %entry
-; GISEL-X64-NEXT:    movl %edi, -{{[0-9]+}}(%rsp)
-; GISEL-X64-NEXT:    fildl -{{[0-9]+}}(%rsp)
-; GISEL-X64-NEXT:    fstpl (%rsi)
-; GISEL-X64-NEXT:    retq
+; X64-LABEL: test_int32_to_double:
+; X64:       # %bb.0: # %entry
+; X64-NEXT:    movl %edi, -{{[0-9]+}}(%rsp)
+; X64-NEXT:    fildl -{{[0-9]+}}(%rsp)
+; X64-NEXT:    fstpl (%rsi)
+; X64-NEXT:    retq
 ;
 ; X86-LABEL: test_int32_to_double:
 ; X86:       # %bb.0: # %entry
@@ -374,8 +313,6 @@ define void @test_int32_to_double(i32 %x, ptr %p) nounwind {
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; X86-NEXT:    movl %ecx, (%esp)
 ; X86-NEXT:    fildl (%esp)
-; X86-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X86-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-NEXT:    fstpl (%eax)
 ; X86-NEXT:    addl $12, %esp
 ; X86-NEXT:    retl
@@ -386,29 +323,18 @@ entry:
 }
 
 define void @test_int64_to_double(i64 %x, ptr %p) nounwind {
-; SDAG-X64-LABEL: test_int64_to_double:
-; SDAG-X64:       # %bb.0: # %entry
-; SDAG-X64-NEXT:    movq %rdi, -{{[0-9]+}}(%rsp)
-; SDAG-X64-NEXT:    fildll -{{[0-9]+}}(%rsp)
-; SDAG-X64-NEXT:    fstpl -{{[0-9]+}}(%rsp)
-; SDAG-X64-NEXT:    fldl -{{[0-9]+}}(%rsp)
-; SDAG-X64-NEXT:    fstpl (%rsi)
-; SDAG-X64-NEXT:    retq
-;
-; GISEL-X64-LABEL: test_int64_to_double:
-; GISEL-X64:       # %bb.0: # %entry
-; GISEL-X64-NEXT:    movq %rdi, -{{[0-9]+}}(%rsp)
-; GISEL-X64-NEXT:    fildll -{{[0-9]+}}(%rsp)
-; GISEL-X64-NEXT:    fstpl (%rsi)
-; GISEL-X64-NEXT:    retq
+; X64-LABEL: test_int64_to_double:
+; X64:       # %bb.0: # %entry
+; X64-NEXT:    movq %rdi, -{{[0-9]+}}(%rsp)
+; X64-NEXT:    fildll -{{[0-9]+}}(%rsp)
+; X64-NEXT:    fstpl (%rsi)
+; X64-NEXT:    retq
 ;
 ; X86-LABEL: test_int64_to_double:
 ; X86:       # %bb.0: # %entry
 ; X86-NEXT:    subl $8, %esp
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NEXT:    fildll {{[0-9]+}}(%esp)
-; X86-NEXT:    fstpl (%esp)
-; X86-NEXT:    fldl (%esp)
 ; X86-NEXT:    fstpl (%eax)
 ; X86-NEXT:    addl $8, %esp
 ; X86-NEXT:    retl
diff --git a/llvm/test/CodeGen/X86/nosse-vector.ll b/llvm/test/CodeGen/X86/nosse-vector.ll
index 746c91af19a39..44c4f6901eb1e 100644
--- a/llvm/test/CodeGen/X86/nosse-vector.ll
+++ b/llvm/test/CodeGen/X86/nosse-vector.ll
@@ -149,17 +149,9 @@ define void @sitofp_4i64_4f32_mem(ptr %p0, ptr %p1) nounwind {
 ; X32-NEXT:    movl %eax, {{[0-9]+}}(%esp)
 ; X32-NEXT:    movl 12(%ebp), %eax
 ; X32-NEXT:    fildll {{[0-9]+}}(%esp)
-; X32-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X32-NEXT:    fildll {{[0-9]+}}(%esp)
-; X32-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X32-NEXT:    fildll {{[0-9]+}}(%esp)
-; X32-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X32-NEXT:    fildll {{[0-9]+}}(%esp)
-; X32-NEXT:    fstps {{[0-9]+}}(%esp)
-; X32-NEXT:    flds {{[0-9]+}}(%esp)
-; X32-NEXT:    flds {{[0-9]+}}(%esp)
-; X32-NEXT:    flds {{[0-9]+}}(%esp)
-; X32-NEXT:    flds {{[0-9]+}}(%esp)
 ; X32-NEXT:    fstps 12(%eax)
 ; X32-NEXT:    fstps 8(%eax)
 ; X32-NEXT:    fstps 4(%eax)
@@ -182,17 +174,9 @@ define void @sitofp_4i64_4f32_mem(ptr %p0, ptr %p1) nounwind {
 ; X64-NEXT:    movq %rcx, -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    movq %rax, -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    fildll -{{[0-9]+}}(%rsp)
-; X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    fildll -{{[0-9]+}}(%rsp)
-; X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    fildll -{{[0-9]+}}(%rsp)
-; X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    fildll -{{[0-9]+}}(%rsp)
-; X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
-; X64-NEXT:    flds -{{[0-9]+}}(%rsp)
-; X64-NEXT:    flds -{{[0-9]+}}(%rsp)
-; X64-NEXT:    flds -{{[0-9]+}}(%rsp)
-; X64-NEXT:    flds -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    fstps 12(%rsi)
 ; X64-NEXT:    fstps 8(%rsi)
 ; X64-NEXT:    fstps 4(%rsi)
@@ -216,22 +200,14 @@ define void @sitofp_4i32_4f32_mem(ptr %p0, ptr %p1) nounwind {
 ; X32-NEXT:    movl 8(%ecx), %esi
 ; X32-NEXT:    movl (%ecx), %edi
 ; X32-NEXT:    movl 4(%ecx), %ecx
-; X32-NEXT:    movl %edi, {{[0-9]+}}(%esp)
+; X32-NEXT:    movl %edi, (%esp)
 ; X32-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
 ; X32-NEXT:    movl %esi, {{[0-9]+}}(%esp)
 ; X32-NEXT:    movl %edx, {{[0-9]+}}(%esp)
+; X32-NEXT:    fildl (%esp)
 ; X32-NEXT:    fildl {{[0-9]+}}(%esp)
-; X32-NEXT:    fstps (%esp)
-; X32-NEXT:    fildl {{[0-9]+}}(%esp)
-; X32-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X32-NEXT:    fildl {{[0-9]+}}(%esp)
-; X32-NEXT:    fstps {{[0-9]+}}(%esp)
 ; X32-NEXT:    fildl {{[0-9]+}}(%esp)
-; X32-NEXT:    fstps {{[0-9]+}}(%esp)
-; X32-NEXT:    flds (%esp)
-; X32-NEXT:    flds {{[0-9]+}}(%esp)
-; X32-NEXT:    flds {{[0-9]+}}(%esp)
-; X32-NEXT:    flds {{[0-9]+}}(%esp)
 ; X32-NEXT:    fstps 12(%eax)
 ; X32-NEXT:    fstps 8(%eax)
 ; X32-NEXT:    fstps 4(%eax)
@@ -252,17 +228,9 @@ define void @sitofp_4i32_4f32_mem(ptr %p0, ptr %p1) nounwind {
 ; X64-NEXT:    movl %ecx, -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    movl %eax, -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    fildl -{{[0-9]+}}(%rsp)
-; X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    fildl -{{[0-9]+}}(%rsp)
-; X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    fildl -{{[0-9]+}}(%rsp)
-; X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    fildl -{{[0-9]+}}(%rsp)
-; X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
-; X64-NEXT:    flds -{{[0-9]+}}(%rsp)
-; X64-NEXT:    flds -{{[0-9]+}}(%rsp)
-; X64-NEXT:    flds -{{[0-9]+}}(%rsp)
-; X64-NEXT:    flds -{{[0-9]+}}(%rsp)
 ; X64-NEXT:    fstps 12(%rsi)
 ; X64-NEXT:    fstps 8(%rsi)
 ; X64-NEXT:    fstps 4(%rsi)
diff --git a/llvm/test/CodeGen/X86/x87-round-to-type.ll b/llvm/test/CodeGen/X86/x87-round-to-type.ll
index 920cd861e8e97..66f53d23cbe9a 100644
--- a/llvm/test/CodeGen/X86/x87-round-to-type.ll
+++ b/llvm/test/CodeGen/X86/x87-round-to-type.ll
@@ -356,10 +356,8 @@ define void @sitofp_store_only_f32(i32 %x, ptr %p) nounwind {
 ; X87-NEXT:    subl $8, %esp
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; X87-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
-; X87-NEXT:    fildl {{[0-9]+}}(%esp)
-; X87-NEXT:    fstps (%esp)
-; X87-NEXT:    flds (%esp)
+; X87-NEXT:    movl %ecx, (%esp)
+; X87-NEXT:    fildl (%esp)
 ; X87-NEXT:    fstps (%eax)
 ; X87-NEXT:    addl $8, %esp
 ; X87-NEXT:    retl
@@ -375,10 +373,8 @@ define void @sitofp_store_twice_f32(i32 %x, ptr %p, ptr %q) nounwind {
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; X87-NEXT:    movl {{[0-9]+}}(%esp), %edx
-; X87-NEXT:    movl %edx, {{[0-9]+}}(%esp)
-; X87-NEXT:    fildl {{[0-9]+}}(%esp)
-; X87-NEXT:    fstps (%esp)
-; X87-NEXT:    flds (%esp)
+; X87-NEXT:    movl %edx, (%esp)
+; X87-NEXT:    fildl (%esp)
 ; X87-NEXT:    fsts (%ecx)
 ; X87-NEXT:    fstps (%eax)
 ; X87-NEXT:    addl $8, %esp

>From 577d96e3548fdd3934460e1514da114b33dfc784 Mon Sep 17 00:00:00 2001
From: Dennis Duda <git at seri.tools>
Date: Sun, 9 Aug 2026 18:40:50 +0200
Subject: [PATCH 08/15] [X86] Skip value-preserving rounds in `LowerFP_ROUND`

A `FP_ROUND` whose second operand is 1 does not change the value, so between
two types that both live on the x87 stack it is a no-op that selects as a
copy - `PreprocessISelDAG` skips those as well.

`getCopyFromParts` marks a narrowing of a value that arrives in a wider
register that way, which on x87 is every f32/f64 that comes out of a call or
an inline asm: the callee already rounded it. Those were paying for a
store/load round-trip each.

Co-authored-by: Claude (Claude-Opus-5) <noreply at anthropic.com>
---
 llvm/lib/Target/X86/X86ISelLowering.cpp     |  5 +++++
 llvm/test/CodeGen/X86/inline-asm-fpstack.ll | 25 +++------------------
 2 files changed, 8 insertions(+), 22 deletions(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 0d28204f98fc9..2bf38352a5155 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -22982,6 +22982,11 @@ SDValue X86TargetLowering::LowerFP_ROUND(SDValue Op, SelectionDAG &DAG) const {
   }
 
   if (needsX87RoundToType(VT) && isScalarFPTypeOnX87Stack(SVT)) {
+    // A value-preserving round has nothing to do: the value already fits VT,
+    // and both operands stay on the x87 stack.
+    if (Op.getConstantOperandVal(IsStrict ? 2 : 1))
+      return Op;
+
     // Leave the round alone when the stores that consume it already do it;
     // combineStore turns those into truncating stores.
     if (isX87RoundDoneByStores(Op))
diff --git a/llvm/test/CodeGen/X86/inline-asm-fpstack.ll b/llvm/test/CodeGen/X86/inline-asm-fpstack.ll
index 31d93f16ae0ea..d8fd28898d31a 100644
--- a/llvm/test/CodeGen/X86/inline-asm-fpstack.ll
+++ b/llvm/test/CodeGen/X86/inline-asm-fpstack.ll
@@ -16,13 +16,9 @@ define x86_fp80 @test1() nounwind {
 define double @test2() nounwind {
 ; CHECK-LABEL: test2:
 ; CHECK:       ## %bb.0:
-; CHECK-NEXT:    subl $8, %esp
 ; CHECK-NEXT:    ## InlineAsm Start
 ; CHECK-NEXT:    fld0
 ; CHECK-NEXT:    ## InlineAsm End
-; CHECK-NEXT:    fstpl (%esp)
-; CHECK-NEXT:    fldl (%esp)
-; CHECK-NEXT:    addl $8, %esp
 ; CHECK-NEXT:    retl
   %tmp85 = call double asm sideeffect "fld0", "={st(0)}"()
   ret double %tmp85
@@ -355,15 +351,11 @@ entry:
 define float @sincos1(float %x) nounwind ssp {
 ; CHECK-LABEL: sincos1:
 ; CHECK:       ## %bb.0: ## %entry
-; CHECK-NEXT:    pushl %eax
 ; CHECK-NEXT:    flds {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    ## InlineAsm Start
 ; CHECK-NEXT:    sincos
 ; CHECK-NEXT:    ## InlineAsm End
 ; CHECK-NEXT:    fstp %st(1)
-; CHECK-NEXT:    fstps (%esp)
-; CHECK-NEXT:    flds (%esp)
-; CHECK-NEXT:    popl %eax
 ; CHECK-NEXT:    retl
 entry:
   %0 = tail call %complex asm "sincos", "={st},={st(1)},0,~{dirflag},~{fpsr},~{flags}"(float %x) nounwind
@@ -375,15 +367,11 @@ entry:
 define float @sincos2(float %x) nounwind ssp {
 ; CHECK-LABEL: sincos2:
 ; CHECK:       ## %bb.0: ## %entry
-; CHECK-NEXT:    pushl %eax
 ; CHECK-NEXT:    flds {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    ## InlineAsm Start
 ; CHECK-NEXT:    sincos
 ; CHECK-NEXT:    ## InlineAsm End
 ; CHECK-NEXT:    fstp %st(1)
-; CHECK-NEXT:    fstps (%esp)
-; CHECK-NEXT:    flds (%esp)
-; CHECK-NEXT:    popl %eax
 ; CHECK-NEXT:    retl
 entry:
   %0 = tail call %complex asm "sincos", "={st(1)},={st},1,~{dirflag},~{fpsr},~{flags}"(float %x) nounwind
@@ -399,22 +387,18 @@ entry:
 define float @sincos3(float %x) nounwind ssp {
 ; CHECK-LABEL: sincos3:
 ; CHECK:       ## %bb.0: ## %entry
-; CHECK-NEXT:    pushl %eax
 ; CHECK-NEXT:    flds {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    fld %st(0)
 ; CHECK-NEXT:    ## InlineAsm Start
 ; CHECK-NEXT:    sincos
 ; CHECK-NEXT:    ## InlineAsm End
 ; CHECK-NEXT:    fstp %st(0)
-; CHECK-NEXT:    fstps (%esp)
-; CHECK-NEXT:    flds (%esp)
 ; CHECK-NEXT:    fxch %st(1)
 ; CHECK-NEXT:    ## InlineAsm Start
 ; CHECK-NEXT:    sincos
 ; CHECK-NEXT:    ## InlineAsm End
 ; CHECK-NEXT:    fstp %st(1)
 ; CHECK-NEXT:    fstp %st(0)
-; CHECK-NEXT:    popl %eax
 ; CHECK-NEXT:    retl
 entry:
   %0 = tail call %complex asm sideeffect "sincos", "={st(1)},={st},1,~{dirflag},~{fpsr},~{flags}"(float %x) nounwind
@@ -511,17 +495,14 @@ return:
 define double @test_operand_rewrite() nounwind {
 ; CHECK-LABEL: test_operand_rewrite:
 ; CHECK:       ## %bb.0: ## %entry
-; CHECK-NEXT:    subl $24, %esp
+; CHECK-NEXT:    subl $8, %esp
 ; CHECK-NEXT:    ## InlineAsm Start
 ; CHECK-NEXT:    foo %st, %st(1)
 ; CHECK-NEXT:    ## InlineAsm End
-; CHECK-NEXT:    fstpl {{[0-9]+}}(%esp)
-; CHECK-NEXT:    fstpl {{[0-9]+}}(%esp)
-; CHECK-NEXT:    fldl {{[0-9]+}}(%esp)
-; CHECK-NEXT:    fsubl {{[0-9]+}}(%esp)
+; CHECK-NEXT:    fsubp %st, %st(1)
 ; CHECK-NEXT:    fstpl (%esp)
 ; CHECK-NEXT:    fldl (%esp)
-; CHECK-NEXT:    addl $24, %esp
+; CHECK-NEXT:    addl $8, %esp
 ; CHECK-NEXT:    retl
 entry:
   %0 = tail call { double, double } asm sideeffect "foo $0, $1", "={st},={st(1)},~{dirflag},~{fpsr},~{flags}"()

>From ac986e15edd654f7f1fe10848e566402fde5fab2 Mon Sep 17 00:00:00 2001
From: Dennis Duda <git at seri.tools>
Date: Sun, 9 Aug 2026 02:07:35 +0200
Subject: [PATCH 09/15] [X86][GlobalISel] Widen x87 f32/f64 arithmetic to s80

Co-authored-by: Claude (Claude-Opus-5) <noreply at anthropic.com>
---
 .../lib/Target/X86/GISel/X86LegalizerInfo.cpp | 17 ++++-
 .../X86/GlobalISel/regbankselect-x87.ll       | 74 ++++++++++++++-----
 llvm/test/CodeGen/X86/GlobalISel/sqrt.mir     |  6 +-
 llvm/test/CodeGen/X86/isel-fadd.ll            | 12 ++-
 llvm/test/CodeGen/X86/isel-fdiv.ll            | 12 ++-
 llvm/test/CodeGen/X86/isel-fmul.ll            | 12 ++-
 llvm/test/CodeGen/X86/isel-fsub.ll            | 12 ++-
 llvm/test/CodeGen/X86/isel-sqrt.ll            | 10 ++-
 llvm/test/CodeGen/X86/isel-x87.ll             | 24 +++++-
 9 files changed, 147 insertions(+), 32 deletions(-)

diff --git a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
index 78ab184af6c19..a520d4843bea9 100644
--- a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
+++ b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
@@ -80,6 +80,15 @@ X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI,
   const LLT v16s32 = LLT::fixed_vector(16, 32);
   const LLT v8s64 = LLT::fixed_vector(8, 64);
 
+  const X86TargetLowering &TLI = *Subtarget.getTargetLowering();
+  bool RoundX87S32 = TLI.needsX87RoundToType(MVT::f32);
+  bool RoundX87S64 = TLI.needsX87RoundToType(MVT::f64);
+  auto NeedsX87RoundToType = [=](const LegalityQuery &Query) {
+    return (RoundX87S32 && Query.Types[0] == s32) ||
+           (RoundX87S64 && Query.Types[0] == s64);
+  };
+  auto WidenToS80 = [=](const LegalityQuery &) { return std::pair(0u, s80); };
+
   const LLT s8MaxVector = HasAVX512 ? v64s8 : HasAVX ? v32s8 : v16s8;
   const LLT s16MaxVector = HasAVX512 ? v32s16 : HasAVX ? v16s16 : v8s16;
   const LLT s32MaxVector = HasAVX512 ? v16s32 : HasAVX ? v8s32 : v4s32;
@@ -137,9 +146,10 @@ X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI,
       .lower();
 
   getActionDefinitionsBuilder(G_FSQRT)
-      .legalFor(HasSSE1 || UseX87, {s32})
-      .legalFor(HasSSE2 || UseX87, {s64})
-      .legalFor(UseX87, {s80});
+      .legalFor(HasSSE1, {s32})
+      .legalFor(HasSSE2, {s64})
+      .widenScalarIf(NeedsX87RoundToType, WidenToS80)
+      .legalFor(UseX87, {s32, s64, s80});
 
   getActionDefinitionsBuilder({G_GET_ROUNDING, G_SET_ROUNDING})
       .customFor({s32});
@@ -440,6 +450,7 @@ X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI,
 
   // fp arithmetic
   getActionDefinitionsBuilder({G_FADD, G_FSUB, G_FMUL, G_FDIV})
+      .widenScalarIf(NeedsX87RoundToType, WidenToS80)
       .legalFor({s32, s64})
       .legalFor(HasSSE1, {v4s32})
       .legalFor(HasSSE2, {v2s64})
diff --git a/llvm/test/CodeGen/X86/GlobalISel/regbankselect-x87.ll b/llvm/test/CodeGen/X86/GlobalISel/regbankselect-x87.ll
index 602313cd671ec..0780d690d5f6d 100644
--- a/llvm/test/CodeGen/X86/GlobalISel/regbankselect-x87.ll
+++ b/llvm/test/CodeGen/X86/GlobalISel/regbankselect-x87.ll
@@ -166,18 +166,27 @@ define void @f5(ptr %a, ptr %b) {
   ; X86-NEXT:   [[C:%[0-9]+]]:gpr(s32) = G_CONSTANT i32 4
   ; X86-NEXT:   [[PTR_ADD:%[0-9]+]]:gpr(p0) = nuw inbounds G_PTR_ADD [[LOAD]], [[C]](s32)
   ; X86-NEXT:   [[LOAD3:%[0-9]+]]:gpr(s32) = G_LOAD [[PTR_ADD]](p0) :: (load (s32) from %ir.a + 4, basealign 8)
-  ; X86-NEXT:   [[MV:%[0-9]+]]:gpr(s64) = G_MERGE_VALUES [[LOAD2]](s32), [[LOAD3]](s32)
   ; X86-NEXT:   [[LOAD4:%[0-9]+]]:gpr(s32) = G_LOAD [[LOAD1]](p0) :: (load (s32) from %ir.b, align 8)
   ; X86-NEXT:   [[PTR_ADD1:%[0-9]+]]:gpr(p0) = nuw inbounds G_PTR_ADD [[LOAD1]], [[C]](s32)
   ; X86-NEXT:   [[LOAD5:%[0-9]+]]:gpr(s32) = G_LOAD [[PTR_ADD1]](p0) :: (load (s32) from %ir.b + 4, basealign 8)
-  ; X86-NEXT:   [[MV1:%[0-9]+]]:gpr(s64) = G_MERGE_VALUES [[LOAD4]](s32), [[LOAD5]](s32)
-  ; X86-NEXT:   [[COPY:%[0-9]+]]:psr(s64) = COPY [[MV]](s64)
-  ; X86-NEXT:   [[COPY1:%[0-9]+]]:psr(s64) = COPY [[MV1]](s64)
-  ; X86-NEXT:   [[FADD:%[0-9]+]]:psr(s64) = G_FADD [[COPY]], [[COPY1]]
-  ; X86-NEXT:   [[COPY2:%[0-9]+]]:gpr(s64) = COPY [[FADD]](s64)
-  ; X86-NEXT:   [[UV:%[0-9]+]]:gpr(s32), [[UV1:%[0-9]+]]:gpr(s32) = G_UNMERGE_VALUES [[COPY2]](s64)
-  ; X86-NEXT:   G_STORE [[UV]](s32), [[LOAD]](p0) :: (store (s32) into %ir.a, align 8)
-  ; X86-NEXT:   G_STORE [[UV1]](s32), [[PTR_ADD]](p0) :: (store (s32) into %ir.a + 4, basealign 8)
+  ; X86-NEXT:   [[FRAME_INDEX2:%[0-9]+]]:gpr(p0) = G_FRAME_INDEX %stack.2
+  ; X86-NEXT:   G_STORE [[LOAD2]](s32), [[FRAME_INDEX2]](p0) :: (store (s32) into %stack.2, align 8)
+  ; X86-NEXT:   [[PTR_ADD2:%[0-9]+]]:gpr(p0) = nuw inbounds G_PTR_ADD [[FRAME_INDEX2]], [[C]](s32)
+  ; X86-NEXT:   G_STORE [[LOAD3]](s32), [[PTR_ADD2]](p0) :: (store (s32) into %stack.2 + 4, basealign 8)
+  ; X86-NEXT:   [[FPEXTLOAD:%[0-9]+]]:psr(s80) = G_FPEXTLOAD [[FRAME_INDEX2]](p0) :: (load (s64) from %stack.2)
+  ; X86-NEXT:   [[FRAME_INDEX3:%[0-9]+]]:gpr(p0) = G_FRAME_INDEX %stack.1
+  ; X86-NEXT:   G_STORE [[LOAD4]](s32), [[FRAME_INDEX3]](p0) :: (store (s32) into %stack.1, align 8)
+  ; X86-NEXT:   [[PTR_ADD3:%[0-9]+]]:gpr(p0) = nuw inbounds G_PTR_ADD [[FRAME_INDEX3]], [[C]](s32)
+  ; X86-NEXT:   G_STORE [[LOAD5]](s32), [[PTR_ADD3]](p0) :: (store (s32) into %stack.1 + 4, basealign 8)
+  ; X86-NEXT:   [[FPEXTLOAD1:%[0-9]+]]:psr(s80) = G_FPEXTLOAD [[FRAME_INDEX3]](p0) :: (load (s64) from %stack.1)
+  ; X86-NEXT:   [[FADD:%[0-9]+]]:psr(s80) = G_FADD [[FPEXTLOAD]], [[FPEXTLOAD1]]
+  ; X86-NEXT:   [[FRAME_INDEX4:%[0-9]+]]:gpr(p0) = G_FRAME_INDEX %stack.0
+  ; X86-NEXT:   G_FPTRUNCSTORE [[FADD]](s80), [[FRAME_INDEX4]](p0) :: (store (s64) into %stack.0)
+  ; X86-NEXT:   [[LOAD6:%[0-9]+]]:gpr(s32) = G_LOAD [[FRAME_INDEX4]](p0) :: (load (s32) from %stack.0, align 8)
+  ; X86-NEXT:   [[PTR_ADD4:%[0-9]+]]:gpr(p0) = nuw inbounds G_PTR_ADD [[FRAME_INDEX4]], [[C]](s32)
+  ; X86-NEXT:   [[LOAD7:%[0-9]+]]:gpr(s32) = G_LOAD [[PTR_ADD4]](p0) :: (load (s32) from %stack.0 + 4, basealign 8)
+  ; X86-NEXT:   G_STORE [[LOAD6]](s32), [[LOAD]](p0) :: (store (s32) into %ir.a, align 8)
+  ; X86-NEXT:   G_STORE [[LOAD7]](s32), [[PTR_ADD]](p0) :: (store (s32) into %ir.a + 4, basealign 8)
   ; X86-NEXT:   RET 0
   ;
   ; X64-LABEL: name: f5
@@ -186,10 +195,19 @@ define void @f5(ptr %a, ptr %b) {
   ; X64-NEXT: {{  $}}
   ; X64-NEXT:   [[COPY:%[0-9]+]]:gpr(p0) = COPY $rdi
   ; X64-NEXT:   [[COPY1:%[0-9]+]]:gpr(p0) = COPY $rsi
-  ; X64-NEXT:   [[LOAD:%[0-9]+]]:psr(s64) = G_LOAD [[COPY]](p0) :: (load (s64) from %ir.a)
-  ; X64-NEXT:   [[LOAD1:%[0-9]+]]:psr(s64) = G_LOAD [[COPY1]](p0) :: (load (s64) from %ir.b)
-  ; X64-NEXT:   [[FADD:%[0-9]+]]:psr(s64) = G_FADD [[LOAD]], [[LOAD1]]
-  ; X64-NEXT:   G_STORE [[FADD]](s64), [[COPY]](p0) :: (store (s64) into %ir.a)
+  ; X64-NEXT:   [[LOAD:%[0-9]+]]:gpr(s64) = G_LOAD [[COPY]](p0) :: (load (s64) from %ir.a)
+  ; X64-NEXT:   [[LOAD1:%[0-9]+]]:gpr(s64) = G_LOAD [[COPY1]](p0) :: (load (s64) from %ir.b)
+  ; X64-NEXT:   [[FRAME_INDEX:%[0-9]+]]:gpr(p0) = G_FRAME_INDEX %stack.2
+  ; X64-NEXT:   G_STORE [[LOAD]](s64), [[FRAME_INDEX]](p0) :: (store (s64) into %stack.2)
+  ; X64-NEXT:   [[FPEXTLOAD:%[0-9]+]]:psr(s80) = G_FPEXTLOAD [[FRAME_INDEX]](p0) :: (load (s64) from %stack.2)
+  ; X64-NEXT:   [[FRAME_INDEX1:%[0-9]+]]:gpr(p0) = G_FRAME_INDEX %stack.1
+  ; X64-NEXT:   G_STORE [[LOAD1]](s64), [[FRAME_INDEX1]](p0) :: (store (s64) into %stack.1)
+  ; X64-NEXT:   [[FPEXTLOAD1:%[0-9]+]]:psr(s80) = G_FPEXTLOAD [[FRAME_INDEX1]](p0) :: (load (s64) from %stack.1)
+  ; X64-NEXT:   [[FADD:%[0-9]+]]:psr(s80) = G_FADD [[FPEXTLOAD]], [[FPEXTLOAD1]]
+  ; X64-NEXT:   [[FRAME_INDEX2:%[0-9]+]]:gpr(p0) = G_FRAME_INDEX %stack.0
+  ; X64-NEXT:   G_FPTRUNCSTORE [[FADD]](s80), [[FRAME_INDEX2]](p0) :: (store (s64) into %stack.0)
+  ; X64-NEXT:   [[LOAD2:%[0-9]+]]:gpr(s64) = G_LOAD [[FRAME_INDEX2]](p0) :: (load (s64) from %stack.0)
+  ; X64-NEXT:   G_STORE [[LOAD2]](s64), [[COPY]](p0) :: (store (s64) into %ir.a)
   ; X64-NEXT:   RET 0
   %load1 = load double, ptr %a, align 8
   %load2 = load double, ptr %b, align 8
@@ -206,9 +224,18 @@ define void @f6(ptr %0, ptr %1) {
   ; X86-NEXT:   [[FRAME_INDEX1:%[0-9]+]]:gpr(p0) = G_FRAME_INDEX %fixed-stack.0
   ; X86-NEXT:   [[LOAD1:%[0-9]+]]:gpr(p0) = G_LOAD [[FRAME_INDEX1]](p0) :: (invariant load (p0) from %fixed-stack.0)
   ; X86-NEXT:   [[C:%[0-9]+]]:psr(s32) = G_FCONSTANT float 2.000000e+01
-  ; X86-NEXT:   [[LOAD2:%[0-9]+]]:psr(s32) = G_LOAD [[LOAD]](p0) :: (load (s32) from %ir.0)
-  ; X86-NEXT:   [[FADD:%[0-9]+]]:psr(s32) = G_FADD [[LOAD2]], [[C]]
-  ; X86-NEXT:   G_STORE [[FADD]](s32), [[LOAD1]](p0) :: (store (s32) into %ir.1)
+  ; X86-NEXT:   [[LOAD2:%[0-9]+]]:gpr(s32) = G_LOAD [[LOAD]](p0) :: (load (s32) from %ir.0)
+  ; X86-NEXT:   [[FRAME_INDEX2:%[0-9]+]]:gpr(p0) = G_FRAME_INDEX %stack.2
+  ; X86-NEXT:   G_STORE [[LOAD2]](s32), [[FRAME_INDEX2]](p0) :: (store (s32) into %stack.2)
+  ; X86-NEXT:   [[FPEXTLOAD:%[0-9]+]]:psr(s80) = G_FPEXTLOAD [[FRAME_INDEX2]](p0) :: (load (s32) from %stack.2)
+  ; X86-NEXT:   [[FRAME_INDEX3:%[0-9]+]]:gpr(p0) = G_FRAME_INDEX %stack.1
+  ; X86-NEXT:   G_STORE [[C]](s32), [[FRAME_INDEX3]](p0) :: (store (s32) into %stack.1)
+  ; X86-NEXT:   [[FPEXTLOAD1:%[0-9]+]]:psr(s80) = G_FPEXTLOAD [[FRAME_INDEX3]](p0) :: (load (s32) from %stack.1)
+  ; X86-NEXT:   [[FADD:%[0-9]+]]:psr(s80) = G_FADD [[FPEXTLOAD]], [[FPEXTLOAD1]]
+  ; X86-NEXT:   [[FRAME_INDEX4:%[0-9]+]]:gpr(p0) = G_FRAME_INDEX %stack.0
+  ; X86-NEXT:   G_FPTRUNCSTORE [[FADD]](s80), [[FRAME_INDEX4]](p0) :: (store (s32) into %stack.0)
+  ; X86-NEXT:   [[LOAD3:%[0-9]+]]:gpr(s32) = G_LOAD [[FRAME_INDEX4]](p0) :: (load (s32) from %stack.0)
+  ; X86-NEXT:   G_STORE [[LOAD3]](s32), [[LOAD1]](p0) :: (store (s32) into %ir.1)
   ; X86-NEXT:   RET 0
   ;
   ; X64-LABEL: name: f6
@@ -218,9 +245,18 @@ define void @f6(ptr %0, ptr %1) {
   ; X64-NEXT:   [[COPY:%[0-9]+]]:gpr(p0) = COPY $rdi
   ; X64-NEXT:   [[COPY1:%[0-9]+]]:gpr(p0) = COPY $rsi
   ; X64-NEXT:   [[C:%[0-9]+]]:psr(s32) = G_FCONSTANT float 2.000000e+01
-  ; X64-NEXT:   [[LOAD:%[0-9]+]]:psr(s32) = G_LOAD [[COPY]](p0) :: (load (s32) from %ir.0)
-  ; X64-NEXT:   [[FADD:%[0-9]+]]:psr(s32) = G_FADD [[LOAD]], [[C]]
-  ; X64-NEXT:   G_STORE [[FADD]](s32), [[COPY1]](p0) :: (store (s32) into %ir.1)
+  ; X64-NEXT:   [[LOAD:%[0-9]+]]:gpr(s32) = G_LOAD [[COPY]](p0) :: (load (s32) from %ir.0)
+  ; X64-NEXT:   [[FRAME_INDEX:%[0-9]+]]:gpr(p0) = G_FRAME_INDEX %stack.2
+  ; X64-NEXT:   G_STORE [[LOAD]](s32), [[FRAME_INDEX]](p0) :: (store (s32) into %stack.2)
+  ; X64-NEXT:   [[FPEXTLOAD:%[0-9]+]]:psr(s80) = G_FPEXTLOAD [[FRAME_INDEX]](p0) :: (load (s32) from %stack.2)
+  ; X64-NEXT:   [[FRAME_INDEX1:%[0-9]+]]:gpr(p0) = G_FRAME_INDEX %stack.1
+  ; X64-NEXT:   G_STORE [[C]](s32), [[FRAME_INDEX1]](p0) :: (store (s32) into %stack.1)
+  ; X64-NEXT:   [[FPEXTLOAD1:%[0-9]+]]:psr(s80) = G_FPEXTLOAD [[FRAME_INDEX1]](p0) :: (load (s32) from %stack.1)
+  ; X64-NEXT:   [[FADD:%[0-9]+]]:psr(s80) = G_FADD [[FPEXTLOAD]], [[FPEXTLOAD1]]
+  ; X64-NEXT:   [[FRAME_INDEX2:%[0-9]+]]:gpr(p0) = G_FRAME_INDEX %stack.0
+  ; X64-NEXT:   G_FPTRUNCSTORE [[FADD]](s80), [[FRAME_INDEX2]](p0) :: (store (s32) into %stack.0)
+  ; X64-NEXT:   [[LOAD1:%[0-9]+]]:gpr(s32) = G_LOAD [[FRAME_INDEX2]](p0) :: (load (s32) from %stack.0)
+  ; X64-NEXT:   G_STORE [[LOAD1]](s32), [[COPY1]](p0) :: (store (s32) into %ir.1)
   ; X64-NEXT:   RET 0
   %load1 = load float, ptr %0
   %add = fadd float %load1, 20.0
diff --git a/llvm/test/CodeGen/X86/GlobalISel/sqrt.mir b/llvm/test/CodeGen/X86/GlobalISel/sqrt.mir
index 4c166c887a5be..bdc80ad43a8a5 100644
--- a/llvm/test/CodeGen/X86/GlobalISel/sqrt.mir
+++ b/llvm/test/CodeGen/X86/GlobalISel/sqrt.mir
@@ -1,5 +1,9 @@
 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
-# RUN: llc -mtriple=i686-linux-gnu -run-pass=reg-bank-select,instruction-select %s -o - | FileCheck %s --check-prefixes GISEL-I686
+# RUN: llc -mtriple=i686-linux-gnu -disable-gisel-legality-check -run-pass=reg-bank-select,instruction-select %s -o - | FileCheck %s --check-prefixes GISEL-I686
+
+# -disable-gisel-legality-check:
+# test_sqrt_f32 and test_sqrt_f64 are not legal in that form, the legalizer
+# would have widened s32/s64 x87 arithmetic to s80.
 
 ---
 name:            test_sqrt_f32
diff --git a/llvm/test/CodeGen/X86/isel-fadd.ll b/llvm/test/CodeGen/X86/isel-fadd.ll
index b45510888098f..8b79e4bc488e6 100644
--- a/llvm/test/CodeGen/X86/isel-fadd.ll
+++ b/llvm/test/CodeGen/X86/isel-fadd.ll
@@ -40,8 +40,18 @@ define float @test_fadd_f32(float %arg1, float %arg2) {
 ;
 ; GISEL-X86-LABEL: test_fadd_f32:
 ; GISEL-X86:       # %bb.0:
-; GISEL-X86-NEXT:    flds {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    subl $12, %esp
+; GISEL-X86-NEXT:    .cfi_def_cfa_offset 16
+; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; GISEL-X86-NEXT:    movl %eax, (%esp)
+; GISEL-X86-NEXT:    flds (%esp)
+; GISEL-X86-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
 ; GISEL-X86-NEXT:    fadds {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    fstps {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    flds {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    addl $12, %esp
+; GISEL-X86-NEXT:    .cfi_def_cfa_offset 4
 ; GISEL-X86-NEXT:    retl
 ;
 ; SSE-LABEL: test_fadd_f32:
diff --git a/llvm/test/CodeGen/X86/isel-fdiv.ll b/llvm/test/CodeGen/X86/isel-fdiv.ll
index 2f1f1639386dc..b88f6a678ab55 100644
--- a/llvm/test/CodeGen/X86/isel-fdiv.ll
+++ b/llvm/test/CodeGen/X86/isel-fdiv.ll
@@ -40,8 +40,18 @@ define float @test_fdiv_f32(float %arg1, float %arg2) {
 ;
 ; GISEL-X86-LABEL: test_fdiv_f32:
 ; GISEL-X86:       # %bb.0:
+; GISEL-X86-NEXT:    subl $12, %esp
+; GISEL-X86-NEXT:    .cfi_def_cfa_offset 16
+; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; GISEL-X86-NEXT:    movl %eax, (%esp)
+; GISEL-X86-NEXT:    flds (%esp)
+; GISEL-X86-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    fdivs {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    fstps {{[0-9]+}}(%esp)
 ; GISEL-X86-NEXT:    flds {{[0-9]+}}(%esp)
-; GISEL-X86-NEXT:    fdivrs {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    addl $12, %esp
+; GISEL-X86-NEXT:    .cfi_def_cfa_offset 4
 ; GISEL-X86-NEXT:    retl
 ;
 ; SSE-LABEL: test_fdiv_f32:
diff --git a/llvm/test/CodeGen/X86/isel-fmul.ll b/llvm/test/CodeGen/X86/isel-fmul.ll
index 92fff53804ee8..60d38f3ca4140 100644
--- a/llvm/test/CodeGen/X86/isel-fmul.ll
+++ b/llvm/test/CodeGen/X86/isel-fmul.ll
@@ -40,8 +40,18 @@ define float @test_fmul_f32(float %arg1, float %arg2) {
 ;
 ; GISEL-X86-LABEL: test_fmul_f32:
 ; GISEL-X86:       # %bb.0:
-; GISEL-X86-NEXT:    flds {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    subl $12, %esp
+; GISEL-X86-NEXT:    .cfi_def_cfa_offset 16
+; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; GISEL-X86-NEXT:    movl %eax, (%esp)
+; GISEL-X86-NEXT:    flds (%esp)
+; GISEL-X86-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
 ; GISEL-X86-NEXT:    fmuls {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    fstps {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    flds {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    addl $12, %esp
+; GISEL-X86-NEXT:    .cfi_def_cfa_offset 4
 ; GISEL-X86-NEXT:    retl
 ;
 ; SSE-LABEL: test_fmul_f32:
diff --git a/llvm/test/CodeGen/X86/isel-fsub.ll b/llvm/test/CodeGen/X86/isel-fsub.ll
index 98a0129c40d56..63c949713d3a2 100644
--- a/llvm/test/CodeGen/X86/isel-fsub.ll
+++ b/llvm/test/CodeGen/X86/isel-fsub.ll
@@ -40,8 +40,18 @@ define float @test_fsub_f32(float %arg1, float %arg2) {
 ;
 ; GISEL-X86-LABEL: test_fsub_f32:
 ; GISEL-X86:       # %bb.0:
+; GISEL-X86-NEXT:    subl $12, %esp
+; GISEL-X86-NEXT:    .cfi_def_cfa_offset 16
+; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; GISEL-X86-NEXT:    movl %eax, (%esp)
+; GISEL-X86-NEXT:    flds (%esp)
+; GISEL-X86-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    fsubs {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    fstps {{[0-9]+}}(%esp)
 ; GISEL-X86-NEXT:    flds {{[0-9]+}}(%esp)
-; GISEL-X86-NEXT:    fsubrs {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    addl $12, %esp
+; GISEL-X86-NEXT:    .cfi_def_cfa_offset 4
 ; GISEL-X86-NEXT:    retl
 ;
 ; SSE-LABEL: test_fsub_f32:
diff --git a/llvm/test/CodeGen/X86/isel-sqrt.ll b/llvm/test/CodeGen/X86/isel-sqrt.ll
index e25ebedbe38ce..73aa958807040 100644
--- a/llvm/test/CodeGen/X86/isel-sqrt.ll
+++ b/llvm/test/CodeGen/X86/isel-sqrt.ll
@@ -47,8 +47,16 @@ define float @test_sqrt_f32(float %a) {
 ;
 ; GISEL-X86-LABEL: test_sqrt_f32:
 ; GISEL-X86:       # %bb.0:
-; GISEL-X86-NEXT:    flds {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    subl $8, %esp
+; GISEL-X86-NEXT:    .cfi_def_cfa_offset 12
+; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; GISEL-X86-NEXT:    movl %eax, (%esp)
+; GISEL-X86-NEXT:    flds (%esp)
 ; GISEL-X86-NEXT:    fsqrt
+; GISEL-X86-NEXT:    fstps {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    flds {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    addl $8, %esp
+; GISEL-X86-NEXT:    .cfi_def_cfa_offset 4
 ; GISEL-X86-NEXT:    retl
   %res = call float @llvm.sqrt.f32(float %a)
   ret float %res
diff --git a/llvm/test/CodeGen/X86/isel-x87.ll b/llvm/test/CodeGen/X86/isel-x87.ll
index 492faaa19cd66..6fb48c8c4dce7 100644
--- a/llvm/test/CodeGen/X86/isel-x87.ll
+++ b/llvm/test/CodeGen/X86/isel-x87.ll
@@ -183,11 +183,20 @@ define void @f3(ptr %a, ptr %b) nounwind {
 define void @f6(ptr %a, ptr %b) nounwind {
 ; GISEL_X86-LABEL: f6:
 ; GISEL_X86:       # %bb.0:
+; GISEL_X86-NEXT:    subl $12, %esp
 ; GISEL_X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; GISEL_X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; GISEL_X86-NEXT:    flds {{\.?LCPI[0-9]+_[0-9]+}}
-; GISEL_X86-NEXT:    fadds (%eax)
-; GISEL_X86-NEXT:    fstps (%ecx)
+; GISEL_X86-NEXT:    movl (%eax), %eax
+; GISEL_X86-NEXT:    movl %eax, (%esp)
+; GISEL_X86-NEXT:    flds (%esp)
+; GISEL_X86-NEXT:    fxch %st(1)
+; GISEL_X86-NEXT:    fstps {{[0-9]+}}(%esp)
+; GISEL_X86-NEXT:    fadds {{[0-9]+}}(%esp)
+; GISEL_X86-NEXT:    fstps {{[0-9]+}}(%esp)
+; GISEL_X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; GISEL_X86-NEXT:    movl %eax, (%ecx)
+; GISEL_X86-NEXT:    addl $12, %esp
 ; GISEL_X86-NEXT:    retl
 ;
 ; SDAG_X86-LABEL: f6:
@@ -202,8 +211,15 @@ define void @f6(ptr %a, ptr %b) nounwind {
 ; GISEL_X64-LABEL: f6:
 ; GISEL_X64:       # %bb.0:
 ; GISEL_X64-NEXT:    flds {{\.?LCPI[0-9]+_[0-9]+}}(%rip)
-; GISEL_X64-NEXT:    fadds (%rdi)
-; GISEL_X64-NEXT:    fstps (%rsi)
+; GISEL_X64-NEXT:    movl (%rdi), %eax
+; GISEL_X64-NEXT:    movl %eax, -{{[0-9]+}}(%rsp)
+; GISEL_X64-NEXT:    flds -{{[0-9]+}}(%rsp)
+; GISEL_X64-NEXT:    fxch %st(1)
+; GISEL_X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
+; GISEL_X64-NEXT:    fadds -{{[0-9]+}}(%rsp)
+; GISEL_X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
+; GISEL_X64-NEXT:    movl -{{[0-9]+}}(%rsp), %eax
+; GISEL_X64-NEXT:    movl %eax, (%rsi)
 ; GISEL_X64-NEXT:    retq
 ;
 ; SDAG_X64-LABEL: f6:

>From 6d63f47df8406e72f3a9005f4976b8c32246ba5a Mon Sep 17 00:00:00 2001
From: Dennis Duda <git at seri.tools>
Date: Thu, 27 Aug 2026 02:28:44 +0200
Subject: [PATCH 10/15] [X86][GlobalISel] Pre-commit test for the x87 `sitofp`
 roundtrip

GlobalISel leaves the `fild` result at the width the x87 stack holds it in, so comparing it against its own reload from memory can come out false. The SelectionDAG path already rounds.

Co-authored-by: Claude (Claude-Opus-5) <noreply at anthropic.com>
---
 llvm/test/CodeGen/X86/isel-sint-to-fp-x87.ll | 79 ++++++++++++++++++++
 1 file changed, 79 insertions(+)

diff --git a/llvm/test/CodeGen/X86/isel-sint-to-fp-x87.ll b/llvm/test/CodeGen/X86/isel-sint-to-fp-x87.ll
index c2c2f994d22b6..19282fdd6e6b4 100644
--- a/llvm/test/CodeGen/X86/isel-sint-to-fp-x87.ll
+++ b/llvm/test/CodeGen/X86/isel-sint-to-fp-x87.ll
@@ -343,3 +343,82 @@ entry:
   store double %conv, ptr %p, align 4
   ret void
 }
+
+; %conv has type float, so it has to be rounded to float before it is used:
+; comparing it against its own reload from memory has to be true.
+define i32 @test_int32_to_float_roundtrip(i32 %x, ptr %p) nounwind {
+; SDAG-X64-LABEL: test_int32_to_float_roundtrip:
+; SDAG-X64:       # %bb.0: # %entry
+; SDAG-X64-NEXT:    movl %edi, -{{[0-9]+}}(%rsp)
+; SDAG-X64-NEXT:    fildl -{{[0-9]+}}(%rsp)
+; SDAG-X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
+; SDAG-X64-NEXT:    flds -{{[0-9]+}}(%rsp)
+; SDAG-X64-NEXT:    fsts (%rsi)
+; SDAG-X64-NEXT:    xorl %eax, %eax
+; SDAG-X64-NEXT:    fucompi %st(0), %st
+; SDAG-X64-NEXT:    setnp %al
+; SDAG-X64-NEXT:    retq
+;
+; GISEL-X64-LABEL: test_int32_to_float_roundtrip:
+; GISEL-X64:       # %bb.0: # %entry
+; GISEL-X64-NEXT:    movl %edi, -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    fildl -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    fsts (%rsi)
+; GISEL-X64-NEXT:    flds (%rsi)
+; GISEL-X64-NEXT:    fxch %st(1)
+; GISEL-X64-NEXT:    fucompi %st(1), %st
+; GISEL-X64-NEXT:    fstp %st(0)
+; GISEL-X64-NEXT:    sete %al
+; GISEL-X64-NEXT:    setnp %cl
+; GISEL-X64-NEXT:    andb %al, %cl
+; GISEL-X64-NEXT:    movzbl %cl, %eax
+; GISEL-X64-NEXT:    andl $1, %eax
+; GISEL-X64-NEXT:    retq
+;
+; SDAG-X86-LABEL: test_int32_to_float_roundtrip:
+; SDAG-X86:       # %bb.0: # %entry
+; SDAG-X86-NEXT:    subl $8, %esp
+; SDAG-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; SDAG-X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; SDAG-X86-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
+; SDAG-X86-NEXT:    fildl {{[0-9]+}}(%esp)
+; SDAG-X86-NEXT:    fstps (%esp)
+; SDAG-X86-NEXT:    flds (%esp)
+; SDAG-X86-NEXT:    fsts (%eax)
+; SDAG-X86-NEXT:    fucomp %st(0)
+; SDAG-X86-NEXT:    fnstsw %ax
+; SDAG-X86-NEXT:    xorl %ecx, %ecx
+; SDAG-X86-NEXT:    # kill: def $ah killed $ah killed $ax
+; SDAG-X86-NEXT:    sahf
+; SDAG-X86-NEXT:    setnp %cl
+; SDAG-X86-NEXT:    movl %ecx, %eax
+; SDAG-X86-NEXT:    addl $8, %esp
+; SDAG-X86-NEXT:    retl
+;
+; GISEL-X86-LABEL: test_int32_to_float_roundtrip:
+; GISEL-X86:       # %bb.0: # %entry
+; GISEL-X86-NEXT:    pushl %eax
+; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; GISEL-X86-NEXT:    movl %eax, (%esp)
+; GISEL-X86-NEXT:    fildl (%esp)
+; GISEL-X86-NEXT:    fsts (%ecx)
+; GISEL-X86-NEXT:    flds (%ecx)
+; GISEL-X86-NEXT:    fxch %st(1)
+; GISEL-X86-NEXT:    fucompi %st(1), %st
+; GISEL-X86-NEXT:    fstp %st(0)
+; GISEL-X86-NEXT:    sete %al
+; GISEL-X86-NEXT:    setnp %cl
+; GISEL-X86-NEXT:    andb %al, %cl
+; GISEL-X86-NEXT:    movzbl %cl, %eax
+; GISEL-X86-NEXT:    andl $1, %eax
+; GISEL-X86-NEXT:    popl %ecx
+; GISEL-X86-NEXT:    retl
+entry:
+  %conv = sitofp i32 %x to float
+  store float %conv, ptr %p, align 4
+  %reload = load float, ptr %p, align 4
+  %cmp = fcmp oeq float %conv, %reload
+  %res = zext i1 %cmp to i32
+  ret i32 %res
+}

>From c2da4f4cf00df31a7643433f8f111557ad25adb7 Mon Sep 17 00:00:00 2001
From: Dennis Duda <git at seri.tools>
Date: Sun, 9 Aug 2026 18:10:12 +0200
Subject: [PATCH 11/15] [X86][GlobalISel] Round `G_SITOFP` results to their own
 type

Just like the SelectionDAG `fild` handling.

Co-authored-by: Claude (Claude-Opus-5) <noreply at anthropic.com>
---
 .../lib/Target/X86/GISel/X86LegalizerInfo.cpp |  30 +-
 llvm/lib/Target/X86/GISel/X86LegalizerInfo.h  |   4 +
 llvm/test/CodeGen/X86/isel-sint-to-fp-x87.ll  | 296 +++++++++++++-----
 3 files changed, 243 insertions(+), 87 deletions(-)

diff --git a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
index a520d4843bea9..3e46fd5fb46ce 100644
--- a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
+++ b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
@@ -80,9 +80,8 @@ X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI,
   const LLT v16s32 = LLT::fixed_vector(16, 32);
   const LLT v8s64 = LLT::fixed_vector(8, 64);
 
-  const X86TargetLowering &TLI = *Subtarget.getTargetLowering();
-  bool RoundX87S32 = TLI.needsX87RoundToType(MVT::f32);
-  bool RoundX87S64 = TLI.needsX87RoundToType(MVT::f64);
+  bool RoundX87S32 = needsX87RoundToType(32);
+  bool RoundX87S64 = needsX87RoundToType(64);
   auto NeedsX87RoundToType = [=](const LegalityQuery &Query) {
     return (RoundX87S32 && Query.Types[0] == s32) ||
            (RoundX87S64 && Query.Types[0] == s64);
@@ -641,6 +640,18 @@ X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI,
   verify(*STI.getInstrInfo());
 }
 
+bool X86LegalizerInfo::needsX87RoundToType(unsigned SizeInBits) const {
+  const X86TargetLowering &TLI = *Subtarget.getTargetLowering();
+  switch (SizeInBits) {
+  case 32:
+    return TLI.needsX87RoundToType(MVT::f32);
+  case 64:
+    return TLI.needsX87RoundToType(MVT::f64);
+  default:
+    return false;
+  }
+}
+
 bool X86LegalizerInfo::legalizeCustom(LegalizerHelper &Helper, MachineInstr &MI,
                                       LostDebugLocObserver &LocObserver) const {
   MachineIRBuilder &MIRBuilder = Helper.MIRBuilder;
@@ -694,11 +705,22 @@ bool X86LegalizerInfo::legalizeSITOFP(MachineInstr &MI,
 
   MachineMemOperand *LoadMMO = MF.getMachineMemOperand(
       PtrInfo, MachineMemOperand::MOLoad, MemSize, Align(MemSize));
+
+  // fild loads the integer at the x87 register's full 80-bit precision, so an
+  // s32/s64 result does not generally hold a value of its own type yet. Take
+  // the wide value and let G_FPTRUNC round it back through memory.
+  bool NeedsRound = needsX87RoundToType(DstTy.getSizeInBits());
+  Register FILDDst =
+      NeedsRound ? MRI.createGenericVirtualRegister(LLT::scalar(80)) : Dst;
+
   MIRBuilder.buildInstr(X86::G_FILD)
-      .addDef(Dst)
+      .addDef(FILDDst)
       .addUse(SlotPointer.getReg(0))
       .addMemOperand(LoadMMO);
 
+  if (NeedsRound)
+    MIRBuilder.buildFPTrunc(Dst, FILDDst);
+
   MI.eraseFromParent();
   return true;
 }
diff --git a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.h b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.h
index 58be7bb7d02b8..acacd7b073ea6 100644
--- a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.h
+++ b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.h
@@ -37,6 +37,10 @@ class X86LegalizerInfo : public LegalizerInfo {
                          MachineInstr &MI) const override;
 
 private:
+  /// Whether an x87 result that is \p SizeInBits wide has to be rounded back to
+  /// its own type through memory.
+  bool needsX87RoundToType(unsigned SizeInBits) const;
+
   bool legalizeBuildVector(MachineInstr &MI, MachineRegisterInfo &MRI,
                            LegalizerHelper &Helper) const;
 
diff --git a/llvm/test/CodeGen/X86/isel-sint-to-fp-x87.ll b/llvm/test/CodeGen/X86/isel-sint-to-fp-x87.ll
index 19282fdd6e6b4..583b9831d11fe 100644
--- a/llvm/test/CodeGen/X86/isel-sint-to-fp-x87.ll
+++ b/llvm/test/CodeGen/X86/isel-sint-to-fp-x87.ll
@@ -23,7 +23,9 @@ define void @test_int8_to_float(i8 %x, ptr %p) nounwind {
 ; GISEL-X64-NEXT:    sarw $8, %di
 ; GISEL-X64-NEXT:    movw %di, -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NEXT:    filds -{{[0-9]+}}(%rsp)
-; GISEL-X64-NEXT:    fstps (%rsi)
+; GISEL-X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    movl -{{[0-9]+}}(%rsp), %eax
+; GISEL-X64-NEXT:    movl %eax, (%rsi)
 ; GISEL-X64-NEXT:    retq
 ;
 ; SDAG-X86-LABEL: test_int8_to_float:
@@ -39,15 +41,17 @@ define void @test_int8_to_float(i8 %x, ptr %p) nounwind {
 ;
 ; GISEL-X86-LABEL: test_int8_to_float:
 ; GISEL-X86:       # %bb.0: # %entry
-; GISEL-X86-NEXT:    pushl %eax
+; GISEL-X86-NEXT:    subl $8, %esp
 ; GISEL-X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
 ; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; GISEL-X86-NEXT:    shlw $8, %ax
 ; GISEL-X86-NEXT:    sarw $8, %ax
 ; GISEL-X86-NEXT:    movw %ax, {{[0-9]+}}(%esp)
 ; GISEL-X86-NEXT:    filds {{[0-9]+}}(%esp)
-; GISEL-X86-NEXT:    fstps (%ecx)
-; GISEL-X86-NEXT:    popl %eax
+; GISEL-X86-NEXT:    fstps {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; GISEL-X86-NEXT:    movl %eax, (%ecx)
+; GISEL-X86-NEXT:    addl $8, %esp
 ; GISEL-X86-NEXT:    retl
 entry:
   %conv = sitofp i8 %x to float
@@ -56,12 +60,21 @@ entry:
 }
 
 define void @test_int16_to_float(i16 %x, ptr %p) nounwind {
-; X64-LABEL: test_int16_to_float:
-; X64:       # %bb.0: # %entry
-; X64-NEXT:    movw %di, -{{[0-9]+}}(%rsp)
-; X64-NEXT:    filds -{{[0-9]+}}(%rsp)
-; X64-NEXT:    fstps (%rsi)
-; X64-NEXT:    retq
+; SDAG-X64-LABEL: test_int16_to_float:
+; SDAG-X64:       # %bb.0: # %entry
+; SDAG-X64-NEXT:    movw %di, -{{[0-9]+}}(%rsp)
+; SDAG-X64-NEXT:    filds -{{[0-9]+}}(%rsp)
+; SDAG-X64-NEXT:    fstps (%rsi)
+; SDAG-X64-NEXT:    retq
+;
+; GISEL-X64-LABEL: test_int16_to_float:
+; GISEL-X64:       # %bb.0: # %entry
+; GISEL-X64-NEXT:    movw %di, -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    filds -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    movl -{{[0-9]+}}(%rsp), %eax
+; GISEL-X64-NEXT:    movl %eax, (%rsi)
+; GISEL-X64-NEXT:    retq
 ;
 ; SDAG-X86-LABEL: test_int16_to_float:
 ; SDAG-X86:       # %bb.0: # %entry
@@ -76,13 +89,15 @@ define void @test_int16_to_float(i16 %x, ptr %p) nounwind {
 ;
 ; GISEL-X86-LABEL: test_int16_to_float:
 ; GISEL-X86:       # %bb.0: # %entry
-; GISEL-X86-NEXT:    pushl %eax
+; GISEL-X86-NEXT:    subl $8, %esp
 ; GISEL-X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
 ; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; GISEL-X86-NEXT:    movw %ax, {{[0-9]+}}(%esp)
 ; GISEL-X86-NEXT:    filds {{[0-9]+}}(%esp)
-; GISEL-X86-NEXT:    fstps (%ecx)
-; GISEL-X86-NEXT:    popl %eax
+; GISEL-X86-NEXT:    fstps {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; GISEL-X86-NEXT:    movl %eax, (%ecx)
+; GISEL-X86-NEXT:    addl $8, %esp
 ; GISEL-X86-NEXT:    retl
 entry:
   %conv = sitofp i16 %x to float
@@ -91,12 +106,21 @@ entry:
 }
 
 define void @test_int32_to_float(i32 %x, ptr %p) nounwind {
-; X64-LABEL: test_int32_to_float:
-; X64:       # %bb.0: # %entry
-; X64-NEXT:    movl %edi, -{{[0-9]+}}(%rsp)
-; X64-NEXT:    fildl -{{[0-9]+}}(%rsp)
-; X64-NEXT:    fstps (%rsi)
-; X64-NEXT:    retq
+; SDAG-X64-LABEL: test_int32_to_float:
+; SDAG-X64:       # %bb.0: # %entry
+; SDAG-X64-NEXT:    movl %edi, -{{[0-9]+}}(%rsp)
+; SDAG-X64-NEXT:    fildl -{{[0-9]+}}(%rsp)
+; SDAG-X64-NEXT:    fstps (%rsi)
+; SDAG-X64-NEXT:    retq
+;
+; GISEL-X64-LABEL: test_int32_to_float:
+; GISEL-X64:       # %bb.0: # %entry
+; GISEL-X64-NEXT:    movl %edi, -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    fildl -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    movl -{{[0-9]+}}(%rsp), %eax
+; GISEL-X64-NEXT:    movl %eax, (%rsi)
+; GISEL-X64-NEXT:    retq
 ;
 ; SDAG-X86-LABEL: test_int32_to_float:
 ; SDAG-X86:       # %bb.0: # %entry
@@ -111,13 +135,15 @@ define void @test_int32_to_float(i32 %x, ptr %p) nounwind {
 ;
 ; GISEL-X86-LABEL: test_int32_to_float:
 ; GISEL-X86:       # %bb.0: # %entry
-; GISEL-X86-NEXT:    pushl %eax
+; GISEL-X86-NEXT:    subl $8, %esp
 ; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; GISEL-X86-NEXT:    movl %eax, (%esp)
-; GISEL-X86-NEXT:    fildl (%esp)
-; GISEL-X86-NEXT:    fstps (%ecx)
-; GISEL-X86-NEXT:    popl %eax
+; GISEL-X86-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    fildl {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    fstps (%esp)
+; GISEL-X86-NEXT:    movl (%esp), %eax
+; GISEL-X86-NEXT:    movl %eax, (%ecx)
+; GISEL-X86-NEXT:    addl $8, %esp
 ; GISEL-X86-NEXT:    retl
 entry:
   %conv = sitofp i32 %x to float
@@ -126,12 +152,21 @@ entry:
 }
 
 define void @test_int64_to_float(i64 %x, ptr %p) nounwind {
-; X64-LABEL: test_int64_to_float:
-; X64:       # %bb.0: # %entry
-; X64-NEXT:    movq %rdi, -{{[0-9]+}}(%rsp)
-; X64-NEXT:    fildll -{{[0-9]+}}(%rsp)
-; X64-NEXT:    fstps (%rsi)
-; X64-NEXT:    retq
+; SDAG-X64-LABEL: test_int64_to_float:
+; SDAG-X64:       # %bb.0: # %entry
+; SDAG-X64-NEXT:    movq %rdi, -{{[0-9]+}}(%rsp)
+; SDAG-X64-NEXT:    fildll -{{[0-9]+}}(%rsp)
+; SDAG-X64-NEXT:    fstps (%rsi)
+; SDAG-X64-NEXT:    retq
+;
+; GISEL-X64-LABEL: test_int64_to_float:
+; GISEL-X64:       # %bb.0: # %entry
+; GISEL-X64-NEXT:    movq %rdi, -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    fildll -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    movl -{{[0-9]+}}(%rsp), %eax
+; GISEL-X64-NEXT:    movl %eax, (%rsi)
+; GISEL-X64-NEXT:    retq
 ;
 ; X86-LABEL: test_int64_to_float:
 ; X86:       # %bb.0: # %entry
@@ -255,19 +290,43 @@ define void @test_int8to_double(i8 %x, ptr %p) nounwind {
 ; GISEL-X64-NEXT:    sarw $8, %di
 ; GISEL-X64-NEXT:    movw %di, -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NEXT:    filds -{{[0-9]+}}(%rsp)
-; GISEL-X64-NEXT:    fstpl (%rsi)
+; GISEL-X64-NEXT:    fstpl -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    movq -{{[0-9]+}}(%rsp), %rax
+; GISEL-X64-NEXT:    movq %rax, (%rsi)
 ; GISEL-X64-NEXT:    retq
 ;
-; X86-LABEL: test_int8to_double:
-; X86:       # %bb.0: # %entry
-; X86-NEXT:    subl $12, %esp
-; X86-NEXT:    movsbl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT:    movw %ax, {{[0-9]+}}(%esp)
-; X86-NEXT:    filds {{[0-9]+}}(%esp)
-; X86-NEXT:    fstpl (%ecx)
-; X86-NEXT:    addl $12, %esp
-; X86-NEXT:    retl
+; SDAG-X86-LABEL: test_int8to_double:
+; SDAG-X86:       # %bb.0: # %entry
+; SDAG-X86-NEXT:    subl $12, %esp
+; SDAG-X86-NEXT:    movsbl {{[0-9]+}}(%esp), %eax
+; SDAG-X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; SDAG-X86-NEXT:    movw %ax, {{[0-9]+}}(%esp)
+; SDAG-X86-NEXT:    filds {{[0-9]+}}(%esp)
+; SDAG-X86-NEXT:    fstpl (%ecx)
+; SDAG-X86-NEXT:    addl $12, %esp
+; SDAG-X86-NEXT:    retl
+;
+; GISEL-X86-LABEL: test_int8to_double:
+; GISEL-X86:       # %bb.0: # %entry
+; GISEL-X86-NEXT:    pushl %ebp
+; GISEL-X86-NEXT:    movl %esp, %ebp
+; GISEL-X86-NEXT:    andl $-8, %esp
+; GISEL-X86-NEXT:    subl $16, %esp
+; GISEL-X86-NEXT:    movzbl 8(%ebp), %ecx
+; GISEL-X86-NEXT:    movl 12(%ebp), %eax
+; GISEL-X86-NEXT:    shlw $8, %cx
+; GISEL-X86-NEXT:    sarw $8, %cx
+; GISEL-X86-NEXT:    movw %cx, {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    filds {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    leal {{[0-9]+}}(%esp), %ecx
+; GISEL-X86-NEXT:    fstpl {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
+; GISEL-X86-NEXT:    movl 4(%ecx), %ecx
+; GISEL-X86-NEXT:    movl %edx, (%eax)
+; GISEL-X86-NEXT:    movl %ecx, 4(%eax)
+; GISEL-X86-NEXT:    movl %ebp, %esp
+; GISEL-X86-NEXT:    popl %ebp
+; GISEL-X86-NEXT:    retl
 entry:
   %conv = sitofp i8 %x to double
   store double %conv, ptr %p, align 4
@@ -275,23 +334,52 @@ entry:
 }
 
 define void @test_int16_to_double(i16 %x, ptr %p) nounwind {
-; X64-LABEL: test_int16_to_double:
-; X64:       # %bb.0: # %entry
-; X64-NEXT:    movw %di, -{{[0-9]+}}(%rsp)
-; X64-NEXT:    filds -{{[0-9]+}}(%rsp)
-; X64-NEXT:    fstpl (%rsi)
-; X64-NEXT:    retq
+; SDAG-X64-LABEL: test_int16_to_double:
+; SDAG-X64:       # %bb.0: # %entry
+; SDAG-X64-NEXT:    movw %di, -{{[0-9]+}}(%rsp)
+; SDAG-X64-NEXT:    filds -{{[0-9]+}}(%rsp)
+; SDAG-X64-NEXT:    fstpl (%rsi)
+; SDAG-X64-NEXT:    retq
 ;
-; X86-LABEL: test_int16_to_double:
-; X86:       # %bb.0: # %entry
-; X86-NEXT:    subl $12, %esp
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT:    movw %cx, {{[0-9]+}}(%esp)
-; X86-NEXT:    filds {{[0-9]+}}(%esp)
-; X86-NEXT:    fstpl (%eax)
-; X86-NEXT:    addl $12, %esp
-; X86-NEXT:    retl
+; GISEL-X64-LABEL: test_int16_to_double:
+; GISEL-X64:       # %bb.0: # %entry
+; GISEL-X64-NEXT:    movw %di, -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    filds -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    fstpl -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    movq -{{[0-9]+}}(%rsp), %rax
+; GISEL-X64-NEXT:    movq %rax, (%rsi)
+; GISEL-X64-NEXT:    retq
+;
+; SDAG-X86-LABEL: test_int16_to_double:
+; SDAG-X86:       # %bb.0: # %entry
+; SDAG-X86-NEXT:    subl $12, %esp
+; SDAG-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; SDAG-X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
+; SDAG-X86-NEXT:    movw %cx, {{[0-9]+}}(%esp)
+; SDAG-X86-NEXT:    filds {{[0-9]+}}(%esp)
+; SDAG-X86-NEXT:    fstpl (%eax)
+; SDAG-X86-NEXT:    addl $12, %esp
+; SDAG-X86-NEXT:    retl
+;
+; GISEL-X86-LABEL: test_int16_to_double:
+; GISEL-X86:       # %bb.0: # %entry
+; GISEL-X86-NEXT:    pushl %ebp
+; GISEL-X86-NEXT:    movl %esp, %ebp
+; GISEL-X86-NEXT:    andl $-8, %esp
+; GISEL-X86-NEXT:    subl $16, %esp
+; GISEL-X86-NEXT:    movzwl 8(%ebp), %eax
+; GISEL-X86-NEXT:    movl 12(%ebp), %ecx
+; GISEL-X86-NEXT:    movw %ax, {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    filds {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    leal {{[0-9]+}}(%esp), %eax
+; GISEL-X86-NEXT:    fstpl {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
+; GISEL-X86-NEXT:    movl 4(%eax), %eax
+; GISEL-X86-NEXT:    movl %edx, (%ecx)
+; GISEL-X86-NEXT:    movl %eax, 4(%ecx)
+; GISEL-X86-NEXT:    movl %ebp, %esp
+; GISEL-X86-NEXT:    popl %ebp
+; GISEL-X86-NEXT:    retl
 entry:
   %conv = sitofp i16 %x to double
   store double %conv, ptr %p, align 4
@@ -299,23 +387,52 @@ entry:
 }
 
 define void @test_int32_to_double(i32 %x, ptr %p) nounwind {
-; X64-LABEL: test_int32_to_double:
-; X64:       # %bb.0: # %entry
-; X64-NEXT:    movl %edi, -{{[0-9]+}}(%rsp)
-; X64-NEXT:    fildl -{{[0-9]+}}(%rsp)
-; X64-NEXT:    fstpl (%rsi)
-; X64-NEXT:    retq
+; SDAG-X64-LABEL: test_int32_to_double:
+; SDAG-X64:       # %bb.0: # %entry
+; SDAG-X64-NEXT:    movl %edi, -{{[0-9]+}}(%rsp)
+; SDAG-X64-NEXT:    fildl -{{[0-9]+}}(%rsp)
+; SDAG-X64-NEXT:    fstpl (%rsi)
+; SDAG-X64-NEXT:    retq
 ;
-; X86-LABEL: test_int32_to_double:
-; X86:       # %bb.0: # %entry
-; X86-NEXT:    subl $12, %esp
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT:    movl %ecx, (%esp)
-; X86-NEXT:    fildl (%esp)
-; X86-NEXT:    fstpl (%eax)
-; X86-NEXT:    addl $12, %esp
-; X86-NEXT:    retl
+; GISEL-X64-LABEL: test_int32_to_double:
+; GISEL-X64:       # %bb.0: # %entry
+; GISEL-X64-NEXT:    movl %edi, -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    fildl -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    fstpl -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    movq -{{[0-9]+}}(%rsp), %rax
+; GISEL-X64-NEXT:    movq %rax, (%rsi)
+; GISEL-X64-NEXT:    retq
+;
+; SDAG-X86-LABEL: test_int32_to_double:
+; SDAG-X86:       # %bb.0: # %entry
+; SDAG-X86-NEXT:    subl $12, %esp
+; SDAG-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; SDAG-X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; SDAG-X86-NEXT:    movl %ecx, (%esp)
+; SDAG-X86-NEXT:    fildl (%esp)
+; SDAG-X86-NEXT:    fstpl (%eax)
+; SDAG-X86-NEXT:    addl $12, %esp
+; SDAG-X86-NEXT:    retl
+;
+; GISEL-X86-LABEL: test_int32_to_double:
+; GISEL-X86:       # %bb.0: # %entry
+; GISEL-X86-NEXT:    pushl %ebp
+; GISEL-X86-NEXT:    movl %esp, %ebp
+; GISEL-X86-NEXT:    andl $-8, %esp
+; GISEL-X86-NEXT:    subl $16, %esp
+; GISEL-X86-NEXT:    movl 8(%ebp), %eax
+; GISEL-X86-NEXT:    movl 12(%ebp), %ecx
+; GISEL-X86-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    fildl {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    leal {{[0-9]+}}(%esp), %eax
+; GISEL-X86-NEXT:    fstpl {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
+; GISEL-X86-NEXT:    movl 4(%eax), %eax
+; GISEL-X86-NEXT:    movl %edx, (%ecx)
+; GISEL-X86-NEXT:    movl %eax, 4(%ecx)
+; GISEL-X86-NEXT:    movl %ebp, %esp
+; GISEL-X86-NEXT:    popl %ebp
+; GISEL-X86-NEXT:    retl
 entry:
   %conv = sitofp i32 %x to double
   store double %conv, ptr %p, align 4
@@ -323,12 +440,21 @@ entry:
 }
 
 define void @test_int64_to_double(i64 %x, ptr %p) nounwind {
-; X64-LABEL: test_int64_to_double:
-; X64:       # %bb.0: # %entry
-; X64-NEXT:    movq %rdi, -{{[0-9]+}}(%rsp)
-; X64-NEXT:    fildll -{{[0-9]+}}(%rsp)
-; X64-NEXT:    fstpl (%rsi)
-; X64-NEXT:    retq
+; SDAG-X64-LABEL: test_int64_to_double:
+; SDAG-X64:       # %bb.0: # %entry
+; SDAG-X64-NEXT:    movq %rdi, -{{[0-9]+}}(%rsp)
+; SDAG-X64-NEXT:    fildll -{{[0-9]+}}(%rsp)
+; SDAG-X64-NEXT:    fstpl (%rsi)
+; SDAG-X64-NEXT:    retq
+;
+; GISEL-X64-LABEL: test_int64_to_double:
+; GISEL-X64:       # %bb.0: # %entry
+; GISEL-X64-NEXT:    movq %rdi, -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    fildll -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    fstpl -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    movq -{{[0-9]+}}(%rsp), %rax
+; GISEL-X64-NEXT:    movq %rax, (%rsi)
+; GISEL-X64-NEXT:    retq
 ;
 ; X86-LABEL: test_int64_to_double:
 ; X86:       # %bb.0: # %entry
@@ -363,6 +489,8 @@ define i32 @test_int32_to_float_roundtrip(i32 %x, ptr %p) nounwind {
 ; GISEL-X64:       # %bb.0: # %entry
 ; GISEL-X64-NEXT:    movl %edi, -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NEXT:    fildl -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
+; GISEL-X64-NEXT:    flds -{{[0-9]+}}(%rsp)
 ; GISEL-X64-NEXT:    fsts (%rsi)
 ; GISEL-X64-NEXT:    flds (%rsi)
 ; GISEL-X64-NEXT:    fxch %st(1)
@@ -397,11 +525,13 @@ define i32 @test_int32_to_float_roundtrip(i32 %x, ptr %p) nounwind {
 ;
 ; GISEL-X86-LABEL: test_int32_to_float_roundtrip:
 ; GISEL-X86:       # %bb.0: # %entry
-; GISEL-X86-NEXT:    pushl %eax
+; GISEL-X86-NEXT:    subl $8, %esp
 ; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; GISEL-X86-NEXT:    movl %eax, (%esp)
-; GISEL-X86-NEXT:    fildl (%esp)
+; GISEL-X86-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    fildl {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    fstps (%esp)
+; GISEL-X86-NEXT:    flds (%esp)
 ; GISEL-X86-NEXT:    fsts (%ecx)
 ; GISEL-X86-NEXT:    flds (%ecx)
 ; GISEL-X86-NEXT:    fxch %st(1)
@@ -412,7 +542,7 @@ define i32 @test_int32_to_float_roundtrip(i32 %x, ptr %p) nounwind {
 ; GISEL-X86-NEXT:    andb %al, %cl
 ; GISEL-X86-NEXT:    movzbl %cl, %eax
 ; GISEL-X86-NEXT:    andl $1, %eax
-; GISEL-X86-NEXT:    popl %ecx
+; GISEL-X86-NEXT:    addl $8, %esp
 ; GISEL-X86-NEXT:    retl
 entry:
   %conv = sitofp i32 %x to float

>From b9406608377cb1d1ae2fe21c5003ba8bc3c90939 Mon Sep 17 00:00:00 2001
From: Dennis Duda <git at seri.tools>
Date: Sun, 9 Aug 2026 18:24:29 +0200
Subject: [PATCH 12/15] [X86][GlobalISel] Select an x87 `G_FPEXT` as a copy

An x87 register is 80 bits wide whatever type it holds, so widening a value
that is already on the stack is exact and free - SelectionDAG selects it as a
`COPY_TO_REGCLASS`. GlobalISel instead lowered every `G_FPEXT` on x87 to a
store/load round-trip, which since the widening of f32/f64 arithmetic to s80
is on the input side of every FP operation.

Make the x87-to-x87 pairs legal and turn them into a plain copy in the
selector. `G_FPTRUNC` keeps its round-trip: that one has to round.

`getFltSemanticForLLT` now needs the 80-bit case, which the post-legalizer
combiner now reaches when it constant-folds a `G_FPEXT` to s80.

Co-authored-by: Claude (Claude-Opus-5) <noreply at anthropic.com>
---
 llvm/lib/CodeGen/LowLevelTypeUtils.cpp        |  3 +
 .../X86/GISel/X86InstructionSelector.cpp      | 22 +++++
 .../lib/Target/X86/GISel/X86LegalizerInfo.cpp | 19 +++++
 llvm/lib/Target/X86/GISel/X86LegalizerInfo.h  |  4 +
 .../X86/GlobalISel/regbankselect-x87.ll       | 84 ++++++++-----------
 llvm/test/CodeGen/X86/isel-fadd.ll            | 17 ++--
 llvm/test/CodeGen/X86/isel-fdiv.ll            | 17 ++--
 llvm/test/CodeGen/X86/isel-fmul.ll            | 17 ++--
 llvm/test/CodeGen/X86/isel-fptrunc-fpext.ll   | 61 ++++----------
 llvm/test/CodeGen/X86/isel-fsub.ll            | 17 ++--
 llvm/test/CodeGen/X86/isel-sqrt.ll            | 52 ++++--------
 llvm/test/CodeGen/X86/isel-x87.ll             | 28 +++----
 12 files changed, 148 insertions(+), 193 deletions(-)

diff --git a/llvm/lib/CodeGen/LowLevelTypeUtils.cpp b/llvm/lib/CodeGen/LowLevelTypeUtils.cpp
index 6ef6f641add8a..85bb2401975d7 100644
--- a/llvm/lib/CodeGen/LowLevelTypeUtils.cpp
+++ b/llvm/lib/CodeGen/LowLevelTypeUtils.cpp
@@ -130,6 +130,9 @@ const llvm::fltSemantics &llvm::getFltSemanticForLLT(LLT Ty) {
       return APFloat::IEEEsingle();
     case 64:
       return APFloat::IEEEdouble();
+    case 80:
+      // Not an IEEE format, but the only 80-bit float there is.
+      return APFloat::x87DoubleExtended();
     case 128:
       return APFloat::IEEEquad();
     }
diff --git a/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp b/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp
index 072fa5f2ef525..7769f7d06ed83 100644
--- a/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp
+++ b/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp
@@ -116,6 +116,7 @@ class X86InstructionSelector : public InstructionSelector {
                           const TargetRegisterClass *DstRC,
                           const Register SrcReg,
                           const TargetRegisterClass *SrcRC) const;
+  bool selectX87FPExt(MachineInstr &I, MachineRegisterInfo &MRI) const;
   bool materializeFP(MachineInstr &I, MachineRegisterInfo &MRI,
                      MachineFunction &MF) const;
   bool selectImplicitDefOrPHI(MachineInstr &I, MachineRegisterInfo &MRI) const;
@@ -460,6 +461,8 @@ bool X86InstructionSelector::select(MachineInstr &I) {
     return selectZext(I, MRI, MF);
   case TargetOpcode::G_ANYEXT:
     return selectAnyext(I, MRI, MF);
+  case TargetOpcode::G_FPEXT:
+    return selectX87FPExt(I, MRI);
   case TargetOpcode::G_ICMP:
     return selectCmp(I, MRI, MF);
   case TargetOpcode::G_FCMP:
@@ -859,6 +862,25 @@ bool X86InstructionSelector::selectTurnIntoCOPY(
   return true;
 }
 
+bool X86InstructionSelector::selectX87FPExt(MachineInstr &I,
+                                            MachineRegisterInfo &MRI) const {
+  assert(I.getOpcode() == TargetOpcode::G_FPEXT && "unexpected instruction");
+
+  const Register DstReg = I.getOperand(0).getReg();
+  const Register SrcReg = I.getOperand(1).getReg();
+  const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI);
+  const RegisterBank &SrcRB = *RBI.getRegBank(SrcReg, MRI, TRI);
+
+  // Only the x87 stack, where the register is 80 bits wide whatever type it
+  // holds and widening is therefore a plain copy.
+  if (DstRB.getID() != X86::PSRRegBankID || SrcRB.getID() != X86::PSRRegBankID)
+    return false;
+
+  return selectTurnIntoCOPY(I, MRI, DstReg,
+                            getRegClass(MRI.getType(DstReg), DstRB), SrcReg,
+                            getRegClass(MRI.getType(SrcReg), SrcRB));
+}
+
 bool X86InstructionSelector::selectTruncOrPtrToInt(MachineInstr &I,
                                                    MachineRegisterInfo &MRI,
                                                    MachineFunction &MF) const {
diff --git a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
index 3e46fd5fb46ce..c1ed80c3ddec2 100644
--- a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
+++ b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
@@ -80,6 +80,8 @@ X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI,
   const LLT v16s32 = LLT::fixed_vector(16, 32);
   const LLT v8s64 = LLT::fixed_vector(8, 64);
 
+  bool X87S32 = isScalarFPTypeOnX87Stack(32);
+  bool X87S64 = isScalarFPTypeOnX87Stack(64);
   bool RoundX87S32 = needsX87RoundToType(32);
   bool RoundX87S64 = needsX87RoundToType(64);
   auto NeedsX87RoundToType = [=](const LegalityQuery &Query) {
@@ -476,6 +478,9 @@ X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI,
       .legalFor(HasSSE2, {{s64, s32}})
       .legalFor(HasAVX, {{v4s64, v4s32}})
       .legalFor(HasAVX512, {{v8s64, v8s32}})
+      .legalFor(X87S32 && X87S64, {{s64, s32}})
+      .legalFor(X87S32, {{s80, s32}})
+      .legalFor(X87S64, {{s80, s64}})
       .lowerFor(UseX87, {{s64, s32}, {s80, s32}, {s80, s64}})
       .libcall();
 
@@ -652,6 +657,20 @@ bool X86LegalizerInfo::needsX87RoundToType(unsigned SizeInBits) const {
   }
 }
 
+bool X86LegalizerInfo::isScalarFPTypeOnX87Stack(unsigned SizeInBits) const {
+  const X86TargetLowering &TLI = *Subtarget.getTargetLowering();
+  switch (SizeInBits) {
+  case 32:
+    return TLI.isScalarFPTypeOnX87Stack(MVT::f32);
+  case 64:
+    return TLI.isScalarFPTypeOnX87Stack(MVT::f64);
+  case 80:
+    return TLI.isScalarFPTypeOnX87Stack(MVT::f80);
+  default:
+    return false;
+  }
+}
+
 bool X86LegalizerInfo::legalizeCustom(LegalizerHelper &Helper, MachineInstr &MI,
                                       LostDebugLocObserver &LocObserver) const {
   MachineIRBuilder &MIRBuilder = Helper.MIRBuilder;
diff --git a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.h b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.h
index acacd7b073ea6..a9df7d04de482 100644
--- a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.h
+++ b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.h
@@ -41,6 +41,10 @@ class X86LegalizerInfo : public LegalizerInfo {
   /// its own type through memory.
   bool needsX87RoundToType(unsigned SizeInBits) const;
 
+  /// Whether a scalar FP value that is \p SizeInBits wide is computed on the
+  /// x87 stack.
+  bool isScalarFPTypeOnX87Stack(unsigned SizeInBits) const;
+
   bool legalizeBuildVector(MachineInstr &MI, MachineRegisterInfo &MRI,
                            LegalizerHelper &Helper) const;
 
diff --git a/llvm/test/CodeGen/X86/GlobalISel/regbankselect-x87.ll b/llvm/test/CodeGen/X86/GlobalISel/regbankselect-x87.ll
index 0780d690d5f6d..8d7ca164469c7 100644
--- a/llvm/test/CodeGen/X86/GlobalISel/regbankselect-x87.ll
+++ b/llvm/test/CodeGen/X86/GlobalISel/regbankselect-x87.ll
@@ -166,25 +166,21 @@ define void @f5(ptr %a, ptr %b) {
   ; X86-NEXT:   [[C:%[0-9]+]]:gpr(s32) = G_CONSTANT i32 4
   ; X86-NEXT:   [[PTR_ADD:%[0-9]+]]:gpr(p0) = nuw inbounds G_PTR_ADD [[LOAD]], [[C]](s32)
   ; X86-NEXT:   [[LOAD3:%[0-9]+]]:gpr(s32) = G_LOAD [[PTR_ADD]](p0) :: (load (s32) from %ir.a + 4, basealign 8)
+  ; X86-NEXT:   [[MV:%[0-9]+]]:gpr(s64) = G_MERGE_VALUES [[LOAD2]](s32), [[LOAD3]](s32)
   ; X86-NEXT:   [[LOAD4:%[0-9]+]]:gpr(s32) = G_LOAD [[LOAD1]](p0) :: (load (s32) from %ir.b, align 8)
   ; X86-NEXT:   [[PTR_ADD1:%[0-9]+]]:gpr(p0) = nuw inbounds G_PTR_ADD [[LOAD1]], [[C]](s32)
   ; X86-NEXT:   [[LOAD5:%[0-9]+]]:gpr(s32) = G_LOAD [[PTR_ADD1]](p0) :: (load (s32) from %ir.b + 4, basealign 8)
-  ; X86-NEXT:   [[FRAME_INDEX2:%[0-9]+]]:gpr(p0) = G_FRAME_INDEX %stack.2
-  ; X86-NEXT:   G_STORE [[LOAD2]](s32), [[FRAME_INDEX2]](p0) :: (store (s32) into %stack.2, align 8)
+  ; X86-NEXT:   [[MV1:%[0-9]+]]:gpr(s64) = G_MERGE_VALUES [[LOAD4]](s32), [[LOAD5]](s32)
+  ; X86-NEXT:   [[COPY:%[0-9]+]]:psr(s64) = COPY [[MV]](s64)
+  ; X86-NEXT:   [[FPEXT:%[0-9]+]]:psr(s80) = G_FPEXT [[COPY]](s64)
+  ; X86-NEXT:   [[COPY1:%[0-9]+]]:psr(s64) = COPY [[MV1]](s64)
+  ; X86-NEXT:   [[FPEXT1:%[0-9]+]]:psr(s80) = G_FPEXT [[COPY1]](s64)
+  ; X86-NEXT:   [[FADD:%[0-9]+]]:psr(s80) = G_FADD [[FPEXT]], [[FPEXT1]]
+  ; X86-NEXT:   [[FRAME_INDEX2:%[0-9]+]]:gpr(p0) = G_FRAME_INDEX %stack.0
+  ; X86-NEXT:   G_FPTRUNCSTORE [[FADD]](s80), [[FRAME_INDEX2]](p0) :: (store (s64) into %stack.0)
+  ; X86-NEXT:   [[LOAD6:%[0-9]+]]:gpr(s32) = G_LOAD [[FRAME_INDEX2]](p0) :: (load (s32) from %stack.0, align 8)
   ; X86-NEXT:   [[PTR_ADD2:%[0-9]+]]:gpr(p0) = nuw inbounds G_PTR_ADD [[FRAME_INDEX2]], [[C]](s32)
-  ; X86-NEXT:   G_STORE [[LOAD3]](s32), [[PTR_ADD2]](p0) :: (store (s32) into %stack.2 + 4, basealign 8)
-  ; X86-NEXT:   [[FPEXTLOAD:%[0-9]+]]:psr(s80) = G_FPEXTLOAD [[FRAME_INDEX2]](p0) :: (load (s64) from %stack.2)
-  ; X86-NEXT:   [[FRAME_INDEX3:%[0-9]+]]:gpr(p0) = G_FRAME_INDEX %stack.1
-  ; X86-NEXT:   G_STORE [[LOAD4]](s32), [[FRAME_INDEX3]](p0) :: (store (s32) into %stack.1, align 8)
-  ; X86-NEXT:   [[PTR_ADD3:%[0-9]+]]:gpr(p0) = nuw inbounds G_PTR_ADD [[FRAME_INDEX3]], [[C]](s32)
-  ; X86-NEXT:   G_STORE [[LOAD5]](s32), [[PTR_ADD3]](p0) :: (store (s32) into %stack.1 + 4, basealign 8)
-  ; X86-NEXT:   [[FPEXTLOAD1:%[0-9]+]]:psr(s80) = G_FPEXTLOAD [[FRAME_INDEX3]](p0) :: (load (s64) from %stack.1)
-  ; X86-NEXT:   [[FADD:%[0-9]+]]:psr(s80) = G_FADD [[FPEXTLOAD]], [[FPEXTLOAD1]]
-  ; X86-NEXT:   [[FRAME_INDEX4:%[0-9]+]]:gpr(p0) = G_FRAME_INDEX %stack.0
-  ; X86-NEXT:   G_FPTRUNCSTORE [[FADD]](s80), [[FRAME_INDEX4]](p0) :: (store (s64) into %stack.0)
-  ; X86-NEXT:   [[LOAD6:%[0-9]+]]:gpr(s32) = G_LOAD [[FRAME_INDEX4]](p0) :: (load (s32) from %stack.0, align 8)
-  ; X86-NEXT:   [[PTR_ADD4:%[0-9]+]]:gpr(p0) = nuw inbounds G_PTR_ADD [[FRAME_INDEX4]], [[C]](s32)
-  ; X86-NEXT:   [[LOAD7:%[0-9]+]]:gpr(s32) = G_LOAD [[PTR_ADD4]](p0) :: (load (s32) from %stack.0 + 4, basealign 8)
+  ; X86-NEXT:   [[LOAD7:%[0-9]+]]:gpr(s32) = G_LOAD [[PTR_ADD2]](p0) :: (load (s32) from %stack.0 + 4, basealign 8)
   ; X86-NEXT:   G_STORE [[LOAD6]](s32), [[LOAD]](p0) :: (store (s32) into %ir.a, align 8)
   ; X86-NEXT:   G_STORE [[LOAD7]](s32), [[PTR_ADD]](p0) :: (store (s32) into %ir.a + 4, basealign 8)
   ; X86-NEXT:   RET 0
@@ -195,18 +191,14 @@ define void @f5(ptr %a, ptr %b) {
   ; X64-NEXT: {{  $}}
   ; X64-NEXT:   [[COPY:%[0-9]+]]:gpr(p0) = COPY $rdi
   ; X64-NEXT:   [[COPY1:%[0-9]+]]:gpr(p0) = COPY $rsi
-  ; X64-NEXT:   [[LOAD:%[0-9]+]]:gpr(s64) = G_LOAD [[COPY]](p0) :: (load (s64) from %ir.a)
-  ; X64-NEXT:   [[LOAD1:%[0-9]+]]:gpr(s64) = G_LOAD [[COPY1]](p0) :: (load (s64) from %ir.b)
-  ; X64-NEXT:   [[FRAME_INDEX:%[0-9]+]]:gpr(p0) = G_FRAME_INDEX %stack.2
-  ; X64-NEXT:   G_STORE [[LOAD]](s64), [[FRAME_INDEX]](p0) :: (store (s64) into %stack.2)
-  ; X64-NEXT:   [[FPEXTLOAD:%[0-9]+]]:psr(s80) = G_FPEXTLOAD [[FRAME_INDEX]](p0) :: (load (s64) from %stack.2)
-  ; X64-NEXT:   [[FRAME_INDEX1:%[0-9]+]]:gpr(p0) = G_FRAME_INDEX %stack.1
-  ; X64-NEXT:   G_STORE [[LOAD1]](s64), [[FRAME_INDEX1]](p0) :: (store (s64) into %stack.1)
-  ; X64-NEXT:   [[FPEXTLOAD1:%[0-9]+]]:psr(s80) = G_FPEXTLOAD [[FRAME_INDEX1]](p0) :: (load (s64) from %stack.1)
-  ; X64-NEXT:   [[FADD:%[0-9]+]]:psr(s80) = G_FADD [[FPEXTLOAD]], [[FPEXTLOAD1]]
-  ; X64-NEXT:   [[FRAME_INDEX2:%[0-9]+]]:gpr(p0) = G_FRAME_INDEX %stack.0
-  ; X64-NEXT:   G_FPTRUNCSTORE [[FADD]](s80), [[FRAME_INDEX2]](p0) :: (store (s64) into %stack.0)
-  ; X64-NEXT:   [[LOAD2:%[0-9]+]]:gpr(s64) = G_LOAD [[FRAME_INDEX2]](p0) :: (load (s64) from %stack.0)
+  ; X64-NEXT:   [[LOAD:%[0-9]+]]:psr(s64) = G_LOAD [[COPY]](p0) :: (load (s64) from %ir.a)
+  ; X64-NEXT:   [[LOAD1:%[0-9]+]]:psr(s64) = G_LOAD [[COPY1]](p0) :: (load (s64) from %ir.b)
+  ; X64-NEXT:   [[FPEXT:%[0-9]+]]:psr(s80) = G_FPEXT [[LOAD]](s64)
+  ; X64-NEXT:   [[FPEXT1:%[0-9]+]]:psr(s80) = G_FPEXT [[LOAD1]](s64)
+  ; X64-NEXT:   [[FADD:%[0-9]+]]:psr(s80) = G_FADD [[FPEXT]], [[FPEXT1]]
+  ; X64-NEXT:   [[FRAME_INDEX:%[0-9]+]]:gpr(p0) = G_FRAME_INDEX %stack.0
+  ; X64-NEXT:   G_FPTRUNCSTORE [[FADD]](s80), [[FRAME_INDEX]](p0) :: (store (s64) into %stack.0)
+  ; X64-NEXT:   [[LOAD2:%[0-9]+]]:gpr(s64) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s64) from %stack.0)
   ; X64-NEXT:   G_STORE [[LOAD2]](s64), [[COPY]](p0) :: (store (s64) into %ir.a)
   ; X64-NEXT:   RET 0
   %load1 = load double, ptr %a, align 8
@@ -223,18 +215,13 @@ define void @f6(ptr %0, ptr %1) {
   ; X86-NEXT:   [[LOAD:%[0-9]+]]:gpr(p0) = G_LOAD [[FRAME_INDEX]](p0) :: (invariant load (p0) from %fixed-stack.1)
   ; X86-NEXT:   [[FRAME_INDEX1:%[0-9]+]]:gpr(p0) = G_FRAME_INDEX %fixed-stack.0
   ; X86-NEXT:   [[LOAD1:%[0-9]+]]:gpr(p0) = G_LOAD [[FRAME_INDEX1]](p0) :: (invariant load (p0) from %fixed-stack.0)
-  ; X86-NEXT:   [[C:%[0-9]+]]:psr(s32) = G_FCONSTANT float 2.000000e+01
-  ; X86-NEXT:   [[LOAD2:%[0-9]+]]:gpr(s32) = G_LOAD [[LOAD]](p0) :: (load (s32) from %ir.0)
-  ; X86-NEXT:   [[FRAME_INDEX2:%[0-9]+]]:gpr(p0) = G_FRAME_INDEX %stack.2
-  ; X86-NEXT:   G_STORE [[LOAD2]](s32), [[FRAME_INDEX2]](p0) :: (store (s32) into %stack.2)
-  ; X86-NEXT:   [[FPEXTLOAD:%[0-9]+]]:psr(s80) = G_FPEXTLOAD [[FRAME_INDEX2]](p0) :: (load (s32) from %stack.2)
-  ; X86-NEXT:   [[FRAME_INDEX3:%[0-9]+]]:gpr(p0) = G_FRAME_INDEX %stack.1
-  ; X86-NEXT:   G_STORE [[C]](s32), [[FRAME_INDEX3]](p0) :: (store (s32) into %stack.1)
-  ; X86-NEXT:   [[FPEXTLOAD1:%[0-9]+]]:psr(s80) = G_FPEXTLOAD [[FRAME_INDEX3]](p0) :: (load (s32) from %stack.1)
-  ; X86-NEXT:   [[FADD:%[0-9]+]]:psr(s80) = G_FADD [[FPEXTLOAD]], [[FPEXTLOAD1]]
-  ; X86-NEXT:   [[FRAME_INDEX4:%[0-9]+]]:gpr(p0) = G_FRAME_INDEX %stack.0
-  ; X86-NEXT:   G_FPTRUNCSTORE [[FADD]](s80), [[FRAME_INDEX4]](p0) :: (store (s32) into %stack.0)
-  ; X86-NEXT:   [[LOAD3:%[0-9]+]]:gpr(s32) = G_LOAD [[FRAME_INDEX4]](p0) :: (load (s32) from %stack.0)
+  ; X86-NEXT:   [[LOAD2:%[0-9]+]]:psr(s32) = G_LOAD [[LOAD]](p0) :: (load (s32) from %ir.0)
+  ; X86-NEXT:   [[FPEXT:%[0-9]+]]:psr(s80) = G_FPEXT [[LOAD2]](s32)
+  ; X86-NEXT:   [[C:%[0-9]+]]:psr(s80) = G_FCONSTANT x86_fp80 2.000000e+01
+  ; X86-NEXT:   [[FADD:%[0-9]+]]:psr(s80) = G_FADD [[FPEXT]], [[C]]
+  ; X86-NEXT:   [[FRAME_INDEX2:%[0-9]+]]:gpr(p0) = G_FRAME_INDEX %stack.0
+  ; X86-NEXT:   G_FPTRUNCSTORE [[FADD]](s80), [[FRAME_INDEX2]](p0) :: (store (s32) into %stack.0)
+  ; X86-NEXT:   [[LOAD3:%[0-9]+]]:gpr(s32) = G_LOAD [[FRAME_INDEX2]](p0) :: (load (s32) from %stack.0)
   ; X86-NEXT:   G_STORE [[LOAD3]](s32), [[LOAD1]](p0) :: (store (s32) into %ir.1)
   ; X86-NEXT:   RET 0
   ;
@@ -244,18 +231,13 @@ define void @f6(ptr %0, ptr %1) {
   ; X64-NEXT: {{  $}}
   ; X64-NEXT:   [[COPY:%[0-9]+]]:gpr(p0) = COPY $rdi
   ; X64-NEXT:   [[COPY1:%[0-9]+]]:gpr(p0) = COPY $rsi
-  ; X64-NEXT:   [[C:%[0-9]+]]:psr(s32) = G_FCONSTANT float 2.000000e+01
-  ; X64-NEXT:   [[LOAD:%[0-9]+]]:gpr(s32) = G_LOAD [[COPY]](p0) :: (load (s32) from %ir.0)
-  ; X64-NEXT:   [[FRAME_INDEX:%[0-9]+]]:gpr(p0) = G_FRAME_INDEX %stack.2
-  ; X64-NEXT:   G_STORE [[LOAD]](s32), [[FRAME_INDEX]](p0) :: (store (s32) into %stack.2)
-  ; X64-NEXT:   [[FPEXTLOAD:%[0-9]+]]:psr(s80) = G_FPEXTLOAD [[FRAME_INDEX]](p0) :: (load (s32) from %stack.2)
-  ; X64-NEXT:   [[FRAME_INDEX1:%[0-9]+]]:gpr(p0) = G_FRAME_INDEX %stack.1
-  ; X64-NEXT:   G_STORE [[C]](s32), [[FRAME_INDEX1]](p0) :: (store (s32) into %stack.1)
-  ; X64-NEXT:   [[FPEXTLOAD1:%[0-9]+]]:psr(s80) = G_FPEXTLOAD [[FRAME_INDEX1]](p0) :: (load (s32) from %stack.1)
-  ; X64-NEXT:   [[FADD:%[0-9]+]]:psr(s80) = G_FADD [[FPEXTLOAD]], [[FPEXTLOAD1]]
-  ; X64-NEXT:   [[FRAME_INDEX2:%[0-9]+]]:gpr(p0) = G_FRAME_INDEX %stack.0
-  ; X64-NEXT:   G_FPTRUNCSTORE [[FADD]](s80), [[FRAME_INDEX2]](p0) :: (store (s32) into %stack.0)
-  ; X64-NEXT:   [[LOAD1:%[0-9]+]]:gpr(s32) = G_LOAD [[FRAME_INDEX2]](p0) :: (load (s32) from %stack.0)
+  ; X64-NEXT:   [[LOAD:%[0-9]+]]:psr(s32) = G_LOAD [[COPY]](p0) :: (load (s32) from %ir.0)
+  ; X64-NEXT:   [[FPEXT:%[0-9]+]]:psr(s80) = G_FPEXT [[LOAD]](s32)
+  ; X64-NEXT:   [[C:%[0-9]+]]:psr(s80) = G_FCONSTANT x86_fp80 2.000000e+01
+  ; X64-NEXT:   [[FADD:%[0-9]+]]:psr(s80) = G_FADD [[FPEXT]], [[C]]
+  ; X64-NEXT:   [[FRAME_INDEX:%[0-9]+]]:gpr(p0) = G_FRAME_INDEX %stack.0
+  ; X64-NEXT:   G_FPTRUNCSTORE [[FADD]](s80), [[FRAME_INDEX]](p0) :: (store (s32) into %stack.0)
+  ; X64-NEXT:   [[LOAD1:%[0-9]+]]:gpr(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s32) from %stack.0)
   ; X64-NEXT:   G_STORE [[LOAD1]](s32), [[COPY1]](p0) :: (store (s32) into %ir.1)
   ; X64-NEXT:   RET 0
   %load1 = load float, ptr %0
diff --git a/llvm/test/CodeGen/X86/isel-fadd.ll b/llvm/test/CodeGen/X86/isel-fadd.ll
index 8b79e4bc488e6..0164521279403 100644
--- a/llvm/test/CodeGen/X86/isel-fadd.ll
+++ b/llvm/test/CodeGen/X86/isel-fadd.ll
@@ -40,17 +40,14 @@ define float @test_fadd_f32(float %arg1, float %arg2) {
 ;
 ; GISEL-X86-LABEL: test_fadd_f32:
 ; GISEL-X86:       # %bb.0:
-; GISEL-X86-NEXT:    subl $12, %esp
-; GISEL-X86-NEXT:    .cfi_def_cfa_offset 16
-; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; GISEL-X86-NEXT:    movl %eax, (%esp)
-; GISEL-X86-NEXT:    flds (%esp)
-; GISEL-X86-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
-; GISEL-X86-NEXT:    fadds {{[0-9]+}}(%esp)
-; GISEL-X86-NEXT:    fstps {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    pushl %eax
+; GISEL-X86-NEXT:    .cfi_def_cfa_offset 8
+; GISEL-X86-NEXT:    flds {{[0-9]+}}(%esp)
 ; GISEL-X86-NEXT:    flds {{[0-9]+}}(%esp)
-; GISEL-X86-NEXT:    addl $12, %esp
+; GISEL-X86-NEXT:    faddp %st, %st(1)
+; GISEL-X86-NEXT:    fstps (%esp)
+; GISEL-X86-NEXT:    flds (%esp)
+; GISEL-X86-NEXT:    popl %eax
 ; GISEL-X86-NEXT:    .cfi_def_cfa_offset 4
 ; GISEL-X86-NEXT:    retl
 ;
diff --git a/llvm/test/CodeGen/X86/isel-fdiv.ll b/llvm/test/CodeGen/X86/isel-fdiv.ll
index b88f6a678ab55..92a2c26ca6ea2 100644
--- a/llvm/test/CodeGen/X86/isel-fdiv.ll
+++ b/llvm/test/CodeGen/X86/isel-fdiv.ll
@@ -40,17 +40,14 @@ define float @test_fdiv_f32(float %arg1, float %arg2) {
 ;
 ; GISEL-X86-LABEL: test_fdiv_f32:
 ; GISEL-X86:       # %bb.0:
-; GISEL-X86-NEXT:    subl $12, %esp
-; GISEL-X86-NEXT:    .cfi_def_cfa_offset 16
-; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; GISEL-X86-NEXT:    movl %eax, (%esp)
-; GISEL-X86-NEXT:    flds (%esp)
-; GISEL-X86-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
-; GISEL-X86-NEXT:    fdivs {{[0-9]+}}(%esp)
-; GISEL-X86-NEXT:    fstps {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    pushl %eax
+; GISEL-X86-NEXT:    .cfi_def_cfa_offset 8
+; GISEL-X86-NEXT:    flds {{[0-9]+}}(%esp)
 ; GISEL-X86-NEXT:    flds {{[0-9]+}}(%esp)
-; GISEL-X86-NEXT:    addl $12, %esp
+; GISEL-X86-NEXT:    fdivrp %st, %st(1)
+; GISEL-X86-NEXT:    fstps (%esp)
+; GISEL-X86-NEXT:    flds (%esp)
+; GISEL-X86-NEXT:    popl %eax
 ; GISEL-X86-NEXT:    .cfi_def_cfa_offset 4
 ; GISEL-X86-NEXT:    retl
 ;
diff --git a/llvm/test/CodeGen/X86/isel-fmul.ll b/llvm/test/CodeGen/X86/isel-fmul.ll
index 60d38f3ca4140..85fc729a4b142 100644
--- a/llvm/test/CodeGen/X86/isel-fmul.ll
+++ b/llvm/test/CodeGen/X86/isel-fmul.ll
@@ -40,17 +40,14 @@ define float @test_fmul_f32(float %arg1, float %arg2) {
 ;
 ; GISEL-X86-LABEL: test_fmul_f32:
 ; GISEL-X86:       # %bb.0:
-; GISEL-X86-NEXT:    subl $12, %esp
-; GISEL-X86-NEXT:    .cfi_def_cfa_offset 16
-; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; GISEL-X86-NEXT:    movl %eax, (%esp)
-; GISEL-X86-NEXT:    flds (%esp)
-; GISEL-X86-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
-; GISEL-X86-NEXT:    fmuls {{[0-9]+}}(%esp)
-; GISEL-X86-NEXT:    fstps {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    pushl %eax
+; GISEL-X86-NEXT:    .cfi_def_cfa_offset 8
+; GISEL-X86-NEXT:    flds {{[0-9]+}}(%esp)
 ; GISEL-X86-NEXT:    flds {{[0-9]+}}(%esp)
-; GISEL-X86-NEXT:    addl $12, %esp
+; GISEL-X86-NEXT:    fmulp %st, %st(1)
+; GISEL-X86-NEXT:    fstps (%esp)
+; GISEL-X86-NEXT:    flds (%esp)
+; GISEL-X86-NEXT:    popl %eax
 ; GISEL-X86-NEXT:    .cfi_def_cfa_offset 4
 ; GISEL-X86-NEXT:    retl
 ;
diff --git a/llvm/test/CodeGen/X86/isel-fptrunc-fpext.ll b/llvm/test/CodeGen/X86/isel-fptrunc-fpext.ll
index 7001f3ef7028d..2155735c11d06 100644
--- a/llvm/test/CodeGen/X86/isel-fptrunc-fpext.ll
+++ b/llvm/test/CodeGen/X86/isel-fptrunc-fpext.ll
@@ -15,10 +15,10 @@
 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx512f -fast-isel=0 -global-isel=1 -global-isel-abort=1 | FileCheck %s --check-prefixes AVX,GLOBAL-AVX
 
 define double @fpext_float_to_double(float %f) nounwind {
-; FASTSDAG-X86-LABEL: fpext_float_to_double:
-; FASTSDAG-X86:       # %bb.0:
-; FASTSDAG-X86-NEXT:    flds {{[0-9]+}}(%esp)
-; FASTSDAG-X86-NEXT:    retl
+; X86-LABEL: fpext_float_to_double:
+; X86:       # %bb.0:
+; X86-NEXT:    flds {{[0-9]+}}(%esp)
+; X86-NEXT:    retl
 ;
 ; SSE-LABEL: fpext_float_to_double:
 ; SSE:       # %bb.0:
@@ -29,24 +29,15 @@ define double @fpext_float_to_double(float %f) nounwind {
 ; AVX:       # %bb.0:
 ; AVX-NEXT:    vcvtss2sd %xmm0, %xmm0, %xmm0
 ; AVX-NEXT:    retq
-;
-; GLOBAL-X86-LABEL: fpext_float_to_double:
-; GLOBAL-X86:       # %bb.0:
-; GLOBAL-X86-NEXT:    pushl %eax
-; GLOBAL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; GLOBAL-X86-NEXT:    movl %eax, (%esp)
-; GLOBAL-X86-NEXT:    flds (%esp)
-; GLOBAL-X86-NEXT:    popl %eax
-; GLOBAL-X86-NEXT:    retl
   %1 = fpext float %f to double
   ret double %1
 }
 
 define x86_fp80 @fpext_float_to_x86_fp80(float %f) nounwind {
-; FASTSDAG-X86-LABEL: fpext_float_to_x86_fp80:
-; FASTSDAG-X86:       # %bb.0:
-; FASTSDAG-X86-NEXT:    flds {{[0-9]+}}(%esp)
-; FASTSDAG-X86-NEXT:    retl
+; X86-LABEL: fpext_float_to_x86_fp80:
+; X86:       # %bb.0:
+; X86-NEXT:    flds {{[0-9]+}}(%esp)
+; X86-NEXT:    retl
 ;
 ; FASTSDAG-SSE-LABEL: fpext_float_to_x86_fp80:
 ; FASTSDAG-SSE:       # %bb.0:
@@ -60,15 +51,6 @@ define x86_fp80 @fpext_float_to_x86_fp80(float %f) nounwind {
 ; FASTSDAG-AVX-NEXT:    flds -{{[0-9]+}}(%rsp)
 ; FASTSDAG-AVX-NEXT:    retq
 ;
-; GLOBAL-X86-LABEL: fpext_float_to_x86_fp80:
-; GLOBAL-X86:       # %bb.0:
-; GLOBAL-X86-NEXT:    pushl %eax
-; GLOBAL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; GLOBAL-X86-NEXT:    movl %eax, (%esp)
-; GLOBAL-X86-NEXT:    flds (%esp)
-; GLOBAL-X86-NEXT:    popl %eax
-; GLOBAL-X86-NEXT:    retl
-;
 ; GLOBAL-SSE-LABEL: fpext_float_to_x86_fp80:
 ; GLOBAL-SSE:       # %bb.0:
 ; GLOBAL-SSE-NEXT:    movd %xmm0, %eax
@@ -87,10 +69,10 @@ define x86_fp80 @fpext_float_to_x86_fp80(float %f) nounwind {
 }
 
 define x86_fp80 @fpext_double_to_x86_fp80(double %d) nounwind {
-; FASTSDAG-X86-LABEL: fpext_double_to_x86_fp80:
-; FASTSDAG-X86:       # %bb.0:
-; FASTSDAG-X86-NEXT:    fldl {{[0-9]+}}(%esp)
-; FASTSDAG-X86-NEXT:    retl
+; X86-LABEL: fpext_double_to_x86_fp80:
+; X86:       # %bb.0:
+; X86-NEXT:    fldl {{[0-9]+}}(%esp)
+; X86-NEXT:    retl
 ;
 ; FASTSDAG-SSE-LABEL: fpext_double_to_x86_fp80:
 ; FASTSDAG-SSE:       # %bb.0:
@@ -104,23 +86,6 @@ define x86_fp80 @fpext_double_to_x86_fp80(double %d) nounwind {
 ; FASTSDAG-AVX-NEXT:    fldl -{{[0-9]+}}(%rsp)
 ; FASTSDAG-AVX-NEXT:    retq
 ;
-; GLOBAL-X86-LABEL: fpext_double_to_x86_fp80:
-; GLOBAL-X86:       # %bb.0:
-; GLOBAL-X86-NEXT:    pushl %ebp
-; GLOBAL-X86-NEXT:    movl %esp, %ebp
-; GLOBAL-X86-NEXT:    andl $-8, %esp
-; GLOBAL-X86-NEXT:    subl $8, %esp
-; GLOBAL-X86-NEXT:    leal 8(%ebp), %eax
-; GLOBAL-X86-NEXT:    movl 8(%ebp), %ecx
-; GLOBAL-X86-NEXT:    movl 4(%eax), %eax
-; GLOBAL-X86-NEXT:    movl %esp, %edx
-; GLOBAL-X86-NEXT:    movl %ecx, (%esp)
-; GLOBAL-X86-NEXT:    movl %eax, 4(%edx)
-; GLOBAL-X86-NEXT:    fldl (%esp)
-; GLOBAL-X86-NEXT:    movl %ebp, %esp
-; GLOBAL-X86-NEXT:    popl %ebp
-; GLOBAL-X86-NEXT:    retl
-;
 ; GLOBAL-SSE-LABEL: fpext_double_to_x86_fp80:
 ; GLOBAL-SSE:       # %bb.0:
 ; GLOBAL-SSE-NEXT:    movq %xmm0, %rax
@@ -250,6 +215,8 @@ define double @fptrunc_x86_fp80_to_double(x86_fp80 %x) nounwind {
 ; FAST-AVX: {{.*}}
 ; FAST-SSE: {{.*}}
 ; FAST-X86: {{.*}}
+; FASTSDAG-X86: {{.*}}
+; GLOBAL-X86: {{.*}}
 ; SDAG-AVX: {{.*}}
 ; SDAG-SSE: {{.*}}
 ; SDAG-X86: {{.*}}
diff --git a/llvm/test/CodeGen/X86/isel-fsub.ll b/llvm/test/CodeGen/X86/isel-fsub.ll
index 63c949713d3a2..acff7b7739ed5 100644
--- a/llvm/test/CodeGen/X86/isel-fsub.ll
+++ b/llvm/test/CodeGen/X86/isel-fsub.ll
@@ -40,17 +40,14 @@ define float @test_fsub_f32(float %arg1, float %arg2) {
 ;
 ; GISEL-X86-LABEL: test_fsub_f32:
 ; GISEL-X86:       # %bb.0:
-; GISEL-X86-NEXT:    subl $12, %esp
-; GISEL-X86-NEXT:    .cfi_def_cfa_offset 16
-; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; GISEL-X86-NEXT:    movl %eax, (%esp)
-; GISEL-X86-NEXT:    flds (%esp)
-; GISEL-X86-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
-; GISEL-X86-NEXT:    fsubs {{[0-9]+}}(%esp)
-; GISEL-X86-NEXT:    fstps {{[0-9]+}}(%esp)
+; GISEL-X86-NEXT:    pushl %eax
+; GISEL-X86-NEXT:    .cfi_def_cfa_offset 8
+; GISEL-X86-NEXT:    flds {{[0-9]+}}(%esp)
 ; GISEL-X86-NEXT:    flds {{[0-9]+}}(%esp)
-; GISEL-X86-NEXT:    addl $12, %esp
+; GISEL-X86-NEXT:    fsubrp %st, %st(1)
+; GISEL-X86-NEXT:    fstps (%esp)
+; GISEL-X86-NEXT:    flds (%esp)
+; GISEL-X86-NEXT:    popl %eax
 ; GISEL-X86-NEXT:    .cfi_def_cfa_offset 4
 ; GISEL-X86-NEXT:    retl
 ;
diff --git a/llvm/test/CodeGen/X86/isel-sqrt.ll b/llvm/test/CodeGen/X86/isel-sqrt.ll
index 73aa958807040..84726d2bdc89d 100644
--- a/llvm/test/CodeGen/X86/isel-sqrt.ll
+++ b/llvm/test/CodeGen/X86/isel-sqrt.ll
@@ -21,43 +21,17 @@ define float @test_sqrt_f32(float %a) {
 ; AVX-NEXT:    vsqrtss %xmm0, %xmm0, %xmm0
 ; AVX-NEXT:    retq
 ;
-; SDAG-X86-LABEL: test_sqrt_f32:
-; SDAG-X86:       # %bb.0:
-; SDAG-X86-NEXT:    pushl %eax
-; SDAG-X86-NEXT:    .cfi_def_cfa_offset 8
-; SDAG-X86-NEXT:    flds {{[0-9]+}}(%esp)
-; SDAG-X86-NEXT:    fsqrt
-; SDAG-X86-NEXT:    fstps (%esp)
-; SDAG-X86-NEXT:    flds (%esp)
-; SDAG-X86-NEXT:    popl %eax
-; SDAG-X86-NEXT:    .cfi_def_cfa_offset 4
-; SDAG-X86-NEXT:    retl
-;
-; FASTISEL-X86-LABEL: test_sqrt_f32:
-; FASTISEL-X86:       # %bb.0:
-; FASTISEL-X86-NEXT:    pushl %eax
-; FASTISEL-X86-NEXT:    .cfi_def_cfa_offset 8
-; FASTISEL-X86-NEXT:    flds {{[0-9]+}}(%esp)
-; FASTISEL-X86-NEXT:    fsqrt
-; FASTISEL-X86-NEXT:    fstps (%esp)
-; FASTISEL-X86-NEXT:    flds (%esp)
-; FASTISEL-X86-NEXT:    popl %eax
-; FASTISEL-X86-NEXT:    .cfi_def_cfa_offset 4
-; FASTISEL-X86-NEXT:    retl
-;
-; GISEL-X86-LABEL: test_sqrt_f32:
-; GISEL-X86:       # %bb.0:
-; GISEL-X86-NEXT:    subl $8, %esp
-; GISEL-X86-NEXT:    .cfi_def_cfa_offset 12
-; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; GISEL-X86-NEXT:    movl %eax, (%esp)
-; GISEL-X86-NEXT:    flds (%esp)
-; GISEL-X86-NEXT:    fsqrt
-; GISEL-X86-NEXT:    fstps {{[0-9]+}}(%esp)
-; GISEL-X86-NEXT:    flds {{[0-9]+}}(%esp)
-; GISEL-X86-NEXT:    addl $8, %esp
-; GISEL-X86-NEXT:    .cfi_def_cfa_offset 4
-; GISEL-X86-NEXT:    retl
+; X86-LABEL: test_sqrt_f32:
+; X86:       # %bb.0:
+; X86-NEXT:    pushl %eax
+; X86-NEXT:    .cfi_def_cfa_offset 8
+; X86-NEXT:    flds {{[0-9]+}}(%esp)
+; X86-NEXT:    fsqrt
+; X86-NEXT:    fstps (%esp)
+; X86-NEXT:    flds (%esp)
+; X86-NEXT:    popl %eax
+; X86-NEXT:    .cfi_def_cfa_offset 4
+; X86-NEXT:    retl
   %res = call float @llvm.sqrt.f32(float %a)
   ret float %res
 }
@@ -107,3 +81,7 @@ define x86_fp80 @test_sqrt_f80(x86_fp80 %a) {
 }
 declare x86_fp80 @llvm.sqrt.f80(x86_fp80) nounwind readnone
 
+;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+; FASTISEL-X86: {{.*}}
+; GISEL-X86: {{.*}}
+; SDAG-X86: {{.*}}
diff --git a/llvm/test/CodeGen/X86/isel-x87.ll b/llvm/test/CodeGen/X86/isel-x87.ll
index 6fb48c8c4dce7..88bd0d3e9739b 100644
--- a/llvm/test/CodeGen/X86/isel-x87.ll
+++ b/llvm/test/CodeGen/X86/isel-x87.ll
@@ -183,20 +183,16 @@ define void @f3(ptr %a, ptr %b) nounwind {
 define void @f6(ptr %a, ptr %b) nounwind {
 ; GISEL_X86-LABEL: f6:
 ; GISEL_X86:       # %bb.0:
-; GISEL_X86-NEXT:    subl $12, %esp
+; GISEL_X86-NEXT:    pushl %eax
 ; GISEL_X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; GISEL_X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; GISEL_X86-NEXT:    flds {{\.?LCPI[0-9]+_[0-9]+}}
-; GISEL_X86-NEXT:    movl (%eax), %eax
-; GISEL_X86-NEXT:    movl %eax, (%esp)
-; GISEL_X86-NEXT:    flds (%esp)
-; GISEL_X86-NEXT:    fxch %st(1)
-; GISEL_X86-NEXT:    fstps {{[0-9]+}}(%esp)
-; GISEL_X86-NEXT:    fadds {{[0-9]+}}(%esp)
-; GISEL_X86-NEXT:    fstps {{[0-9]+}}(%esp)
-; GISEL_X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; GISEL_X86-NEXT:    flds (%eax)
+; GISEL_X86-NEXT:    fldt {{\.?LCPI[0-9]+_[0-9]+}}
+; GISEL_X86-NEXT:    faddp %st, %st(1)
+; GISEL_X86-NEXT:    fstps (%esp)
+; GISEL_X86-NEXT:    movl (%esp), %eax
 ; GISEL_X86-NEXT:    movl %eax, (%ecx)
-; GISEL_X86-NEXT:    addl $12, %esp
+; GISEL_X86-NEXT:    popl %eax
 ; GISEL_X86-NEXT:    retl
 ;
 ; SDAG_X86-LABEL: f6:
@@ -210,13 +206,9 @@ define void @f6(ptr %a, ptr %b) nounwind {
 ;
 ; GISEL_X64-LABEL: f6:
 ; GISEL_X64:       # %bb.0:
-; GISEL_X64-NEXT:    flds {{\.?LCPI[0-9]+_[0-9]+}}(%rip)
-; GISEL_X64-NEXT:    movl (%rdi), %eax
-; GISEL_X64-NEXT:    movl %eax, -{{[0-9]+}}(%rsp)
-; GISEL_X64-NEXT:    flds -{{[0-9]+}}(%rsp)
-; GISEL_X64-NEXT:    fxch %st(1)
-; GISEL_X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
-; GISEL_X64-NEXT:    fadds -{{[0-9]+}}(%rsp)
+; GISEL_X64-NEXT:    flds (%rdi)
+; GISEL_X64-NEXT:    fldt {{\.?LCPI[0-9]+_[0-9]+}}(%rip)
+; GISEL_X64-NEXT:    faddp %st, %st(1)
 ; GISEL_X64-NEXT:    fstps -{{[0-9]+}}(%rsp)
 ; GISEL_X64-NEXT:    movl -{{[0-9]+}}(%rsp), %eax
 ; GISEL_X64-NEXT:    movl %eax, (%rsi)

>From 3424df3b5f0296e77367d4cdd8fe2cdb8163cbc1 Mon Sep 17 00:00:00 2001
From: Dennis Duda <git at seri.tools>
Date: Sun, 9 Aug 2026 02:33:09 +0200
Subject: [PATCH 13/15] [clang][X86] Report `FLT_EVAL_METHOD=0` on x86 without
 SSE

Clang now follows its own user manual: Rounding after each f32/f64 x87 op.

`-ffp-eval-method=extended` now properly implements `FLT_EVAL_METHOD=2`: Rounding at assignments and casts, but keeping extended precision in intermediates.

Co-authored-by: Claude (Claude-Opus-5) <noreply at anthropic.com>
---
 clang/docs/ReleaseNotes.md                    | 10 +++++++
 clang/lib/Basic/Targets/X86.h                 | 10 +++----
 clang/test/CodeGen/X86/excess-precision-x87.c | 29 +++++++++++++++++++
 clang/test/CodeGen/X86/fp-eval-method.c       |  7 ++---
 clang/test/Preprocessor/flt_eval_macro.cpp    |  9 ++++--
 clang/test/Sema/x86-eval-method.c             |  6 ++--
 clang/test/Sema/x86_64-eval-method.c          |  4 +--
 7 files changed, 58 insertions(+), 17 deletions(-)
 create mode 100644 clang/test/CodeGen/X86/excess-precision-x87.c

diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 043a0ddae2a6c..d60610b5e9ef3 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -262,6 +262,9 @@ features cannot lower the translation-unit ABI level;
 ### Modified Compiler Flags
 
 - All options of the `-fzero-call-used-regs` compiler flag are now allowed on RISC-V.
+- `-ffp-eval-method=source` and `#pragma clang fp eval_method(source)` are now
+  accepted on x86 without SSE, where they used to be rejected because the
+  backend could not round x87 results to their type.
 
 ### Removed Compiler Flags
 
@@ -820,6 +823,13 @@ features cannot lower the translation-unit ABI level;
 
 ### Floating Point Support in Clang
 
+- Fixed x87 code keeping the extended precision of an intermediate result in a
+  `float` or `double` value, so that a value could compare unequal to itself
+  depending on whether the register allocator had spilled it. Every x87
+  `float`/`double` result is now rounded, just as is already is documented in
+  the manual. As a consequence, `__FLT_EVAL_METHOD__` is now `0` by default,
+  instead of `2`, on x86 without SSE.
+
 ### Fixed Point Support in Clang
 
 ### AST Matchers
diff --git a/clang/lib/Basic/Targets/X86.h b/clang/lib/Basic/Targets/X86.h
index 658730ae88186..56e9b16e5934f 100644
--- a/clang/lib/Basic/Targets/X86.h
+++ b/clang/lib/Basic/Targets/X86.h
@@ -183,13 +183,13 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo {
   }
 
   LangOptions::FPEvalMethodKind getFPEvalMethod() const override {
-    // X87 evaluates with 80 bits "long double" precision.
-    return SSELevel == NoSSE ? LangOptions::FPEvalMethodKind::FEM_Extended
-                             : LangOptions::FPEvalMethodKind::FEM_Source;
+    // X87 computes at 80 bits, but the backend rounds every f32/f64 result
+    // back to its own type, so intermediate results have the range and
+    // precision of their type just as they do with SSE.
+    return LangOptions::FPEvalMethodKind::FEM_Source;
   }
 
-  // EvalMethod `source` is not supported for targets with `NoSSE` feature.
-  bool supportSourceEvalMethod() const override { return SSELevel > NoSSE; }
+  bool supportSourceEvalMethod() const override { return true; }
 
   ArrayRef<const char *> getGCCRegNames() const override;
 
diff --git a/clang/test/CodeGen/X86/excess-precision-x87.c b/clang/test/CodeGen/X86/excess-precision-x87.c
new file mode 100644
index 0000000000000..2917dcef390f5
--- /dev/null
+++ b/clang/test/CodeGen/X86/excess-precision-x87.c
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -triple i386-unknown-linux-gnu -target-feature -sse \
+// RUN:   -O1 -emit-llvm -o - %s | FileCheck %s --check-prefix=SRC
+// RUN: %clang_cc1 -triple i386-unknown-linux-gnu -target-feature -sse \
+// RUN:   -ffp-eval-method=extended -O1 -emit-llvm -o - %s \
+// RUN:   | FileCheck %s --check-prefix=EXT
+
+// SRC-LABEL: define {{.*}}float @expr(
+// SRC: fmul float
+// SRC: fmul float
+// SRC: fadd float
+// SRC-NOT: x86_fp80
+//
+// EXT-LABEL: define {{.*}}float @expr(
+// EXT: fmul x86_fp80
+// EXT: fmul x86_fp80
+// EXT: fadd x86_fp80
+// EXT: fptrunc x86_fp80 {{.*}} to float
+float expr(float a, float b, float c, float d) {
+  return a * b + c * d;
+}
+
+// SRC-LABEL: define {{.*}}i32 @eval_method(
+// SRC: ret i32 0
+//
+// EXT-LABEL: define {{.*}}i32 @eval_method(
+// EXT: ret i32 2
+int eval_method(void) {
+  return __FLT_EVAL_METHOD__;
+}
diff --git a/clang/test/CodeGen/X86/fp-eval-method.c b/clang/test/CodeGen/X86/fp-eval-method.c
index c1d8f617400d5..2e275035b4d78 100644
--- a/clang/test/CodeGen/X86/fp-eval-method.c
+++ b/clang/test/CodeGen/X86/fp-eval-method.c
@@ -1,8 +1,8 @@
 // RUN: %clang_cc1 -triple i386-unknown-netbsd -emit-llvm -o - %s \
-// RUN: | FileCheck %s -check-prefixes=CHECK-EXT
+// RUN: | FileCheck %s
 
 // RUN: %clang_cc1 -triple i386--linux -emit-llvm -o - %s \
-// RUN: | FileCheck %s -check-prefixes=CHECK-EXT
+// RUN: | FileCheck %s
 
 float f(float x, float y) {
   // CHECK: define{{.*}} float @f
@@ -11,7 +11,6 @@ float f(float x, float y) {
 }
 
 int getEvalMethod(void) {
-  // CHECK: ret i32 1
-  // CHECK-EXT: ret i32 2
+  // CHECK: ret i32 0
   return __FLT_EVAL_METHOD__;
 }
diff --git a/clang/test/Preprocessor/flt_eval_macro.cpp b/clang/test/Preprocessor/flt_eval_macro.cpp
index fa5d6fcd820b1..44170ade83778 100644
--- a/clang/test/Preprocessor/flt_eval_macro.cpp
+++ b/clang/test/Preprocessor/flt_eval_macro.cpp
@@ -2,7 +2,11 @@
 // RUN:   | FileCheck %s -strict-whitespace
 
 // RUN: %clang_cc1 -E -dM -triple=x86_64-none-none -target-feature -sse \
-// RUN:   %s -o - | FileCheck %s -check-prefix=EXT -strict-whitespace
+// RUN:   %s -o - | FileCheck %s -strict-whitespace
+
+// RUN: %clang_cc1 -E -dM -triple=x86_64-none-none -target-feature -sse \
+// RUN:   -ffp-eval-method=extended %s -o - \
+// RUN:   | FileCheck %s -check-prefix=EXT -strict-whitespace
 
 // RUN: %clang_cc1 -E -dM -triple=arm64e-apple-ios -target-feature -sse \
 // RUN:   %s -o - | FileCheck %s  -strict-whitespace
@@ -23,8 +27,7 @@
 // RUN:   | FileCheck %s  -strict-whitespace
 
 // RUN: %clang_cc1 -E -dM -triple i386-pc-windows -target-cpu pentium4 \
-// RUN:   -target-feature -sse %s -o - | FileCheck -check-prefix=EXT %s \
-// RUN:   -strict-whitespace
+// RUN:   -target-feature -sse %s -o - | FileCheck %s -strict-whitespace
 
 #ifdef __FLT_EVAL_METHOD__
 #if __FLT_EVAL_METHOD__ == 3
diff --git a/clang/test/Sema/x86-eval-method.c b/clang/test/Sema/x86-eval-method.c
index e540a59528b6d..10b97336b0937 100644
--- a/clang/test/Sema/x86-eval-method.c
+++ b/clang/test/Sema/x86-eval-method.c
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -fexperimental-strict-floating-point \
 // RUN: -triple i386-pc-windows -target-cpu pentium4 -target-feature -sse \
-// RUN: -emit-llvm -ffp-eval-method=source  -o - -verify=warn %s
+// RUN: -emit-llvm -ffp-eval-method=source  -o - -verify=no-warn %s
 //
 // RUN: %clang_cc1 -fexperimental-strict-floating-point \
 // RUN: -triple i386-pc-windows -target-cpu pentium4 \
@@ -10,9 +10,9 @@
 
 float add1(float a, float b, float c) {
   return a + b + c;
-} // warn-warning{{setting the floating point evaluation method to `source` on a target without SSE is not supported}}
+}
 
 float add2(float a, float b, float c) {
 #pragma clang fp eval_method(source)
   return a + b + c;
-} // warn-warning{{setting the floating point evaluation method to `source` on a target without SSE is not supported}}
+}
diff --git a/clang/test/Sema/x86_64-eval-method.c b/clang/test/Sema/x86_64-eval-method.c
index fe4368a42ca12..52554795630ad 100644
--- a/clang/test/Sema/x86_64-eval-method.c
+++ b/clang/test/Sema/x86_64-eval-method.c
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -fexperimental-strict-floating-point \
 // RUN: -triple x86_64-linux-gnu -target-feature -sse -emit-llvm \
-// RUN: -o - -verify=warn %s
+// RUN: -o - -verify=no-warn %s
 //
 // RUN: %clang_cc1 -fexperimental-strict-floating-point \
 // RUN: -triple x86_64-linux-gnu -emit-llvm -o - -verify=no-warn %s
@@ -10,4 +10,4 @@
 float add2(float a, float b, float c) {
 #pragma clang fp eval_method(source)
   return a + b + c;
-} // warn-warning{{setting the floating point evaluation method to `source` on a target without SSE is not supported}}
+}

>From 703430edb95232f3a0757742c83a7a86fec76c90 Mon Sep 17 00:00:00 2001
From: Dennis Duda <git at seri.tools>
Date: Sun, 9 Aug 2026 02:01:26 +0200
Subject: [PATCH 14/15] [X86] Add an opt-out for x87 f32/f64 rounding

Allow going back to the previous behavior, equivalent to `-fexcess-precision=fast` in GNU.

The opt-out feature makes `sqrt.mir` legal again.

Co-authored-by: Claude (Claude-Opus-5) <noreply at anthropic.com>
---
 llvm/lib/Target/X86/X86.td                 |   8 +
 llvm/lib/Target/X86/X86ISelLowering.cpp    |  12 +-
 llvm/test/CodeGen/X86/GlobalISel/sqrt.mir  |   7 +-
 llvm/test/CodeGen/X86/x87-round-to-type.ll | 268 +++++++++++++++++++++
 4 files changed, 290 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/Target/X86/X86.td b/llvm/lib/Target/X86/X86.td
index 5786c659b0f98..68889a4a66226 100644
--- a/llvm/lib/Target/X86/X86.td
+++ b/llvm/lib/Target/X86/X86.td
@@ -44,6 +44,14 @@ def FeatureReserveEDI : SubtargetFeature<"reserve-edi", "ReservedRReg[X86::EDI]"
 def FeatureX87     : SubtargetFeature<"x87","HasX87", "true",
                                       "Enable X87 float instructions">;
 
+// Skips the store/load round-trip that rounds a result to its own type, so an
+// f32/f64 in a register no longer generally holds a value of its type.
+def FeatureX87ExcessPrecision
+    : SubtargetFeature<"x87-excess-precision", "AllowX87ExcessPrecision",
+                       "true",
+                       "Let X87 f32/f64 results keep the register's extended "
+                       "precision instead of rounding them to their type">;
+
 // Does not have intrinsics or ABI effects.
 def FeatureNOPL    : SubtargetFeature<"nopl", "HasNOPL", "true",
                                       "Enable NOPL instruction (generally pentium pro+)",
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 2bf38352a5155..4085790dd205e 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -77,6 +77,15 @@ static cl::opt<int> ExperimentalPrefInnermostLoopAlignment(
         "alignment set by x86-experimental-pref-loop-alignment."),
     cl::Hidden);
 
+static cl::opt<bool> X87RoundToType(
+    "x86-x87-round-to-type", cl::init(true),
+    cl::desc("Round the result of every X87 f32/f64 operation to its own type "
+             "instead of leaving it at the register's extended precision. "
+             "Costs a store/load round-trip per operation; turning this off "
+             "restores the historical, faster, incorrect behaviour. The "
+             "per-function spelling of that is +x87-excess-precision."),
+    cl::Hidden);
+
 static cl::opt<int> BrMergingBaseCostThresh(
     "x86-br-merging-base-cost", cl::init(2),
     cl::desc(
@@ -3739,7 +3748,8 @@ bool X86TargetLowering::isScalarFPTypeOnX87Stack(EVT VT) const {
 }
 
 bool X86TargetLowering::needsX87RoundToType(EVT VT) const {
-  return (VT == MVT::f32 || VT == MVT::f64) && isScalarFPTypeOnX87Stack(VT);
+  return X87RoundToType && !Subtarget.allowX87ExcessPrecision() &&
+         (VT == MVT::f32 || VT == MVT::f64) && isScalarFPTypeOnX87Stack(VT);
 }
 
 bool X86TargetLowering::isLoadBitCastBeneficial(EVT LoadVT, EVT BitcastVT,
diff --git a/llvm/test/CodeGen/X86/GlobalISel/sqrt.mir b/llvm/test/CodeGen/X86/GlobalISel/sqrt.mir
index bdc80ad43a8a5..4d714f4b09213 100644
--- a/llvm/test/CodeGen/X86/GlobalISel/sqrt.mir
+++ b/llvm/test/CodeGen/X86/GlobalISel/sqrt.mir
@@ -1,9 +1,8 @@
 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
-# RUN: llc -mtriple=i686-linux-gnu -disable-gisel-legality-check -run-pass=reg-bank-select,instruction-select %s -o - | FileCheck %s --check-prefixes GISEL-I686
+# RUN: llc -mtriple=i686-linux-gnu -mattr=+x87-excess-precision -run-pass=reg-bank-select,instruction-select %s -o - | FileCheck %s --check-prefixes GISEL-I686
 
-# -disable-gisel-legality-check:
-# test_sqrt_f32 and test_sqrt_f64 are not legal in that form, the legalizer
-# would have widened s32/s64 x87 arithmetic to s80.
+# test_sqrt_f32 and test_sqrt_f64 are only legal under -mattr=+x87-excess-precision.
+# Without it, the legalizer widens the f32/f64 arithmetic to s80.
 
 ---
 name:            test_sqrt_f32
diff --git a/llvm/test/CodeGen/X86/x87-round-to-type.ll b/llvm/test/CodeGen/X86/x87-round-to-type.ll
index 66f53d23cbe9a..691494c7035e4 100644
--- a/llvm/test/CodeGen/X86/x87-round-to-type.ll
+++ b/llvm/test/CodeGen/X86/x87-round-to-type.ll
@@ -1,5 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
 ; RUN: llc < %s -mtriple=i686-unknown-linux-gnu -mattr=-sse | FileCheck %s --check-prefixes=X87
+; RUN: llc < %s -mtriple=i686-unknown-linux-gnu -mattr=-sse,+x87-excess-precision | FileCheck %s --check-prefixes=EXCESS
 
 declare float @llvm.sqrt.f32(float)
 declare double @llvm.sqrt.f64(double)
@@ -32,6 +33,24 @@ define i32 @cmp_reload_f32(float %a, float %b, ptr %p) nounwind {
 ; X87-NEXT:    movzbl %cl, %eax
 ; X87-NEXT:    popl %ecx
 ; X87-NEXT:    retl
+;
+; EXCESS-LABEL: cmp_reload_f32:
+; EXCESS:       # %bb.0:
+; EXCESS-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; EXCESS-NEXT:    flds {{[0-9]+}}(%esp)
+; EXCESS-NEXT:    fadds {{[0-9]+}}(%esp)
+; EXCESS-NEXT:    fsts (%eax)
+; EXCESS-NEXT:    flds (%eax)
+; EXCESS-NEXT:    fxch %st(1)
+; EXCESS-NEXT:    fucompp
+; EXCESS-NEXT:    fnstsw %ax
+; EXCESS-NEXT:    # kill: def $ah killed $ah killed $ax
+; EXCESS-NEXT:    sahf
+; EXCESS-NEXT:    setnp %al
+; EXCESS-NEXT:    sete %cl
+; EXCESS-NEXT:    andb %al, %cl
+; EXCESS-NEXT:    movzbl %cl, %eax
+; EXCESS-NEXT:    retl
   %add = fadd float %a, %b
   store volatile float %add, ptr %p
   %reload = load volatile float, ptr %p
@@ -62,6 +81,24 @@ define i32 @cmp_reload_f64(double %a, double %b, ptr %p) nounwind {
 ; X87-NEXT:    movzbl %cl, %eax
 ; X87-NEXT:    addl $8, %esp
 ; X87-NEXT:    retl
+;
+; EXCESS-LABEL: cmp_reload_f64:
+; EXCESS:       # %bb.0:
+; EXCESS-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; EXCESS-NEXT:    fldl {{[0-9]+}}(%esp)
+; EXCESS-NEXT:    faddl {{[0-9]+}}(%esp)
+; EXCESS-NEXT:    fstl (%eax)
+; EXCESS-NEXT:    fldl (%eax)
+; EXCESS-NEXT:    fxch %st(1)
+; EXCESS-NEXT:    fucompp
+; EXCESS-NEXT:    fnstsw %ax
+; EXCESS-NEXT:    # kill: def $ah killed $ah killed $ax
+; EXCESS-NEXT:    sahf
+; EXCESS-NEXT:    setnp %al
+; EXCESS-NEXT:    sete %cl
+; EXCESS-NEXT:    andb %al, %cl
+; EXCESS-NEXT:    movzbl %cl, %eax
+; EXCESS-NEXT:    retl
   %add = fadd double %a, %b
   store volatile double %add, ptr %p
   %reload = load volatile double, ptr %p
@@ -82,6 +119,12 @@ define float @fadd_f32(float %a, float %b) nounwind {
 ; X87-NEXT:    flds (%esp)
 ; X87-NEXT:    popl %eax
 ; X87-NEXT:    retl
+;
+; EXCESS-LABEL: fadd_f32:
+; EXCESS:       # %bb.0:
+; EXCESS-NEXT:    flds {{[0-9]+}}(%esp)
+; EXCESS-NEXT:    fadds {{[0-9]+}}(%esp)
+; EXCESS-NEXT:    retl
   %r = fadd float %a, %b
   ret float %r
 }
@@ -96,6 +139,12 @@ define float @fsub_f32(float %a, float %b) nounwind {
 ; X87-NEXT:    flds (%esp)
 ; X87-NEXT:    popl %eax
 ; X87-NEXT:    retl
+;
+; EXCESS-LABEL: fsub_f32:
+; EXCESS:       # %bb.0:
+; EXCESS-NEXT:    flds {{[0-9]+}}(%esp)
+; EXCESS-NEXT:    fsubs {{[0-9]+}}(%esp)
+; EXCESS-NEXT:    retl
   %r = fsub float %a, %b
   ret float %r
 }
@@ -110,6 +159,12 @@ define float @fmul_f32(float %a, float %b) nounwind {
 ; X87-NEXT:    flds (%esp)
 ; X87-NEXT:    popl %eax
 ; X87-NEXT:    retl
+;
+; EXCESS-LABEL: fmul_f32:
+; EXCESS:       # %bb.0:
+; EXCESS-NEXT:    flds {{[0-9]+}}(%esp)
+; EXCESS-NEXT:    fmuls {{[0-9]+}}(%esp)
+; EXCESS-NEXT:    retl
   %r = fmul float %a, %b
   ret float %r
 }
@@ -124,6 +179,12 @@ define float @fdiv_f32(float %a, float %b) nounwind {
 ; X87-NEXT:    flds (%esp)
 ; X87-NEXT:    popl %eax
 ; X87-NEXT:    retl
+;
+; EXCESS-LABEL: fdiv_f32:
+; EXCESS:       # %bb.0:
+; EXCESS-NEXT:    flds {{[0-9]+}}(%esp)
+; EXCESS-NEXT:    fdivs {{[0-9]+}}(%esp)
+; EXCESS-NEXT:    retl
   %r = fdiv float %a, %b
   ret float %r
 }
@@ -138,6 +199,12 @@ define float @fsqrt_f32(float %a) nounwind {
 ; X87-NEXT:    flds (%esp)
 ; X87-NEXT:    popl %eax
 ; X87-NEXT:    retl
+;
+; EXCESS-LABEL: fsqrt_f32:
+; EXCESS:       # %bb.0:
+; EXCESS-NEXT:    flds {{[0-9]+}}(%esp)
+; EXCESS-NEXT:    fsqrt
+; EXCESS-NEXT:    retl
   %r = call float @llvm.sqrt.f32(float %a)
   ret float %r
 }
@@ -152,6 +219,12 @@ define double @fadd_f64(double %a, double %b) nounwind {
 ; X87-NEXT:    fldl (%esp)
 ; X87-NEXT:    addl $8, %esp
 ; X87-NEXT:    retl
+;
+; EXCESS-LABEL: fadd_f64:
+; EXCESS:       # %bb.0:
+; EXCESS-NEXT:    fldl {{[0-9]+}}(%esp)
+; EXCESS-NEXT:    faddl {{[0-9]+}}(%esp)
+; EXCESS-NEXT:    retl
   %r = fadd double %a, %b
   ret double %r
 }
@@ -166,6 +239,12 @@ define double @fsqrt_f64(double %a) nounwind {
 ; X87-NEXT:    fldl (%esp)
 ; X87-NEXT:    addl $8, %esp
 ; X87-NEXT:    retl
+;
+; EXCESS-LABEL: fsqrt_f64:
+; EXCESS:       # %bb.0:
+; EXCESS-NEXT:    fldl {{[0-9]+}}(%esp)
+; EXCESS-NEXT:    fsqrt
+; EXCESS-NEXT:    retl
   %r = call double @llvm.sqrt.f64(double %a)
   ret double %r
 }
@@ -179,6 +258,13 @@ define x86_fp80 @fadd_f80(x86_fp80 %a, x86_fp80 %b) nounwind {
 ; X87-NEXT:    fldt {{[0-9]+}}(%esp)
 ; X87-NEXT:    faddp %st, %st(1)
 ; X87-NEXT:    retl
+;
+; EXCESS-LABEL: fadd_f80:
+; EXCESS:       # %bb.0:
+; EXCESS-NEXT:    fldt {{[0-9]+}}(%esp)
+; EXCESS-NEXT:    fldt {{[0-9]+}}(%esp)
+; EXCESS-NEXT:    faddp %st, %st(1)
+; EXCESS-NEXT:    retl
   %r = fadd x86_fp80 %a, %b
   ret x86_fp80 %r
 }
@@ -195,6 +281,12 @@ define float @fadd_const_f32(float %a) nounwind {
 ; X87-NEXT:    flds (%esp)
 ; X87-NEXT:    popl %eax
 ; X87-NEXT:    retl
+;
+; EXCESS-LABEL: fadd_const_f32:
+; EXCESS:       # %bb.0:
+; EXCESS-NEXT:    fld1
+; EXCESS-NEXT:    fadds {{[0-9]+}}(%esp)
+; EXCESS-NEXT:    retl
   %r = fadd float %a, 1.0
   ret float %r
 }
@@ -207,6 +299,12 @@ define float @fneg_f32(float %a) nounwind {
 ; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    fchs
 ; X87-NEXT:    retl
+;
+; EXCESS-LABEL: fneg_f32:
+; EXCESS:       # %bb.0:
+; EXCESS-NEXT:    flds {{[0-9]+}}(%esp)
+; EXCESS-NEXT:    fchs
+; EXCESS-NEXT:    retl
   %r = fneg float %a
   ret float %r
 }
@@ -217,6 +315,12 @@ define float @fabs_f32(float %a) nounwind {
 ; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    fabs
 ; X87-NEXT:    retl
+;
+; EXCESS-LABEL: fabs_f32:
+; EXCESS:       # %bb.0:
+; EXCESS-NEXT:    flds {{[0-9]+}}(%esp)
+; EXCESS-NEXT:    fabs
+; EXCESS-NEXT:    retl
   %r = call float @llvm.fabs.f32(float %a)
   ret float %r
 }
@@ -231,6 +335,14 @@ define void @store_only_f32(float %a, float %b, ptr %p) nounwind {
 ; X87-NEXT:    fadds {{[0-9]+}}(%esp)
 ; X87-NEXT:    fstps (%eax)
 ; X87-NEXT:    retl
+;
+; EXCESS-LABEL: store_only_f32:
+; EXCESS:       # %bb.0:
+; EXCESS-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; EXCESS-NEXT:    flds {{[0-9]+}}(%esp)
+; EXCESS-NEXT:    fadds {{[0-9]+}}(%esp)
+; EXCESS-NEXT:    fstps (%eax)
+; EXCESS-NEXT:    retl
   %r = fadd float %a, %b
   store float %r, ptr %p
   ret void
@@ -244,6 +356,14 @@ define void @store_only_f64(double %a, double %b, ptr %p) nounwind {
 ; X87-NEXT:    faddl {{[0-9]+}}(%esp)
 ; X87-NEXT:    fstpl (%eax)
 ; X87-NEXT:    retl
+;
+; EXCESS-LABEL: store_only_f64:
+; EXCESS:       # %bb.0:
+; EXCESS-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; EXCESS-NEXT:    fldl {{[0-9]+}}(%esp)
+; EXCESS-NEXT:    faddl {{[0-9]+}}(%esp)
+; EXCESS-NEXT:    fstpl (%eax)
+; EXCESS-NEXT:    retl
   %r = fadd double %a, %b
   store double %r, ptr %p
   ret void
@@ -260,6 +380,16 @@ define void @store_twice_f32(float %a, float %b, ptr %p, ptr %q) nounwind {
 ; X87-NEXT:    fsts (%ecx)
 ; X87-NEXT:    fstps (%eax)
 ; X87-NEXT:    retl
+;
+; EXCESS-LABEL: store_twice_f32:
+; EXCESS:       # %bb.0:
+; EXCESS-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; EXCESS-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; EXCESS-NEXT:    flds {{[0-9]+}}(%esp)
+; EXCESS-NEXT:    fadds {{[0-9]+}}(%esp)
+; EXCESS-NEXT:    fsts (%ecx)
+; EXCESS-NEXT:    fstps (%eax)
+; EXCESS-NEXT:    retl
   %r = fadd float %a, %b
   store float %r, ptr %p
   store float %r, ptr %q
@@ -279,6 +409,14 @@ define float @store_and_use_f32(float %a, float %b, ptr %p) nounwind {
 ; X87-NEXT:    fsts (%eax)
 ; X87-NEXT:    popl %eax
 ; X87-NEXT:    retl
+;
+; EXCESS-LABEL: store_and_use_f32:
+; EXCESS:       # %bb.0:
+; EXCESS-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; EXCESS-NEXT:    flds {{[0-9]+}}(%esp)
+; EXCESS-NEXT:    fadds {{[0-9]+}}(%esp)
+; EXCESS-NEXT:    fsts (%eax)
+; EXCESS-NEXT:    retl
   %r = fadd float %a, %b
   store float %r, ptr %p
   ret float %r
@@ -297,6 +435,18 @@ define void @store_narrower_f32(double %a, double %b, ptr %p) nounwind {
 ; X87-NEXT:    fstps (%eax)
 ; X87-NEXT:    addl $8, %esp
 ; X87-NEXT:    retl
+;
+; EXCESS-LABEL: store_narrower_f32:
+; EXCESS:       # %bb.0:
+; EXCESS-NEXT:    pushl %eax
+; EXCESS-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; EXCESS-NEXT:    fldl {{[0-9]+}}(%esp)
+; EXCESS-NEXT:    faddl {{[0-9]+}}(%esp)
+; EXCESS-NEXT:    fstps (%esp)
+; EXCESS-NEXT:    flds (%esp)
+; EXCESS-NEXT:    fstps (%eax)
+; EXCESS-NEXT:    popl %eax
+; EXCESS-NEXT:    retl
   %r = fadd double %a, %b
   %t = fptrunc double %r to float
   store float %t, ptr %p
@@ -316,6 +466,15 @@ define float @sitofp_i32_f32(i32 %x) nounwind {
 ; X87-NEXT:    flds (%esp)
 ; X87-NEXT:    addl $8, %esp
 ; X87-NEXT:    retl
+;
+; EXCESS-LABEL: sitofp_i32_f32:
+; EXCESS:       # %bb.0:
+; EXCESS-NEXT:    pushl %eax
+; EXCESS-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; EXCESS-NEXT:    movl %eax, (%esp)
+; EXCESS-NEXT:    fildl (%esp)
+; EXCESS-NEXT:    popl %eax
+; EXCESS-NEXT:    retl
   %r = sitofp i32 %x to float
   ret float %r
 }
@@ -331,6 +490,15 @@ define double @sitofp_i32_f64(i32 %x) nounwind {
 ; X87-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X87-NEXT:    addl $12, %esp
 ; X87-NEXT:    retl
+;
+; EXCESS-LABEL: sitofp_i32_f64:
+; EXCESS:       # %bb.0:
+; EXCESS-NEXT:    pushl %eax
+; EXCESS-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; EXCESS-NEXT:    movl %eax, (%esp)
+; EXCESS-NEXT:    fildl (%esp)
+; EXCESS-NEXT:    popl %eax
+; EXCESS-NEXT:    retl
   %r = sitofp i32 %x to double
   ret double %r
 }
@@ -344,6 +512,11 @@ define float @sitofp_i64_f32(i64 %x) nounwind {
 ; X87-NEXT:    flds (%esp)
 ; X87-NEXT:    popl %eax
 ; X87-NEXT:    retl
+;
+; EXCESS-LABEL: sitofp_i64_f32:
+; EXCESS:       # %bb.0:
+; EXCESS-NEXT:    fildll {{[0-9]+}}(%esp)
+; EXCESS-NEXT:    retl
   %r = sitofp i64 %x to float
   ret float %r
 }
@@ -442,6 +615,16 @@ define float @uitofp_i32_f32(i32 %x) nounwind {
 ; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    addl $20, %esp
 ; X87-NEXT:    retl
+;
+; EXCESS-LABEL: uitofp_i32_f32:
+; EXCESS:       # %bb.0:
+; EXCESS-NEXT:    subl $12, %esp
+; EXCESS-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; EXCESS-NEXT:    movl %eax, (%esp)
+; EXCESS-NEXT:    movl $0, {{[0-9]+}}(%esp)
+; EXCESS-NEXT:    fildll (%esp)
+; EXCESS-NEXT:    addl $12, %esp
+; EXCESS-NEXT:    retl
   %r = uitofp i32 %x to float
   ret float %r
 }
@@ -453,6 +636,11 @@ define x86_fp80 @sitofp_i64_f80(i64 %x) nounwind {
 ; X87:       # %bb.0:
 ; X87-NEXT:    fildll {{[0-9]+}}(%esp)
 ; X87-NEXT:    retl
+;
+; EXCESS-LABEL: sitofp_i64_f80:
+; EXCESS:       # %bb.0:
+; EXCESS-NEXT:    fildll {{[0-9]+}}(%esp)
+; EXCESS-NEXT:    retl
   %r = sitofp i64 %x to x86_fp80
   ret x86_fp80 %r
 }
@@ -467,6 +655,15 @@ define float @fptrunc_f80_f32(x86_fp80 %a) nounwind {
 ; X87-NEXT:    flds (%esp)
 ; X87-NEXT:    popl %eax
 ; X87-NEXT:    retl
+;
+; EXCESS-LABEL: fptrunc_f80_f32:
+; EXCESS:       # %bb.0:
+; EXCESS-NEXT:    pushl %eax
+; EXCESS-NEXT:    fldt {{[0-9]+}}(%esp)
+; EXCESS-NEXT:    fstps (%esp)
+; EXCESS-NEXT:    flds (%esp)
+; EXCESS-NEXT:    popl %eax
+; EXCESS-NEXT:    retl
   %r = fptrunc x86_fp80 %a to float
   ret float %r
 }
@@ -480,6 +677,15 @@ define double @fptrunc_f80_f64(x86_fp80 %a) nounwind {
 ; X87-NEXT:    fldl (%esp)
 ; X87-NEXT:    addl $8, %esp
 ; X87-NEXT:    retl
+;
+; EXCESS-LABEL: fptrunc_f80_f64:
+; EXCESS:       # %bb.0:
+; EXCESS-NEXT:    subl $12, %esp
+; EXCESS-NEXT:    fldt {{[0-9]+}}(%esp)
+; EXCESS-NEXT:    fstpl (%esp)
+; EXCESS-NEXT:    fldl (%esp)
+; EXCESS-NEXT:    addl $12, %esp
+; EXCESS-NEXT:    retl
   %r = fptrunc x86_fp80 %a to double
   ret double %r
 }
@@ -493,6 +699,15 @@ define float @fptrunc_f64_f32(double %a) nounwind {
 ; X87-NEXT:    flds (%esp)
 ; X87-NEXT:    popl %eax
 ; X87-NEXT:    retl
+;
+; EXCESS-LABEL: fptrunc_f64_f32:
+; EXCESS:       # %bb.0:
+; EXCESS-NEXT:    pushl %eax
+; EXCESS-NEXT:    fldl {{[0-9]+}}(%esp)
+; EXCESS-NEXT:    fstps (%esp)
+; EXCESS-NEXT:    flds (%esp)
+; EXCESS-NEXT:    popl %eax
+; EXCESS-NEXT:    retl
   %r = fptrunc double %a to float
   ret float %r
 }
@@ -503,6 +718,11 @@ define x86_fp80 @fpext_f32_f80(float %a) nounwind {
 ; X87:       # %bb.0:
 ; X87-NEXT:    flds {{[0-9]+}}(%esp)
 ; X87-NEXT:    retl
+;
+; EXCESS-LABEL: fpext_f32_f80:
+; EXCESS:       # %bb.0:
+; EXCESS-NEXT:    flds {{[0-9]+}}(%esp)
+; EXCESS-NEXT:    retl
   %r = fpext float %a to x86_fp80
   ret x86_fp80 %r
 }
@@ -522,6 +742,17 @@ define float @spill_across_call(float %a, float %b) nounwind {
 ; X87-NEXT:    flds {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Folded Reload
 ; X87-NEXT:    addl $12, %esp
 ; X87-NEXT:    retl
+;
+; EXCESS-LABEL: spill_across_call:
+; EXCESS:       # %bb.0:
+; EXCESS-NEXT:    subl $12, %esp
+; EXCESS-NEXT:    flds {{[0-9]+}}(%esp)
+; EXCESS-NEXT:    fadds {{[0-9]+}}(%esp)
+; EXCESS-NEXT:    fstps {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Folded Spill
+; EXCESS-NEXT:    calll opaque at PLT
+; EXCESS-NEXT:    flds {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Folded Reload
+; EXCESS-NEXT:    addl $12, %esp
+; EXCESS-NEXT:    retl
   %r = fadd float %a, %b
   call void @opaque()
   ret float %r
@@ -545,6 +776,16 @@ define float @chain_f32(float %a, float %b, float %c, float %d) nounwind {
 ; X87-NEXT:    flds (%esp)
 ; X87-NEXT:    addl $12, %esp
 ; X87-NEXT:    retl
+;
+; EXCESS-LABEL: chain_f32:
+; EXCESS:       # %bb.0:
+; EXCESS-NEXT:    flds {{[0-9]+}}(%esp)
+; EXCESS-NEXT:    flds {{[0-9]+}}(%esp)
+; EXCESS-NEXT:    fmuls {{[0-9]+}}(%esp)
+; EXCESS-NEXT:    fxch %st(1)
+; EXCESS-NEXT:    fmuls {{[0-9]+}}(%esp)
+; EXCESS-NEXT:    faddp %st, %st(1)
+; EXCESS-NEXT:    retl
   %ab = fmul float %a, %b
   %cd = fmul float %c, %d
   %r = fadd float %ab, %cd
@@ -564,8 +805,35 @@ define float @strict_fadd_f32(float %a, float %b) nounwind strictfp {
 ; X87-NEXT:    wait
 ; X87-NEXT:    popl %eax
 ; X87-NEXT:    retl
+;
+; EXCESS-LABEL: strict_fadd_f32:
+; EXCESS:       # %bb.0:
+; EXCESS-NEXT:    flds {{[0-9]+}}(%esp)
+; EXCESS-NEXT:    fadds {{[0-9]+}}(%esp)
+; EXCESS-NEXT:    wait
+; EXCESS-NEXT:    retl
   %r = call float @llvm.experimental.constrained.fadd.f32(float %a, float %b,
                                                           metadata !"round.dynamic",
                                                           metadata !"fpexcept.strict")
   ret float %r
 }
+
+; The opt-out is a subtarget feature, so it is a per-function property: this one
+; keeps the extended precision while everything above it is rounded.
+define float @attr_excess_precision(float %a, float %b) nounwind #0 {
+; X87-LABEL: attr_excess_precision:
+; X87:       # %bb.0:
+; X87-NEXT:    flds {{[0-9]+}}(%esp)
+; X87-NEXT:    fadds {{[0-9]+}}(%esp)
+; X87-NEXT:    retl
+;
+; EXCESS-LABEL: attr_excess_precision:
+; EXCESS:       # %bb.0:
+; EXCESS-NEXT:    flds {{[0-9]+}}(%esp)
+; EXCESS-NEXT:    fadds {{[0-9]+}}(%esp)
+; EXCESS-NEXT:    retl
+  %r = fadd float %a, %b
+  ret float %r
+}
+
+attributes #0 = { "target-features"="+x87,-sse,+x87-excess-precision" }

>From 2e980ee2d85ab9949bb3bd7fac03286ed47f0693 Mon Sep 17 00:00:00 2001
From: Dennis Duda <git at seri.tools>
Date: Sun, 9 Aug 2026 02:53:47 +0200
Subject: [PATCH 15/15] [clang][X86] Make `-fexcess-precision=fast` use the x87
 opt-out

-fexcess-precision=fast now restores the old behavior: `FLT_EVAL_METHOD=2` without any rounding.

Co-authored-by: Claude (Claude-Opus-5) <noreply at anthropic.com>
---
 clang/docs/ReleaseNotes.md                     |  5 +++++
 clang/docs/UsersManual.md                      |  6 ++++--
 .../clang/Basic/DiagnosticParseKinds.td        |  6 +++---
 clang/lib/Basic/Targets/X86.cpp                |  2 ++
 clang/lib/Basic/Targets/X86.h                  | 14 +++++++++-----
 clang/lib/Driver/ToolChains/Arch/X86.cpp       |  4 ++++
 clang/lib/Parse/ParseStmt.cpp                  |  9 ++++-----
 clang/test/CodeGen/X86/excess-precision-x87.c  | 18 +++++++++++-------
 clang/test/CodeGen/X86/fp-eval-method.c        | 10 +++++++---
 clang/test/Driver/fexcess-precision.c          |  4 ++++
 clang/test/Preprocessor/flt_eval_macro.cpp     |  8 ++++++++
 clang/test/Sema/x86-eval-method.c              | 10 ++++++++--
 clang/test/Sema/x86_64-eval-method.c           |  7 ++++++-
 13 files changed, 75 insertions(+), 28 deletions(-)

diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index d60610b5e9ef3..13b615c6c5b2e 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -265,6 +265,10 @@ features cannot lower the translation-unit ABI level;
 - `-ffp-eval-method=source` and `#pragma clang fp eval_method(source)` are now
   accepted on x86 without SSE, where they used to be rejected because the
   backend could not round x87 results to their type.
+- `-fexcess-precision=fast` is no longer an alias for `standard`. On x86 without
+  SSE: x87 `float`/`double` results keep the register's extended precision
+  instead of being rounded to their type, and `__FLT_EVAL_METHOD__` becomes `2`
+  rather than `0`. It has no effect on other targets.
 
 ### Removed Compiler Flags
 
@@ -829,6 +833,7 @@ features cannot lower the translation-unit ABI level;
   `float`/`double` result is now rounded, just as is already is documented in
   the manual. As a consequence, `__FLT_EVAL_METHOD__` is now `0` by default,
   instead of `2`, on x86 without SSE.
+- `-fexcess-precision=fast` opts out of the fix described above.
 
 ### Fixed Point Support in Clang
 
diff --git a/clang/docs/UsersManual.md b/clang/docs/UsersManual.md
index 3bec20612c048..fddcece752956 100644
--- a/clang/docs/UsersManual.md
+++ b/clang/docs/UsersManual.md
@@ -2098,8 +2098,10 @@ excess precision arithmetic.  Valid values are:
 * `standard` - The default.  Allow the use of excess precision arithmetic
   under the constraints of the C and C++ standards. Has no effect except on
   the types and targets listed above.
-* `fast` - Accepted for GCC compatibility, but currently treated as an
-  alias for `standard`.
+* `fast` - Allow excess precision to escape an expression. On x86 without SSE:
+  x87 `float`/`double` results keep the register's extended precision instead of
+  being rounded to their type, and `__FLT_EVAL_METHOD__` becomes `2` rather than
+  `0`. It has no effect on other targets.
 * `16` - Forces `_Float16` operations to be emitted without using excess
   precision arithmetic.
 :::
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td
index 4ca2ed38363c4..0b87a9ae842fa 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -1271,9 +1271,9 @@ def err_pragma_attribute_namespace_on_attribute : Error<
 def note_pragma_attribute_namespace_on_attribute : Note<
   "omit the namespace to add attributes to the most-recently"
   " pushed attribute group">;
-def warn_no_support_for_eval_method_source_on_m32 : Warning<
-  "setting the floating point evaluation method to `source` on a target "
-  "without SSE is not supported">, InGroup<Pragmas>;
+def warn_no_support_for_eval_method_source_with_excess_precision : Warning<
+  "setting the floating point evaluation method to `source` is not supported "
+  "with '-fexcess-precision=fast' on a target without SSE">, InGroup<Pragmas>;
 // - #pragma __debug
 def warn_pragma_debug_dependent_argument : Warning<
   "%select{value|type}0-dependent expression passed as an argument to debug "
diff --git a/clang/lib/Basic/Targets/X86.cpp b/clang/lib/Basic/Targets/X86.cpp
index 8ab39b750dc99..e84051c7550c0 100644
--- a/clang/lib/Basic/Targets/X86.cpp
+++ b/clang/lib/Basic/Targets/X86.cpp
@@ -458,6 +458,8 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
       HasJMPABS = true;
     } else if (Feature == "+branch-hint") {
       HasBranchHint = true;
+    } else if (Feature == "+x87-excess-precision") {
+      AllowX87ExcessPrecision = true;
     }
 
     X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Feature)
diff --git a/clang/lib/Basic/Targets/X86.h b/clang/lib/Basic/Targets/X86.h
index 56e9b16e5934f..be5def8b54320 100644
--- a/clang/lib/Basic/Targets/X86.h
+++ b/clang/lib/Basic/Targets/X86.h
@@ -48,6 +48,7 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo {
     AVX2,
     AVX512F
   } SSELevel = NoSSE;
+  bool AllowX87ExcessPrecision = false;
   bool HasMMX = false;
   enum XOPEnum { NoXOP, SSE4A, FMA4, XOP } XOPLevel = NoXOP;
   enum AddrSpace { ptr32_sptr = 270, ptr32_uptr = 271, ptr64 = 272 };
@@ -183,13 +184,16 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo {
   }
 
   LangOptions::FPEvalMethodKind getFPEvalMethod() const override {
-    // X87 computes at 80 bits, but the backend rounds every f32/f64 result
-    // back to its own type, so intermediate results have the range and
-    // precision of their type just as they do with SSE.
-    return LangOptions::FPEvalMethodKind::FEM_Source;
+    // X87 computes at 80 bits, but the backend rounds every f32/f64 result back
+    // to its own type unless -fexcess-precision=fast asked it not to.
+    return SSELevel == NoSSE && AllowX87ExcessPrecision
+               ? LangOptions::FPEvalMethodKind::FEM_Extended
+               : LangOptions::FPEvalMethodKind::FEM_Source;
   }
 
-  bool supportSourceEvalMethod() const override { return true; }
+  bool supportSourceEvalMethod() const override {
+    return SSELevel > NoSSE || !AllowX87ExcessPrecision;
+  }
 
   ArrayRef<const char *> getGCCRegNames() const override;
 
diff --git a/clang/lib/Driver/ToolChains/Arch/X86.cpp b/clang/lib/Driver/ToolChains/Arch/X86.cpp
index d0108e5d99853..add6beb72b072 100644
--- a/clang/lib/Driver/ToolChains/Arch/X86.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/X86.cpp
@@ -229,6 +229,10 @@ void x86::getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple,
         << D.getOpts().getOptionName(LVIOpt);
   }
 
+  if (Arg *A = Args.getLastArg(options::OPT_fexcess_precision_EQ))
+    if (StringRef(A->getValue()) == "fast")
+      Features.push_back("+x87-excess-precision");
+
   enum class EGPRFeature { Unknown, Disabled, Enabled };
   EGPRFeature EGPROpt = EGPRFeature::Unknown;
   // Now add any that the user explicitly requested on the command line,
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index 5e67cd551bff8..11f65615ac2b0 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -1252,16 +1252,15 @@ StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
   if (isStmtExpr && LastIsError && !Stmts.empty())
     return StmtError();
 
-  // Warn the user that using option `-ffp-eval-method=source` on a
-  // 32-bit target and feature `sse` disabled, or using
-  // `pragma clang fp eval_method=source` and feature `sse` disabled, is not
-  // supported.
+  // Warn the user that using option `-ffp-eval-method=source`, or using
+  // `pragma clang fp eval_method=source`, is not supported on a target that
+  // keeps excess precision (x87 without SSE, under -fexcess-precision=fast).
   if (!PP.getTargetInfo().supportSourceEvalMethod() &&
       (PP.getLastFPEvalPragmaLocation().isValid() ||
        PP.getCurrentFPEvalMethod() ==
            LangOptions::FPEvalMethodKind::FEM_Source))
     Diag(Tok.getLocation(),
-         diag::warn_no_support_for_eval_method_source_on_m32);
+         diag::warn_no_support_for_eval_method_source_with_excess_precision);
 
   SourceLocation CloseLoc = Tok.getLocation();
 
diff --git a/clang/test/CodeGen/X86/excess-precision-x87.c b/clang/test/CodeGen/X86/excess-precision-x87.c
index 2917dcef390f5..771126664608f 100644
--- a/clang/test/CodeGen/X86/excess-precision-x87.c
+++ b/clang/test/CodeGen/X86/excess-precision-x87.c
@@ -1,14 +1,17 @@
 // RUN: %clang_cc1 -triple i386-unknown-linux-gnu -target-feature -sse \
-// RUN:   -O1 -emit-llvm -o - %s | FileCheck %s --check-prefix=SRC
+// RUN:   -O1 -emit-llvm -o - %s | FileCheck %s --check-prefixes=NARROW,SRC
+// RUN: %clang_cc1 -triple i386-unknown-linux-gnu -target-feature -sse \
+// RUN:   -target-feature +x87-excess-precision -O1 -emit-llvm -o - %s \
+// RUN:   | FileCheck %s --check-prefixes=NARROW,FAST
 // RUN: %clang_cc1 -triple i386-unknown-linux-gnu -target-feature -sse \
 // RUN:   -ffp-eval-method=extended -O1 -emit-llvm -o - %s \
 // RUN:   | FileCheck %s --check-prefix=EXT
 
-// SRC-LABEL: define {{.*}}float @expr(
-// SRC: fmul float
-// SRC: fmul float
-// SRC: fadd float
-// SRC-NOT: x86_fp80
+// NARROW-LABEL: define {{.*}}float @expr(
+// NARROW: fmul float
+// NARROW: fmul float
+// NARROW: fadd float
+// NARROW-NOT: x86_fp80
 //
 // EXT-LABEL: define {{.*}}float @expr(
 // EXT: fmul x86_fp80
@@ -19,8 +22,9 @@ float expr(float a, float b, float c, float d) {
   return a * b + c * d;
 }
 
-// SRC-LABEL: define {{.*}}i32 @eval_method(
+// NARROW-LABEL: define {{.*}}i32 @eval_method(
 // SRC: ret i32 0
+// FAST: ret i32 2
 //
 // EXT-LABEL: define {{.*}}i32 @eval_method(
 // EXT: ret i32 2
diff --git a/clang/test/CodeGen/X86/fp-eval-method.c b/clang/test/CodeGen/X86/fp-eval-method.c
index 2e275035b4d78..f0df8341ee80b 100644
--- a/clang/test/CodeGen/X86/fp-eval-method.c
+++ b/clang/test/CodeGen/X86/fp-eval-method.c
@@ -1,8 +1,11 @@
 // RUN: %clang_cc1 -triple i386-unknown-netbsd -emit-llvm -o - %s \
-// RUN: | FileCheck %s
+// RUN: | FileCheck %s -check-prefixes=CHECK,CHECK-SRC
 
 // RUN: %clang_cc1 -triple i386--linux -emit-llvm -o - %s \
-// RUN: | FileCheck %s
+// RUN: | FileCheck %s -check-prefixes=CHECK,CHECK-SRC
+
+// RUN: %clang_cc1 -triple i386--linux -target-feature +x87-excess-precision \
+// RUN: -emit-llvm -o - %s | FileCheck %s -check-prefixes=CHECK,CHECK-EXCESS
 
 float f(float x, float y) {
   // CHECK: define{{.*}} float @f
@@ -11,6 +14,7 @@ float f(float x, float y) {
 }
 
 int getEvalMethod(void) {
-  // CHECK: ret i32 0
+  // CHECK-SRC: ret i32 0
+  // CHECK-EXCESS: ret i32 2
   return __FLT_EVAL_METHOD__;
 }
diff --git a/clang/test/Driver/fexcess-precision.c b/clang/test/Driver/fexcess-precision.c
index 0aa1022f17fdc..550d5765e5b2e 100644
--- a/clang/test/Driver/fexcess-precision.c
+++ b/clang/test/Driver/fexcess-precision.c
@@ -63,12 +63,16 @@
 
 // CHECK-FAST: "-ffloat16-excess-precision=fast"
 // CHECK-FAST: "-fbfloat16-excess-precision=fast"
+// CHECK-FAST: "-target-feature" "+x87-excess-precision"
 // CHECK-STD: "-ffloat16-excess-precision=standard"
 // CHECK-STD: "-fbfloat16-excess-precision=standard"
+// CHECK-STD-NOT: "+x87-excess-precision"
 // CHECK-NONE: "-ffloat16-excess-precision=none"
 // CHECK-NONE: "-fbfloat16-excess-precision=none"
+// CHECK-NONE-NOT: "+x87-excess-precision"
 // CHECK-ERR-NONE: unsupported argument 'none' to option '-fexcess-precision='
 // CHECK: "-cc1"
 // CHECK-NOT: "-ffloat16-excess-precision=fast"
 // CHECK-NOT: "-fbfloat16-excess-precision=fast"
+// CHECK-NOT: "+x87-excess-precision"
 // CHECK-ERR-16: unsupported argument '16' to option '-fexcess-precision='
diff --git a/clang/test/Preprocessor/flt_eval_macro.cpp b/clang/test/Preprocessor/flt_eval_macro.cpp
index 44170ade83778..7961a4e31c89c 100644
--- a/clang/test/Preprocessor/flt_eval_macro.cpp
+++ b/clang/test/Preprocessor/flt_eval_macro.cpp
@@ -8,6 +8,10 @@
 // RUN:   -ffp-eval-method=extended %s -o - \
 // RUN:   | FileCheck %s -check-prefix=EXT -strict-whitespace
 
+// RUN: %clang_cc1 -E -dM -triple=x86_64-none-none -target-feature -sse \
+// RUN:   -target-feature +x87-excess-precision %s -o - \
+// RUN:   | FileCheck %s -check-prefix=EXT -strict-whitespace
+
 // RUN: %clang_cc1 -E -dM -triple=arm64e-apple-ios -target-feature -sse \
 // RUN:   %s -o - | FileCheck %s  -strict-whitespace
 
@@ -29,6 +33,10 @@
 // RUN: %clang_cc1 -E -dM -triple i386-pc-windows -target-cpu pentium4 \
 // RUN:   -target-feature -sse %s -o - | FileCheck %s -strict-whitespace
 
+// RUN: %clang_cc1 -E -dM -triple i386-pc-windows -target-cpu pentium4 \
+// RUN:   -target-feature -sse -target-feature +x87-excess-precision %s -o - \
+// RUN:   | FileCheck %s -check-prefix=EXT -strict-whitespace
+
 #ifdef __FLT_EVAL_METHOD__
 #if __FLT_EVAL_METHOD__ == 3
 #define __GLIBC_FLT_EVAL_METHOD 2
diff --git a/clang/test/Sema/x86-eval-method.c b/clang/test/Sema/x86-eval-method.c
index 10b97336b0937..e23b407eaa445 100644
--- a/clang/test/Sema/x86-eval-method.c
+++ b/clang/test/Sema/x86-eval-method.c
@@ -2,6 +2,12 @@
 // RUN: -triple i386-pc-windows -target-cpu pentium4 -target-feature -sse \
 // RUN: -emit-llvm -ffp-eval-method=source  -o - -verify=no-warn %s
 //
+// ... unless -fexcess-precision=fast is set.
+// RUN: %clang_cc1 -fexperimental-strict-floating-point \
+// RUN: -triple i386-pc-windows -target-cpu pentium4 -target-feature -sse \
+// RUN: -target-feature +x87-excess-precision \
+// RUN: -emit-llvm -ffp-eval-method=source  -o - -verify=warn %s
+//
 // RUN: %clang_cc1 -fexperimental-strict-floating-point \
 // RUN: -triple i386-pc-windows -target-cpu pentium4 \
 // RUN: -emit-llvm -ffp-eval-method=source  -o - -verify=no-warn %s
@@ -10,9 +16,9 @@
 
 float add1(float a, float b, float c) {
   return a + b + c;
-}
+} // warn-warning{{setting the floating point evaluation method to `source` is not supported with '-fexcess-precision=fast' on a target without SSE}}
 
 float add2(float a, float b, float c) {
 #pragma clang fp eval_method(source)
   return a + b + c;
-}
+} // warn-warning{{setting the floating point evaluation method to `source` is not supported with '-fexcess-precision=fast' on a target without SSE}}
diff --git a/clang/test/Sema/x86_64-eval-method.c b/clang/test/Sema/x86_64-eval-method.c
index 52554795630ad..e90afbb230812 100644
--- a/clang/test/Sema/x86_64-eval-method.c
+++ b/clang/test/Sema/x86_64-eval-method.c
@@ -2,6 +2,11 @@
 // RUN: -triple x86_64-linux-gnu -target-feature -sse -emit-llvm \
 // RUN: -o - -verify=no-warn %s
 //
+// ... unless -fexcess-precision=fast is set.
+// RUN: %clang_cc1 -fexperimental-strict-floating-point \
+// RUN: -triple x86_64-linux-gnu -target-feature -sse \
+// RUN: -target-feature +x87-excess-precision -emit-llvm -o - -verify=warn %s
+//
 // RUN: %clang_cc1 -fexperimental-strict-floating-point \
 // RUN: -triple x86_64-linux-gnu -emit-llvm -o - -verify=no-warn %s
 
@@ -10,4 +15,4 @@
 float add2(float a, float b, float c) {
 #pragma clang fp eval_method(source)
   return a + b + c;
-}
+} // warn-warning{{setting the floating point evaluation method to `source` is not supported with '-fexcess-precision=fast' on a target without SSE}}



More information about the cfe-commits mailing list