summaryrefslogtreecommitdiff
path: root/mlir
diff options
context:
space:
mode:
authorTobias Gysi <tobias.gysi@nextsilicon.com>2023-05-16 11:06:36 +0000
committerTobias Gysi <tobias.gysi@nextsilicon.com>2023-05-16 11:06:45 +0000
commit4af245850545520d88029f72c555ee0e0975c280 (patch)
treea0bd054336dc9b53c435984834143d9211a84559 /mlir
parent095e6ac9fd92d03dcb1e19b60cb06a8140aae69d (diff)
downloadllvm-4af245850545520d88029f72c555ee0e0975c280.tar.gz
[mlir][llvm] Add expect intrinsics.
The revision adds the LLVM expect and expect.with.probability intrinsics. Reviewed By: Dinistro, ftynse Differential Revision: https://reviews.llvm.org/D150643
Diffstat (limited to 'mlir')
-rw-r--r--mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td35
-rw-r--r--mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td1
-rw-r--r--mlir/include/mlir/Target/LLVMIR/ModuleImport.h3
-rw-r--r--mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp1
-rw-r--r--mlir/lib/Target/LLVMIR/ModuleImport.cpp12
-rw-r--r--mlir/test/Target/LLVMIR/Import/intrinsic.ll20
-rw-r--r--mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir18
-rw-r--r--mlir/tools/mlir-tblgen/LLVMIRConversionGen.cpp2
8 files changed, 89 insertions, 3 deletions
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
index 141ad6df62dd..a6b3cd307932 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
@@ -266,6 +266,37 @@ def LLVM_AssumeOp
: LLVM_ZeroResultIntrOp<"assume", []>, Arguments<(ins I1:$cond)>;
//
+// Expect intrinsics.
+//
+
+def LLVM_ExpectOp
+ : LLVM_OneResultIntrOp<"expect", [], [0],
+ [Pure, SameOperandsAndResultType]> {
+ let arguments = (ins AnySignlessInteger:$val,
+ AnySignlessInteger:$expected);
+ let assemblyFormat = "$val `,` $expected attr-dict `:` type($val)";
+}
+
+def LLVM_ExpectWithProbabilityOp
+ : LLVM_OneResultIntrOp<"expect.with.probability", [], [0],
+ [Pure, AllTypesMatch<["val", "expected", "res"]>]> {
+ let arguments = (ins AnySignlessInteger:$val,
+ AnySignlessInteger:$expected,
+ F64Attr:$prob);
+ string llvmBuilder = [{
+ createIntrinsicCall(
+ builder, llvm::Intrinsic::expect_with_probability,
+ {$val, $expected, llvm::ConstantFP::get(builder.getDoubleTy(), $prob)},
+ {$_resultType});
+ }];
+ string mlirBuilder = [{
+ $res = $_builder.create<LLVM::ExpectWithProbabilityOp>(
+ $_location, $val, $expected, $_float_attr($prob));
+ }];
+ let assemblyFormat = "$val `,` $expected `,` $prob attr-dict `:` type($val)";
+}
+
+//
// Coroutine intrinsics.
//
@@ -727,8 +758,8 @@ def LLVM_DebugTrap : LLVM_ZeroResultIntrOp<"debugtrap">;
def LLVM_UBSanTrap : LLVM_ZeroResultIntrOp<"ubsantrap"> {
let arguments = (ins I8Attr:$failureKind);
string llvmBuilder = [{
- builder.CreateIntrinsic(
- llvm::Intrinsic::ubsantrap, {}, {builder.getInt8($failureKind)});
+ createIntrinsicCall(
+ builder, llvm::Intrinsic::ubsantrap, {builder.getInt8($failureKind)});
}];
string mlirBuilder = [{
$_op =
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td
index 9512765dbb06..96ebf42dec32 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td
@@ -159,6 +159,7 @@ class LLVM_OpBase<Dialect dialect, string mnemonic, list<Trait> traits = []> :
// - $_op - substituted by a reference to store the newly created MLIR
// operation (only for MLIR operations that return no result);
// - $_int_attr - substituted by a call to an integer attribute matcher;
+ // - $_float_attr - substituted by a call to a float attribute matcher;
// - $_var_attr - substituted by a call to a variable attribute matcher;
// - $_resultType - substituted with the MLIR result type;
// - $_location - substituted with the MLIR location;
diff --git a/mlir/include/mlir/Target/LLVMIR/ModuleImport.h b/mlir/include/mlir/Target/LLVMIR/ModuleImport.h
index 47af0756a21e..ce622f7cabab 100644
--- a/mlir/include/mlir/Target/LLVMIR/ModuleImport.h
+++ b/mlir/include/mlir/Target/LLVMIR/ModuleImport.h
@@ -136,6 +136,9 @@ public:
/// Converts `value` to an integer attribute. Asserts if the matching fails.
IntegerAttr matchIntegerAttr(llvm::Value *value);
+ /// Converts `value` to a float attribute. Asserts if the matching fails.
+ FloatAttr matchFloatAttr(llvm::Value *value);
+
/// Converts `value` to a local variable attribute. Asserts if the matching
/// fails.
DILocalVariableAttr matchLocalVariableAttr(llvm::Value *value);
diff --git a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
index c12d7f5166a5..8783be7da377 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
@@ -24,6 +24,7 @@
using namespace mlir;
using namespace mlir::LLVM;
+using mlir::LLVM::detail::createIntrinsicCall;
using mlir::LLVM::detail::getLLVMConstant;
#include "mlir/Dialect/LLVMIR/LLVMConversionEnumsToLLVM.inc"
diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
index f4ea8017ac8e..d9f115c6d77a 100644
--- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
@@ -1163,11 +1163,21 @@ IntegerAttr ModuleImport::matchIntegerAttr(llvm::Value *value) {
FailureOr<Value> converted = convertValue(value);
bool success = succeeded(converted) &&
matchPattern(*converted, m_Constant(&integerAttr));
- assert(success && "expected a constant value");
+ assert(success && "expected a constant integer value");
(void)success;
return integerAttr;
}
+FloatAttr ModuleImport::matchFloatAttr(llvm::Value *value) {
+ FloatAttr floatAttr;
+ FailureOr<Value> converted = convertValue(value);
+ bool success =
+ succeeded(converted) && matchPattern(*converted, m_Constant(&floatAttr));
+ assert(success && "expected a constant float value");
+ (void)success;
+ return floatAttr;
+}
+
DILocalVariableAttr ModuleImport::matchLocalVariableAttr(llvm::Value *value) {
auto *nodeAsVal = cast<llvm::MetadataAsValue>(value);
auto *node = cast<llvm::DILocalVariable>(nodeAsVal->getMetadata());
diff --git a/mlir/test/Target/LLVMIR/Import/intrinsic.ll b/mlir/test/Target/LLVMIR/Import/intrinsic.ll
index bd072e283bcd..fadfc124adbd 100644
--- a/mlir/test/Target/LLVMIR/Import/intrinsic.ll
+++ b/mlir/test/Target/LLVMIR/Import/intrinsic.ll
@@ -467,6 +467,24 @@ define void @assume(i1 %true) {
ret void
}
+; CHECK-LABEL: @expect
+; CHECK-SAME: %[[VAL:[a-zA-Z0-9]+]]
+define void @expect(i32 %0) {
+ ; CHECK: %[[EXP:.+]] = llvm.mlir.constant(42 : i32) : i32
+ ; CHECK: llvm.intr.expect %[[VAL]], %[[EXP]] : i32
+ %2 = call i32 @llvm.expect.i32(i32 %0, i32 42)
+ ret void
+}
+
+; CHECK-LABEL: @expect_with_probability
+; CHECK-SAME: %[[VAL:[a-zA-Z0-9]+]]
+define void @expect_with_probability(i16 %0) {
+ ; CHECK: %[[EXP:.+]] = llvm.mlir.constant(42 : i16) : i16
+ ; CHECK: llvm.intr.expect.with.probability %[[VAL]], %[[EXP]], 5.000000e-01 : i16
+ %2 = call i16 @llvm.expect.with.probability.i16(i16 %0, i16 42, double 0.5)
+ ret void
+}
+
; CHECK-LABEL: llvm.func @coro_id
define void @coro_id(i32 %0, ptr %1) {
; CHECK: llvm.intr.coro.id %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}} : (i32, !llvm.ptr, !llvm.ptr, !llvm.ptr) -> !llvm.token
@@ -774,6 +792,8 @@ declare { i32, i1 } @llvm.smul.with.overflow.i32(i32, i32)
declare { <8 x i32>, <8 x i1> } @llvm.smul.with.overflow.v8i32(<8 x i32>, <8 x i32>)
declare { i32, i1 } @llvm.umul.with.overflow.i32(i32, i32)
declare { <8 x i32>, <8 x i1> } @llvm.umul.with.overflow.v8i32(<8 x i32>, <8 x i32>)
+declare i32 @llvm.expect.i32(i32, i32)
+declare i16 @llvm.expect.with.probability.i16(i16, i16, double immarg)
declare token @llvm.coro.id(i32, ptr readnone, ptr nocapture readonly, ptr)
declare ptr @llvm.coro.begin(token, ptr writeonly)
declare i64 @llvm.coro.size.i64()
diff --git a/mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir b/mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir
index 80a52224a839..199a6e5dd159 100644
--- a/mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir
+++ b/mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir
@@ -466,6 +466,22 @@ llvm.func @umul_with_overflow_test(%arg0: i32, %arg1: i32, %arg2: vector<8xi32>,
llvm.return
}
+// CHECK-LABEL: @expect
+llvm.func @expect(%arg0: i32) {
+ %0 = llvm.mlir.constant(42 : i32) : i32
+ // CHECK: call i32 @llvm.expect.i32(i32 %{{.*}}, i32 42)
+ %1 = llvm.intr.expect %arg0, %0 : i32
+ llvm.return
+}
+
+// CHECK-LABEL: @expect_with_probability
+llvm.func @expect_with_probability(%arg0: i16) {
+ %0 = llvm.mlir.constant(42 : i16) : i16
+ // CHECK: call i16 @llvm.expect.with.probability.i16(i16 %{{.*}}, i16 42, double 5.000000e-01)
+ %1 = llvm.intr.expect.with.probability %arg0, %0, 5.000000e-01 : i16
+ llvm.return
+}
+
// CHECK-LABEL: @coro_id
llvm.func @coro_id(%arg0: i32, %arg1: !llvm.ptr<i8>) {
// CHECK: call token @llvm.coro.id
@@ -814,6 +830,8 @@ llvm.func @lifetime(%p: !llvm.ptr) {
// CHECK-DAG: declare { <8 x i32>, <8 x i1> } @llvm.usub.with.overflow.v8i32(<8 x i32>, <8 x i32>)
// CHECK-DAG: declare { i32, i1 } @llvm.umul.with.overflow.i32(i32, i32)
// CHECK-DAG: declare { <8 x i32>, <8 x i1> } @llvm.umul.with.overflow.v8i32(<8 x i32>, <8 x i32>)
+// CHECK-DAG: declare i32 @llvm.expect.i32(i32, i32)
+// CHECK-DAG: declare i16 @llvm.expect.with.probability.i16(i16, i16, double immarg)
// CHECK-DAG: declare token @llvm.coro.id(i32, ptr readnone, ptr nocapture readonly, ptr)
// CHECK-DAG: declare ptr @llvm.coro.begin(token, ptr writeonly)
// CHECK-DAG: declare i64 @llvm.coro.size.i64()
diff --git a/mlir/tools/mlir-tblgen/LLVMIRConversionGen.cpp b/mlir/tools/mlir-tblgen/LLVMIRConversionGen.cpp
index 926ebdf20d78..f10f3cd8f9a1 100644
--- a/mlir/tools/mlir-tblgen/LLVMIRConversionGen.cpp
+++ b/mlir/tools/mlir-tblgen/LLVMIRConversionGen.cpp
@@ -266,6 +266,8 @@ static LogicalResult emitOneMLIRBuilder(const Record &record, raw_ostream &os,
bs << "moduleImport.mapNoResultOp(inst)";
} else if (name == "_int_attr") {
bs << "moduleImport.matchIntegerAttr";
+ } else if (name == "_float_attr") {
+ bs << "moduleImport.matchFloatAttr";
} else if (name == "_var_attr") {
bs << "moduleImport.matchLocalVariableAttr";
} else if (name == "_resultType") {