I found a case where after a specific awkward set of inlining and combining, we would end up with code that looked like:
%1 = icmp slt i32 %shr, -128 %2 = select i1 %1, i32 128, i32 %shr %.inv = icmp sgt i32 %shr, 127 %spec.select.i = select i1 %.inv, i32 127, i32 %2 %conv7 = trunc i32 %spec.select.i to i8
This should be turned into a min/max pattern, but somewhere along the line the "-128" in the first select was instead transformed into "128", as only the bottom byte was ever demanded.
To fix this, I've put in further canonicalisation for the immediates of select, preferring to use the same value as the icmp if available.
nit: try and keep -> try to keep