================
@@ -233,23 +233,64 @@ static bool isSMEABIRoutineCall(const CallInst &CI,
          SMEAttrs(F->getName(), 
TLI.getRuntimeLibcallsInfo()).isSMEABIRoutine();
 }
 
+static bool isPossiblyIncompatibleIntrinsic(const Instruction *I,
+                                            bool ConsiderZA, bool ConsiderSM) {
+  auto *II = dyn_cast<IntrinsicInst>(I);
+  if (!II)
+    return false;
+
+  StringRef Name = II->getCalledFunction()->getName();
+  if (ConsiderZA && Name.starts_with("llvm.aarch64.sme."))
+    return true;
+
+  if (ConsiderSM) {
+    if (Name.starts_with("llvm.aarch64.neon") ||
+        Name.starts_with("llvm.aarch64.sve") ||
+        Name.starts_with("llvm.aarch64.sme") ||
+        Name.starts_with("llvm.vscale") ||
+        Name.starts_with("llvm.masked.gather") ||
+        Name.starts_with("llvm.masked.scatter")) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
 /// 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) {
+                                       const AArch64TargetLowering &TLI,
+                                       bool ConsiderZA, bool ConsiderSM) {
+  assert((ConsiderZA || ConsiderSM) && "No SME state to consider");
   for (const BasicBlock &BB : *F) {
     for (const Instruction &I : BB) {
-      // Be conservative for now and assume that any call to inline asm or to
-      // intrinsics could could result in non-streaming ops (e.g. calls to
-      // @llvm.aarch64.* or @llvm.gather/scatter intrinsics). We can assume 
that
-      // all native LLVM instructions can be lowered to compatible 
instructions.
-      if (isa<CallInst>(I) && !I.isDebugOrPseudoInst() &&
-          (cast<CallInst>(I).isInlineAsm() || isa<IntrinsicInst>(I) ||
-           isSMEABIRoutineCall(cast<CallInst>(I), TLI)))
+      // We can assume that all native LLVM instructions can be lowered to
+      // compatible instructions.
+      if (!isa<CallInst>(I) || I.isDebugOrPseudoInst())
+        continue;
+      // Be conservative for now and assume that any call to inline asm could
+      // result in different behaviour.
+      if (cast<CallInst>(I).isInlineAsm())
+        return true;
+
+      // Be conservative around operations on scalable types, as those may have
+      // different behaviour in/out of streaming mode.
+      if (ConsiderSM && (I.getType()->isScalableTy() ||
+                         any_of(I.operand_values(), [](const Value *V) {
+                           return V->getType()->isScalableTy();
+                         })))
+        return true;
----------------
MacDue wrote:

My opinion is right now we should be conservative as possible. Allowing the 
inlining of possibly behavior changing cases should wait until we have a cost 
model and more defined semantics. For the same reasons, we might also want to 
disable inlining fixed vectors into streaming functions unless `alwaysinline` 
is set.

https://github.com/llvm/llvm-project/pull/223393
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to