Any function in this module that make use of DemandedElts laregely does
not work with scalable vectors. DemandedElts is used to define which
elements of the vector to look at. At best, for scalable vectors, we can
express the first N elements of the vector. However, in practice, most
code that uses these functions expect to be able to talk about the
entire vector. In principle, this module should be able to be extended
to work with scalable vectors. However, before we can do that, we should
ensure that it does not cause code with scalable vectors to miscompile.
All functions that use a DemandedElts will bail out if the vector is
scalable. Usages of getNumElements() are updated to go through
FixedVectorType pointers.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Unit Tests
Event Timeline
We probably should support computeKnownBits with scalable vectors; the functionality mostly just works. The one part that doesn't is the "DemandedElts", but really it's a minor part, and we can just ignore it for scalable vectors. (So essentially, drop the new assertion from computeKnownBits, and bail out in the few places in the implementation that actually care.)
llvm/lib/Analysis/ValueTracking.cpp | ||
---|---|---|
211 | I'm surprised this assertion doesn't break anything else; computeKnownBits has a lot of callers. |
llvm/lib/Analysis/ValueTracking.cpp | ||
---|---|---|
211 | Yes, I think that's the reason for this failure: |
Yeah, it looks like there are some parts of computeKnownBits that should work for scalable vectors. I'll update it to do the right thing.
It's not obvious what DemandedElts should actually mean for a scalable vector. How do you decide whether elements past the minimum length are actually demanded? I can think of the following possibilities:
- The elements beyond the minimum are always demanded
- The demanded elements is a repeating pattern
- We shouldn't use DemandedElts for scalable vectors at all.
It probably makes sense to just choose the last one until we actually have some real-world testscases that would benefit. Also saves some implementation work short-term.
Given that, it probably makes sense to only construct DemandedElts for FixedVectorTypes, and just use APInt(1, 1) for scalable vectors.
llvm/lib/Analysis/ValueTracking.cpp | ||
---|---|---|
1939 | No reason to check Scalable; a ConstantVector is never scalable anyway. |
So your proposal is that for scalable vectors, DemandedElts can have any value?
llvm/lib/Analysis/ValueTracking.cpp | ||
---|---|---|
1939 | ConstantVector::getSplat() can return a scalable ConstantVector |
llvm/lib/Analysis/ValueTracking.cpp | ||
---|---|---|
1939 | I guess it actually returns a ConstantExpr? |
So your proposal is that for scalable vectors, DemandedElts can have any value?
We'd ignore the value, yes.
Probably, for the sake of assertions etc., it would make sense to require it to be APInt(1, 1), as opposed to actually making it unconstrained. But that's not really important.
llvm/lib/Analysis/ValueTracking.cpp | ||
---|---|---|
1939 | Yes, The fact that getSplat is an API on ConstantVector is a historical accident, I think. |
After spending some time considering how to deal with some breakages caused by my previous version of this patch, I've decided to change my approach.
For the most part, any function that uses a DemandedElts does not actually do the right thing for scalable vectors. An obvious bandaid that can be applied to this to do *something* is to just ignore the DemandedElts for scalable vectors and do some default behavior (such as considering the entire vector). However, I think this is dangerous because code may break if this function returns results for vector elements that the caller does not expect to get results for. Regardless, I would like to see a real fix be implemented rather than time being spent on applying many layers of band aids.
LGTM
I still think enabling it for scalable vectors is worth pursuing, as a relatively small amount of work; see D79264. But we probably want the other changes here anyway, so this seems fine for now.
I agree. I'm just saying that step 1 is to remove the broken uses of getNumElements().
I recently created a patch that also hit issues with DemandedElts (https://reviews.llvm.org/D79083) in CodeGen. I pondered some of the same issues in this patch and I chose to ignore the DemandedElts values and make it work for certain cases such as SPLAT_VECTOR.
I'm surprised this assertion doesn't break anything else; computeKnownBits has a lot of callers.