[PATCH] Optimize icmp involving addition better
David Majnemer
david.majnemer at gmail.com
Thu Apr 11 02:24:45 PDT 2013
Thanks for taking a look.
> Hi David,
>
>> --- lib/Transforms/InstCombine/InstCombineCompares.cpp (revision 179146)
>> +++ lib/Transforms/InstCombine/InstCombineCompares.cpp (working copy)
>> @@ -2487,6 +2487,59 @@
>> return new ICmpInst(Pred, Y, Z);
>> }
>>
>> + // icmp slt (X + -1), Y -> icmp sle X, Y
>> + if (A && NoOp0WrapProblem && match(B, m_AllOnes()) &&
>> + Pred == CmpInst::ICMP_SLT)
>
> it would be cheaper to first check the predicate Pred before doing the match,
> rather than after, so that if the predicate is wrong then the match code
> isn't executed.
Changed.
>
>> + // if C1 has greater magnitude than C2:
>> + // icmp (X + C1), (Y + C2) -> icmp (X + C3), Y
>
> You didn't define C3 (C3 = C1 - C2 here). You also forgot to mention that
> they have to have the same sign.
Changed.
>
>> + //
>> + // if C2 has greater magnitude than C1:
>> + // icmp (X + C1), (Y + C2) -> icmp X, (Y + C3)
>
> Likewise.
Changed.
>
>> + if (A && C && NoOp0WrapProblem && NoOp1WrapProblem &&
>> + (BO0->hasOneUse() || BO1->hasOneUse()) &&
>> + ICmpInst::getSignedPredicate(Pred) == Pred)
>
> You can use isSigned(Pred) rather than this last test.
Your expression is different than mine in that it excludes the possibilities of pred being ICMP_EQ or ICMP_NE.
My goal was to exclude the optimization from deal with unsigned comparisons, I've changed it to !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();
>> + APInt AP3;
>> + if (AP1Abs.uge(AP2Abs))
>> + AP3 = AP1Abs - AP2Abs;
>
> Can't this be: AP3 = AP1 - AP2
Changed.
>
>> + else
>> + AP3 = AP2Abs - AP1Abs;
>
> And here: AP3 = AP2 - AP1
Changed.
>
>> + if (AP1.isNegative())
>> + AP3 = -AP3;
>
> Then this can go away.
Changed.
>
>> +
>> + ConstantInt *C3 = Builder->getInt(AP3);
>> + Value *Modded = AP1Abs.uge(AP2Abs) ? A : C;
>> + Value *NewAdd = Builder->CreateNSWAdd(Modded, C3);
>> + Value *NewLHS = Modded == A ? NewAdd : A;
>> + Value *NewRHS = Modded == C ? NewAdd : C;
>> + return new ICmpInst(Pred, NewLHS, NewRHS);
>
> Instead of this, it might be simpler to do:
>
> if (AP1Abs.uge(AP2Abs)) {
> AP3 = AP1 - AP2;
> ConstantInt *C3 = Builder->getInt(AP3); // Could just use AP1-AP2 directly
> Value *NewAdd = Builder->CreateNSWAdd(A, C3);
> return new ICmpInst(Pred, NewAdd, C);
> } else {
> ... likewise ...
> }
>
> Ciao, Duncan.
>> + }
>> + }
>> +
>> +
>> // 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;
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
-------------- next part --------------
A non-text attachment was scrubbed...
Name: icmp_cstv2.diff
Type: application/octet-stream
Size: 2504 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130411/be9b0543/attachment.obj>
More information about the llvm-commits
mailing list