Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions clang/include/clang/CIR/Dialect/IR/CIROps.td
Original file line number Diff line number Diff line change
Expand Up @@ -1864,4 +1864,22 @@ def VAArgOp : CIR_Op<"va.arg">,
let hasVerifier = 0;
}

//===----------------------------------------------------------------------===//
// Operations Lowered Directly to LLVM IR
//
// These operations are hacks to get around missing features in LLVM's dialect.
// Use it sparingly and remove it once the features are added.
//===----------------------------------------------------------------------===//

def ZeroInitConstOp : CIR_Op<"llvmir.zeroinit", [Pure]>,
Results<(outs AnyType:$result)> {
let summary = "Zero initializes a constant value of a given type";
let description = [{
This operation circumvents the lack of a zeroinitializer operation in LLVM
Dialect. It can zeroinitialize any LLVM type.
}];
let assemblyFormat = "attr-dict `:` type($result)";
let hasVerifier = 0;
}

#endif // MLIR_CIR_DIALECT_CIR_OPS
14 changes: 14 additions & 0 deletions clang/lib/CIR/Lowering/DirectToLLVM/LowerAttrToLLVMIR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,20 @@ class CIRDialectLLVMIRTranslationInterface
op->removeAttr(attribute.getName());
return mlir::success();
}

/// Translates the given operation to LLVM IR using the provided IR builder
/// and saving the state in `moduleTranslation`.
mlir::LogicalResult convertOperation(
mlir::Operation *op, llvm::IRBuilderBase &builder,
mlir::LLVM::ModuleTranslation &moduleTranslation) const final {

if (auto cirOp = llvm::dyn_cast<mlir::cir::ZeroInitConstOp>(op))
moduleTranslation.mapValue(cirOp.getResult()) =
llvm::Constant::getNullValue(
moduleTranslation.convertType(cirOp.getType()));

return mlir::success();
}
};

void registerCIRDialectTranslation(mlir::DialectRegistry &registry) {
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1825,6 +1825,9 @@ void ConvertCIRToLLVMPass::runOnOperation() {
target.addIllegalDialect<mlir::BuiltinDialect, mlir::cir::CIRDialect,
mlir::func::FuncDialect>();

// Allow operations that will be lowered directly to LLVM IR.
target.addLegalOp<mlir::cir::ZeroInitConstOp>();

getOperation()->removeAttr("cir.sob");
getOperation()->removeAttr("cir.lang");

Expand Down
9 changes: 9 additions & 0 deletions clang/test/CIR/Translation/zeroinitializer.cir
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,13 @@ module {
// Should lower #cir.null on pointers to a null initializer.
llvm.mlir.global external @ptr() {addr_space = 0 : i32, cir.initial_value = #cir.zero : !llvm.ptr<i32>} : !llvm.ptr<i32>
// CHECK: @ptr = global ptr null

// Should lower aggregates types with elements initialized with cir.llvmir.zeroinit.
llvm.mlir.global external @arr() {addr_space = 0 : i32} : !llvm.array<1 x !llvm.struct<"struct.S", (i8, i32)>> {
%0 = llvm.mlir.undef : !llvm.array<1 x !llvm.struct<"struct.S", (i8, i32)>>
%1 = cir.llvmir.zeroinit : !llvm.struct<"struct.S", (i8, i32)>
%2 = llvm.insertvalue %1, %0[0] : !llvm.array<1 x !llvm.struct<"struct.S", (i8, i32)>>
llvm.return %2 : !llvm.array<1 x !llvm.struct<"struct.S", (i8, i32)>>
}
// CHECK: @arr = global [1 x %struct.S] zeroinitializer
}