This is an archive of the discontinued LLVM Phabricator instance.

[SROA] Check typeSizeEqualsStoreSize in isVectorPromotionViable
ClosedPublic

Authored by bjope on Sep 16 2022, 6:02 AM.

Details

Summary

Commit de3445e0ef15c4209 (https://reviews.llvm.org/D132096) made
changes to isVectorPromotionViable basically doing

// Create Vector with size of V, and each element of type Ty
...
uint64_t ElementSize = DL.getTypeStoreSizeInBits(Ty).getFixedSize();
uint64_t VectorSize = DL.getTypeSizeInBits(V).getFixedSize();
...
VectorType *VTy = VectorType::get(Ty, VectorSize / ElementSize, false);

Not quite sure why it uses the TypeStoreSize for the ElementSize,
but the new vector would only match in size with the old vector in
situations when the TypeStoreSize equals the TypeSize for Ty.
Therefore this patch adds a typeSizeEqualsStoreSize check as yet
another condition for allowing the the new type as a promotion
candidate.

Without this fix the new @test15 test would fail with an assert
like this:

opt: ../lib/Transforms/Scalar/SROA.cpp:1966:

auto isVectorPromotionViable(llvm::sroa::Partition &,
                             const llvm::DataLayout &)
     ::(anonymous class)::operator()(llvm::VectorType *,
                                     llvm::VectorType *) const:
Assertion `DL.getTypeSizeInBits(RHSTy).getFixedSize() ==
           DL.getTypeSizeInBits(LHSTy).getFixedSize() &&
           "Cannot have vector types of different sizes!"' failed.

...
#8 isVectorPromotionViable(...)::$_10::operator()...
#9 llvm::SROAPass::rewritePartition(...)
#10 llvm::SROAPass::splitAlloca(...)
#11 llvm::SROAPass::runOnAlloca(...)
#12 llvm::SROAPass::runImpl(...)
#13 llvm::SROAPass::run(...)

Diff Detail

Event Timeline

bjope created this revision.Sep 16 2022, 6:02 AM
Herald added a project: Restricted Project. · View Herald TranscriptSep 16 2022, 6:02 AM
bjope requested review of this revision.Sep 16 2022, 6:02 AM
Herald added a project: Restricted Project. · View Herald TranscriptSep 16 2022, 6:02 AM
bjope updated this revision to Diff 460750.Sep 16 2022, 7:24 AM

Adding missing CHECKS to the new test case.

Thanks for catching this. I would like someone with more experience in SROA than me to take a look, in case there's something I've missed, though.

bjope added inline comments.Sep 19 2022, 8:19 AM
llvm/lib/Transforms/Scalar/SROA.cpp
1936

I should probably add some explanatory code comment here (given that this solution is accepted).

Background to why I used the typeSizeEqualsStoreSize check:

The idea is to make a similar check to what is done at line 1859 ("While the definition of LLVM vectors is bitpacked, we don't support sizes that aren't byte sized."), although that isn't exactly what testing for typeSizeEqualsStoreSize is doing.

Not sure if it would be better to check for "byte sized". It might work as well (but it would complicate stuff for our out-of-target with 16 bit bytes if hard-coding another "8" here).

Anyhow, for the "VectorSize / ElementSize" calculation below to result in a vector with the same size as the original vector I think typeSizeEqualsStoreSize needs to be fulfilled (or we could change the ElementSize calculation to just use getTypeSizeInBits instead of getTypeStoreSizeInBits, but then I suspect that the transform might be unsafe in case typeSizeEqualsStoreSize isn't fulfilled). So checking for typeSizeEqualsStoreSize seemed like a defensive approach here to avoid the corner cases without sacrificing the normal cases that we want to handle (and that is regression tested).

MatzeB accepted this revision.Sep 20 2022, 1:12 PM

Seems sensible. Thanks for catching and fixing. LGTM

This revision is now accepted and ready to land.Sep 20 2022, 1:12 PM