<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <p>Thanks for the explanation.</p>
    <p>Thinkng a bit more, as Roland pointed out, I believe there are
      two issues here:</p>
    <p>1. disjointness analysis doesn't work for all heap, which is a
      known issue<br>
      2. even in cases where disjointness analysis works, we can't
      autovectorize because we read "longs" which are then turned into
      "double".</p>
    <p>These seem two orthogonal issues. While I think it would be
      worthwhile to fix (1) -  I have seen other cases where suboptimal
      code was generated because of that, I don't think we're fully out
      of the woods with that.</p>
    <p>The fix I came up with yesterday seems a reasonable stop-gap
      solution for (2): if the memory var handle is fully aligned, and
      its endianness is == platform endianness, then don't bother with
      the long -> double trip and just use Unsafe::getDouble. That
      said, this fix will only work under these conditions (aligned
      _plain_ access with right endianness). Anything else will fall
      back to the old pattern. This tweak shouldn't cost anything, as
      these conditions are invariants for a given var handle instance
      (whose final fields are trusted, as defined in
      "java.lang.invoke"), which is typically held in a static final
      field, so everything should be known to the JIT. If we want to
      address that at the vectorizer level, it will probably require
      deeper changes which treat the Unsafe.getLong +
      Long.longBitsToDouble as a single operation.</p>
    <p>Thoughts?</p>
    <p>Maurizio<br>
    </p>
    <div class="moz-cite-prefix">On 20/03/2024 19:59, John Rose wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:333FF521-3863-41BC-BCF0-3048BB766677@oracle.com">
      
      <div dir="ltr">This fits into a loop optimization technique that
        Roland worked on, called loop predication. You speculate that
        the loop invariant inputs are somehow favorable and test. If all
        is well you run the loop transformed to exploit the speculated
        favorable condition. In this case it is disjointness of reads
        and writes. If the speculation fails you might recompile, or use
        a defined fallback loop. </div>
      <div dir="ltr"><br>
      </div>
      <div dir="ltr">If the loop is worth vectorizing the cost of
        checking disjointness is comparatively small, commensurate with
        other predicates we now use.</div>
      <div dir="ltr"><br>
      </div>
      <div dir="ltr">Certainly a disjointness test is cheaper than the
        very subtle range analysis we do routinely for range check
        elimination, of any loop containing array accesses linear in the
        loop trip count. </div>
      <div dir="ltr"><br>
      </div>
      <div dir="ltr">So, it’s merely one of those “small matters of
        programming”.</div>
      <div dir="ltr"><br>
        <blockquote type="cite">On Mar 20, 2024, at 11:51 AM, Maurizio
          Cimadamore <a class="moz-txt-link-rfc2396E" href="mailto:maurizio.cimadamore@oracle.com"><maurizio.cimadamore@oracle.com></a> wrote:<br>
          <br>
        </blockquote>
      </div>
      <blockquote type="cite">
        <div dir="ltr">
          <p>Thanks for the analysis Roland. If I understand correctly,
            even if this analysis is not supported today, in principle
            it could be done, right?</p>
          <p>After all, we know ia/oa (e.g. their addresses) and the
            ranges we're going to access these at (otherwise we could
            not hoist bound checks outside the loop).</p>
          <p>So, we might be able, in principle, to check that - perhaps
            the issue is that (as in this case) all the addresses are
            completely dynamic, so you really need a disjointness
            runtime check (outside the loop), which might be more
            expensive than the incremental benefit added by
            vectorization?</p>
          <p>Maurizio<br>
          </p>
          <p><br>
          </p>
          <div class="moz-cite-prefix">On 20/03/2024 16:26, Roland
            Westrelin wrote:<br>
          </div>
          <blockquote type="cite" cite="mid:8734sklvhu.fsf@redhat.com">
            <pre>is that the compiler can't prove it's legal to vectorize. Doubles are
read from ia and oa and then added and written back to oa. There's no
way for the compiler to tell that the off heap areas pointed to by ia
and oa don't overlap. So possibly, the value written to:

oa + 8*i

is going to be read back at the next iteration with:

ia + 8*i

(ia could be oa+8)

The autovectorizer would need to insert a runtime check that the 2 areas
don't overlap but there's no support for that at this point. I suppose
the same issue exists with the MemorySegment API when memory is off
heap.
</pre>
          </blockquote>
        </div>
      </blockquote>
    </blockquote>
  </body>
</html>