This patch is a first draft of a new pass that adds a more flexible way

to eliminate compares based on more complex constraints collected from

dominating conditions.

In particular, it aims at simplifying conditions of the forms below

using a forward propagation approach, rather than instcomine-style

ad-hoc backwards walking of def-use chains.

if (x < y) if (y < z) if (x < z) <- simplify

or

if (x + 2 < y) if (x + 1 < y) <- simplify assuming no wraps

The general approach is to collect conditions and blocks, sort them by

dominance and then iterate over the sorted list. Conditions are turned

into a linear inequality and add it to a system containing the linear

inequalities that hold on entry to the block. For blocks, we check each

compare against the system and see if it is implied by the constraints

in the system.

We also keep a stack of processed conditions and remove conditions from

the stack and the constraint system once they go out-of-scope (= do not

dominate the current block any longer).

Currently there still are the least the following issues

- Checking the system requires multiplications/additions on potentially large numbers and could overflow. I guess we would need to detect and bail out when that happens
- Currently large unsigned constants cannot be added to the system (coefficients must be represented as integers)
- The way constraints are managed currently is not very optimized.

The last 2 don't need to be addressed immediately, but I think the first

one would need to be addressed to start with.

But for now, I'd like to share the approach to get some initial

thoughts/feedback.