<!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>