[Mlir-commits] [mlir] [mlir] Added new attributes to the llvm.call op in llvmir target (PR #99663)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Tue Jul 23 03:10:10 PDT 2024


https://github.com/FMarno updated https://github.com/llvm/llvm-project/pull/99663

>From de8cbbeba934cb99baaeb07452f7729a7cadbb39 Mon Sep 17 00:00:00 2001
From: Finlay Marno <finlay.marno at codeplay.com>
Date: Fri, 19 Jul 2024 14:35:12 +0100
Subject: [PATCH 1/5] [mlir] Added new attributes to the llvm.call op in llvmir
 target

The new attributes are:
 * convergent
 * no_unwind
 * will_return
 * memory effects
---
 mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td   |  7 +-
 mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp    | 12 +++-
 .../LLVMIR/LLVMToLLVMIRTranslation.cpp        | 22 ++++++
 mlir/lib/Target/LLVMIR/ModuleImport.cpp       | 24 +++++++
 mlir/test/Dialect/LLVMIR/call.mlir            | 34 +++++++++
 .../Target/LLVMIR/Import/call-attributes.ll   | 53 ++++++++++++++
 mlir/test/Target/LLVMIR/llvmir.mlir           | 72 +++++++++++++++++++
 7 files changed, 220 insertions(+), 4 deletions(-)
 create mode 100644 mlir/test/Dialect/LLVMIR/call.mlir
 create mode 100644 mlir/test/Target/LLVMIR/Import/call-attributes.ll

diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
index d2d1fbaf304b2..6abcadf0a4b45 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
@@ -652,7 +652,12 @@ def LLVM_CallOp : LLVM_MemAccessOpBase<"call",
                                    "{}">:$fastmathFlags,
                   OptionalAttr<DenseI32ArrayAttr>:$branch_weights,
                   DefaultValuedAttr<CConv, "CConv::C">:$CConv,
-                  DefaultValuedAttr<TailCallKind, "TailCallKind::None">:$TailCallKind);
+                  DefaultValuedAttr<TailCallKind, "TailCallKind::None">:$TailCallKind,
+                  OptionalAttr<LLVM_MemoryEffectsAttr>:$memory,
+                  OptionalAttr<UnitAttr>:$convergent,
+                  OptionalAttr<UnitAttr>:$no_unwind,
+                  OptionalAttr<UnitAttr>:$will_return
+                  );
   // Append the aliasing related attributes defined in LLVM_MemAccessOpBase.
   let arguments = !con(args, aliasAttrs);
   let results = (outs Optional<LLVM_Type>:$result);
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index b572b79d089a6..45457ea4cc8ef 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -982,6 +982,8 @@ void CallOp::build(OpBuilder &builder, OperationState &state, TypeRange results,
         /*var_callee_type=*/nullptr, callee, args, /*fastmathFlags=*/nullptr,
         /*branch_weights=*/nullptr,
         /*CConv=*/nullptr, /*TailCallKind=*/nullptr,
+/*memory=*/nullptr,
+        /*convergent=*/nullptr, /*no_unwind=*/nullptr, /*will_return=*/nullptr,
         /*access_groups=*/nullptr, /*alias_scopes=*/nullptr,
         /*noalias_scopes=*/nullptr, /*tbaa=*/nullptr);
 }
@@ -1005,7 +1007,9 @@ void CallOp::build(OpBuilder &builder, OperationState &state,
         getCallOpVarCalleeType(calleeType), callee, args,
         /*fastmathFlags=*/nullptr,
         /*branch_weights=*/nullptr, /*CConv=*/nullptr,
-        /*TailCallKind=*/nullptr, /*access_groups=*/nullptr,
+        /*TailCallKind=*/nullptr, /*memory=*/nullptr, /*convergent=*/nullptr,
+        /*no_unwind=*/nullptr, /*will_return=*/nullptr,
+        /*access_groups=*/nullptr,
         /*alias_scopes=*/nullptr, /*noalias_scopes=*/nullptr, /*tbaa=*/nullptr);
 }
 
@@ -1015,7 +1019,8 @@ void CallOp::build(OpBuilder &builder, OperationState &state,
         getCallOpVarCalleeType(calleeType),
         /*callee=*/nullptr, args,
         /*fastmathFlags=*/nullptr, /*branch_weights=*/nullptr,
-        /*CConv=*/nullptr, /*TailCallKind=*/nullptr,
+        /*CConv=*/nullptr, /*TailCallKind=*/nullptr, /*memory=*/nullptr,
+        /*convergent=*/nullptr, /*no_unwind=*/nullptr, /*will_return=*/nullptr,
         /*access_groups=*/nullptr, /*alias_scopes=*/nullptr,
         /*noalias_scopes=*/nullptr, /*tbaa=*/nullptr);
 }
@@ -1026,7 +1031,8 @@ void CallOp::build(OpBuilder &builder, OperationState &state, LLVMFuncOp func,
   build(builder, state, getCallOpResultTypes(calleeType),
         getCallOpVarCalleeType(calleeType), SymbolRefAttr::get(func), args,
         /*fastmathFlags=*/nullptr, /*branch_weights=*/nullptr,
-        /*CConv=*/nullptr, /*TailCallKind=*/nullptr,
+        /*CConv=*/nullptr, /*TailCallKind=*/nullptr, /*memory=*/nullptr,
+        /*convergent=*/nullptr, /*no_unwind=*/nullptr, /*will_return=*/nullptr,
         /*access_groups=*/nullptr, /*alias_scopes=*/nullptr,
         /*noalias_scopes=*/nullptr, /*tbaa=*/nullptr);
 }
diff --git a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
index 3d6dd1247b413..488945cc7f34c 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
@@ -219,6 +219,28 @@ convertOperationImpl(Operation &opInst, llvm::IRBuilderBase &builder,
     }
     call->setCallingConv(convertCConvToLLVM(callOp.getCConv()));
     call->setTailCallKind(convertTailCallKindToLLVM(callOp.getTailCallKind()));
+    if (callOp.getConvergentAttr())
+      call->addFnAttr(llvm::Attribute::Convergent);
+    if (callOp.getNoUnwindAttr())
+      call->addFnAttr(llvm::Attribute::NoUnwind);
+    if (callOp.getWillReturnAttr())
+      call->addFnAttr(llvm::Attribute::WillReturn);
+
+    // memory effects
+    if (callOp.getMemory()) {
+      MemoryEffectsAttr memAttr = callOp.getMemoryAttr();
+      llvm::MemoryEffects newMemEffects =
+          llvm::MemoryEffects(llvm::MemoryEffects::Location::ArgMem,
+                              convertModRefInfoToLLVM(memAttr.getArgMem())) |
+          llvm::MemoryEffects(
+              llvm::MemoryEffects::Location::InaccessibleMem,
+              convertModRefInfoToLLVM(memAttr.getInaccessibleMem())) |
+          llvm::MemoryEffects(llvm::MemoryEffects::Location::Other,
+                              convertModRefInfoToLLVM(memAttr.getOther()));
+
+      call->setMemoryEffects(newMemEffects);
+    }
+
     moduleTranslation.setAccessGroupsMetadata(callOp, call);
     moduleTranslation.setAliasScopeMetadata(callOp, call);
     moduleTranslation.setTBAAMetadata(callOp, call);
diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
index 16007592175f7..5e4c33941802d 100644
--- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
@@ -1471,6 +1471,30 @@ LogicalResult ModuleImport::convertInstruction(llvm::Instruction *inst) {
     callOp.setTailCallKind(
         convertTailCallKindFromLLVM(callInst->getTailCallKind()));
     setFastmathFlagsAttr(inst, callOp);
+
+    // handle function attrs
+    if (callInst->hasFnAttr(llvm::Attribute::Convergent))
+      callOp.setConvergent(true);
+    if (callInst->hasFnAttr(llvm::Attribute::NoUnwind))
+      callOp.setNoUnwind(true);
+    if (callInst->hasFnAttr(llvm::Attribute::WillReturn))
+      callOp.setWillReturn(true);
+
+    // memory effects
+    llvm::MemoryEffects memEffects = callInst->getMemoryEffects();
+    // Only set the attr when it does not match the default value.
+    auto othermem = convertModRefInfoFromLLVM(
+        memEffects.getModRef(llvm::MemoryEffects::Location::Other));
+    auto argMem = convertModRefInfoFromLLVM(
+        memEffects.getModRef(llvm::MemoryEffects::Location::ArgMem));
+    auto inaccessibleMem = convertModRefInfoFromLLVM(
+        memEffects.getModRef(llvm::MemoryEffects::Location::InaccessibleMem));
+    auto memAttr = MemoryEffectsAttr::get(callOp.getContext(), othermem, argMem,
+                                          inaccessibleMem);
+    if (!memAttr.isReadWrite()) {
+      callOp.setMemoryAttr(memAttr);
+    }
+
     if (!callInst->getType()->isVoidTy())
       mapValue(inst, callOp.getResult());
     else
diff --git a/mlir/test/Dialect/LLVMIR/call.mlir b/mlir/test/Dialect/LLVMIR/call.mlir
new file mode 100644
index 0000000000000..1dfb8d47c120e
--- /dev/null
+++ b/mlir/test/Dialect/LLVMIR/call.mlir
@@ -0,0 +1,34 @@
+// RUN: mlir-opt -split-input-file -verify-diagnostics %s | mlir-opt | FileCheck %s
+
+module {
+  // CHECK: llvm.func @f()
+  llvm.func @f()
+
+  // CHECK-LABEL: call_convergent
+  llvm.func @call_convergent() {
+    // CHECK: llvm.call @f() {convergent} : () -> ()
+    llvm.call @f() {convergent} : () -> ()
+    llvm.return
+  }
+
+  // CHECK-LABEL: call_no_unwind
+  llvm.func @call_no_unwind() {
+    // CHECK: llvm.call @f() {no_unwind} : () -> ()
+    llvm.call @f() {no_unwind} : () -> ()
+    llvm.return
+  }
+
+  // CHECK-LABEL: call_will_return
+  llvm.func @call_will_return() {
+    // CHECK: llvm.call @f() {will_return} : () -> ()
+    llvm.call @f() {will_return} : () -> ()
+    llvm.return
+  }
+
+  // CHECK-LABEL: call_mem_effects
+  llvm.func @call_mem_effects() {
+    // CHECK: llvm.call @f() {memory = #llvm.memory_effects<other = none, argMem = read, inaccessibleMem = write>} : () -> ()
+    llvm.call @f() {memory = #llvm.memory_effects<other = none, argMem = read, inaccessibleMem = write>} : () -> ()
+    llvm.return
+  }
+}
diff --git a/mlir/test/Target/LLVMIR/Import/call-attributes.ll b/mlir/test/Target/LLVMIR/Import/call-attributes.ll
new file mode 100644
index 0000000000000..c6200a2713bd9
--- /dev/null
+++ b/mlir/test/Target/LLVMIR/Import/call-attributes.ll
@@ -0,0 +1,53 @@
+; RUN: mlir-translate -import-llvm -split-input-file %s | FileCheck %s
+
+; CHECK: llvm.func @f()
+declare void @f()
+
+; CHECK-LABEL: @call_convergent
+define void @call_convergent() {
+; CHECK: llvm.call @f() {convergent}
+  call void @f() convergent
+  ret void
+}
+
+// -----
+
+; CHECK: llvm.func @f()
+declare void @f()
+
+; CHECK-LABEL: @call_no_unwind
+define void @call_no_unwind() {
+; CHECK: llvm.call @f() {no_unwind}
+  call void @f() nounwind
+  ret void
+}
+
+// -----
+
+; CHECK: llvm.func @f()
+declare void @f()
+
+; CHECK-LABEL: @call_will_return
+define void @call_will_return() {
+; CHECK: llvm.call @f() {will_return}
+  call void @f() willreturn
+  ret void
+}
+
+// -----
+
+; CHECK: llvm.func @f()
+declare void @f()
+
+; CHECK-LABEL: @call_will_return
+define void @call_will_return() {
+; CHECK: llvm.call @f() {memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>}
+  call void @f() memory(none)
+; CHECK: llvm.call @f() {memory = #llvm.memory_effects<other = none, argMem = write, inaccessibleMem = read>}
+  call void @f() memory(none, inaccessiblemem: read, argmem: write)
+; CHECK: llvm.call @f() {memory = #llvm.memory_effects<other = write, argMem = none, inaccessibleMem = write>}
+  call void @f() memory(write, argmem: none)
+; CHECK: llvm.call @f() {memory = #llvm.memory_effects<other = readwrite, argMem = readwrite, inaccessibleMem = read>}
+  call void @f() memory(readwrite, inaccessiblemem: read)
+  ret void
+}
diff --git a/mlir/test/Target/LLVMIR/llvmir.mlir b/mlir/test/Target/LLVMIR/llvmir.mlir
index 802a2ff9ea866..ab5b65bde6305 100644
--- a/mlir/test/Target/LLVMIR/llvmir.mlir
+++ b/mlir/test/Target/LLVMIR/llvmir.mlir
@@ -2477,3 +2477,75 @@ llvm.func @willreturn() attributes { will_return } {
 
 // CHECK: #[[ATTRS]]
 // CHECK-SAME: willreturn
+
+// -----
+
+llvm.func @f()
+
+// CHECK-LABEL: @convergent_call
+// CHECK: call void @f() #[[ATTRS:[0-9]+]]
+llvm.func @convergent_call() {
+  llvm.call @f() {convergent} : () -> ()
+  llvm.return
+}
+
+// CHECK: #[[ATTRS]]
+// CHECK-SAME: convergent
+
+// -----
+
+llvm.func @f()
+
+// CHECK-LABEL: @nounwind_call
+// CHECK: call void @f() #[[ATTRS:[0-9]+]]
+llvm.func @nounwind_call() {
+  llvm.call @f() {no_unwind} : () -> ()
+  llvm.return
+}
+
+// CHECK: #[[ATTRS]]
+// CHECK-SAME: nounwind
+
+// -----
+
+llvm.func @f()
+
+// CHECK-LABEL: @willreturn_call
+// CHECK: call void @f() #[[ATTRS:[0-9]+]]
+llvm.func @willreturn_call() {
+  llvm.call @f() {will_return} : () -> ()
+  llvm.return
+}
+
+// CHECK: #[[ATTRS]]
+// CHECK-SAME: willreturn
+
+// -----
+
+llvm.func @fa()
+llvm.func @fb()
+llvm.func @fc()
+llvm.func @fd()
+
+// CHECK-LABEL: @mem_none_call
+// CHECK: call void @fa() #[[ATTRS_0:[0-9]+]]
+// CHECK: call void @fb() #[[ATTRS_1:[0-9]+]]
+// CHECK: call void @fc() #[[ATTRS_2:[0-9]+]]
+// CHECK: call void @fd() #[[ATTRS_3:[0-9]+]]
+llvm.func @mem_none_call() {
+  llvm.call @fa() {memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>} : () -> ()
+  llvm.call @fb() {memory = #llvm.memory_effects<other = read, argMem = none, inaccessibleMem = write>} : () -> ()
+  llvm.call @fc() {memory = #llvm.memory_effects<other = read, argMem = read, inaccessibleMem = write>} : () -> ()
+  llvm.call @fd() {memory = #llvm.memory_effects<other = readwrite, argMem = read, inaccessibleMem = readwrite>} : () -> ()
+  llvm.return
+
+}
+
+// CHECK: #[[ATTRS_0]]
+// CHECK-SAME: memory(none)
+// CHECK: #[[ATTRS_1]]
+// CHECK-SAME: memory(read, argmem: none, inaccessiblemem: write)
+// CHECK: #[[ATTRS_2]]
+// CHECK-SAME: memory(read, inaccessiblemem: write)
+// CHECK: #[[ATTRS_3]]
+// CHECK-SAME: memory(readwrite, argmem: read)

>From 9675497e5e1bbc7251f69286e301169b9bab70e1 Mon Sep 17 00:00:00 2001
From: Finlay Marno <finlay.marno at codeplay.com>
Date: Mon, 22 Jul 2024 11:00:22 +0100
Subject: [PATCH 2/5] amend! small style changes + new test

[mlir] Added new attributes to the llvm.call op in llvmir target

The new attributes are:
 * convergent
 * no_unwind
 * will_return
 * memory effects
---
 .../LLVMIR/LLVMToLLVMIRTranslation.cpp        |  3 +-
 mlir/lib/Target/LLVMIR/ModuleImport.cpp       |  8 +--
 mlir/test/Dialect/LLVMIR/call.mlir            | 52 +++++++++----------
 .../Target/LLVMIR/Import/call-attributes.ll   | 10 ++--
 4 files changed, 37 insertions(+), 36 deletions(-)

diff --git a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
index 488945cc7f34c..2d3d8ede39765 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
@@ -227,8 +227,7 @@ convertOperationImpl(Operation &opInst, llvm::IRBuilderBase &builder,
       call->addFnAttr(llvm::Attribute::WillReturn);
 
     // memory effects
-    if (callOp.getMemory()) {
-      MemoryEffectsAttr memAttr = callOp.getMemoryAttr();
+    if (MemoryEffectsAttr memAttr = callOp.getMemoryAttr()) {
       llvm::MemoryEffects newMemEffects =
           llvm::MemoryEffects(llvm::MemoryEffects::Location::ArgMem,
                               convertModRefInfoToLLVM(memAttr.getArgMem())) |
diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
index 5e4c33941802d..490a1fec40a99 100644
--- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
@@ -1482,15 +1482,15 @@ LogicalResult ModuleImport::convertInstruction(llvm::Instruction *inst) {
 
     // memory effects
     llvm::MemoryEffects memEffects = callInst->getMemoryEffects();
-    // Only set the attr when it does not match the default value.
-    auto othermem = convertModRefInfoFromLLVM(
+    ModRefInfo othermem = convertModRefInfoFromLLVM(
         memEffects.getModRef(llvm::MemoryEffects::Location::Other));
-    auto argMem = convertModRefInfoFromLLVM(
+    ModRefInfo argMem = convertModRefInfoFromLLVM(
         memEffects.getModRef(llvm::MemoryEffects::Location::ArgMem));
-    auto inaccessibleMem = convertModRefInfoFromLLVM(
+    ModRefInfo inaccessibleMem = convertModRefInfoFromLLVM(
         memEffects.getModRef(llvm::MemoryEffects::Location::InaccessibleMem));
     auto memAttr = MemoryEffectsAttr::get(callOp.getContext(), othermem, argMem,
                                           inaccessibleMem);
+    // Only set the attr when it does not match the default value.
     if (!memAttr.isReadWrite()) {
       callOp.setMemoryAttr(memAttr);
     }
diff --git a/mlir/test/Dialect/LLVMIR/call.mlir b/mlir/test/Dialect/LLVMIR/call.mlir
index 1dfb8d47c120e..4d464dab4d6c6 100644
--- a/mlir/test/Dialect/LLVMIR/call.mlir
+++ b/mlir/test/Dialect/LLVMIR/call.mlir
@@ -1,34 +1,32 @@
 // RUN: mlir-opt -split-input-file -verify-diagnostics %s | mlir-opt | FileCheck %s
 
-module {
-  // CHECK: llvm.func @f()
-  llvm.func @f()
+// CHECK: llvm.func @f()
+llvm.func @f()
 
-  // CHECK-LABEL: call_convergent
-  llvm.func @call_convergent() {
-    // CHECK: llvm.call @f() {convergent} : () -> ()
-    llvm.call @f() {convergent} : () -> ()
-    llvm.return
-  }
+// CHECK-LABEL: call_convergent
+llvm.func @call_convergent() {
+  // CHECK: llvm.call @f() {convergent} : () -> ()
+  llvm.call @f() {convergent} : () -> ()
+  llvm.return
+}
 
-  // CHECK-LABEL: call_no_unwind
-  llvm.func @call_no_unwind() {
-    // CHECK: llvm.call @f() {no_unwind} : () -> ()
-    llvm.call @f() {no_unwind} : () -> ()
-    llvm.return
-  }
+// CHECK-LABEL: call_no_unwind
+llvm.func @call_no_unwind() {
+  // CHECK: llvm.call @f() {no_unwind} : () -> ()
+  llvm.call @f() {no_unwind} : () -> ()
+  llvm.return
+}
 
-  // CHECK-LABEL: call_will_return
-  llvm.func @call_will_return() {
-    // CHECK: llvm.call @f() {will_return} : () -> ()
-    llvm.call @f() {will_return} : () -> ()
-    llvm.return
-  }
+// CHECK-LABEL: call_will_return
+llvm.func @call_will_return() {
+  // CHECK: llvm.call @f() {will_return} : () -> ()
+  llvm.call @f() {will_return} : () -> ()
+  llvm.return
+}
 
-  // CHECK-LABEL: call_mem_effects
-  llvm.func @call_mem_effects() {
-    // CHECK: llvm.call @f() {memory = #llvm.memory_effects<other = none, argMem = read, inaccessibleMem = write>} : () -> ()
-    llvm.call @f() {memory = #llvm.memory_effects<other = none, argMem = read, inaccessibleMem = write>} : () -> ()
-    llvm.return
-  }
+// CHECK-LABEL: call_mem_effects
+llvm.func @call_mem_effects() {
+  // CHECK: llvm.call @f() {memory = #llvm.memory_effects<other = none, argMem = read, inaccessibleMem = write>} : () -> ()
+  llvm.call @f() {memory = #llvm.memory_effects<other = none, argMem = read, inaccessibleMem = write>} : () -> ()
+  llvm.return
 }
diff --git a/mlir/test/Target/LLVMIR/Import/call-attributes.ll b/mlir/test/Target/LLVMIR/Import/call-attributes.ll
index c6200a2713bd9..09487f805607e 100644
--- a/mlir/test/Target/LLVMIR/Import/call-attributes.ll
+++ b/mlir/test/Target/LLVMIR/Import/call-attributes.ll
@@ -39,15 +39,19 @@ define void @call_will_return() {
 ; CHECK: llvm.func @f()
 declare void @f()
 
-; CHECK-LABEL: @call_will_return
-define void @call_will_return() {
+; CHECK-LABEL: @call_memory_effects
+define void @call_memory_effects() {
 ; CHECK: llvm.call @f() {memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>}
   call void @f() memory(none)
 ; CHECK: llvm.call @f() {memory = #llvm.memory_effects<other = none, argMem = write, inaccessibleMem = read>}
-  call void @f() memory(none, inaccessiblemem: read, argmem: write)
+  call void @f() memory(none, argmem: write, inaccessiblemem: read)
 ; CHECK: llvm.call @f() {memory = #llvm.memory_effects<other = write, argMem = none, inaccessibleMem = write>}
   call void @f() memory(write, argmem: none)
 ; CHECK: llvm.call @f() {memory = #llvm.memory_effects<other = readwrite, argMem = readwrite, inaccessibleMem = read>}
   call void @f() memory(readwrite, inaccessiblemem: read)
+; CHECK: llvm.call @f()
+; CHECK-NOT: #llvm.memory_effects
+; CHECK-SAME: : () -> ()
+  call void @f() memory(readwrite)
   ret void
 }

>From 4361145001cff79c01c9de32a534fed112f07054 Mon Sep 17 00:00:00 2001
From: Finlay Marno <finlay.marno at codeplay.com>
Date: Mon, 22 Jul 2024 15:55:18 +0100
Subject: [PATCH 3/5] amend! move tests

[mlir] Added new attributes to the llvm.call op in llvmir target

The new attributes are:
 * convergent
 * no_unwind
 * will_return
 * memory effects
---
 mlir/test/Dialect/LLVMIR/call.mlir            | 32 ----------
 mlir/test/Dialect/LLVMIR/roundtrip.mlir       | 18 ++++++
 .../Target/LLVMIR/Import/call-attributes.ll   | 57 ------------------
 .../test/Target/LLVMIR/Import/instructions.ll | 58 +++++++++++++++++++
 4 files changed, 76 insertions(+), 89 deletions(-)
 delete mode 100644 mlir/test/Dialect/LLVMIR/call.mlir
 delete mode 100644 mlir/test/Target/LLVMIR/Import/call-attributes.ll

diff --git a/mlir/test/Dialect/LLVMIR/call.mlir b/mlir/test/Dialect/LLVMIR/call.mlir
deleted file mode 100644
index 4d464dab4d6c6..0000000000000
--- a/mlir/test/Dialect/LLVMIR/call.mlir
+++ /dev/null
@@ -1,32 +0,0 @@
-// RUN: mlir-opt -split-input-file -verify-diagnostics %s | mlir-opt | FileCheck %s
-
-// CHECK: llvm.func @f()
-llvm.func @f()
-
-// CHECK-LABEL: call_convergent
-llvm.func @call_convergent() {
-  // CHECK: llvm.call @f() {convergent} : () -> ()
-  llvm.call @f() {convergent} : () -> ()
-  llvm.return
-}
-
-// CHECK-LABEL: call_no_unwind
-llvm.func @call_no_unwind() {
-  // CHECK: llvm.call @f() {no_unwind} : () -> ()
-  llvm.call @f() {no_unwind} : () -> ()
-  llvm.return
-}
-
-// CHECK-LABEL: call_will_return
-llvm.func @call_will_return() {
-  // CHECK: llvm.call @f() {will_return} : () -> ()
-  llvm.call @f() {will_return} : () -> ()
-  llvm.return
-}
-
-// CHECK-LABEL: call_mem_effects
-llvm.func @call_mem_effects() {
-  // CHECK: llvm.call @f() {memory = #llvm.memory_effects<other = none, argMem = read, inaccessibleMem = write>} : () -> ()
-  llvm.call @f() {memory = #llvm.memory_effects<other = none, argMem = read, inaccessibleMem = write>} : () -> ()
-  llvm.return
-}
diff --git a/mlir/test/Dialect/LLVMIR/roundtrip.mlir b/mlir/test/Dialect/LLVMIR/roundtrip.mlir
index ca9748a2b8b7b..ff16bb0f857dd 100644
--- a/mlir/test/Dialect/LLVMIR/roundtrip.mlir
+++ b/mlir/test/Dialect/LLVMIR/roundtrip.mlir
@@ -1,5 +1,10 @@
 // RUN: mlir-opt %s | mlir-opt | FileCheck %s
 
+
+// CHECK-LABEL: func @baz
+// something to call
+llvm.func @baz()
+
 // CHECK-LABEL: func @ops
 // CHECK-SAME: (%[[I32:.*]]: i32, %[[FLOAT:.*]]: f32, %[[PTR1:.*]]: !llvm.ptr, %[[PTR2:.*]]: !llvm.ptr, %[[BOOL:.*]]: i1, %[[VPTR1:.*]]: !llvm.vec<2 x ptr>)
 func.func @ops(%arg0: i32, %arg1: f32,
@@ -93,6 +98,19 @@ func.func @ops(%arg0: i32, %arg1: f32,
   llvm.call %variadic_func(%arg0, %arg0) vararg(!llvm.func<void (i32, ...)>) : !llvm.ptr, (i32, i32) -> ()
   llvm.call %variadic_func(%arg0, %arg0) vararg(!llvm.func<void (i32, ...)>) {fastmathFlags = #llvm.fastmath<fast>} : !llvm.ptr, (i32, i32) -> ()
 
+// Function call attributes
+// CHECK: llvm.call @baz() {convergent} : () -> ()
+  llvm.call @baz() {convergent} : () -> ()
+
+// CHECK: llvm.call @baz() {no_unwind} : () -> ()
+  llvm.call @baz() {no_unwind} : () -> ()
+
+// CHECK: llvm.call @baz() {will_return} : () -> ()
+  llvm.call @baz() {will_return} : () -> ()
+
+// CHECK: llvm.call @baz() {memory = #llvm.memory_effects<other = none, argMem = read, inaccessibleMem = write>} : () -> ()
+  llvm.call @baz() {memory = #llvm.memory_effects<other = none, argMem = read, inaccessibleMem = write>} : () -> ()
+
 // Terminator operations and their successors.
 //
 // CHECK: llvm.br ^[[BB1:.*]]
diff --git a/mlir/test/Target/LLVMIR/Import/call-attributes.ll b/mlir/test/Target/LLVMIR/Import/call-attributes.ll
deleted file mode 100644
index 09487f805607e..0000000000000
--- a/mlir/test/Target/LLVMIR/Import/call-attributes.ll
+++ /dev/null
@@ -1,57 +0,0 @@
-; RUN: mlir-translate -import-llvm -split-input-file %s | FileCheck %s
-
-; CHECK: llvm.func @f()
-declare void @f()
-
-; CHECK-LABEL: @call_convergent
-define void @call_convergent() {
-; CHECK: llvm.call @f() {convergent}
-  call void @f() convergent
-  ret void
-}
-
-// -----
-
-; CHECK: llvm.func @f()
-declare void @f()
-
-; CHECK-LABEL: @call_no_unwind
-define void @call_no_unwind() {
-; CHECK: llvm.call @f() {no_unwind}
-  call void @f() nounwind
-  ret void
-}
-
-// -----
-
-; CHECK: llvm.func @f()
-declare void @f()
-
-; CHECK-LABEL: @call_will_return
-define void @call_will_return() {
-; CHECK: llvm.call @f() {will_return}
-  call void @f() willreturn
-  ret void
-}
-
-// -----
-
-; CHECK: llvm.func @f()
-declare void @f()
-
-; CHECK-LABEL: @call_memory_effects
-define void @call_memory_effects() {
-; CHECK: llvm.call @f() {memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>}
-  call void @f() memory(none)
-; CHECK: llvm.call @f() {memory = #llvm.memory_effects<other = none, argMem = write, inaccessibleMem = read>}
-  call void @f() memory(none, argmem: write, inaccessiblemem: read)
-; CHECK: llvm.call @f() {memory = #llvm.memory_effects<other = write, argMem = none, inaccessibleMem = write>}
-  call void @f() memory(write, argmem: none)
-; CHECK: llvm.call @f() {memory = #llvm.memory_effects<other = readwrite, argMem = readwrite, inaccessibleMem = read>}
-  call void @f() memory(readwrite, inaccessiblemem: read)
-; CHECK: llvm.call @f()
-; CHECK-NOT: #llvm.memory_effects
-; CHECK-SAME: : () -> ()
-  call void @f() memory(readwrite)
-  ret void
-}
diff --git a/mlir/test/Target/LLVMIR/Import/instructions.ll b/mlir/test/Target/LLVMIR/Import/instructions.ll
index 005aafb20a510..b4dad2deb3496 100644
--- a/mlir/test/Target/LLVMIR/Import/instructions.ll
+++ b/mlir/test/Target/LLVMIR/Import/instructions.ll
@@ -528,6 +528,64 @@ define void @varargs_call(i32 %0) {
 
 ; // -----
 
+; CHECK: llvm.func @f()
+declare void @f()
+
+; CHECK-LABEL: @call_convergent
+define void @call_convergent() {
+; CHECK: llvm.call @f() {convergent}
+  call void @f() convergent
+  ret void
+}
+
+; // -----
+
+; CHECK: llvm.func @f()
+declare void @f()
+
+; CHECK-LABEL: @call_no_unwind
+define void @call_no_unwind() {
+; CHECK: llvm.call @f() {no_unwind}
+  call void @f() nounwind
+  ret void
+}
+
+; // -----
+
+; CHECK: llvm.func @f()
+declare void @f()
+
+; CHECK-LABEL: @call_will_return
+define void @call_will_return() {
+; CHECK: llvm.call @f() {will_return}
+  call void @f() willreturn
+  ret void
+}
+
+; // -----
+
+; CHECK: llvm.func @f()
+declare void @f()
+
+; CHECK-LABEL: @call_memory_effects
+define void @call_memory_effects() {
+; CHECK: llvm.call @f() {memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>}
+  call void @f() memory(none)
+; CHECK: llvm.call @f() {memory = #llvm.memory_effects<other = none, argMem = write, inaccessibleMem = read>}
+  call void @f() memory(none, argmem: write, inaccessiblemem: read)
+; CHECK: llvm.call @f() {memory = #llvm.memory_effects<other = write, argMem = none, inaccessibleMem = write>}
+  call void @f() memory(write, argmem: none)
+; CHECK: llvm.call @f() {memory = #llvm.memory_effects<other = readwrite, argMem = readwrite, inaccessibleMem = read>}
+  call void @f() memory(readwrite, inaccessiblemem: read)
+; CHECK: llvm.call @f()
+; CHECK-NOT: #llvm.memory_effects
+; CHECK-SAME: : () -> ()
+  call void @f() memory(readwrite)
+  ret void
+}
+
+; // -----
+
 %sub_struct = type { i32, i8 }
 %my_struct = type { %sub_struct, [4 x i32] }
 

>From 868ffe5657bc36771832353fa72b4254382d9edb Mon Sep 17 00:00:00 2001
From: Finlay Marno <finlay.marno at codeplay.com>
Date: Mon, 22 Jul 2024 17:12:38 +0100
Subject: [PATCH 4/5] amend! style fixes

[mlir] Added new attributes to the llvm.call op in llvmir target

The new attributes are:
 * convergent
 * no_unwind
 * will_return
 * memory effects
---
 .../LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp     | 6 ++----
 mlir/lib/Target/LLVMIR/ModuleImport.cpp                   | 8 +++-----
 2 files changed, 5 insertions(+), 9 deletions(-)

diff --git a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
index 2d3d8ede39765..8837c19b48588 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
@@ -226,9 +226,8 @@ convertOperationImpl(Operation &opInst, llvm::IRBuilderBase &builder,
     if (callOp.getWillReturnAttr())
       call->addFnAttr(llvm::Attribute::WillReturn);
 
-    // memory effects
     if (MemoryEffectsAttr memAttr = callOp.getMemoryAttr()) {
-      llvm::MemoryEffects newMemEffects =
+      llvm::MemoryEffects memEffects =
           llvm::MemoryEffects(llvm::MemoryEffects::Location::ArgMem,
                               convertModRefInfoToLLVM(memAttr.getArgMem())) |
           llvm::MemoryEffects(
@@ -236,8 +235,7 @@ convertOperationImpl(Operation &opInst, llvm::IRBuilderBase &builder,
               convertModRefInfoToLLVM(memAttr.getInaccessibleMem())) |
           llvm::MemoryEffects(llvm::MemoryEffects::Location::Other,
                               convertModRefInfoToLLVM(memAttr.getOther()));
-
-      call->setMemoryEffects(newMemEffects);
+      call->setMemoryEffects(memEffects);
     }
 
     moduleTranslation.setAccessGroupsMetadata(callOp, call);
diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
index 490a1fec40a99..42e9b66a6a2ac 100644
--- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
@@ -1472,7 +1472,7 @@ LogicalResult ModuleImport::convertInstruction(llvm::Instruction *inst) {
         convertTailCallKindFromLLVM(callInst->getTailCallKind()));
     setFastmathFlagsAttr(inst, callOp);
 
-    // handle function attrs
+    // Handle function attributes.
     if (callInst->hasFnAttr(llvm::Attribute::Convergent))
       callOp.setConvergent(true);
     if (callInst->hasFnAttr(llvm::Attribute::NoUnwind))
@@ -1480,7 +1480,6 @@ LogicalResult ModuleImport::convertInstruction(llvm::Instruction *inst) {
     if (callInst->hasFnAttr(llvm::Attribute::WillReturn))
       callOp.setWillReturn(true);
 
-    // memory effects
     llvm::MemoryEffects memEffects = callInst->getMemoryEffects();
     ModRefInfo othermem = convertModRefInfoFromLLVM(
         memEffects.getModRef(llvm::MemoryEffects::Location::Other));
@@ -1490,10 +1489,9 @@ LogicalResult ModuleImport::convertInstruction(llvm::Instruction *inst) {
         memEffects.getModRef(llvm::MemoryEffects::Location::InaccessibleMem));
     auto memAttr = MemoryEffectsAttr::get(callOp.getContext(), othermem, argMem,
                                           inaccessibleMem);
-    // Only set the attr when it does not match the default value.
-    if (!memAttr.isReadWrite()) {
+    // Only set the attribute when it does not match the default value.
+    if (!memAttr.isReadWrite())
       callOp.setMemoryAttr(memAttr);
-    }
 
     if (!callInst->getType()->isVoidTy())
       mapValue(inst, callOp.getResult());

>From be2c24024503cb1501088243be02a13bc7988cd6 Mon Sep 17 00:00:00 2001
From: Finlay Marno <finlay.marno at codeplay.com>
Date: Tue, 23 Jul 2024 11:09:06 +0100
Subject: [PATCH 5/5] amend! format

[mlir] Added new attributes to the llvm.call op in llvmir target

The new attributes are:
 * convergent
 * no_unwind
 * will_return
 * memory effects
---
 mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index 45457ea4cc8ef..f0ac45be4b9e8 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -982,7 +982,7 @@ void CallOp::build(OpBuilder &builder, OperationState &state, TypeRange results,
         /*var_callee_type=*/nullptr, callee, args, /*fastmathFlags=*/nullptr,
         /*branch_weights=*/nullptr,
         /*CConv=*/nullptr, /*TailCallKind=*/nullptr,
-/*memory=*/nullptr,
+        /*memory=*/nullptr,
         /*convergent=*/nullptr, /*no_unwind=*/nullptr, /*will_return=*/nullptr,
         /*access_groups=*/nullptr, /*alias_scopes=*/nullptr,
         /*noalias_scopes=*/nullptr, /*tbaa=*/nullptr);
@@ -1227,7 +1227,7 @@ void CallOp::print(OpAsmPrinter &p) {
   if (getCConv() != LLVM::CConv::C)
     p << stringifyCConv(getCConv()) << ' ';
 
-  if(getTailCallKind() != LLVM::TailCallKind::None)
+  if (getTailCallKind() != LLVM::TailCallKind::None)
     p << tailcallkind::stringifyTailCallKind(getTailCallKind()) << ' ';
 
   // Print the direct callee if present as a function attribute, or an indirect



More information about the Mlir-commits mailing list