[flang-commits] [flang] 473d001 - [mlir][llvmir] Convert attributes for functions without bodies.

Slava Zakharin via flang-commits flang-commits at lists.llvm.org
Thu Nov 3 08:53:54 PDT 2022


Author: Slava Zakharin
Date: 2022-11-03T08:52:19-07:00
New Revision: 473d00115244ae8bfc3049a32262a347aeccb460

URL: https://github.com/llvm/llvm-project/commit/473d00115244ae8bfc3049a32262a347aeccb460
DIFF: https://github.com/llvm/llvm-project/commit/473d00115244ae8bfc3049a32262a347aeccb460.diff

LOG: [mlir][llvmir] Convert attributes for functions without bodies.

So far the function argument attributes were only translated
for functions with bodies. This change makes sure that this
happens for functions without bodies (declarations) as well.

This is needed for https://github.com/llvm/llvm-project/issues/58579

Reviewed By: ftynse

Differential Revision: https://reviews.llvm.org/D137047

Added: 
    

Modified: 
    flang/test/Fir/target.fir
    mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
    mlir/test/Dialect/LLVMIR/func.mlir
    mlir/test/Target/LLVMIR/llvmir.mlir

Removed: 
    


################################################################################
diff  --git a/flang/test/Fir/target.fir b/flang/test/Fir/target.fir
index 831c75379aa07..f6cf0587fcae9 100644
--- a/flang/test/Fir/target.fir
+++ b/flang/test/Fir/target.fir
@@ -48,13 +48,13 @@ func.func @gen8() -> !fir.complex<8> {
   return %5 : !fir.complex<8>
 }
 
-// I32: declare void @sink4(ptr)
+// I32: declare void @sink4(ptr byval({ float, float }) align 4)
 // X64: declare void @sink4(<2 x float>)
 // AARCH64: declare void @sink4([2 x float])
 // PPC: declare void @sink4(float, float)
 func.func private @sink4(!fir.complex<4>) -> ()
 
-// I32: declare void @sink8(ptr)
+// I32: declare void @sink8(ptr byval({ double, double }) align 4)
 // X64: declare void @sink8(double, double)
 // AARCH64: declare void @sink8([2 x double])
 // PPC: declare void @sink8(double, double)

diff  --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
index d1cdc77e4b968..3f808a5d05f7d 100644
--- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
@@ -826,107 +826,9 @@ LogicalResult ModuleTranslation::convertOneFunction(LLVMFuncOp func) {
   debugTranslation->translate(func, *llvmFunc);
 
   // Add function arguments to the value remapping table.
-  // If there was noalias info then we decorate each argument accordingly.
-  unsigned int argIdx = 0;
-  for (auto kvp : llvm::zip(func.getArguments(), llvmFunc->args())) {
-    llvm::Argument &llvmArg = std::get<1>(kvp);
-    BlockArgument mlirArg = std::get<0>(kvp);
-
-    if (auto attr = func.getArgAttrOfType<UnitAttr>(
-            argIdx, LLVMDialect::getNoAliasAttrName())) {
-      // NB: Attribute already verified to be boolean, so check if we can indeed
-      // attach the attribute to this argument, based on its type.
-      auto argTy = mlirArg.getType();
-      if (!argTy.isa<LLVM::LLVMPointerType>())
-        return func.emitError(
-            "llvm.noalias attribute attached to LLVM non-pointer argument");
-      llvmArg.addAttr(llvm::Attribute::AttrKind::NoAlias);
-    }
-
-    if (auto attr = func.getArgAttrOfType<IntegerAttr>(
-            argIdx, LLVMDialect::getAlignAttrName())) {
-      // NB: Attribute already verified to be int, so check if we can indeed
-      // attach the attribute to this argument, based on its type.
-      auto argTy = mlirArg.getType();
-      if (!argTy.isa<LLVM::LLVMPointerType>())
-        return func.emitError(
-            "llvm.align attribute attached to LLVM non-pointer argument");
-      llvmArg.addAttrs(llvm::AttrBuilder(llvmArg.getContext())
-                           .addAlignmentAttr(llvm::Align(attr.getInt())));
-    }
-
-    if (auto attr = func.getArgAttrOfType<TypeAttr>(
-            argIdx, LLVMDialect::getStructRetAttrName())) {
-      auto argTy = mlirArg.getType().dyn_cast<LLVM::LLVMPointerType>();
-      if (!argTy)
-        return func.emitError(
-            "llvm.sret attribute attached to LLVM non-pointer argument");
-      if (!argTy.isOpaque() && argTy.getElementType() != attr.getValue())
-        return func.emitError("llvm.sret attribute attached to LLVM pointer "
-                              "argument of a 
diff erent type");
-      llvmArg.addAttrs(llvm::AttrBuilder(llvmArg.getContext())
-                           .addStructRetAttr(convertType(attr.getValue())));
-    }
-
-    if (auto attr = func.getArgAttrOfType<TypeAttr>(
-            argIdx, LLVMDialect::getByValAttrName())) {
-      auto argTy = mlirArg.getType().dyn_cast<LLVM::LLVMPointerType>();
-      if (!argTy)
-        return func.emitError(
-            "llvm.byval attribute attached to LLVM non-pointer argument");
-      if (!argTy.isOpaque() && argTy.getElementType() != attr.getValue())
-        return func.emitError("llvm.byval attribute attached to LLVM pointer "
-                              "argument of a 
diff erent type");
-      llvmArg.addAttrs(llvm::AttrBuilder(llvmArg.getContext())
-                           .addByValAttr(convertType(attr.getValue())));
-    }
-
-    if (auto attr = func.getArgAttrOfType<TypeAttr>(
-            argIdx, LLVMDialect::getByRefAttrName())) {
-      auto argTy = mlirArg.getType().dyn_cast<LLVM::LLVMPointerType>();
-      if (!argTy)
-        return func.emitError(
-            "llvm.byref attribute attached to LLVM non-pointer argument");
-      if (!argTy.isOpaque() && argTy.getElementType() != attr.getValue())
-        return func.emitError("llvm.byref attribute attached to LLVM pointer "
-                              "argument of a 
diff erent type");
-      llvmArg.addAttrs(llvm::AttrBuilder(llvmArg.getContext())
-                           .addByRefAttr(convertType(attr.getValue())));
-    }
-
-    if (auto attr = func.getArgAttrOfType<TypeAttr>(
-            argIdx, LLVMDialect::getInAllocaAttrName())) {
-      auto argTy = mlirArg.getType().dyn_cast<LLVM::LLVMPointerType>();
-      if (!argTy)
-        return func.emitError(
-            "llvm.inalloca attribute attached to LLVM non-pointer argument");
-      if (!argTy.isOpaque() && argTy.getElementType() != attr.getValue())
-        return func.emitError(
-            "llvm.inalloca attribute attached to LLVM pointer "
-            "argument of a 
diff erent type");
-      llvmArg.addAttrs(llvm::AttrBuilder(llvmArg.getContext())
-                           .addInAllocaAttr(convertType(attr.getValue())));
-    }
-
-    if (auto attr = func.getArgAttrOfType<UnitAttr>(argIdx, "llvm.nest")) {
-      auto argTy = mlirArg.getType();
-      if (!argTy.isa<LLVM::LLVMPointerType>())
-        return func.emitError(
-            "llvm.nest attribute attached to LLVM non-pointer argument");
-      llvmArg.addAttrs(llvm::AttrBuilder(llvmArg.getContext())
-                           .addAttribute(llvm::Attribute::Nest));
-    }
-
-    if (auto attr = func.getArgAttrOfType<UnitAttr>(
-            argIdx, LLVMDialect::getNoUndefAttrName())) {
-      // llvm.noundef can be added to any argument type.
-      llvmArg.addAttrs(llvm::AttrBuilder(llvmArg.getContext())
-                           .addAttribute(llvm::Attribute::NoUndef));
-    }
-
+  for (auto [mlirArg, llvmArg] :
+       llvm::zip(func.getArguments(), llvmFunc->args()))
     mapValue(mlirArg, &llvmArg);
-    argIdx++;
-  }
 
   // Check the personality and set it.
   if (func.getPersonality()) {
@@ -986,6 +888,105 @@ LogicalResult ModuleTranslation::convertFunctionSignatures() {
     if (function->getAttrOfType<UnitAttr>(LLVMDialect::getReadnoneAttrName()))
       llvmFunc->setDoesNotAccessMemory();
 
+    // Convert argument attributes.
+    unsigned int argIdx = 0;
+    for (auto [mlirArgTy, llvmArg] :
+         llvm::zip(function.getArgumentTypes(), llvmFunc->args())) {
+      if (auto attr = function.getArgAttrOfType<UnitAttr>(
+              argIdx, LLVMDialect::getNoAliasAttrName())) {
+        // NB: Attribute already verified to be boolean, so check if we can
+        // indeed attach the attribute to this argument, based on its type.
+        if (!mlirArgTy.isa<LLVM::LLVMPointerType>())
+          return function.emitError(
+              "llvm.noalias attribute attached to LLVM non-pointer argument");
+        llvmArg.addAttr(llvm::Attribute::AttrKind::NoAlias);
+      }
+
+      if (auto attr = function.getArgAttrOfType<IntegerAttr>(
+              argIdx, LLVMDialect::getAlignAttrName())) {
+        // NB: Attribute already verified to be int, so check if we can indeed
+        // attach the attribute to this argument, based on its type.
+        if (!mlirArgTy.isa<LLVM::LLVMPointerType>())
+          return function.emitError(
+              "llvm.align attribute attached to LLVM non-pointer argument");
+        llvmArg.addAttrs(llvm::AttrBuilder(llvmArg.getContext())
+                             .addAlignmentAttr(llvm::Align(attr.getInt())));
+      }
+
+      if (auto attr = function.getArgAttrOfType<TypeAttr>(
+              argIdx, LLVMDialect::getStructRetAttrName())) {
+        auto argTy = mlirArgTy.dyn_cast<LLVM::LLVMPointerType>();
+        if (!argTy)
+          return function.emitError(
+              "llvm.sret attribute attached to LLVM non-pointer argument");
+        if (!argTy.isOpaque() && argTy.getElementType() != attr.getValue())
+          return function.emitError(
+              "llvm.sret attribute attached to LLVM pointer "
+              "argument of a 
diff erent type");
+        llvmArg.addAttrs(llvm::AttrBuilder(llvmArg.getContext())
+                             .addStructRetAttr(convertType(attr.getValue())));
+      }
+
+      if (auto attr = function.getArgAttrOfType<TypeAttr>(
+              argIdx, LLVMDialect::getByValAttrName())) {
+        auto argTy = mlirArgTy.dyn_cast<LLVM::LLVMPointerType>();
+        if (!argTy)
+          return function.emitError(
+              "llvm.byval attribute attached to LLVM non-pointer argument");
+        if (!argTy.isOpaque() && argTy.getElementType() != attr.getValue())
+          return function.emitError(
+              "llvm.byval attribute attached to LLVM pointer "
+              "argument of a 
diff erent type");
+        llvmArg.addAttrs(llvm::AttrBuilder(llvmArg.getContext())
+                             .addByValAttr(convertType(attr.getValue())));
+      }
+
+      if (auto attr = function.getArgAttrOfType<TypeAttr>(
+              argIdx, LLVMDialect::getByRefAttrName())) {
+        auto argTy = mlirArgTy.dyn_cast<LLVM::LLVMPointerType>();
+        if (!argTy)
+          return function.emitError(
+              "llvm.byref attribute attached to LLVM non-pointer argument");
+        if (!argTy.isOpaque() && argTy.getElementType() != attr.getValue())
+          return function.emitError(
+              "llvm.byref attribute attached to LLVM pointer "
+              "argument of a 
diff erent type");
+        llvmArg.addAttrs(llvm::AttrBuilder(llvmArg.getContext())
+                             .addByRefAttr(convertType(attr.getValue())));
+      }
+
+      if (auto attr = function.getArgAttrOfType<TypeAttr>(
+              argIdx, LLVMDialect::getInAllocaAttrName())) {
+        auto argTy = mlirArgTy.dyn_cast<LLVM::LLVMPointerType>();
+        if (!argTy)
+          return function.emitError(
+              "llvm.inalloca attribute attached to LLVM non-pointer argument");
+        if (!argTy.isOpaque() && argTy.getElementType() != attr.getValue())
+          return function.emitError(
+              "llvm.inalloca attribute attached to LLVM pointer "
+              "argument of a 
diff erent type");
+        llvmArg.addAttrs(llvm::AttrBuilder(llvmArg.getContext())
+                             .addInAllocaAttr(convertType(attr.getValue())));
+      }
+
+      if (auto attr =
+              function.getArgAttrOfType<UnitAttr>(argIdx, "llvm.nest")) {
+        if (!mlirArgTy.isa<LLVM::LLVMPointerType>())
+          return function.emitError(
+              "llvm.nest attribute attached to LLVM non-pointer argument");
+        llvmArg.addAttrs(llvm::AttrBuilder(llvmArg.getContext())
+                             .addAttribute(llvm::Attribute::Nest));
+      }
+
+      if (auto attr = function.getArgAttrOfType<UnitAttr>(
+              argIdx, LLVMDialect::getNoUndefAttrName())) {
+        // llvm.noundef can be added to any argument type.
+        llvmArg.addAttrs(llvm::AttrBuilder(llvmArg.getContext())
+                             .addAttribute(llvm::Attribute::NoUndef));
+      }
+      ++argIdx;
+    }
+
     // Forward the pass-through attributes to LLVM.
     if (failed(forwardPassthroughAttributes(
             function.getLoc(), function.getPassthrough(), llvmFunc)))

diff  --git a/mlir/test/Dialect/LLVMIR/func.mlir b/mlir/test/Dialect/LLVMIR/func.mlir
index 17cc6bf564793..7746d5c04b811 100644
--- a/mlir/test/Dialect/LLVMIR/func.mlir
+++ b/mlir/test/Dialect/LLVMIR/func.mlir
@@ -104,6 +104,24 @@ module {
     llvm.return
   }
 
+  // CHECK: llvm.func @llvm_noalias_decl(!llvm.ptr<f32> {llvm.noalias})
+  llvm.func @llvm_noalias_decl(!llvm.ptr<f32> {llvm.noalias})
+  // CHECK: llvm.func @byrefattr_decl(!llvm.ptr<i32> {llvm.byref = i32})
+  llvm.func @byrefattr_decl(!llvm.ptr<i32> {llvm.byref = i32})
+  // CHECK: llvm.func @byvalattr_decl(!llvm.ptr<i32> {llvm.byval = i32})
+  llvm.func @byvalattr_decl(!llvm.ptr<i32> {llvm.byval = i32})
+  // CHECK: llvm.func @sretattr_decl(!llvm.ptr<i32> {llvm.sret = i32})
+  llvm.func @sretattr_decl(!llvm.ptr<i32> {llvm.sret = i32})
+  // CHECK: llvm.func @nestattr_decl(!llvm.ptr<i32> {llvm.nest})
+  llvm.func @nestattr_decl(!llvm.ptr<i32> {llvm.nest})
+  // CHECK: llvm.func @noundefattr_decl(i32 {llvm.noundef})
+  llvm.func @noundefattr_decl(i32 {llvm.noundef})
+  // CHECK: llvm.func @llvm_align_decl(!llvm.ptr<f32> {llvm.align = 4 : i64})
+  llvm.func @llvm_align_decl(!llvm.ptr<f32> {llvm.align = 4})
+  // CHECK: llvm.func @inallocaattr_decl(!llvm.ptr<i32> {llvm.inalloca = i32})
+  llvm.func @inallocaattr_decl(!llvm.ptr<i32> {llvm.inalloca = i32})
+
+
   // CHECK: llvm.func @variadic(...)
   llvm.func @variadic(...)
 

diff  --git a/mlir/test/Target/LLVMIR/llvmir.mlir b/mlir/test/Target/LLVMIR/llvmir.mlir
index 54eb0f5e04c2c..84c750abcfd73 100644
--- a/mlir/test/Target/LLVMIR/llvmir.mlir
+++ b/mlir/test/Target/LLVMIR/llvmir.mlir
@@ -1049,31 +1049,65 @@ llvm.func @llvm_noalias(%arg0: !llvm.ptr<f32> {llvm.noalias}) {
   llvm.return
 }
 
+// CHECK-LABEL: declare void @llvm_noalias_decl(ptr noalias)
+llvm.func @llvm_noalias_decl(!llvm.ptr<f32> {llvm.noalias})
+
+// CHECK-LABEL: define void @byrefattr(ptr byref(i32) %
+llvm.func @byrefattr(%arg0: !llvm.ptr<i32> {llvm.byref = i32}) {
+  llvm.return
+}
+
+// CHECK-LABEL: declare void @byrefattr_decl(ptr byref(i32))
+llvm.func @byrefattr_decl(!llvm.ptr<i32> {llvm.byref = i32})
+
 // CHECK-LABEL: define void @byvalattr(ptr byval(i32) %
 llvm.func @byvalattr(%arg0: !llvm.ptr<i32> {llvm.byval = i32}) {
   llvm.return
 }
 
+// CHECK-LABEL: declare void @byvalattr_decl(ptr byval(i32))
+llvm.func @byvalattr_decl(!llvm.ptr<i32> {llvm.byval = i32})
+
 // CHECK-LABEL: define void @sretattr(ptr sret(i32) %
 llvm.func @sretattr(%arg0: !llvm.ptr<i32> {llvm.sret = i32}) {
   llvm.return
 }
 
+// CHECK-LABEL: declare void @sretattr_decl(ptr sret(i32))
+llvm.func @sretattr_decl(!llvm.ptr<i32> {llvm.sret = i32})
+
 // CHECK-LABEL: define void @nestattr(ptr nest %
 llvm.func @nestattr(%arg0: !llvm.ptr<i32> {llvm.nest}) {
   llvm.return
 }
 
+// CHECK-LABEL: declare void @nestattr_decl(ptr nest)
+llvm.func @nestattr_decl(!llvm.ptr<i32> {llvm.nest})
+
 // CHECK-LABEL: define void @noundefattr(i32 noundef %
 llvm.func @noundefattr(%arg0: i32 {llvm.noundef}) {
   llvm.return
 }
 
+// CHECK-LABEL: declare void @noundefattr_decl(i32 noundef)
+llvm.func @noundefattr_decl(i32 {llvm.noundef})
+
 // CHECK-LABEL: define void @llvm_align(ptr align 4 {{%*.}})
 llvm.func @llvm_align(%arg0: !llvm.ptr<f32> {llvm.align = 4}) {
   llvm.return
 }
 
+// CHECK-LABEL: declare void @llvm_align_decl(ptr align 4)
+llvm.func @llvm_align_decl(!llvm.ptr<f32> {llvm.align = 4})
+
+// CHECK-LABEL: define void @inallocaattr(ptr inalloca(i32) %
+llvm.func @inallocaattr(%arg0: !llvm.ptr<i32> {llvm.inalloca = i32}) {
+  llvm.return
+}
+
+// CHECK-LABEL: declare void @inallocaattr_decl(ptr inalloca(i32))
+llvm.func @inallocaattr_decl(!llvm.ptr<i32> {llvm.inalloca = i32})
+
 // CHECK-LABEL: @llvm_varargs(...)
 llvm.func @llvm_varargs(...)
 


        


More information about the flang-commits mailing list