This is an archive of the discontinued LLVM Phabricator instance.

[SVE] add derived vector get(Type *, ElementCount) and get(Type *, VectorType)
AbandonedPublic

Authored by ctetreau on Jun 23 2020, 4:32 PM.

Details

Summary

These new getters in the derived vector types provide consistency with
all the other derived get functions. Prior to this change, if a
developer were to write:

auto *VTy = FixedVectorType::get(SomeTy, SomeVTy->getElementCount())

Not only is the type of VTy VectorType, which is inconsistent with how
all the other getters work when called through a derived vector type
get() function, but it might even actually be an instance of
ScalableVectorType, which is almost certainly not what the caller
expects.

This patch adds get functions that ensure that all base VectorType are
hidden when called via a derived vector type. When these functions are
called, if the result would not have matched the requested type, nullptr
is returned. This enables patterns like:

if (auto *SVTy = ScalableVectorType::get(SomeTy, SomeVTy)) {
// stuff

... where if SomeVTy is a fixed width vector, the branch will not be
taken.

Diff Detail

Event Timeline

ctetreau created this revision.Jun 23 2020, 4:32 PM
ctetreau edited the summary of this revision. (Show Details)
ctetreau edited the summary of this revision. (Show Details)

Prior to this change, if a developer were to write:

auto *VTy = FixedVectorType::get(SomeTy, SomeVTy->getElementCount())

This is just a compile error on master. (You could write "using VectorType::get" in the class to force overloading, but definitions in derived classes hide definitions from the base class by default.)


Could you give an example where you plan to use this? I don't expect it's common for code to take an arbitrary vector type, and try to produce a specific vector type based on it.

Prior to this change, if a developer were to write:

auto *VTy = FixedVectorType::get(SomeTy, SomeVTy->getElementCount())

This is just a compile error on master. (You could write "using VectorType::get" in the class to force overloading, but definitions in derived classes hide definitions from the base class by default.)


Could you give an example where you plan to use this? I don't expect it's common for code to take an arbitrary vector type, and try to produce a specific vector type based on it.

This case came up in a code review comment on D82218. I had made a change like return FixedVectorType::get(Ty, cast<FixedVectorType>(VTy)->getNumElements()); and the reviewer asked why I was casting when I could just do return FixedVectorType::get(Ty, VTy->getElementCount());. My assumption was that it would just resolve to VectorType::get(Ty, VTy->getElementCount()). My concern was that one could call FixedVectorType::get and get an instance of ScalableVectorType. While this is what would have happened if get were a free function, clearly this is not what happens with it being a static function.

There does still exist a valid use case for these new functions. It can simplify code like:

FixedVectorType *NewFVTy = nullptr;
if (auto *FVTy = dyn_cast<FixedVectorType>(VTy)) {
   NewFVTy = FixedVectorType::get(SomeTy, FVTy);
}

... into something like:

FixedVectorType *NewFVTy = FixedVectorType::get(SomeTy, VTy)

My main concern was the perceived type mismatch due to overload resolution. However, since that can't happen, I'm not 100% sure these new functions carry their own weight.

ctetreau abandoned this revision.Jul 9 2020, 12:50 PM