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