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
14 changes: 6 additions & 8 deletions clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1267,14 +1267,12 @@ class CIRGlobalOpLowering
return mlir::success();
} else if (isa<mlir::cir::ZeroAttr, mlir::cir::NullAttr>(init.value())) {
// TODO(cir): once LLVM's dialect has a proper zeroinitializer attribute
// this should be updated. For now, we tag the LLVM global with a cir.zero
// attribute that is later replaced with a zeroinitializer. Null pointers
// also use this path for simplicity, as we would otherwise require a
// region-based initialization for the global op.
auto llvmGlobalOp = rewriter.replaceOpWithNewOp<mlir::LLVM::GlobalOp>(
op, llvmType, isConst, linkage, symbol, nullptr);
auto cirZeroAttr = mlir::cir::ZeroAttr::get(getContext(), llvmType);
llvmGlobalOp->setAttr("cir.initial_value", cirZeroAttr);
// this should be updated. For now, we use a custom op to initialize
// globals to zero.
setupRegionInitializedLLVMGlobalOp(op, rewriter);
auto value =
lowerCirAttrAsValue(init.value(), loc, rewriter, typeConverter);
rewriter.create<mlir::LLVM::ReturnOp>(loc, value);
return mlir::success();
} else if (const auto structAttr =
init.value().dyn_cast<mlir::cir::ConstStructAttr>()) {
Expand Down
11 changes: 0 additions & 11 deletions clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVMIR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,6 @@ class CIRDialectLLVMIRTranslationInterface
amendOperation(mlir::Operation *op, mlir::NamedAttribute attribute,
mlir::LLVM::ModuleTranslation &moduleTranslation) const final {

// Translate CIR's zero attribute to LLVM's zero initializer.
if (isa<mlir::cir::ZeroAttr>(attribute.getValue())) {
if (llvm::isa<mlir::LLVM::GlobalOp>(op)) {
auto *globalVal = llvm::cast<llvm::GlobalVariable>(
moduleTranslation.lookupGlobal(op));
globalVal->setInitializer(
llvm::Constant::getNullValue(globalVal->getValueType()));
} else
return op->emitError("#cir.zero not supported");
}

// Translate CIR's extra function attributes to LLVM's function attributes.
auto func = dyn_cast<mlir::LLVM::LLVMFuncOp>(op);
if (!func)
Expand Down
11 changes: 11 additions & 0 deletions clang/test/CIR/Lowering/globals.cir
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
!u64i = !cir.int<u, 64>
!u8i = !cir.int<u, 8>
!ty_22struct2EA22 = !cir.struct<"struct.A", !s32i, !cir.array<!cir.array<!s32i x 2> x 2>, #cir.recdecl.ast>
!ty_22struct2EBar22 = !cir.struct<"struct.Bar", !s32i, !s8i, #cir.recdecl.ast>

module {
cir.global external @a = #cir.int<3> : !s32i
Expand Down Expand Up @@ -134,4 +135,14 @@ module {
// MLIR: llvm.mlir.global external @zeroInitFlt(dense<0.000000e+00> : tensor<2xf32>) {addr_space = 0 : i32} : !llvm.array<2 x f32>
cir.global "private" internal @staticVar = #cir.int<0> : !s32i
// MLIR: llvm.mlir.global internal @staticVar(0 : i32) {addr_space = 0 : i32} : i32
cir.global external @nullPtr = #cir.null : !cir.ptr<!s32i>
// MLIR: llvm.mlir.global external @nullPtr()
// MLIR: %0 = llvm.mlir.null : !llvm.ptr<i32>
// MLIR: llvm.return %0 : !llvm.ptr<i32>
// MLIR: }
cir.global external @zeroStruct = #cir.zero : !ty_22struct2EBar22
// MLIR: llvm.mlir.global external @zeroStruct()
// MLIR: %0 = cir.llvmir.zeroinit : !llvm.struct<"struct.Bar", (i32, i8)>
// MLIR: llvm.return %0 : !llvm.struct<"struct.Bar", (i32, i8)>
// MLIR: }
}
14 changes: 10 additions & 4 deletions clang/test/CIR/Translation/zeroinitializer.cir
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,18 @@
// RUN: FileCheck --input-file=%t.ll %s

module {
// Should lower #cir.zero on structs to a zeroinitializer.
llvm.mlir.global external @bar() {addr_space = 0 : i32, cir.initial_value = #cir.zero : !llvm.struct<"struct.S", (i8, i32)>} : !llvm.struct<"struct.S", (i8, i32)>
// Should zero-initialize global structs initialized with cir.llvmir.zeroinit.
llvm.mlir.global external @bar() {addr_space = 0 : i32} : !llvm.struct<"struct.S", (i8, i32)> {
%0 = cir.llvmir.zeroinit : !llvm.struct<"struct.S", (i8, i32)>
llvm.return %0 : !llvm.struct<"struct.S", (i8, i32)>
}
// CHECK: @bar = global %struct.S zeroinitializer

// 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>
// Should null-initialize global pointer initialized with cir.llvmir.zeroinit.
llvm.mlir.global external @ptr() {addr_space = 0 : i32} : !llvm.ptr<i32> {
%0 = cir.llvmir.zeroinit : !llvm.ptr<i32>
llvm.return %0 : !llvm.ptr<i32>
}
// CHECK: @ptr = global ptr null

// Should lower aggregates types with elements initialized with cir.llvmir.zeroinit.
Expand Down