// Atomic Operations
//===----------------------------------------------------------------------===//
-def AtomicBinOpXchg : I64EnumAttrCase<"xchg", 0>;
-def AtomicBinOpAdd : I64EnumAttrCase<"add", 1>;
-def AtomicBinOpSub : I64EnumAttrCase<"sub", 2>;
-def AtomicBinOpAnd : I64EnumAttrCase<"_and", 3>;
-def AtomicBinOpNand : I64EnumAttrCase<"nand", 4>;
-def AtomicBinOpOr : I64EnumAttrCase<"_or", 5>;
-def AtomicBinOpXor : I64EnumAttrCase<"_xor", 6>;
-def AtomicBinOpMax : I64EnumAttrCase<"max", 7>;
-def AtomicBinOpMin : I64EnumAttrCase<"min", 8>;
-def AtomicBinOpUMax : I64EnumAttrCase<"umax", 9>;
-def AtomicBinOpUMin : I64EnumAttrCase<"umin", 10>;
-def AtomicBinOpFAdd : I64EnumAttrCase<"fadd", 11>;
-def AtomicBinOpFSub : I64EnumAttrCase<"fsub", 12>;
-def AtomicBinOp : I64EnumAttr<
+def AtomicBinOpXchg : LLVM_EnumAttrCase<"xchg", "xchg", "Xchg", 0>;
+def AtomicBinOpAdd : LLVM_EnumAttrCase<"add", "add", "Add", 1>;
+def AtomicBinOpSub : LLVM_EnumAttrCase<"sub", "sub", "Sub", 2>;
+def AtomicBinOpAnd : LLVM_EnumAttrCase<"_and", "_and", "And", 3>;
+def AtomicBinOpNand : LLVM_EnumAttrCase<"nand", "nand", "Nand", 4>;
+def AtomicBinOpOr : LLVM_EnumAttrCase<"_or", "_or", "Or", 5>;
+def AtomicBinOpXor : LLVM_EnumAttrCase<"_xor", "_xor", "Xor", 6>;
+def AtomicBinOpMax : LLVM_EnumAttrCase<"max", "max", "Max", 7>;
+def AtomicBinOpMin : LLVM_EnumAttrCase<"min", "min", "Min", 8>;
+def AtomicBinOpUMax : LLVM_EnumAttrCase<"umax", "umax", "UMax", 9>;
+def AtomicBinOpUMin : LLVM_EnumAttrCase<"umin", "umin", "UMin", 10>;
+def AtomicBinOpFAdd : LLVM_EnumAttrCase<"fadd", "fadd", "FAdd", 11>;
+def AtomicBinOpFSub : LLVM_EnumAttrCase<"fsub", "fsub", "FSub", 12>;
+def AtomicBinOpFMax : LLVM_EnumAttrCase<"fmax", "fmax", "FMax", 13>;
+def AtomicBinOpFMin : LLVM_EnumAttrCase<"fmin", "fmin", "FMin", 14>;
+def AtomicBinOpUIncWrap : LLVM_EnumAttrCase<"uinc_wrap",
+ "uinc_wrap", "UIncWrap", 15>;
+def AtomicBinOpUDecWrap : LLVM_EnumAttrCase<"udec_wrap",
+ "udec_wrap", "UDecWrap", 16>;
+
+// A sentinel value that has no MLIR counterpart.
+def AtomicBadBinOp : LLVM_EnumAttrCase<"", "", "BAD_BINOP", 0>;
+
+def AtomicBinOp : LLVM_EnumAttr<
"AtomicBinOp",
+ "::llvm::AtomicRMWInst::BinOp",
"llvm.atomicrmw binary operations",
[AtomicBinOpXchg, AtomicBinOpAdd, AtomicBinOpSub, AtomicBinOpAnd,
AtomicBinOpNand, AtomicBinOpOr, AtomicBinOpXor, AtomicBinOpMax,
AtomicBinOpMin, AtomicBinOpUMax, AtomicBinOpUMin, AtomicBinOpFAdd,
- AtomicBinOpFSub]> {
+ AtomicBinOpFSub, AtomicBinOpFMax, AtomicBinOpFMin, AtomicBinOpUIncWrap,
+ AtomicBinOpUDecWrap],
+ [AtomicBadBinOp]> {
let cppNamespace = "::mlir::LLVM";
}
-def AtomicOrderingNotAtomic : I64EnumAttrCase<"not_atomic", 0>;
-def AtomicOrderingUnordered : I64EnumAttrCase<"unordered", 1>;
-def AtomicOrderingMonotonic : I64EnumAttrCase<"monotonic", 2>;
-def AtomicOrderingAcquire : I64EnumAttrCase<"acquire", 4>;
-def AtomicOrderingRelease : I64EnumAttrCase<"release", 5>;
-def AtomicOrderingAcquireRelease : I64EnumAttrCase<"acq_rel", 6>;
-def AtomicOrderingSequentiallyConsistent : I64EnumAttrCase<"seq_cst", 7>;
-def AtomicOrdering : I64EnumAttr<
+def AtomicOrderingNotAtomic : LLVM_EnumAttrCase<"not_atomic",
+ "not_atomic", "NotAtomic", 0>;
+def AtomicOrderingUnordered : LLVM_EnumAttrCase<"unordered",
+ "unordered", "Unordered", 1>;
+def AtomicOrderingMonotonic : LLVM_EnumAttrCase<"monotonic",
+ "monotonic", "Monotonic", 2>;
+def AtomicOrderingAcquire : LLVM_EnumAttrCase<"acquire",
+ "acquire", "Acquire", 4>;
+def AtomicOrderingRelease : LLVM_EnumAttrCase<"release",
+ "release", "Release", 5>;
+def AtomicOrderingAcquireRelease :
+ LLVM_EnumAttrCase<"acq_rel", "acq_rel", "AcquireRelease", 6>;
+def AtomicOrderingSequentiallyConsistent :
+ LLVM_EnumAttrCase<"seq_cst", "seq_cst", "SequentiallyConsistent", 7>;
+def AtomicOrdering : LLVM_EnumAttr<
"AtomicOrdering",
+ "::llvm::AtomicOrdering",
"Atomic ordering for LLVM's memory model",
[AtomicOrderingNotAtomic, AtomicOrderingUnordered, AtomicOrderingMonotonic,
AtomicOrderingAcquire, AtomicOrderingRelease, AtomicOrderingAcquireRelease,
- AtomicOrderingSequentiallyConsistent]> {
+ AtomicOrderingSequentiallyConsistent
+ ]> {
let cppNamespace = "::mlir::LLVM";
}
}
//===----------------------------------------------------------------------===//
-// FCmp Predicates
+// FCmp and ICmp Predicates
//===----------------------------------------------------------------------===//
-// Predicate for float comparisons
-def FCmpPredicateFALSE : I64EnumAttrCase<"_false", 0>;
-def FCmpPredicateOEQ : I64EnumAttrCase<"oeq", 1>;
-def FCmpPredicateOGT : I64EnumAttrCase<"ogt", 2>;
-def FCmpPredicateOGE : I64EnumAttrCase<"oge", 3>;
-def FCmpPredicateOLT : I64EnumAttrCase<"olt", 4>;
-def FCmpPredicateOLE : I64EnumAttrCase<"ole", 5>;
-def FCmpPredicateONE : I64EnumAttrCase<"one", 6>;
-def FCmpPredicateORD : I64EnumAttrCase<"ord", 7>;
-def FCmpPredicateUEQ : I64EnumAttrCase<"ueq", 8>;
-def FCmpPredicateUGT : I64EnumAttrCase<"ugt", 9>;
-def FCmpPredicateUGE : I64EnumAttrCase<"uge", 10>;
-def FCmpPredicateULT : I64EnumAttrCase<"ult", 11>;
-def FCmpPredicateULE : I64EnumAttrCase<"ule", 12>;
-def FCmpPredicateUNE : I64EnumAttrCase<"une", 13>;
-def FCmpPredicateUNO : I64EnumAttrCase<"uno", 14>;
-def FCmpPredicateTRUE : I64EnumAttrCase<"_true", 15>;
-
-def FCmpPredicate : I64EnumAttr<
+// Predicates for float comparisons
+def FCmpPredicateFALSE : LLVM_EnumAttrCase<"_false", "_false", "FCMP_FALSE", 0>;
+def FCmpPredicateOEQ : LLVM_EnumAttrCase<"oeq", "oeq", "FCMP_OEQ", 1>;
+def FCmpPredicateOGT : LLVM_EnumAttrCase<"ogt", "ogt", "FCMP_OGT", 2>;
+def FCmpPredicateOGE : LLVM_EnumAttrCase<"oge", "oge", "FCMP_OGE", 3>;
+def FCmpPredicateOLT : LLVM_EnumAttrCase<"olt", "olt", "FCMP_OLT", 4>;
+def FCmpPredicateOLE : LLVM_EnumAttrCase<"ole", "ole", "FCMP_OLE", 5>;
+def FCmpPredicateONE : LLVM_EnumAttrCase<"one", "one", "FCMP_ONE", 6>;
+def FCmpPredicateORD : LLVM_EnumAttrCase<"ord", "ord", "FCMP_ORD", 7>;
+def FCmpPredicateUEQ : LLVM_EnumAttrCase<"ueq", "ueq", "FCMP_UEQ", 8>;
+def FCmpPredicateUGT : LLVM_EnumAttrCase<"ugt", "ugt", "FCMP_UGT", 9>;
+def FCmpPredicateUGE : LLVM_EnumAttrCase<"uge", "uge", "FCMP_UGE", 10>;
+def FCmpPredicateULT : LLVM_EnumAttrCase<"ult", "ult", "FCMP_ULT", 11>;
+def FCmpPredicateULE : LLVM_EnumAttrCase<"ule", "ule", "FCMP_ULE", 12>;
+def FCmpPredicateUNE : LLVM_EnumAttrCase<"une", "une", "FCMP_UNE", 13>;
+def FCmpPredicateUNO : LLVM_EnumAttrCase<"uno", "uno", "FCMP_UNO", 14>;
+def FCmpPredicateTRUE : LLVM_EnumAttrCase<"_true", "_true", "FCMP_TRUE", 15>;
+
+// A sentinel value that has no MLIR counterpart.
+def ICmpPredicateBad : LLVM_EnumAttrCase<"", "", "BAD_ICMP_PREDICATE", 0>;
+
+// Predicates for integer comparisons.
+def ICmpPredicateEQ : LLVM_EnumAttrCase<"eq", "eq", "ICMP_EQ", 0>;
+def ICmpPredicateNE : LLVM_EnumAttrCase<"ne", "ne", "ICMP_NE", 1>;
+def ICmpPredicateSLT : LLVM_EnumAttrCase<"slt", "slt", "ICMP_SLT", 2>;
+def ICmpPredicateSLE : LLVM_EnumAttrCase<"sle", "sle", "ICMP_SLE", 3>;
+def ICmpPredicateSGT : LLVM_EnumAttrCase<"sgt", "sgt", "ICMP_SGT", 4>;
+def ICmpPredicateSGE : LLVM_EnumAttrCase<"sge", "sge", "ICMP_SGE", 5>;
+def ICmpPredicateULT : LLVM_EnumAttrCase<"ult", "ult", "ICMP_ULT", 6>;
+def ICmpPredicateULE : LLVM_EnumAttrCase<"ule", "ule", "ICMP_ULE", 7>;
+def ICmpPredicateUGT : LLVM_EnumAttrCase<"ugt", "ugt", "ICMP_UGT", 8>;
+def ICmpPredicateUGE : LLVM_EnumAttrCase<"uge", "uge", "ICMP_UGE", 9>;
+
+// A sentinel value that has no MLIR counterpart.
+def FCmpPredicateBad : LLVM_EnumAttrCase<"", "", "BAD_FCMP_PREDICATE", 0>;
+
+// LLVM's predicate enum contains the floating-point and integer comparison
+// cases, while the LLVM dialect uses two separate enums. The floating-point
+// predicate enum thus defines all integer predicates as unsupported and
+// vice versa.
+def FCmpPredicate : LLVM_EnumAttr<
"FCmpPredicate",
+ "::llvm::CmpInst::Predicate",
"llvm.fcmp comparison predicate",
[FCmpPredicateFALSE, FCmpPredicateOEQ, FCmpPredicateOGT, FCmpPredicateOGE,
FCmpPredicateOLT, FCmpPredicateOLE, FCmpPredicateONE, FCmpPredicateORD,
FCmpPredicateUEQ, FCmpPredicateUGT, FCmpPredicateUGE, FCmpPredicateULT,
- FCmpPredicateULE, FCmpPredicateUNE, FCmpPredicateUNO, FCmpPredicateTRUE
+ FCmpPredicateULE, FCmpPredicateUNE, FCmpPredicateUNO, FCmpPredicateTRUE],
+ [ICmpPredicateEQ, ICmpPredicateNE, ICmpPredicateSLT, ICmpPredicateSLE,
+ ICmpPredicateSGT, ICmpPredicateSGE, ICmpPredicateULT, ICmpPredicateULE,
+ ICmpPredicateUGT, ICmpPredicateUGE, FCmpPredicateBad, ICmpPredicateBad
]> {
let cppNamespace = "::mlir::LLVM";
}
-//===----------------------------------------------------------------------===//
-// ICmp Predicates
-//===----------------------------------------------------------------------===//
-
-// Predicate for integer comparisons.
-def ICmpPredicateEQ : I64EnumAttrCase<"eq", 0>;
-def ICmpPredicateNE : I64EnumAttrCase<"ne", 1>;
-def ICmpPredicateSLT : I64EnumAttrCase<"slt", 2>;
-def ICmpPredicateSLE : I64EnumAttrCase<"sle", 3>;
-def ICmpPredicateSGT : I64EnumAttrCase<"sgt", 4>;
-def ICmpPredicateSGE : I64EnumAttrCase<"sge", 5>;
-def ICmpPredicateULT : I64EnumAttrCase<"ult", 6>;
-def ICmpPredicateULE : I64EnumAttrCase<"ule", 7>;
-def ICmpPredicateUGT : I64EnumAttrCase<"ugt", 8>;
-def ICmpPredicateUGE : I64EnumAttrCase<"uge", 9>;
-def ICmpPredicate : I64EnumAttr<
+def ICmpPredicate : LLVM_EnumAttr<
"ICmpPredicate",
- "llvm.icmp comparison predicate",
+ "::llvm::CmpInst::Predicate",
+ "lvm.icmp comparison predicate",
[ICmpPredicateEQ, ICmpPredicateNE, ICmpPredicateSLT, ICmpPredicateSLE,
ICmpPredicateSGT, ICmpPredicateSGE, ICmpPredicateULT, ICmpPredicateULE,
- ICmpPredicateUGT, ICmpPredicateUGE]> {
+ ICmpPredicateUGT, ICmpPredicateUGE],
+ [FCmpPredicateFALSE, FCmpPredicateOEQ, FCmpPredicateOGT, FCmpPredicateOGE,
+ FCmpPredicateOLT, FCmpPredicateOLE, FCmpPredicateONE, FCmpPredicateORD,
+ FCmpPredicateUEQ, FCmpPredicateUGT, FCmpPredicateUGE, FCmpPredicateULT,
+ FCmpPredicateULE, FCmpPredicateUNE, FCmpPredicateUNO, FCmpPredicateTRUE,
+ FCmpPredicateBad, ICmpPredicateBad
+ ]> {
let cppNamespace = "::mlir::LLVM";
}
// - `name`: name of the C++ enum class in MLIR API;
// - `llvmName`: name of the C++ enum in LLVM API;
// - `description`: textual description for documentation purposes;
-// - `cases`: list of enum cases.
+// - `cases`: list of enum cases;
+// - `unsupportedCases`: optional list of unsupported enum cases.
// For example, `LLVM_EnumAttr<Linkage, "::llvm::GlobalValue::LinkageTypes`
// produces `mlir::LLVM::Linkage` enum class in MLIR API that corresponds to (a
// subset of) values in the `llvm::GlobalValue::LinkageTypes` in LLVM API.
+// All unsupported cases are excluded from the MLIR enum and trigger an error
+// during the import from LLVM IR. They are useful to handle sentinel values
+// such as `llvm::AtomicRMWInst::BinOp::BAD_BINOP` that LLVM commonly uses to
+// terminate its enums.
class LLVM_EnumAttr<string name, string llvmName, string description,
- list<LLVM_EnumAttrCase> cases> :
+ list<LLVM_EnumAttrCase> cases,
+ list<LLVM_EnumAttrCase> unsupportedCases = []> :
I64EnumAttr<name, description, cases> {
+
+ // List of unsupported cases that have no conversion to an MLIR value.
+ list<LLVM_EnumAttrCase> unsupported = unsupportedCases;
+
// The equivalent enum class name in LLVM.
string llvmClassName = llvmName;
}
let hasCustomAssemblyFormat = 1;
string llvmInstName = "ICmp";
string llvmBuilder = [{
- $res = builder.CreateICmp(getLLVMCmpPredicate($predicate), $lhs, $rhs);
+ $res = builder.CreateICmp(
+ convertICmpPredicateToLLVM($predicate), $lhs, $rhs);
}];
string mlirBuilder = [{
auto *iCmpInst = cast<llvm::ICmpInst>(inst);
- $res = $_builder.create<$_qualCppClassName>(
- $_location, getICmpPredicate(iCmpInst->getPredicate()), $lhs, $rhs);
+ $res = $_builder.create<$_qualCppClassName>($_location,
+ convertICmpPredicateFromLLVM(iCmpInst->getPredicate()), $lhs, $rhs);
}];
// Set the $predicate index to -1 to indicate there is no matching operand
// and decrement the following indices.
let hasCustomAssemblyFormat = 1;
string llvmInstName = "FCmp";
string llvmBuilder = [{
- $res = builder.CreateFCmp(getLLVMCmpPredicate($predicate), $lhs, $rhs);
+ $res = builder.CreateFCmp(convertFCmpPredicateToLLVM($predicate), $lhs, $rhs);
}];
string mlirBuilder = [{
auto *fCmpInst = cast<llvm::FCmpInst>(inst);
auto op = $_builder.create<$_qualCppClassName>(
- $_location, getFCmpPredicate(fCmpInst->getPredicate()), $lhs, $rhs);
+ $_location, convertFCmpPredicateFromLLVM(fCmpInst->getPredicate()), $lhs, $rhs);
moduleImport.setFastmathFlagsAttr(inst, op);
$res = op;
}];
}];
string llvmInstName = "AtomicRMW";
string llvmBuilder = [{
- $res = builder.CreateAtomicRMW(getLLVMAtomicBinOp($bin_op), $ptr, $val,
- llvm::MaybeAlign(),
- getLLVMAtomicOrdering($ordering));
+ $res = builder.CreateAtomicRMW(
+ convertAtomicBinOpToLLVM($bin_op), $ptr, $val, llvm::MaybeAlign(),
+ convertAtomicOrderingToLLVM($ordering));
}];
string mlirBuilder = [{
auto *atomicInst = cast<llvm::AtomicRMWInst>(inst);
$res = $_builder.create<LLVM::AtomicRMWOp>($_location, $_resultType,
- getLLVMAtomicBinOp(atomicInst->getOperation()), $ptr, $val,
- getLLVMAtomicOrdering(atomicInst->getOrdering()));
+ convertAtomicBinOpFromLLVM(atomicInst->getOperation()), $ptr, $val,
+ convertAtomicOrderingFromLLVM(atomicInst->getOrdering()));
}];
// Only $ptr and $val are llvm instruction operands.
list<int> llvmArgIndices = [-1, 0, 1, -1];
string llvmInstName = "AtomicCmpXchg";
string llvmBuilder = [{
$res = builder.CreateAtomicCmpXchg($ptr, $cmp, $val, llvm::MaybeAlign(),
- getLLVMAtomicOrdering($success_ordering),
- getLLVMAtomicOrdering($failure_ordering));
+ convertAtomicOrderingToLLVM($success_ordering),
+ convertAtomicOrderingToLLVM($failure_ordering));
}];
string mlirBuilder = [{
auto *cmpXchgInst = cast<llvm::AtomicCmpXchgInst>(inst);
$res = $_builder.create<LLVM::AtomicCmpXchgOp>(
$_location, $_resultType, $ptr, $cmp, $val,
- getLLVMAtomicOrdering(cmpXchgInst->getSuccessOrdering()),
- getLLVMAtomicOrdering(cmpXchgInst->getFailureOrdering()));
+ convertAtomicOrderingFromLLVM(cmpXchgInst->getSuccessOrdering()),
+ convertAtomicOrderingFromLLVM(cmpXchgInst->getFailureOrdering()));
}];
}
string llvmInstName = "Fence";
let llvmBuilder = [{
llvm::LLVMContext &llvmContext = builder.getContext();
- builder.CreateFence(getLLVMAtomicOrdering($ordering),
+ builder.CreateFence(convertAtomicOrderingToLLVM($ordering),
llvmContext.getOrInsertSyncScopeID($syncscope));
}];
string mlirBuilder = [{
llvm::FenceInst *fenceInst = cast<llvm::FenceInst>(inst);
$_op = $_builder.create<LLVM::FenceOp>(
$_location,
- getLLVMAtomicOrdering(fenceInst->getOrdering()),
+ convertAtomicOrderingFromLLVM(fenceInst->getOrdering()),
getLLVMSyncScope(fenceInst));
}];
let hasCustomAssemblyFormat = 1;
if (!ptrType.isOpaque() && valType != ptrType.getElementType())
return emitOpError("expected LLVM IR element type for operand #0 to "
"match type for operand #1");
- if (getBinOp() == AtomicBinOp::fadd || getBinOp() == AtomicBinOp::fsub) {
+ if (getBinOp() == AtomicBinOp::fadd || getBinOp() == AtomicBinOp::fsub ||
+ getBinOp() == AtomicBinOp::fmin || getBinOp() == AtomicBinOp::fmax) {
if (!mlir::LLVM::isCompatibleFloatingPointType(valType))
return emitOpError("expected LLVM IR floating point type");
} else if (getBinOp() == AtomicBinOp::xchg) {
#include "mlir/Dialect/LLVMIR/LLVMConversionEnumsToLLVM.inc"
-/// Convert MLIR integer comparison predicate to LLVM IR comparison predicate.
-static llvm::CmpInst::Predicate getLLVMCmpPredicate(ICmpPredicate p) {
- switch (p) {
- case LLVM::ICmpPredicate::eq:
- return llvm::CmpInst::Predicate::ICMP_EQ;
- case LLVM::ICmpPredicate::ne:
- return llvm::CmpInst::Predicate::ICMP_NE;
- case LLVM::ICmpPredicate::slt:
- return llvm::CmpInst::Predicate::ICMP_SLT;
- case LLVM::ICmpPredicate::sle:
- return llvm::CmpInst::Predicate::ICMP_SLE;
- case LLVM::ICmpPredicate::sgt:
- return llvm::CmpInst::Predicate::ICMP_SGT;
- case LLVM::ICmpPredicate::sge:
- return llvm::CmpInst::Predicate::ICMP_SGE;
- case LLVM::ICmpPredicate::ult:
- return llvm::CmpInst::Predicate::ICMP_ULT;
- case LLVM::ICmpPredicate::ule:
- return llvm::CmpInst::Predicate::ICMP_ULE;
- case LLVM::ICmpPredicate::ugt:
- return llvm::CmpInst::Predicate::ICMP_UGT;
- case LLVM::ICmpPredicate::uge:
- return llvm::CmpInst::Predicate::ICMP_UGE;
- }
- llvm_unreachable("incorrect comparison predicate");
-}
-
-static llvm::CmpInst::Predicate getLLVMCmpPredicate(FCmpPredicate p) {
- switch (p) {
- case LLVM::FCmpPredicate::_false:
- return llvm::CmpInst::Predicate::FCMP_FALSE;
- case LLVM::FCmpPredicate::oeq:
- return llvm::CmpInst::Predicate::FCMP_OEQ;
- case LLVM::FCmpPredicate::ogt:
- return llvm::CmpInst::Predicate::FCMP_OGT;
- case LLVM::FCmpPredicate::oge:
- return llvm::CmpInst::Predicate::FCMP_OGE;
- case LLVM::FCmpPredicate::olt:
- return llvm::CmpInst::Predicate::FCMP_OLT;
- case LLVM::FCmpPredicate::ole:
- return llvm::CmpInst::Predicate::FCMP_OLE;
- case LLVM::FCmpPredicate::one:
- return llvm::CmpInst::Predicate::FCMP_ONE;
- case LLVM::FCmpPredicate::ord:
- return llvm::CmpInst::Predicate::FCMP_ORD;
- case LLVM::FCmpPredicate::ueq:
- return llvm::CmpInst::Predicate::FCMP_UEQ;
- case LLVM::FCmpPredicate::ugt:
- return llvm::CmpInst::Predicate::FCMP_UGT;
- case LLVM::FCmpPredicate::uge:
- return llvm::CmpInst::Predicate::FCMP_UGE;
- case LLVM::FCmpPredicate::ult:
- return llvm::CmpInst::Predicate::FCMP_ULT;
- case LLVM::FCmpPredicate::ule:
- return llvm::CmpInst::Predicate::FCMP_ULE;
- case LLVM::FCmpPredicate::une:
- return llvm::CmpInst::Predicate::FCMP_UNE;
- case LLVM::FCmpPredicate::uno:
- return llvm::CmpInst::Predicate::FCMP_UNO;
- case LLVM::FCmpPredicate::_true:
- return llvm::CmpInst::Predicate::FCMP_TRUE;
- }
- llvm_unreachable("incorrect comparison predicate");
-}
-
-static llvm::AtomicRMWInst::BinOp getLLVMAtomicBinOp(AtomicBinOp op) {
- switch (op) {
- case LLVM::AtomicBinOp::xchg:
- return llvm::AtomicRMWInst::BinOp::Xchg;
- case LLVM::AtomicBinOp::add:
- return llvm::AtomicRMWInst::BinOp::Add;
- case LLVM::AtomicBinOp::sub:
- return llvm::AtomicRMWInst::BinOp::Sub;
- case LLVM::AtomicBinOp::_and:
- return llvm::AtomicRMWInst::BinOp::And;
- case LLVM::AtomicBinOp::nand:
- return llvm::AtomicRMWInst::BinOp::Nand;
- case LLVM::AtomicBinOp::_or:
- return llvm::AtomicRMWInst::BinOp::Or;
- case LLVM::AtomicBinOp::_xor:
- return llvm::AtomicRMWInst::BinOp::Xor;
- case LLVM::AtomicBinOp::max:
- return llvm::AtomicRMWInst::BinOp::Max;
- case LLVM::AtomicBinOp::min:
- return llvm::AtomicRMWInst::BinOp::Min;
- case LLVM::AtomicBinOp::umax:
- return llvm::AtomicRMWInst::BinOp::UMax;
- case LLVM::AtomicBinOp::umin:
- return llvm::AtomicRMWInst::BinOp::UMin;
- case LLVM::AtomicBinOp::fadd:
- return llvm::AtomicRMWInst::BinOp::FAdd;
- case LLVM::AtomicBinOp::fsub:
- return llvm::AtomicRMWInst::BinOp::FSub;
- }
- llvm_unreachable("incorrect atomic binary operator");
-}
-
-static llvm::AtomicOrdering getLLVMAtomicOrdering(AtomicOrdering ordering) {
- switch (ordering) {
- case LLVM::AtomicOrdering::not_atomic:
- return llvm::AtomicOrdering::NotAtomic;
- 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::acq_rel:
- return llvm::AtomicOrdering::AcquireRelease;
- case LLVM::AtomicOrdering::seq_cst:
- return llvm::AtomicOrdering::SequentiallyConsistent;
- }
- llvm_unreachable("incorrect atomic ordering");
-}
-
static llvm::FastMathFlags getFastmathFlags(FastmathFlagsInterface &op) {
using llvmFMF = llvm::FastMathFlags;
using FuncT = void (llvmFMF::*)(bool);
}
}
-static ICmpPredicate getICmpPredicate(llvm::CmpInst::Predicate pred) {
- switch (pred) {
- default:
- llvm_unreachable("incorrect comparison predicate");
- case llvm::CmpInst::Predicate::ICMP_EQ:
- return LLVM::ICmpPredicate::eq;
- case llvm::CmpInst::Predicate::ICMP_NE:
- return LLVM::ICmpPredicate::ne;
- case llvm::CmpInst::Predicate::ICMP_SLT:
- return LLVM::ICmpPredicate::slt;
- case llvm::CmpInst::Predicate::ICMP_SLE:
- return LLVM::ICmpPredicate::sle;
- case llvm::CmpInst::Predicate::ICMP_SGT:
- return LLVM::ICmpPredicate::sgt;
- case llvm::CmpInst::Predicate::ICMP_SGE:
- return LLVM::ICmpPredicate::sge;
- case llvm::CmpInst::Predicate::ICMP_ULT:
- return LLVM::ICmpPredicate::ult;
- case llvm::CmpInst::Predicate::ICMP_ULE:
- return LLVM::ICmpPredicate::ule;
- case llvm::CmpInst::Predicate::ICMP_UGT:
- return LLVM::ICmpPredicate::ugt;
- case llvm::CmpInst::Predicate::ICMP_UGE:
- return LLVM::ICmpPredicate::uge;
- }
- llvm_unreachable("incorrect integer comparison predicate");
-}
-
-static FCmpPredicate getFCmpPredicate(llvm::CmpInst::Predicate pred) {
- switch (pred) {
- default:
- llvm_unreachable("incorrect comparison predicate");
- case llvm::CmpInst::Predicate::FCMP_FALSE:
- return LLVM::FCmpPredicate::_false;
- case llvm::CmpInst::Predicate::FCMP_TRUE:
- return LLVM::FCmpPredicate::_true;
- case llvm::CmpInst::Predicate::FCMP_OEQ:
- return LLVM::FCmpPredicate::oeq;
- case llvm::CmpInst::Predicate::FCMP_ONE:
- return LLVM::FCmpPredicate::one;
- case llvm::CmpInst::Predicate::FCMP_OLT:
- return LLVM::FCmpPredicate::olt;
- case llvm::CmpInst::Predicate::FCMP_OLE:
- return LLVM::FCmpPredicate::ole;
- case llvm::CmpInst::Predicate::FCMP_OGT:
- return LLVM::FCmpPredicate::ogt;
- case llvm::CmpInst::Predicate::FCMP_OGE:
- return LLVM::FCmpPredicate::oge;
- case llvm::CmpInst::Predicate::FCMP_ORD:
- return LLVM::FCmpPredicate::ord;
- case llvm::CmpInst::Predicate::FCMP_ULT:
- return LLVM::FCmpPredicate::ult;
- case llvm::CmpInst::Predicate::FCMP_ULE:
- return LLVM::FCmpPredicate::ule;
- case llvm::CmpInst::Predicate::FCMP_UGT:
- return LLVM::FCmpPredicate::ugt;
- case llvm::CmpInst::Predicate::FCMP_UGE:
- return LLVM::FCmpPredicate::uge;
- case llvm::CmpInst::Predicate::FCMP_UNO:
- return LLVM::FCmpPredicate::uno;
- case llvm::CmpInst::Predicate::FCMP_UEQ:
- return LLVM::FCmpPredicate::ueq;
- case llvm::CmpInst::Predicate::FCMP_UNE:
- return LLVM::FCmpPredicate::une;
- }
- llvm_unreachable("incorrect floating point 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");
-}
-
-static AtomicBinOp getLLVMAtomicBinOp(llvm::AtomicRMWInst::BinOp binOp) {
- switch (binOp) {
- case llvm::AtomicRMWInst::Xchg:
- return LLVM::AtomicBinOp::xchg;
- case llvm::AtomicRMWInst::Add:
- return LLVM::AtomicBinOp::add;
- case llvm::AtomicRMWInst::Sub:
- return LLVM::AtomicBinOp::sub;
- case llvm::AtomicRMWInst::And:
- return LLVM::AtomicBinOp::_and;
- case llvm::AtomicRMWInst::Nand:
- return LLVM::AtomicBinOp::nand;
- case llvm::AtomicRMWInst::Or:
- return LLVM::AtomicBinOp::_or;
- case llvm::AtomicRMWInst::Xor:
- return LLVM::AtomicBinOp::_xor;
- case llvm::AtomicRMWInst::Max:
- return LLVM::AtomicBinOp::max;
- case llvm::AtomicRMWInst::Min:
- return LLVM::AtomicBinOp::min;
- case llvm::AtomicRMWInst::UMax:
- return LLVM::AtomicBinOp::umax;
- case llvm::AtomicRMWInst::UMin:
- return LLVM::AtomicBinOp::umin;
- case llvm::AtomicRMWInst::FAdd:
- return LLVM::AtomicBinOp::fadd;
- case llvm::AtomicRMWInst::FSub:
- return LLVM::AtomicBinOp::fsub;
- default:
- llvm_unreachable("unsupported atomic binary operation");
- }
-}
-
/// Converts the sync scope identifier of `fenceInst` to the string
/// representation necessary to build the LLVM dialect fence operation.
static StringRef getLLVMSyncScope(llvm::FenceInst *fenceInst) {
%12 = atomicrmw fadd ptr %ptr2, float %val2 acquire
; CHECK: llvm.atomicrmw fsub %[[PTR2]], %[[VAL2]] acquire
%13 = atomicrmw fsub ptr %ptr2, float %val2 acquire
+ ; CHECK: llvm.atomicrmw fmax %[[PTR2]], %[[VAL2]] acquire
+ %14 = atomicrmw fmax ptr %ptr2, float %val2 acquire
+ ; CHECK: llvm.atomicrmw fmin %[[PTR2]], %[[VAL2]] acquire
+ %15 = atomicrmw fmin ptr %ptr2, float %val2 acquire
+ ; CHECK: llvm.atomicrmw uinc_wrap %[[PTR1]], %[[VAL1]] acquire
+ %16 = atomicrmw uinc_wrap ptr %ptr1, i32 %val1 acquire
+ ; CHECK: llvm.atomicrmw udec_wrap %[[PTR1]], %[[VAL1]] acquire
+ %17 = atomicrmw udec_wrap ptr %ptr1, i32 %val1 acquire
ret void
}
%0 = llvm.atomicrmw fadd %f32_ptr, %f32 monotonic : !llvm.ptr<f32>, f32
// CHECK: atomicrmw fsub ptr %{{.*}}, float %{{.*}} monotonic
%1 = llvm.atomicrmw fsub %f32_ptr, %f32 monotonic : !llvm.ptr<f32>, f32
+ // CHECK: atomicrmw fmax ptr %{{.*}}, float %{{.*}} monotonic
+ %2 = llvm.atomicrmw fmax %f32_ptr, %f32 monotonic : !llvm.ptr<f32>, f32
+ // CHECK: atomicrmw fmin ptr %{{.*}}, float %{{.*}} monotonic
+ %3 = llvm.atomicrmw fmin %f32_ptr, %f32 monotonic : !llvm.ptr<f32>, f32
// CHECK: atomicrmw xchg ptr %{{.*}}, float %{{.*}} monotonic
- %2 = llvm.atomicrmw xchg %f32_ptr, %f32 monotonic : !llvm.ptr<f32>, f32
+ %4 = llvm.atomicrmw xchg %f32_ptr, %f32 monotonic : !llvm.ptr<f32>, f32
// CHECK: atomicrmw add ptr %{{.*}}, i32 %{{.*}} acquire
- %3 = llvm.atomicrmw add %i32_ptr, %i32 acquire : !llvm.ptr<i32>, i32
+ %5 = llvm.atomicrmw add %i32_ptr, %i32 acquire : !llvm.ptr<i32>, i32
// CHECK: atomicrmw sub ptr %{{.*}}, i32 %{{.*}} release
- %4 = llvm.atomicrmw sub %i32_ptr, %i32 release : !llvm.ptr<i32>, i32
+ %6 = llvm.atomicrmw sub %i32_ptr, %i32 release : !llvm.ptr<i32>, i32
// CHECK: atomicrmw and ptr %{{.*}}, i32 %{{.*}} acq_rel
- %5 = llvm.atomicrmw _and %i32_ptr, %i32 acq_rel : !llvm.ptr<i32>, i32
+ %7 = llvm.atomicrmw _and %i32_ptr, %i32 acq_rel : !llvm.ptr<i32>, i32
// CHECK: atomicrmw nand ptr %{{.*}}, i32 %{{.*}} seq_cst
- %6 = llvm.atomicrmw nand %i32_ptr, %i32 seq_cst : !llvm.ptr<i32>, i32
+ %8 = llvm.atomicrmw nand %i32_ptr, %i32 seq_cst : !llvm.ptr<i32>, i32
// CHECK: atomicrmw or ptr %{{.*}}, i32 %{{.*}} monotonic
- %7 = llvm.atomicrmw _or %i32_ptr, %i32 monotonic : !llvm.ptr<i32>, i32
+ %9 = llvm.atomicrmw _or %i32_ptr, %i32 monotonic : !llvm.ptr<i32>, i32
// CHECK: atomicrmw xor ptr %{{.*}}, i32 %{{.*}} monotonic
- %8 = llvm.atomicrmw _xor %i32_ptr, %i32 monotonic : !llvm.ptr<i32>, i32
+ %10 = llvm.atomicrmw _xor %i32_ptr, %i32 monotonic : !llvm.ptr<i32>, i32
// CHECK: atomicrmw max ptr %{{.*}}, i32 %{{.*}} monotonic
- %9 = llvm.atomicrmw max %i32_ptr, %i32 monotonic : !llvm.ptr<i32>, i32
+ %11 = llvm.atomicrmw max %i32_ptr, %i32 monotonic : !llvm.ptr<i32>, i32
// CHECK: atomicrmw min ptr %{{.*}}, i32 %{{.*}} monotonic
- %10 = llvm.atomicrmw min %i32_ptr, %i32 monotonic : !llvm.ptr<i32>, i32
+ %12 = llvm.atomicrmw min %i32_ptr, %i32 monotonic : !llvm.ptr<i32>, i32
// CHECK: atomicrmw umax ptr %{{.*}}, i32 %{{.*}} monotonic
- %11 = llvm.atomicrmw umax %i32_ptr, %i32 monotonic : !llvm.ptr<i32>, i32
+ %13 = llvm.atomicrmw umax %i32_ptr, %i32 monotonic : !llvm.ptr<i32>, i32
// CHECK: atomicrmw umin ptr %{{.*}}, i32 %{{.*}} monotonic
- %12 = llvm.atomicrmw umin %i32_ptr, %i32 monotonic : !llvm.ptr<i32>, i32
+ %14 = llvm.atomicrmw umin %i32_ptr, %i32 monotonic : !llvm.ptr<i32>, i32
+ // CHECK: atomicrmw uinc_wrap ptr %{{.*}}, i32 %{{.*}} monotonic
+ %15 = llvm.atomicrmw uinc_wrap %i32_ptr, %i32 monotonic : !llvm.ptr<i32>, i32
+ // CHECK: atomicrmw udec_wrap ptr %{{.*}}, i32 %{{.*}} monotonic
+ %16 = llvm.atomicrmw udec_wrap %i32_ptr, %i32 monotonic : !llvm.ptr<i32>, i32
llvm.return
}
return cases;
}
+
+ std::vector<LLVMEnumAttrCase> getAllUnsupportedCases() const {
+ const auto *inits = def->getValueAsListInit("unsupported");
+
+ std::vector<LLVMEnumAttrCase> cases;
+ cases.reserve(inits->size());
+
+ for (const llvm::Init *init : *inits)
+ cases.emplace_back(cast<llvm::DefInit>(init));
+
+ return cases;
+ }
};
// Wraper class around a Tablegen definition of a C-style LLVM enum attribute.
os << formatv(" return {0}::{1}::{2};\n", cppNamespace, cppClassName,
cppEnumerant);
}
+ for (const auto &enumerant : enumAttr.getAllUnsupportedCases()) {
+ StringRef llvmEnumerant = enumerant.getLLVMEnumerant();
+ os << formatv(" case {0}::{1}:\n", llvmClass, llvmEnumerant);
+ os << formatv(" llvm_unreachable(\"unsupported case {0}::{1}\");\n",
+ enumAttr.getLLVMClassName(), llvmEnumerant);
+ }
os << " }\n";
os << formatv(" llvm_unreachable(\"unknown {0} type\");",