[llvm-branch-commits] [llvm] [AArch64][SME] NFC: Inline getCompatibilityForChangeToStreamingMode. (PR #231899)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Wed Oct 14 05:47:35 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-aarch64
Author: Sander de Smalen (sdesmalen-arm)
<details>
<summary>Changes</summary>
This removes the need for the `StreamingIncompatibility` enum and makes the code a little simpler.
This PR also moves `hasPossibleIncompatibleOps` to AArch64TTIimpl, so that we can query the costmodel in a follow-up PR.
---
Full diff: https://github.com/llvm/llvm-project/pull/231899.diff
2 Files Affected:
- (modified) llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp (+43-62)
- (modified) llvm/lib/Target/AArch64/AArch64TargetTransformInfo.h (+3)
``````````diff
diff --git a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
index 79a0472b917a9..f94555a4e3ddb 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
@@ -172,63 +172,13 @@ static cl::opt<TailFoldingOption, true, cl::parser<std::string>> SVETailFolding(
"\nnoreverse Inverse of above"),
cl::location(TailFoldingOptionLoc));
-// Enum to record why an operation is incompatible in a different streaming
-// mode.
-enum class StreamingIncompatibility : uint8_t {
- None = 0,
- VScaleDependent = 1 << 0,
- HasIncompatibleInstruction = 1 << 1,
- FullyIncompatible = VScaleDependent | HasIncompatibleInstruction,
- LLVM_MARK_AS_BITMASK_ENUM(/*LargestFlag=*/HasIncompatibleInstruction)
-};
-
-/// Returns an enum describing whether \p I is an instruction that is
-/// incompatible in the mode of the caller.
-static StreamingIncompatibility
-getCompatibilityForChangeToStreamingMode(const Instruction *I) {
- if (auto *II = dyn_cast<IntrinsicInst>(I)) {
- unsigned IID = II->getIntrinsicID();
- switch (IID) {
- default:
- // Conservatively disallow target intrinsics in other modes.
- if (Intrinsic::isTargetIntrinsic(IID))
- return StreamingIncompatibility::FullyIncompatible;
- break;
- case Intrinsic::vscale:
- return StreamingIncompatibility::VScaleDependent;
- case Intrinsic::masked_gather:
- case Intrinsic::masked_scatter:
- case Intrinsic::masked_compressstore:
- case Intrinsic::experimental_vector_histogram_add:
- // Instructions that are not available in streaming mode.
- // Fixed-length operations can still be code-generated by scalarizing.
- // FIXME: Consider FEAT_FA64.
- if (I->getOperand(0)->getType()->isScalableTy())
- return StreamingIncompatibility::FullyIncompatible;
- break;
- }
- }
-
- // Inlining operations on scalable vectors is rejected when
- // vscale-dependent operations cannot be safely inlined.
- if (I->getType()->isScalableTy() ||
- any_of(I->operand_values(),
- [](const Value *V) { return V->getType()->isScalableTy(); }) ||
- (isa<GetElementPtrInst>(I) &&
- cast<GetElementPtrInst>(I)->getSourceElementType()->isScalableTy()) ||
- (isa<AllocaInst>(I) && cast<AllocaInst>(I)->isScalable()))
- return StreamingIncompatibility::VScaleDependent;
-
- return StreamingIncompatibility::None;
-}
-
/// Returns true if the function has explicit operations that can only be
/// lowered using incompatible instructions for the selected mode. This also
/// returns true if the function F may use or modify ZA state.
-static bool hasPossibleIncompatibleOps(const Function *F,
- const AArch64TargetLowering &TLI,
- bool ConsiderZA, bool ConsiderZT,
- bool ConsiderSM) {
+bool AArch64TTIImpl::hasPossibleIncompatibleOps(const Function *F,
+ bool ConsiderZA,
+ bool ConsiderZT,
+ bool ConsiderSM) const {
if (!ConsiderZA && !ConsiderZT && !ConsiderSM)
return false;
@@ -247,7 +197,7 @@ static bool hasPossibleIncompatibleOps(const Function *F,
for (const BasicBlock &BB : *F) {
for (const Instruction &I : BB) {
if (auto *CB = dyn_cast<CallBase>(&I)) {
- SMECallAttrs CallAttrs(*CB, &TLI.getRuntimeLibcallsInfo());
+ SMECallAttrs CallAttrs(*CB, &TLI->getRuntimeLibcallsInfo());
// Inline asm must be rejected as it could use SME state.
if (CB->isInlineAsm())
@@ -272,17 +222,49 @@ static bool hasPossibleIncompatibleOps(const Function *F,
// Inlining operations on fixed-length vectors when the streaming
// mode does not match is rejected because performance may be impacted.
// This decision should eventually be moved to the cost-model.
+ // When IsVScaleDependent is true, then we allow fixed-length vectors as
+ // the operation may be something like llvm.vector.match, which takes both
+ // a scalable and a fixed-length vector.
if (!IsAlwaysInline && (isa<FixedVectorType>(I.getType()) ||
any_of(I.operand_values(), [](const Value *V) {
return isa<FixedVectorType>(V->getType());
})))
return true;
- StreamingIncompatibility C = getCompatibilityForChangeToStreamingMode(&I);
- if (any(C & StreamingIncompatibility::HasIncompatibleInstruction) ||
- (!AssumeVScaleIsEquivalent &&
- any(C & StreamingIncompatibility::VScaleDependent)))
- return true;
+ if (auto *II = dyn_cast<IntrinsicInst>(&I)) {
+ unsigned IID = II->getIntrinsicID();
+ switch (IID) {
+ default:
+ if (!Intrinsic::isTargetIntrinsic(IID))
+ break;
+ // Conservatively assume target intrinsics are vscale dependent
+ // or invalid in the current mode.
+ return true;
+ case Intrinsic::masked_gather:
+ case Intrinsic::masked_scatter:
+ case Intrinsic::masked_compressstore:
+ case Intrinsic::experimental_vector_histogram_add:
+ // Instructions that are not available in streaming mode.
+ // Fixed-length operations can still be code-generated by scalarizing.
+ // FIXME: Consider FEAT_FA64.
+ if (I.getOperand(0)->getType()->isScalableTy())
+ return true;
+ break;
+ case Intrinsic::vscale:
+ return !AssumeVScaleIsEquivalent;
+ }
+ }
+
+ // Determine if the operation is vscale dependent by looking at it's
+ // operand/result types.
+ bool IsVScaleDependent = false;
+ if (I.getType()->isScalableTy() ||
+ any_of(I.operand_values(),
+ [](const Value *V) { return V->getType()->isScalableTy(); }) ||
+ (isa<GetElementPtrInst>(I) &&
+ cast<GetElementPtrInst>(I).getSourceElementType()->isScalableTy()) ||
+ (isa<AllocaInst>(I) && cast<AllocaInst>(I).isScalable()))
+ return !AssumeVScaleIsEquivalent;
}
}
@@ -387,8 +369,7 @@ bool AArch64TTIImpl::areInlineCompatible(const Function *Caller,
if (ConsiderSM && (Caller->isStrictFP() || Callee->isStrictFP()))
return false;
- if (hasPossibleIncompatibleOps(Callee, *getTLI(), ConsiderZA, ConsiderZT,
- ConsiderSM))
+ if (hasPossibleIncompatibleOps(Callee, ConsiderZA, ConsiderZT, ConsiderSM))
return false;
return BaseT::areInlineCompatible(Caller, Callee);
diff --git a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.h b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.h
index 65c6364cffc35..2563fb50df3a4 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.h
+++ b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.h
@@ -576,6 +576,9 @@ class AArch64TTIImpl final : public BasicTTIImplBase<AArch64TTIImpl> {
return ST->enableAggressiveInterleaving();
}
/// @}
+
+ bool hasPossibleIncompatibleOps(const Function *F, bool ConsiderZA,
+ bool ConsiderZT, bool ConsiderSM) const;
};
} // end namespace llvm
``````````
</details>
https://github.com/llvm/llvm-project/pull/231899
More information about the llvm-branch-commits
mailing list