[lworld] RFR: 8377480: [lworld] incorrect execution due to EA pointer comparison optimization at scalarized call

Dan Heidinga heidinga at openjdk.org
Wed Feb 11 21:46:58 UTC 2026


On Wed, 11 Feb 2026 14:05:12 GMT, Roland Westrelin <roland at openjdk.org> wrote:

> EA goes over arguments to a non inlined call and uses
> `BCEscapeAnalyzer` to add edges to the `ConnectionGraph`. With
> valhalla, that code goes over inputs to a `CallNode` using the
> scalarized calling convention and queries `BCEscapeAnalyzer` with the
> index of the argument in the scalarized CC but `BCEscapeAnalyzer` has
> no knowledge of the scalarized CC. So `is_arg_returned()` for instance
> is passed the wrong argument number and EA, as a result, can add
> incorrect edges to the `ConnectionGraph`.
> 
> In the test case:
> 
> 
>     static value class MyValue {
>         Object o;
> 
>         MyValue(Object o) {
>             this.o = o;
>         }
>     }
> 
>     static int test1(Object o) {
>         MyValue v = new MyValue(null);
>         Object res = notInlined(v, o);
>         if (res == null) {
>             return 1;
>         }
>         return 2;
>     }
> 
>     static Object notInlined(MyValue arg1, Object arg2) {
>         return arg2;
>     }
> 
> 
> 2nd argument is returned by `notInlined()`. The second argument in the
> scalarized CC in `test1()` is `Myvalue.o`. So EA deduces that the
> return value of `notInlined()` is `v.o` (which is `null`) instead of
> `o` which is non null.
> 
> With this EA:
> 
>     public static void test2() {
>         MyValue arg = new MyValue(null);
>         MyValue res = notInlined2(arg);
>         if (res.o != null) {
>             throw new RuntimeException("never taken");
>         }
>     }
>     
>     static MyValue notInlined2(MyValue v) {
>         return v;
>     }
> 
> 
> 
> the fixed logic connects the return of `notInlined2` with `v.o`.

src/hotspot/share/opto/escape.cpp line 2150:

> 2148:       }
> 2149:       _i_sig_cc++;
> 2150:     }

Is it worth tracking the previous BasicType from the signature rather than reaching back with the `_i_sig_cc-1`?  

Something like:
Suggestion:

   BasicType prev_bt = T_VOID;
    while (_i_sig_cc < _sig_cc->length()) {
      BasicType bt = _sig_cc->at(_i_sig_cc)._bt;
      if (bt == T_METADATA) {
        _depth++;
      } else if (bt == T_VOID && (prev_bt != T_LONG && prev_bt != T_DOUBLE)) {
        _depth--;
        if (_depth == 0) {
          _i_domain++;
        }
      } else {
        return;
      }
      prev_bt = bt;
      _i_sig_cc++;
    }

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

PR Review Comment: https://git.openjdk.org/valhalla/pull/2079#discussion_r2795665929


More information about the valhalla-dev mailing list