Skip to content

Commit 01192a0

Browse files
authored
[mlir][llvm] Add zeroinitializer constant (#65508)
This patch adds support for the zeroinitializer constant to LLVM dialect. It's meant to simplify zero-initialization of aggregate types in MLIR, although it can also be used with non-aggregate types.
1 parent 3ac4ba3 commit 01192a0

File tree

3 files changed

+57
-0
lines changed

3 files changed

+57
-0
lines changed

mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1506,6 +1506,30 @@ def LLVM_PoisonOp : LLVM_Op<"mlir.poison", [Pure]>,
15061506
let assemblyFormat = "attr-dict `:` type($res)";
15071507
}
15081508

1509+
def LLVM_ZeroOp
1510+
: LLVM_Op<"mlir.zero", [Pure]>,
1511+
LLVM_Builder<"$res = llvm::Constant::getNullValue($_resultType);">
1512+
{
1513+
let summary = "Creates a zero-initialized value of LLVM dialect type.";
1514+
let description = [{
1515+
Unlike LLVM IR, MLIR does not have first-class zero-initialized values.
1516+
Such values must be created as SSA values using `llvm.mlir.zero`. This
1517+
operation has no operands or attributes. It creates a zero-initialized
1518+
value of the specified LLVM IR dialect type.
1519+
1520+
Example:
1521+
1522+
```mlir
1523+
// Create a zero-initialized value for a structure with a 32-bit integer
1524+
// followed by a float.
1525+
%0 = llvm.mlir.zero : !llvm.struct<(i32, f32)>
1526+
```
1527+
}];
1528+
let results = (outs LLVM_Type:$res);
1529+
let builders = [LLVM_OneResultOpBuilder];
1530+
let assemblyFormat = "attr-dict `:` type($res)";
1531+
}
1532+
15091533
def LLVM_ConstantOp
15101534
: LLVM_Op<"mlir.constant", [Pure, ConstantLike]>,
15111535
LLVM_Builder<[{$res = getLLVMConstant($_resultType, $value, $_location,

mlir/test/Dialect/LLVMIR/roundtrip.mlir

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,13 @@ func.func @null() {
334334
llvm.return
335335
}
336336

337+
// CHECK-LABEL: @zero
338+
func.func @zero() {
339+
// CHECK: llvm.mlir.zero : i8
340+
%0 = llvm.mlir.zero : i8
341+
llvm.return
342+
}
343+
337344
// CHECK-LABEL: @atomic_load
338345
func.func @atomic_load(%ptr : !llvm.ptr) {
339346
// CHECK: llvm.load %{{.*}} atomic monotonic {alignment = 4 : i64} : !llvm.ptr -> f32

mlir/test/Target/LLVMIR/llvmir.mlir

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2292,3 +2292,29 @@ llvm.func @locally_streaming_func() attributes {arm_locally_streaming} {
22922292
}
22932293

22942294
// CHECK: attributes #[[ATTR]] = { "aarch64_pstate_sm_body" }
2295+
2296+
// -----
2297+
2298+
//
2299+
// Zero-initialize operation.
2300+
//
2301+
2302+
// CHECK: @partially_zeroinit_aggregate = linkonce global { i32, i64, [3 x i8] } { i32 0, i64 1, [3 x i8] zeroinitializer }
2303+
llvm.mlir.global linkonce @partially_zeroinit_aggregate() : !llvm.struct<(i32, i64, !llvm.array<3 x i8>)> {
2304+
%0 = llvm.mlir.zero : !llvm.struct<(i32, i64, !llvm.array<3 x i8>)>
2305+
%1 = llvm.mlir.constant(1 : i64) : i64
2306+
%2 = llvm.insertvalue %1, %0[1] : !llvm.struct<(i32, i64, !llvm.array<3 x i8>)>
2307+
llvm.return %2 : !llvm.struct<(i32, i64, !llvm.array<3 x i8>)>
2308+
}
2309+
2310+
llvm.func @zeroinit_complex_local_aggregate() {
2311+
// CHECK: %[[#VAR:]] = alloca [1000 x { i32, [3 x { double, <4 x ptr>, [2 x ptr] }], [6 x ptr] }], i64 1, align 32
2312+
%0 = llvm.mlir.constant(1 : i64) : i64
2313+
%1 = llvm.alloca %0 x !llvm.array<1000 x !llvm.struct<(i32, !llvm.array<3 x !llvm.struct<(f64, !llvm.vec<4 x ptr>, !llvm.array<2 x ptr>)>>, !llvm.array<6 x ptr>)>> : (i64) -> !llvm.ptr
2314+
2315+
// CHECK: store [1000 x { i32, [3 x { double, <4 x ptr>, [2 x ptr] }], [6 x ptr] }] zeroinitializer, ptr %[[#VAR]], align 32
2316+
%2 = llvm.mlir.zero : !llvm.array<1000 x !llvm.struct<(i32, !llvm.array<3 x !llvm.struct<(f64, !llvm.vec<4 x ptr>, !llvm.array<2 x ptr>)>>, !llvm.array<6 x ptr>)>>
2317+
llvm.store %2, %1 : !llvm.array<1000 x !llvm.struct<(i32, !llvm.array<3 x !llvm.struct<(f64, !llvm.vec<4 x ptr>, !llvm.array<2 x ptr>)>>, !llvm.array<6 x ptr>)>>, !llvm.ptr
2318+
2319+
llvm.return
2320+
}

0 commit comments

Comments
 (0)