Skip to content

Commit f72d8bd

Browse files
sitio-coutolanza
authored andcommitted
[CIR][Lowering] Implement cir.llvmir.zeroinit operation
Due to the lack of zeroinitializer support in LLVM, some cases are tricky to lower #cir.zero. An example is when an array is only partially initialize with #cir.zero attributes. Since we can't just zeroinitialize the whole array, the current #cir.zero attribute amend does not suffice. To simplify the lowering, this patch introduces a new operation that is solely used to generate zeroinitialize LLVM IR constants. ghstack-source-id: a3fd40e Pull Request resolved: #218
1 parent afacca3 commit f72d8bd

File tree

4 files changed

+44
-0
lines changed

4 files changed

+44
-0
lines changed

clang/include/clang/CIR/Dialect/IR/CIROps.td

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1864,4 +1864,22 @@ def VAArgOp : CIR_Op<"va.arg">,
18641864
let hasVerifier = 0;
18651865
}
18661866

1867+
//===----------------------------------------------------------------------===//
1868+
// Operations Lowered Directly to LLVM IR
1869+
//
1870+
// These operations are hacks to get around missing features in LLVM's dialect.
1871+
// Use it sparingly and remove it once the features are added.
1872+
//===----------------------------------------------------------------------===//
1873+
1874+
def ZeroInitConstOp : CIR_Op<"llvmir.zeroinit", [Pure]>,
1875+
Results<(outs AnyType:$result)> {
1876+
let summary = "Zero initializes a constant value of a given type";
1877+
let description = [{
1878+
This operation circumvents the lack of a zeroinitializer operation in LLVM
1879+
Dialect. It can zeroinitialize any LLVM type.
1880+
}];
1881+
let assemblyFormat = "attr-dict `:` type($result)";
1882+
let hasVerifier = 0;
1883+
}
1884+
18671885
#endif // MLIR_CIR_DIALECT_CIR_OPS

clang/lib/CIR/Lowering/DirectToLLVM/LowerAttrToLLVMIR.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,20 @@ class CIRDialectLLVMIRTranslationInterface
7777
op->removeAttr(attribute.getName());
7878
return mlir::success();
7979
}
80+
81+
/// Translates the given operation to LLVM IR using the provided IR builder
82+
/// and saving the state in `moduleTranslation`.
83+
mlir::LogicalResult convertOperation(
84+
mlir::Operation *op, llvm::IRBuilderBase &builder,
85+
mlir::LLVM::ModuleTranslation &moduleTranslation) const final {
86+
87+
if (auto cirOp = llvm::dyn_cast<mlir::cir::ZeroInitConstOp>(op))
88+
moduleTranslation.mapValue(cirOp.getResult()) =
89+
llvm::Constant::getNullValue(
90+
moduleTranslation.convertType(cirOp.getType()));
91+
92+
return mlir::success();
93+
}
8094
};
8195

8296
void registerCIRDialectTranslation(mlir::DialectRegistry &registry) {

clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1825,6 +1825,9 @@ void ConvertCIRToLLVMPass::runOnOperation() {
18251825
target.addIllegalDialect<mlir::BuiltinDialect, mlir::cir::CIRDialect,
18261826
mlir::func::FuncDialect>();
18271827

1828+
// Allow operations that will be lowered directly to LLVM IR.
1829+
target.addLegalOp<mlir::cir::ZeroInitConstOp>();
1830+
18281831
getOperation()->removeAttr("cir.sob");
18291832
getOperation()->removeAttr("cir.lang");
18301833

clang/test/CIR/Translation/zeroinitializer.cir

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,13 @@ module {
99
// Should lower #cir.null on pointers to a null initializer.
1010
llvm.mlir.global external @ptr() {addr_space = 0 : i32, cir.initial_value = #cir.zero : !llvm.ptr<i32>} : !llvm.ptr<i32>
1111
// CHECK: @ptr = global ptr null
12+
13+
// Should lower aggregates types with elements initialized with cir.llvmir.zeroinit.
14+
llvm.mlir.global external @arr() {addr_space = 0 : i32} : !llvm.array<1 x !llvm.struct<"struct.S", (i8, i32)>> {
15+
%0 = llvm.mlir.undef : !llvm.array<1 x !llvm.struct<"struct.S", (i8, i32)>>
16+
%1 = cir.llvmir.zeroinit : !llvm.struct<"struct.S", (i8, i32)>
17+
%2 = llvm.insertvalue %1, %0[0] : !llvm.array<1 x !llvm.struct<"struct.S", (i8, i32)>>
18+
llvm.return %2 : !llvm.array<1 x !llvm.struct<"struct.S", (i8, i32)>>
19+
}
20+
// CHECK: @arr = global [1 x %struct.S] zeroinitializer
1221
}

0 commit comments

Comments
 (0)