[llvm-commits] [llvm] r127829 - in /llvm/trunk: lib/CodeGen/SelectionDAG/TargetLowering.cpp test/CodeGen/X86/divide-by-constant.ll

Rafael EspĂ­ndola rafael.espindola at gmail.com
Wed Jul 11 11:22:10 PDT 2012


This caused pr13326. Can you take a look?

On 17 March 2011 16:39, Benjamin Kramer <benny.kra at googlemail.com> wrote:
> Author: d0k
> Date: Thu Mar 17 15:39:14 2011
> New Revision: 127829
>
> URL: http://llvm.org/viewvc/llvm-project?rev=127829&view=rev
> Log:
> BuildUDIV: If the divisor is even we can simplify the fixup of the multiplied value by introducing an early shift.
>
> This allows us to compile "unsigned foo(unsigned x) { return x/28; }" into
>         shrl    $2, %edi
>         imulq   $613566757, %rdi, %rax
>         shrq    $32, %rax
>         ret
>
> instead of
>         movl    %edi, %eax
>         imulq   $613566757, %rax, %rcx
>         shrq    $32, %rcx
>         subl    %ecx, %eax
>         shrl    %eax
>         addl    %ecx, %eax
>         shrl    $4, %eax
>
> on x86_64
>
> Modified:
>     llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp
>     llvm/trunk/test/CodeGen/X86/divide-by-constant.ll
>
> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp?rev=127829&r1=127828&r2=127829&view=diff
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp (original)
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp Thu Mar 17 15:39:14 2011
> @@ -3174,26 +3174,39 @@
>
>    // FIXME: We should use a narrower constant when the upper
>    // bits are known to be zero.
> -  ConstantSDNode *N1C = cast<ConstantSDNode>(N->getOperand(1));
> -  APInt::mu magics = N1C->getAPIntValue().magicu();
> +  const APInt &N1C = cast<ConstantSDNode>(N->getOperand(1))->getAPIntValue();
> +  APInt::mu magics = N1C.magicu();
> +
> +  SDValue Q = N->getOperand(0);
> +
> +  // If the divisor is even, we can avoid using the expensive fixup by shifting
> +  // the divided value upfront.
> +  if (magics.a != 0 && !N1C[0]) {
> +    unsigned Shift = N1C.countTrailingZeros();
> +    Q = DAG.getNode(ISD::SRL, dl, VT, Q,
> +                    DAG.getConstant(Shift, getShiftAmountTy(Q.getValueType())));
> +    if (Created)
> +      Created->push_back(Q.getNode());
> +
> +    // Get magic number for the shifted divisor.
> +    magics = N1C.lshr(Shift).magicu(Shift);
> +    assert(magics.a == 0 && "Should use cheap fixup now");
> +  }
>
>    // Multiply the numerator (operand 0) by the magic value
>    // FIXME: We should support doing a MUL in a wider type
> -  SDValue Q;
>    if (isOperationLegalOrCustom(ISD::MULHU, VT))
> -    Q = DAG.getNode(ISD::MULHU, dl, VT, N->getOperand(0),
> -                    DAG.getConstant(magics.m, VT));
> +    Q = DAG.getNode(ISD::MULHU, dl, VT, Q, DAG.getConstant(magics.m, VT));
>    else if (isOperationLegalOrCustom(ISD::UMUL_LOHI, VT))
> -    Q = SDValue(DAG.getNode(ISD::UMUL_LOHI, dl, DAG.getVTList(VT, VT),
> -                              N->getOperand(0),
> -                              DAG.getConstant(magics.m, VT)).getNode(), 1);
> +    Q = SDValue(DAG.getNode(ISD::UMUL_LOHI, dl, DAG.getVTList(VT, VT), Q,
> +                            DAG.getConstant(magics.m, VT)).getNode(), 1);
>    else
>      return SDValue();       // No mulhu or equvialent
>    if (Created)
>      Created->push_back(Q.getNode());
>
>    if (magics.a == 0) {
> -    assert(magics.s < N1C->getAPIntValue().getBitWidth() &&
> +    assert(magics.s < N1C.getBitWidth() &&
>             "We shouldn't generate an undefined shift!");
>      return DAG.getNode(ISD::SRL, dl, VT, Q,
>                   DAG.getConstant(magics.s, getShiftAmountTy(Q.getValueType())));
>
> Modified: llvm/trunk/test/CodeGen/X86/divide-by-constant.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/divide-by-constant.ll?rev=127829&r1=127828&r2=127829&view=diff
> ==============================================================================
> --- llvm/trunk/test/CodeGen/X86/divide-by-constant.ll (original)
> +++ llvm/trunk/test/CodeGen/X86/divide-by-constant.ll Thu Mar 17 15:39:14 2011
> @@ -60,3 +60,14 @@
>  ; CHECK: shrl  $31, %ecx
>  ; CHECK: sarl  $18, %eax
>  }
> +
> +define i32 @test7(i32 %x) nounwind {
> +  %div = udiv i32 %x, 28
> +  ret i32 %div
> +; CHECK: test7:
> +; CHECK: shrl $2
> +; CHECK: movl $613566757
> +; CHECK: mull
> +; CHECK-NOT: shrl
> +; CHECK: ret
> +}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits



More information about the llvm-commits mailing list