Skip to content

Commit fbca061

Browse files
committed
[MLIR][mlir-link] Fix issues in mlir link path
1 parent 40de5e2 commit fbca061

File tree

3 files changed

+49
-33
lines changed

3 files changed

+49
-33
lines changed

mlir/include/mlir/Dialect/LLVMIR/LLVMLinkerInterface.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ class LLVMSymbolLinkerInterface
5050
for (auto op : toLink) {
5151
auto structor = dyn_cast<structor_t>(op);
5252
if (!structor)
53-
llvm_unreachable("invali global structor operation");
53+
llvm_unreachable("invalid global structor operation");
5454

5555
ArrayRef<Attribute> structorList;
5656
if constexpr (std::is_same<LLVM::GlobalCtorsOp, structor_t>()) {

mlir/include/mlir/Linker/LLVMLinkerMixin.h

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -340,29 +340,38 @@ class LLVMLinkerMixin {
340340
return ConflictResolution::LinkFromSrc;
341341
}
342342

343-
std::optional<ComdatSelector> srcComdatSel = derived.getComdatSelector(pair.src);
344-
std::optional<ComdatSelector> dstComdatSel = derived.getComdatSelector(pair.dst);
343+
std::optional<ComdatSelector> srcComdatSel =
344+
derived.getComdatSelector(pair.src);
345+
std::optional<ComdatSelector> dstComdatSel =
346+
derived.getComdatSelector(pair.dst);
345347
if (srcComdatSel.has_value() && dstComdatSel.has_value()) {
346348
auto srcComdatName = srcComdatSel->name;
347349
auto dstComdatName = dstComdatSel->name;
348350
auto srcComdat = srcComdatSel->kind;
349351
auto dstComdat = dstComdatSel->kind;
350352
if (srcComdatName != dstComdatName) {
351-
llvm_unreachable("Comdat selector names don't match");
353+
llvm_unreachable("Comdat selector names don't match");
352354
}
353355
if (srcComdat != dstComdat) {
354-
llvm_unreachable("Comdat selector kinds don't match");
356+
llvm_unreachable("Comdat selector kinds don't match");
355357
}
356358

357359
if (srcComdat == mlir::LLVM::comdat::Comdat::Any) {
358-
return ConflictResolution::LinkFromDst;
360+
return ConflictResolution::LinkFromDst;
359361
}
360362
if (srcComdat == mlir::LLVM::comdat::Comdat::NoDeduplicate) {
361-
return ConflictResolution::Failure;
363+
return ConflictResolution::Failure;
362364
}
363365
llvm_unreachable("unimplemented comdat kind");
364366
}
365367

368+
// If we reach here, we have two external definitions that can't be resolved
369+
// This is typically an error case in LLVM linking
370+
if (isExternalLinkage(srcLinkage) && isExternalLinkage(dstLinkage) &&
371+
!srcIsDeclaration && !dstIsDeclaration) {
372+
return ConflictResolution::Failure;
373+
}
374+
366375
llvm_unreachable("unimplemented conflict resolution");
367376
}
368377
};

mlir/lib/Dialect/LLVMIR/IR/LLVMLinkerInterface.cpp

Lines changed: 33 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -85,23 +85,25 @@ static bool hasComdat(Operation *op) {
8585
static SymbolRefAttr getComdatSymbol(Operation *op) {
8686
assert(hasComdat(op) && "Operation with Comdat expected");
8787
if (auto gv = dyn_cast<LLVM::GlobalOp>(op))
88-
return gv.getComdat().value();
88+
return gv.getComdat().value();
8989
if (auto fn = dyn_cast<LLVM::LLVMFuncOp>(op))
90-
return fn.getComdat().value();
90+
return fn.getComdat().value();
9191
llvm_unreachable("unexpected operation");
9292
}
9393

9494
bool LLVM::LLVMSymbolLinkerInterface::isComdat(Operation *op) {
9595
return isa<LLVM::ComdatOp>(op);
9696
}
9797

98-
std::optional<mlir::link::ComdatSelector> LLVM::LLVMSymbolLinkerInterface::getComdatSelector(Operation *op) {
98+
std::optional<mlir::link::ComdatSelector>
99+
LLVM::LLVMSymbolLinkerInterface::getComdatSelector(Operation *op) {
99100
if (!hasComdat(op))
100101
return std::nullopt;
101102

102103
auto symbol = getComdatSymbol(op);
103104
auto *symTabOp = SymbolTable::getNearestSymbolTable(op);
104-
auto comdatSelector = cast<mlir::LLVM::ComdatSelectorOp>(SymbolTable::lookupSymbolIn(symTabOp, symbol));
105+
auto comdatSelector = cast<mlir::LLVM::ComdatSelectorOp>(
106+
SymbolTable::lookupSymbolIn(symTabOp, symbol));
105107
return {{comdatSelector.getSymName(), comdatSelector.getComdat()}};
106108
}
107109

@@ -112,7 +114,8 @@ bool LLVM::LLVMSymbolLinkerInterface::isDeclaration(Operation *op) {
112114
return gv.getInitializerRegion().empty() && !gv.getValue();
113115
if (auto fn = dyn_cast<LLVM::LLVMFuncOp>(op))
114116
return fn.getBody().empty();
115-
if (isa<LLVM::GlobalCtorsOp, LLVM::GlobalDtorsOp, LLVM::ComdatOp, LLVM::AliasOp>(op))
117+
if (isa<LLVM::GlobalCtorsOp, LLVM::GlobalDtorsOp, LLVM::ComdatOp,
118+
LLVM::AliasOp>(op))
116119
return false;
117120
llvm_unreachable("unexpected operation");
118121
}
@@ -446,48 +449,50 @@ getAppendedOpWithInitRegion(llvm::ArrayRef<mlir::Operation *> globs,
446449
return targetGV;
447450
}
448451

449-
static Operation *appendGlobalOps(ArrayRef<Operation *> globs, LLVM::GlobalOp lastGV, LinkState &state) {
452+
static Operation *appendGlobalOps(ArrayRef<Operation *> globs,
453+
LLVM::GlobalOp lastGV, LinkState &state) {
450454
// Src ops that are declarations are ignored in favour of dst operation
451455
// This mimics the behaviour of linkAppendingVarProto in llvm-link
452456
if (globs.size() == 1)
453-
return state.clone(globs.front());
457+
return state.clone(globs.front());
454458

455459
if (!lastGV.getInitializer().empty()) {
456-
return getAppendedOpWithInitRegion(globs, state);
460+
return getAppendedOpWithInitRegion(globs, state);
457461
} else {
458-
auto [value, type] = getAppendedAttr(globs, state);
462+
auto [value, type] = getAppendedAttr(globs, state);
459463

460-
auto valueAttrName = lastGV.getValueAttrName();
461-
auto typeAttrName = lastGV.getGlobalTypeAttrName();
464+
auto valueAttrName = lastGV.getValueAttrName();
465+
auto typeAttrName = lastGV.getGlobalTypeAttrName();
462466

463-
auto cloned = state.clone(globs.back());
464-
cloned->setAttr(valueAttrName, value);
465-
cloned->setAttr(typeAttrName, TypeAttr::get(type));
466-
return cloned;
467+
auto cloned = state.clone(globs.back());
468+
cloned->setAttr(valueAttrName, value);
469+
cloned->setAttr(typeAttrName, TypeAttr::get(type));
470+
return cloned;
467471
}
468472
llvm_unreachable("unknown value attribute type");
469473
}
470474

471-
static Operation *appendComdatOps(ArrayRef<Operation *> globs, LLVM::ComdatOp comdat, LinkState &state) {
475+
static Operation *appendComdatOps(ArrayRef<Operation *> globs,
476+
LLVM::ComdatOp comdat, LinkState &state) {
472477
auto result = cast<LLVM::ComdatOp>(state.clone(comdat));
473478
llvm::StringMap<Operation *> selectors;
474479

475480
for (auto selector : result.getOps<LLVM::ComdatSelectorOp>()) {
476-
selectors[selector.getSymName()] = selector;
481+
selectors[selector.getSymName()] = selector;
477482
}
478483

479484
for (auto *glob : globs) {
480485
comdat = dyn_cast<LLVM::ComdatOp>(glob);
481-
for (auto &op : comdat.getBody().getOps()) {
482-
auto selector = cast<LLVM::ComdatSelectorOp>(op);
483-
auto selectorName = selector.getSymName();
484-
if (selectors.contains(selectorName)) {
485-
continue;
486-
}
487-
auto *cloned = state.clone(selector);
488-
cloned->moveBefore(&result.getBody().front().back());
489-
selectors[selectorName] = cloned;
486+
for (auto &op : comdat.getBody().getOps()) {
487+
auto selector = cast<LLVM::ComdatSelectorOp>(op);
488+
auto selectorName = selector.getSymName();
489+
if (selectors.contains(selectorName)) {
490+
continue;
490491
}
492+
auto *cloned = state.clone(selector);
493+
cloned->moveBefore(&result.getBody().front().back());
494+
selectors[selectorName] = cloned;
495+
}
491496
}
492497
return result;
493498
}
@@ -500,6 +505,8 @@ Operation *LLVM::LLVMSymbolLinkerInterface::appendGlobals(llvm::StringRef glob,
500505
return appendGlobalStructors<LLVM::GlobalDtorsOp>(state);
501506

502507
const auto &globs = append.lookup(glob);
508+
if (globs.empty())
509+
return nullptr;
503510
if (auto lastGV = dyn_cast<LLVM::GlobalOp>(globs.back()))
504511
return appendGlobalOps(globs, lastGV, state);
505512
if (auto comdat = dyn_cast<LLVM::ComdatOp>(globs.back()))

0 commit comments

Comments
 (0)