RFR: 8325674: Constant fold across compares

Joshua Cao duke at openjdk.org
Wed Feb 14 19:40:14 UTC 2024


For example, `x + 1 < 2` -> `x < 2 - 1` iff we can prove that `x + 1` does not overflow and `2 - 1` does not overflow. We can always fold if it is an `==` or `!=` since overflow will not affect the result of the comparison.

Consider this more practical example:


public void foo(int[] arr) {
  for (i = arr.length - 1; i >= 0; --i) {
    blackhole(arr[i]);
  }
}


C2 emits a loop guard that looks `arr.length - 1 < 0`. We know `arr.length - 1` does not overflow because `arr.length` is positive. We can fold the comparison into `arr.length < 1`. We have to compute `arr.length - 1` computation if we enter the loop anyway, but we can avoid the subtraction computation if we never enter the loop. I believe the simplification can also help with stronger integer range analysis in https://bugs.openjdk.org/browse/JDK-8275202.

Some additional notes:
* there is various overflow checking code across `src/hotspot/share/opto`. I separated about the functions from convertnode.cpp into `type.hpp`. Maybe the functions belong somewhere else?
* there is a change in Parse::do_if() to repeatedly apply GVN until the test is canonical. We need multiple iterations in the case of `C1 > C2 - X` -> `C2 - X < C1` -> `C2 < X` -> `X > C2`.  This fails the assertion if `BoolTest(btest).is_canonical()`. We can avoid this by applying GVN one more time to get `C2 < X`.
* we should not transform loop backedge conditions. For example, if we have `for (i = 0; i < 10; ++i) {}`, the backedge condition is `i + 1 < 10`. If we transform it into `i < 9`, it messes with CountedLoop's recognition of induction variables and strides.r
* this change optimizes some of the equality checks in `TestUnsignedComparison.java` and breaks the IR checks. I removed those tests.

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

Commit messages:
 - 8325674: Constant fold across compares

Changes: https://git.openjdk.org/jdk/pull/17853/files
 Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=17853&range=00
  Issue: https://bugs.openjdk.org/browse/JDK-8325674
  Stats: 483 lines in 7 files changed: 420 ins; 59 del; 4 mod
  Patch: https://git.openjdk.org/jdk/pull/17853.diff
  Fetch: git fetch https://git.openjdk.org/jdk.git pull/17853/head:pull/17853

PR: https://git.openjdk.org/jdk/pull/17853


More information about the hotspot-compiler-dev mailing list