[llvm] r179316 - Optimize icmp involving addition better

David Majnemer david.majnemer at gmail.com
Wed Apr 17 21:42:22 PDT 2013


I'm sorry to hear that this is making something upset. I'm afraid I do not
have such hardware. The transform that this code does is pretty simple. A
wild guess would be that the ARM backend is surprised by something and is
lowering some code wrong.

I'd be happy to help you with this, is there an easy way for me to get
proper hardware?

Thanks
-- 
David Majnemer


On Wed, Apr 17, 2013 at 2:39 AM, Renato Golin <renato.golin at linaro.org>wrote:

> Folks,
>
> This patch is not agreeing with some Cortex-A9/15 specific optimization,
> as it fails only when I specify either on --mcpu the command line option.
> Before I start digging the huge code, can anyone of you spot any direct
> problem of this patch against A9/15 specific optimizations?
>
> I'm trying to reduce the test into a manageable and reproducible source
> file, but this can take a while. If I don't hear from anyone until Friday,
> I'm afraid I'll have to revert the patch until we can figure out what's
> going on. We need a clean trunk to produce the LLVM ARM binaries for 3.3
> release.
>
> cheers,
> --renato
>
>
> On 16 April 2013 14:01, Renato Golin <renato.golin at linaro.org> wrote:
>
>> Hi David,
>>
>> This patch broke one of out buildbots:
>>
>> http://lab.llvm.org:8011/builders/clang-native-arm-lnt/builds/532
>>
>> I have reverted you patch locally and the test pass again, but it's not
>> easy to spot what's wrong with it.
>>
>> Do you have access to ARM hardware?
>>
>> cheers,
>> --renato
>>
>>
>> On 11 April 2013 21:05, David Majnemer <david.majnemer at gmail.com> wrote:
>>
>>> Author: majnemer
>>> Date: Thu Apr 11 15:05:46 2013
>>> New Revision: 179316
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=179316&view=rev
>>> Log:
>>> Optimize icmp involving addition better
>>>
>>> Allows LLVM to optimize sequences like the following:
>>>
>>> %add = add nsw i32 %x, 1
>>> %cmp = icmp sgt i32 %add, %y
>>>
>>> into:
>>>
>>> %cmp = icmp sge i32 %x, %y
>>>
>>> as well as:
>>>
>>> %add1 = add nsw i32 %x, 20
>>> %add2 = add nsw i32 %y, 57
>>> %cmp = icmp sge i32 %add1, %add2
>>>
>>> into:
>>>
>>> %add = add nsw i32 %y, 37
>>> %cmp = icmp sle i32 %cmp, %x
>>>
>>> Modified:
>>>     llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp
>>>     llvm/trunk/test/Transforms/InstCombine/icmp.ll
>>>
>>> Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp?rev=179316&r1=179315&r2=179316&view=diff
>>>
>>> ==============================================================================
>>> --- llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp
>>> (original)
>>> +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp Thu
>>> Apr 11 15:05:46 2013
>>> @@ -2487,6 +2487,55 @@ Instruction *InstCombiner::visitICmpInst
>>>        return new ICmpInst(Pred, Y, Z);
>>>      }
>>>
>>> +    // icmp slt (X + -1), Y -> icmp sle X, Y
>>> +    if (A && NoOp0WrapProblem && Pred == CmpInst::ICMP_SLT &&
>>> +        match(B, m_AllOnes()))
>>> +      return new ICmpInst(CmpInst::ICMP_SLE, A, Op1);
>>> +
>>> +    // icmp sge (X + -1), Y -> icmp sgt X, Y
>>> +    if (A && NoOp0WrapProblem && Pred == CmpInst::ICMP_SGE &&
>>> +        match(B, m_AllOnes()))
>>> +      return new ICmpInst(CmpInst::ICMP_SGT, A, Op1);
>>> +
>>> +    // icmp sle (X + 1), Y -> icmp slt X, Y
>>> +    if (A && NoOp0WrapProblem && Pred == CmpInst::ICMP_SLE &&
>>> +        match(B, m_One()))
>>> +      return new ICmpInst(CmpInst::ICMP_SLT, A, Op1);
>>> +
>>> +    // icmp sgt (X + 1), Y -> icmp sge X, Y
>>> +    if (A && NoOp0WrapProblem && Pred == CmpInst::ICMP_SGT &&
>>> +        match(B, m_One()))
>>> +      return new ICmpInst(CmpInst::ICMP_SGE, A, Op1);
>>> +
>>> +    // if C1 has greater magnitude than C2:
>>> +    //  icmp (X + C1), (Y + C2) -> icmp (X + C3), Y
>>> +    //  s.t. C3 = C1 - C2
>>> +    //
>>> +    // if C2 has greater magnitude than C1:
>>> +    //  icmp (X + C1), (Y + C2) -> icmp X, (Y + C3)
>>> +    //  s.t. C3 = C2 - C1
>>> +    if (A && C && NoOp0WrapProblem && NoOp1WrapProblem &&
>>> +        (BO0->hasOneUse() || BO1->hasOneUse()) && !I.isUnsigned())
>>> +      if (ConstantInt *C1 = dyn_cast<ConstantInt>(B))
>>> +        if (ConstantInt *C2 = dyn_cast<ConstantInt>(D)) {
>>> +          const APInt &AP1 = C1->getValue();
>>> +          const APInt &AP2 = C2->getValue();
>>> +          if (AP1.isNegative() == AP2.isNegative()) {
>>> +            APInt AP1Abs = C1->getValue().abs();
>>> +            APInt AP2Abs = C2->getValue().abs();
>>> +            if (AP1Abs.uge(AP2Abs)) {
>>> +              ConstantInt *C3 = Builder->getInt(AP1 - AP2);
>>> +              Value *NewAdd = Builder->CreateNSWAdd(A, C3);
>>> +              return new ICmpInst(Pred, NewAdd, C);
>>> +            } else {
>>> +              ConstantInt *C3 = Builder->getInt(AP2 - AP1);
>>> +              Value *NewAdd = Builder->CreateNSWAdd(C, C3);
>>> +              return new ICmpInst(Pred, A, NewAdd);
>>> +            }
>>> +          }
>>> +        }
>>> +
>>> +
>>>      // Analyze the case when either Op0 or Op1 is a sub instruction.
>>>      // Op0 = A - B (or A and B are null); Op1 = C - D (or C and D are
>>> null).
>>>      A = 0; B = 0; C = 0; D = 0;
>>>
>>> Modified: llvm/trunk/test/Transforms/InstCombine/icmp.ll
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/icmp.ll?rev=179316&r1=179315&r2=179316&view=diff
>>>
>>> ==============================================================================
>>> --- llvm/trunk/test/Transforms/InstCombine/icmp.ll (original)
>>> +++ llvm/trunk/test/Transforms/InstCombine/icmp.ll Thu Apr 11 15:05:46
>>> 2013
>>> @@ -886,3 +886,55 @@ define i1 @icmp_mul0_ne0(i32 %x) {
>>>    %cmp = icmp ne i32 %mul, 0
>>>    ret i1 %cmp
>>>  }
>>> +
>>> +; CHECK: @icmp_sub1_sge
>>> +; CHECK-NEXT: icmp sgt i32 %x, %y
>>> +define i1 @icmp_sub1_sge(i32 %x, i32 %y) {
>>> +  %sub = add nsw i32 %x, -1
>>> +  %cmp = icmp sge i32 %sub, %y
>>> +  ret i1 %cmp
>>> +}
>>> +
>>> +; CHECK: @icmp_add1_sgt
>>> +; CHECK-NEXT: icmp sge i32 %x, %y
>>> +define i1 @icmp_add1_sgt(i32 %x, i32 %y) {
>>> +  %add = add nsw i32 %x, 1
>>> +  %cmp = icmp sgt i32 %add, %y
>>> +  ret i1 %cmp
>>> +}
>>> +
>>> +; CHECK: @icmp_sub1_slt
>>> +; CHECK-NEXT: icmp sle i32 %x, %y
>>> +define i1 @icmp_sub1_slt(i32 %x, i32 %y) {
>>> +  %sub = add nsw i32 %x, -1
>>> +  %cmp = icmp slt i32 %sub, %y
>>> +  ret i1 %cmp
>>> +}
>>> +
>>> +; CHECK: @icmp_add1_sle
>>> +; CHECK-NEXT: icmp slt i32 %x, %y
>>> +define i1 @icmp_add1_sle(i32 %x, i32 %y) {
>>> +  %add = add nsw i32 %x, 1
>>> +  %cmp = icmp sle i32 %add, %y
>>> +  ret i1 %cmp
>>> +}
>>> +
>>> +; CHECK: @icmp_add20_sge_add57
>>> +; CHECK-NEXT: [[ADD:%[a-z0-9]+]] = add nsw i32 %y, 37
>>> +; CHECK-NEXT: icmp sle i32 [[ADD]], %x
>>> +define i1 @icmp_add20_sge_add57(i32 %x, i32 %y) {
>>> +  %1 = add nsw i32 %x, 20
>>> +  %2 = add nsw i32 %y, 57
>>> +  %cmp = icmp sge i32 %1, %2
>>> +  ret i1 %cmp
>>> +}
>>> +
>>> +; CHECK: @icmp_sub57_sge_sub20
>>> +; CHECK-NEXT: [[SUB:%[a-z0-9]+]] = add nsw i32 %x, -37
>>> +; CHECK-NEXT: icmp sge i32 [[SUB]], %y
>>> +define i1 @icmp_sub57_sge_sub20(i32 %x, i32 %y) {
>>> +  %1 = add nsw i32 %x, -57
>>> +  %2 = add nsw i32 %y, -20
>>> +  %cmp = icmp sge i32 %1, %2
>>> +  ret i1 %cmp
>>> +}
>>>
>>>
>>> _______________________________________________
>>> llvm-commits mailing list
>>> llvm-commits at cs.uiuc.edu
>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>>
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130417/99a7177e/attachment.html>


More information about the llvm-commits mailing list