https://github.com/oltolm updated https://github.com/llvm/llvm-project/pull/210358
>From d810fc1b3f3c208a125fd8bce8f0a2a59bd97e96 Mon Sep 17 00:00:00 2001 From: Oleg Tolmatcev <[email protected]> Date: Mon, 14 Sep 2026 14:20:24 +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. For instance methods, pass the sret pointer after `this` to match Microsoft ABI argument ordering. 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. Only i128 arguments to these libcalls are passed indirectly; other arguments follow the regular Win64 calling convention. 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. Add C and C++ coverage for MSVC and MinGW targets, and update the X86 codegen tests to check the indirect-return form. --- clang/docs/ReleaseNotes.md | 4 + clang/lib/CodeGen/Targets/X86.cpp | 10 +- clang/test/CodeGen/win64-i128.c | 30 +- clang/test/CodeGenCXX/win64-i128.cpp | 19 + llvm/lib/Target/X86/X86ISelLowering.cpp | 134 ++++--- llvm/lib/Target/X86/X86ISelLowering.h | 4 + llvm/test/CodeGen/X86/divmod128.ll | 351 +++++++++++------- llvm/test/CodeGen/X86/fp128-cast.ll | 12 +- llvm/test/CodeGen/X86/fp80-conv-libcalls.ll | 10 +- .../CodeGen/X86/i128-fpconv-win64-strict.ll | 46 ++- llvm/test/CodeGen/X86/i128-fpconv-win64.ll | 46 ++- 11 files changed, 433 insertions(+), 233 deletions(-) create mode 100644 clang/test/CodeGenCXX/win64-i128.cpp diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index ef694e1d0f5cc..9084ab4736d89 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -94,6 +94,10 @@ features cannot lower the translation-unit ABI level; always passed the parts separately. `-fclang-abi-compat=23` restores the previous behavior. (#GH212109) +- 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. + - On MIPS N32/N64, an `__int128` now correctly start in an even-numbered register or 16-byte aligned stack slot, matching GCC. diff --git a/clang/lib/CodeGen/Targets/X86.cpp b/clang/lib/CodeGen/Targets/X86.cpp index 14fe5ffae8372..5f1ca58c76f15 100644 --- a/clang/lib/CodeGen/Targets/X86.cpp +++ b/clang/lib/CodeGen/Targets/X86.cpp @@ -3586,12 +3586,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. @@ -3670,6 +3668,10 @@ void WinX86_64ABIInfo::computeInfo(CGFunctionInfo &FI) const { FI.getReturnInfo() = classify(FI.getReturnType(), FreeSSERegs, ClassifyKind::Return, CC); + if (FI.getReturnInfo().isIndirect() && FI.isInstanceMethod() && + getCXXABI().isSRetParameterAfterThis()) + FI.getReturnInfo().setSRetAfterThis(true); + if (IsVectorCall) { // We can use up to 6 SSE register parameters with vectorcall. FreeSSERegs = 6; diff --git a/clang/test/CodeGen/win64-i128.c b/clang/test/CodeGen/win64-i128.c index ce338d451115c..fc2664be7dd6f 100644 --- a/clang/test/CodeGen/win64-i128.c +++ b/clang/test/CodeGen/win64-i128.c @@ -2,6 +2,8 @@ // RUN: | FileCheck %s --check-prefixes=CHECK,X64 // RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -o - %s \ // RUN: | FileCheck %s --check-prefixes=CHECK,X64 +// RUN: %clang --target=x86_64-windows-msvc -mno-sse -S -emit-llvm -o - %s \ +// RUN: | FileCheck %s --check-prefixes=CHECK,NOSSE // RUN: %clang_cc1 -triple aarch64-windows-msvc -emit-llvm -o - %s \ // RUN: | FileCheck %s --check-prefixes=CHECK,ARM,ARM64 // RUN: %clang_cc1 -triple arm64ec-windows-msvc -emit-llvm -o - %s \ @@ -11,14 +13,38 @@ 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 nofreeobj noundef align 16 dead_on_return dereferenceable(16) %0, ptr nofreeobj noundef align 16 dead_on_return dereferenceable(16) %1) +// X64-LABEL: define dso_local void @bar( +// X64-SAME: sret(i128) align 16 +// X64-SAME: ptr nofree noundef align 16 dead_on_return +// X64-SAME: ptr nofreeobj noundef align 16 dead_on_return +// NOSSE-LABEL: define dso_local void @bar( +// NOSSE-SAME: sret(i128) align 16 +// NOSSE-SAME: ptr nofreeobj noundef align 16 dead_on_return +// NOSSE-SAME: ptr nofree noundef align 16 dead_on_return // ARM: define dso_local i128 @bar(i128 noundef %a, i128 noundef %b) +#if defined(__x86_64__) && !defined(__arm64ec__) +int128_t __attribute__((vectorcall)) vectorcall_foo(void) { return 0; } + +// X64-LABEL: define dso_local x86_vectorcallcc void @"\01vectorcall_foo@@0"( +// X64-SAME: sret(i128) align 16 + +int128_t __attribute__((vectorcall)) vectorcall_bar(int128_t a, int128_t b) { + return a * b; +} + +// X64-LABEL: define dso_local x86_vectorcallcc void @"\01vectorcall_bar@@32"( +// X64-SAME: sret(i128) align 16 +// X64-SAME: ptr nofree noundef align 16 dead_on_return +// X64-SAME: ptr nofree noundef align 16 dead_on_return +#endif + void vararg(int a, ...) { // CHECK: define{{.*}} void @vararg __builtin_va_list ap; diff --git a/clang/test/CodeGenCXX/win64-i128.cpp b/clang/test/CodeGenCXX/win64-i128.cpp new file mode 100644 index 0000000000000..a683e782e906b --- /dev/null +++ b/clang/test/CodeGenCXX/win64-i128.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -triple x86_64-windows-gnu -emit-llvm -o - %s \ +// RUN: | FileCheck %s --check-prefix=GNU +// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -o - %s \ +// RUN: | FileCheck %s --check-prefix=MSVC + +typedef int int128_t __attribute__((mode(TI))); + +struct S { + int128_t f(); +}; + +int128_t S::f() { return 0; } + +// GNU-LABEL: define dso_local void @_ZN1S1fEv( +// GNU-SAME: ptr dead_on_unwind noalias writable sret(i128) align 16 %agg.result, +// GNU-SAME: ptr noundef nonnull align 1 dereferenceable(1) %this) +// MSVC-LABEL: define dso_local void @"?f@S@@QEAA_LXZ"( +// MSVC-SAME: ptr noundef nonnull align 1 dereferenceable(1) %this, +// MSVC-SAME: ptr dead_on_unwind noalias writable sret(i128) align 16 %agg.result) diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index a41cb2914660c..ecdcf4d92d9eb 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -2743,6 +2743,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); @@ -22461,6 +22462,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 = @@ -30849,66 +30852,97 @@ 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> CallArgs, 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 : CallArgs) { + EVT ArgVT = Arg.getValueType(); + // i128 is split before calling convention analysis, so make it indirect + // while the whole value is still available. Other argument types are + // handled by CC_X86_Win64_C. + if (ArgVT != MVT::i128) { + Args.emplace_back(Arg, ArgVT.getTypeForEVT(*DAG.getContext())); + continue; + } + + 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, @@ -30933,16 +30967,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> CallArgs = {Arg}; + return lowerWin64IndirectI128Libcall(DAG, dl, VT, LC, CallArgs, Chain); } SDValue X86TargetLowering::LowerWin64_INT128_TO_FP(SDValue Op, @@ -35296,6 +35324,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 5215bb0704dca..2041c35f5f369 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.h +++ b/llvm/lib/Target/X86/X86ISelLowering.h @@ -844,6 +844,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> CallArgs, + 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/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 36ec50efa70b3..bbbd72a0ed476 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/fp80-conv-libcalls.ll b/llvm/test/CodeGen/X86/fp80-conv-libcalls.ll index 9a41d25feb030..b3f85c0fb31b4 100644 --- a/llvm/test/CodeGen/X86/fp80-conv-libcalls.ll +++ b/llvm/test/CodeGen/X86/fp80-conv-libcalls.ll @@ -92,15 +92,15 @@ define i128 @test_fptosi(x86_fp80 %x) nounwind { ; ; MSVC-LABEL: test_fptosi: ; MSVC: # %bb.0: -; MSVC-NEXT: subq $56, %rsp +; MSVC-NEXT: subq $72, %rsp ; MSVC-NEXT: fldt (%rcx) ; MSVC-NEXT: fstpt {{[0-9]+}}(%rsp) ; MSVC-NEXT: leaq {{[0-9]+}}(%rsp), %rcx +; MSVC-NEXT: leaq {{[0-9]+}}(%rsp), %rdx ; MSVC-NEXT: callq __fixxfti -; MSVC-NEXT: movq %xmm0, %rax -; MSVC-NEXT: pshufd {{.*#+}} xmm0 = xmm0[2,3,2,3] -; MSVC-NEXT: movq %xmm0, %rdx -; MSVC-NEXT: addq $56, %rsp +; MSVC-NEXT: movq {{[0-9]+}}(%rsp), %rax +; MSVC-NEXT: movq {{[0-9]+}}(%rsp), %rdx +; MSVC-NEXT: addq $72, %rsp ; MSVC-NEXT: retq %r = fptosi x86_fp80 %x to i128 ret i128 %r diff --git a/llvm/test/CodeGen/X86/i128-fpconv-win64-strict.ll b/llvm/test/CodeGen/X86/i128-fpconv-win64-strict.ll index 64869da48e6c0..dd5300c7b71e5 100644 --- a/llvm/test/CodeGen/X86/i128-fpconv-win64-strict.ll +++ b/llvm/test/CodeGen/X86/i128-fpconv-win64-strict.ll @@ -5,10 +5,12 @@ 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 $56, %rsp +; WIN64-NEXT: leaq {{[0-9]+}}(%rsp), %rcx +; WIN64-NEXT: movaps %xmm0, %xmm1 ; WIN64-NEXT: callq __fixdfti -; WIN64-NEXT: movq %xmm0, %rax -; WIN64-NEXT: addq $40, %rsp +; WIN64-NEXT: movq {{[0-9]+}}(%rsp), %rax +; WIN64-NEXT: addq $56, %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 +20,12 @@ 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 $56, %rsp +; WIN64-NEXT: leaq {{[0-9]+}}(%rsp), %rcx +; WIN64-NEXT: movaps %xmm0, %xmm1 ; WIN64-NEXT: callq __fixunsdfti -; WIN64-NEXT: movq %xmm0, %rax -; WIN64-NEXT: addq $40, %rsp +; WIN64-NEXT: movq {{[0-9]+}}(%rsp), %rax +; WIN64-NEXT: addq $56, %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 +35,12 @@ 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 $56, %rsp +; WIN64-NEXT: leaq {{[0-9]+}}(%rsp), %rcx +; WIN64-NEXT: movaps %xmm0, %xmm1 ; WIN64-NEXT: callq __fixsfti -; WIN64-NEXT: movq %xmm0, %rax -; WIN64-NEXT: addq $40, %rsp +; WIN64-NEXT: movq {{[0-9]+}}(%rsp), %rax +; WIN64-NEXT: addq $56, %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 +50,12 @@ 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 $56, %rsp +; WIN64-NEXT: leaq {{[0-9]+}}(%rsp), %rcx +; WIN64-NEXT: movaps %xmm0, %xmm1 ; WIN64-NEXT: callq __fixunssfti -; WIN64-NEXT: movq %xmm0, %rax -; WIN64-NEXT: addq $40, %rsp +; WIN64-NEXT: movq {{[0-9]+}}(%rsp), %rax +; WIN64-NEXT: addq $56, %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 +65,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 +84,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..c0b1fcc60a448 100644 --- a/llvm/test/CodeGen/X86/i128-fpconv-win64.ll +++ b/llvm/test/CodeGen/X86/i128-fpconv-win64.ll @@ -5,10 +5,12 @@ define i64 @double_to_i128(double %d) nounwind { ; WIN64-LABEL: double_to_i128: ; WIN64: # %bb.0: -; WIN64-NEXT: subq $40, %rsp +; WIN64-NEXT: subq $56, %rsp +; WIN64-NEXT: leaq {{[0-9]+}}(%rsp), %rcx +; WIN64-NEXT: movaps %xmm0, %xmm1 ; WIN64-NEXT: callq __fixdfti -; WIN64-NEXT: movq %xmm0, %rax -; WIN64-NEXT: addq $40, %rsp +; WIN64-NEXT: movq {{[0-9]+}}(%rsp), %rax +; WIN64-NEXT: addq $56, %rsp ; WIN64-NEXT: retq %1 = fptosi double %d to i128 %2 = trunc i128 %1 to i64 @@ -18,10 +20,12 @@ 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 $56, %rsp +; WIN64-NEXT: leaq {{[0-9]+}}(%rsp), %rcx +; WIN64-NEXT: movaps %xmm0, %xmm1 ; WIN64-NEXT: callq __fixunsdfti -; WIN64-NEXT: movq %xmm0, %rax -; WIN64-NEXT: addq $40, %rsp +; WIN64-NEXT: movq {{[0-9]+}}(%rsp), %rax +; WIN64-NEXT: addq $56, %rsp ; WIN64-NEXT: retq %1 = fptoui double %d to i128 %2 = trunc i128 %1 to i64 @@ -31,10 +35,12 @@ 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 $56, %rsp +; WIN64-NEXT: leaq {{[0-9]+}}(%rsp), %rcx +; WIN64-NEXT: movaps %xmm0, %xmm1 ; WIN64-NEXT: callq __fixsfti -; WIN64-NEXT: movq %xmm0, %rax -; WIN64-NEXT: addq $40, %rsp +; WIN64-NEXT: movq {{[0-9]+}}(%rsp), %rax +; WIN64-NEXT: addq $56, %rsp ; WIN64-NEXT: retq %1 = fptosi float %d to i128 %2 = trunc i128 %1 to i64 @@ -44,10 +50,12 @@ 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 $56, %rsp +; WIN64-NEXT: leaq {{[0-9]+}}(%rsp), %rcx +; WIN64-NEXT: movaps %xmm0, %xmm1 ; WIN64-NEXT: callq __fixunssfti -; WIN64-NEXT: movq %xmm0, %rax -; WIN64-NEXT: addq $40, %rsp +; WIN64-NEXT: movq {{[0-9]+}}(%rsp), %rax +; WIN64-NEXT: addq $56, %rsp ; WIN64-NEXT: retq %1 = fptoui float %d to i128 %2 = trunc i128 %1 to i64 @@ -57,13 +65,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 +83,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
