[llvm] r283383 - [ARM] Use __rt_div functions for divrem on Windows

Diana Picus via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 6 00:42:24 PDT 2016


Hi Martin,

I suspect this commit has broken our ARM selfhost bots [1]. I haven't
reproduced it yet (in progress), but maybe you can have a look.

Thanks,
Diana

[1] http://lab.llvm.org:8011/builders/clang-cmake-armv7-a15-selfhost-neon/builds/5687

On 6 October 2016 at 00:08, Martin Storsjo via llvm-commits
<llvm-commits at lists.llvm.org> wrote:
> Author: mstorsjo
> Date: Wed Oct  5 16:08:02 2016
> New Revision: 283383
>
> URL: http://llvm.org/viewvc/llvm-project?rev=283383&view=rev
> Log:
> [ARM] Use __rt_div functions for divrem on Windows
>
> This avoids falling back to calling out to the GCC rem functions
> (__moddi3, __umoddi3) when targeting Windows.
>
> The __rt_div functions have flipped the two arguments compared
> to the __aeabi_divmod functions. To match MSVC, we emit a
> check for division by zero before actually calling the library
> function (even if the library function itself also might do
> the same check).
>
> Not all calls to __rt_div functions for division are currently
> merged with calls to the same function with the same parameters
> for the remainder. This is more wasteful than a div + mls as before,
> but avoids calls to __moddi3.
>
> Differential Revision: https://reviews.llvm.org/D24076
>
> Modified:
>     llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
>     llvm/trunk/test/CodeGen/ARM/Windows/dbzchk.ll
>     llvm/trunk/test/CodeGen/ARM/divmod-eabi.ll
>
> Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=283383&r1=283382&r2=283383&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original)
> +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Wed Oct  5 16:08:02 2016
> @@ -980,19 +980,26 @@ ARMTargetLowering::ARMTargetLowering(con
>    setOperationAction(ISD::UREM,  MVT::i32, Expand);
>    // Register based DivRem for AEABI (RTABI 4.2)
>    if (Subtarget->isTargetAEABI() || Subtarget->isTargetAndroid() ||
> -      Subtarget->isTargetGNUAEABI() || Subtarget->isTargetMuslAEABI()) {
> +      Subtarget->isTargetGNUAEABI() || Subtarget->isTargetMuslAEABI() ||
> +      Subtarget->isTargetWindows()) {
>      setOperationAction(ISD::SREM, MVT::i64, Custom);
>      setOperationAction(ISD::UREM, MVT::i64, Custom);
>      HasStandaloneRem = false;
>
> -    setLibcallName(RTLIB::SDIVREM_I8,  "__aeabi_idivmod");
> -    setLibcallName(RTLIB::SDIVREM_I16, "__aeabi_idivmod");
> -    setLibcallName(RTLIB::SDIVREM_I32, "__aeabi_idivmod");
> -    setLibcallName(RTLIB::SDIVREM_I64, "__aeabi_ldivmod");
> -    setLibcallName(RTLIB::UDIVREM_I8,  "__aeabi_uidivmod");
> -    setLibcallName(RTLIB::UDIVREM_I16, "__aeabi_uidivmod");
> -    setLibcallName(RTLIB::UDIVREM_I32, "__aeabi_uidivmod");
> -    setLibcallName(RTLIB::UDIVREM_I64, "__aeabi_uldivmod");
> +    for (const auto &LC :
> +         {RTLIB::SDIVREM_I8, RTLIB::SDIVREM_I16, RTLIB::SDIVREM_I32})
> +      setLibcallName(LC, Subtarget->isTargetWindows() ? "__rt_sdiv"
> +                                                      : "__aeabi_idivmod");
> +    setLibcallName(RTLIB::SDIVREM_I64, Subtarget->isTargetWindows()
> +                                           ? "__rt_sdiv64"
> +                                           : "__aeabi_ldivmod");
> +    for (const auto &LC :
> +         {RTLIB::UDIVREM_I8, RTLIB::UDIVREM_I16, RTLIB::UDIVREM_I32})
> +      setLibcallName(LC, Subtarget->isTargetWindows() ? "__rt_udiv"
> +                                                      : "__aeabi_uidivmod");
> +    setLibcallName(RTLIB::UDIVREM_I64, Subtarget->isTargetWindows()
> +                                           ? "__rt_udiv64"
> +                                           : " __aeabi_uldivmod");
>
>      setLibcallCallingConv(RTLIB::SDIVREM_I8, CallingConv::ARM_AAPCS);
>      setLibcallCallingConv(RTLIB::SDIVREM_I16, CallingConv::ARM_AAPCS);
> @@ -7388,6 +7395,19 @@ SDValue ARMTargetLowering::LowerDIV_Wind
>    return LowerWindowsDIVLibCall(Op, DAG, Signed, DBZCHK);
>  }
>
> +static SDValue WinDBZCheckDenominator(SelectionDAG &DAG, SDNode *N, SDValue InChain) {
> +  SDLoc DL(N);
> +  SDValue Op = N->getOperand(1);
> +  if (N->getValueType(0) == MVT::i32)
> +    return DAG.getNode(ARMISD::WIN__DBZCHK, DL, MVT::Other, InChain, Op);
> +  SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, Op,
> +                           DAG.getConstant(0, DL, MVT::i32));
> +  SDValue Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, Op,
> +                           DAG.getConstant(1, DL, MVT::i32));
> +  return DAG.getNode(ARMISD::WIN__DBZCHK, DL, MVT::Other, InChain,
> +                     DAG.getNode(ISD::OR, DL, MVT::i32, Lo, Hi));
> +}
> +
>  void ARMTargetLowering::ExpandDIV_Windows(
>      SDValue Op, SelectionDAG &DAG, bool Signed,
>      SmallVectorImpl<SDValue> &Results) const {
> @@ -7398,14 +7418,7 @@ void ARMTargetLowering::ExpandDIV_Window
>           "unexpected type for custom lowering DIV");
>    SDLoc dl(Op);
>
> -  SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, Op.getOperand(1),
> -                           DAG.getConstant(0, dl, MVT::i32));
> -  SDValue Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, Op.getOperand(1),
> -                           DAG.getConstant(1, dl, MVT::i32));
> -  SDValue Or = DAG.getNode(ISD::OR, dl, MVT::i32, Lo, Hi);
> -
> -  SDValue DBZCHK =
> -      DAG.getNode(ARMISD::WIN__DBZCHK, dl, MVT::Other, DAG.getEntryNode(), Or);
> +  SDValue DBZCHK = WinDBZCheckDenominator(DAG, Op.getNode(), DAG.getEntryNode());
>
>    SDValue Result = LowerWindowsDIVLibCall(Op, DAG, Signed, DBZCHK);
>
> @@ -12406,7 +12419,7 @@ static RTLIB::Libcall getDivRemLibcall(
>  }
>
>  static TargetLowering::ArgListTy getDivRemArgList(
> -    const SDNode *N, LLVMContext *Context) {
> +    const SDNode *N, LLVMContext *Context, const ARMSubtarget *Subtarget) {
>    assert((N->getOpcode() == ISD::SDIVREM || N->getOpcode() == ISD::UDIVREM ||
>            N->getOpcode() == ISD::SREM    || N->getOpcode() == ISD::UREM) &&
>           "Unhandled Opcode in getDivRemArgList");
> @@ -12423,12 +12436,15 @@ static TargetLowering::ArgListTy getDivR
>      Entry.isZExt = !isSigned;
>      Args.push_back(Entry);
>    }
> +  if (Subtarget->isTargetWindows() && Args.size() >= 2)
> +    std::swap(Args[0], Args[1]);
>    return Args;
>  }
>
>  SDValue ARMTargetLowering::LowerDivRem(SDValue Op, SelectionDAG &DAG) const {
>    assert((Subtarget->isTargetAEABI() || Subtarget->isTargetAndroid() ||
> -          Subtarget->isTargetGNUAEABI() || Subtarget->isTargetMuslAEABI()) &&
> +          Subtarget->isTargetGNUAEABI() || Subtarget->isTargetMuslAEABI() ||
> +          Subtarget->isTargetWindows()) &&
>           "Register-based DivRem lowering only");
>    unsigned Opcode = Op->getOpcode();
>    assert((Opcode == ISD::SDIVREM || Opcode == ISD::UDIVREM) &&
> @@ -12461,13 +12477,17 @@ SDValue ARMTargetLowering::LowerDivRem(S
>    SDValue InChain = DAG.getEntryNode();
>
>    TargetLowering::ArgListTy Args = getDivRemArgList(Op.getNode(),
> -                                                    DAG.getContext());
> +                                                    DAG.getContext(),
> +                                                    Subtarget);
>
>    SDValue Callee = DAG.getExternalSymbol(getLibcallName(LC),
>                                           getPointerTy(DAG.getDataLayout()));
>
>    Type *RetTy = (Type*)StructType::get(Ty, Ty, nullptr);
>
> +  if (Subtarget->isTargetWindows())
> +    InChain = WinDBZCheckDenominator(DAG, Op.getNode(), InChain);
> +
>    TargetLowering::CallLoweringInfo CLI(DAG);
>    CLI.setDebugLoc(dl).setChain(InChain)
>      .setCallee(getLibcallCallingConv(LC), RetTy, Callee, std::move(Args))
> @@ -12500,11 +12520,15 @@ SDValue ARMTargetLowering::LowerREM(SDNo
>    RTLIB::Libcall LC = getDivRemLibcall(N, N->getValueType(0).getSimpleVT().
>                                                               SimpleTy);
>    SDValue InChain = DAG.getEntryNode();
> -  TargetLowering::ArgListTy Args = getDivRemArgList(N, DAG.getContext());
> +  TargetLowering::ArgListTy Args = getDivRemArgList(N, DAG.getContext(),
> +                                                    Subtarget);
>    bool isSigned = N->getOpcode() == ISD::SREM;
>    SDValue Callee = DAG.getExternalSymbol(getLibcallName(LC),
>                                           getPointerTy(DAG.getDataLayout()));
>
> +  if (Subtarget->isTargetWindows())
> +    InChain = WinDBZCheckDenominator(DAG, N, InChain);
> +
>    // Lower call
>    CallLoweringInfo CLI(DAG);
>    CLI.setChain(InChain)
>
> Modified: llvm/trunk/test/CodeGen/ARM/Windows/dbzchk.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/Windows/dbzchk.ll?rev=283383&r1=283382&r2=283383&view=diff
> ==============================================================================
> --- llvm/trunk/test/CodeGen/ARM/Windows/dbzchk.ll (original)
> +++ llvm/trunk/test/CodeGen/ARM/Windows/dbzchk.ll Wed Oct  5 16:08:02 2016
> @@ -141,7 +141,7 @@ attributes #0 = { optsize }
>  ; CHECK-CFG-ASM-NEXT: udf.w #249
>  ; CHECK-CFG-ASM-LABEL: .LBB2_4:
>  ; CHECK-CFG-ASM: bl __rt_udiv
> -; CHECK-CFG-ASM: pop.w {{{.*}}, r11, pc}
> +; CHECK-CFG-ASM: pop.w {r11, pc}
>
>  ; RUN: llc -O0 -mtriple thumbv7--windows-itanium -verify-machineinstrs -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-WIN__DBZCHK
>
>
> Modified: llvm/trunk/test/CodeGen/ARM/divmod-eabi.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/divmod-eabi.ll?rev=283383&r1=283382&r2=283383&view=diff
> ==============================================================================
> --- llvm/trunk/test/CodeGen/ARM/divmod-eabi.ll (original)
> +++ llvm/trunk/test/CodeGen/ARM/divmod-eabi.ll Wed Oct  5 16:08:02 2016
> @@ -42,15 +42,13 @@ entry:
>  ; DARWIN-DEFAULT: add [[sum:r[0-9]+]], r0, [[div]]
>  ; DARWIN-O0: mov [[rem:r[0-9]+]], r0
>  ; WINDOWS: __rt_sdiv
> -; WINDOWS-DEFAULT: mls [[rem:r[0-9]+]], r0,
> -; WINDOWS-DEFAULT: adds [[sum:r[0-9]+]], [[rem]], r0
> -; WINDOWS-O0: mov [[div:r[0-9]+]], r0
> -; WINDOWS-O0: mls [[rem:r[0-9]+]], [[div]],
> +; WINDOWS: __rt_sdiv
> +; WINDOWS-DEFAULT: add [[sum:r[0-9]+]], r1
> +; WINDOWS-O0: mov [[rem:r[0-9]+]], r1
>    %rem8 = srem i32 %conv1, %conv
>  ; EABI: __aeabi_idivmod
>  ; DARWIN: __modsi3
>  ; WINDOWS: __rt_sdiv
> -; WINDOWS: mls [[rem1:r[0-9]+]], r0,
>    %add = add nsw i32 %rem, %div
>    %add13 = add nsw i32 %add, %rem8
>    %conv14 = trunc i32 %add13 to i16
> @@ -60,9 +58,10 @@ entry:
>  ; DARWIN-O0: add [[sum:r[0-9]+]], [[rem]], [[div]]
>  ; DARWIN-O0: add [[res:r[0-9]+]], [[sum]], r0
>  ; DARWIN: sxth r0, [[res]]
> -; WINDOWS-O0: adds [[sum:r[0-9]+]], [[rem]], [[div]]
> -; WINDOWS: add [[rem1]], [[sum]]
> -; WINDOWS: sxth [[res:r[0-9]+]], [[rem1]]
> +; WINDOWS-DEFAULT: adds [[sum1:r[0-9]+]], [[sum]], r1
> +; WINDOWS-O0: adds [[sum:r[0-9]+]], [[rem]],
> +; WINDOWS-O0: add [[sum1:r[0-9]+]], r1
> +; WINDOWS: sxth [[res:r[0-9]+]], [[sum1]]
>    ret i16 %conv14
>  }
>
> @@ -84,22 +83,20 @@ entry:
>  ; WINDOWS: __rt_sdiv
>  ; WINDOWS: mov [[div:r[0-9]+]], r0
>  ; WINDOWS: __rt_sdiv
> -; WINDOWS: mls [[rem:r[0-9]+]], r0,
> -; WINDOWS-DEFAULT: add [[div]], [[rem]]
> +; WINDOWS-DEFAULT: add [[div]], r1
>    %rem1 = srem i32 %b, %a
>  ; EABI: __aeabi_idivmod
>  ; DARWIN: __modsi3
>  ; WINDOWS: __rt_sdiv
> -; WINDOWS: mls [[rem1:r[0-9]+]], r0,
>    %add = add nsw i32 %rem, %div
>    %add2 = add nsw i32 %add, %rem1
>  ; EABI: add r0{{.*}}r1
>  ; DARWIN-DEFAULT: add r0, [[sum]], r0
>  ; DARWIN-O0: add [[sum:r[0-9]+]], [[rem]], [[div]]
>  ; DARWIN-O0: add [[res:r[0-9]+]], [[sum]], r0
> -; WINDOWS-DEFAULT: add [[rem1]], [[div]]
> +; WINDOWS-DEFAULT: adds r0, [[div]], r1
>  ; WINDOWS-O0: adds [[sum:r[0-9]+]], [[rem]], [[div]]
> -; WINDOWS-O0: add [[rem1]], [[sum]]
> +; WINDOWS-O0: add [[sum]], r1
>    ret i32 %add2
>  }
>
> @@ -119,22 +116,20 @@ entry:
>  ; WINDOWS: __rt_udiv
>  ; WINDOWS: mov [[div:r[0-9]+]], r0
>  ; WINDOWS: __rt_udiv
> -; WINDOWS: mls [[rem:r[0-9]+]], r0,
> -; WINDOWS-DEFAULT: add [[div]], [[rem]]
> +; WINDOWS-DEFAULT: add [[div]], r1
>    %rem1 = urem i32 %b, %a
>  ; EABI: __aeabi_uidivmod
>  ; DARWIN: __umodsi3
>  ; WINDOWS: __rt_udiv
> -; WINDOWS: mls [[rem1:r[0-9]+]], r0,
>    %add = add nuw i32 %rem, %div
>    %add2 = add nuw i32 %add, %rem1
>  ; EABI: add r0{{.*}}r1
>  ; DARWIN-DEFAULT: add r0, [[sum]], r0
>  ; DARWIN-O0: add [[sum:r[0-9]+]], [[rem]], [[div]]
>  ; DARWIN-O0: add [[res:r[0-9]+]], [[sum]], r0
> -; WINDOWS-DEFAULT: add [[rem1]], [[div]]
> -; WINDOWS-O0: adds [[sum:r[0-9]+]], [[rem]], [[div]]
> -; WINDOWS-O0: add [[rem1]], [[sum]]
> +; WINDOWS-DEFAULT: adds [[sum:r[0-9]+]], [[div]], r1
> +; WINDOWS-O0: adds [[sum:r[0-9]+]],
> +; WINDOWS-O0: add [[sum]], r1
>    ret i32 %add2
>  }
>
> @@ -154,14 +149,11 @@ entry:
>  ; DARWIN: mov [[div2:r[0-9]+]], r1
>  ; DARWIN: __moddi3
>  ; WINDOWS: __rt_sdiv64
> -; WINDOWS: mov [[div1:r[0-9]+]], r0
> -; WINDOWS: mov [[div2:r[0-9]+]], r1
> -; WINDOWS: __moddi3
>    %add = add nsw i64 %rem, %div
>  ; DARWIN: adds r0{{.*}}[[div1]]
>  ; DARWIN: adc r1{{.*}}[[div2]]
> -; WINDOWS: adds.w r0, r0, [[div1]]
> -; WINDOWS: adc.w r1, r1, [[div2]]
> +; WINDOWS: adds r0, r0, r2
> +; WINDOWS: adcs r1, r3
>    ret i64 %add
>  }
>
> @@ -179,11 +171,10 @@ entry:
>  ; WINDOWS: __rt_sdiv
>  ; WINDOWS: mov [[div:r[0-9]+]], r0
>  ; WINDOWS: __rt_sdiv
> -; WINDOWS: mls [[rem:r[0-9]+]], r0,
>    %add = add nsw i16 %rem, %div
>  ; EABI: add r0, r1
>  ; DARWIN: add r0{{.*}}[[div1]]
> -; WINDOWS: add [[rem]], [[div]]
> +; WINDOWS: adds r0, r1, [[div]]
>    ret i16 %add
>  }
>
> @@ -201,11 +192,10 @@ entry:
>  ; WINDOWS: __rt_sdiv
>  ; WINDOWS: mov [[div:r[0-9]+]], r0
>  ; WINDOWS: __rt_sdiv
> -; WINDOWS: mls [[rem:r[0-9]+]], r0,
>    %add = add nsw i32 %rem, %div
>  ; EABI:        add     r0{{.*}}r1
>  ; DARWIN: add r0{{.*}}[[sum]]
> -; WINDOWS: add [[rem]], [[div]]
> +; WINDOWS: adds r0, r1, [[div]]
>    ret i32 %add
>  }
>
> @@ -221,7 +211,7 @@ entry:
>  ; WINDOWS: __rt_sdiv
>    ret i32 %rem
>  ; EABI:        mov     r0, r1
> -; WINDOWS: mls r0, r0,
> +; WINDOWS: mov  r0, r1
>  }
>
>  define i32 @g3(i32 %a, i32 %b) {
> @@ -235,16 +225,15 @@ entry:
>  ; DARWIN: __modsi3
>  ; DARWIN: mov [[sum:r[0-9]+]], r0
>  ; WINDOWS: __rt_sdiv
> -; WINDOWS: mls [[rem:r[0-9]+]], r0,
> +; WINDOWS: mov [[rem:r[0-9]+]], r1
>    %rem1 = srem i32 %b, %rem
>  ; EABI: __aeabi_idivmod
>  ; DARWIN: __modsi3
>  ; WINDOWS: __rt_sdiv
> -; WINDOWS: mls [[rem1:r[0-9]+]], r0,
>    %add = add nsw i32 %rem1, %rem
>  ; EABI: add r0, r1, [[mod]]
>  ; DARWIN: add r0{{.*}}[[sum]]
> -; WINDOWS: add [[rem1]], [[rem]]
> +; WINDOWS: adds r0, r1, [[rem]]
>    ret i32 %add
>  }
>
> @@ -264,10 +253,9 @@ entry:
>  ; EABI: __aeabi_idivmod
>  ; DARWIN: __modsi3
>  ; WINDOWS: __rt_sdiv
> -; WINDOWS: mls [[rem:r[0-9]+]], r0,
>    %add = add nsw i32 %rem, %div
>  ; EABI: add r0, r1, [[div]]
>  ; DARWIN: add r0{{.*}}[[sum]]
> -; WINDOWS: add [[rem]], [[div]]
> +; WINDOWS: adds r0, r1, [[div]]
>    ret i32 %add
>  }
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits


More information about the llvm-commits mailing list