RFR: 8335444: Generalize implementation of AndNode mul_ring

Jasmine Karthikeyan jkarthikeyan at openjdk.org
Wed Jul 31 15:59:37 UTC 2024


On Wed, 31 Jul 2024 12:05:15 GMT, Damon Fenacci <dfenacci at openjdk.org> wrote:

>> Hi all,
>> I've written this patch which improves type calculation for bitwise-and functions. Previously, the only cases that were considered were if one of the inputs to the node were a positive constant. I've generalized this behavior, as well as added a case to better estimate the result for arbitrary ranges. Since these are very common patterns to see, this can help propagate more precise types throughout the ideal graph for a large number of methods, making other optimizations and analyses stronger. I was interested in where this patch improves types, so I ran CTW for `java_base` and `java_base_2` and printed out the differences in this gist [here](https://gist.github.com/jaskarth/b45260d81ab621656f4a55cc51cf5292). While I don't think it's particularly complicated I've also added some discussion of the mathematics below, mostly because I thought it was interesting to work through :)
>> 
>> This patch passes tier1-3 testing on my linux x64 machine. Thoughts and reviews would be very appreciated!
>
> src/hotspot/share/opto/mulnode.cpp line 638:
> 
>> 636: 
>> 637:   // Since the result of bitwise-and can be as high as the largest value of each range, the result should find the maximum.
>> 638:   return IntegerType::make(std::numeric_limits<NativeType>::min() >> shift_bits, MAX2(r0->_hi, r1->_hi), widen);
> 
> I was just wondering if it would be OK to use `(r0->_lo & r1->_lo)` as the minimum value instead of finding the number of leading 1s and shifting. It seems to be a bit more constrained and compact (and seemingly correct). What do you think?

I actually did experiment with this before coming up with the current approach, but I found that there are cases where it produces incorrect bounds. With a small example where `r0 = [-3, -1]` and `r1 = [-7, -1]`, using `r0->_lo & r1->_lo` results in `-3 & -7`, which equals `-7`. However, in the case where the value in `r0` is `-3` and `r1` is `-6`, we can get an out of bounds result as `-3 & -6` equals `-8`. Because of that I thought the best way to fix this was to find the common leading 1s. This approach does lead to us losing some information in the lower-order bits but I thought it was an acceptable compromise since the code to handle finding common bits across a range of integers becomes quite a bit more complicated. I hope this clarifies!

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

PR Review Comment: https://git.openjdk.org/jdk/pull/20066#discussion_r1698750137


More information about the hotspot-compiler-dev mailing list