[Mlir-commits] [mlir] 76cf140 - [MLIR] Added llvm.fence
Alex Zinenko
llvmlistbot at llvm.org
Tue Mar 17 09:53:45 PDT 2020
Author: Sagar Jain
Date: 2020-03-17T17:53:37+01:00
New Revision: 76cf14035be346ad7f8f9fef334fbc03fc11bd33
URL: https://github.com/llvm/llvm-project/commit/76cf14035be346ad7f8f9fef334fbc03fc11bd33
DIFF: https://github.com/llvm/llvm-project/commit/76cf14035be346ad7f8f9fef334fbc03fc11bd33.diff
LOG: [MLIR] Added llvm.fence
This patch adds llvm.fence. I tried not to change the syntax much.
syntax:
LLVM IR
`fence [syncscope("<target-scope>")] <ordering>`
MLIR LLVM Dialect
`llvm.fence [syncscope("<target-scope>")] <ordering>`
example:
LLVM IR: `fence syncscope("agent") seq_cst`
MLIR: `llvm.fence syncscope("agent") seq_cst`
Differential Revision: https://reviews.llvm.org/D75645
Added:
Modified:
mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp
mlir/test/Dialect/LLVMIR/invalid.mlir
mlir/test/Dialect/LLVMIR/roundtrip.mlir
mlir/test/Target/import.ll
mlir/test/Target/llvmir.mlir
Removed:
################################################################################
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
index c702ed8d2fca..c495dfd7c903 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
@@ -943,4 +943,16 @@ def LLVM_AssumeOp : LLVM_Op<"intr.assume", []>,
}];
}
+def LLVM_FenceOp : LLVM_ZeroResultOp<"fence", []>,
+ Arguments<(ins AtomicOrdering:$ordering,
+ StrAttr:$syncscope)> {
+ let llvmBuilder = [{
+ llvm::LLVMContext &llvmContext = builder.getContext();
+ builder.CreateFence(getLLVMAtomicOrdering($ordering),
+ llvmContext.getOrInsertSyncScopeID($syncscope));
+ }];
+ let parser = [{ return parseFenceOp(parser, result); }];
+ let printer = [{ printFenceOp(p, *this); }];
+ let verifier = "return ::verify(*this);";
+}
#endif // LLVMIR_OPS
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index 7a15d579127d..2a2e6699fee5 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -1567,6 +1567,47 @@ static LogicalResult verify(AtomicCmpXchgOp op) {
return success();
}
+//===----------------------------------------------------------------------===//
+// Printer, parser and verifier for LLVM::FenceOp.
+//===----------------------------------------------------------------------===//
+
+// <operation> ::= `llvm.fence` (`syncscope(`strAttr`)`)? keyword
+// attribute-dict?
+static ParseResult parseFenceOp(OpAsmParser &parser, OperationState &result) {
+ StringAttr sScope;
+ StringRef syncscopeKeyword = "syncscope";
+ if (!failed(parser.parseOptionalKeyword(syncscopeKeyword))) {
+ if (parser.parseLParen() ||
+ parser.parseAttribute(sScope, syncscopeKeyword, result.attributes) ||
+ parser.parseRParen())
+ return failure();
+ } else {
+ result.addAttribute(syncscopeKeyword,
+ parser.getBuilder().getStringAttr(""));
+ }
+ if (parseAtomicOrdering(parser, result, "ordering") ||
+ parser.parseOptionalAttrDict(result.attributes))
+ return failure();
+ return success();
+}
+
+static void printFenceOp(OpAsmPrinter &p, FenceOp &op) {
+ StringRef syncscopeKeyword = "syncscope";
+ p << op.getOperationName() << ' ';
+ if (!op.getAttr(syncscopeKeyword).cast<StringAttr>().getValue().empty())
+ p << "syncscope(" << op.getAttr(syncscopeKeyword) << ") ";
+ p << stringifyAtomicOrdering(op.ordering());
+}
+
+static LogicalResult verify(FenceOp &op) {
+ if (op.ordering() == AtomicOrdering::not_atomic ||
+ op.ordering() == AtomicOrdering::unordered ||
+ op.ordering() == AtomicOrdering::monotonic)
+ return op.emitOpError("can be given only acquire, release, acq_rel, "
+ "and seq_cst orderings");
+ return success();
+}
+
//===----------------------------------------------------------------------===//
// LLVMDialect initialization, type parsing, and registration.
//===----------------------------------------------------------------------===//
diff --git a/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp b/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp
index 6a774acdf6bf..86351bd689ad 100644
--- a/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp
+++ b/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp
@@ -485,8 +485,7 @@ static const DenseMap<unsigned, StringRef> opcMap = {
INST(Or, Or), INST(Xor, XOr), INST(Alloca, Alloca), INST(Load, Load),
INST(Store, Store),
// Getelementptr is handled specially.
- INST(Ret, Return),
- // FIXME: fence
+ INST(Ret, Return), INST(Fence, Fence),
// FIXME: atomiccmpxchg
// FIXME: atomicrmw
INST(Trunc, Trunc), INST(ZExt, ZExt), INST(SExt, SExt),
@@ -539,6 +538,26 @@ static ICmpPredicate getICmpPredicate(llvm::CmpInst::Predicate p) {
llvm_unreachable("incorrect comparison predicate");
}
+static AtomicOrdering getLLVMAtomicOrdering(llvm::AtomicOrdering ordering) {
+ switch (ordering) {
+ case llvm::AtomicOrdering::NotAtomic:
+ return LLVM::AtomicOrdering::not_atomic;
+ case llvm::AtomicOrdering::Unordered:
+ return LLVM::AtomicOrdering::unordered;
+ case llvm::AtomicOrdering::Monotonic:
+ return LLVM::AtomicOrdering::monotonic;
+ case llvm::AtomicOrdering::Acquire:
+ return LLVM::AtomicOrdering::acquire;
+ case llvm::AtomicOrdering::Release:
+ return LLVM::AtomicOrdering::release;
+ case llvm::AtomicOrdering::AcquireRelease:
+ return LLVM::AtomicOrdering::acq_rel;
+ case llvm::AtomicOrdering::SequentiallyConsistent:
+ return LLVM::AtomicOrdering::seq_cst;
+ }
+ llvm_unreachable("incorrect atomic ordering");
+}
+
// `br` branches to `target`. Return the branch arguments to `br`, in the
// same order of the PHIs in `target`.
LogicalResult
@@ -743,6 +762,23 @@ LogicalResult Importer::processInstruction(llvm::Instruction *inst) {
v = op->getResult(0);
return success();
}
+ case llvm::Instruction::Fence: {
+ StringRef syncscope;
+ SmallVector<StringRef, 4> ssNs;
+ llvm::LLVMContext &llvmContext = dialect->getLLVMContext();
+ llvm::FenceInst *fence = cast<llvm::FenceInst>(inst);
+ llvmContext.getSyncScopeNames(ssNs);
+ int fenceSyncScopeID = fence->getSyncScopeID();
+ for (unsigned i = 0, e = ssNs.size(); i != e; i++) {
+ if (fenceSyncScopeID == llvmContext.getOrInsertSyncScopeID(ssNs[i])) {
+ syncscope = ssNs[i];
+ break;
+ }
+ }
+ b.create<FenceOp>(loc, getLLVMAtomicOrdering(fence->getOrdering()),
+ syncscope);
+ return success();
+ }
case llvm::Instruction::GetElementPtr: {
// FIXME: Support inbounds GEPs.
llvm::GetElementPtrInst *gep = cast<llvm::GetElementPtrInst>(inst);
diff --git a/mlir/test/Dialect/LLVMIR/invalid.mlir b/mlir/test/Dialect/LLVMIR/invalid.mlir
index eaee62ef8324..03de594083dd 100644
--- a/mlir/test/Dialect/LLVMIR/invalid.mlir
+++ b/mlir/test/Dialect/LLVMIR/invalid.mlir
@@ -561,3 +561,10 @@ llvm.func @caller(%arg0: !llvm.i32) -> !llvm.i32 {
%2 = llvm.landingpad : !llvm<"{ i8*, i32 }">
llvm.return %0 : !llvm.i32
}
+
+// -----
+
+func @invalid_ordering_in_fence() {
+ // expected-error @+1 {{can be given only acquire, release, acq_rel, and seq_cst orderings}}
+ llvm.fence syncscope("agent") monotonic
+}
diff --git a/mlir/test/Dialect/LLVMIR/roundtrip.mlir b/mlir/test/Dialect/LLVMIR/roundtrip.mlir
index 8a8de4cf6f21..32fe4c496523 100644
--- a/mlir/test/Dialect/LLVMIR/roundtrip.mlir
+++ b/mlir/test/Dialect/LLVMIR/roundtrip.mlir
@@ -292,4 +292,15 @@ func @useFreezeOp(%arg0: !llvm.i32) {
// CHECK: = llvm.freeze %[[x]] : !llvm.i8
%2 = llvm.freeze %1 : !llvm.i8
return
+}
+
+// CHECK-LABEL: @useFenceInst
+func @useFenceInst() {
+ // CHECK: syncscope("agent") seq_cst
+ llvm.fence syncscope("agent") seq_cst
+ // CHECK: seq_cst
+ llvm.fence syncscope("") seq_cst
+ // CHECK: release
+ llvm.fence release
+ return
}
\ No newline at end of file
diff --git a/mlir/test/Target/import.ll b/mlir/test/Target/import.ll
index 5e38b6b2fe7d..0394309093f2 100644
--- a/mlir/test/Target/import.ll
+++ b/mlir/test/Target/import.ll
@@ -307,4 +307,15 @@ define i32 @useFreezeOp(i32 %x) {
%3 = freeze i8 %2
%poison = add nsw i1 0, undef
ret i32 0
+}
+
+;CHECK-LABEL: @useFenceInst
+define i32 @useFenceInst() {
+ ;CHECK: llvm.fence syncscope("agent") seq_cst
+ fence syncscope("agent") seq_cst
+ ;CHECK: llvm.fence release
+ fence release
+ ;CHECK: llvm.fence seq_cst
+ fence syncscope("") seq_cst
+ ret i32 0
}
\ No newline at end of file
diff --git a/mlir/test/Target/llvmir.mlir b/mlir/test/Target/llvmir.mlir
index 7f202b39a471..43cc7d804dae 100644
--- a/mlir/test/Target/llvmir.mlir
+++ b/mlir/test/Target/llvmir.mlir
@@ -1190,3 +1190,14 @@ llvm.func @boolConstArg() -> !llvm.i1 {
%2 = llvm.and %0, %1 : !llvm.i1
llvm.return %2 : !llvm.i1
}
+
+// CHECK-LABEL: @callFenceInst
+llvm.func @callFenceInst() {
+ // CHECK: fence syncscope("agent") release
+ llvm.fence syncscope("agent") release
+ // CHECK: fence release
+ llvm.fence release
+ // CHECK: fence release
+ llvm.fence syncscope("") release
+ llvm.return
+}
\ No newline at end of file
More information about the Mlir-commits
mailing list