On Tue, 29 Mar 2022 21:56:18 GMT, Vamsi Parasa <d...@openjdk.java.net> wrote:
>> This is both complicated and inefficient, I would suggest building the >> intrinsic in the IR graph so that the compiler can simplify >> `Integer.compareUnsigned(x, y) < 0` into `x u< y`. Thanks. > >> This is both complicated and inefficient, I would suggest building the >> intrinsic in the IR graph so that the compiler can simplify >> `Integer.compareUnsigned(x, y) < 0` into `x u< y`. Thanks. > > Thank you for the suggestion! This intrinsic uses 1 cmp instruction instead > of two and shows ~10% improvement due to better branch prediction. Even > without the intrinsic, the compiler is currently able to reduce it to x u< y > but is still generating two cmp (unsigned) instructions as > Integer.compareUnsigned(x, y) is implemented as x u< y? -1 : (x ==y ? 0 : 1). @vamsi-parasa But normally the result of the `compare` methods is not used as a raw integer (it is useless to do so since the methods do not have any promise regarding the value of the result, only its sign). The idiom is to compare the result with 0, such as `Integer.compare(x, y) > 0`, the compiler can reduce this to `x > y` (last time I checked it does not do so but in principle this is possible). Your intrinsic prevents the compiler to do such transformations, hurting the performance of real programs. > Even without the intrinsic, the compiler is currently able to reduce it to x > u< y It is because the compiler can recognise the pattern `x + MIN_VALUE < y + MIN_VALUE` and transforms it into `x u< y`. This transformation is fragile however if one of the arguments is in the form `x + con`, in such cases constant propagation may lead to slight deviations from recognised patterns, defeat the transformations. As a result, it may be justifiable to have a dedicated intrinsic for that since unsigned comparisons are pretty basic operations that are needed for optimal range check performance. Thanks. ------------- PR: https://git.openjdk.java.net/jdk/pull/7975