[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