RFR: 8346664: C2: Optimize mask check with constant offset [v22]

Quan Anh Mai qamai at openjdk.org
Wed Feb 12 06:36:21 UTC 2025


On Wed, 12 Feb 2025 06:31:08 GMT, Quan Anh Mai <qamai at openjdk.org> wrote:

>> Matthias Ernst has updated the pull request incrementally with one additional commit since the last revision:
>> 
>>   Reword correctness (fixes).
>
> src/hotspot/share/opto/mulnode.cpp line 2113:
> 
>> 2111: //
>> 2112: //    expr % mod == 0                             (multiple of power of two)
>> 2113: // => (a + expr) % mod         == a % mod         (zero element in modular arithmetic)
> 
> The use of the `%` operator here is pretty misleading, what we want is the unsigned remainder (a.k.a the floor remainder or the mathematical congruent notation). You also need the modular of the int or long arithmetic to be divisible by `mod` for this to work. I suggest writing it in pure mathematical form like this. Better formatting is encouraged:
> 
>     This section is concerned with pure mathematics values, not programming arithmetic values. For unsigned integers x, y; let's denote x mod y be the unsigned remainder of x when divided by y. It satisfies:
>     - (x mod y) < y
>     - There exists integer q such that x == q * y + (x mod y)
>     According to the basic properties of division, this value is unique
>     We then have:
>     1. a mod 2**w == (a mod 2**W) mod 2**w
>       Proof: Call a mod 2**w = r1 and a mod 2**W = r2, we have:
>         a == q1 * 2**w + r1
>         a == q2 * 2**W + r2
>         -> q1 * 2**w + r1 == q2 * 2**W + r2
>         -> r2 == (q1 - q2 * 2**(W - w)) * 2**w + r1
>         -> r2 mod 2**w == r1
>         -> (a mod 2**W) mod 2**w == a mod 2**w (qed)
>     2. expr mod 2**w == 0 -> ((a + expr) mod 2**W) mod 2**w == a mod 2**w
>       Proof: Since expr mod 2**w == 0, we have expr == q1 * 2**w
>       Call a mod 2**w == r, we have a == q2 * 2**w + r
>       We have a + expr == q2 * 2**w + r + q1 * 2**w == (q2 + q1) * 2**w + r
>       Which means that (a + expr) mod 2**w == a mod 2**w
>       Furthermore, since (a + expr) mod 2**w == ((a + expr) mod 2**W) mod 2**w (according to 1)
>       We have ((a + expr) mod 2**W) mod 2**w == a mod 2**w (qed)
> 
>     Back to the programming arithmetic domain, ((a + expr) mod 2**W) is the sum of a and expr in the int/long domain, a mod 2**w == a & (2**w - 1). This leads to us having:
>     (a + expr) & (2**w - 1) == a & (2**w - 1)
>     Furthermore, mask & (2**w - 1) == mask
>     (a + expr) & (2**w - 1) & mask == a & (2**w - 1) & mask
>     -> (a + expr) & mask == a & mask (qed)

Jumping from the mathematical world to the programming arithmetic world is always tricky and we should always be cautious, in this case, the use of `a + expr` needs extra cautions because it is really `(a + expr) mod 2**W`

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/22856#discussion_r1952059259


More information about the hotspot-compiler-dev mailing list