[PATCH] D82056: [SVE] Remove calls to VectorType::getNumElements from Transforms/Vectorize

Christopher Tetreault via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 25 14:47:13 PDT 2020


ctetreau added inline comments.


================
Comment at: llvm/lib/Transforms/Vectorize/VectorCombine.cpp:339
+  auto *DestTy = dyn_cast<FixedVectorType>(I.getType());
+  auto *SrcTy = cast<FixedVectorType>(V->getType());
   if (!DestTy || I.getOperand(0)->getType() != SrcTy)
----------------
spatel wrote:
> ctetreau wrote:
> > spatel wrote:
> > > ctetreau wrote:
> > > > ctetreau wrote:
> > > > > spatel wrote:
> > > > > > IIUC, we can't safely cast to FixedVectorType at this point (the dyn_cast may have failed).
> > > > > > 
> > > > > > Should we add a test like this:
> > > > > > 
> > > > > > ```
> > > > > > define <vscale x 4 x float> @scalable_bitcast_same_elt_size(<vscale x 4 x i32> %v) {
> > > > > >   %shuf = shufflevector <vscale x 4 x i32> %v, <vscale x 4 x i32> undef, <vscale x 4 x i32> zeroinitializer
> > > > > >   %r = bitcast <vscale x 4 x i32> %shuf to <vscale x 4 x float>
> > > > > >   ret <vscale x 4 x float> %r
> > > > > > }
> > > > > > 
> > > > > > ```
> > > > > > 
> > > > > > I would add that in a preliminary commit myself, but it already crashes somewhere in the TTI cost model.
> > > > > I can take a look at adding this test case and seeing if I can get to this line with a scalable vector.
> > > > Looking at this more closely, it occurs to me that the TTI stuff is completely unimplemented for scalable vectors currently, so I'm not going to be able to add this test case. That said, for now, the scope of the cast to FixedVectorType can be reduced to just the two calls to getNumElements(). In principle, it should be possible to implement this function in terms of ElementCount. I'll add a fixme for this.
> > > > 
> > > > I think this should be safe, assuming it passes all the tests.
> > > I think there's still a potential bug in doing the plain `cast<>` even if we can't show it in a test at this time.
> > > Ie, we should do:
> > >   auto *SrcTy = dyn_cast<FixedVectorType>(V->getType());
> > >   if (!DestTy || !SrcTy || ...)
> > What is the bug? V must be nonnull because the matcher succeeded, and it must be a value with type VectorType, because it is the first argument to a shufflevector. What am I missing?
> The diff has changed, so the above code is fine now. But the diff below is nakedly casting to `FixedVectorType`. How did we ensure that our generic `VectorType` values actually are `FixedVectorType`? Ie, if we re-arrange this code for some reason to move the TTI checks after the diff below, then my test example will crash on this line:
>   unsigned DestNumElts = cast<FixedVectorType>(DestTy)->getNumElements();
Oh yeah, sorry about that. I posted the comments before I pushed the diff.

To answer your question, nothing prevents foldBitcastShuf from being called with a scalable vector. It just happens to not happen yet. Prior to this change, the code just does the wrong thing for scalable vectors. It might just happen to work, given how shuffle masks for scalable vectors work, but if masks other than all 0, or all -1 are ever added, this will break down.

For all these patches to remove calls to getNumElements(), the strategy has been to assume that existing calls to getNumElements() that don't check if the vector is scalable are explicitly expecting the vector to have fixed width. All these calls are being changed to unconditionally cast to FixedVectorType. If the existing tests don't break, then it must be the case that the assumption was correct.

I acknowledge that on some level, substituting a miscompile with a crash is actually a behavior change. However, my goal has been to prevent different control flow paths from being taken after the point of the bug. At the point of a call to getNumElements(), either the compiler will crash if it gets a scalable vector, or it will behave the same as it did before. For this case, TTI.getShuffleCost will already crash if it DestTy or SrcTy are scalable vectors, so this really is an NFC.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D82056/new/

https://reviews.llvm.org/D82056



More information about the llvm-commits mailing list