[llvm] [TLI] Pass replace-with-veclib works with Scalable Vectors. (PR #73642)

Maciej Gabka via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 19 08:36:30 PST 2023


================
@@ -38,138 +42,152 @@ STATISTIC(NumTLIFuncDeclAdded,
 STATISTIC(NumFuncUsedAdded,
           "Number of functions added to `llvm.compiler.used`");
 
-static bool replaceWithTLIFunction(CallInst &CI, const StringRef TLIName) {
-  Module *M = CI.getModule();
-
-  Function *OldFunc = CI.getCalledFunction();
-
-  // Check if the vector library function is already declared in this module,
-  // otherwise insert it.
+/// Returns a vector Function that it adds to the Module \p M. When an \p
+/// ScalarFunc is not null, it copies its attributes to the newly created
+/// Function.
+Function *getTLIFunction(Module *M, FunctionType *VectorFTy,
+                         Function *ScalarFunc, const StringRef TLIName) {
   Function *TLIFunc = M->getFunction(TLIName);
   if (!TLIFunc) {
-    TLIFunc = Function::Create(OldFunc->getFunctionType(),
-                               Function::ExternalLinkage, TLIName, *M);
-    TLIFunc->copyAttributesFrom(OldFunc);
+    TLIFunc =
+        Function::Create(VectorFTy, Function::ExternalLinkage, TLIName, *M);
+    if (ScalarFunc)
+      TLIFunc->copyAttributesFrom(ScalarFunc);
 
     LLVM_DEBUG(dbgs() << DEBUG_TYPE << ": Added vector library function `"
                       << TLIName << "` of type `" << *(TLIFunc->getType())
                       << "` to module.\n");
 
     ++NumTLIFuncDeclAdded;
-
-    // Add the freshly created function to llvm.compiler.used,
-    // similar to as it is done in InjectTLIMappings
+    // Add the freshly created function to llvm.compiler.used, similar to as it
+    // is done in InjectTLIMappings.
     appendToCompilerUsed(*M, {TLIFunc});
-
     LLVM_DEBUG(dbgs() << DEBUG_TYPE << ": Adding `" << TLIName
                       << "` to `@llvm.compiler.used`.\n");
     ++NumFuncUsedAdded;
   }
+  return TLIFunc;
+}
 
-  // Replace the call to the vector intrinsic with a call
-  // to the corresponding function from the vector library.
+/// Replace the call to the vector intrinsic ( \p FuncToReplace ) with a call to
+/// the corresponding function from the vector library ( \p TLIFunc ).
+static void replaceWithTLIFunction(CallInst &CI, VFInfo &Info,
+                                   Function *TLIVecFunc) {
   IRBuilder<> IRBuilder(&CI);
   SmallVector<Value *> Args(CI.args());
+  if (auto OptMaskpos = Info.getParamIndexForOptionalMask()) {
+    if (Args.size() == TLIVecFunc->getFunctionType()->getNumParams())
+      static_assert(true && "mask was already in place");
----------------
mgabka wrote:

I do not think this is needed, IIUC if the vectorised intrinsic passed as input to this pass contained a mask, you would create a scalar type **i1** for the scalar version, and for it we would still try to find masked or unmasked vector mappings.
To me looks like there is no way to handle masked vector intrinsics passed as input to this pass, as you are not able to distinguish if the vector of i1 is a mask or just a regular argument.
So this extra check should be removed.
The VFABI you are using here ensures that Info.getParamIndexForOptionalMask() will return within range, but maybe you could just do an extra regular assert:

assert(OptMaskpos.value()>Args.size() && "Mask can not  replace function arguments." ));

?

https://github.com/llvm/llvm-project/pull/73642


More information about the llvm-commits mailing list