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

Benjamin Kramer benny.kra at gmail.com
Wed Jul 11 11:40:06 PDT 2012


On 11.07.2012, at 20:22, Rafael EspĂ­ndola <rafael.espindola at gmail.com> wrote:

> This caused pr13326. Can you take a look?

Fixed in r160058.

- Ben
> 
> 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