[lld] [lld][macho] Move unwind logic from equalsVariable to equalsConstant (PR #165325)

Ellis Hoag via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 27 15:20:47 PDT 2025


================
@@ -179,8 +179,30 @@ bool ICF::equalsConstant(const ConcatInputSection *ia,
       return isecA->getOffset(ra.addend) == isecB->getOffset(rb.addend);
     }
   };
-  return std::equal(ia->relocs.begin(), ia->relocs.end(), ib->relocs.begin(),
-                    f);
+  if (!std::equal(ia->relocs.begin(), ia->relocs.end(), ib->relocs.begin(), f))
+    return false;
+
+  // Check unwind info structural compatibility: if there are symbols with
+  // associated unwind info, check that both sections have compatible symbol
+  // layouts. For simplicity, we only attempt folding when all symbols are at
+  // offset zero within the section (which is typically the case with
+  // .subsections_via_symbols.)
+  auto hasUnwind = [](Defined *d) { return d->unwindEntry() != nullptr; };
+  const auto *itA = llvm::find_if(ia->symbols, hasUnwind);
+  const auto *itB = llvm::find_if(ib->symbols, hasUnwind);
+  if (itA == ia->symbols.end())
+    return itB == ib->symbols.end();
+  if (itB == ib->symbols.end())
+    return false;
+  const Defined *da = *itA;
+  const Defined *db = *itB;
+  if (da->value != 0 || db->value != 0)
+    return false;
+  auto isZero = [](Defined *d) { return d->value == 0; };
+  return std::find_if_not(std::next(itA), ia->symbols.end(), isZero) ==
+             ia->symbols.end() &&
+         std::find_if_not(std::next(itB), ib->symbols.end(), isZero) ==
+             ib->symbols.end();
----------------
ellishg wrote:

This doesn't check if all symbols have offset zero, it only checks if all symbols after the first one with unwind info has offset zero. Is that what we want?

https://github.com/llvm/llvm-project/pull/165325


More information about the llvm-commits mailing list