[PATCH] Optimize icmp involving addition better
Duncan Sands
baldrick at free.fr
Wed Apr 10 06:11:56 PDT 2013
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.
> + // 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.
> + //
> + // if C2 has greater magnitude than C1:
> + // icmp (X + C1), (Y + C2) -> icmp X, (Y + C3)
Likewise.
> + if (A && C && NoOp0WrapProblem && NoOp1WrapProblem &&
> + (BO0->hasOneUse() || BO1->hasOneUse()) &&
> + ICmpInst::getSignedPredicate(Pred) == Pred)
You can use isSigned(Pred) rather than this last test.
> + 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
> + else
> + AP3 = AP2Abs - AP1Abs;
And here: AP3 = AP2 - AP1
> + if (AP1.isNegative())
> + AP3 = -AP3;
Then this can go away.
> +
> + 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;
More information about the llvm-commits
mailing list