[PATCH] D51942: [InstCombine] Fold (C/x)>0 into x>0 if possible

Martin Elshuber via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 26 04:23:04 PDT 2018


marels added a comment.

In https://reviews.llvm.org/D51942#1245559, @spatel wrote:

> In https://reviews.llvm.org/D51942#1245429, @marels wrote:
>
> > I was not able to find a way to match the following predicates with the existing API.
>
>
> Sorry this wasn't clear - I was only suggesting that we handle vector splat (all constants within the vector are identical or undef) patterns in this patch. You're correct that handling arbitrary vector constants is a harder problem. The API I would use here is "m_APFloat" (it deals with splat constants internally, so you probably don't need to do anything special in the calling code for this patch).


I do not think it is that much harder, it just requires some API extensions. I do not like it to much to just handle splat pattern because it unnecessarily hardens the preconditions just because of a lack API and I guess more optimisations could benefit from such an extension. However, if there is no API yet, I think it is best to restrict on splat values - at least for now. Do you know? Are there any activities ongoing in extending the PatternMatching API. As a first shot I am thinking of something like

template <typename ScalarType> m_ComplexMatch(bool (match_fn*)(ScalarType &e));

where as match_fn is called on all vector elements (or on the single scalar). This generically allows more complex matchings.

>> @spatel what do you think about @john.brawn suggestion to removing the hasAllowReciprocal check?
> 
> That sounds correct - I don't think you don't need it here.

I will remove this.

> But that does raise the question: are you planning to generalize this transform? I see a few possible enhancements:

I think most of those are not truly generalisations because they require different equality transformations. But they are worth to take a look into in separate patches.

> 1. Handle (X / C) < 0.0  (constant is divisor rather than dividend
> 2. Handle (X * C) < 0.0  (multiplication rather than division)



1. and 2. are equivalent: To remove the dot operation from the compare, the inequality has to be multiplied by C or 1/C with the predicate swapped depending on the sign of C.

> 3. Handle all of the above with non-zero compare constant: (X / C1) < C2, (C1 / X) < C2, (X * C1) < C2

ad (X / C1) < C2, (X * C1) < C2: Could be easily combined with the implementation of 1. and 2. On only need to compute C2*C1 or C2/C1 at compile time.
ad (C1 / X) < C2: Transforming this the same way in as done in this patch (*X*X/C1) leads to the equation (with the predicate swapped depending on the sign of C1):

  X < X*X*C2/C1

Assuming C1/X is used later you only add instructions.
Assuming C1/X is not used later, you trade a division by 2 multiplications. This can be beneficial but in general benefits are hard to assume during InstCombine.
When transforming differently by (e.g. *X/C1) the predicate cannot be determined anymore because the sign of X is not known to the compiler.


Repository:
  rL LLVM

https://reviews.llvm.org/D51942





More information about the llvm-commits mailing list