@@ -144,6 +144,12 @@ struct ComdatSelector {
144144 ComdatKind kind;
145145};
146146
147+ struct Comdat {
148+ ComdatKind kind;
149+ StringRef name;
150+ llvm::SmallPtrSet< Operation *, 2 > users;
151+ };
152+
147153// ===----------------------------------------------------------------------===//
148154// LLVMLinkerMixin
149155// ===----------------------------------------------------------------------===//
@@ -172,6 +178,12 @@ class LLVMLinkerMixin {
172178 if (derived.isComdat (pair.src ))
173179 return true ;
174180
181+ if (std::optional<link::ConflictResolution> res =
182+ derived.getComdatResolution (pair.src )) {
183+ // Comdats are either used or dropped as a group
184+ return res.value () == ConflictResolution::LinkFromSrc;
185+ }
186+
175187 Linkage srcLinkage = derived.getLinkage (pair.src );
176188
177189 // Always import variables with appending linkage.
@@ -218,6 +230,10 @@ class LLVMLinkerMixin {
218230 return pair.src ->emitError (error) << " dst: " << pair.dst ->getLoc ();
219231 };
220232
233+ if (derived.isComdat (pair.src ) != derived.isComdat (pair.dst )) {
234+ return linkError (" Linking ComdatOp with non-comdat op" );
235+ }
236+
221237 Linkage srcLinkage = derived.getLinkage (pair.src );
222238 Linkage dstLinkage = derived.getLinkage (pair.dst );
223239
@@ -259,6 +275,11 @@ class LLVMLinkerMixin {
259275 assert (derived.canBeLinked (pair.src ) && " expected linkable operation" );
260276 assert (derived.canBeLinked (pair.dst ) && " expected linkable operation" );
261277
278+ // We insert the computed comdat information into the dst module comdat op
279+ // Make sure it is linked in as we want
280+ if (derived.isComdat (pair.src ))
281+ return ConflictResolution::LinkFromDst;
282+
262283 Linkage srcLinkage = derived.getLinkage (pair.src );
263284 Linkage dstLinkage = derived.getLinkage (pair.dst );
264285
@@ -352,37 +373,6 @@ class LLVMLinkerMixin {
352373 return ConflictResolution::LinkFromSrc;
353374 }
354375
355- std::optional<ComdatSelector> srcComdatSel =
356- derived.getComdatSelector (pair.src );
357- std::optional<ComdatSelector> dstComdatSel =
358- derived.getComdatSelector (pair.dst );
359- if (srcComdatSel.has_value () && dstComdatSel.has_value ()) {
360- auto srcComdatName = srcComdatSel->name ;
361- auto dstComdatName = dstComdatSel->name ;
362- auto srcComdat = srcComdatSel->kind ;
363- auto dstComdat = dstComdatSel->kind ;
364- if (srcComdatName != dstComdatName) {
365- llvm_unreachable (" Comdat selector names don't match" );
366- }
367- if (srcComdat != dstComdat) {
368- llvm_unreachable (" Comdat selector kinds don't match" );
369- }
370-
371- if (srcComdat == mlir::LLVM::comdat::Comdat::Any) {
372- return ConflictResolution::LinkFromDst;
373- }
374- if (srcComdat == mlir::LLVM::comdat::Comdat::NoDeduplicate) {
375- return ConflictResolution::Failure;
376- }
377- if (srcComdat == mlir::LLVM::comdat::Comdat::ExactMatch) {
378- return ConflictResolution::LinkFromDst;
379- }
380- if (srcComdat == mlir::LLVM::comdat::Comdat::SameSize) {
381- return ConflictResolution::LinkFromDst;
382- }
383- llvm_unreachable (" unimplemented comdat kind" );
384- }
385-
386376 // If we reach here, we have two external definitions that can't be resolved
387377 // This is typically an error case in LLVM linking
388378 if (isExternalLinkage (srcLinkage) && isExternalLinkage (dstLinkage) &&
0 commit comments