Skip to content

Commit ac724ef

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 6d380e5 commit ac724ef

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
@@ -1852,4 +1852,22 @@ def VAArgOp : CIR_Op<"va.arg">,
18521852
let hasVerifier = 0;
18531853
}
18541854

1855+
//===----------------------------------------------------------------------===//
1856+
// Operations Lowered Directly to LLVM IR
1857+
//
1858+
// These operations are hacks to get around missing features in LLVM's dialect.
1859+
// Use it sparingly and remove it once the features are added.
1860+
//===----------------------------------------------------------------------===//
1861+
1862+
def ZeroInitConstOp : CIR_Op<"llvmir.zeroinit", [Pure]>,
1863+
Results<(outs AnyType:$result)> {
1864+
let summary = "Zero initializes a constant value of a given type";
1865+
let description = [{
1866+
This operation circumvents the lack of a zeroinitializer operation in LLVM
1867+
Dialect. It can zeroinitialize any LLVM type.
1868+
}];
1869+
let assemblyFormat = "attr-dict `:` type($result)";
1870+
let hasVerifier = 0;
1871+
}
1872+
18551873
#endif // LLVM_CLANG_CIR_DIALECT_IR_CIROPS

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

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

8195
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
@@ -1835,6 +1835,9 @@ void ConvertCIRToLLVMPass::runOnOperation() {
18351835
target.addIllegalDialect<mlir::BuiltinDialect, mlir::cir::CIRDialect,
18361836
mlir::func::FuncDialect>();
18371837

1838+
// Allow operations that will be lowered directly to LLVM IR.
1839+
target.addLegalOp<mlir::cir::ZeroInitConstOp>();
1840+
18381841
getOperation()->removeAttr("cir.sob");
18391842
getOperation()->removeAttr("cir.lang");
18401843

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} : !llvm.ptr
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)