[mlir][llvm] Add poison constant.

This patch introduces the poison constant from LLVM in the LLVM IR dialect. It also adds import and export support for it, along with roundtrip tests.

Reviewed By: gysit

Differential Revision: https://reviews.llvm.org/D146631
This commit is contained in:
Théo Degioanni 2023-03-23 07:58:37 +01:00 committed by Tobias Gysi
parent f9f4767af9
commit a35f9c6e08
6 changed files with 42 additions and 3 deletions

View File

@ -105,6 +105,7 @@ values for thread-safety and concept parsimony reasons. Instead, regular values
are produced by dedicated operations that have the corresponding semantics:
[`llvm.mlir.constant`](#llvmmlirconstant-mlirllvmconstantop),
[`llvm.mlir.undef`](#llvmmlirundef-mlirllvmundefop),
[`llvm.mlir.poison`](#llvmmlirpoison-mlirllvmpoisonop),
[`llvm.mlir.null`](#llvmmlirnull-mlirllvmnullop). Note how these operations are
prefixed with `mlir.` to indicate that they don't belong to LLVM IR but are only
necessary to model it in MLIR. The values produced by these operations are

View File

@ -1652,7 +1652,7 @@ def LLVM_UndefOp : LLVM_Op<"mlir.undef", [Pure]>,
Unlike LLVM IR, MLIR does not have first-class undefined values. Such values
must be created as SSA values using `llvm.mlir.undef`. This operation has no
operands or attributes. It creates an undefined value of the specified LLVM
IR dialect type wrapping an LLVM IR structure type.
IR dialect type.
Example:
@ -1666,6 +1666,28 @@ def LLVM_UndefOp : LLVM_Op<"mlir.undef", [Pure]>,
let assemblyFormat = "attr-dict `:` type($res)";
}
def LLVM_PoisonOp : LLVM_Op<"mlir.poison", [Pure]>,
LLVM_Builder<"$res = llvm::PoisonValue::get($_resultType);"> {
let summary = "Creates a poison value of LLVM dialect type.";
let description = [{
Unlike LLVM IR, MLIR does not have first-class poison values. Such values
must be created as SSA values using `llvm.mlir.poison`. This operation has
no operands or attributes. It creates a poison value of the specified LLVM
IR dialect type.
Example:
```mlir
// Create a poison value for a structure with a 32-bit integer followed
// by a float.
%0 = llvm.mlir.poison : !llvm.struct<(i32, f32)>
```
}];
let results = (outs LLVM_Type:$res);
let builders = [LLVM_OneResultOpBuilder];
let assemblyFormat = "attr-dict `:` type($res)";
}
def LLVM_ConstantOp
: LLVM_Op<"mlir.constant", [Pure, ConstantLike]>,
LLVM_Builder<[{$res = getLLVMConstant($_resultType, $value, $_location,

View File

@ -1036,6 +1036,12 @@ FailureOr<Value> ModuleImport::convertConstant(llvm::Constant *constant) {
return builder.create<NullOp>(loc, type).getResult();
}
// Convert poison.
if (auto *poisonVal = dyn_cast<llvm::PoisonValue>(constant)) {
Type type = convertType(poisonVal->getType());
return builder.create<PoisonOp>(loc, type).getResult();
}
// Convert undef.
if (auto *undefVal = dyn_cast<llvm::UndefValue>(constant)) {
Type type = convertType(undefVal->getType());

View File

@ -438,10 +438,14 @@ llvm.func @invokeLandingpad() -> i32 attributes { personality = @__gxx_personali
func.func @useFreezeOp(%arg0: i32) {
// CHECK: = llvm.freeze %[[ARG0:.*]] : i32
%0 = llvm.freeze %arg0 : i32
// CHECK: %[[x:.*]] = llvm.mlir.undef : i8
// CHECK: %[[UNDEF:.*]] = llvm.mlir.undef : i8
%1 = llvm.mlir.undef : i8
// CHECK: = llvm.freeze %[[x]] : i8
// CHECK: = llvm.freeze %[[UNDEF]] : i8
%2 = llvm.freeze %1 : i8
// CHECK: %[[POISON:.*]] = llvm.mlir.poison : i8
%3 = llvm.mlir.poison : i8
// CHECK: = llvm.freeze %[[POISON]] : i8
%4 = llvm.freeze %3 : i8
return
}

View File

@ -523,10 +523,13 @@ define void @gep_dynamic_idx(ptr %ptr, i32 %idx) {
; CHECK-SAME: %[[ARG1:[a-zA-Z0-9]+]]
define void @freeze(i32 %arg1) {
; CHECK: %[[UNDEF:[0-9]+]] = llvm.mlir.undef : i64
; CHECK: %[[POISON:[0-9]+]] = llvm.mlir.poison : i16
; CHECK: llvm.freeze %[[ARG1]] : i32
; CHECK: llvm.freeze %[[UNDEF]] : i64
; CHECK: llvm.freeze %[[POISON]] : i16
%1 = freeze i32 %arg1
%2 = freeze i64 undef
%3 = freeze i16 poison
ret void
}

View File

@ -1618,6 +1618,9 @@ llvm.func @callFreezeOp(%x : i32) {
%1 = llvm.mlir.undef : i32
// CHECK: freeze i32 undef
%2 = llvm.freeze %1 : i32
%3 = llvm.mlir.poison : i32
// CHECK: freeze i32 poison
%4 = llvm.freeze %3 : i32
llvm.return
}