Given a pattern like:
%old_cmp1 = icmp slt i32 %x, C2 %old_replacement = select i1 %old_cmp1, i32 %target_low, i32 %target_high %old_x_offseted = add i32 %x, C1 %old_cmp0 = icmp ult i32 %old_x_offseted, C0 %r = select i1 %old_cmp0, i32 %x, i32 %old_replacement
it can be rewritten as more canonical pattern:
%new_cmp1 = icmp slt i32 %x, -C1 %new_cmp2 = icmp sge i32 %x, C0-C1 %new_clamped_low = select i1 %new_cmp1, i32 %target_low, i32 %x %r = select i1 %new_cmp2, i32 %target_high, i32 %new_clamped_low
Iff -C1 s<= C2 s<= C0-C1
Also, ULT predicate can also be UGE; or UGT iff C0 != -1 (+invert result)
Also, SLT predicate can also be SGE; or SGT iff C2 != INT_MAX (+invert result)
If C1 == 0, then all 3 instructions must be one-use; else at most either %old_cmp1 or %old_x_offseted can have extra uses.
So there are two icmp's, each one with 3 predicate variants, so there are 9 fold variants:
This fold was brought up in https://reviews.llvm.org/D65148#1603922 by @dmgreen, and is needed to unblock that patch.
This patch requires D65530.