Skip to content

Conversation

@fhahn
Copy link
Contributor

@fhahn fhahn commented Nov 3, 2025

Implement CastInfo from VPRecipeBase to VPIRMetadata to support isa/dyn_Cast. This is similar to CastInfoVPPhiAccessors, supporting dyn_cast by down-casting to the concrete recipe types inheriting from VPIRMetadata.

Can be used for more generalized VPIRMetadata printing following #165825.

Implement CastInfo from VPRecipeBase to VPIRMetadata to support
isa/dyn_Cast. This is similar to CastInfoVPPhiAccessors, supporting
dyn_cast by down-casting to the concrete recipe types inheriting from
VPIRMetadata.

Can be used for more generalized VPIRMetadata printing following
llvm#165825.
@llvmbot
Copy link
Member

llvmbot commented Nov 3, 2025

@llvm/pr-subscribers-vectorizers

@llvm/pr-subscribers-llvm-transforms

Author: Florian Hahn (fhahn)

Changes

Implement CastInfo from VPRecipeBase to VPIRMetadata to support isa/dyn_Cast. This is similar to CastInfoVPPhiAccessors, supporting dyn_cast by down-casting to the concrete recipe types inheriting from VPIRMetadata.

Can be used for more generalized VPIRMetadata printing following #165825.


Full diff: https://github.com/llvm/llvm-project/pull/166245.diff

1 Files Affected:

  • (modified) llvm/lib/Transforms/Vectorize/VPlan.h (+70)
diff --git a/llvm/lib/Transforms/Vectorize/VPlan.h b/llvm/lib/Transforms/Vectorize/VPlan.h
index cfe1f1e9d7528..2c47aa3f35e02 100644
--- a/llvm/lib/Transforms/Vectorize/VPlan.h
+++ b/llvm/lib/Transforms/Vectorize/VPlan.h
@@ -3815,6 +3815,76 @@ template <>
 struct CastInfo<VPPhiAccessors, const VPRecipeBase *>
     : CastInfoVPPhiAccessors<const VPRecipeBase *> {};
 
+/// Casting from VPRecipeBase -> VPIRMetadata is supported for all recipe types
+/// implementing VPIRMetadata. Used by isa<> & co.
+template <> struct CastIsPossible<VPIRMetadata, const VPRecipeBase *> {
+  static inline bool isPossible(const VPRecipeBase *R) {
+    return isa<VPInstruction, VPWidenRecipe, VPWidenCastRecipe,
+               VPWidenIntrinsicRecipe, VPWidenCallRecipe, VPWidenSelectRecipe,
+               VPReplicateRecipe, VPInterleaveRecipe, VPInterleaveEVLRecipe,
+               VPWidenLoadRecipe, VPWidenLoadEVLRecipe, VPWidenStoreRecipe,
+               VPWidenStoreEVLRecipe>(R);
+  }
+};
+
+/// Support casting from VPRecipeBase -> VPIRMetadata, by down-casting to the
+/// recipe types implementing VPIRMetadata. Used by cast<>, dyn_cast<> & co.
+template <typename SrcTy>
+struct CastInfoVPIRMetadata : public CastIsPossible<VPIRMetadata, SrcTy> {
+
+  using Self = CastInfo<VPIRMetadata, SrcTy>;
+
+  /// doCast is used by cast<>.
+  static inline VPIRMetadata *doCast(SrcTy R) {
+    return const_cast<VPIRMetadata *>([R]() -> const VPIRMetadata * {
+      switch (R->getVPDefID()) {
+      case VPDef::VPInstructionSC:
+        return cast<VPInstruction>(R);
+      case VPDef::VPWidenSC:
+        return cast<VPWidenRecipe>(R);
+      case VPDef::VPWidenCastSC:
+        return cast<VPWidenCastRecipe>(R);
+      case VPDef::VPWidenIntrinsicSC:
+        return cast<VPWidenIntrinsicRecipe>(R);
+      case VPDef::VPWidenCallSC:
+        return cast<VPWidenCallRecipe>(R);
+      case VPDef::VPWidenSelectSC:
+        return cast<VPWidenSelectRecipe>(R);
+      case VPDef::VPReplicateSC:
+        return cast<VPReplicateRecipe>(R);
+      case VPDef::VPInterleaveSC:
+        return cast<VPInterleaveRecipe>(R);
+      case VPDef::VPInterleaveEVLSC:
+        return cast<VPInterleaveEVLRecipe>(R);
+      case VPDef::VPWidenLoadSC:
+        return cast<VPWidenLoadRecipe>(R);
+      case VPDef::VPWidenLoadEVLSC:
+        return cast<VPWidenLoadEVLRecipe>(R);
+      case VPDef::VPWidenStoreSC:
+        return cast<VPWidenStoreRecipe>(R);
+      case VPDef::VPWidenStoreEVLSC:
+        return cast<VPWidenStoreEVLRecipe>(R);
+      default:
+        llvm_unreachable("invalid recipe for VPIRMetadata cast");
+      }
+    }());
+  }
+
+  /// doCastIfPossible is used by dyn_cast<>.
+  static inline VPIRMetadata *doCastIfPossible(SrcTy f) {
+    if (!Self::isPossible(f))
+      return nullptr;
+    return doCast(f);
+  }
+};
+
+template <>
+struct CastInfo<VPIRMetadata, VPRecipeBase *>
+    : CastInfoVPIRMetadata<VPRecipeBase *> {};
+template <>
+struct CastInfo<VPIRMetadata, const VPRecipeBase *>
+    : CastInfoVPIRMetadata<const VPRecipeBase *> {};
+
 /// VPBasicBlock serves as the leaf of the Hierarchical Control-Flow Graph. It
 /// holds a sequence of zero or more VPRecipe's each representing a sequence of
 /// output IR instructions. All PHI-like recipes must come before any non-PHI recipes.

struct CastInfo<VPIRMetadata, VPRecipeBase *>
: CastInfoVPIRMetadata<VPRecipeBase *> {};
template <>
struct CastInfo<VPIRMetadata, const VPRecipeBase *>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aren't we casting from a const to a non-const pointer here - is this safe?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(somehow my response seem to got lost, but that should be taken care of now)


/// doCast is used by cast<>.
static inline VPIRMetadata *doCast(SrcTy R) {
return const_cast<VPIRMetadata *>([R]() -> const VPIRMetadata * {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks a bit odd. We potentially take a non-const SrcTy, cast it to a non-const VPInstruction, etc., then return const VPIRMetadata * from the lambda function, which then returns VPIRMetadata *. Why not just do

  return cast<VPIRMetadata *> ([R]() -> VPIRMetadata * {
    ...

?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this was not 100% const-correct. I updated the patch to avoid this, by adding a templated castToVPIRMetadata, which can take care of both casting const * -> const *and non-const -> non-const.

Not sure if there's a nicer way to do that safely.

@fhahn
Copy link
Contributor Author

fhahn commented Nov 12, 2025

ping :)

Copy link
Contributor

@david-arm david-arm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Seems fine to me.

Copy link
Collaborator

@ayalz ayalz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couple of post-approval consistency nits.

using Self = CastInfo<VPIRMetadata, SrcTy>;
using RetTy = decltype(detail::castToVPIRMetadata(std::declval<SrcTy>()));

static inline RetTy doCast(SrcTy R) { return detail::castToVPIRMetadata(R); }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
static inline RetTy doCast(SrcTy R) { return detail::castToVPIRMetadata(R); }
/// doCast is used by cast<>.
static inline RetTy doCast(SrcTy R) { return detail::castToVPIRMetadata(R); }

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done thanks


static inline RetTy doCast(SrcTy R) { return detail::castToVPIRMetadata(R); }

static inline RetTy doCastIfPossible(SrcTy R) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
static inline RetTy doCastIfPossible(SrcTy R) {
/// doCastIfPossible is used by dyn_cast<>.
static inline RetTy doCastIfPossible(SrcTy R) {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done thanks

/// Casting from VPRecipeBase -> VPIRMetadata is supported for all recipe types
/// implementing VPIRMetadata. Used by isa<> & co.
namespace detail {
/// Returns const VPIRMetadata* if input is const, and VPIRMetadata* otherwise.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Independent consistency follow-up: should the above down-casting to VPPhiAccessors also support non/const-ness.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The above supports const/non-const with const_cast. I can update it to use the same approach as here, after this PR lands

Comment on lines +3918 to +3922
return isa<VPInstruction, VPWidenRecipe, VPWidenCastRecipe,
VPWidenIntrinsicRecipe, VPWidenCallRecipe, VPWidenSelectRecipe,
VPReplicateRecipe, VPInterleaveRecipe, VPInterleaveEVLRecipe,
VPWidenLoadRecipe, VPWidenLoadEVLRecipe, VPWidenStoreRecipe,
VPWidenStoreEVLRecipe>(R);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be good to note at VPIRMetadata that any recipe inheriting from it should be listed here. Also for VPPhiAccessors.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added thanks

@fhahn fhahn enabled auto-merge (squash) November 18, 2025 11:02
@fhahn fhahn merged commit 2432465 into llvm:main Nov 18, 2025
9 of 10 checks passed
llvm-sync bot pushed a commit to arm/arm-toolchain that referenced this pull request Nov 18, 2025
…data (NFC). (#166245)

Implement CastInfo from VPRecipeBase to VPIRMetadata to support
isa/dyn_Cast. This is similar to CastInfoVPPhiAccessors, supporting
dyn_cast by down-casting to the concrete recipe types inheriting from
VPIRMetadata.

Can be used for more generalized VPIRMetadata printing following
llvm/llvm-project#165825.

PR: llvm/llvm-project#166245
@fhahn fhahn deleted the vplan-dyncast-vpirmetadata branch November 18, 2025 16:16
nekoshirro pushed a commit to nekoshirro/Alchemist-LLVM that referenced this pull request Nov 24, 2025
… (#166245)

Implement CastInfo from VPRecipeBase to VPIRMetadata to support
isa/dyn_Cast. This is similar to CastInfoVPPhiAccessors, supporting
dyn_cast by down-casting to the concrete recipe types inheriting from
VPIRMetadata.

Can be used for more generalized VPIRMetadata printing following
llvm/llvm-project#165825.

PR: llvm/llvm-project#166245
Signed-off-by: Hafidz Muzakky <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants