Index: ELF/InputSection.h =================================================================== --- ELF/InputSection.h +++ ELF/InputSection.h @@ -227,13 +227,12 @@ // be found by looking at the next one). struct SectionPiece { SectionPiece(size_t Off, uint32_t Hash, bool Live) - : InputOff(Off), Hash(Hash), OutputOff(0), - Live(Live || !Config->GcSections) {} + : InputOff(Off), Live(Live || !Config->GcSections), Hash(Hash >> 1) {} uint32_t InputOff; - uint32_t Hash; - int64_t OutputOff : 63; - uint64_t Live : 1; + uint32_t Live : 1; + uint32_t Hash : 31; + uint64_t OutputOff = 0; }; static_assert(sizeof(SectionPiece) == 16, "SectionPiece is too big"); Index: ELF/SyntheticSections.h =================================================================== --- ELF/SyntheticSections.h +++ ELF/SyntheticSections.h @@ -859,7 +859,8 @@ // If we use lower bits, it significantly increases the probability of // hash collisons. size_t getShardId(uint32_t Hash) { - return Hash >> (32 - llvm::countTrailingZeros(NumShards)); + assert((Hash >> 31) == 0); + return Hash >> (31 - llvm::countTrailingZeros(NumShards)); } // Section size Index: ELF/SyntheticSections.cpp =================================================================== --- ELF/SyntheticSections.cpp +++ ELF/SyntheticSections.cpp @@ -2876,8 +2876,10 @@ parallelForEachN(0, Concurrency, [&](size_t ThreadId) { for (MergeInputSection *Sec : Sections) { for (size_t I = 0, E = Sec->Pieces.size(); I != E; ++I) { + if (!Sec->Pieces[I].Live) + continue; size_t ShardId = getShardId(Sec->Pieces[I].Hash); - if ((ShardId & (Concurrency - 1)) == ThreadId && Sec->Pieces[I].Live) + if ((ShardId & (Concurrency - 1)) == ThreadId) Sec->Pieces[I].OutputOff = Shards[ShardId].add(Sec->getData(I)); } }