Abe wrote:
<personal introduction/>
Hi, pleased to meet you :)
<topic introduction>
As some of you already know, at SARC we are working on a new "if converter" to
help convert
simple "if"-based blocks of code that appear inside loops into an
autovectorizer-friendly form
that closely resembles the C ternary operator ["c ? x : y"]. GCC already has
such a converter,
but it is off by default, in part because it is unsafe: if enabled, it can
cause certain code
to be transformed in such a way that it malfunctions even though the
non-converted code worked
just fine with the same inputs. The new converter, originally by my teammate
Sebastian Pop,
is safer [almost-always safe *]; we are working on getting it into good-enough
shape that the
always-safe transformations can be turned on by default whenever the
autovectorizer is on.
* Always safe for stores, sometimes a little risky for loads:
speculative loads might cause multithreaded programs with
insufficient locking to fail due to writes by another thread
being "lost"/"missed", even though the same program works OK
"by luck" when compiled without if-conversion of loads.
This risk comes mainly/only from what the relevant literature
calls a "half hammock": an "if" with a "then" section but no
"else" section [or effectively vice-versa, e.g. an empty "then"
and a non-empty "else"]. In this case, e.g. "if (c) X[x] = Y[y];"
with no attached "else" section is risky to fully if-convert
in the event of the code being compiled running multithreaded
and not having been written with all the locking it really needs.
Respectively, e.g. "if (c) ; /* empty ''then'' */ else X[x] = Y[y];".
For the unenlightened, can you outline the problem with this code sequence?
(i.e. the expected transformation that makes it unsafe!?) I would hope your
scratchpad patch would turn this into something like
a1 = c ? &Y[y] : &scratch;
temp = *a1;
a2 = c ? &X[x] : &scratch;
*a2 = temp;
which seems OK to me - so is the scratchpad approach going away?
(The problem that things might be read in a different order *across* the
elements of a vector, I can see, but that belongs in the domain of the
vectorizer itself, not if-conversion, I would think?)
One of the reasons the new if converter has not yet been submitted
for incorporation into GCC`s trunk is that it still has some
performance regressions WRT the old converter, and most of those
are "true regressions", i.e. not just because the old converter
was less safe and the additional safety is what is causing the loss,
but rather because there is more work to do before the patch is ready.
As of this writing, the new if converter sometimes tries
to "convert" something that is already vectorizer-friendly,
and in doing so it renders that code now-NOT-vectorizer-friendly.
Can you give an example? My understanding was that the existing vectorizer
bailed out pretty much straightaway if the number of basic blocks in the loop
was not exactly 2 (for inner loops) or 5 (for outermost loops, i.e. containing
exactly one inner loop)...that seems to rule out vectorization of *any* kind of
conditional execution, that the if-converter might convert?
Thanks, Alan