[PATCH] [ConstantRange] Add a smultiply method for signed multiply

Sanjoy Das sanjoy at playingwithpointers.com
Sat Feb 21 13:05:18 PST 2015

Is it fair to say that your question is: given that
ConstantRange::multiply uses the unsigned and signed max of the range
to calculate its result, how can it possibly work in a signed context?

So the first half of the answer is that you're right, in general the
result computed by using the smax and smin vs. using the umax and umin
will be different.  For instance, given this scheme, [-1, 2) `smult`
[-1, 2) is [-1, 2) (everything is i8 in this email) while [-1, 2)
`umult` [-1, 2) is the full i8 range. **

However, we need to look at the "contract" umult and smult have to

X `umult` Y returns Zu such that Zu is a (sometimes proper) subset of
{ x * y (mod 2^n) | x \in X, y \in Y }

X `smult` Y returns Zs such that Zs is a (sometimes proper) subset
of { x * y (mod 2^n) | x \in X, y \in Y }

In other words, both of them follow the exact same contract.  You can
see how this is true for the [-1, 2) example -- both [-1, 2) and the
full i8 set are legitimate answers for *both* [-1, 2) `smult` [-1, 2)
and [-1, 2) `umult` [-1, 2).  Since [-1, 2) is a more "precise"
answer, *both* `smult` and `umult` should try to return [-1, 2).

Concretely, if in ConstantRange::multiply you can produce a better
(smaller) range
as answer with the signed interpretation of the two ranges you're
multiplying, you should do so.  There is no need for a separate

** I did not bother to verify the math here

-- Sanjoy

More information about the llvm-commits mailing list