This is an archive of the discontinued LLVM Phabricator instance.

[IR] Add LLVM IR support for target("aarch64.svcount") type.
ClosedPublic

Authored by sdesmalen on Oct 27 2022, 9:52 AM.

Details

Summary

The C and C++ Language Extensions for AArch64 SME2 [1] adds a new type called
svcount_t which describes a predicate. This is not a predicate vector
mask, but rather a description of a predicate vector mask that can be
expanded into a mask using explicit instructions. The type is a scalable
opaque type.

To implement svcount_t type this patch uses the existing Target Extension Type
mechanism, but adds further support so that this type can be a scalable type.

AArch64 CodeGen support will follow in a separate patch.

[1] https://github.com/ARM-software/acle/pull/217

Diff Detail

Event Timeline

sdesmalen created this revision.Oct 27 2022, 9:52 AM
sdesmalen requested review of this revision.Oct 27 2022, 9:52 AM
Herald added a project: Restricted Project. · View Herald TranscriptOct 27 2022, 9:52 AM

Any chance this can be implemented as an opaque type as introduced in https://reviews.llvm.org/D135202 instead? Providing a general mechanism for target-specific types is the purpose of opaque types, so it would be great if they work for this use case. cc @jcranmer-intel

Any chance this can be implemented as an opaque type as introduced in https://reviews.llvm.org/D135202 instead? Providing a general mechanism for target-specific types is the purpose of opaque types, so it would be great if they work for this use case. cc @jcranmer-intel

Can this be implemented in the existing way? Otherwise users of -DCLANG_ENABLE_OPAQUE_POINTERS=OFF/-Xclang -no-opaque-pointers won't be able to use SME intrinsics.

nikic added a comment.Oct 27 2022, 2:23 PM

Any chance this can be implemented as an opaque type as introduced in https://reviews.llvm.org/D135202 instead? Providing a general mechanism for target-specific types is the purpose of opaque types, so it would be great if they work for this use case. cc @jcranmer-intel

Can this be implemented in the existing way? Otherwise users of -DCLANG_ENABLE_OPAQUE_POINTERS=OFF/-Xclang -no-opaque-pointers won't be able to use SME intrinsics.

Despite both having "opaque" in the name, opaque pointers and opaque types aren't really related. Opaque types would work even with -no-opaque-pointers.

Any chance this can be implemented as an opaque type as introduced in https://reviews.llvm.org/D135202 instead? Providing a general mechanism for target-specific types is the purpose of opaque types, so it would be great if they work for this use case. cc @jcranmer-intel

Can this be implemented in the existing way? Otherwise users of -DCLANG_ENABLE_OPAQUE_POINTERS=OFF/-Xclang -no-opaque-pointers won't be able to use SME intrinsics.

Despite both having "opaque" in the name, opaque pointers and opaque types aren't really related. Opaque types would work even with -no-opaque-pointers.

Ah ok, that's fine then. Although from looking at D135202 it doesn't look like the design has been settled yet? I don't think we should be writing patches upon speculative changes, so unless D135202 is going to land very soon I'd prefer we continued with the traditional approach.

nikic added a comment.Oct 28 2022, 2:13 AM

Ah ok, that's fine then. Although from looking at D135202 it doesn't look like the design has been settled yet? I don't think we should be writing patches upon speculative changes, so unless D135202 is going to land very soon I'd prefer we continued with the traditional approach.

Yeah, possibly. I'd suggest to still consider the possibility when you put up the RFC for this change, as it's likely going to be an easier sell if it doesn't require the addition of a new target-specific type.

Ah ok, that's fine then. Although from looking at D135202 it doesn't look like the design has been settled yet? I don't think we should be writing patches upon speculative changes, so unless D135202 is going to land very soon I'd prefer we continued with the traditional approach.

At a quick glance of this patch, this does seem like something that could be built on top of opaque types were they already landed, so it's at least worth considering how this type might be implemented as an opaque type. The thing that's the most unsettled in the design is effectively the communication of DataLayout-like type properties of target types, and while I hoped to have a solution to that coded up today, I didn't get enough time to do so.

From the spec, svreinterpret_c(svreinterpret_b(x)) is equivalent to x, right? So you could just lower svcount_t to <vscale x 16 x i1>, but you want to avoid confusion with non-SME predicate vectors in LLVM IR?

sdesmalen updated this revision to Diff 496098.Feb 9 2023, 5:36 AM
sdesmalen retitled this revision from [IR] Add LLVM IR support for aarch64_svcount opaque type. to [IR] Add LLVM IR support for target("aarch64.svcount") type..
sdesmalen edited the summary of this revision. (Show Details)

Refactored the patch to use the existing target("<customtype>") mechanism.

Thanks for all the previous comments! I've rewritten the patch to use the new target-extension types, since that functionality has now landed. This made the patch a lot simpler. I've only had to add a new interface to check if the TargetExtType is scalable.

I will try to be a bit more responsive to comments this time around :)

From the spec, svreinterpret_c(svreinterpret_b(x)) is equivalent to x, right? So you could just lower svcount_t to <vscale x 16 x i1>, but you want to avoid confusion with non-SME predicate vectors in LLVM IR?

We could let Clang emit the reinterpret cast, but we want the intrinsics to be correct for other front-ends as well think of e.g. MLIR. By giving it a proper type it becomes unambiguous what the format of the predicate value must be when passing it to the intrinsic.

nikic added inline comments.Feb 14 2023, 2:13 AM
llvm/lib/Transforms/Scalar/SROA.cpp
895 ↗(On Diff #496098)

I think it would be more elegant to get the TypeSize return value here and check whether it is isScalable(). That would avoid the need to explicitly check for ScalableVectorType and scalable target extension types. (Feel free to pre-commit as an NFC change and reduce the diff here.)

TypeSize Size = DL.getTypeStoreSize(LI.getType());
if (Size.isScalable())
  return PI.setAborted(&LI);
return handleLoadOrStore(LI.getType(), LI, Offset, Size.getFixedValue(), LI.isVolatile());
sdesmalen added inline comments.Feb 14 2023, 6:57 AM
llvm/lib/Transforms/Scalar/SROA.cpp
895 ↗(On Diff #496098)

That makes sense, thanks for the suggestion. I can do the same (look at allocated type size, rather than the type itself) for all other cases in this file as well.

sdesmalen updated this revision to Diff 497588.Feb 15 2023, 1:06 AM

Split out SROA changes into rG462227f1150f as suggested, and rebased this patch.

I'd ideally like to see discussion of this target extension type somewhere in documentation, but alas, AArch64 is one of the backends that lacks a dedicated target documentation page.

llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
1703–1705 ↗(On Diff #497588)

A better fix here, I think, is to add a test for the block below so that it only applies to integer or integer vector types.

sdesmalen updated this revision to Diff 499202.Feb 21 2023, 9:06 AM
  • Added description of the svcount type to AArch64SME.rst
  • Use isIntOrIntVectorTy() in foldSelectInstWithICmp
  • Added Type::isScalableTy() convenience function.
sdesmalen marked an inline comment as done.Feb 22 2023, 2:35 AM

@jcranmer-intel thanks for your review, I think I've addressed both your comments now.

nikic added inline comments.Feb 22 2023, 7:57 AM
llvm/include/llvm/IR/Type.h
216 ↗(On Diff #499202)

It doesn't look like these new methods are actually used?

llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
1705 ↗(On Diff #499202)

This could be committed separately.

Thank you for adding documentation for target("aarch64.svcount"). Otherwise, the only other thing I would comment is the same thing that Nikita said with regards to the unused new methods.

sdesmalen added inline comments.Feb 23 2023, 7:36 AM
llvm/include/llvm/IR/Type.h
216 ↗(On Diff #499202)

They are used in the patches that follow it (D143642 and D136862). I thought it made sense to add them to this patch, given that this patch adds the concept of scalable target extension types (with svcount being an instantiation of that). I'm happy to move the interfaces to the other patches if that has the preference.

nikic added inline comments.Feb 23 2023, 7:55 AM
llvm/include/llvm/IR/Type.h
216 ↗(On Diff #499202)

I think it would be better to introduce them later, mainly because I'm not sure we really need them. I think checking isa<ScalabelVectorType> is an anti-pattern in most (but maybe not all) cases.

E.g. for the SCEV change I put up D144624 as an alternative which works on TypeSize only. I think something like this can usually be done (places that have to guard against scalable vectors are generally places that query TypeSize...)

sdesmalen updated this revision to Diff 499876.Feb 23 2023, 8:33 AM
  • Removed unused interfaces.
  • Rebased after moving out change in foldSelectInstWithICmp.
nikic accepted this revision.Feb 23 2023, 9:42 AM

LGTM from IR perspective. I assume this already has internal consensus on the ARM side.

llvm/docs/AArch64SME.rst
462

Probably select as well,

llvm/lib/IR/Type.cpp
868

Could drop the outer check while there is only one type...

This revision is now accepted and ready to land.Feb 23 2023, 9:42 AM
jcranmer-intel accepted this revision.Feb 23 2023, 10:04 AM
sdesmalen marked 2 inline comments as done.Mar 1 2023, 12:19 AM

Thanks for the reviews! I've addressed the nits before committing the patch.