Index: ELF/ICF.cpp =================================================================== --- ELF/ICF.cpp +++ ELF/ICF.cpp @@ -78,6 +78,7 @@ #include "SymbolTable.h" #include "Symbols.h" #include "SyntheticSections.h" +#include "Writer.h" #include "lld/Common/Threads.h" #include "llvm/ADT/Hashing.h" #include "llvm/BinaryFormat/ELF.h" @@ -302,6 +303,13 @@ A->getSize() != B->getSize() || A->Data != B->Data) return false; + // If two sections have different output sections, we cannot merge them. + // FIXME: This doesn't do the right thing in the case where there is a linker + // script. We probably need to move output section assignment before ICF to + // get the correct behaviour here. + if (getOutputSectionName(A) != getOutputSectionName(B)) + return false; + if (A->AreRelocsRela) return constantEq(A, A->template relas(), B, B->template relas()); Index: ELF/InputSection.h =================================================================== --- ELF/InputSection.h +++ ELF/InputSection.h @@ -317,7 +317,7 @@ static bool classof(const SectionBase *S); - InputSectionBase *getRelocatedSection(); + InputSectionBase *getRelocatedSection() const; template void relocateNonAlloc(uint8_t *Buf, llvm::ArrayRef Rels); Index: ELF/InputSection.cpp =================================================================== --- ELF/InputSection.cpp +++ ELF/InputSection.cpp @@ -325,7 +325,7 @@ *To++ = Sections[Idx]->getOutputSection()->SectionIndex; } -InputSectionBase *InputSection::getRelocatedSection() { +InputSectionBase *InputSection::getRelocatedSection() const { if (!File || (Type != SHT_RELA && Type != SHT_REL)) return nullptr; ArrayRef Sections = File->getSections(); Index: ELF/Writer.h =================================================================== --- ELF/Writer.h +++ ELF/Writer.h @@ -48,7 +48,7 @@ }; void addReservedSymbols(); -llvm::StringRef getOutputSectionName(InputSectionBase *S); +llvm::StringRef getOutputSectionName(const InputSectionBase *S); template uint32_t calcMipsEFlags(); Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -92,7 +92,7 @@ return Name.startswith(Prefix) || Name == Prefix.drop_back(); } -StringRef elf::getOutputSectionName(InputSectionBase *S) { +StringRef elf::getOutputSectionName(const InputSectionBase *S) { if (Config->Relocatable) return S->Name; Index: test/ELF/icf-different-output-sections.s =================================================================== --- test/ELF/icf-different-output-sections.s +++ test/ELF/icf-different-output-sections.s @@ -0,0 +1,9 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: ld.lld %t -o %t2 --icf=all --print-icf-sections | count 0 + +.section foo,"ax" +.byte 42 + +.section bar,"ax" +.byte 42