https://github.com/oltolm updated 
https://github.com/llvm/llvm-project/pull/210358

>From a0c3143112a5e1e159574c9216c8d1274424d3ce Mon Sep 17 00:00:00 2001
From: Oleg Tolmatcev <[email protected]>
Date: Fri, 17 Jul 2026 17:17:02 +0200
Subject: [PATCH] [clang][X86] Return Win64 __int128 indirectly

Return Win64 __int128 and __uint128 values through a hidden sret pointer
instead of treating them as v2i64 values returned in XMM0.

This matches current GCC behavior and removes the old MinGW i128 direct-return
special case. Make the X86 backend follow the same rule for i128 libcalls it
creates itself: Win64 i128 div/rem/fp-conversion libcalls now use an sret
result slot, and i128 multiply is routed through the same path so __multi3 is
called with the correct ABI too.

Without this, some Win64 callers expected an i128 result directly in registers
while the callee wrote it through an sret pointer. That broke compiler-rt
builtins such as mulvti3 and muloti4 when they called __multi3.

Update the X86 codegen tests to check the indirect-return form.
---
 clang/docs/ReleaseNotes.md                    |   4 +
 clang/lib/CodeGen/Targets/X86.cpp             |   6 +-
 clang/test/CodeGen/win64-i128.c               |   8 +-
 llvm/lib/Target/X86/X86ISelLowering.cpp       | 126 ++++---
 llvm/lib/Target/X86/X86ISelLowering.h         |   4 +
 llvm/lib/Target/X86/X86ISelLoweringCall.cpp   |  11 +-
 llvm/test/CodeGen/X86/divmod128.ll            | 351 +++++++++++-------
 llvm/test/CodeGen/X86/fp128-cast.ll           |  12 +-
 .../CodeGen/X86/i128-fpconv-win64-strict.ll   |  50 ++-
 llvm/test/CodeGen/X86/i128-fpconv-win64.ll    |  50 ++-
 10 files changed, 389 insertions(+), 233 deletions(-)

diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 8e47adbc64a4c..b9bc075a44d96 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -50,6 +50,10 @@ latest release, please see the [Clang Web 
Site](https://clang.llvm.org) or the
 
 ### ABI Changes in This Version
 
+- On x86_64 Windows targets, Clang now returns `__int128` and `unsigned
+  __int128` indirectly through a hidden return pointer. This matches how Clang
+  already returns 16-byte structs on the same targets.
+
 ### AST Dumping Potentially Breaking Changes
 
 ### Clang Frontend Potentially Breaking Changes
diff --git a/clang/lib/CodeGen/Targets/X86.cpp 
b/clang/lib/CodeGen/Targets/X86.cpp
index 807d372c3c8fd..c13e3a16ae098 100644
--- a/clang/lib/CodeGen/Targets/X86.cpp
+++ b/clang/lib/CodeGen/Targets/X86.cpp
@@ -3510,12 +3510,10 @@ ABIArgInfo WinX86_64ABIInfo::classify(QualType Ty, 
unsigned &FreeSSERegs,
             Align, /*AddrSpace=*/getDataLayout().getAllocaAddrSpace(),
             /*ByVal=*/false);
 
-      // Mingw64 GCC returns i128 in XMM0. Coerce to v2i64 to handle that.
-      // Clang matches them for compatibility.
       if (BT->getKind() == BuiltinType::Int128 ||
           BT->getKind() == BuiltinType::UInt128)
-        return ABIArgInfo::getDirect(llvm::FixedVectorType::get(
-            llvm::Type::getInt64Ty(getVMContext()), 2));
+        return getNaturalAlignIndirect(Ty, 
getDataLayout().getAllocaAddrSpace(),
+                                       /*ByVal=*/false);
 
       // Mingw64 GCC returns f128 via sret, and Clang matches that for
       // compatibility. This mirrors the X86 backend's CanLowerReturn logic.
diff --git a/clang/test/CodeGen/win64-i128.c b/clang/test/CodeGen/win64-i128.c
index 862dd842f7db4..a427bf025d7fd 100644
--- a/clang/test/CodeGen/win64-i128.c
+++ b/clang/test/CodeGen/win64-i128.c
@@ -11,12 +11,16 @@ typedef int int128_t __attribute__((mode(TI)));
 
 int128_t foo(void) { return 0; }
 
-// X64: define dso_local <2 x i64> @foo()
+// X64-LABEL: define dso_local void @foo(
+// X64-SAME: sret(i128) align 16
 // ARM: define dso_local i128 @foo()
 
 int128_t bar(int128_t a, int128_t b) { return a * b; }
 
-// X64: define dso_local <2 x i64> @bar(ptr noundef align 16 dead_on_return 
%0, ptr noundef align 16 dead_on_return %1)
+// X64-LABEL: define dso_local void @bar(
+// X64-SAME: sret(i128) align 16
+// X64-SAME: ptr noundef align 16 dead_on_return
+// X64-SAME: ptr noundef align 16 dead_on_return
 // ARM: define dso_local i128 @bar(i128 noundef %a, i128 noundef %b)
 
 void vararg(int a, ...) {
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp 
b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 97e783c09f0f2..01da24df9194f 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -2710,6 +2710,7 @@ X86TargetLowering::X86TargetLowering(const 
X86TargetMachine &TM,
   setOperationAction(ISD::FSINCOS, MVT::f32, Expand);
 
   if (Subtarget.isTargetWin64()) {
+    setOperationAction(ISD::MUL, MVT::i128, Custom);
     setOperationAction(ISD::SDIV, MVT::i128, Custom);
     setOperationAction(ISD::UDIV, MVT::i128, Custom);
     setOperationAction(ISD::SREM, MVT::i128, Custom);
@@ -22435,6 +22436,8 @@ SDValue X86TargetLowering::LowerFP_TO_INT(SDValue Op, 
SelectionDAG &DAG) const {
       LC = RTLIB::getFPTOSINT(SrcVT, VT);
     else
       LC = RTLIB::getFPTOUINT(SrcVT, VT);
+    if (Subtarget.isTargetWin64() && VT == MVT::i128)
+      return LowerWin64_FP_TO_INT128(Op, DAG, Chain);
 
     MakeLibCallOptions CallOptions;
     std::pair<SDValue, SDValue> Tmp =
@@ -30634,66 +30637,89 @@ static SDValue LowerMULO(SDValue Op, const 
X86Subtarget &Subtarget,
   return DAG.getMergeValues({Low, Ovf}, dl);
 }
 
-SDValue X86TargetLowering::LowerWin64_i128OP(SDValue Op, SelectionDAG &DAG) 
const {
+SDValue X86TargetLowering::lowerWin64IndirectI128Libcall(
+    SelectionDAG &DAG, const SDLoc &DL, EVT RetVT, RTLIB::Libcall LC,
+    ArrayRef<SDValue> IndirectArgs, SDValue &Chain) const {
+  RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
+  if (LCImpl == RTLIB::Unsupported)
+    return SDValue();
+
+  TargetLowering::ArgListTy Args;
+  Type *RetTy = RetVT.getTypeForEVT(*DAG.getContext());
+  MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
+  const Align StackAlign = DAG.getDataLayout().getPrefTypeAlign(RetTy);
+  int ResultFI = MFI.CreateStackObject(
+      DAG.getDataLayout().getTypeAllocSize(RetTy), StackAlign, false);
+  SDValue ResultPtr =
+      DAG.getFrameIndex(ResultFI, getFrameIndexTy(DAG.getDataLayout()));
+
+  TargetLowering::ArgListEntry ResultEntry(
+      ResultPtr, PointerType::get(*DAG.getContext(),
+                                  DAG.getDataLayout().getAllocaAddrSpace()));
+  ResultEntry.IsSRet = true;
+  ResultEntry.Alignment = StackAlign;
+  ResultEntry.IndirectType = RetTy;
+  Args.push_back(ResultEntry);
+
+  for (SDValue Arg : IndirectArgs) {
+    EVT ArgVT = Arg.getValueType();
+    SDValue StackPtr = DAG.CreateStackTemporary(ArgVT, 16);
+    int SPFI = cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex();
+    MachinePointerInfo MPI =
+        MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), SPFI);
+    Chain = DAG.getStore(Chain, DL, Arg, StackPtr, MPI, Align(16));
+    Args.emplace_back(StackPtr, PointerType::get(*DAG.getContext(), 0));
+  }
+
+  SDValue Callee =
+      DAG.getExternalSymbol(LCImpl, getPointerTy(DAG.getDataLayout()));
+
+  TargetLowering::CallLoweringInfo CLI(DAG);
+  CLI.setDebugLoc(DL).setChain(Chain).setLibCallee(
+      DAG.getLibcalls().getLibcallImplCallingConv(LCImpl),
+      Type::getVoidTy(*DAG.getContext()), Callee, std::move(Args));
+
+  std::pair<SDValue, SDValue> CallInfo = LowerCallTo(CLI);
+  Chain = CallInfo.second;
+  MachinePointerInfo PtrInfo =
+      MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), ResultFI);
+  return DAG.getLoad(RetVT, DL, Chain, ResultPtr, PtrInfo, StackAlign);
+}
+
+SDValue X86TargetLowering::LowerWin64_i128OP(SDValue Op,
+                                             SelectionDAG &DAG) const {
   assert(Subtarget.isTargetWin64() && "Unexpected target");
   EVT VT = Op.getValueType();
   assert(VT.isInteger() && VT.getSizeInBits() == 128 &&
          "Unexpected return type for lowering");
 
-  if (isa<ConstantSDNode>(Op->getOperand(1))) {
+  if (Op.getOpcode() != ISD::MUL && isa<ConstantSDNode>(Op->getOperand(1))) {
     SmallVector<SDValue> Result;
     if (expandDIVREMByConstant(Op.getNode(), Result, MVT::i64, DAG))
       return DAG.getNode(ISD::BUILD_PAIR, SDLoc(Op), VT, Result[0], Result[1]);
   }
 
   RTLIB::Libcall LC;
-  bool isSigned;
   switch (Op->getOpcode()) {
-  // clang-format off
+    // clang-format off
   default: llvm_unreachable("Unexpected request for libcall!");
-  case ISD::SDIV:      isSigned = true;  LC = RTLIB::SDIV_I128;    break;
-  case ISD::UDIV:      isSigned = false; LC = RTLIB::UDIV_I128;    break;
-  case ISD::SREM:      isSigned = true;  LC = RTLIB::SREM_I128;    break;
-  case ISD::UREM:      isSigned = false; LC = RTLIB::UREM_I128;    break;
-  // clang-format on
+  case ISD::MUL:       LC = RTLIB::MUL_I128;   break;
+  case ISD::SDIV:      LC = RTLIB::SDIV_I128;  break;
+  case ISD::UDIV:      LC = RTLIB::UDIV_I128;  break;
+  case ISD::SREM:      LC = RTLIB::SREM_I128;  break;
+  case ISD::UREM:      LC = RTLIB::UREM_I128;  break;
+    // clang-format on
   }
 
-  SDLoc dl(Op);
-  SDValue InChain = DAG.getEntryNode();
-
-  TargetLowering::ArgListTy Args;
-  for (unsigned i = 0, e = Op->getNumOperands(); i != e; ++i) {
-    EVT ArgVT = Op->getOperand(i).getValueType();
+  SmallVector<SDValue, 2> IndirectArgs(Op->op_begin(), Op->op_end());
+  for (auto Arg : IndirectArgs) {
+    [[maybe_unused]] EVT ArgVT = Arg.getValueType();
     assert(ArgVT.isInteger() && ArgVT.getSizeInBits() == 128 &&
            "Unexpected argument type for lowering");
-    SDValue StackPtr = DAG.CreateStackTemporary(ArgVT, 16);
-    int SPFI = cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex();
-    MachinePointerInfo MPI =
-        MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), SPFI);
-    InChain =
-        DAG.getStore(InChain, dl, Op->getOperand(i), StackPtr, MPI, Align(16));
-    Args.emplace_back(StackPtr, PointerType::get(*DAG.getContext(), 0));
   }
-
-  RTLIB::LibcallImpl LCImpl = DAG.getLibcalls().getLibcallImpl(LC);
-  if (LCImpl == RTLIB::Unsupported)
-    return SDValue();
-
-  SDValue Callee =
-      DAG.getExternalSymbol(LCImpl, getPointerTy(DAG.getDataLayout()));
-
-  TargetLowering::CallLoweringInfo CLI(DAG);
-  CLI.setDebugLoc(dl)
-      .setChain(InChain)
-      .setLibCallee(DAG.getLibcalls().getLibcallImplCallingConv(LCImpl),
-                    EVT(MVT::v2i64).getTypeForEVT(*DAG.getContext()), Callee,
-                    std::move(Args))
-      .setInRegister()
-      .setSExtResult(isSigned)
-      .setZExtResult(!isSigned);
-
-  std::pair<SDValue, SDValue> CallInfo = LowerCallTo(CLI);
-  return DAG.getBitcast(VT, CallInfo.first);
+  SDValue InChain = DAG.getEntryNode();
+  return lowerWin64IndirectI128Libcall(DAG, SDLoc(Op), VT, LC, IndirectArgs,
+                                       InChain);
 }
 
 SDValue X86TargetLowering::LowerWin64_FP_TO_INT128(SDValue Op,
@@ -30718,16 +30744,10 @@ SDValue 
X86TargetLowering::LowerWin64_FP_TO_INT128(SDValue Op,
   assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpected request for libcall!");
 
   SDLoc dl(Op);
-  MakeLibCallOptions CallOptions;
   Chain = IsStrict ? Op.getOperand(0) : DAG.getEntryNode();
 
-  SDValue Result;
-  // Expect the i128 argument returned as a v2i64 in xmm0, cast back to the
-  // expected VT (i128).
-  std::tie(Result, Chain) =
-      makeLibCall(DAG, LC, MVT::v2i64, Arg, CallOptions, dl, Chain);
-  Result = DAG.getBitcast(VT, Result);
-  return Result;
+  SmallVector<SDValue, 1> IndirectArgs = {Arg};
+  return lowerWin64IndirectI128Libcall(DAG, dl, VT, LC, IndirectArgs, Chain);
 }
 
 SDValue X86TargetLowering::LowerWin64_INT128_TO_FP(SDValue Op,
@@ -34999,6 +35019,12 @@ void X86TargetLowering::ReplaceNodeResults(SDNode *N,
   }
   case ISD::MUL: {
     EVT VT = N->getValueType(0);
+    if (VT == MVT::i128) {
+      SDValue V = LowerWin64_i128OP(SDValue(N, 0), DAG);
+      Results.push_back(V);
+      return;
+    }
+
     assert(getTypeAction(*DAG.getContext(), VT) == TypeWidenVector &&
            VT.getVectorElementType() == MVT::i8 && "Unexpected VT!");
     // Pre-promote these to vXi16 to avoid op legalization thinking all 16
diff --git a/llvm/lib/Target/X86/X86ISelLowering.h 
b/llvm/lib/Target/X86/X86ISelLowering.h
index 798050028c15a..ff5ade5643a07 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.h
+++ b/llvm/lib/Target/X86/X86ISelLowering.h
@@ -840,6 +840,10 @@ namespace llvm {
     SDValue LowerGET_FPENV_MEM(SDValue Op, SelectionDAG &DAG) const;
     SDValue LowerSET_FPENV_MEM(SDValue Op, SelectionDAG &DAG) const;
     SDValue LowerRESET_FPENV(SDValue Op, SelectionDAG &DAG) const;
+    SDValue lowerWin64IndirectI128Libcall(SelectionDAG &DAG, const SDLoc &DL,
+                                          EVT RetVT, RTLIB::Libcall LC,
+                                          ArrayRef<SDValue> IndirectArgs,
+                                          SDValue &Chain) const;
     SDValue LowerWin64_i128OP(SDValue Op, SelectionDAG &DAG) const;
     SDValue LowerWin64_FP_TO_INT128(SDValue Op, SelectionDAG &DAG,
                                     SDValue &Chain) const;
diff --git a/llvm/lib/Target/X86/X86ISelLoweringCall.cpp 
b/llvm/lib/Target/X86/X86ISelLoweringCall.cpp
index 8f14198cf268b..ea3b0af428a5b 100644
--- a/llvm/lib/Target/X86/X86ISelLoweringCall.cpp
+++ b/llvm/lib/Target/X86/X86ISelLoweringCall.cpp
@@ -671,9 +671,9 @@ bool X86TargetLowering::CanLowerReturn(
     CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg,
     const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context,
     const Type *RetTy) const {
-  // Mingw64 GCC returns f128 via sret, and LLVM matches it for compatibility.
-  // This logic exists for libcalls, a frontend should explicitly use sret
-  // rather than rely on the sret demotion here.
+  // Match the frontend ABI lowering for Win64 i128 and for mingw64 f128
+  // libcalls. A frontend should explicitly use sret rather than rely on the
+  // sret demotion here.
   //
   // Using sret is a reasonable implementation of the Windows x64 calling
   // convention:
@@ -704,8 +704,9 @@ bool X86TargetLowering::CanLowerReturn(
   };
 
   if (IsWin64F128StackCC(CallConv) &&
-      llvm::any_of(
-          Outs, [](const ISD::OutputArg &Out) { return Out.VT == MVT::f128; }))
+      llvm::any_of(Outs, [](const ISD::OutputArg &Out) {
+        return Out.VT == MVT::f128 || Out.VT == MVT::i128;
+      }))
     return false;
 
   SmallVector<CCValAssign, 16> RVLocs;
diff --git a/llvm/test/CodeGen/X86/divmod128.ll 
b/llvm/test/CodeGen/X86/divmod128.ll
index b6d7c6724f394..e6860c0b924ae 100644
--- a/llvm/test/CodeGen/X86/divmod128.ll
+++ b/llvm/test/CodeGen/X86/divmod128.ll
@@ -16,16 +16,17 @@ define i64 @mod128(i128 %x) nounwind {
 ;
 ; WIN64-LABEL: mod128:
 ; WIN64:       # %bb.0:
-; WIN64-NEXT:    subq $72, %rsp
+; WIN64-NEXT:    subq $88, %rsp
 ; WIN64-NEXT:    movq %rdx, {{[0-9]+}}(%rsp)
 ; WIN64-NEXT:    movq %rcx, {{[0-9]+}}(%rsp)
 ; WIN64-NEXT:    movq $3, {{[0-9]+}}(%rsp)
 ; WIN64-NEXT:    movq $0, {{[0-9]+}}(%rsp)
 ; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
 ; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %r8
 ; WIN64-NEXT:    callq __modti3
-; WIN64-NEXT:    movq %xmm0, %rax
-; WIN64-NEXT:    addq $72, %rsp
+; WIN64-NEXT:    movq {{[0-9]+}}(%rsp), %rax
+; WIN64-NEXT:    addq $88, %rsp
 ; WIN64-NEXT:    retq
 
 
@@ -46,16 +47,17 @@ define i64 @div128(i128 %x) nounwind {
 ;
 ; WIN64-LABEL: div128:
 ; WIN64:       # %bb.0:
-; WIN64-NEXT:    subq $72, %rsp
+; WIN64-NEXT:    subq $88, %rsp
 ; WIN64-NEXT:    movq %rdx, {{[0-9]+}}(%rsp)
 ; WIN64-NEXT:    movq %rcx, {{[0-9]+}}(%rsp)
 ; WIN64-NEXT:    movq $3, {{[0-9]+}}(%rsp)
 ; WIN64-NEXT:    movq $0, {{[0-9]+}}(%rsp)
 ; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
 ; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %r8
 ; WIN64-NEXT:    callq __divti3
-; WIN64-NEXT:    movq %xmm0, %rax
-; WIN64-NEXT:    addq $72, %rsp
+; WIN64-NEXT:    movq {{[0-9]+}}(%rsp), %rax
+; WIN64-NEXT:    addq $88, %rsp
 ; WIN64-NEXT:    retq
 
 
@@ -128,17 +130,30 @@ define i64 @udiv128(i128 %x) nounwind {
 ;
 ; WIN64-LABEL: udiv128:
 ; WIN64:       # %bb.0:
+; WIN64-NEXT:    subq $88, %rsp
 ; WIN64-NEXT:    movq %rdx, %r8
-; WIN64-NEXT:    addq %rcx, %r8
-; WIN64-NEXT:    adcq $0, %r8
-; WIN64-NEXT:    movabsq $-6148914691236517205, %r9 # imm = 0xAAAAAAAAAAAAAAAB
-; WIN64-NEXT:    movq %r8, %rax
-; WIN64-NEXT:    mulq %r9
+; WIN64-NEXT:    movabsq $-6148914691236517205, %rdx # imm = 0xAAAAAAAAAAAAAAAB
+; WIN64-NEXT:    movq %rdx, {{[0-9]+}}(%rsp)
+; WIN64-NEXT:    movabsq $-6148914691236517206, %rax # imm = 0xAAAAAAAAAAAAAAAA
+; WIN64-NEXT:    movq %rax, {{[0-9]+}}(%rsp)
+; WIN64-NEXT:    movq %rcx, %r9
+; WIN64-NEXT:    addq %r8, %r9
+; WIN64-NEXT:    adcq $0, %r9
+; WIN64-NEXT:    movq %r9, %rax
+; WIN64-NEXT:    mulq %rdx
 ; WIN64-NEXT:    shrq %rdx
 ; WIN64-NEXT:    leaq (%rdx,%rdx,2), %rax
-; WIN64-NEXT:    subq %r8, %rax
-; WIN64-NEXT:    addq %rcx, %rax
-; WIN64-NEXT:    imulq %r9, %rax
+; WIN64-NEXT:    subq %rax, %r9
+; WIN64-NEXT:    subq %r9, %rcx
+; WIN64-NEXT:    movq %rcx, {{[0-9]+}}(%rsp)
+; WIN64-NEXT:    sbbq $0, %r8
+; WIN64-NEXT:    movq %r8, {{[0-9]+}}(%rsp)
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %r8
+; WIN64-NEXT:    callq __multi3
+; WIN64-NEXT:    movq {{[0-9]+}}(%rsp), %rax
+; WIN64-NEXT:    addq $88, %rsp
 ; WIN64-NEXT:    retq
 
 
@@ -505,25 +520,31 @@ define i128 @udiv_i128_3(i128 %x) nounwind {
 ;
 ; WIN64-LABEL: udiv_i128_3:
 ; WIN64:       # %bb.0: # %entry
+; WIN64-NEXT:    subq $88, %rsp
 ; WIN64-NEXT:    movq %rdx, %r8
+; WIN64-NEXT:    movabsq $-6148914691236517205, %rdx # imm = 0xAAAAAAAAAAAAAAAB
+; WIN64-NEXT:    movq %rdx, {{[0-9]+}}(%rsp)
+; WIN64-NEXT:    movabsq $-6148914691236517206, %rax # imm = 0xAAAAAAAAAAAAAAAA
+; WIN64-NEXT:    movq %rax, {{[0-9]+}}(%rsp)
 ; WIN64-NEXT:    movq %rcx, %r9
-; WIN64-NEXT:    addq %rdx, %r9
+; WIN64-NEXT:    addq %r8, %r9
 ; WIN64-NEXT:    adcq $0, %r9
-; WIN64-NEXT:    movabsq $-6148914691236517205, %r10 # imm = 0xAAAAAAAAAAAAAAAB
 ; WIN64-NEXT:    movq %r9, %rax
-; WIN64-NEXT:    mulq %r10
+; WIN64-NEXT:    mulq %rdx
 ; WIN64-NEXT:    shrq %rdx
 ; WIN64-NEXT:    leaq (%rdx,%rdx,2), %rax
 ; WIN64-NEXT:    subq %rax, %r9
 ; WIN64-NEXT:    subq %r9, %rcx
+; WIN64-NEXT:    movq %rcx, {{[0-9]+}}(%rsp)
 ; WIN64-NEXT:    sbbq $0, %r8
-; WIN64-NEXT:    movabsq $-6148914691236517206, %r9 # imm = 0xAAAAAAAAAAAAAAAA
-; WIN64-NEXT:    imulq %rcx, %r9
-; WIN64-NEXT:    movq %rcx, %rax
-; WIN64-NEXT:    mulq %r10
-; WIN64-NEXT:    addq %r9, %rdx
-; WIN64-NEXT:    imulq %r10, %r8
-; WIN64-NEXT:    addq %r8, %rdx
+; WIN64-NEXT:    movq %r8, {{[0-9]+}}(%rsp)
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %r8
+; WIN64-NEXT:    callq __multi3
+; WIN64-NEXT:    movq {{[0-9]+}}(%rsp), %rax
+; WIN64-NEXT:    movq {{[0-9]+}}(%rsp), %rdx
+; WIN64-NEXT:    addq $88, %rsp
 ; WIN64-NEXT:    retq
 entry:
   %rem = udiv i128 %x, 3
@@ -555,25 +576,31 @@ define i128 @udiv_i128_5(i128 %x) nounwind {
 ;
 ; WIN64-LABEL: udiv_i128_5:
 ; WIN64:       # %bb.0: # %entry
+; WIN64-NEXT:    subq $88, %rsp
 ; WIN64-NEXT:    movq %rdx, %r8
+; WIN64-NEXT:    movabsq $-3689348814741910323, %rdx # imm = 0xCCCCCCCCCCCCCCCD
+; WIN64-NEXT:    movq %rdx, {{[0-9]+}}(%rsp)
+; WIN64-NEXT:    movabsq $-3689348814741910324, %rax # imm = 0xCCCCCCCCCCCCCCCC
+; WIN64-NEXT:    movq %rax, {{[0-9]+}}(%rsp)
 ; WIN64-NEXT:    movq %rcx, %r9
-; WIN64-NEXT:    addq %rdx, %r9
+; WIN64-NEXT:    addq %r8, %r9
 ; WIN64-NEXT:    adcq $0, %r9
-; WIN64-NEXT:    movabsq $-3689348814741910323, %r10 # imm = 0xCCCCCCCCCCCCCCCD
 ; WIN64-NEXT:    movq %r9, %rax
-; WIN64-NEXT:    mulq %r10
+; WIN64-NEXT:    mulq %rdx
 ; WIN64-NEXT:    shrq $2, %rdx
 ; WIN64-NEXT:    leaq (%rdx,%rdx,4), %rax
 ; WIN64-NEXT:    subq %rax, %r9
 ; WIN64-NEXT:    subq %r9, %rcx
+; WIN64-NEXT:    movq %rcx, {{[0-9]+}}(%rsp)
 ; WIN64-NEXT:    sbbq $0, %r8
-; WIN64-NEXT:    movabsq $-3689348814741910324, %r9 # imm = 0xCCCCCCCCCCCCCCCC
-; WIN64-NEXT:    imulq %rcx, %r9
-; WIN64-NEXT:    movq %rcx, %rax
-; WIN64-NEXT:    mulq %r10
-; WIN64-NEXT:    addq %r9, %rdx
-; WIN64-NEXT:    imulq %r10, %r8
-; WIN64-NEXT:    addq %r8, %rdx
+; WIN64-NEXT:    movq %r8, {{[0-9]+}}(%rsp)
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %r8
+; WIN64-NEXT:    callq __multi3
+; WIN64-NEXT:    movq {{[0-9]+}}(%rsp), %rax
+; WIN64-NEXT:    movq {{[0-9]+}}(%rsp), %rdx
+; WIN64-NEXT:    addq $88, %rsp
 ; WIN64-NEXT:    retq
 entry:
   %rem = udiv i128 %x, 5
@@ -607,7 +634,12 @@ define i128 @udiv_i128_15(i128 %x) nounwind {
 ;
 ; WIN64-LABEL: udiv_i128_15:
 ; WIN64:       # %bb.0: # %entry
+; WIN64-NEXT:    subq $88, %rsp
 ; WIN64-NEXT:    movq %rdx, %r8
+; WIN64-NEXT:    movabsq $-1229782938247303441, %rax # imm = 0xEEEEEEEEEEEEEEEF
+; WIN64-NEXT:    movq %rax, {{[0-9]+}}(%rsp)
+; WIN64-NEXT:    movabsq $-1229782938247303442, %rax # imm = 0xEEEEEEEEEEEEEEEE
+; WIN64-NEXT:    movq %rax, {{[0-9]+}}(%rsp)
 ; WIN64-NEXT:    movq %rcx, %r9
 ; WIN64-NEXT:    addq %rdx, %r9
 ; WIN64-NEXT:    adcq $0, %r9
@@ -619,15 +651,16 @@ define i128 @udiv_i128_15(i128 %x) nounwind {
 ; WIN64-NEXT:    leaq (%rax,%rax,2), %rax
 ; WIN64-NEXT:    subq %rax, %r9
 ; WIN64-NEXT:    subq %r9, %rcx
+; WIN64-NEXT:    movq %rcx, {{[0-9]+}}(%rsp)
 ; WIN64-NEXT:    sbbq $0, %r8
-; WIN64-NEXT:    movabsq $-1229782938247303442, %r9 # imm = 0xEEEEEEEEEEEEEEEE
-; WIN64-NEXT:    imulq %rcx, %r9
-; WIN64-NEXT:    movabsq $-1229782938247303441, %r10 # imm = 0xEEEEEEEEEEEEEEEF
-; WIN64-NEXT:    movq %rcx, %rax
-; WIN64-NEXT:    mulq %r10
-; WIN64-NEXT:    addq %r9, %rdx
-; WIN64-NEXT:    imulq %r10, %r8
-; WIN64-NEXT:    addq %r8, %rdx
+; WIN64-NEXT:    movq %r8, {{[0-9]+}}(%rsp)
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %r8
+; WIN64-NEXT:    callq __multi3
+; WIN64-NEXT:    movq {{[0-9]+}}(%rsp), %rax
+; WIN64-NEXT:    movq {{[0-9]+}}(%rsp), %rdx
+; WIN64-NEXT:    addq $88, %rsp
 ; WIN64-NEXT:    retq
 entry:
   %rem = udiv i128 %x, 15
@@ -661,27 +694,33 @@ define i128 @udiv_i128_17(i128 %x) nounwind {
 ;
 ; WIN64-LABEL: udiv_i128_17:
 ; WIN64:       # %bb.0: # %entry
+; WIN64-NEXT:    subq $88, %rsp
 ; WIN64-NEXT:    movq %rdx, %r8
+; WIN64-NEXT:    movabsq $-1085102592571150095, %rdx # imm = 0xF0F0F0F0F0F0F0F1
+; WIN64-NEXT:    movq %rdx, {{[0-9]+}}(%rsp)
+; WIN64-NEXT:    movabsq $-1085102592571150096, %rax # imm = 0xF0F0F0F0F0F0F0F0
+; WIN64-NEXT:    movq %rax, {{[0-9]+}}(%rsp)
 ; WIN64-NEXT:    movq %rcx, %r9
-; WIN64-NEXT:    addq %rdx, %r9
+; WIN64-NEXT:    addq %r8, %r9
 ; WIN64-NEXT:    adcq $0, %r9
-; WIN64-NEXT:    movabsq $-1085102592571150095, %r10 # imm = 0xF0F0F0F0F0F0F0F1
 ; WIN64-NEXT:    movq %r9, %rax
-; WIN64-NEXT:    mulq %r10
+; WIN64-NEXT:    mulq %rdx
 ; WIN64-NEXT:    movq %rdx, %rax
 ; WIN64-NEXT:    andq $-16, %rax
 ; WIN64-NEXT:    shrq $4, %rdx
 ; WIN64-NEXT:    addq %rax, %rdx
 ; WIN64-NEXT:    subq %rdx, %r9
 ; WIN64-NEXT:    subq %r9, %rcx
+; WIN64-NEXT:    movq %rcx, {{[0-9]+}}(%rsp)
 ; WIN64-NEXT:    sbbq $0, %r8
-; WIN64-NEXT:    movabsq $-1085102592571150096, %r9 # imm = 0xF0F0F0F0F0F0F0F0
-; WIN64-NEXT:    imulq %rcx, %r9
-; WIN64-NEXT:    movq %rcx, %rax
-; WIN64-NEXT:    mulq %r10
-; WIN64-NEXT:    addq %r9, %rdx
-; WIN64-NEXT:    imulq %r10, %r8
-; WIN64-NEXT:    addq %r8, %rdx
+; WIN64-NEXT:    movq %r8, {{[0-9]+}}(%rsp)
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %r8
+; WIN64-NEXT:    callq __multi3
+; WIN64-NEXT:    movq {{[0-9]+}}(%rsp), %rax
+; WIN64-NEXT:    movq {{[0-9]+}}(%rsp), %rdx
+; WIN64-NEXT:    addq $88, %rsp
 ; WIN64-NEXT:    retq
 entry:
   %rem = udiv i128 %x, 17
@@ -717,6 +756,7 @@ define i128 @udiv_i128_255(i128 %x) nounwind {
 ;
 ; WIN64-LABEL: udiv_i128_255:
 ; WIN64:       # %bb.0: # %entry
+; WIN64-NEXT:    subq $88, %rsp
 ; WIN64-NEXT:    movq %rdx, %r8
 ; WIN64-NEXT:    movq %rcx, %rax
 ; WIN64-NEXT:    addq %rdx, %rax
@@ -729,17 +769,22 @@ define i128 @udiv_i128_255(i128 %x) nounwind {
 ; WIN64-NEXT:    subq %rax, %rdx
 ; WIN64-NEXT:    movq %rcx, %rax
 ; WIN64-NEXT:    addq %r8, %rax
+; WIN64-NEXT:    movabsq $-72340172838076673, %r9 # imm = 0xFEFEFEFEFEFEFEFF
+; WIN64-NEXT:    movq %r9, {{[0-9]+}}(%rsp)
+; WIN64-NEXT:    movabsq $-72340172838076674, %r9 # imm = 0xFEFEFEFEFEFEFEFE
+; WIN64-NEXT:    movq %r9, {{[0-9]+}}(%rsp)
 ; WIN64-NEXT:    adcq %rdx, %rax
 ; WIN64-NEXT:    subq %rax, %rcx
+; WIN64-NEXT:    movq %rcx, {{[0-9]+}}(%rsp)
 ; WIN64-NEXT:    sbbq $0, %r8
-; WIN64-NEXT:    movabsq $-72340172838076674, %r9 # imm = 0xFEFEFEFEFEFEFEFE
-; WIN64-NEXT:    imulq %rcx, %r9
-; WIN64-NEXT:    movabsq $-72340172838076673, %r10 # imm = 0xFEFEFEFEFEFEFEFF
-; WIN64-NEXT:    movq %rcx, %rax
-; WIN64-NEXT:    mulq %r10
-; WIN64-NEXT:    addq %r9, %rdx
-; WIN64-NEXT:    imulq %r10, %r8
-; WIN64-NEXT:    addq %r8, %rdx
+; WIN64-NEXT:    movq %r8, {{[0-9]+}}(%rsp)
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %r8
+; WIN64-NEXT:    callq __multi3
+; WIN64-NEXT:    movq {{[0-9]+}}(%rsp), %rax
+; WIN64-NEXT:    movq {{[0-9]+}}(%rsp), %rdx
+; WIN64-NEXT:    addq $88, %rsp
 ; WIN64-NEXT:    retq
 entry:
   %rem = udiv i128 %x, 255
@@ -773,27 +818,33 @@ define i128 @udiv_i128_257(i128 %x) nounwind {
 ;
 ; WIN64-LABEL: udiv_i128_257:
 ; WIN64:       # %bb.0: # %entry
+; WIN64-NEXT:    subq $88, %rsp
 ; WIN64-NEXT:    movq %rdx, %r8
+; WIN64-NEXT:    movabsq $-71777214294589695, %rdx # imm = 0xFF00FF00FF00FF01
+; WIN64-NEXT:    movq %rdx, {{[0-9]+}}(%rsp)
+; WIN64-NEXT:    movabsq $-71777214294589696, %rax # imm = 0xFF00FF00FF00FF00
+; WIN64-NEXT:    movq %rax, {{[0-9]+}}(%rsp)
 ; WIN64-NEXT:    movq %rcx, %r9
-; WIN64-NEXT:    addq %rdx, %r9
+; WIN64-NEXT:    addq %r8, %r9
 ; WIN64-NEXT:    adcq $0, %r9
-; WIN64-NEXT:    movabsq $-71777214294589695, %r10 # imm = 0xFF00FF00FF00FF01
 ; WIN64-NEXT:    movq %r9, %rax
-; WIN64-NEXT:    mulq %r10
+; WIN64-NEXT:    mulq %rdx
 ; WIN64-NEXT:    movq %rdx, %rax
 ; WIN64-NEXT:    andq $-256, %rax
 ; WIN64-NEXT:    shrq $8, %rdx
 ; WIN64-NEXT:    addq %rax, %rdx
 ; WIN64-NEXT:    subq %rdx, %r9
 ; WIN64-NEXT:    subq %r9, %rcx
+; WIN64-NEXT:    movq %rcx, {{[0-9]+}}(%rsp)
 ; WIN64-NEXT:    sbbq $0, %r8
-; WIN64-NEXT:    movabsq $-71777214294589696, %r9 # imm = 0xFF00FF00FF00FF00
-; WIN64-NEXT:    imulq %rcx, %r9
-; WIN64-NEXT:    movq %rcx, %rax
-; WIN64-NEXT:    mulq %r10
-; WIN64-NEXT:    addq %r9, %rdx
-; WIN64-NEXT:    imulq %r10, %r8
-; WIN64-NEXT:    addq %r8, %rdx
+; WIN64-NEXT:    movq %r8, {{[0-9]+}}(%rsp)
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %r8
+; WIN64-NEXT:    callq __multi3
+; WIN64-NEXT:    movq {{[0-9]+}}(%rsp), %rax
+; WIN64-NEXT:    movq {{[0-9]+}}(%rsp), %rdx
+; WIN64-NEXT:    addq $88, %rsp
 ; WIN64-NEXT:    retq
 entry:
   %rem = udiv i128 %x, 257
@@ -829,6 +880,7 @@ define i128 @udiv_i128_65535(i128 %x) nounwind {
 ;
 ; WIN64-LABEL: udiv_i128_65535:
 ; WIN64:       # %bb.0: # %entry
+; WIN64-NEXT:    subq $88, %rsp
 ; WIN64-NEXT:    movq %rdx, %r8
 ; WIN64-NEXT:    movq %rcx, %rax
 ; WIN64-NEXT:    addq %rdx, %rax
@@ -841,17 +893,22 @@ define i128 @udiv_i128_65535(i128 %x) nounwind {
 ; WIN64-NEXT:    subq %rax, %rdx
 ; WIN64-NEXT:    movq %rcx, %rax
 ; WIN64-NEXT:    addq %r8, %rax
+; WIN64-NEXT:    movabsq $-281479271743489, %r9 # imm = 0xFFFEFFFEFFFEFFFF
+; WIN64-NEXT:    movq %r9, {{[0-9]+}}(%rsp)
+; WIN64-NEXT:    movabsq $-281479271743490, %r9 # imm = 0xFFFEFFFEFFFEFFFE
+; WIN64-NEXT:    movq %r9, {{[0-9]+}}(%rsp)
 ; WIN64-NEXT:    adcq %rdx, %rax
 ; WIN64-NEXT:    subq %rax, %rcx
+; WIN64-NEXT:    movq %rcx, {{[0-9]+}}(%rsp)
 ; WIN64-NEXT:    sbbq $0, %r8
-; WIN64-NEXT:    movabsq $-281479271743490, %r9 # imm = 0xFFFEFFFEFFFEFFFE
-; WIN64-NEXT:    imulq %rcx, %r9
-; WIN64-NEXT:    movabsq $-281479271743489, %r10 # imm = 0xFFFEFFFEFFFEFFFF
-; WIN64-NEXT:    movq %rcx, %rax
-; WIN64-NEXT:    mulq %r10
-; WIN64-NEXT:    addq %r9, %rdx
-; WIN64-NEXT:    imulq %r10, %r8
-; WIN64-NEXT:    addq %r8, %rdx
+; WIN64-NEXT:    movq %r8, {{[0-9]+}}(%rsp)
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %r8
+; WIN64-NEXT:    callq __multi3
+; WIN64-NEXT:    movq {{[0-9]+}}(%rsp), %rax
+; WIN64-NEXT:    movq {{[0-9]+}}(%rsp), %rdx
+; WIN64-NEXT:    addq $88, %rsp
 ; WIN64-NEXT:    retq
 entry:
   %rem = udiv i128 %x, 65535
@@ -885,27 +942,33 @@ define i128 @udiv_i128_65537(i128 %x) nounwind {
 ;
 ; WIN64-LABEL: udiv_i128_65537:
 ; WIN64:       # %bb.0: # %entry
+; WIN64-NEXT:    subq $88, %rsp
 ; WIN64-NEXT:    movq %rdx, %r8
+; WIN64-NEXT:    movabsq $-281470681808895, %rdx # imm = 0xFFFF0000FFFF0001
+; WIN64-NEXT:    movq %rdx, {{[0-9]+}}(%rsp)
+; WIN64-NEXT:    movabsq $-281470681808896, %rax # imm = 0xFFFF0000FFFF0000
+; WIN64-NEXT:    movq %rax, {{[0-9]+}}(%rsp)
 ; WIN64-NEXT:    movq %rcx, %r9
-; WIN64-NEXT:    addq %rdx, %r9
+; WIN64-NEXT:    addq %r8, %r9
 ; WIN64-NEXT:    adcq $0, %r9
-; WIN64-NEXT:    movabsq $-281470681808895, %r10 # imm = 0xFFFF0000FFFF0001
 ; WIN64-NEXT:    movq %r9, %rax
-; WIN64-NEXT:    mulq %r10
+; WIN64-NEXT:    mulq %rdx
 ; WIN64-NEXT:    movq %rdx, %rax
 ; WIN64-NEXT:    andq $-65536, %rax # imm = 0xFFFF0000
 ; WIN64-NEXT:    shrq $16, %rdx
 ; WIN64-NEXT:    addq %rax, %rdx
 ; WIN64-NEXT:    subq %rdx, %r9
 ; WIN64-NEXT:    subq %r9, %rcx
+; WIN64-NEXT:    movq %rcx, {{[0-9]+}}(%rsp)
 ; WIN64-NEXT:    sbbq $0, %r8
-; WIN64-NEXT:    movabsq $-281470681808896, %r9 # imm = 0xFFFF0000FFFF0000
-; WIN64-NEXT:    imulq %rcx, %r9
-; WIN64-NEXT:    movq %rcx, %rax
-; WIN64-NEXT:    mulq %r10
-; WIN64-NEXT:    addq %r9, %rdx
-; WIN64-NEXT:    imulq %r10, %r8
-; WIN64-NEXT:    addq %r8, %rdx
+; WIN64-NEXT:    movq %r8, {{[0-9]+}}(%rsp)
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %r8
+; WIN64-NEXT:    callq __multi3
+; WIN64-NEXT:    movq {{[0-9]+}}(%rsp), %rax
+; WIN64-NEXT:    movq {{[0-9]+}}(%rsp), %rdx
+; WIN64-NEXT:    addq $88, %rsp
 ; WIN64-NEXT:    retq
 entry:
   %rem = udiv i128 %x, 65537
@@ -939,27 +1002,33 @@ define i128 @udiv_i128_12(i128 %x) nounwind {
 ;
 ; WIN64-LABEL: udiv_i128_12:
 ; WIN64:       # %bb.0: # %entry
+; WIN64-NEXT:    subq $88, %rsp
 ; WIN64-NEXT:    movq %rdx, %r8
-; WIN64-NEXT:    shrdq $2, %rdx, %rcx
+; WIN64-NEXT:    movabsq $-6148914691236517205, %rdx # imm = 0xAAAAAAAAAAAAAAAB
+; WIN64-NEXT:    movq %rdx, {{[0-9]+}}(%rsp)
+; WIN64-NEXT:    movabsq $-6148914691236517206, %rax # imm = 0xAAAAAAAAAAAAAAAA
+; WIN64-NEXT:    movq %rax, {{[0-9]+}}(%rsp)
+; WIN64-NEXT:    shrdq $2, %r8, %rcx
 ; WIN64-NEXT:    shrq $2, %r8
 ; WIN64-NEXT:    movq %rcx, %r9
 ; WIN64-NEXT:    addq %r8, %r9
 ; WIN64-NEXT:    adcq $0, %r9
-; WIN64-NEXT:    movabsq $-6148914691236517205, %r10 # imm = 0xAAAAAAAAAAAAAAAB
 ; WIN64-NEXT:    movq %r9, %rax
-; WIN64-NEXT:    mulq %r10
+; WIN64-NEXT:    mulq %rdx
 ; WIN64-NEXT:    shrq %rdx
 ; WIN64-NEXT:    leaq (%rdx,%rdx,2), %rax
 ; WIN64-NEXT:    subq %rax, %r9
 ; WIN64-NEXT:    subq %r9, %rcx
+; WIN64-NEXT:    movq %rcx, {{[0-9]+}}(%rsp)
 ; WIN64-NEXT:    sbbq $0, %r8
-; WIN64-NEXT:    movabsq $-6148914691236517206, %r9 # imm = 0xAAAAAAAAAAAAAAAA
-; WIN64-NEXT:    imulq %rcx, %r9
-; WIN64-NEXT:    movq %rcx, %rax
-; WIN64-NEXT:    mulq %r10
-; WIN64-NEXT:    addq %r9, %rdx
-; WIN64-NEXT:    imulq %r10, %r8
-; WIN64-NEXT:    addq %r8, %rdx
+; WIN64-NEXT:    movq %r8, {{[0-9]+}}(%rsp)
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %r8
+; WIN64-NEXT:    callq __multi3
+; WIN64-NEXT:    movq {{[0-9]+}}(%rsp), %rax
+; WIN64-NEXT:    movq {{[0-9]+}}(%rsp), %rdx
+; WIN64-NEXT:    addq $88, %rsp
 ; WIN64-NEXT:    retq
 entry:
   %rem = udiv i128 %x, 12
@@ -980,19 +1049,22 @@ define i128 @urem_i128_3_minsize(i128 %x) nounwind 
minsize {
 ;
 ; WIN64-LABEL: urem_i128_3_minsize:
 ; WIN64:       # %bb.0: # %entry
-; WIN64-NEXT:    subq $72, %rsp
+; WIN64-NEXT:    pushq %rsi
+; WIN64-NEXT:    subq $80, %rsp
 ; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rax
 ; WIN64-NEXT:    movq %rdx, 8(%rax)
 ; WIN64-NEXT:    movq %rcx, (%rax)
-; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
-; WIN64-NEXT:    movq $3, (%rdx)
-; WIN64-NEXT:    andq $0, 8(%rdx)
-; WIN64-NEXT:    movq %rax, %rcx
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %r8
+; WIN64-NEXT:    movq $3, (%r8)
+; WIN64-NEXT:    andq $0, 8(%r8)
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rsi
+; WIN64-NEXT:    movq %rsi, %rcx
+; WIN64-NEXT:    movq %rax, %rdx
 ; WIN64-NEXT:    callq __umodti3
-; WIN64-NEXT:    movq %xmm0, %rax
-; WIN64-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,3,2,3]
-; WIN64-NEXT:    movq %xmm0, %rdx
-; WIN64-NEXT:    addq $72, %rsp
+; WIN64-NEXT:    movq (%rsi), %rax
+; WIN64-NEXT:    movq 8(%rsi), %rdx
+; WIN64-NEXT:    addq $80, %rsp
+; WIN64-NEXT:    popq %rsi
 ; WIN64-NEXT:    retq
 entry:
   %rem = urem i128 %x, 3
@@ -1012,19 +1084,22 @@ define i128 @urem_i128_3_optsize(i128 %x) nounwind 
optsize {
 ;
 ; WIN64-LABEL: urem_i128_3_optsize:
 ; WIN64:       # %bb.0: # %entry
-; WIN64-NEXT:    subq $72, %rsp
+; WIN64-NEXT:    pushq %rsi
+; WIN64-NEXT:    subq $80, %rsp
 ; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rax
 ; WIN64-NEXT:    movq %rdx, 8(%rax)
 ; WIN64-NEXT:    movq %rcx, (%rax)
-; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
-; WIN64-NEXT:    movq $3, (%rdx)
-; WIN64-NEXT:    movq $0, 8(%rdx)
-; WIN64-NEXT:    movq %rax, %rcx
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %r8
+; WIN64-NEXT:    movq $3, (%r8)
+; WIN64-NEXT:    movq $0, 8(%r8)
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rsi
+; WIN64-NEXT:    movq %rsi, %rcx
+; WIN64-NEXT:    movq %rax, %rdx
 ; WIN64-NEXT:    callq __umodti3
-; WIN64-NEXT:    movq %xmm0, %rax
-; WIN64-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,3,2,3]
-; WIN64-NEXT:    movq %xmm0, %rdx
-; WIN64-NEXT:    addq $72, %rsp
+; WIN64-NEXT:    movq (%rsi), %rax
+; WIN64-NEXT:    movq 8(%rsi), %rdx
+; WIN64-NEXT:    addq $80, %rsp
+; WIN64-NEXT:    popq %rsi
 ; WIN64-NEXT:    retq
 entry:
   %rem = urem i128 %x, 3
@@ -1066,7 +1141,12 @@ define i128 @udiv_i128_100(i128 %x) nounwind {
 ;
 ; WIN64-LABEL: udiv_i128_100:
 ; WIN64:       # %bb.0: # %entry
+; WIN64-NEXT:    subq $88, %rsp
 ; WIN64-NEXT:    movq %rdx, %r8
+; WIN64-NEXT:    movabsq $-8116567392432202711, %rax # imm = 0x8F5C28F5C28F5C29
+; WIN64-NEXT:    movq %rax, {{[0-9]+}}(%rsp)
+; WIN64-NEXT:    movabsq $2951479051793528258, %rax # imm = 0x28F5C28F5C28F5C2
+; WIN64-NEXT:    movq %rax, {{[0-9]+}}(%rsp)
 ; WIN64-NEXT:    movq %rcx, %rax
 ; WIN64-NEXT:    shrdq $62, %rdx, %rax
 ; WIN64-NEXT:    movabsq $1152921504606846975, %rdx # imm = 0xFFFFFFFFFFFFFFF
@@ -1086,15 +1166,16 @@ define i128 @udiv_i128_100(i128 %x) nounwind {
 ; WIN64-NEXT:    subq %rax, %r9
 ; WIN64-NEXT:    shrq $2, %r8
 ; WIN64-NEXT:    subq %r9, %rcx
+; WIN64-NEXT:    movq %rcx, {{[0-9]+}}(%rsp)
 ; WIN64-NEXT:    sbbq $0, %r8
-; WIN64-NEXT:    movabsq $2951479051793528258, %r9 # imm = 0x28F5C28F5C28F5C2
-; WIN64-NEXT:    imulq %rcx, %r9
-; WIN64-NEXT:    movabsq $-8116567392432202711, %r10 # imm = 0x8F5C28F5C28F5C29
-; WIN64-NEXT:    movq %rcx, %rax
-; WIN64-NEXT:    mulq %r10
-; WIN64-NEXT:    addq %r9, %rdx
-; WIN64-NEXT:    imulq %r10, %r8
-; WIN64-NEXT:    addq %r8, %rdx
+; WIN64-NEXT:    movq %r8, {{[0-9]+}}(%rsp)
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %r8
+; WIN64-NEXT:    callq __multi3
+; WIN64-NEXT:    movq {{[0-9]+}}(%rsp), %rax
+; WIN64-NEXT:    movq {{[0-9]+}}(%rsp), %rdx
+; WIN64-NEXT:    addq $88, %rsp
 ; WIN64-NEXT:    retq
 entry:
   %rem = udiv i128 %x, 100
@@ -1135,7 +1216,12 @@ define i128 @udiv_i128_13(i128 %x) nounwind {
 ;
 ; WIN64-LABEL: udiv_i128_13:
 ; WIN64:       # %bb.0: # %entry
+; WIN64-NEXT:    subq $88, %rsp
 ; WIN64-NEXT:    movq %rdx, %r8
+; WIN64-NEXT:    movabsq $5675921253449092805, %rax # imm = 0x4EC4EC4EC4EC4EC5
+; WIN64-NEXT:    movq %rax, {{[0-9]+}}(%rsp)
+; WIN64-NEXT:    movabsq $-4256940940086819604, %rax # imm = 0xC4EC4EC4EC4EC4EC
+; WIN64-NEXT:    movq %rax, {{[0-9]+}}(%rsp)
 ; WIN64-NEXT:    movabsq $1152921504606846975, %rax # imm = 0xFFFFFFFFFFFFFFF
 ; WIN64-NEXT:    movq %rcx, %rdx
 ; WIN64-NEXT:    andq %rax, %rdx
@@ -1154,15 +1240,16 @@ define i128 @udiv_i128_13(i128 %x) nounwind {
 ; WIN64-NEXT:    leaq (%rdx,%rax,4), %rax
 ; WIN64-NEXT:    subq %rax, %r9
 ; WIN64-NEXT:    subq %r9, %rcx
+; WIN64-NEXT:    movq %rcx, {{[0-9]+}}(%rsp)
 ; WIN64-NEXT:    sbbq $0, %r8
-; WIN64-NEXT:    movabsq $-4256940940086819604, %r9 # imm = 0xC4EC4EC4EC4EC4EC
-; WIN64-NEXT:    imulq %rcx, %r9
-; WIN64-NEXT:    movabsq $5675921253449092805, %r10 # imm = 0x4EC4EC4EC4EC4EC5
-; WIN64-NEXT:    movq %rcx, %rax
-; WIN64-NEXT:    mulq %r10
-; WIN64-NEXT:    addq %r9, %rdx
-; WIN64-NEXT:    imulq %r10, %r8
-; WIN64-NEXT:    addq %r8, %rdx
+; WIN64-NEXT:    movq %r8, {{[0-9]+}}(%rsp)
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %r8
+; WIN64-NEXT:    callq __multi3
+; WIN64-NEXT:    movq {{[0-9]+}}(%rsp), %rax
+; WIN64-NEXT:    movq {{[0-9]+}}(%rsp), %rdx
+; WIN64-NEXT:    addq $88, %rsp
 ; WIN64-NEXT:    retq
 entry:
   %rem = udiv i128 %x, 13
diff --git a/llvm/test/CodeGen/X86/fp128-cast.ll 
b/llvm/test/CodeGen/X86/fp128-cast.ll
index 2fef3746729c1..46692355192c4 100644
--- a/llvm/test/CodeGen/X86/fp128-cast.ll
+++ b/llvm/test/CodeGen/X86/fp128-cast.ll
@@ -518,13 +518,15 @@ define dso_local void @TestFPToSIF128_I128() nounwind {
 ;
 ; WIN64-SSE-LABEL: TestFPToSIF128_I128:
 ; WIN64-SSE:       # %bb.0: # %entry
-; WIN64-SSE-NEXT:    subq $56, %rsp
+; WIN64-SSE-NEXT:    subq $72, %rsp
 ; WIN64-SSE-NEXT:    movaps vf128(%rip), %xmm0
 ; WIN64-SSE-NEXT:    movaps %xmm0, {{[0-9]+}}(%rsp)
 ; WIN64-SSE-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-SSE-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
 ; WIN64-SSE-NEXT:    callq __fixtfti
+; WIN64-SSE-NEXT:    movaps {{[0-9]+}}(%rsp), %xmm0
 ; WIN64-SSE-NEXT:    movaps %xmm0, vi128(%rip)
-; WIN64-SSE-NEXT:    addq $56, %rsp
+; WIN64-SSE-NEXT:    addq $72, %rsp
 ; WIN64-SSE-NEXT:    retq
 ;
 ; X86-LABEL: TestFPToSIF128_I128:
@@ -584,13 +586,15 @@ define dso_local void @TestFPToUIF128_U128() nounwind {
 ;
 ; WIN64-SSE-LABEL: TestFPToUIF128_U128:
 ; WIN64-SSE:       # %bb.0: # %entry
-; WIN64-SSE-NEXT:    subq $56, %rsp
+; WIN64-SSE-NEXT:    subq $72, %rsp
 ; WIN64-SSE-NEXT:    movaps vf128(%rip), %xmm0
 ; WIN64-SSE-NEXT:    movaps %xmm0, {{[0-9]+}}(%rsp)
 ; WIN64-SSE-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-SSE-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
 ; WIN64-SSE-NEXT:    callq __fixunstfti
+; WIN64-SSE-NEXT:    movaps {{[0-9]+}}(%rsp), %xmm0
 ; WIN64-SSE-NEXT:    movaps %xmm0, vu128(%rip)
-; WIN64-SSE-NEXT:    addq $56, %rsp
+; WIN64-SSE-NEXT:    addq $72, %rsp
 ; WIN64-SSE-NEXT:    retq
 ;
 ; X86-LABEL: TestFPToUIF128_U128:
diff --git a/llvm/test/CodeGen/X86/i128-fpconv-win64-strict.ll 
b/llvm/test/CodeGen/X86/i128-fpconv-win64-strict.ll
index 64869da48e6c0..95656030edee9 100644
--- a/llvm/test/CodeGen/X86/i128-fpconv-win64-strict.ll
+++ b/llvm/test/CodeGen/X86/i128-fpconv-win64-strict.ll
@@ -5,10 +5,13 @@
 define i64 @double_to_i128(double %d) nounwind strictfp {
 ; WIN64-LABEL: double_to_i128:
 ; WIN64:       # %bb.0:
-; WIN64-NEXT:    subq $40, %rsp
+; WIN64-NEXT:    subq $72, %rsp
+; WIN64-NEXT:    movsd %xmm0, {{[0-9]+}}(%rsp)
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
 ; WIN64-NEXT:    callq __fixdfti
-; WIN64-NEXT:    movq %xmm0, %rax
-; WIN64-NEXT:    addq $40, %rsp
+; WIN64-NEXT:    movq {{[0-9]+}}(%rsp), %rax
+; WIN64-NEXT:    addq $72, %rsp
 ; WIN64-NEXT:    retq
   %1 = tail call i128 @llvm.experimental.constrained.fptosi.i128.f64(double 
%d, metadata !"fpexcept.strict")
   %2 = trunc i128 %1 to i64
@@ -18,10 +21,13 @@ define i64 @double_to_i128(double %d) nounwind strictfp {
 define i64 @double_to_ui128(double %d) nounwind strictfp {
 ; WIN64-LABEL: double_to_ui128:
 ; WIN64:       # %bb.0:
-; WIN64-NEXT:    subq $40, %rsp
+; WIN64-NEXT:    subq $72, %rsp
+; WIN64-NEXT:    movsd %xmm0, {{[0-9]+}}(%rsp)
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
 ; WIN64-NEXT:    callq __fixunsdfti
-; WIN64-NEXT:    movq %xmm0, %rax
-; WIN64-NEXT:    addq $40, %rsp
+; WIN64-NEXT:    movq {{[0-9]+}}(%rsp), %rax
+; WIN64-NEXT:    addq $72, %rsp
 ; WIN64-NEXT:    retq
   %1 = tail call i128 @llvm.experimental.constrained.fptoui.i128.f64(double 
%d, metadata !"fpexcept.strict")
   %2 = trunc i128 %1 to i64
@@ -31,10 +37,13 @@ define i64 @double_to_ui128(double %d) nounwind strictfp {
 define i64 @float_to_i128(float %d) nounwind strictfp {
 ; WIN64-LABEL: float_to_i128:
 ; WIN64:       # %bb.0:
-; WIN64-NEXT:    subq $40, %rsp
+; WIN64-NEXT:    subq $72, %rsp
+; WIN64-NEXT:    movss %xmm0, {{[0-9]+}}(%rsp)
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
 ; WIN64-NEXT:    callq __fixsfti
-; WIN64-NEXT:    movq %xmm0, %rax
-; WIN64-NEXT:    addq $40, %rsp
+; WIN64-NEXT:    movq {{[0-9]+}}(%rsp), %rax
+; WIN64-NEXT:    addq $72, %rsp
 ; WIN64-NEXT:    retq
   %1 = tail call i128 @llvm.experimental.constrained.fptosi.i128.f32(float %d, 
metadata !"fpexcept.strict")
   %2 = trunc i128 %1 to i64
@@ -44,10 +53,13 @@ define i64 @float_to_i128(float %d) nounwind strictfp {
 define i64 @float_to_ui128(float %d) nounwind strictfp {
 ; WIN64-LABEL: float_to_ui128:
 ; WIN64:       # %bb.0:
-; WIN64-NEXT:    subq $40, %rsp
+; WIN64-NEXT:    subq $72, %rsp
+; WIN64-NEXT:    movss %xmm0, {{[0-9]+}}(%rsp)
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
 ; WIN64-NEXT:    callq __fixunssfti
-; WIN64-NEXT:    movq %xmm0, %rax
-; WIN64-NEXT:    addq $40, %rsp
+; WIN64-NEXT:    movq {{[0-9]+}}(%rsp), %rax
+; WIN64-NEXT:    addq $72, %rsp
 ; WIN64-NEXT:    retq
   %1 = tail call i128 @llvm.experimental.constrained.fptoui.i128.f32(float %d, 
metadata !"fpexcept.strict")
   %2 = trunc i128 %1 to i64
@@ -57,14 +69,15 @@ define i64 @float_to_ui128(float %d) nounwind strictfp {
 define i64 @longdouble_to_i128(ptr nocapture readonly %0) nounwind strictfp {
 ; WIN64-LABEL: longdouble_to_i128:
 ; WIN64:       # %bb.0:
-; WIN64-NEXT:    subq $56, %rsp
+; WIN64-NEXT:    subq $72, %rsp
 ; WIN64-NEXT:    fldt (%rcx)
 ; WIN64-NEXT:    fstpt {{[0-9]+}}(%rsp)
 ; WIN64-NEXT:    wait
 ; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
 ; WIN64-NEXT:    callq __fixxfti
-; WIN64-NEXT:    movq %xmm0, %rax
-; WIN64-NEXT:    addq $56, %rsp
+; WIN64-NEXT:    movq {{[0-9]+}}(%rsp), %rax
+; WIN64-NEXT:    addq $72, %rsp
 ; WIN64-NEXT:    retq
   %2 = load x86_fp80, ptr %0, align 16
   %3 = tail call i128 @llvm.experimental.constrained.fptosi.i128.f80(x86_fp80 
%2, metadata !"fpexcept.strict")
@@ -75,14 +88,15 @@ define i64 @longdouble_to_i128(ptr nocapture readonly %0) 
nounwind strictfp {
 define i64 @longdouble_to_ui128(ptr nocapture readonly %0) nounwind strictfp {
 ; WIN64-LABEL: longdouble_to_ui128:
 ; WIN64:       # %bb.0:
-; WIN64-NEXT:    subq $56, %rsp
+; WIN64-NEXT:    subq $72, %rsp
 ; WIN64-NEXT:    fldt (%rcx)
 ; WIN64-NEXT:    fstpt {{[0-9]+}}(%rsp)
 ; WIN64-NEXT:    wait
 ; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
 ; WIN64-NEXT:    callq __fixunsxfti
-; WIN64-NEXT:    movq %xmm0, %rax
-; WIN64-NEXT:    addq $56, %rsp
+; WIN64-NEXT:    movq {{[0-9]+}}(%rsp), %rax
+; WIN64-NEXT:    addq $72, %rsp
 ; WIN64-NEXT:    retq
   %2 = load x86_fp80, ptr %0, align 16
   %3 = tail call i128 @llvm.experimental.constrained.fptoui.i128.f80(x86_fp80 
%2, metadata !"fpexcept.strict")
diff --git a/llvm/test/CodeGen/X86/i128-fpconv-win64.ll 
b/llvm/test/CodeGen/X86/i128-fpconv-win64.ll
index 414318738baf7..2554ed6c403c2 100644
--- a/llvm/test/CodeGen/X86/i128-fpconv-win64.ll
+++ b/llvm/test/CodeGen/X86/i128-fpconv-win64.ll
@@ -5,10 +5,13 @@
 define i64 @double_to_i128(double %d) nounwind {
 ; WIN64-LABEL: double_to_i128:
 ; WIN64:       # %bb.0:
-; WIN64-NEXT:    subq $40, %rsp
+; WIN64-NEXT:    subq $72, %rsp
+; WIN64-NEXT:    movsd %xmm0, {{[0-9]+}}(%rsp)
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
 ; WIN64-NEXT:    callq __fixdfti
-; WIN64-NEXT:    movq %xmm0, %rax
-; WIN64-NEXT:    addq $40, %rsp
+; WIN64-NEXT:    movq {{[0-9]+}}(%rsp), %rax
+; WIN64-NEXT:    addq $72, %rsp
 ; WIN64-NEXT:    retq
   %1 = fptosi double %d to i128
   %2 = trunc i128 %1 to i64
@@ -18,10 +21,13 @@ define i64 @double_to_i128(double %d) nounwind {
 define i64 @double_to_ui128(double %d) nounwind {
 ; WIN64-LABEL: double_to_ui128:
 ; WIN64:       # %bb.0:
-; WIN64-NEXT:    subq $40, %rsp
+; WIN64-NEXT:    subq $72, %rsp
+; WIN64-NEXT:    movsd %xmm0, {{[0-9]+}}(%rsp)
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
 ; WIN64-NEXT:    callq __fixunsdfti
-; WIN64-NEXT:    movq %xmm0, %rax
-; WIN64-NEXT:    addq $40, %rsp
+; WIN64-NEXT:    movq {{[0-9]+}}(%rsp), %rax
+; WIN64-NEXT:    addq $72, %rsp
 ; WIN64-NEXT:    retq
   %1 = fptoui double %d to i128
   %2 = trunc i128 %1 to i64
@@ -31,10 +37,13 @@ define i64 @double_to_ui128(double %d) nounwind {
 define i64 @float_to_i128(float %d) nounwind {
 ; WIN64-LABEL: float_to_i128:
 ; WIN64:       # %bb.0:
-; WIN64-NEXT:    subq $40, %rsp
+; WIN64-NEXT:    subq $72, %rsp
+; WIN64-NEXT:    movss %xmm0, {{[0-9]+}}(%rsp)
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
 ; WIN64-NEXT:    callq __fixsfti
-; WIN64-NEXT:    movq %xmm0, %rax
-; WIN64-NEXT:    addq $40, %rsp
+; WIN64-NEXT:    movq {{[0-9]+}}(%rsp), %rax
+; WIN64-NEXT:    addq $72, %rsp
 ; WIN64-NEXT:    retq
   %1 = fptosi float %d to i128
   %2 = trunc i128 %1 to i64
@@ -44,10 +53,13 @@ define i64 @float_to_i128(float %d) nounwind {
 define i64 @float_to_ui128(float %d) nounwind {
 ; WIN64-LABEL: float_to_ui128:
 ; WIN64:       # %bb.0:
-; WIN64-NEXT:    subq $40, %rsp
+; WIN64-NEXT:    subq $72, %rsp
+; WIN64-NEXT:    movss %xmm0, {{[0-9]+}}(%rsp)
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
 ; WIN64-NEXT:    callq __fixunssfti
-; WIN64-NEXT:    movq %xmm0, %rax
-; WIN64-NEXT:    addq $40, %rsp
+; WIN64-NEXT:    movq {{[0-9]+}}(%rsp), %rax
+; WIN64-NEXT:    addq $72, %rsp
 ; WIN64-NEXT:    retq
   %1 = fptoui float %d to i128
   %2 = trunc i128 %1 to i64
@@ -57,13 +69,14 @@ define i64 @float_to_ui128(float %d) nounwind {
 define i64 @longdouble_to_i128(ptr nocapture readonly %0) nounwind {
 ; WIN64-LABEL: longdouble_to_i128:
 ; WIN64:       # %bb.0:
-; WIN64-NEXT:    subq $56, %rsp
+; WIN64-NEXT:    subq $72, %rsp
 ; WIN64-NEXT:    fldt (%rcx)
 ; WIN64-NEXT:    fstpt {{[0-9]+}}(%rsp)
 ; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
 ; WIN64-NEXT:    callq __fixxfti
-; WIN64-NEXT:    movq %xmm0, %rax
-; WIN64-NEXT:    addq $56, %rsp
+; WIN64-NEXT:    movq {{[0-9]+}}(%rsp), %rax
+; WIN64-NEXT:    addq $72, %rsp
 ; WIN64-NEXT:    retq
   %2 = load x86_fp80, ptr %0, align 16
   %3 = fptosi x86_fp80 %2 to i128
@@ -74,13 +87,14 @@ define i64 @longdouble_to_i128(ptr nocapture readonly %0) 
nounwind {
 define i64 @longdouble_to_ui128(ptr nocapture readonly %0) nounwind {
 ; WIN64-LABEL: longdouble_to_ui128:
 ; WIN64:       # %bb.0:
-; WIN64-NEXT:    subq $56, %rsp
+; WIN64-NEXT:    subq $72, %rsp
 ; WIN64-NEXT:    fldt (%rcx)
 ; WIN64-NEXT:    fstpt {{[0-9]+}}(%rsp)
 ; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
+; WIN64-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
 ; WIN64-NEXT:    callq __fixunsxfti
-; WIN64-NEXT:    movq %xmm0, %rax
-; WIN64-NEXT:    addq $56, %rsp
+; WIN64-NEXT:    movq {{[0-9]+}}(%rsp), %rax
+; WIN64-NEXT:    addq $72, %rsp
 ; WIN64-NEXT:    retq
   %2 = load x86_fp80, ptr %0, align 16
   %3 = fptoui x86_fp80 %2 to i128

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to