[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