The intersection of two ConstantRanges may consist of two disjoint ranges. As we can only return one range as the result, we need to return one of the two possible ranges that cover both. Currently the result is picked based on set size. However, this is not always optimal: If we're in an unsigned context, we'd prefer to get a large unsigned range over a small signed range -- the latter effectively becomes a full set in the unsigned domain.
This revision adds an IntersectionType, which can be either Smallest, Unsigned or Signed. Smallest is the current behavior and Unsigned and Signed are new variants that prefer not to wrap the unsigned/signed domain. The new type isn't used anywhere yet (but SCEV will be a good first user).
I've also added some comments to illustrate the various cases in intersectWith(), which should hopefully make it more obvious what is going on.
The or if both possibilities wrap or don't wrap, the smaller set. is applicable for both the Unsigned and Signed IntersectionTypes. Maybe move that phrase to the end, after explaining Unsigned?