This is an archive of the discontinued LLVM Phabricator instance.

[LV] Process pointer IVs with PHINodes in collectLoopUniforms
ClosedPublic

Authored by mssimpso on Sep 13 2016, 8:40 AM.

Details

Summary

This patch moves the processing of pointer induction variables in collectLoopUniforms from the consecutive pointer phase of the analysis to the phi node phase. Previously, if a pointer induction variable was used by both a scalarized non-memory instruction as well as a vectorized memory instruction, we would incorrectly identify the pointer as uniform. Pointer induction variables should be treated the same as other phi nodes. That is, they are uniform if all users of the induction variable and induction variable update are uniform.

Diff Detail

Repository
rL LLVM

Event Timeline

mssimpso updated this revision to Diff 71178.Sep 13 2016, 8:40 AM
mssimpso retitled this revision from to [LV] Process pointer IVs with PHINodes in collectLoopUniforms.
mssimpso updated this object.
mssimpso added a reviewer: mkuper.
mssimpso added subscribers: llvm-commits, mcrosier.
mkuper added inline comments.Sep 13 2016, 9:43 AM
lib/Transforms/Vectorize/LoopVectorize.cpp
5397 ↗(On Diff #71178)

Do we care about bitcasts / GEP chains? (I'm ok with being conservative with this, just making sure it's by choice.)

5398 ↗(On Diff #71178)

Do we need to check that if U is a store, then Ptr is actually the pointer operand of the store, not the value?

I'm thinking about:
store i32* %p, i32** %q,
Where both %p and %q are consecutive.

5466 ↗(On Diff #71178)

The only thing that changed here, functionally, is the addition of isVectorizedMemAccessUse right?
The rest is cleanup?

Thanks for the quick feedback, Michael!

lib/Transforms/Vectorize/LoopVectorize.cpp
5397 ↗(On Diff #71178)

This is intentionally conservative, and we can probably relax it eventually. This patch was NFC when I tested it on SPEC, by the way.

But note that Ptr should be the actual pointer operand of a memory access (see comment below). This covers the case where we have a GEP that is bitcast, and the bitcast is then used by the memory access. We look through bitcasts in isConsecutivePointer, which calls getGEPInstruction.

For chains of instructions, we have to prove the user uniform first. This already happens to some degree in the expansion phase of the analysis. If GEP1 is only used by GEP2, and GEP2 remains uniform, GEP1 will be marked uniform as well. The same is true for the GEP in the bitcast case above.

5398 ↗(On Diff #71178)

Yes, nice catch! I'll update the patch. We want all users of the pointer to be memory accesses, where the pointer is the pointer operand. This is all we consider when checking for scalarization.

We already know Ptr is the pointer operand of one memory access, but it could be used as the value operand of another. Something like:

%x = load i32* %p
store i32* %p, i32** %q

%p can't remain uniform because we need to store all it's corresponding values to memory. %q remains uniform if the other conditions are met (the store is not scalarized, etc.).

5466 ↗(On Diff #71178)

That's right. I'm happy to save the cleanup for a separate patch if you prefer.

mkuper added inline comments.Sep 13 2016, 10:43 AM
lib/Transforms/Vectorize/LoopVectorize.cpp
5398 ↗(On Diff #71178)

Yes, this is exactly what I meant.

5466 ↗(On Diff #71178)

My personal preference is to do it the other way around - NFC cleanups go in first, and then you can put up the functional patch (post-cleanup) for review. This kills two birds with one stone:

  1. We don't have to revert cleanups if the functional patch turns out to be broken.
  2. Reviewing the functional patch is easier. :-)

(If you think the cleanup itself is complex enough to deserve review, then I'd prefer two separate reviews, but, again, cleanup first.)

mssimpso added inline comments.Sep 13 2016, 10:48 AM
lib/Transforms/Vectorize/LoopVectorize.cpp
5398 ↗(On Diff #71178)

Great, I'll add another test case for this.

5466 ↗(On Diff #71178)

Sounds good. I'll go ahead with the cleanup before updating the patch here.

mssimpso updated this revision to Diff 71214.Sep 13 2016, 12:14 PM

Addressed Michael's comments.

  • Updated UsersAreMemAccesses to check that uses are pointer operands.
  • Added a new test case for the discussed code fragment.
  • Rebased on top of the NFC clean up.
mkuper accepted this revision.Sep 13 2016, 2:26 PM
mkuper edited edge metadata.

LGTM

This revision is now accepted and ready to land.Sep 13 2016, 2:26 PM
This revision was automatically updated to reflect the committed changes.