[llvm] [X86] Eliminate dead SSE loads and stores after rewriting stack spills (PR #213498)

via llvm-commits llvm-commits at lists.llvm.org
Sun Aug 2 11:27:08 PDT 2026


https://github.com/AZero13 updated https://github.com/llvm/llvm-project/pull/213498

>From 6bafe122061cd20ad592e3c93e560089ef32930f Mon Sep 17 00:00:00 2001
From: AZero13 <gfunni234 at gmail.com>
Date: Sat, 1 Aug 2026 20:08:12 -0400
Subject: [PATCH 1/2] [X86] Add pre-commit test case for x87 float return and
 SSE roundtrip

---
 llvm/test/CodeGen/X86/x87-inout-bounce.ll | 94 +++++++++++++++++++++++
 1 file changed, 94 insertions(+)
 create mode 100644 llvm/test/CodeGen/X86/x87-inout-bounce.ll

diff --git a/llvm/test/CodeGen/X86/x87-inout-bounce.ll b/llvm/test/CodeGen/X86/x87-inout-bounce.ll
new file mode 100644
index 0000000000000..161ca2c1742b1
--- /dev/null
+++ b/llvm/test/CodeGen/X86/x87-inout-bounce.ll
@@ -0,0 +1,94 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=i386-unknown-linux-gnu -mattr=+sse2,+x87 | FileCheck %s
+
+define float @returns_float() {
+; CHECK-LABEL: returns_float:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    subl $12, %esp
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    calll rand at PLT
+; CHECK-NEXT:    cvtsi2ss %eax, %xmm0
+; CHECK-NEXT:    movss %xmm0, {{[0-9]+}}(%esp)
+; CHECK-NEXT:    flds {{[0-9]+}}(%esp)
+; CHECK-NEXT:    addl $12, %esp
+; CHECK-NEXT:    .cfi_def_cfa_offset 4
+; CHECK-NEXT:    retl
+entry:
+  %call = call i32 @rand()
+  %conv = sitofp i32 %call to float
+  ret float %conv
+}
+
+declare i32 @rand()
+
+define float @example_float() {
+; CHECK-LABEL: example_float:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    subl $28, %esp
+; CHECK-NEXT:    .cfi_def_cfa_offset 32
+; CHECK-NEXT:    calll returns_float at PLT
+; CHECK-NEXT:    fstps {{[0-9]+}}(%esp)
+; CHECK-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
+; CHECK-NEXT:    movss %xmm0, (%esp) # 4-byte Spill
+; CHECK-NEXT:    calll returns_float at PLT
+; CHECK-NEXT:    fstps {{[0-9]+}}(%esp)
+; CHECK-NEXT:    movss (%esp), %xmm0 # 4-byte Reload
+; CHECK-NEXT:    # xmm0 = mem[0],zero,zero,zero
+; CHECK-NEXT:    addss {{[0-9]+}}(%esp), %xmm0
+; CHECK-NEXT:    movss %xmm0, (%esp) # 4-byte Spill
+; CHECK-NEXT:    calll returns_float at PLT
+; CHECK-NEXT:    fstps {{[0-9]+}}(%esp)
+; CHECK-NEXT:    movss (%esp), %xmm0 # 4-byte Reload
+; CHECK-NEXT:    # xmm0 = mem[0],zero,zero,zero
+; CHECK-NEXT:    addss {{[0-9]+}}(%esp), %xmm0
+; CHECK-NEXT:    movss %xmm0, (%esp) # 4-byte Spill
+; CHECK-NEXT:    calll returns_float at PLT
+; CHECK-NEXT:    fstps {{[0-9]+}}(%esp)
+; CHECK-NEXT:    movss (%esp), %xmm0 # 4-byte Reload
+; CHECK-NEXT:    # xmm0 = mem[0],zero,zero,zero
+; CHECK-NEXT:    addss {{[0-9]+}}(%esp), %xmm0
+; CHECK-NEXT:    movss %xmm0, (%esp) # 4-byte Spill
+; CHECK-NEXT:    calll returns_float at PLT
+; CHECK-NEXT:    fstps {{[0-9]+}}(%esp)
+; CHECK-NEXT:    movss (%esp), %xmm0 # 4-byte Reload
+; CHECK-NEXT:    # xmm0 = mem[0],zero,zero,zero
+; CHECK-NEXT:    addss {{[0-9]+}}(%esp), %xmm0
+; CHECK-NEXT:    movss %xmm0, {{[0-9]+}}(%esp)
+; CHECK-NEXT:    flds {{[0-9]+}}(%esp)
+; CHECK-NEXT:    addl $28, %esp
+; CHECK-NEXT:    .cfi_def_cfa_offset 4
+; CHECK-NEXT:    retl
+entry:
+  %call = call float @returns_float()
+  %call1 = call float @returns_float()
+  %add = fadd float %call, %call1
+  %call2 = call float @returns_float()
+  %add3 = fadd float %add, %call2
+  %call4 = call float @returns_float()
+  %add5 = fadd float %add3, %call4
+  %call6 = call float @returns_float()
+  %add7 = fadd float %add5, %call6
+  ret float %add7
+}
+
+declare x86_fp80 @returns_long_double()
+
+define x86_fp80 @testC() {
+; CHECK-LABEL: testC:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    subl $12, %esp
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    calll returns_long_double at PLT
+; CHECK-NEXT:    fstps {{[0-9]+}}(%esp)
+; CHECK-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
+; CHECK-NEXT:    movss %xmm0, {{[0-9]+}}(%esp)
+; CHECK-NEXT:    flds {{[0-9]+}}(%esp)
+; CHECK-NEXT:    addl $12, %esp
+; CHECK-NEXT:    .cfi_def_cfa_offset 4
+; CHECK-NEXT:    retl
+entry:
+  %call = call x86_fp80 @returns_long_double()
+  %conv = fptrunc x86_fp80 %call to float
+  %conv1 = fpext float %conv to x86_fp80
+  ret x86_fp80 %conv1
+}

>From b980bde5c8e0ee1694ab2f71c3bcc14963d041b3 Mon Sep 17 00:00:00 2001
From: AZero13 <gfunni234 at gmail.com>
Date: Sat, 1 Aug 2026 21:20:34 -0400
Subject: [PATCH 2/2] [X86] Eliminate dead SSE loads and stores after rewriting
 stack spills

These spills are redundant and can be removed.
---
 llvm/lib/Target/X86/X86FixupInstTuning.cpp    | 294 +++++++++++++++++-
 llvm/test/CodeGen/X86/fp-intrinsics.ll        |  20 +-
 .../CodeGen/X86/fp-strict-scalar-inttofp.ll   |  28 +-
 llvm/test/CodeGen/X86/fp80-strict-scalar.ll   |  12 +-
 llvm/test/CodeGen/X86/ftrunc.ll               |   4 +-
 llvm/test/CodeGen/X86/isel-fptrunc-fpext.ll   |   8 +-
 llvm/test/CodeGen/X86/scalar-fp-to-i64.ll     |  30 +-
 llvm/test/CodeGen/X86/scalar-int-to-fp.ll     |  28 +-
 llvm/test/CodeGen/X86/x87-inout-bounce.ll     |  31 +-
 9 files changed, 354 insertions(+), 101 deletions(-)

diff --git a/llvm/lib/Target/X86/X86FixupInstTuning.cpp b/llvm/lib/Target/X86/X86FixupInstTuning.cpp
index 621fd35a03cd5..b55979d04ecb5 100644
--- a/llvm/lib/Target/X86/X86FixupInstTuning.cpp
+++ b/llvm/lib/Target/X86/X86FixupInstTuning.cpp
@@ -23,13 +23,20 @@
 
 #include "X86.h"
 #include "X86InstrInfo.h"
-#include "X86RegisterInfo.h"
 #include "X86Subtarget.h"
 #include "llvm/ADT/Statistic.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineFunctionAnalysisManager.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstr.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineMemOperand.h"
+#include "llvm/CodeGen/MachineOperand.h"
 #include "llvm/CodeGen/MachinePassManager.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/PseudoSourceValue.h"
 #include "llvm/IR/Analysis.h"
 
 using namespace llvm;
@@ -47,6 +54,8 @@ class X86FixupInstTuningImpl {
   bool processInstruction(MachineFunction &MF, MachineBasicBlock &MBB,
                           MachineBasicBlock::iterator &I);
 
+  bool processSpills(MachineBasicBlock &MBB, MachineFunction &MF);
+
   const X86InstrInfo *TII = nullptr;
   const X86Subtarget *ST = nullptr;
   const MCSchedModel *SM = nullptr;
@@ -88,6 +97,288 @@ static std::optional<bool> CmpOptionals(T NewVal, T CurVal) {
   return std::nullopt;
 }
 
+bool X86FixupInstTuningImpl::processSpills(MachineBasicBlock &MBB,
+                                           MachineFunction &MF) {
+  bool Changed = false;
+
+  // Tracks a load->store chain: load from OrigFI into Reg, store Reg to
+  // SpillFI. We want to redirect later loads from SpillFI to OrigFI.
+  struct SpillEntry {
+    SmallVector<MachineOperand, X86::AddrNumOperands> OrigMOs;
+    MachineInstr *LoadMI = nullptr;  // The original load from OrigFI.
+    MachineInstr *StoreMI = nullptr; // The store to SpillFI.
+    MCRegister LoadReg;              // The register used as intermediary.
+    unsigned UseCount = 0;           // Number of loads from SpillFI seen.
+    unsigned RewriteCount = 0;       // Number successfully rewritten.
+    LocationSize Size = LocationSize::beforeOrAfterPointer();
+    int64_t Offset = 0;
+    int OrigFI = -1;
+    bool Invalid = false;
+  };
+
+  // Maps SpillFI -> SpillEntry (the redirect info for that slot).
+  DenseMap<int, SpillEntry> SpillMap;
+
+  // Maps physical register -> (OrigFI, address operands, LoadMI).
+  // Keyed by the canonical (largest) super-register to handle aliasing.
+  struct RegEntry {
+    SmallVector<MachineOperand, X86::AddrNumOperands> MOs;
+    MachineInstr *LoadMI = nullptr;
+    int FI = -1;
+    LocationSize Size = LocationSize::beforeOrAfterPointer();
+  };
+  DenseMap<MCRegister, RegEntry> RegToFI;
+
+  auto InvalidateReg = [&](MCRegister Reg) {
+    for (MCRegAliasIterator AI(Reg, TRI, /*IncludeSelf=*/true); AI.isValid();
+         ++AI)
+      RegToFI.erase(*AI);
+    for (auto &[FI, SE] : SpillMap) {
+      if (SE.Invalid)
+        continue;
+      bool UsesReg = false;
+      for (const MachineOperand &MO : SE.OrigMOs) {
+        if (MO.isReg() && MO.getReg() && TRI->regsOverlap(MO.getReg(), Reg)) {
+          UsesReg = true;
+          break;
+        }
+      }
+      if (UsesReg)
+        SE.Invalid = true;
+    }
+  };
+
+  auto IsSafeToEraseLoad = [&](MachineInstr *LoadMI, MachineInstr *StoreMI,
+                               MCRegister Reg) -> bool {
+    // Walk forward from LoadMI. The register must not be read by anything
+    // other than StoreMI, and must be redefined (or reach end-of-block
+    // without being live-out).
+    for (MachineBasicBlock::iterator I = std::next(LoadMI->getIterator()),
+                                     E = MBB.end();
+         I != E; ++I) {
+      if (&*I == StoreMI)
+        continue;
+      if (I->readsRegister(Reg, TRI))
+        return false;
+      if (I->definesRegister(Reg, TRI))
+        return true;
+    }
+    // Check if the register is live-out of the block.
+    for (MCRegAliasIterator AI(Reg, TRI, /*IncludeSelf=*/true); AI.isValid();
+         ++AI) {
+      for (MachineBasicBlock *Succ : MBB.successors()) {
+        if (Succ->isLiveIn(*AI))
+          return false;
+      }
+    }
+    return true;
+  };
+
+  for (MachineInstr &MI : MBB) {
+    if (MI.isCall()) {
+      // Calls clobber registers and may read/write memory; clear tracking
+      // state.
+      RegToFI.clear();
+      SpillMap.clear();
+      continue;
+    }
+
+    int LoadedFI = -1;
+    MCRegister LoadedReg(TII->isLoadFromStackSlotPostFE(MI, LoadedFI));
+    bool IsX87 = X86::isX87Instruction(MI);
+
+    if (LoadedReg && IsX87) {
+      auto It = SpillMap.find(LoadedFI);
+      if (It != SpillMap.end() && !MI.memoperands_empty()) {
+        // This load reads from a SpillFI we're tracking. Rewrite it to
+        // read directly from OrigFI.
+        SpillEntry &SE = It->second;
+        const MachineMemOperand *MMO = nullptr;
+        for (const MachineMemOperand *M : MI.memoperands()) {
+          if (M->isLoad()) {
+            MMO = M;
+            break;
+          }
+        }
+        if (MMO && MMO->getSize() == SE.Size && MMO->getOffset() == SE.Offset) {
+          MachineFrameInfo &MFI = MF.getFrameInfo();
+          int64_t OrigSize = MFI.getObjectSize(SE.OrigFI);
+          if (!SE.Size.hasValue() || OrigSize >= (int64_t)SE.Size.getValue()) {
+            SE.UseCount++;
+            if (!SE.Invalid) {
+              int MemIdx = X86::getFirstAddrOperandIdx(MI);
+              if (MemIdx >= 0) {
+                for (int i = 0; i < X86::AddrNumOperands; ++i)
+                  MI.getOperand(MemIdx + i) = SE.OrigMOs[i];
+                // Replace MMO with one describing OrigFI rather than SpillFI.
+                MachinePointerInfo PtrInfo =
+                    MachinePointerInfo::getFixedStack(MF, SE.OrigFI, SE.Offset);
+                MachineMemOperand *NewMMO =
+                    MF.getMachineMemOperand(MMO, PtrInfo, MMO->getSize());
+                MI.setMemRefs(MF, {NewMMO});
+                SE.RewriteCount++;
+                Changed = true;
+              }
+            }
+          }
+        }
+      }
+    }
+
+    // MMO-based fallback: handles x87 loads (LD_F32m, LD_F64m, etc.) that
+    // aren't recognized by isLoadFromStackSlotPostFE because they aren't
+    // in isFrameLoadOpcode, but do have valid FixedStackPseudoSourceValue
+    // MMOs. We can rewrite address operands but cannot delete the store
+    // (since we can't track all uses via this path reliably).
+    if (!LoadedReg && MI.mayLoad() && IsX87) {
+      int MemIdx = X86::getFirstAddrOperandIdx(MI);
+      if (MemIdx >= 0) {
+        for (const MachineMemOperand *MMO : MI.memoperands()) {
+          if (!MMO->isLoad())
+            continue;
+          const auto *FSPV = dyn_cast_or_null<FixedStackPseudoSourceValue>(
+              MMO->getPseudoValue());
+          if (!FSPV)
+            continue;
+          int FI = FSPV->getFrameIndex();
+          auto It = SpillMap.find(FI);
+          if (It != SpillMap.end()) {
+            SpillEntry &SE = It->second;
+            if (MMO->getSize() == SE.Size && MMO->getOffset() == SE.Offset) {
+              MachineFrameInfo &MFI = MF.getFrameInfo();
+              int64_t OrigSize = MFI.getObjectSize(SE.OrigFI);
+              if (!SE.Size.hasValue() ||
+                  OrigSize >= (int64_t)SE.Size.getValue()) {
+                SE.UseCount++;
+                if (!SE.Invalid) {
+                  for (int i = 0; i < X86::AddrNumOperands; ++i)
+                    MI.getOperand(MemIdx + i) = SE.OrigMOs[i];
+                  MachinePointerInfo PtrInfo =
+                      MachinePointerInfo::getFixedStack(MF, SE.OrigFI,
+                                                        SE.Offset);
+                  MachineMemOperand *NewMMO =
+                      MF.getMachineMemOperand(MMO, PtrInfo, MMO->getSize());
+                  MI.setMemRefs(MF, {NewMMO});
+                  SE.RewriteCount++;
+                  Changed = true;
+                }
+              }
+            }
+            break;
+          }
+        }
+      }
+    }
+
+    int StoredFI = -1;
+    MCRegister StoredReg(TII->isStoreToStackSlotPostFE(MI, StoredFI));
+
+    if (StoredReg) {
+      // If the stored register was loaded from a known FI, record the chain.
+      auto It = RegToFI.find(StoredReg);
+      if (It != RegToFI.end() && !MI.memoperands_empty()) {
+        const MachineMemOperand *MMO = MI.memoperands().front();
+        if (MMO->getSize() == It->second.Size && MMO->getSize().hasValue()) {
+          SpillEntry SE;
+          SE.OrigMOs = It->second.MOs;
+          SE.LoadMI = It->second.LoadMI;
+          SE.LoadReg = StoredReg;
+          SE.StoreMI = &MI;
+          SE.Size = MMO->getSize();
+          SE.Offset = MMO->getOffset();
+          SE.OrigFI = It->second.FI;
+          SpillMap[StoredFI] = SE;
+        } else {
+          SpillMap.erase(StoredFI);
+        }
+      } else {
+        // The store overwrites SpillFI with unknown data — invalidate.
+        SpillMap.erase(StoredFI);
+      }
+    }
+
+    // If the instruction writes to memory but we couldn't identify it as a
+    // simple stack slot store, check MMOs for stores to tracked SpillFIs.
+    // Only invalidate what we can't identify.
+    if (MI.mayStore() && !StoredReg) {
+      bool HasUnknownStore = false;
+      for (const MachineMemOperand *MMO : MI.memoperands()) {
+        if (!MMO->isStore())
+          continue;
+        const auto *FSPV = dyn_cast_or_null<FixedStackPseudoSourceValue>(
+            MMO->getPseudoValue());
+        if (FSPV) {
+          // Known FI store — invalidate just that entry.
+          int FI = FSPV->getFrameIndex();
+          SpillMap.erase(FI);
+          SmallVector<int, 4> ToErase;
+          for (auto &[KeyFI, SE] : SpillMap) {
+            if (SE.OrigFI == FI)
+              ToErase.push_back(KeyFI);
+          }
+          for (int KeyFI : ToErase)
+            SpillMap.erase(KeyFI);
+        } else {
+          HasUnknownStore = true;
+        }
+      }
+      if (HasUnknownStore)
+        SpillMap.clear();
+    }
+
+    // Any register def (explicit or implicit) invalidates all aliases.
+    for (const MachineOperand &MO : MI.operands()) {
+      if (MO.isReg() && MO.isDef() && MO.getReg().isPhysical())
+        InvalidateReg(MO.getReg());
+    }
+
+    // --- Step 5: Track loads from stack slots ---
+    if (LoadedReg) {
+      int MemIdx = X86::getFirstAddrOperandIdx(MI);
+      if (MemIdx >= 0 && !MI.memoperands_empty()) {
+        bool ClobbersAddr = false;
+        for (int i = 0; i < X86::AddrNumOperands; ++i) {
+          const MachineOperand &MO = MI.getOperand(MemIdx + i);
+          if (MO.isReg() && MO.getReg() &&
+              MI.definesRegister(MO.getReg(), TRI)) {
+            ClobbersAddr = true;
+            break;
+          }
+        }
+        if (!ClobbersAddr) {
+          RegEntry RE;
+          for (int i = 0; i < X86::AddrNumOperands; ++i)
+            RE.MOs.push_back(MI.getOperand(MemIdx + i));
+          RE.LoadMI = &MI;
+          RE.FI = LoadedFI;
+          RE.Size = MI.memoperands().front()->getSize();
+          RegToFI[LoadedReg] = RE;
+        }
+      }
+    }
+  }
+
+  SmallPtrSet<MachineInstr *, 4> ToErase;
+  for (auto &[FI, SE] : SpillMap) {
+    // Only delete the store if ALL loads from SpillFI were rewritten.
+    if (SE.RewriteCount > 0 && SE.RewriteCount == SE.UseCount) {
+      if (SE.StoreMI)
+        ToErase.insert(SE.StoreMI);
+      // Only delete the load if its register is provably dead.
+      if (SE.LoadMI && SE.StoreMI &&
+          IsSafeToEraseLoad(SE.LoadMI, SE.StoreMI, SE.LoadReg))
+        ToErase.insert(SE.LoadMI);
+    }
+  }
+
+  for (MachineInstr *MI : ToErase) {
+    MI->eraseFromParent();
+    Changed = true;
+  }
+
+  return Changed;
+}
+
 bool X86FixupInstTuningImpl::processInstruction(
     MachineFunction &MF, MachineBasicBlock &MBB,
     MachineBasicBlock::iterator &I) {
@@ -712,6 +1003,7 @@ bool X86FixupInstTuningImpl::runOnMachineFunction(MachineFunction &MF) {
   SM = &ST->getSchedModel();
 
   for (MachineBasicBlock &MBB : MF) {
+    Changed |= processSpills(MBB, MF);
     for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ++I) {
       if (processInstruction(MF, MBB, I)) {
         ++NumInstChanges;
diff --git a/llvm/test/CodeGen/X86/fp-intrinsics.ll b/llvm/test/CodeGen/X86/fp-intrinsics.ll
index 5d69a217fb402..cdd56f32a9781 100644
--- a/llvm/test/CodeGen/X86/fp-intrinsics.ll
+++ b/llvm/test/CodeGen/X86/fp-intrinsics.ll
@@ -1080,8 +1080,6 @@ define i64 @f20s64(double %x) #0 {
 ; X86-SSE:       # %bb.0: # %entry
 ; X86-SSE-NEXT:    subl $20, %esp
 ; X86-SSE-NEXT:    .cfi_def_cfa_offset 24
-; X86-SSE-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
-; X86-SSE-NEXT:    movsd %xmm0, {{[0-9]+}}(%esp)
 ; X86-SSE-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-SSE-NEXT:    wait
 ; X86-SSE-NEXT:    fnstcw {{[0-9]+}}(%esp)
@@ -2076,9 +2074,7 @@ define double @sifdi(i32 %x) #0 {
 ; X87:       # %bb.0: # %entry
 ; X87-NEXT:    pushl %eax
 ; X87-NEXT:    .cfi_def_cfa_offset 8
-; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X87-NEXT:    movl %eax, (%esp)
-; X87-NEXT:    fildl (%esp)
+; X87-NEXT:    fildl {{[0-9]+}}(%esp)
 ; X87-NEXT:    wait
 ; X87-NEXT:    popl %eax
 ; X87-NEXT:    .cfi_def_cfa_offset 4
@@ -2205,9 +2201,7 @@ define float @siffi(i32 %x) #0 {
 ; X87:       # %bb.0: # %entry
 ; X87-NEXT:    pushl %eax
 ; X87-NEXT:    .cfi_def_cfa_offset 8
-; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X87-NEXT:    movl %eax, (%esp)
-; X87-NEXT:    fildl (%esp)
+; X87-NEXT:    fildl {{[0-9]+}}(%esp)
 ; X87-NEXT:    wait
 ; X87-NEXT:    popl %eax
 ; X87-NEXT:    .cfi_def_cfa_offset 4
@@ -2484,10 +2478,7 @@ define double @uifdl(i64 %x) #0 {
 ; X86-SSE-NEXT:    fildll {{[0-9]+}}(%esp)
 ; X86-SSE-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}(,%eax,4)
 ; X86-SSE-NEXT:    fstpl {{[0-9]+}}(%esp)
-; X86-SSE-NEXT:    wait
-; X86-SSE-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
-; X86-SSE-NEXT:    movsd %xmm0, (%esp)
-; X86-SSE-NEXT:    fldl (%esp)
+; X86-SSE-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-SSE-NEXT:    wait
 ; X86-SSE-NEXT:    addl $28, %esp
 ; X86-SSE-NEXT:    .cfi_def_cfa_offset 4
@@ -2706,10 +2697,7 @@ define float @uiffl(i64 %x) #0 {
 ; X86-SSE-NEXT:    fildll {{[0-9]+}}(%esp)
 ; X86-SSE-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}(,%eax,4)
 ; X86-SSE-NEXT:    fstps {{[0-9]+}}(%esp)
-; X86-SSE-NEXT:    wait
-; X86-SSE-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
-; X86-SSE-NEXT:    movss %xmm0, (%esp)
-; X86-SSE-NEXT:    flds (%esp)
+; X86-SSE-NEXT:    flds {{[0-9]+}}(%esp)
 ; X86-SSE-NEXT:    wait
 ; X86-SSE-NEXT:    addl $20, %esp
 ; X86-SSE-NEXT:    .cfi_def_cfa_offset 4
diff --git a/llvm/test/CodeGen/X86/fp-strict-scalar-inttofp.ll b/llvm/test/CodeGen/X86/fp-strict-scalar-inttofp.ll
index f0aa3827ce937..17aa07683b4f3 100644
--- a/llvm/test/CodeGen/X86/fp-strict-scalar-inttofp.ll
+++ b/llvm/test/CodeGen/X86/fp-strict-scalar-inttofp.ll
@@ -249,9 +249,7 @@ define float @sitofp_i32tof32(i32 %x) #0 {
 ; X87:       # %bb.0:
 ; X87-NEXT:    pushl %eax
 ; X87-NEXT:    .cfi_def_cfa_offset 8
-; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X87-NEXT:    movl %eax, (%esp)
-; X87-NEXT:    fildl (%esp)
+; X87-NEXT:    fildl {{[0-9]+}}(%esp)
 ; X87-NEXT:    wait
 ; X87-NEXT:    popl %eax
 ; X87-NEXT:    .cfi_def_cfa_offset 4
@@ -595,10 +593,7 @@ define float @uitofp_i64tof32(i64 %x) #0 {
 ; SSE-X86-NEXT:    fildll {{[0-9]+}}(%esp)
 ; SSE-X86-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}(,%eax,4)
 ; SSE-X86-NEXT:    fstps {{[0-9]+}}(%esp)
-; SSE-X86-NEXT:    wait
-; SSE-X86-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
-; SSE-X86-NEXT:    movss %xmm0, (%esp)
-; SSE-X86-NEXT:    flds (%esp)
+; SSE-X86-NEXT:    flds {{[0-9]+}}(%esp)
 ; SSE-X86-NEXT:    wait
 ; SSE-X86-NEXT:    movl %ebp, %esp
 ; SSE-X86-NEXT:    popl %ebp
@@ -637,10 +632,7 @@ define float @uitofp_i64tof32(i64 %x) #0 {
 ; AVX-X86-NEXT:    fildll {{[0-9]+}}(%esp)
 ; AVX-X86-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}(,%eax,4)
 ; AVX-X86-NEXT:    fstps {{[0-9]+}}(%esp)
-; AVX-X86-NEXT:    wait
-; AVX-X86-NEXT:    vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero
-; AVX-X86-NEXT:    vmovss %xmm0, (%esp)
-; AVX-X86-NEXT:    flds (%esp)
+; AVX-X86-NEXT:    flds {{[0-9]+}}(%esp)
 ; AVX-X86-NEXT:    wait
 ; AVX-X86-NEXT:    movl %ebp, %esp
 ; AVX-X86-NEXT:    popl %ebp
@@ -884,9 +876,7 @@ define double @sitofp_i32tof64(i32 %x) #0 {
 ; X87:       # %bb.0:
 ; X87-NEXT:    pushl %eax
 ; X87-NEXT:    .cfi_def_cfa_offset 8
-; X87-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X87-NEXT:    movl %eax, (%esp)
-; X87-NEXT:    fildl (%esp)
+; X87-NEXT:    fildl {{[0-9]+}}(%esp)
 ; X87-NEXT:    wait
 ; X87-NEXT:    popl %eax
 ; X87-NEXT:    .cfi_def_cfa_offset 4
@@ -1284,10 +1274,7 @@ define double @uitofp_i64tof64(i64 %x) #0 {
 ; SSE-X86-NEXT:    fildll {{[0-9]+}}(%esp)
 ; SSE-X86-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}(,%eax,4)
 ; SSE-X86-NEXT:    fstpl {{[0-9]+}}(%esp)
-; SSE-X86-NEXT:    wait
-; SSE-X86-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
-; SSE-X86-NEXT:    movsd %xmm0, (%esp)
-; SSE-X86-NEXT:    fldl (%esp)
+; SSE-X86-NEXT:    fldl {{[0-9]+}}(%esp)
 ; SSE-X86-NEXT:    wait
 ; SSE-X86-NEXT:    movl %ebp, %esp
 ; SSE-X86-NEXT:    popl %ebp
@@ -1326,10 +1313,7 @@ define double @uitofp_i64tof64(i64 %x) #0 {
 ; AVX-X86-NEXT:    fildll {{[0-9]+}}(%esp)
 ; AVX-X86-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}(,%eax,4)
 ; AVX-X86-NEXT:    fstpl {{[0-9]+}}(%esp)
-; AVX-X86-NEXT:    wait
-; AVX-X86-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero
-; AVX-X86-NEXT:    vmovsd %xmm0, (%esp)
-; AVX-X86-NEXT:    fldl (%esp)
+; AVX-X86-NEXT:    fldl {{[0-9]+}}(%esp)
 ; AVX-X86-NEXT:    wait
 ; AVX-X86-NEXT:    movl %ebp, %esp
 ; AVX-X86-NEXT:    popl %ebp
diff --git a/llvm/test/CodeGen/X86/fp80-strict-scalar.ll b/llvm/test/CodeGen/X86/fp80-strict-scalar.ll
index b9b1ae60d479e..6276c36677d59 100644
--- a/llvm/test/CodeGen/X86/fp80-strict-scalar.ll
+++ b/llvm/test/CodeGen/X86/fp80-strict-scalar.ll
@@ -737,9 +737,7 @@ define x86_fp80 @sint32_to_fp80(i32 %x) #0 {
 ; X86:       # %bb.0:
 ; X86-NEXT:    pushl %eax
 ; X86-NEXT:    .cfi_def_cfa_offset 8
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    movl %eax, (%esp)
-; X86-NEXT:    fildl (%esp)
+; X86-NEXT:    fildl {{[0-9]+}}(%esp)
 ; X86-NEXT:    wait
 ; X86-NEXT:    popl %eax
 ; X86-NEXT:    .cfi_def_cfa_offset 4
@@ -866,10 +864,8 @@ define x86_fp80 @uint32_to_fp80(i32 %x) #0 {
 ; X86-NEXT:    .cfi_def_cfa_register %ebp
 ; X86-NEXT:    andl $-8, %esp
 ; X86-NEXT:    subl $8, %esp
-; X86-NEXT:    movl 8(%ebp), %eax
-; X86-NEXT:    movl %eax, (%esp)
 ; X86-NEXT:    movl $0, {{[0-9]+}}(%esp)
-; X86-NEXT:    fildll (%esp)
+; X86-NEXT:    fildll 8(%ebp)
 ; X86-NEXT:    wait
 ; X86-NEXT:    movl %ebp, %esp
 ; X86-NEXT:    popl %ebp
@@ -899,12 +895,10 @@ define x86_fp80 @uint64_to_fp80(i64 %x) #0 {
 ; X86-NEXT:    .cfi_def_cfa_register %ebp
 ; X86-NEXT:    andl $-8, %esp
 ; X86-NEXT:    subl $8, %esp
-; X86-NEXT:    movl 8(%ebp), %eax
 ; X86-NEXT:    movl 12(%ebp), %ecx
 ; X86-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
-; X86-NEXT:    movl %eax, (%esp)
 ; X86-NEXT:    shrl $31, %ecx
-; X86-NEXT:    fildll (%esp)
+; X86-NEXT:    fildll 8(%ebp)
 ; X86-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}(,%ecx,4)
 ; X86-NEXT:    wait
 ; X86-NEXT:    movl %ebp, %esp
diff --git a/llvm/test/CodeGen/X86/ftrunc.ll b/llvm/test/CodeGen/X86/ftrunc.ll
index 1ab9040a2810f..599cea901196f 100644
--- a/llvm/test/CodeGen/X86/ftrunc.ll
+++ b/llvm/test/CodeGen/X86/ftrunc.ll
@@ -513,7 +513,7 @@ define double @trunc_signed_f64_no_fast_math(double %x) nounwind {
 ; X86-AVX1-NEXT:    subl $24, %esp
 ; X86-AVX1-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero
 ; X86-AVX1-NEXT:    vmovsd %xmm0, (%esp)
-; X86-AVX1-NEXT:    fldl (%esp)
+; X86-AVX1-NEXT:    fldl 8(%ebp)
 ; X86-AVX1-NEXT:    fisttpll (%esp)
 ; X86-AVX1-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero
 ; X86-AVX1-NEXT:    vmovlps %xmm0, {{[0-9]+}}(%esp)
@@ -748,7 +748,7 @@ define double @trunc_signed_f64_disable_via_intrinsic(double %x) #0 {
 ; X86-AVX1-NEXT:    subl $32, %esp
 ; X86-AVX1-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero
 ; X86-AVX1-NEXT:    vmovsd %xmm0, (%esp)
-; X86-AVX1-NEXT:    fldl (%esp)
+; X86-AVX1-NEXT:    fldl 8(%ebp)
 ; X86-AVX1-NEXT:    fisttpll (%esp)
 ; X86-AVX1-NEXT:    xorl %eax, %eax
 ; X86-AVX1-NEXT:    vucomisd {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0
diff --git a/llvm/test/CodeGen/X86/isel-fptrunc-fpext.ll b/llvm/test/CodeGen/X86/isel-fptrunc-fpext.ll
index 7f58fffe2b5ed..c1da2d6e73be6 100644
--- a/llvm/test/CodeGen/X86/isel-fptrunc-fpext.ll
+++ b/llvm/test/CodeGen/X86/isel-fptrunc-fpext.ll
@@ -33,9 +33,7 @@ define double @fpext_float_to_double(float %f) nounwind {
 ; 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:    flds {{[0-9]+}}(%esp)
 ; GLOBAL-X86-NEXT:    popl %eax
 ; GLOBAL-X86-NEXT:    retl
   %1 = fpext float %f to double
@@ -63,9 +61,7 @@ define x86_fp80 @fpext_float_to_x86_fp80(float %f) nounwind {
 ; 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:    flds {{[0-9]+}}(%esp)
 ; GLOBAL-X86-NEXT:    popl %eax
 ; GLOBAL-X86-NEXT:    retl
 ;
diff --git a/llvm/test/CodeGen/X86/scalar-fp-to-i64.ll b/llvm/test/CodeGen/X86/scalar-fp-to-i64.ll
index 3287869f2c601..cec58ca87d63d 100644
--- a/llvm/test/CodeGen/X86/scalar-fp-to-i64.ll
+++ b/llvm/test/CodeGen/X86/scalar-fp-to-i64.ll
@@ -339,7 +339,7 @@ define i64 @f_to_s64(float %a) nounwind {
 ; X86-AVX512F-WIN-NEXT:    subl $8, %esp
 ; X86-AVX512F-WIN-NEXT:    vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero
 ; X86-AVX512F-WIN-NEXT:    vmovss %xmm0, (%esp)
-; X86-AVX512F-WIN-NEXT:    flds (%esp)
+; X86-AVX512F-WIN-NEXT:    flds 8(%ebp)
 ; X86-AVX512F-WIN-NEXT:    fisttpll (%esp)
 ; X86-AVX512F-WIN-NEXT:    movl (%esp), %eax
 ; X86-AVX512F-WIN-NEXT:    movl {{[0-9]+}}(%esp), %edx
@@ -352,7 +352,7 @@ define i64 @f_to_s64(float %a) nounwind {
 ; X86-AVX512F-LIN-NEXT:    subl $12, %esp
 ; X86-AVX512F-LIN-NEXT:    vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero
 ; X86-AVX512F-LIN-NEXT:    vmovss %xmm0, (%esp)
-; X86-AVX512F-LIN-NEXT:    flds (%esp)
+; X86-AVX512F-LIN-NEXT:    flds {{[0-9]+}}(%esp)
 ; X86-AVX512F-LIN-NEXT:    fisttpll (%esp)
 ; X86-AVX512F-LIN-NEXT:    movl (%esp), %eax
 ; X86-AVX512F-LIN-NEXT:    movl {{[0-9]+}}(%esp), %edx
@@ -367,7 +367,7 @@ define i64 @f_to_s64(float %a) nounwind {
 ; X86-SSE3-WIN-NEXT:    subl $8, %esp
 ; X86-SSE3-WIN-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
 ; X86-SSE3-WIN-NEXT:    movss %xmm0, (%esp)
-; X86-SSE3-WIN-NEXT:    flds (%esp)
+; X86-SSE3-WIN-NEXT:    flds 8(%ebp)
 ; X86-SSE3-WIN-NEXT:    fisttpll (%esp)
 ; X86-SSE3-WIN-NEXT:    movl (%esp), %eax
 ; X86-SSE3-WIN-NEXT:    movl {{[0-9]+}}(%esp), %edx
@@ -380,7 +380,7 @@ define i64 @f_to_s64(float %a) nounwind {
 ; X86-SSE3-LIN-NEXT:    subl $12, %esp
 ; X86-SSE3-LIN-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
 ; X86-SSE3-LIN-NEXT:    movss %xmm0, (%esp)
-; X86-SSE3-LIN-NEXT:    flds (%esp)
+; X86-SSE3-LIN-NEXT:    flds {{[0-9]+}}(%esp)
 ; X86-SSE3-LIN-NEXT:    fisttpll (%esp)
 ; X86-SSE3-LIN-NEXT:    movl (%esp), %eax
 ; X86-SSE3-LIN-NEXT:    movl {{[0-9]+}}(%esp), %edx
@@ -398,9 +398,7 @@ define i64 @f_to_s64(float %a) nounwind {
 ; X86-SSE2-WIN-NEXT:    movl %esp, %ebp
 ; X86-SSE2-WIN-NEXT:    andl $-8, %esp
 ; X86-SSE2-WIN-NEXT:    subl $16, %esp
-; X86-SSE2-WIN-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
-; X86-SSE2-WIN-NEXT:    movss %xmm0, {{[0-9]+}}(%esp)
-; X86-SSE2-WIN-NEXT:    flds {{[0-9]+}}(%esp)
+; X86-SSE2-WIN-NEXT:    flds 8(%ebp)
 ; X86-SSE2-WIN-NEXT:    fnstcw {{[0-9]+}}(%esp)
 ; X86-SSE2-WIN-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
 ; X86-SSE2-WIN-NEXT:    orl $3072, %eax # imm = 0xC00
@@ -408,7 +406,7 @@ define i64 @f_to_s64(float %a) nounwind {
 ; X86-SSE2-WIN-NEXT:    fldcw {{[0-9]+}}(%esp)
 ; X86-SSE2-WIN-NEXT:    fistpll {{[0-9]+}}(%esp)
 ; X86-SSE2-WIN-NEXT:    fldcw {{[0-9]+}}(%esp)
-; X86-SSE2-WIN-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-SSE2-WIN-NEXT:    movl 8(%ebp), %eax
 ; X86-SSE2-WIN-NEXT:    movl {{[0-9]+}}(%esp), %edx
 ; X86-SSE2-WIN-NEXT:    movl %ebp, %esp
 ; X86-SSE2-WIN-NEXT:    popl %ebp
@@ -417,8 +415,6 @@ define i64 @f_to_s64(float %a) nounwind {
 ; X86-SSE2-LIN-LABEL: f_to_s64:
 ; X86-SSE2-LIN:       # %bb.0:
 ; X86-SSE2-LIN-NEXT:    subl $20, %esp
-; X86-SSE2-LIN-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
-; X86-SSE2-LIN-NEXT:    movss %xmm0, {{[0-9]+}}(%esp)
 ; X86-SSE2-LIN-NEXT:    flds {{[0-9]+}}(%esp)
 ; X86-SSE2-LIN-NEXT:    fnstcw {{[0-9]+}}(%esp)
 ; X86-SSE2-LIN-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
@@ -772,7 +768,7 @@ define i64 @d_to_s64(double %a) nounwind {
 ; X86-AVX512F-WIN-NEXT:    subl $8, %esp
 ; X86-AVX512F-WIN-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero
 ; X86-AVX512F-WIN-NEXT:    vmovsd %xmm0, (%esp)
-; X86-AVX512F-WIN-NEXT:    fldl (%esp)
+; X86-AVX512F-WIN-NEXT:    fldl 8(%ebp)
 ; X86-AVX512F-WIN-NEXT:    fisttpll (%esp)
 ; X86-AVX512F-WIN-NEXT:    movl (%esp), %eax
 ; X86-AVX512F-WIN-NEXT:    movl {{[0-9]+}}(%esp), %edx
@@ -785,7 +781,7 @@ define i64 @d_to_s64(double %a) nounwind {
 ; X86-AVX512F-LIN-NEXT:    subl $12, %esp
 ; X86-AVX512F-LIN-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero
 ; X86-AVX512F-LIN-NEXT:    vmovsd %xmm0, (%esp)
-; X86-AVX512F-LIN-NEXT:    fldl (%esp)
+; X86-AVX512F-LIN-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-AVX512F-LIN-NEXT:    fisttpll (%esp)
 ; X86-AVX512F-LIN-NEXT:    movl (%esp), %eax
 ; X86-AVX512F-LIN-NEXT:    movl {{[0-9]+}}(%esp), %edx
@@ -800,7 +796,7 @@ define i64 @d_to_s64(double %a) nounwind {
 ; X86-SSE3-WIN-NEXT:    subl $8, %esp
 ; X86-SSE3-WIN-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
 ; X86-SSE3-WIN-NEXT:    movsd %xmm0, (%esp)
-; X86-SSE3-WIN-NEXT:    fldl (%esp)
+; X86-SSE3-WIN-NEXT:    fldl 8(%ebp)
 ; X86-SSE3-WIN-NEXT:    fisttpll (%esp)
 ; X86-SSE3-WIN-NEXT:    movl (%esp), %eax
 ; X86-SSE3-WIN-NEXT:    movl {{[0-9]+}}(%esp), %edx
@@ -813,7 +809,7 @@ define i64 @d_to_s64(double %a) nounwind {
 ; X86-SSE3-LIN-NEXT:    subl $12, %esp
 ; X86-SSE3-LIN-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
 ; X86-SSE3-LIN-NEXT:    movsd %xmm0, (%esp)
-; X86-SSE3-LIN-NEXT:    fldl (%esp)
+; X86-SSE3-LIN-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-SSE3-LIN-NEXT:    fisttpll (%esp)
 ; X86-SSE3-LIN-NEXT:    movl (%esp), %eax
 ; X86-SSE3-LIN-NEXT:    movl {{[0-9]+}}(%esp), %edx
@@ -831,9 +827,7 @@ define i64 @d_to_s64(double %a) nounwind {
 ; X86-SSE2-WIN-NEXT:    movl %esp, %ebp
 ; X86-SSE2-WIN-NEXT:    andl $-8, %esp
 ; X86-SSE2-WIN-NEXT:    subl $16, %esp
-; X86-SSE2-WIN-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
-; X86-SSE2-WIN-NEXT:    movsd %xmm0, {{[0-9]+}}(%esp)
-; X86-SSE2-WIN-NEXT:    fldl {{[0-9]+}}(%esp)
+; X86-SSE2-WIN-NEXT:    fldl 8(%ebp)
 ; X86-SSE2-WIN-NEXT:    fnstcw {{[0-9]+}}(%esp)
 ; X86-SSE2-WIN-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
 ; X86-SSE2-WIN-NEXT:    orl $3072, %eax # imm = 0xC00
@@ -850,8 +844,6 @@ define i64 @d_to_s64(double %a) nounwind {
 ; X86-SSE2-LIN-LABEL: d_to_s64:
 ; X86-SSE2-LIN:       # %bb.0:
 ; X86-SSE2-LIN-NEXT:    subl $20, %esp
-; X86-SSE2-LIN-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
-; X86-SSE2-LIN-NEXT:    movsd %xmm0, {{[0-9]+}}(%esp)
 ; X86-SSE2-LIN-NEXT:    fldl {{[0-9]+}}(%esp)
 ; X86-SSE2-LIN-NEXT:    fnstcw {{[0-9]+}}(%esp)
 ; X86-SSE2-LIN-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
diff --git a/llvm/test/CodeGen/X86/scalar-int-to-fp.ll b/llvm/test/CodeGen/X86/scalar-int-to-fp.ll
index 43c1a84f7cd6c..3df35d2a1fb1d 100644
--- a/llvm/test/CodeGen/X86/scalar-int-to-fp.ll
+++ b/llvm/test/CodeGen/X86/scalar-int-to-fp.ll
@@ -112,9 +112,7 @@ define float @s32_to_f(i32 %a) nounwind {
 ; X87-LABEL: s32_to_f:
 ; 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:    fildl {{[0-9]+}}(%esp)
 ; X87-NEXT:    popl %eax
 ; X87-NEXT:    retl
   %r = sitofp i32 %a to float
@@ -232,18 +230,14 @@ 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:    movl {{[0-9]+}}(%esp), %eax
-; SSE1_32-NEXT:    movl %eax, (%esp)
-; SSE1_32-NEXT:    fildl (%esp)
+; SSE1_32-NEXT:    fildl {{[0-9]+}}(%esp)
 ; SSE1_32-NEXT:    popl %eax
 ; SSE1_32-NEXT:    retl
 ;
 ; X87-LABEL: s32_to_d:
 ; 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:    fildl {{[0-9]+}}(%esp)
 ; X87-NEXT:    popl %eax
 ; X87-NEXT:    retl
   %r = sitofp i32 %a to double
@@ -279,9 +273,7 @@ define x86_fp80 @s32_to_x(i32 %a) nounwind {
 ; CHECK32-LABEL: s32_to_x:
 ; CHECK32:       # %bb.0:
 ; CHECK32-NEXT:    pushl %eax
-; CHECK32-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; CHECK32-NEXT:    movl %eax, (%esp)
-; CHECK32-NEXT:    fildl (%esp)
+; CHECK32-NEXT:    fildl {{[0-9]+}}(%esp)
 ; CHECK32-NEXT:    popl %eax
 ; CHECK32-NEXT:    retl
 ;
@@ -335,9 +327,7 @@ define float @u64_to_f(i64 %a) nounwind {
 ; AVX512F_32-NEXT:    fildll {{[0-9]+}}(%esp)
 ; AVX512F_32-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}(,%eax,4)
 ; AVX512F_32-NEXT:    fstps {{[0-9]+}}(%esp)
-; AVX512F_32-NEXT:    vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero
-; AVX512F_32-NEXT:    vmovss %xmm0, (%esp)
-; AVX512F_32-NEXT:    flds (%esp)
+; AVX512F_32-NEXT:    flds {{[0-9]+}}(%esp)
 ; AVX512F_32-NEXT:    movl %ebp, %esp
 ; AVX512F_32-NEXT:    popl %ebp
 ; AVX512F_32-NEXT:    retl
@@ -355,9 +345,7 @@ define float @u64_to_f(i64 %a) nounwind {
 ; SSE2_32-NEXT:    fildll {{[0-9]+}}(%esp)
 ; SSE2_32-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}(,%eax,4)
 ; SSE2_32-NEXT:    fstps {{[0-9]+}}(%esp)
-; SSE2_32-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
-; SSE2_32-NEXT:    movss %xmm0, (%esp)
-; SSE2_32-NEXT:    flds (%esp)
+; SSE2_32-NEXT:    flds {{[0-9]+}}(%esp)
 ; SSE2_32-NEXT:    movl %ebp, %esp
 ; SSE2_32-NEXT:    popl %ebp
 ; SSE2_32-NEXT:    retl
@@ -394,9 +382,7 @@ define float @u64_to_f(i64 %a) nounwind {
 ; SSE1_32-NEXT:    fildll {{[0-9]+}}(%esp)
 ; SSE1_32-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}(,%ecx,4)
 ; SSE1_32-NEXT:    fstps {{[0-9]+}}(%esp)
-; SSE1_32-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
-; SSE1_32-NEXT:    movss %xmm0, (%esp)
-; SSE1_32-NEXT:    flds (%esp)
+; SSE1_32-NEXT:    flds {{[0-9]+}}(%esp)
 ; SSE1_32-NEXT:    movl %ebp, %esp
 ; SSE1_32-NEXT:    popl %ebp
 ; SSE1_32-NEXT:    retl
diff --git a/llvm/test/CodeGen/X86/x87-inout-bounce.ll b/llvm/test/CodeGen/X86/x87-inout-bounce.ll
index 161ca2c1742b1..d07d40dd7cc8f 100644
--- a/llvm/test/CodeGen/X86/x87-inout-bounce.ll
+++ b/llvm/test/CodeGen/X86/x87-inout-bounce.ll
@@ -28,11 +28,9 @@ define float @example_float() {
 ; CHECK-NEXT:    .cfi_def_cfa_offset 32
 ; CHECK-NEXT:    calll returns_float at PLT
 ; CHECK-NEXT:    fstps {{[0-9]+}}(%esp)
-; CHECK-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
-; CHECK-NEXT:    movss %xmm0, (%esp) # 4-byte Spill
 ; CHECK-NEXT:    calll returns_float at PLT
 ; CHECK-NEXT:    fstps {{[0-9]+}}(%esp)
-; CHECK-NEXT:    movss (%esp), %xmm0 # 4-byte Reload
+; CHECK-NEXT:    movss {{[-0-9]+}}(%e{{[sb]}}p), %xmm0 # 4-byte Reload
 ; CHECK-NEXT:    # xmm0 = mem[0],zero,zero,zero
 ; CHECK-NEXT:    addss {{[0-9]+}}(%esp), %xmm0
 ; CHECK-NEXT:    movss %xmm0, (%esp) # 4-byte Spill
@@ -80,8 +78,6 @@ define x86_fp80 @testC() {
 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
 ; CHECK-NEXT:    calll returns_long_double at PLT
 ; CHECK-NEXT:    fstps {{[0-9]+}}(%esp)
-; CHECK-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
-; CHECK-NEXT:    movss %xmm0, {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    flds {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    addl $12, %esp
 ; CHECK-NEXT:    .cfi_def_cfa_offset 4
@@ -92,3 +88,28 @@ entry:
   %conv1 = fpext float %conv to x86_fp80
   ret x86_fp80 %conv1
 }
+
+declare float @returns_x87_float()
+
+define float @testA() {
+; CHECK-LABEL: testA:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    subl $28, %esp
+; CHECK-NEXT:    .cfi_def_cfa_offset 32
+; CHECK-NEXT:    calll returns_x87_float at PLT
+; CHECK-NEXT:    fstps {{[0-9]+}}(%esp)
+; CHECK-NEXT:    calll returns_x87_float at PLT
+; CHECK-NEXT:    fstps {{[0-9]+}}(%esp)
+; CHECK-NEXT:    movss {{[-0-9]+}}(%e{{[sb]}}p), %xmm0 # 4-byte Reload
+; CHECK-NEXT:    # xmm0 = mem[0],zero,zero,zero
+; CHECK-NEXT:    addss {{[0-9]+}}(%esp), %xmm0
+; CHECK-NEXT:    movss %xmm0, {{[0-9]+}}(%esp)
+; CHECK-NEXT:    flds {{[0-9]+}}(%esp)
+; CHECK-NEXT:    addl $28, %esp
+; CHECK-NEXT:    .cfi_def_cfa_offset 4
+; CHECK-NEXT:    retl
+  %1 = call float @returns_x87_float()
+  %2 = call float @returns_x87_float()
+  %3 = fadd float %1, %2
+  ret float %3
+}



More information about the llvm-commits mailing list