[Mlir-commits] [mlir] fde27bd - [mlir] Added new attributes to the llvm.call op in llvmir target (#99663)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Tue Jul 23 03:44:17 PDT 2024
Author: Finlay
Date: 2024-07-23T12:44:13+02:00
New Revision: fde27bd221c3ba011918a50bc2a47130959d33b7
URL: https://github.com/llvm/llvm-project/commit/fde27bd221c3ba011918a50bc2a47130959d33b7
DIFF: https://github.com/llvm/llvm-project/commit/fde27bd221c3ba011918a50bc2a47130959d33b7.diff
LOG: [mlir] Added new attributes to the llvm.call op in llvmir target (#99663)
The new attributes are:
* convergent
* no_unwind
* will_return
* memory effects
Added:
Modified:
mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
mlir/lib/Target/LLVMIR/ModuleImport.cpp
mlir/test/Dialect/LLVMIR/roundtrip.mlir
mlir/test/Target/LLVMIR/Import/instructions.ll
mlir/test/Target/LLVMIR/llvmir.mlir
Removed:
################################################################################
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..f0ac45be4b9e8 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);
}
@@ -1221,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
diff --git a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
index 3d6dd1247b413..8837c19b48588 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
@@ -219,6 +219,25 @@ 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);
+
+ if (MemoryEffectsAttr memAttr = callOp.getMemoryAttr()) {
+ llvm::MemoryEffects memEffects =
+ 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(memEffects);
+ }
+
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..42e9b66a6a2ac 100644
--- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
@@ -1471,6 +1471,28 @@ LogicalResult ModuleImport::convertInstruction(llvm::Instruction *inst) {
callOp.setTailCallKind(
convertTailCallKindFromLLVM(callInst->getTailCallKind()));
setFastmathFlagsAttr(inst, callOp);
+
+ // Handle function attributes.
+ 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);
+
+ llvm::MemoryEffects memEffects = callInst->getMemoryEffects();
+ ModRefInfo othermem = convertModRefInfoFromLLVM(
+ memEffects.getModRef(llvm::MemoryEffects::Location::Other));
+ ModRefInfo argMem = convertModRefInfoFromLLVM(
+ memEffects.getModRef(llvm::MemoryEffects::Location::ArgMem));
+ ModRefInfo inaccessibleMem = convertModRefInfoFromLLVM(
+ memEffects.getModRef(llvm::MemoryEffects::Location::InaccessibleMem));
+ auto memAttr = MemoryEffectsAttr::get(callOp.getContext(), othermem, argMem,
+ inaccessibleMem);
+ // 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());
else
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/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] }
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)
More information about the Mlir-commits
mailing list