diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.def b/llvm/include/llvm/IR/RuntimeLibcalls.def --- a/llvm/include/llvm/IR/RuntimeLibcalls.def +++ b/llvm/include/llvm/IR/RuntimeLibcalls.def @@ -47,6 +47,8 @@ HANDLE_LIBCALL(MUL_I32, "__mulsi3") HANDLE_LIBCALL(MUL_I64, "__muldi3") HANDLE_LIBCALL(MUL_I128, "__multi3") +HANDLE_LIBCALL(MUL_IEXT, nullptr) + HANDLE_LIBCALL(MULO_I32, "__mulosi4") HANDLE_LIBCALL(MULO_I64, "__mulodi4") HANDLE_LIBCALL(MULO_I128, "__muloti4") @@ -55,31 +57,43 @@ HANDLE_LIBCALL(SDIV_I32, "__divsi3") HANDLE_LIBCALL(SDIV_I64, "__divdi3") HANDLE_LIBCALL(SDIV_I128, "__divti3") +HANDLE_LIBCALL(SDIV_IEXT, "__divei4") + HANDLE_LIBCALL(UDIV_I8, "__udivqi3") HANDLE_LIBCALL(UDIV_I16, "__udivhi3") HANDLE_LIBCALL(UDIV_I32, "__udivsi3") HANDLE_LIBCALL(UDIV_I64, "__udivdi3") HANDLE_LIBCALL(UDIV_I128, "__udivti3") +HANDLE_LIBCALL(UDIV_IEXT, "__udivei4") + HANDLE_LIBCALL(SREM_I8, "__modqi3") HANDLE_LIBCALL(SREM_I16, "__modhi3") HANDLE_LIBCALL(SREM_I32, "__modsi3") HANDLE_LIBCALL(SREM_I64, "__moddi3") HANDLE_LIBCALL(SREM_I128, "__modti3") +HANDLE_LIBCALL(SREM_IEXT, "__modei4") + HANDLE_LIBCALL(UREM_I8, "__umodqi3") HANDLE_LIBCALL(UREM_I16, "__umodhi3") HANDLE_LIBCALL(UREM_I32, "__umodsi3") HANDLE_LIBCALL(UREM_I64, "__umoddi3") HANDLE_LIBCALL(UREM_I128, "__umodti3") +HANDLE_LIBCALL(UREM_IEXT, "__umodei4") + HANDLE_LIBCALL(SDIVREM_I8, nullptr) HANDLE_LIBCALL(SDIVREM_I16, nullptr) HANDLE_LIBCALL(SDIVREM_I32, nullptr) HANDLE_LIBCALL(SDIVREM_I64, nullptr) HANDLE_LIBCALL(SDIVREM_I128, nullptr) +HANDLE_LIBCALL(SDIVREM_IEXT, nullptr) + HANDLE_LIBCALL(UDIVREM_I8, nullptr) HANDLE_LIBCALL(UDIVREM_I16, nullptr) HANDLE_LIBCALL(UDIVREM_I32, nullptr) HANDLE_LIBCALL(UDIVREM_I64, nullptr) HANDLE_LIBCALL(UDIVREM_I128, nullptr) +HANDLE_LIBCALL(UDIVREM_IEXT, nullptr) + HANDLE_LIBCALL(NEG_I32, "__negsi2") HANDLE_LIBCALL(NEG_I64, "__negdi2") HANDLE_LIBCALL(CTLZ_I32, "__clzsi2") diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -142,12 +142,10 @@ RTLIB::Libcall Call_F128, RTLIB::Libcall Call_PPCF128, SmallVectorImpl &Results); - SDValue ExpandIntLibCall(SDNode *Node, bool isSigned, - RTLIB::Libcall Call_I8, - RTLIB::Libcall Call_I16, - RTLIB::Libcall Call_I32, - RTLIB::Libcall Call_I64, - RTLIB::Libcall Call_I128); + SDValue ExpandIntLibCall(SDNode *Node, bool isSigned, RTLIB::Libcall Call_I8, + RTLIB::Libcall Call_I16, RTLIB::Libcall Call_I32, + RTLIB::Libcall Call_I64, RTLIB::Libcall Call_I128, + RTLIB::Libcall Call_IEXT); void ExpandArgFPLibCall(SDNode *Node, RTLIB::Libcall Call_F32, RTLIB::Libcall Call_F64, RTLIB::Libcall Call_F80, RTLIB::Libcall Call_F128, @@ -2101,15 +2099,17 @@ ExpandFPLibCall(Node, LC, Results); } -SDValue SelectionDAGLegalize::ExpandIntLibCall(SDNode* Node, bool isSigned, - RTLIB::Libcall Call_I8, - RTLIB::Libcall Call_I16, - RTLIB::Libcall Call_I32, - RTLIB::Libcall Call_I64, - RTLIB::Libcall Call_I128) { +SDValue SelectionDAGLegalize::ExpandIntLibCall( + SDNode *Node, bool isSigned, RTLIB::Libcall Call_I8, + RTLIB::Libcall Call_I16, RTLIB::Libcall Call_I32, RTLIB::Libcall Call_I64, + RTLIB::Libcall Call_I128, RTLIB::Libcall Call_IEXT) { RTLIB::Libcall LC; switch (Node->getSimpleValueType(0).SimpleTy) { - default: llvm_unreachable("Unexpected request for libcall!"); + + default: + LC = Call_IEXT; + break; + case MVT::i8: LC = Call_I8; break; case MVT::i16: LC = Call_I16; break; case MVT::i32: LC = Call_I32; break; @@ -2144,7 +2144,11 @@ RTLIB::Libcall LC; switch (Node->getSimpleValueType(0).SimpleTy) { - default: llvm_unreachable("Unexpected request for libcall!"); + + default: + LC = isSigned ? RTLIB::SDIVREM_IEXT : RTLIB::UDIVREM_IEXT; + break; + case MVT::i8: LC= isSigned ? RTLIB::SDIVREM_I8 : RTLIB::UDIVREM_I8; break; case MVT::i16: LC= isSigned ? RTLIB::SDIVREM_I16 : RTLIB::UDIVREM_I16; break; case MVT::i32: LC= isSigned ? RTLIB::SDIVREM_I32 : RTLIB::UDIVREM_I32; break; @@ -4315,28 +4319,24 @@ RTLIB::SUB_PPCF128, Results); break; case ISD::SREM: - Results.push_back(ExpandIntLibCall(Node, true, - RTLIB::SREM_I8, - RTLIB::SREM_I16, RTLIB::SREM_I32, - RTLIB::SREM_I64, RTLIB::SREM_I128)); + Results.push_back(ExpandIntLibCall( + Node, true, RTLIB::SREM_I8, RTLIB::SREM_I16, RTLIB::SREM_I32, + RTLIB::SREM_I64, RTLIB::SREM_I128, RTLIB::SREM_IEXT)); break; case ISD::UREM: - Results.push_back(ExpandIntLibCall(Node, false, - RTLIB::UREM_I8, - RTLIB::UREM_I16, RTLIB::UREM_I32, - RTLIB::UREM_I64, RTLIB::UREM_I128)); + Results.push_back(ExpandIntLibCall( + Node, false, RTLIB::UREM_I8, RTLIB::UREM_I16, RTLIB::UREM_I32, + RTLIB::UREM_I64, RTLIB::UREM_I128, RTLIB::UREM_IEXT)); break; case ISD::SDIV: - Results.push_back(ExpandIntLibCall(Node, true, - RTLIB::SDIV_I8, - RTLIB::SDIV_I16, RTLIB::SDIV_I32, - RTLIB::SDIV_I64, RTLIB::SDIV_I128)); + Results.push_back(ExpandIntLibCall( + Node, true, RTLIB::SDIV_I8, RTLIB::SDIV_I16, RTLIB::SDIV_I32, + RTLIB::SDIV_I64, RTLIB::SDIV_I128, RTLIB::SDIV_IEXT)); break; case ISD::UDIV: - Results.push_back(ExpandIntLibCall(Node, false, - RTLIB::UDIV_I8, - RTLIB::UDIV_I16, RTLIB::UDIV_I32, - RTLIB::UDIV_I64, RTLIB::UDIV_I128)); + Results.push_back(ExpandIntLibCall( + Node, false, RTLIB::UDIV_I8, RTLIB::UDIV_I16, RTLIB::UDIV_I32, + RTLIB::UDIV_I64, RTLIB::UDIV_I128, RTLIB::UDIV_IEXT)); break; case ISD::SDIVREM: case ISD::UDIVREM: @@ -4344,10 +4344,9 @@ ExpandDivRemLibCall(Node, Results); break; case ISD::MUL: - Results.push_back(ExpandIntLibCall(Node, false, - RTLIB::MUL_I8, - RTLIB::MUL_I16, RTLIB::MUL_I32, - RTLIB::MUL_I64, RTLIB::MUL_I128)); + Results.push_back(ExpandIntLibCall( + Node, false, RTLIB::MUL_I8, RTLIB::MUL_I16, RTLIB::MUL_I32, + RTLIB::MUL_I64, RTLIB::MUL_I128, RTLIB::MUL_IEXT)); break; case ISD::CTLZ_ZERO_UNDEF: switch (Node->getSimpleValueType(0).SimpleTy) { diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp @@ -3901,6 +3901,59 @@ ReplaceValueWith(SDValue(Node, 1), Ovf); } +// Emit a call to __udivei4 or friend which require +// the arguments be based on the stack +// and extra argument that contains the number of bits of the operands. +// Returns the result of the call operation. +static SDValue passArguments_DIVREM(const TargetLowering &TLI, + const RTLIB::Libcall &LC, SelectionDAG &DAG, + SDNode *N, const SDLoc &DL, const EVT &VT) { + + SDValue InChain = DAG.getEntryNode(); + + TargetLowering::ArgListTy Args; + TargetLowering::ArgListEntry Entry; + + for (const llvm::SDUse &Op : N->ops()) { + EVT ArgVT = Op.getValueType(); + assert(ArgVT.isInteger() && ArgVT.getSizeInBits() > 128 && + "Unexpected argument type for lowering"); + SDValue StackPtr = DAG.CreateStackTemporary(ArgVT, 4); + Entry.Node = StackPtr; + InChain = DAG.getStore(InChain, DL, Op, StackPtr, MachinePointerInfo()); + Type *ArgTy = ArgVT.getTypeForEVT(*DAG.getContext()); + Entry.Ty = PointerType::get(ArgTy, 0); + Entry.IsSExt = false; + Entry.IsZExt = false; + Args.push_back(Entry); + } + + int Bits = N->getOperand(0) + .getValueType() + .getTypeForEVT(*DAG.getContext()) + ->getIntegerBitWidth(); + Entry.Node = DAG.getConstant(Bits, DL, TLI.getPointerTy(DAG.getDataLayout())); + Entry.Ty = Type::getInt32Ty(*DAG.getContext()); + Entry.IsSExt = false; + Entry.IsZExt = true; + Args.push_back(Entry); + + SDValue Callee = DAG.getExternalSymbol(TLI.getLibcallName(LC), + TLI.getPointerTy(DAG.getDataLayout())); + + TargetLowering::CallLoweringInfo CLI(DAG); + CLI.setDebugLoc(DL) + .setChain(InChain) + .setLibCallee(TLI.getLibcallCallingConv(LC), + VT.getTypeForEVT(*DAG.getContext()), Callee, + std::move(Args)) + .setInRegister() + .setSExtResult(/*isSigned*/ false) + .setZExtResult(/*!isSigned*/ true); + + return TLI.LowerCallTo(CLI).first; +} + void DAGTypeLegalizer::ExpandIntRes_SDIV(SDNode *N, SDValue &Lo, SDValue &Hi) { EVT VT = N->getValueType(0); @@ -3922,6 +3975,14 @@ LC = RTLIB::SDIV_I64; else if (VT == MVT::i128) LC = RTLIB::SDIV_I128; + + else { + SDValue Result = + passArguments_DIVREM(TLI, RTLIB::SDIV_IEXT, DAG, N, dl, VT); + SplitInteger(Result, Lo, Hi); + return; + } + assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported SDIV!"); TargetLowering::MakeLibCallOptions CallOptions; @@ -4113,6 +4174,14 @@ LC = RTLIB::SREM_I64; else if (VT == MVT::i128) LC = RTLIB::SREM_I128; + + else { + SDValue Result = + passArguments_DIVREM(TLI, RTLIB::SREM_IEXT, DAG, N, dl, VT); + SplitInteger(Result, Lo, Hi); + return; + } + assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported SREM!"); TargetLowering::MakeLibCallOptions CallOptions; @@ -4288,6 +4357,14 @@ LC = RTLIB::UDIV_I64; else if (VT == MVT::i128) LC = RTLIB::UDIV_I128; + + else { + SDValue Result = + passArguments_DIVREM(TLI, RTLIB::UDIV_IEXT, DAG, N, dl, VT); + SplitInteger(Result, Lo, Hi); + return; + } + assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported UDIV!"); TargetLowering::MakeLibCallOptions CallOptions; @@ -4315,6 +4392,14 @@ LC = RTLIB::UREM_I64; else if (VT == MVT::i128) LC = RTLIB::UREM_I128; + + else { + SDValue Result = + passArguments_DIVREM(TLI, RTLIB::UREM_IEXT, DAG, N, dl, VT); + SplitInteger(Result, Lo, Hi); + return; + } + assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported UREM!"); TargetLowering::MakeLibCallOptions CallOptions; diff --git a/llvm/test/CodeGen/X86/udivmodei5.ll b/llvm/test/CodeGen/X86/udivmodei5.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/X86/udivmodei5.ll @@ -0,0 +1,398 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple=x86_64-unknown | FileCheck %s + + +define i129 @udiv129(i129 %a, i129 %b) { +; CHECK-LABEL: udiv129: +; CHECK: # %bb.0: +; CHECK-NEXT: subq $104, %rsp +; CHECK-NEXT: .cfi_def_cfa_offset 112 +; CHECK-NEXT: andl $1, %r9d +; CHECK-NEXT: andl $1, %edx +; CHECK-NEXT: movq %rsi, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %rdi, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %rcx, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %r8, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %rdx, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %r9, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq $0, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq $0, {{[0-9]+}}(%rsp) +; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rdi +; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rsi +; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rdx +; CHECK-NEXT: movl $256, %ecx # imm = 0x100 +; CHECK-NEXT: callq __udivei4@PLT +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rcx +; CHECK-NEXT: andl $1, %ecx +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rdx +; CHECK-NEXT: addq $104, %rsp +; CHECK-NEXT: .cfi_def_cfa_offset 8 +; CHECK-NEXT: retq + %res = udiv i129 %a, %b + ret i129 %res +} + +define i129 @urem129(i129 %a, i129 %b) { +; CHECK-LABEL: urem129: +; CHECK: # %bb.0: +; CHECK-NEXT: subq $104, %rsp +; CHECK-NEXT: .cfi_def_cfa_offset 112 +; CHECK-NEXT: andl $1, %r9d +; CHECK-NEXT: andl $1, %edx +; CHECK-NEXT: movq %rsi, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %rdi, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %rcx, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %r8, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %rdx, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %r9, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq $0, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq $0, {{[0-9]+}}(%rsp) +; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rdi +; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rsi +; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rdx +; CHECK-NEXT: movl $256, %ecx # imm = 0x100 +; CHECK-NEXT: callq __umodei4@PLT +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rcx +; CHECK-NEXT: andl $1, %ecx +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rdx +; CHECK-NEXT: addq $104, %rsp +; CHECK-NEXT: .cfi_def_cfa_offset 8 +; CHECK-NEXT: retq + %res = urem i129 %a, %b + ret i129 %res +} + +define i129 @sdiv129(i129 %a, i129 %b) { +; CHECK-LABEL: sdiv129: +; CHECK: # %bb.0: +; CHECK-NEXT: subq $104, %rsp +; CHECK-NEXT: .cfi_def_cfa_offset 112 +; CHECK-NEXT: andl $1, %r9d +; CHECK-NEXT: negq %r9 +; CHECK-NEXT: andl $1, %edx +; CHECK-NEXT: negq %rdx +; CHECK-NEXT: movq %rsi, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %rdi, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %rcx, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %r8, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %rdx, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %rdx, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %r9, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %r9, {{[0-9]+}}(%rsp) +; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rdi +; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rsi +; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rdx +; CHECK-NEXT: movl $256, %ecx # imm = 0x100 +; CHECK-NEXT: callq __divei4@PLT +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rcx +; CHECK-NEXT: andl $1, %ecx +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rdx +; CHECK-NEXT: addq $104, %rsp +; CHECK-NEXT: .cfi_def_cfa_offset 8 +; CHECK-NEXT: retq + %res = sdiv i129 %a, %b + ret i129 %res +} + +define i129 @srem129(i129 %a, i129 %b) { +; CHECK-LABEL: srem129: +; CHECK: # %bb.0: +; CHECK-NEXT: subq $104, %rsp +; CHECK-NEXT: .cfi_def_cfa_offset 112 +; CHECK-NEXT: andl $1, %r9d +; CHECK-NEXT: negq %r9 +; CHECK-NEXT: andl $1, %edx +; CHECK-NEXT: negq %rdx +; CHECK-NEXT: movq %rsi, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %rdi, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %rcx, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %r8, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %rdx, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %rdx, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %r9, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %r9, {{[0-9]+}}(%rsp) +; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rdi +; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rsi +; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rdx +; CHECK-NEXT: movl $256, %ecx # imm = 0x100 +; CHECK-NEXT: callq __modei4@PLT +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rcx +; CHECK-NEXT: andl $1, %ecx +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rdx +; CHECK-NEXT: addq $104, %rsp +; CHECK-NEXT: .cfi_def_cfa_offset 8 +; CHECK-NEXT: retq + %res = srem i129 %a, %b + ret i129 %res +} + +; Some higher sizes +define i257 @sdiv257(i257 %a, i257 %b) { +; CHECK-LABEL: sdiv257: +; CHECK: # %bb.0: +; CHECK-NEXT: pushq %r14 +; CHECK-NEXT: .cfi_def_cfa_offset 16 +; CHECK-NEXT: pushq %rbx +; CHECK-NEXT: .cfi_def_cfa_offset 24 +; CHECK-NEXT: subq $200, %rsp +; CHECK-NEXT: .cfi_def_cfa_offset 224 +; CHECK-NEXT: .cfi_offset %rbx, -24 +; CHECK-NEXT: .cfi_offset %r14, -16 +; CHECK-NEXT: movq %rdi, %rbx +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax +; CHECK-NEXT: andl $1, %eax +; CHECK-NEXT: negq %rax +; CHECK-NEXT: andl $1, %r9d +; CHECK-NEXT: negq %r9 +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %r11 +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %r10 +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %r14 +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rdi +; CHECK-NEXT: movq %r8, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %rcx, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %rdx, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %rsi, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %rdi, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %r14, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %r11, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %r10, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %r9, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %r9, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %r9, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %r9, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp) +; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rdi +; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rsi +; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rdx +; CHECK-NEXT: movl $512, %ecx # imm = 0x200 +; CHECK-NEXT: callq __divei4@PLT +; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rcx +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rdx +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rsi +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rdi +; CHECK-NEXT: movq %rdi, 24(%rbx) +; CHECK-NEXT: movq %rsi, 16(%rbx) +; CHECK-NEXT: movq %rdx, 8(%rbx) +; CHECK-NEXT: movq %rcx, (%rbx) +; CHECK-NEXT: andl $1, %eax +; CHECK-NEXT: movb %al, 32(%rbx) +; CHECK-NEXT: movq %rbx, %rax +; CHECK-NEXT: addq $200, %rsp +; CHECK-NEXT: .cfi_def_cfa_offset 24 +; CHECK-NEXT: popq %rbx +; CHECK-NEXT: .cfi_def_cfa_offset 16 +; CHECK-NEXT: popq %r14 +; CHECK-NEXT: .cfi_def_cfa_offset 8 +; CHECK-NEXT: retq + %res = sdiv i257 %a, %b + ret i257 %res +} + +define i1001 @srem1001(i1001 %a, i1001 %b) { +; CHECK-LABEL: srem1001: +; CHECK: # %bb.0: +; CHECK-NEXT: pushq %rbp +; CHECK-NEXT: .cfi_def_cfa_offset 16 +; CHECK-NEXT: pushq %r15 +; CHECK-NEXT: .cfi_def_cfa_offset 24 +; CHECK-NEXT: pushq %r14 +; CHECK-NEXT: .cfi_def_cfa_offset 32 +; CHECK-NEXT: pushq %r13 +; CHECK-NEXT: .cfi_def_cfa_offset 40 +; CHECK-NEXT: pushq %r12 +; CHECK-NEXT: .cfi_def_cfa_offset 48 +; CHECK-NEXT: pushq %rbx +; CHECK-NEXT: .cfi_def_cfa_offset 56 +; CHECK-NEXT: subq $408, %rsp # imm = 0x198 +; CHECK-NEXT: .cfi_def_cfa_offset 464 +; CHECK-NEXT: .cfi_offset %rbx, -56 +; CHECK-NEXT: .cfi_offset %r12, -48 +; CHECK-NEXT: .cfi_offset %r13, -40 +; CHECK-NEXT: .cfi_offset %r14, -32 +; CHECK-NEXT: .cfi_offset %r15, -24 +; CHECK-NEXT: .cfi_offset %rbp, -16 +; CHECK-NEXT: movq %rdi, %rbx +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax +; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax +; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax +; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax +; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax +; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax +; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax +; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax +; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax +; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax +; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %r9, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %r8, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %rcx, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %rdx, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %rsi, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax +; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax +; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax +; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax +; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax +; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax +; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax +; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax +; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax +; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax +; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax +; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax +; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax +; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax +; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax +; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax +; CHECK-NEXT: shlq $23, %rax +; CHECK-NEXT: sarq $23, %rax +; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax +; CHECK-NEXT: shlq $23, %rax +; CHECK-NEXT: sarq $23, %rax +; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp) +; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rdi +; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rsi +; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rdx +; CHECK-NEXT: movl $1024, %ecx # imm = 0x400 +; CHECK-NEXT: callq __modei4@PLT +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rcx +; CHECK-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rcx +; CHECK-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %r10 +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %r11 +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %r14 +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %r15 +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %r12 +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %r13 +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %r8 +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rdx +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rsi +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rdi +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rbp +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rcx +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %r9 +; CHECK-NEXT: movq %r9, 112(%rbx) +; CHECK-NEXT: movq %rcx, 104(%rbx) +; CHECK-NEXT: movq %rbp, 96(%rbx) +; CHECK-NEXT: movq %rdi, 88(%rbx) +; CHECK-NEXT: movq %rsi, 80(%rbx) +; CHECK-NEXT: movq %rdx, 72(%rbx) +; CHECK-NEXT: movq %r8, 64(%rbx) +; CHECK-NEXT: movq %r13, 56(%rbx) +; CHECK-NEXT: movq %r12, 48(%rbx) +; CHECK-NEXT: movq %r15, 40(%rbx) +; CHECK-NEXT: movq %r14, 32(%rbx) +; CHECK-NEXT: movq %r11, 24(%rbx) +; CHECK-NEXT: movq %r10, 16(%rbx) +; CHECK-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rcx # 8-byte Reload +; CHECK-NEXT: movq %rcx, 8(%rbx) +; CHECK-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rcx # 8-byte Reload +; CHECK-NEXT: movq %rcx, (%rbx) +; CHECK-NEXT: movl %eax, 120(%rbx) +; CHECK-NEXT: shrq $32, %rax +; CHECK-NEXT: andl $511, %eax # imm = 0x1FF +; CHECK-NEXT: movw %ax, 124(%rbx) +; CHECK-NEXT: movq %rbx, %rax +; CHECK-NEXT: addq $408, %rsp # imm = 0x198 +; CHECK-NEXT: .cfi_def_cfa_offset 56 +; CHECK-NEXT: popq %rbx +; CHECK-NEXT: .cfi_def_cfa_offset 48 +; CHECK-NEXT: popq %r12 +; CHECK-NEXT: .cfi_def_cfa_offset 40 +; CHECK-NEXT: popq %r13 +; CHECK-NEXT: .cfi_def_cfa_offset 32 +; CHECK-NEXT: popq %r14 +; CHECK-NEXT: .cfi_def_cfa_offset 24 +; CHECK-NEXT: popq %r15 +; CHECK-NEXT: .cfi_def_cfa_offset 16 +; CHECK-NEXT: popq %rbp +; CHECK-NEXT: .cfi_def_cfa_offset 8 +; CHECK-NEXT: retq + %res = srem i1001 %a, %b + ret i1001 %res +} + +define i129 @chain129(i129 %a, i129 %b) { +; CHECK-LABEL: chain129: +; CHECK: # %bb.0: +; CHECK-NEXT: subq $200, %rsp +; CHECK-NEXT: .cfi_def_cfa_offset 208 +; CHECK-NEXT: andl $1, %r9d +; CHECK-NEXT: andl $1, %edx +; CHECK-NEXT: movq %rsi, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %rdi, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %rcx, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %r8, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %rdx, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %r9, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq $0, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq $0, {{[0-9]+}}(%rsp) +; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rdi +; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rsi +; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rdx +; CHECK-NEXT: movl $256, %ecx # imm = 0x100 +; CHECK-NEXT: callq __udivei4@PLT +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax +; CHECK-NEXT: andl $1, %eax +; CHECK-NEXT: negq %rax +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rcx +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rdx +; CHECK-NEXT: movq %rdx, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %rcx, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq %rax, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq $0, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq $0, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq $17, {{[0-9]+}}(%rsp) +; CHECK-NEXT: movq $0, {{[0-9]+}}(%rsp) +; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rdi +; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rsi +; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rdx +; CHECK-NEXT: movl $256, %ecx # imm = 0x100 +; CHECK-NEXT: callq __divei4@PLT +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rcx +; CHECK-NEXT: andl $1, %ecx +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rdx +; CHECK-NEXT: addq $200, %rsp +; CHECK-NEXT: .cfi_def_cfa_offset 8 +; CHECK-NEXT: retq + %res = udiv i129 %a, %b + %res2 = sdiv i129 %res, 17 + ret i129 %res2 +}