This replaces several rewriting rules in `ScalarEvolution::applyLoopGuards` that are applied to min/max expressions with the equivalent ones but applied to its arguments.

So currently given we have a loop guard `min(a, b) >= c`, the min expression gets rewritten as `max(c, min(a, b))`.

With such approach, we're unable to apply the rewrite if `min` operands are `zext` for example (`min(zext(a), zext(b))`), however it's equivalent to the expression `zext(min(a, b))` for which we can apply the rewrite.

We can rewrite the `min` operands instead with these expressions:

`a --> max(c, a)`and`b --> max(c, b)`

and this would allow us to apply the loop guard in this and similar cases: `min(zext(a), zext(b))` would get rewritten as `min(zext(max(c, a)), zext(max(c, b)))` instead of just being skipped.

The table of replaced rules (omitting predicates signedness for simplicity):

Old rule | New rules |

min(a, b) >= c --> max(c, min(a, b)) | a --> max(a, c) and b --> max(b, c) |

min(a, b) > c --> max(c + 1, min(a, b)) | a --> max(a, c + 1) and b --> max(b, c + 1) |

max(a, b) <= c --> min(c, max(a, b)) | a --> min(a, c) and b --> min(b, c) |

max(a, b) < c --> min(c - 1, max(a, b)) | a --> min(a, c - 1) and b --> min(b, c - 1) |