[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 04:36:27 PDT 2016


I managed to reproduce this offline.
Reverted in r283442. Please let me know if you want me to test the
patch locally before committing again.

Regards,
Diana

On 6 October 2016 at 10:42, Diana Picus <diana.picus at linaro.org> wrote:
> 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