Skip to content

Commit d07dad8

Browse files
ftynseLeporacanthicus
authored andcommitted
[mlir] don't drop undef initializers in translation to LLVM IR
LLVM IR allows globals with external linkage to have initializers, including undef. The translation was incorrectly using undef as a indicator that the initializer should be ignored in translation, leading to the impossibility to create an external global with an explicit undef initializer. Fix this and use nullptr as a marker instead. Reviewed By: wsmoses Differential Revision: https://reviews.llvm.org/D105631
1 parent e401ff8 commit d07dad8

File tree

2 files changed

+23
-7
lines changed

2 files changed

+23
-7
lines changed

mlir/lib/Target/LLVMIR/ModuleTranslation.cpp

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -442,11 +442,13 @@ static Block &getModuleBody(Operation *module) {
442442
}
443443

444444
/// A helper method to decide if a constant must not be set as a global variable
445-
/// initializer.
445+
/// initializer. For an external linkage variable, the variable with an
446+
/// initializer is considered externally visible and defined in this module, the
447+
/// variable without an initializer is externally available and is defined
448+
/// elsewhere.
446449
static bool shouldDropGlobalInitializer(llvm::GlobalValue::LinkageTypes linkage,
447450
llvm::Constant *cst) {
448-
return (linkage == llvm::GlobalVariable::ExternalLinkage &&
449-
isa<llvm::UndefValue>(cst)) ||
451+
return (linkage == llvm::GlobalVariable::ExternalLinkage && !cst) ||
450452
linkage == llvm::GlobalVariable::ExternalWeakLinkage;
451453
}
452454

@@ -455,7 +457,7 @@ static bool shouldDropGlobalInitializer(llvm::GlobalValue::LinkageTypes linkage,
455457
LogicalResult ModuleTranslation::convertGlobals() {
456458
for (auto op : getModuleBody(mlirModule).getOps<LLVM::GlobalOp>()) {
457459
llvm::Type *type = convertType(op.getType());
458-
llvm::Constant *cst = llvm::UndefValue::get(type);
460+
llvm::Constant *cst = nullptr;
459461
if (op.getValueOrNull()) {
460462
// String attributes are treated separately because they cannot appear as
461463
// in-function constants and are thus not supported by getLLVMConstant.
@@ -471,10 +473,18 @@ LogicalResult ModuleTranslation::convertGlobals() {
471473

472474
auto linkage = convertLinkageToLLVM(op.linkage());
473475
auto addrSpace = op.addr_space();
476+
477+
// LLVM IR requires constant with linkage other than external or weak
478+
// external to have initializers. If MLIR does not provide an initializer,
479+
// default to undef.
480+
bool dropInitializer = shouldDropGlobalInitializer(linkage, cst);
481+
if (!dropInitializer && !cst)
482+
cst = llvm::UndefValue::get(type);
483+
else if (dropInitializer && cst)
484+
cst = nullptr;
485+
474486
auto *var = new llvm::GlobalVariable(
475-
*llvmModule, type, op.constant(), linkage,
476-
shouldDropGlobalInitializer(linkage, cst) ? nullptr : cst,
477-
op.sym_name(),
487+
*llvmModule, type, op.constant(), linkage, cst, op.sym_name(),
478488
/*InsertBefore=*/nullptr, llvm::GlobalValue::NotThreadLocal, addrSpace);
479489

480490
if (op.unnamed_addr().hasValue())

mlir/test/Target/LLVMIR/llvmir.mlir

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ llvm.mlir.global internal constant @string_const("foobar") : !llvm.array<6 x i8>
3333
// CHECK: @int_global_undef = internal global i64 undef
3434
llvm.mlir.global internal @int_global_undef() : i64
3535

36+
// CHECK: @explicit_undef = global i32 undef
37+
llvm.mlir.global external @explicit_undef() : i32 {
38+
%0 = llvm.mlir.undef : i32
39+
llvm.return %0 : i32
40+
}
41+
3642
// CHECK: @int_gep = internal constant i32* getelementptr (i32, i32* @i32_global, i32 2)
3743
llvm.mlir.global internal constant @int_gep() : !llvm.ptr<i32> {
3844
%addr = llvm.mlir.addressof @i32_global : !llvm.ptr<i32>

0 commit comments

Comments
 (0)