This patch extends applyLoopGuards to detect a single-cond range check
idiom that InstCombine generates.
It extends applyLoopGuards to detect (LHS Predicate RHS) which
represents a compare for a range check with a single condition,
as InstCombine may create. A check of the form (-1 + X) u< C
where C in [1, unsigned max) can be de-composed into 2 separate checks:
- X u< (1 + C)
- X u> 0.
In practice, this enables us to correctly compute a tight trip count
bounds for code as in the function below. InstCombine will fold the
minimum iteration check created by LoopRotate with the user check (< 8).
void unsigned_check(short *pred, unsigned width) { if (width < 8) { for (int x = 0; x < width; x++) pred[x] = pred[x] * pred[x]; } }
As a consequence, LLVM creates dead vector loops for the code above,
e.g. see https://godbolt.org/z/cb8eTcqET
Note that I think it is a bit unfortunate that we still need to detect
such patterns explicitly, but I am not sure if there's a better
alternative at the moment.
Attempt to model using Alive2:
https://alive2.llvm.org/ce/z/_VbcYZ
I found the wording on this confusing the first several times I read it. Can you reword? One suggestion below if helpful.
Check for a condition of the form (X - 1) < C. InstCombine will create this form when combining two checks of the form x <= C and x >u 0.
(Note the use of the <= to avoid need for C+1 in example. Note avoid mention "range check" as X > 0 doesn't seem like an idiomatic range check to me.)