This is an archive of the discontinued LLVM Phabricator instance.

[LoopVectorize] Annotate versioned loop with noalias metadata
ClosedPublic

Authored by anemet on Feb 12 2016, 12:35 AM.

Details

Summary

Use the new LoopVersioning facility (D16712) to add noalias metadata in
the vector loop if we versioned with memchecks. This can enable some
optimization opportunities further down the pipeline (see the included
test or the benchmark improvement quoted in D16712).

The test also covers the bug I had in the initial version in D16712.

The vectorizer did not previously use LoopVersioning. The reason is
that the vectorizer performs its transformations in single shot. It
creates an empty single-block vector loop that it then populates with
the widened, if-converted instructions. Thus creating an intermediate
versioned scalar loop seems wasteful.

So this patch (rather than bringing in LoopVersioning fully) adds a
special interface to LoopVersioning to allow the vectorizer to add
no-alias annotation while still performing its own versioning.

As the vectorizer propagates metadata from the instructions in the
original loop to the vector instructions we also check the pointer in
the original instruction and see if LoopVersioning can add no-alias
metadata based on the issued memchecks.

Diff Detail

Event Timeline

anemet updated this revision to Diff 47775.Feb 12 2016, 12:35 AM
anemet retitled this revision from to [LoopVectorize] Annotate versioned loop with noalias metadata.
anemet updated this object.
anemet added reviewers: hfinkel, nadav.
anemet added a subscriber: llvm-commits.
anemet updated this revision to Diff 47778.Feb 12 2016, 1:02 AM

I forgot to clang-format

Hi Adam,

Please find some comments inline.

Thanks,
Michael

include/llvm/Transforms/Utils/LoopVersioning.h
92–96

Formatting looks weird here.

lib/Transforms/Vectorize/LoopVectorize.cpp
449–455

These functions are generally useful, not only in LoopVectorizer - e.g. we have their duplicates in SLPVectorizer. While you're at it, could you please move them out to a common place (and commit as a separate change)?

659–663

Does it belong here? I.e. should it really be a part of propagateMetadata? Probably that's fine with the current usage of propagateMetadata but it might become surprising if one decides to use this function somewhere else.

anemet marked an inline comment as done.Feb 15 2016, 6:00 PM
anemet added inline comments.
lib/Transforms/Vectorize/LoopVectorize.cpp
449–455

They are not really duplicates. The one in LV copies from instruction to one/many. The one in SLP copies many to one and merges them in the process in a metadata-specific way.

You can obviously still refactor the common parts or create a superset but I think that will probably be harder to read at the end.

What do you think?

659–663

Well, that depends on what you respond to the above but semantically, I do think it belongs here.

Here we're propagating the metadata from the "versioned" scalar loop (which is never created) to the vector loop. Let me know if this is not clear and I should add a comment.

mzolotukhin added inline comments.Feb 16 2016, 11:58 AM
lib/Transforms/Vectorize/LoopVectorize.cpp
449–455

That's true, but to me it looks like SLP version is just more general, where we need to merge several, potentially different sets of attributes. In LV case we can also think of such merging, but all the sets are the same, so the merge is trivial.

The reason I think it might be useful is that it's currently easy to forget to update both versions. E.g. when I added propagation of 'nontemporal' hints, I had to fix that in two very similar places.

659–663

Yeah, if you feel convinced that there is no reason in factoring propagateMetadata out, then it's fine to keep this code here I guess.

test/Transforms/LoopVectorize/noalias-md.ll
1–2

Don't you need -scoped-alias in the first command as well?

anemet added inline comments.Feb 16 2016, 12:35 PM
lib/Transforms/Vectorize/LoopVectorize.cpp
449–455

I would actually have a slight preference that for a new metadata each pass is carefully considered separately. Look at the if-conversion comment in the LV version as an example.

But I don't feel very strongly about this, so if you want you can factor them out.

test/Transforms/LoopVectorize/noalias-md.ll
1–2

No, -scoped-noalias is necessary to be able to query scoped noalias info. The first case only generates the metadata.

mzolotukhin accepted this revision.Feb 16 2016, 1:02 PM
mzolotukhin added a reviewer: mzolotukhin.
mzolotukhin added inline comments.
lib/Transforms/Vectorize/LoopVectorize.cpp
449–455

That sounds good to me.

This revision is now accepted and ready to land.Feb 16 2016, 1:02 PM

Thanks, Michael!

anemet updated this revision to Diff 48253.Feb 17 2016, 3:53 PM
anemet edited edge metadata.

Further performance analysis revealed that we were missing (valid)
optimizations cases compared to the original version in D16712.

Uniform loads are "scalarized" i.e. they are not vectorized by the original
instruction but cloned into the vector loop and then the splat value is
constructed (see the noalias-md-licm.ll test). Because of this
propagateMetadata was not invoked on them so we missed annotating these.

This new version splits annotation between cloned and newly created
instructions. As a side effect, the original propagateMetadata function is
unchanged which should help if we wanted to share this the SLP vectorizer.

Michael, still LGTY?

Yes, the change still looks fine.

This revision was automatically updated to reflect the committed changes.