[llvm] [X86] Fix stack temporary leaks for x87 float returns (PR #213134)

via llvm-commits llvm-commits at lists.llvm.org
Sun Aug 2 08:57:15 PDT 2026


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

>From 6e1f4c84d10cbf96af539e3685ab05eebd9ab291 Mon Sep 17 00:00:00 2001
From: AZero13 <gfunni234 at gmail.com>
Date: Thu, 30 Jul 2026 16:09:08 -0400
Subject: [PATCH 1/2] Add pre-commit test for x87 stack leak

[X86] Add pre-commit test for x87 float temporary stack leak
---
 llvm/test/CodeGen/X86/stack-coloring-x87.ll | 98 ++++++++++++++++++++
 llvm/test/CodeGen/X86/x87-stack-coloring.ll | 99 +++++++++++++++++++++
 2 files changed, 197 insertions(+)
 create mode 100644 llvm/test/CodeGen/X86/stack-coloring-x87.ll
 create mode 100644 llvm/test/CodeGen/X86/x87-stack-coloring.ll

diff --git a/llvm/test/CodeGen/X86/stack-coloring-x87.ll b/llvm/test/CodeGen/X86/stack-coloring-x87.ll
new file mode 100644
index 0000000000000..8990b810bd590
--- /dev/null
+++ b/llvm/test/CodeGen/X86/stack-coloring-x87.ll
@@ -0,0 +1,98 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=x86_64-pc-windows-msvc -O2 | FileCheck %s
+
+%struct.ByValStruct = type { [4 x i64] }
+declare void @use_byval(ptr byval(%struct.ByValStruct) %a)
+
+define void @test_byval(ptr %p1, ptr %p2, ptr %p3) {
+; CHECK-LABEL: test_byval:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    pushq %rsi
+; CHECK-NEXT:    .seh_pushreg %rsi
+; CHECK-NEXT:    pushq %rdi
+; CHECK-NEXT:    .seh_pushreg %rdi
+; CHECK-NEXT:    subq $136, %rsp
+; CHECK-NEXT:    .seh_stackalloc 136
+; CHECK-NEXT:    .seh_endprologue
+; CHECK-NEXT:    movq %r8, %rsi
+; CHECK-NEXT:    movq %rdx, %rdi
+; CHECK-NEXT:    movq 24(%rcx), %rax
+; CHECK-NEXT:    movq %rax, {{[0-9]+}}(%rsp)
+; CHECK-NEXT:    movq 16(%rcx), %rax
+; CHECK-NEXT:    movq %rax, {{[0-9]+}}(%rsp)
+; CHECK-NEXT:    movq (%rcx), %rax
+; CHECK-NEXT:    movq 8(%rcx), %rcx
+; CHECK-NEXT:    movq %rcx, {{[0-9]+}}(%rsp)
+; CHECK-NEXT:    movq %rax, {{[0-9]+}}(%rsp)
+; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; CHECK-NEXT:    callq use_byval
+; CHECK-NEXT:    movq 24(%rdi), %rax
+; CHECK-NEXT:    movq %rax, {{[0-9]+}}(%rsp)
+; CHECK-NEXT:    movq 16(%rdi), %rax
+; CHECK-NEXT:    movq %rax, {{[0-9]+}}(%rsp)
+; CHECK-NEXT:    movq (%rdi), %rax
+; CHECK-NEXT:    movq 8(%rdi), %rcx
+; CHECK-NEXT:    movq %rcx, {{[0-9]+}}(%rsp)
+; CHECK-NEXT:    movq %rax, {{[0-9]+}}(%rsp)
+; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; CHECK-NEXT:    callq use_byval
+; CHECK-NEXT:    movq 24(%rsi), %rax
+; CHECK-NEXT:    movq %rax, {{[0-9]+}}(%rsp)
+; CHECK-NEXT:    movq 16(%rsi), %rax
+; CHECK-NEXT:    movq %rax, {{[0-9]+}}(%rsp)
+; CHECK-NEXT:    movq (%rsi), %rax
+; CHECK-NEXT:    movq 8(%rsi), %rcx
+; CHECK-NEXT:    movq %rcx, {{[0-9]+}}(%rsp)
+; CHECK-NEXT:    movq %rax, {{[0-9]+}}(%rsp)
+; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; CHECK-NEXT:    callq use_byval
+; CHECK-NEXT:    nop
+; CHECK-NEXT:    .seh_startepilogue
+; CHECK-NEXT:    addq $136, %rsp
+; CHECK-NEXT:    popq %rdi
+; CHECK-NEXT:    popq %rsi
+; CHECK-NEXT:    .seh_endepilogue
+; CHECK-NEXT:    retq
+; CHECK-NEXT:    .seh_endproc
+entry:
+  call void @use_byval(ptr byval(%struct.ByValStruct) %p1)
+  call void @use_byval(ptr byval(%struct.ByValStruct) %p2)
+  call void @use_byval(ptr byval(%struct.ByValStruct) %p3)
+  ret void
+}
+
+declare void @use_f80(x86_fp80)
+define void @test_f80(x86_fp80 %p1, x86_fp80 %p2, x86_fp80 %p3) {
+; CHECK-LABEL: test_f80:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    subq $104, %rsp
+; CHECK-NEXT:    .seh_stackalloc 104
+; CHECK-NEXT:    .seh_endprologue
+; CHECK-NEXT:    fldt (%r8)
+; CHECK-NEXT:    fstpt {{[-0-9]+}}(%r{{[sb]}}p) # 10-byte Folded Spill
+; CHECK-NEXT:    fldt (%rdx)
+; CHECK-NEXT:    fstpt {{[-0-9]+}}(%r{{[sb]}}p) # 10-byte Folded Spill
+; CHECK-NEXT:    fldt (%rcx)
+; CHECK-NEXT:    fstpt {{[0-9]+}}(%rsp)
+; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; CHECK-NEXT:    callq use_f80
+; CHECK-NEXT:    fldt {{[-0-9]+}}(%r{{[sb]}}p) # 10-byte Folded Reload
+; CHECK-NEXT:    fstpt {{[0-9]+}}(%rsp)
+; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; CHECK-NEXT:    callq use_f80
+; CHECK-NEXT:    fldt {{[-0-9]+}}(%r{{[sb]}}p) # 10-byte Folded Reload
+; CHECK-NEXT:    fstpt {{[0-9]+}}(%rsp)
+; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; CHECK-NEXT:    callq use_f80
+; CHECK-NEXT:    nop
+; CHECK-NEXT:    .seh_startepilogue
+; CHECK-NEXT:    addq $104, %rsp
+; CHECK-NEXT:    .seh_endepilogue
+; CHECK-NEXT:    retq
+; CHECK-NEXT:    .seh_endproc
+entry:
+  call void @use_f80(x86_fp80 %p1)
+  call void @use_f80(x86_fp80 %p2)
+  call void @use_f80(x86_fp80 %p3)
+  ret void
+}
diff --git a/llvm/test/CodeGen/X86/x87-stack-coloring.ll b/llvm/test/CodeGen/X86/x87-stack-coloring.ll
new file mode 100644
index 0000000000000..eeca372cf3ac5
--- /dev/null
+++ b/llvm/test/CodeGen/X86/x87-stack-coloring.ll
@@ -0,0 +1,99 @@
+; 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
+
+; ModuleID = 'example_big.c'
+source_filename = "example_big.c"
+target datalayout = "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:128-f64:32:64-f80:32-n8:16:32-S128"
+target triple = "i386-unknown-linux-gnu"
+
+; Function Attrs: noinline nounwind uwtable
+define dso_local float @returns_float() local_unnamed_addr #0 {
+; CHECK-LABEL: returns_float:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    subl $44, %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 = tail call i32 @rand() #3
+  %conv = sitofp i32 %call to float
+  ret float %conv
+}
+
+declare i32 @rand() local_unnamed_addr #1
+
+; Function Attrs: nounwind uwtable
+define dso_local float @example() local_unnamed_addr #2 {
+; CHECK-LABEL: example:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    subl $44, %esp
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    calll returns_float
+; CHECK-NEXT:    fstps {{[0-9]+}}(%esp)
+; CHECK-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
+; CHECK-NEXT:    movss %xmm0, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    calll returns_float
+; 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]+}}(%e{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    calll returns_float
+; 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]+}}(%e{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    calll returns_float
+; 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]+}}(%e{{[sb]}}p) # 4-byte Spill
+; CHECK-NEXT:    calll returns_float
+; 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 $12, %esp
+; CHECK-NEXT:    .cfi_def_cfa_offset 4
+; CHECK-NEXT:    retl
+entry:
+  %call = tail call float @returns_float()
+  %call1 = tail call float @returns_float()
+  %add = fadd float %call, %call1
+  %call2 = tail call float @returns_float()
+  %add3 = fadd float %add, %call2
+  %call4 = tail call float @returns_float()
+  %add5 = fadd float %add3, %call4
+  %call6 = tail call float @returns_float()
+  %add7 = fadd float %add5, %call6
+  ret float %add7
+}
+
+attributes #0 = { noinline nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="pentium4" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
+attributes #1 = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="pentium4" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
+attributes #2 = { nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="pentium4" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
+attributes #3 = { nounwind }
+
+!llvm.module.flags = !{!0, !1, !2, !3}
+!llvm.ident = !{!4}
+!llvm.errno.tbaa = !{!5}
+
+!0 = !{i32 1, !"NumRegisterParameters", i32 0}
+!1 = !{i32 8, !"PIC Level", i32 2}
+!2 = !{i32 7, !"PIE Level", i32 2}
+!3 = !{i32 7, !"uwtable", i32 2}
+!4 = !{!"clang version 24.0.0git (https://github.com/AZero13/llvm-project.git 1b9e4c34a31ca71c2016b58ee23ee2729e3a58c3)"}
+!5 = !{!6, !7, i64 0}
+!6 = !{!"__libc_errno", !7, i64 0}
+!7 = !{!"int", !8, i64 0}
+!8 = !{!"omnipotent char", !9, i64 0}
+!9 = !{!"Simple C/C++ TBAA"}

>From 3e40a30abe66a5d5a9511de612b5ad8c9026ea3b Mon Sep 17 00:00:00 2001
From: AZero13 <gfunni234 at gmail.com>
Date: Thu, 30 Jul 2026 16:18:42 -0400
Subject: [PATCH 2/2] [X86] Fix stack temporary leaks for x87 float returns

When passing arguments indirectly (like byval structs or x87 floats), LLVM creates temporary stack slots in the backend.

Right now, these temporary stack slots leak memory across function calls.

To fix:

Add LIFETIME_START / LIFETIME_END markers around temporary argument slots in LowerCall.

Also add lifetime markers around x87 conversion scratch slots in PreprocessISelDAG to enable stack coloring for FP_ROUND/FP_EXTEND stack temporaries.

Allow StackColoring to safely merge stack slots even if they don't have a matching IR AllocaInst.

Parallelize indirect argument setup in LowerCall using MemOpChains so the instruction scheduler isn't artificially constrained.
---
 llvm/lib/CodeGen/StackColoring.cpp            | 81 +++++++++---------
 llvm/lib/Target/X86/X86ISelDAGToDAG.cpp       | 82 +++++++++++++++++--
 llvm/lib/Target/X86/X86ISelLoweringCall.cpp   | 28 +++++--
 llvm/test/CodeGen/X86/avx512-regcall-Mask.ll  | 18 ++--
 llvm/test/CodeGen/X86/fp-intrinsics.ll        | 12 +--
 .../CodeGen/X86/fp-strict-scalar-inttofp.ll   | 16 ++--
 .../test/CodeGen/X86/fp128-libcalls-strict.ll |  6 +-
 llvm/test/CodeGen/X86/fp128-libcalls.ll       | 16 ++--
 llvm/test/CodeGen/X86/half.ll                 | 12 +--
 llvm/test/CodeGen/X86/i128-fp128-abi.ll       | 24 +++---
 llvm/test/CodeGen/X86/pr3457.ll               |  4 +-
 llvm/test/CodeGen/X86/sse-intel-ocl.ll        | 20 ++---
 llvm/test/CodeGen/X86/stack-coloring-x87.ll   | 12 +--
 llvm/test/CodeGen/X86/uint64-to-float.ll      | 14 ++--
 llvm/test/CodeGen/X86/win64-byval.ll          |  6 +-
 llvm/test/CodeGen/X86/x87-stack-coloring.ll   | 70 ++++++++++++++--
 16 files changed, 279 insertions(+), 142 deletions(-)

diff --git a/llvm/lib/CodeGen/StackColoring.cpp b/llvm/lib/CodeGen/StackColoring.cpp
index ea1f33f791765..0352f4f0b220f 100644
--- a/llvm/lib/CodeGen/StackColoring.cpp
+++ b/llvm/lib/CodeGen/StackColoring.cpp
@@ -928,31 +928,6 @@ void StackColoring::remapInstructions(DenseMap<int, int> &SlotRemap) {
   for (const std::pair<int, int> &SI : SlotRemap) {
     const AllocaInst *From = MFI->getObjectAllocation(SI.first);
     const AllocaInst *To = MFI->getObjectAllocation(SI.second);
-    assert(To && From && "Invalid allocation object");
-    Allocas[From] = To;
-
-    // If From is before wo, its possible that there is a use of From between
-    // them.
-    if (From->comesBefore(To))
-      const_cast<AllocaInst *>(To)->moveBefore(
-          const_cast<AllocaInst *>(From)->getIterator());
-
-    // AA might be used later for instruction scheduling, and we need it to be
-    // able to deduce the correct aliasing releationships between pointers
-    // derived from the alloca being remapped and the target of that remapping.
-    // The only safe way, without directly informing AA about the remapping
-    // somehow, is to directly update the IR to reflect the change being made
-    // here.
-    Instruction *Inst = const_cast<AllocaInst *>(To);
-    if (From->getType() != To->getType()) {
-      BitCastInst *Cast = new BitCastInst(Inst, From->getType());
-      Cast->insertAfter(Inst->getIterator());
-      Inst = Cast;
-    }
-
-    // We keep both slots to maintain AliasAnalysis metadata later.
-    MergedAllocas.insert(From);
-    MergedAllocas.insert(To);
 
     // Transfer the stack protector layout tag, but make sure that SSPLK_AddrOf
     // does not overwrite SSPLK_SmallArray or SSPLK_LargeArray, and make sure
@@ -966,21 +941,49 @@ void StackColoring::remapInstructions(DenseMap<int, int> &SlotRemap) {
           FromKind != MachineFrameInfo::SSPLK_AddrOf)))
       MFI->setObjectSSPLayout(SI.second, FromKind);
 
-    // The new alloca might not be valid in a llvm.dbg.declare for this
-    // variable, so poison out the use to make the verifier happy.
-    AllocaInst *FromAI = const_cast<AllocaInst *>(From);
-    if (FromAI->isUsedByMetadata())
-      ValueAsMetadata::handleRAUW(FromAI, PoisonValue::get(FromAI->getType()));
-    for (auto &Use : FromAI->uses()) {
-      if (BitCastInst *BCI = dyn_cast<BitCastInst>(Use.get()))
-        if (BCI->isUsedByMetadata())
-          ValueAsMetadata::handleRAUW(BCI, PoisonValue::get(BCI->getType()));
-    }
+    if (From && To) {
+      Allocas[From] = To;
+
+      // If From is before wo, its possible that there is a use of From between
+      // them.
+      if (From->comesBefore(To))
+        const_cast<AllocaInst *>(To)->moveBefore(
+            const_cast<AllocaInst *>(From)->getIterator());
+
+      // AA might be used later for instruction scheduling, and we need it to be
+      // able to deduce the correct aliasing releationships between pointers
+      // derived from the alloca being remapped and the target of that
+      // remapping. The only safe way, without directly informing AA about the
+      // remapping somehow, is to directly update the IR to reflect the change
+      // being made here.
+      Instruction *Inst = const_cast<AllocaInst *>(To);
+      if (From->getType() != To->getType()) {
+        BitCastInst *Cast = new BitCastInst(Inst, From->getType());
+        Cast->insertAfter(Inst->getIterator());
+        Inst = Cast;
+      }
 
-    // Note that this will not replace uses in MMOs (which we'll update below),
-    // or anywhere else (which is why we won't delete the original
-    // instruction).
-    FromAI->replaceAllUsesWith(Inst);
+      // We keep both slots to maintain AliasAnalysis metadata later.
+      MergedAllocas.insert(From);
+      MergedAllocas.insert(To);
+
+      // The new alloca might not be valid in a llvm.dbg.declare for this
+      // variable, so poison out the use to make the verifier happy.
+      AllocaInst *FromAI = const_cast<AllocaInst *>(From);
+      if (FromAI->isUsedByMetadata())
+        ValueAsMetadata::handleRAUW(FromAI,
+                                    PoisonValue::get(FromAI->getType()));
+      for (auto &Use : FromAI->uses()) {
+        if (BitCastInst *BCI = dyn_cast<BitCastInst>(Use.get()))
+          if (BCI->isUsedByMetadata())
+            ValueAsMetadata::handleRAUW(BCI, PoisonValue::get(BCI->getType()));
+      }
+
+      // Note that this will not replace uses in MMOs (which we'll update
+      // below), or anywhere else (which is why we won't delete the original
+      // instruction).
+      FromAI->replaceAllUsesWith(Inst);
+    }
   }
 
   // Remap all instructions to the new stack slots.
diff --git a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
index d078117061677..c85608064e906 100644
--- a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
+++ b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
@@ -1457,17 +1457,53 @@ void X86DAGToDAGISel::PreprocessISelDAG() {
 
       // FIXME: optimize the case where the src/dest is a load or store?
 
-      SDValue Store = CurDAG->getTruncStore(
-          CurDAG->getEntryNode(), dl, N->getOperand(0), MemTmp, MPI, MemVT);
+      // Mark the start of the stack temporary's lifetime.
+      SDValue LifetimeStart =
+          CurDAG->getLifetimeNode(true, dl, CurDAG->getEntryNode(), SPFI);
+
+      SDValue StoreVal = N->getOperand(0);
+
+      SDValue Store = CurDAG->getTruncStore(LifetimeStart, dl, StoreVal, MemTmp,
+                                            MPI, MemVT);
       SDValue Result = CurDAG->getExtLoad(ISD::EXTLOAD, dl, DstVT, Store,
                                           MemTmp, MPI, MemVT);
 
+      // Mark the end of the stack temporary's lifetime. Anchor it before the
+      // DAG root to prevent dead code elimination and avoid placing it after
+      // terminators.
+      SDValue LifetimeEnd =
+          CurDAG->getLifetimeNode(false, dl, Result.getValue(1), SPFI);
+      SDValue Root = CurDAG->getRoot();
+      SDValue GluedNode = Root;
+      // Walk up the glued sequence to find the start of the glued chain.
+      // This prevents inserting TokenFactors between glued nodes, which would
+      // break the scheduler.
+      while (GluedNode->getNumOperands() > 0 &&
+             GluedNode->getOperand(GluedNode->getNumOperands() - 1)
+                     .getValueType() == MVT::Glue) {
+        GluedNode = GluedNode->getOperand(GluedNode->getNumOperands() - 1);
+      }
+
+      if (GluedNode.getNode() && GluedNode.getNumOperands() > 0 &&
+          GluedNode.getOperand(0).getValueType() == MVT::Other &&
+          GluedNode.getOpcode() != ISD::TokenFactor) {
+        SDValue NewChain =
+            CurDAG->getNode(ISD::TokenFactor, dl, MVT::Other,
+                            GluedNode.getOperand(0), LifetimeEnd);
+        SmallVector<SDValue, 4> Ops(GluedNode->op_begin(), GluedNode->op_end());
+        Ops[0] = NewChain;
+        CurDAG->UpdateNodeOperands(GluedNode.getNode(), Ops);
+      } else {
+        CurDAG->setRoot(CurDAG->getNode(ISD::TokenFactor, dl, MVT::Other, Root,
+                                        LifetimeEnd));
+      }
+
       // We're about to replace all uses of the FP_ROUND/FP_EXTEND with the
       // extload we created.  This will cause general havok on the dag because
       // anything below the conversion could be folded into other existing nodes.
       // To avoid invalidating 'I', back it up to the convert node.
       --I;
-      CurDAG->ReplaceAllUsesOfValueWith(SDValue(N, 0), Result);
+      CurDAG->ReplaceAllUsesWith(N, Result.getNode());
       break;
     }
 
@@ -1513,11 +1549,15 @@ void X86DAGToDAGISel::PreprocessISelDAG() {
 
       // FIXME: optimize the case where the src/dest is a load or store?
 
+      // Mark the start of the stack temporary's lifetime.
+      SDValue LifetimeStart =
+          CurDAG->getLifetimeNode(true, dl, N->getOperand(0), SPFI);
+
       //Since the operation is StrictFP, use the preexisting chain.
       SDValue Store, Result;
       if (!SrcIsSSE) {
         SDVTList VTs = CurDAG->getVTList(MVT::Other);
-        SDValue Ops[] = {N->getOperand(0), N->getOperand(1), MemTmp};
+        SDValue Ops[] = {LifetimeStart, N->getOperand(1), MemTmp};
         Store = CurDAG->getMemIntrinsicNode(X86ISD::FST, dl, VTs, Ops, MemVT,
                                             MPI, /*Align*/ std::nullopt,
                                             MachineMemOperand::MOStore);
@@ -1528,8 +1568,8 @@ void X86DAGToDAGISel::PreprocessISelDAG() {
         }
       } else {
         assert(SrcVT == MemVT && "Unexpected VT!");
-        Store = CurDAG->getStore(N->getOperand(0), dl, N->getOperand(1), MemTmp,
-                                 MPI);
+        Store =
+            CurDAG->getStore(LifetimeStart, dl, N->getOperand(1), MemTmp, MPI);
       }
 
       if (!DstIsSSE) {
@@ -1548,6 +1588,36 @@ void X86DAGToDAGISel::PreprocessISelDAG() {
         Result = CurDAG->getLoad(DstVT, dl, Store, MemTmp, MPI);
       }
 
+      // Mark the end of the stack temporary's lifetime. Anchor it before the
+      // DAG root to prevent dead code elimination and avoid placing it after
+      // terminators.
+      SDValue LifetimeEnd =
+          CurDAG->getLifetimeNode(false, dl, Result.getValue(1), SPFI);
+      SDValue Root = CurDAG->getRoot();
+      SDValue GluedNode = Root;
+      // Walk up the glued sequence to find the start of the glued chain.
+      // This prevents inserting TokenFactors between glued nodes, which would
+      // break the scheduler.
+      while (GluedNode->getNumOperands() > 0 &&
+             GluedNode->getOperand(GluedNode->getNumOperands() - 1)
+                     .getValueType() == MVT::Glue) {
+        GluedNode = GluedNode->getOperand(GluedNode->getNumOperands() - 1);
+      }
+
+      if (GluedNode.getNode() && GluedNode.getNumOperands() > 0 &&
+          GluedNode.getOperand(0).getValueType() == MVT::Other &&
+          GluedNode.getOpcode() != ISD::TokenFactor) {
+        SDValue NewChain =
+            CurDAG->getNode(ISD::TokenFactor, dl, MVT::Other,
+                            GluedNode.getOperand(0), LifetimeEnd);
+        SmallVector<SDValue, 4> Ops(GluedNode->op_begin(), GluedNode->op_end());
+        Ops[0] = NewChain;
+        CurDAG->UpdateNodeOperands(GluedNode.getNode(), Ops);
+      } else {
+        CurDAG->setRoot(CurDAG->getNode(ISD::TokenFactor, dl, MVT::Other, Root,
+                                        LifetimeEnd));
+      }
+
       // We're about to replace all uses of the FP_ROUND/FP_EXTEND with the
       // extload we created.  This will cause general havok on the dag because
       // anything below the conversion could be folded into other existing nodes.
diff --git a/llvm/lib/Target/X86/X86ISelLoweringCall.cpp b/llvm/lib/Target/X86/X86ISelLoweringCall.cpp
index 8f14198cf268b..d6da6881df0af 100644
--- a/llvm/lib/Target/X86/X86ISelLoweringCall.cpp
+++ b/llvm/lib/Target/X86/X86ISelLoweringCall.cpp
@@ -2318,7 +2318,7 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
 
   SmallVector<std::pair<Register, SDValue>, 8> RegsToPass;
   SmallVector<SDValue, 8> MemOpChains;
-
+  SmallVector<int, 8> CallTemporaries;
   // The next loop assumes that the locations are in the same order of the
   // input arguments.
   assert(isSortedByValueNo(ArgLocs) &&
@@ -2365,17 +2365,20 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
       Arg = DAG.getBitcast(RegVT, Arg);
       break;
     case CCValAssign::Indirect: {
+      SDValue SetupChain;
       if (isByVal) {
         // Memcpy the argument to a temporary stack slot to prevent
         // the caller from seeing any modifications the callee may make
         // as guaranteed by the `byval` attribute.
+        uint64_t Size = Flags.getByValSize();
         int FrameIdx = MF.getFrameInfo().CreateStackObject(
-            Flags.getByValSize(),
-            std::max(Align(16), Flags.getNonZeroByValAlign()), false);
+            Size, std::max(Align(16), Flags.getNonZeroByValAlign()), false);
+        CallTemporaries.push_back(FrameIdx);
+        SDValue LifetimeChain = DAG.getLifetimeNode(true, dl, Chain, FrameIdx);
         SDValue StackSlot =
             DAG.getFrameIndex(FrameIdx, getPointerTy(DAG.getDataLayout()));
-        Chain =
-            CreateCopyOfByValArgument(Arg, StackSlot, Chain, Flags, DAG, dl);
+        SetupChain = CreateCopyOfByValArgument(Arg, StackSlot, LifetimeChain,
+                                               Flags, DAG, dl);
         // From now on treat this as a regular pointer
         Arg = StackSlot;
         isByVal = false;
@@ -2383,11 +2386,14 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
         // Store the argument.
         SDValue SpillSlot = DAG.CreateStackTemporary(VA.getValVT());
         int FI = cast<FrameIndexSDNode>(SpillSlot)->getIndex();
-        Chain = DAG.getStore(
-            Chain, dl, Arg, SpillSlot,
+        CallTemporaries.push_back(FI);
+        SDValue LifetimeChain = DAG.getLifetimeNode(true, dl, Chain, FI);
+        SetupChain = DAG.getStore(
+            LifetimeChain, dl, Arg, SpillSlot,
             MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FI));
         Arg = SpillSlot;
       }
+      MemOpChains.push_back(SetupChain);
       break;
     }
     }
@@ -2790,8 +2796,12 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
 
   // Handle result values, copying them out of physregs into vregs that we
   // return.
-  return LowerCallResult(Chain, InGlue, CallConv, isVarArg, Ins, dl, DAG,
-                         InVals, RegMask);
+  SDValue ResChain = LowerCallResult(Chain, InGlue, CallConv, isVarArg, Ins, dl,
+                                     DAG, InVals, RegMask);
+  for (int FI : CallTemporaries) {
+    ResChain = DAG.getLifetimeNode(false, dl, ResChain, FI);
+  }
+  return ResChain;
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/llvm/test/CodeGen/X86/avx512-regcall-Mask.ll b/llvm/test/CodeGen/X86/avx512-regcall-Mask.ll
index 162f5efd78f6d..e772e1bf3fcf5 100644
--- a/llvm/test/CodeGen/X86/avx512-regcall-Mask.ll
+++ b/llvm/test/CodeGen/X86/avx512-regcall-Mask.ll
@@ -323,9 +323,9 @@ define dso_local x86_regcallcc i32 @test_argv32i1(<32 x i1> %x0, <32 x i1> %x1,
 ; WIN64-NEXT:    .seh_setframe %rbp, 128
 ; WIN64-NEXT:    .seh_endprologue
 ; WIN64-NEXT:    andq $-32, %rsp
-; WIN64-NEXT:    kmovd %edx, %k0
-; WIN64-NEXT:    kmovd %eax, %k1
-; WIN64-NEXT:    kmovd %ecx, %k2
+; WIN64-NEXT:    kmovd %eax, %k0
+; WIN64-NEXT:    kmovd %ecx, %k1
+; WIN64-NEXT:    kmovd %edx, %k2
 ; WIN64-NEXT:    vpmovm2b %k2, %zmm0
 ; WIN64-NEXT:    vmovdqa %ymm0, {{[0-9]+}}(%rsp)
 ; WIN64-NEXT:    vpmovm2b %k1, %zmm0
@@ -549,9 +549,9 @@ define dso_local x86_regcallcc i16 @test_argv16i1(<16 x i1> %x0, <16 x i1> %x1,
 ; WIN64-NEXT:    subq $88, %rsp
 ; WIN64-NEXT:    .seh_stackalloc 88
 ; WIN64-NEXT:    .seh_endprologue
-; WIN64-NEXT:    kmovd %edx, %k0
-; WIN64-NEXT:    kmovd %eax, %k1
-; WIN64-NEXT:    kmovd %ecx, %k2
+; WIN64-NEXT:    kmovd %eax, %k0
+; WIN64-NEXT:    kmovd %ecx, %k1
+; WIN64-NEXT:    kmovd %edx, %k2
 ; WIN64-NEXT:    vpmovm2b %k2, %zmm0
 ; WIN64-NEXT:    vmovdqa %xmm0, {{[0-9]+}}(%rsp)
 ; WIN64-NEXT:    vpmovm2b %k1, %zmm0
@@ -779,9 +779,9 @@ define dso_local x86_regcallcc i8 @test_argv8i1(<8 x i1> %x0, <8 x i1> %x1, <8 x
 ; WIN64-NEXT:    subq $88, %rsp
 ; WIN64-NEXT:    .seh_stackalloc 88
 ; WIN64-NEXT:    .seh_endprologue
-; WIN64-NEXT:    kmovd %edx, %k0
-; WIN64-NEXT:    kmovd %eax, %k1
-; WIN64-NEXT:    kmovd %ecx, %k2
+; WIN64-NEXT:    kmovd %eax, %k0
+; WIN64-NEXT:    kmovd %ecx, %k1
+; WIN64-NEXT:    kmovd %edx, %k2
 ; WIN64-NEXT:    vpmovm2w %k2, %zmm0
 ; WIN64-NEXT:    vmovdqa %xmm0, {{[0-9]+}}(%rsp)
 ; WIN64-NEXT:    vpmovm2w %k1, %zmm0
diff --git a/llvm/test/CodeGen/X86/fp-intrinsics.ll b/llvm/test/CodeGen/X86/fp-intrinsics.ll
index 5d69a217fb402..31a0d483ecfce 100644
--- a/llvm/test/CodeGen/X86/fp-intrinsics.ll
+++ b/llvm/test/CodeGen/X86/fp-intrinsics.ll
@@ -2475,21 +2475,21 @@ define double @uifdl(i64 %x) #0 {
 ;
 ; X86-SSE-LABEL: uifdl:
 ; X86-SSE:       # %bb.0: # %entry
-; X86-SSE-NEXT:    subl $28, %esp
-; X86-SSE-NEXT:    .cfi_def_cfa_offset 32
+; X86-SSE-NEXT:    subl $20, %esp
+; X86-SSE-NEXT:    .cfi_def_cfa_offset 24
 ; X86-SSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-SSE-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
 ; X86-SSE-NEXT:    movlps %xmm0, {{[0-9]+}}(%esp)
 ; X86-SSE-NEXT:    shrl $31, %eax
 ; 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:    fstpl (%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:    wait
-; X86-SSE-NEXT:    addl $28, %esp
+; X86-SSE-NEXT:    addl $20, %esp
 ; X86-SSE-NEXT:    .cfi_def_cfa_offset 4
 ; X86-SSE-NEXT:    retl
 ;
@@ -2708,8 +2708,8 @@ define float @uiffl(i64 %x) #0 {
 ; 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:    movss %xmm0, {{[0-9]+}}(%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..17c86d8959404 100644
--- a/llvm/test/CodeGen/X86/fp-strict-scalar-inttofp.ll
+++ b/llvm/test/CodeGen/X86/fp-strict-scalar-inttofp.ll
@@ -597,8 +597,8 @@ define float @uitofp_i64tof32(i64 %x) #0 {
 ; 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:    movss %xmm0, {{[0-9]+}}(%esp)
+; SSE-X86-NEXT:    flds {{[0-9]+}}(%esp)
 ; SSE-X86-NEXT:    wait
 ; SSE-X86-NEXT:    movl %ebp, %esp
 ; SSE-X86-NEXT:    popl %ebp
@@ -639,8 +639,8 @@ define float @uitofp_i64tof32(i64 %x) #0 {
 ; 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:    vmovss %xmm0, {{[0-9]+}}(%esp)
+; AVX-X86-NEXT:    flds {{[0-9]+}}(%esp)
 ; AVX-X86-NEXT:    wait
 ; AVX-X86-NEXT:    movl %ebp, %esp
 ; AVX-X86-NEXT:    popl %ebp
@@ -1276,14 +1276,14 @@ define double @uitofp_i64tof64(i64 %x) #0 {
 ; SSE-X86-NEXT:    movl %esp, %ebp
 ; SSE-X86-NEXT:    .cfi_def_cfa_register %ebp
 ; SSE-X86-NEXT:    andl $-8, %esp
-; SSE-X86-NEXT:    subl $24, %esp
+; SSE-X86-NEXT:    subl $16, %esp
 ; SSE-X86-NEXT:    movl 12(%ebp), %eax
 ; SSE-X86-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
 ; SSE-X86-NEXT:    movlps %xmm0, {{[0-9]+}}(%esp)
 ; SSE-X86-NEXT:    shrl $31, %eax
 ; 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:    fstpl (%esp)
 ; SSE-X86-NEXT:    wait
 ; SSE-X86-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
 ; SSE-X86-NEXT:    movsd %xmm0, (%esp)
@@ -1318,14 +1318,14 @@ define double @uitofp_i64tof64(i64 %x) #0 {
 ; AVX-X86-NEXT:    movl %esp, %ebp
 ; AVX-X86-NEXT:    .cfi_def_cfa_register %ebp
 ; AVX-X86-NEXT:    andl $-8, %esp
-; AVX-X86-NEXT:    subl $24, %esp
+; AVX-X86-NEXT:    subl $16, %esp
 ; AVX-X86-NEXT:    movl 12(%ebp), %eax
 ; AVX-X86-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero
 ; AVX-X86-NEXT:    vmovlps %xmm0, {{[0-9]+}}(%esp)
 ; AVX-X86-NEXT:    shrl $31, %eax
 ; 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:    fstpl (%esp)
 ; AVX-X86-NEXT:    wait
 ; AVX-X86-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero
 ; AVX-X86-NEXT:    vmovsd %xmm0, (%esp)
diff --git a/llvm/test/CodeGen/X86/fp128-libcalls-strict.ll b/llvm/test/CodeGen/X86/fp128-libcalls-strict.ll
index cae271f7a2ed4..9c80bdab640b6 100644
--- a/llvm/test/CodeGen/X86/fp128-libcalls-strict.ll
+++ b/llvm/test/CodeGen/X86/fp128-libcalls-strict.ll
@@ -599,9 +599,9 @@ define fp128 @fma(fp128 %x, fp128 %y, fp128 %z) nounwind strictfp {
 ; WIN-NEXT:    pushq %rsi
 ; WIN-NEXT:    subq $96, %rsp
 ; WIN-NEXT:    movq %rcx, %rsi
-; WIN-NEXT:    movaps (%r9), %xmm0
-; WIN-NEXT:    movaps (%rdx), %xmm1
-; WIN-NEXT:    movaps (%r8), %xmm2
+; WIN-NEXT:    movaps (%rdx), %xmm0
+; WIN-NEXT:    movaps (%r8), %xmm1
+; WIN-NEXT:    movaps (%r9), %xmm2
 ; WIN-NEXT:    movaps %xmm2, {{[0-9]+}}(%rsp)
 ; WIN-NEXT:    movaps %xmm1, {{[0-9]+}}(%rsp)
 ; WIN-NEXT:    movaps %xmm0, {{[0-9]+}}(%rsp)
diff --git a/llvm/test/CodeGen/X86/fp128-libcalls.ll b/llvm/test/CodeGen/X86/fp128-libcalls.ll
index c594b15ef1cbe..4c71a44e95757 100644
--- a/llvm/test/CodeGen/X86/fp128-libcalls.ll
+++ b/llvm/test/CodeGen/X86/fp128-libcalls.ll
@@ -212,8 +212,8 @@ define dso_local void @Test128_1Add(fp128 %d1) nounwind {
 ; WIN-NEXT:    subq $88, %rsp
 ; WIN-NEXT:    movaps (%rcx), %xmm0
 ; WIN-NEXT:    movaps vf128(%rip), %xmm1
-; WIN-NEXT:    movaps %xmm1, {{[0-9]+}}(%rsp)
 ; WIN-NEXT:    movaps %xmm0, {{[0-9]+}}(%rsp)
+; WIN-NEXT:    movaps %xmm1, {{[0-9]+}}(%rsp)
 ; WIN-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
 ; WIN-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
 ; WIN-NEXT:    leaq {{[0-9]+}}(%rsp), %r8
@@ -469,8 +469,8 @@ define dso_local void @Test128_1Sub(fp128 %d1) nounwind {
 ; WIN-NEXT:    subq $88, %rsp
 ; WIN-NEXT:    movaps (%rcx), %xmm0
 ; WIN-NEXT:    movaps vf128(%rip), %xmm1
-; WIN-NEXT:    movaps %xmm1, {{[0-9]+}}(%rsp)
 ; WIN-NEXT:    movaps %xmm0, {{[0-9]+}}(%rsp)
+; WIN-NEXT:    movaps %xmm1, {{[0-9]+}}(%rsp)
 ; WIN-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
 ; WIN-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
 ; WIN-NEXT:    leaq {{[0-9]+}}(%rsp), %r8
@@ -726,8 +726,8 @@ define dso_local void @Test128_1Mul(fp128 %d1) nounwind {
 ; WIN-NEXT:    subq $88, %rsp
 ; WIN-NEXT:    movaps (%rcx), %xmm0
 ; WIN-NEXT:    movaps vf128(%rip), %xmm1
-; WIN-NEXT:    movaps %xmm1, {{[0-9]+}}(%rsp)
 ; WIN-NEXT:    movaps %xmm0, {{[0-9]+}}(%rsp)
+; WIN-NEXT:    movaps %xmm1, {{[0-9]+}}(%rsp)
 ; WIN-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
 ; WIN-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
 ; WIN-NEXT:    leaq {{[0-9]+}}(%rsp), %r8
@@ -983,8 +983,8 @@ define dso_local void @Test128_1Div(fp128 %d1) nounwind {
 ; WIN-NEXT:    subq $88, %rsp
 ; WIN-NEXT:    movaps (%rcx), %xmm0
 ; WIN-NEXT:    movaps vf128(%rip), %xmm1
-; WIN-NEXT:    movaps %xmm1, {{[0-9]+}}(%rsp)
 ; WIN-NEXT:    movaps %xmm0, {{[0-9]+}}(%rsp)
+; WIN-NEXT:    movaps %xmm1, {{[0-9]+}}(%rsp)
 ; WIN-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
 ; WIN-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
 ; WIN-NEXT:    leaq {{[0-9]+}}(%rsp), %r8
@@ -1222,8 +1222,8 @@ define dso_local void @Test128_1Rem(fp128 %d1) nounwind {
 ; WIN-NEXT:    subq $88, %rsp
 ; WIN-NEXT:    movaps (%rcx), %xmm0
 ; WIN-NEXT:    movaps vf128(%rip), %xmm1
-; WIN-NEXT:    movaps %xmm1, {{[0-9]+}}(%rsp)
 ; WIN-NEXT:    movaps %xmm0, {{[0-9]+}}(%rsp)
+; WIN-NEXT:    movaps %xmm1, {{[0-9]+}}(%rsp)
 ; WIN-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
 ; WIN-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
 ; WIN-NEXT:    leaq {{[0-9]+}}(%rsp), %r8
@@ -2143,9 +2143,9 @@ define fp128 @Test128FMA(fp128 %a, fp128 %b, fp128 %c) nounwind {
 ; WIN-NEXT:    pushq %rsi
 ; WIN-NEXT:    subq $96, %rsp
 ; WIN-NEXT:    movq %rcx, %rsi
-; WIN-NEXT:    movaps (%r9), %xmm0
-; WIN-NEXT:    movaps (%rdx), %xmm1
-; WIN-NEXT:    movaps (%r8), %xmm2
+; WIN-NEXT:    movaps (%rdx), %xmm0
+; WIN-NEXT:    movaps (%r8), %xmm1
+; WIN-NEXT:    movaps (%r9), %xmm2
 ; WIN-NEXT:    movaps %xmm2, {{[0-9]+}}(%rsp)
 ; WIN-NEXT:    movaps %xmm1, {{[0-9]+}}(%rsp)
 ; WIN-NEXT:    movaps %xmm0, {{[0-9]+}}(%rsp)
diff --git a/llvm/test/CodeGen/X86/half.ll b/llvm/test/CodeGen/X86/half.ll
index b6a4a12eb0fac..64afca8071c46 100644
--- a/llvm/test/CodeGen/X86/half.ll
+++ b/llvm/test/CodeGen/X86/half.ll
@@ -549,12 +549,12 @@ define <4 x double> @test_extend64_vec4(ptr %p) #0 {
 ; CHECK-I686-NEXT:    pushl %esi
 ; CHECK-I686-NEXT:    subl $104, %esp
 ; CHECK-I686-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; CHECK-I686-NEXT:    pinsrw $0, 6(%eax), %xmm0
+; CHECK-I686-NEXT:    pinsrw $0, 2(%eax), %xmm0
 ; CHECK-I686-NEXT:    movdqa %xmm0, {{[-0-9]+}}(%e{{[sb]}}p) # 16-byte Spill
-; CHECK-I686-NEXT:    pinsrw $0, (%eax), %xmm0
+; CHECK-I686-NEXT:    pinsrw $0, 4(%eax), %xmm0
 ; CHECK-I686-NEXT:    movdqa %xmm0, {{[-0-9]+}}(%e{{[sb]}}p) # 16-byte Spill
-; CHECK-I686-NEXT:    pinsrw $0, 2(%eax), %xmm0
-; CHECK-I686-NEXT:    pinsrw $0, 4(%eax), %xmm1
+; CHECK-I686-NEXT:    pinsrw $0, 6(%eax), %xmm0
+; CHECK-I686-NEXT:    pinsrw $0, (%eax), %xmm1
 ; CHECK-I686-NEXT:    pextrw $0, %xmm1, %eax
 ; CHECK-I686-NEXT:    movw %ax, (%esp)
 ; CHECK-I686-NEXT:    pextrw $0, %xmm0, %esi
@@ -577,10 +577,10 @@ define <4 x double> @test_extend64_vec4(ptr %p) #0 {
 ; CHECK-I686-NEXT:    fstpl {{[0-9]+}}(%esp)
 ; CHECK-I686-NEXT:    calll __extendhfsf2
 ; CHECK-I686-NEXT:    fstpl {{[0-9]+}}(%esp)
-; CHECK-I686-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
-; CHECK-I686-NEXT:    movhps {{.*#+}} xmm0 = xmm0[0,1],mem[0,1]
 ; CHECK-I686-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
 ; CHECK-I686-NEXT:    movhps {{.*#+}} xmm1 = xmm1[0,1],mem[0,1]
+; CHECK-I686-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
+; CHECK-I686-NEXT:    movhps {{.*#+}} xmm0 = xmm0[0,1],mem[0,1]
 ; CHECK-I686-NEXT:    addl $104, %esp
 ; CHECK-I686-NEXT:    popl %esi
 ; CHECK-I686-NEXT:    retl
diff --git a/llvm/test/CodeGen/X86/i128-fp128-abi.ll b/llvm/test/CodeGen/X86/i128-fp128-abi.ll
index 9f385ee2faf4e..4454e4fa5e848 100644
--- a/llvm/test/CodeGen/X86/i128-fp128-abi.ll
+++ b/llvm/test/CodeGen/X86/i128-fp128-abi.ll
@@ -706,9 +706,9 @@ define void @call_leading_args(PrimTy %x) nounwind {
 ; CHECK-MSVC64-F128:       # %bb.0:
 ; CHECK-MSVC64-F128-NEXT:    subq $88, %rsp
 ; CHECK-MSVC64-F128-NEXT:    movaps (%rcx), %xmm0
-; CHECK-MSVC64-F128-NEXT:    movaps %xmm0, 48(%rsp)
 ; CHECK-MSVC64-F128-NEXT:    leaq 48(%rsp), %rax
 ; CHECK-MSVC64-F128-NEXT:    movq %rax, 40(%rsp)
+; CHECK-MSVC64-F128-NEXT:    movaps %xmm0, 48(%rsp)
 ; CHECK-MSVC64-F128-NEXT:    movq $0, 32(%rsp)
 ; CHECK-MSVC64-F128-NEXT:    leaq 64(%rsp), %rcx
 ; CHECK-MSVC64-F128-NEXT:    xorl %edx, %edx
@@ -735,9 +735,9 @@ define void @call_leading_args(PrimTy %x) nounwind {
 ; CHECK-MINGW-F128:       # %bb.0:
 ; CHECK-MINGW-F128-NEXT:    subq $88, %rsp
 ; CHECK-MINGW-F128-NEXT:    movaps (%rcx), %xmm0
-; CHECK-MINGW-F128-NEXT:    movaps %xmm0, 48(%rsp)
 ; CHECK-MINGW-F128-NEXT:    leaq 48(%rsp), %rax
 ; CHECK-MINGW-F128-NEXT:    movq %rax, 40(%rsp)
+; CHECK-MINGW-F128-NEXT:    movaps %xmm0, 48(%rsp)
 ; CHECK-MINGW-F128-NEXT:    movq $0, 32(%rsp)
 ; CHECK-MINGW-F128-NEXT:    leaq 64(%rsp), %rcx
 ; CHECK-MINGW-F128-NEXT:    xorl %edx, %edx
@@ -857,13 +857,13 @@ define void @call_many_leading_args(PrimTy %x) nounwind {
 ; CHECK-MSVC64-F128:       # %bb.0:
 ; CHECK-MSVC64-F128-NEXT:    subq $120, %rsp
 ; CHECK-MSVC64-F128-NEXT:    movaps (%rcx), %xmm0
-; CHECK-MSVC64-F128-NEXT:    xorps %xmm1, %xmm1
-; CHECK-MSVC64-F128-NEXT:    movaps %xmm1, 80(%rsp)
+; CHECK-MSVC64-F128-NEXT:    leaq 64(%rsp), %rax
+; CHECK-MSVC64-F128-NEXT:    movq %rax, 48(%rsp)
 ; CHECK-MSVC64-F128-NEXT:    leaq 80(%rsp), %rax
 ; CHECK-MSVC64-F128-NEXT:    movq %rax, 40(%rsp)
 ; CHECK-MSVC64-F128-NEXT:    movaps %xmm0, 64(%rsp)
-; CHECK-MSVC64-F128-NEXT:    leaq 64(%rsp), %rax
-; CHECK-MSVC64-F128-NEXT:    movq %rax, 48(%rsp)
+; CHECK-MSVC64-F128-NEXT:    xorps %xmm0, %xmm0
+; CHECK-MSVC64-F128-NEXT:    movaps %xmm0, 80(%rsp)
 ; CHECK-MSVC64-F128-NEXT:    movq $0, 32(%rsp)
 ; CHECK-MSVC64-F128-NEXT:    leaq 96(%rsp), %rcx
 ; CHECK-MSVC64-F128-NEXT:    xorl %edx, %edx
@@ -892,13 +892,13 @@ define void @call_many_leading_args(PrimTy %x) nounwind {
 ; CHECK-MINGW-F128:       # %bb.0:
 ; CHECK-MINGW-F128-NEXT:    subq $120, %rsp
 ; CHECK-MINGW-F128-NEXT:    movaps (%rcx), %xmm0
-; CHECK-MINGW-F128-NEXT:    xorps %xmm1, %xmm1
-; CHECK-MINGW-F128-NEXT:    movaps %xmm1, 80(%rsp)
+; CHECK-MINGW-F128-NEXT:    leaq 64(%rsp), %rax
+; CHECK-MINGW-F128-NEXT:    movq %rax, 48(%rsp)
 ; CHECK-MINGW-F128-NEXT:    leaq 80(%rsp), %rax
 ; CHECK-MINGW-F128-NEXT:    movq %rax, 40(%rsp)
 ; CHECK-MINGW-F128-NEXT:    movaps %xmm0, 64(%rsp)
-; CHECK-MINGW-F128-NEXT:    leaq 64(%rsp), %rax
-; CHECK-MINGW-F128-NEXT:    movq %rax, 48(%rsp)
+; CHECK-MINGW-F128-NEXT:    xorps %xmm0, %xmm0
+; CHECK-MINGW-F128-NEXT:    movaps %xmm0, 80(%rsp)
 ; CHECK-MINGW-F128-NEXT:    movq $0, 32(%rsp)
 ; CHECK-MINGW-F128-NEXT:    leaq 96(%rsp), %rcx
 ; CHECK-MINGW-F128-NEXT:    xorl %edx, %edx
@@ -1021,9 +1021,9 @@ define void @call_trailing_arg(PrimTy %x) nounwind {
 ; CHECK-MSVC64-F128:       # %bb.0:
 ; CHECK-MSVC64-F128-NEXT:    subq $88, %rsp
 ; CHECK-MSVC64-F128-NEXT:    movaps (%rcx), %xmm0
-; CHECK-MSVC64-F128-NEXT:    movaps %xmm0, 48(%rsp)
 ; CHECK-MSVC64-F128-NEXT:    leaq 48(%rsp), %rax
 ; CHECK-MSVC64-F128-NEXT:    movq %rax, 40(%rsp)
+; CHECK-MSVC64-F128-NEXT:    movaps %xmm0, 48(%rsp)
 ; CHECK-MSVC64-F128-NEXT:    movq $0, 32(%rsp)
 ; CHECK-MSVC64-F128-NEXT:    leaq 64(%rsp), %rcx
 ; CHECK-MSVC64-F128-NEXT:    xorl %edx, %edx
@@ -1050,9 +1050,9 @@ define void @call_trailing_arg(PrimTy %x) nounwind {
 ; CHECK-MINGW-F128:       # %bb.0:
 ; CHECK-MINGW-F128-NEXT:    subq $88, %rsp
 ; CHECK-MINGW-F128-NEXT:    movaps (%rcx), %xmm0
-; CHECK-MINGW-F128-NEXT:    movaps %xmm0, 48(%rsp)
 ; CHECK-MINGW-F128-NEXT:    leaq 48(%rsp), %rax
 ; CHECK-MINGW-F128-NEXT:    movq %rax, 40(%rsp)
+; CHECK-MINGW-F128-NEXT:    movaps %xmm0, 48(%rsp)
 ; CHECK-MINGW-F128-NEXT:    movq $0, 32(%rsp)
 ; CHECK-MINGW-F128-NEXT:    leaq 64(%rsp), %rcx
 ; CHECK-MINGW-F128-NEXT:    xorl %edx, %edx
diff --git a/llvm/test/CodeGen/X86/pr3457.ll b/llvm/test/CodeGen/X86/pr3457.ll
index 4f11bc949b772..fb5dbfc85ef83 100644
--- a/llvm/test/CodeGen/X86/pr3457.ll
+++ b/llvm/test/CodeGen/X86/pr3457.ll
@@ -12,11 +12,11 @@ define void @foo(ptr nocapture %P) nounwind {
 ; CHECK-NEXT:    calll _test
 ; CHECK-NEXT:    fstpl {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
-; CHECK-NEXT:    movsd %xmm0, (%esp) ## 8-byte Spill
+; CHECK-NEXT:    movsd %xmm0, {{[-0-9]+}}(%e{{[sb]}}p) ## 8-byte Spill
 ; CHECK-NEXT:    calll _test
 ; CHECK-NEXT:    fstpl {{[0-9]+}}(%esp)
 ; CHECK-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
-; CHECK-NEXT:    movsd (%esp), %xmm1 ## 8-byte Reload
+; CHECK-NEXT:    movsd {{[-0-9]+}}(%e{{[sb]}}p), %xmm1 ## 8-byte Reload
 ; CHECK-NEXT:    ## xmm1 = mem[0],zero
 ; CHECK-NEXT:    mulsd %xmm1, %xmm1
 ; CHECK-NEXT:    mulsd %xmm0, %xmm0
diff --git a/llvm/test/CodeGen/X86/sse-intel-ocl.ll b/llvm/test/CodeGen/X86/sse-intel-ocl.ll
index b2de7545ff5f5..001f3ff66de37 100644
--- a/llvm/test/CodeGen/X86/sse-intel-ocl.ll
+++ b/llvm/test/CodeGen/X86/sse-intel-ocl.ll
@@ -220,26 +220,26 @@ define intel_ocl_bicc <16 x float> @test_prolog_epilog(<16 x float> %a, <16 x fl
 ; WIN64-NEXT:    subq $232, %rsp
 ; WIN64-NEXT:    movaps %xmm7, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
 ; WIN64-NEXT:    movaps %xmm6, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
-; WIN64-NEXT:    movaps (%r9), %xmm4
+; WIN64-NEXT:    movaps (%rcx), %xmm4
 ; WIN64-NEXT:    movaps (%rdx), %xmm5
 ; WIN64-NEXT:    movaps (%r8), %xmm6
-; WIN64-NEXT:    movaps (%rcx), %xmm7
-; WIN64-NEXT:    movaps %xmm1, {{[0-9]+}}(%rsp)
-; WIN64-NEXT:    movaps %xmm0, {{[0-9]+}}(%rsp)
-; WIN64-NEXT:    movaps %xmm2, {{[0-9]+}}(%rsp)
-; WIN64-NEXT:    movaps %xmm3, {{[0-9]+}}(%rsp)
-; WIN64-NEXT:    movaps %xmm7, {{[0-9]+}}(%rsp)
-; WIN64-NEXT:    movaps %xmm6, {{[0-9]+}}(%rsp)
-; WIN64-NEXT:    movaps %xmm5, {{[0-9]+}}(%rsp)
+; WIN64-NEXT:    movaps (%r9), %xmm7
 ; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rax
 ; WIN64-NEXT:    movq %rax, {{[0-9]+}}(%rsp)
 ; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rax
 ; WIN64-NEXT:    movq %rax, {{[0-9]+}}(%rsp)
-; WIN64-NEXT:    movaps %xmm4, {{[0-9]+}}(%rsp)
 ; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rax
 ; WIN64-NEXT:    movq %rax, {{[0-9]+}}(%rsp)
 ; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rax
 ; WIN64-NEXT:    movq %rax, {{[0-9]+}}(%rsp)
+; WIN64-NEXT:    movaps %xmm7, {{[0-9]+}}(%rsp)
+; WIN64-NEXT:    movaps %xmm6, {{[0-9]+}}(%rsp)
+; WIN64-NEXT:    movaps %xmm5, {{[0-9]+}}(%rsp)
+; WIN64-NEXT:    movaps %xmm4, {{[0-9]+}}(%rsp)
+; WIN64-NEXT:    movaps %xmm3, {{[0-9]+}}(%rsp)
+; WIN64-NEXT:    movaps %xmm2, {{[0-9]+}}(%rsp)
+; WIN64-NEXT:    movaps %xmm1, {{[0-9]+}}(%rsp)
+; WIN64-NEXT:    movaps %xmm0, {{[0-9]+}}(%rsp)
 ; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
 ; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
 ; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %r8
diff --git a/llvm/test/CodeGen/X86/stack-coloring-x87.ll b/llvm/test/CodeGen/X86/stack-coloring-x87.ll
index 8990b810bd590..53dd483d3d5be 100644
--- a/llvm/test/CodeGen/X86/stack-coloring-x87.ll
+++ b/llvm/test/CodeGen/X86/stack-coloring-x87.ll
@@ -11,8 +11,8 @@ define void @test_byval(ptr %p1, ptr %p2, ptr %p3) {
 ; CHECK-NEXT:    .seh_pushreg %rsi
 ; CHECK-NEXT:    pushq %rdi
 ; CHECK-NEXT:    .seh_pushreg %rdi
-; CHECK-NEXT:    subq $136, %rsp
-; CHECK-NEXT:    .seh_stackalloc 136
+; CHECK-NEXT:    subq $72, %rsp
+; CHECK-NEXT:    .seh_stackalloc 72
 ; CHECK-NEXT:    .seh_endprologue
 ; CHECK-NEXT:    movq %r8, %rsi
 ; CHECK-NEXT:    movq %rdx, %rdi
@@ -48,7 +48,7 @@ define void @test_byval(ptr %p1, ptr %p2, ptr %p3) {
 ; CHECK-NEXT:    callq use_byval
 ; CHECK-NEXT:    nop
 ; CHECK-NEXT:    .seh_startepilogue
-; CHECK-NEXT:    addq $136, %rsp
+; CHECK-NEXT:    addq $72, %rsp
 ; CHECK-NEXT:    popq %rdi
 ; CHECK-NEXT:    popq %rsi
 ; CHECK-NEXT:    .seh_endepilogue
@@ -65,8 +65,8 @@ declare void @use_f80(x86_fp80)
 define void @test_f80(x86_fp80 %p1, x86_fp80 %p2, x86_fp80 %p3) {
 ; CHECK-LABEL: test_f80:
 ; CHECK:       # %bb.0: # %entry
-; CHECK-NEXT:    subq $104, %rsp
-; CHECK-NEXT:    .seh_stackalloc 104
+; CHECK-NEXT:    subq $72, %rsp
+; CHECK-NEXT:    .seh_stackalloc 72
 ; CHECK-NEXT:    .seh_endprologue
 ; CHECK-NEXT:    fldt (%r8)
 ; CHECK-NEXT:    fstpt {{[-0-9]+}}(%r{{[sb]}}p) # 10-byte Folded Spill
@@ -86,7 +86,7 @@ define void @test_f80(x86_fp80 %p1, x86_fp80 %p2, x86_fp80 %p3) {
 ; CHECK-NEXT:    callq use_f80
 ; CHECK-NEXT:    nop
 ; CHECK-NEXT:    .seh_startepilogue
-; CHECK-NEXT:    addq $104, %rsp
+; CHECK-NEXT:    addq $72, %rsp
 ; CHECK-NEXT:    .seh_endepilogue
 ; CHECK-NEXT:    retq
 ; CHECK-NEXT:    .seh_endproc
diff --git a/llvm/test/CodeGen/X86/uint64-to-float.ll b/llvm/test/CodeGen/X86/uint64-to-float.ll
index 03a8171589622..d2d05b2fc0cea 100644
--- a/llvm/test/CodeGen/X86/uint64-to-float.ll
+++ b/llvm/test/CodeGen/X86/uint64-to-float.ll
@@ -22,9 +22,7 @@ define float @test(i64 %a) nounwind {
 ; X86-NEXT:    fildll {{[0-9]+}}(%esp)
 ; X86-NEXT:    fadds {{\.?LCPI[0-9]+_[0-9]+}}(,%eax,4)
 ; X86-NEXT:    fstps {{[0-9]+}}(%esp)
-; X86-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
-; X86-NEXT:    movss %xmm0, (%esp)
-; X86-NEXT:    flds (%esp)
+; X86-NEXT:    flds {{[0-9]+}}(%esp)
 ; X86-NEXT:    movl %ebp, %esp
 ; X86-NEXT:    popl %ebp
 ; X86-NEXT:    retl
@@ -50,22 +48,20 @@ define float @test(i64 %a) nounwind {
 ; X86-WIN-NEXT:    pushl %ebp
 ; X86-WIN-NEXT:    movl %esp, %ebp
 ; X86-WIN-NEXT:    andl $-8, %esp
-; X86-WIN-NEXT:    subl $24, %esp
+; X86-WIN-NEXT:    subl $16, %esp
 ; X86-WIN-NEXT:    movl 12(%ebp), %eax
 ; X86-WIN-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
 ; X86-WIN-NEXT:    movlps %xmm0, {{[0-9]+}}(%esp)
 ; X86-WIN-NEXT:    shrl $31, %eax
 ; X86-WIN-NEXT:    fildll {{[0-9]+}}(%esp)
-; X86-WIN-NEXT:    fnstcw {{[0-9]+}}(%esp)
-; X86-WIN-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
+; X86-WIN-NEXT:    fnstcw (%esp)
+; X86-WIN-NEXT:    movzwl (%esp), %ecx
 ; X86-WIN-NEXT:    orl $768, %ecx # imm = 0x300
 ; X86-WIN-NEXT:    movw %cx, {{[0-9]+}}(%esp)
 ; X86-WIN-NEXT:    fldcw {{[0-9]+}}(%esp)
 ; X86-WIN-NEXT:    fadds __real at 5f80000000000000(,%eax,4)
-; X86-WIN-NEXT:    fldcw {{[0-9]+}}(%esp)
+; X86-WIN-NEXT:    fldcw (%esp)
 ; X86-WIN-NEXT:    fstps {{[0-9]+}}(%esp)
-; X86-WIN-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
-; X86-WIN-NEXT:    movss %xmm0, {{[0-9]+}}(%esp)
 ; X86-WIN-NEXT:    flds {{[0-9]+}}(%esp)
 ; X86-WIN-NEXT:    movl %ebp, %esp
 ; X86-WIN-NEXT:    popl %ebp
diff --git a/llvm/test/CodeGen/X86/win64-byval.ll b/llvm/test/CodeGen/X86/win64-byval.ll
index 573a0016e8772..a4ed85cad6078 100644
--- a/llvm/test/CodeGen/X86/win64-byval.ll
+++ b/llvm/test/CodeGen/X86/win64-byval.ll
@@ -63,21 +63,21 @@ define void @test() {
 ; CHECK-NEXT:    subq $136, %rsp
 ; CHECK-NEXT:    .seh_stackalloc 136
 ; CHECK-NEXT:    .seh_endprologue
+; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %rax
+; CHECK-NEXT:    movq %rax, {{[0-9]+}}(%rsp)
 ; CHECK-NEXT:    movq .refptr.G(%rip), %rax
 ; CHECK-NEXT:    movq (%rax), %rcx
 ; CHECK-NEXT:    movq 8(%rax), %rax
 ; CHECK-NEXT:    movq %rax, {{[0-9]+}}(%rsp)
 ; CHECK-NEXT:    movq %rcx, {{[0-9]+}}(%rsp)
-; CHECK-NEXT:    movq %rcx, {{[0-9]+}}(%rsp)
 ; CHECK-NEXT:    movq %rax, {{[0-9]+}}(%rsp)
 ; CHECK-NEXT:    movq %rcx, {{[0-9]+}}(%rsp)
 ; CHECK-NEXT:    movq %rax, {{[0-9]+}}(%rsp)
 ; CHECK-NEXT:    movq %rcx, {{[0-9]+}}(%rsp)
 ; CHECK-NEXT:    movq %rax, {{[0-9]+}}(%rsp)
-; CHECK-NEXT:    movq %rax, {{[0-9]+}}(%rsp)
 ; CHECK-NEXT:    movq %rcx, {{[0-9]+}}(%rsp)
-; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %rax
 ; CHECK-NEXT:    movq %rax, {{[0-9]+}}(%rsp)
+; CHECK-NEXT:    movq %rcx, {{[0-9]+}}(%rsp)
 ; CHECK-NEXT:    movq $10, {{[0-9]+}}(%rsp)
 ; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
 ; CHECK-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
diff --git a/llvm/test/CodeGen/X86/x87-stack-coloring.ll b/llvm/test/CodeGen/X86/x87-stack-coloring.ll
index eeca372cf3ac5..e32d4c6583a00 100644
--- a/llvm/test/CodeGen/X86/x87-stack-coloring.ll
+++ b/llvm/test/CodeGen/X86/x87-stack-coloring.ll
@@ -1,8 +1,6 @@
 ; 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
 
-; ModuleID = 'example_big.c'
-source_filename = "example_big.c"
 target datalayout = "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:128-f64:32:64-f80:32-n8:16:32-S128"
 target triple = "i386-unknown-linux-gnu"
 
@@ -10,7 +8,7 @@ target triple = "i386-unknown-linux-gnu"
 define dso_local float @returns_float() local_unnamed_addr #0 {
 ; CHECK-LABEL: returns_float:
 ; CHECK:       # %bb.0: # %entry
-; CHECK-NEXT:    subl $44, %esp
+; CHECK-NEXT:    subl $12, %esp
 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
 ; CHECK-NEXT:    calll rand at PLT
 ; CHECK-NEXT:    cvtsi2ss %eax, %xmm0
@@ -27,11 +25,29 @@ entry:
 
 declare i32 @rand() local_unnamed_addr #1
 
+; Function Attrs: noinline nounwind uwtable
+define dso_local x86_fp80 @returns_long_double() local_unnamed_addr #0 {
+; CHECK-LABEL: returns_long_double:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    subl $12, %esp
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    calll rand at PLT
+; CHECK-NEXT:    movl %eax, {{[0-9]+}}(%esp)
+; CHECK-NEXT:    fildl {{[0-9]+}}(%esp)
+; CHECK-NEXT:    addl $12, %esp
+; CHECK-NEXT:    .cfi_def_cfa_offset 4
+; CHECK-NEXT:    retl
+entry:
+  %call = tail call i32 @rand() #3
+  %conv = sitofp i32 %call to x86_fp80
+  ret x86_fp80 %conv
+}
+
 ; Function Attrs: nounwind uwtable
-define dso_local float @example() local_unnamed_addr #2 {
-; CHECK-LABEL: example:
+define dso_local float @example_float() local_unnamed_addr #2 {
+; CHECK-LABEL: example_float:
 ; CHECK:       # %bb.0: # %entry
-; CHECK-NEXT:    subl $44, %esp
+; CHECK-NEXT:    subl $12, %esp
 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
 ; CHECK-NEXT:    calll returns_float
 ; CHECK-NEXT:    fstps {{[0-9]+}}(%esp)
@@ -78,6 +94,48 @@ entry:
   ret float %add7
 }
 
+; Function Attrs: nounwind uwtable
+define dso_local float @example_long_double() local_unnamed_addr #2 {
+; CHECK-LABEL: example_long_double:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    subl $28, %esp
+; CHECK-NEXT:    .cfi_def_cfa_offset 32
+; CHECK-NEXT:    calll returns_long_double
+; CHECK-NEXT:    fstpt {{[-0-9]+}}(%e{{[sb]}}p) # 10-byte Folded Spill
+; CHECK-NEXT:    calll returns_long_double
+; CHECK-NEXT:    fldt {{[-0-9]+}}(%e{{[sb]}}p) # 10-byte Folded Reload
+; CHECK-NEXT:    faddp %st, %st(1)
+; CHECK-NEXT:    fstpt {{[-0-9]+}}(%e{{[sb]}}p) # 10-byte Folded Spill
+; CHECK-NEXT:    calll returns_long_double
+; CHECK-NEXT:    fldt {{[-0-9]+}}(%e{{[sb]}}p) # 10-byte Folded Reload
+; CHECK-NEXT:    faddp %st, %st(1)
+; CHECK-NEXT:    fstpt {{[-0-9]+}}(%e{{[sb]}}p) # 10-byte Folded Spill
+; CHECK-NEXT:    calll returns_long_double
+; CHECK-NEXT:    fldt {{[-0-9]+}}(%e{{[sb]}}p) # 10-byte Folded Reload
+; CHECK-NEXT:    faddp %st, %st(1)
+; CHECK-NEXT:    fstpt {{[-0-9]+}}(%e{{[sb]}}p) # 10-byte Folded Spill
+; CHECK-NEXT:    calll returns_long_double
+; CHECK-NEXT:    fldt {{[-0-9]+}}(%e{{[sb]}}p) # 10-byte Folded Reload
+; CHECK-NEXT:    faddp %st, %st(1)
+; CHECK-NEXT:    fstps {{[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 = tail call x86_fp80 @returns_long_double()
+  %call1 = tail call x86_fp80 @returns_long_double()
+  %add = fadd x86_fp80 %call, %call1
+  %call2 = tail call x86_fp80 @returns_long_double()
+  %add3 = fadd x86_fp80 %add, %call2
+  %call4 = tail call x86_fp80 @returns_long_double()
+  %add5 = fadd x86_fp80 %add3, %call4
+  %call6 = tail call x86_fp80 @returns_long_double()
+  %add7 = fadd x86_fp80 %add5, %call6
+  %conv = fptrunc x86_fp80 %add7 to float
+  ret float %conv
+}
+
 attributes #0 = { noinline nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="pentium4" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
 attributes #1 = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="pentium4" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
 attributes #2 = { nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="pentium4" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }



More information about the llvm-commits mailing list