Dear all,

Hi! I noticed an interesting situation when using getUnsignedRange and getSignedRange of SCEV for URem instruction.

Here is an example with 2 IR instructions:

%rem.lhs.trunc = trunc i32 %i15.082 to i8 → getUnsignedRange → [1,50)

%rem81 = urem i8 %rem.lhs.trunc, 3 → getUnsignedRange → [-47,50)

The problems are:

- From my perspective, the getUnsignedRange() function should return non-negative range but it seems not so in the example. Is there anything wrong?
- The range of the IR %rem81 should be [0,3), considering the equation: X%3 < 3?

Thanks in advance for your time and suggestions!

1. There is nothing wrong about getUnsignedRange returning a range

with a negative value. "Signed" and "Unsigned" are merely hints, the

underlying ConstantRange representation does not have a concept of

sign. [A, B) represents all the values enumerated by "for (I = A; I

!= B; I++ /*wrapping addition*/) { yield(I); }"

2. I would guess this is because SCEV does not directly represent urem

but instead represents it as "%x urem %y == %x -<nuw> ((%x udiv %y)

*<nuw> %y)". This makes it difficult for SCEV to infer that the X

urem 3 is u< 3.

I feel that we maybe able to pattern match "%x -<nuw> ((%x udiv %y)

*<nuw> %y)" to infer that the results should be smaller than %y. But

not sure if this approach could scale well

Dear all,

Thanks a lot for your analysis and suggestion.

Currently, I walk around in a way similar to what Hongbin said, by treating SCEV of URem specially to get the range.

I guess maybe the rule of inference can be updated haha

Thanks again for your time and answer!