JDK-8298282 : Fail to elide bound checks in loop with the same entry condition
  • Type: Enhancement
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 20
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • Submitted: 2022-12-07
  • Updated: 2022-12-08
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
tbdUnresolved
Description
Consider this program:

public class Sample {
    static final String[] ARRAY = new String[1000];
    static final ArrayList<String> LIST = new ArrayList<>(Arrays.asList(ARRAY));

    @CompilerControl(CompilerControl.Mode.DONT_INLINE)
    public static void test(Object o) {}

    @Benchmark
    public void run(Blackhole bh) {
        for (int i = 0; Integer.compareUnsigned(i, LIST.size()) < 0; i++) {
            test(LIST.get(i));
        }
    }
}

The loop is compiled to:

  0x00007fbe5c6b6280:   mov    %ebp,%r8d
  0x00007fbe5c6b6283:   test   %r10d,%r10d
  0x00007fbe5c6b6286:   jl     0x00007fbe5c6b6328
  0x00007fbe5c6b628c:   cmp    %r10d,%r8d
  0x00007fbe5c6b628f:   jae    0x00007fbe5c6b62fa
  0x00007fbe5c6b6295:   movabs $0x751589d30,%r10            ;   {oop(a 'java/util/ArrayList'{0x0000000751589d30})}
  0x00007fbe5c6b629f:   mov    0x14(%r10),%r11d
  0x00007fbe5c6b62a3:   mov    %r8d,%ebp
  0x00007fbe5c6b62a6:   mov    0xc(%r12,%r11,8),%r10d       ; implicit exception: dispatches to 0x00007fbe5c6b634d
  0x00007fbe5c6b62ab:   cmp    %r10d,%ebp
  0x00007fbe5c6b62ae:   jae    0x00007fbe5c6b6314
  0x00007fbe5c6b62b0:   lea    (%r12,%r11,8),%r10
  0x00007fbe5c6b62b4:   mov    0x10(%r10,%rbp,4),%r11d
  0x00007fbe5c6b62b9:   mov    %r11,%rsi
  0x00007fbe5c6b62bc:   shl    $0x3,%rsi
  0x00007fbe5c6b62c0:   data16 xchg %ax,%ax
  0x00007fbe5c6b62c3:   call   0x00007fbe5c6b9700           ; ImmutableOopMap {}
                                                            ;*invokestatic test {reexecute=0 rethrow=0 return_oop=0}
                                                            ; - org.openjdk.bench.vm.compiler.Sample::run@22 (line 51)
                                                            ;   {static_call}
  0x00007fbe5c6b62c8:   mov    0x380(%r15),%r11
  0x00007fbe5c6b62cf:   movabs $0x751589d30,%r10            ;   {oop(a 'java/util/ArrayList'{0x0000000751589d30})}
  0x00007fbe5c6b62d9:   mov    0x10(%r10),%r10d
  0x00007fbe5c6b62dd:   inc    %ebp                         ; ImmutableOopMap {}
                                                            ;*goto {reexecute=1 rethrow=0 return_oop=0}
                                                            ; - (reexecute) org.openjdk.bench.vm.compiler.Sample::run@28 (line 50)
  0x00007fbe5c6b62df:   test   %eax,(%r11)                  ;   {poll}
  0x00007fbe5c6b62e2:   cmp    %r10d,%ebp
  0x00007fbe5c6b62e5:   jb     0x00007fbe5c6b6280

Obviously, the bound check at 0x00007fbe5c6b628c is the same as the loop condition, it should be elided.