Index: ELF/SyntheticSections.h =================================================================== --- ELF/SyntheticSections.h +++ ELF/SyntheticSections.h @@ -619,6 +619,7 @@ void addSymbols(std::vector &Symbols); private: + // See the comment in writeBloomFilter. enum { Shift2 = 6 }; void writeBloomFilter(uint8_t *Buf); Index: ELF/SyntheticSections.cpp =================================================================== --- ELF/SyntheticSections.cpp +++ ELF/SyntheticSections.cpp @@ -2178,6 +2178,8 @@ for (const Entry &Sym : Symbols) { size_t I = (Sym.Hash / C) & (MaskWords - 1); uint64_t Val = readUint(Buf + I * Config->Wordsize); + // We choose Shift2 = 6 to give us 6 bits (nearly) independent from the low + // 6 bits, and thus less collision. Val |= uint64_t(1) << (Sym.Hash % C); Val |= uint64_t(1) << ((Sym.Hash >> Shift2) % C); writeUint(Buf + I * Config->Wordsize, Val); Index: test/ELF/gnu-hash-table-rwsegment.s =================================================================== --- test/ELF/gnu-hash-table-rwsegment.s +++ test/ELF/gnu-hash-table-rwsegment.s @@ -8,8 +8,8 @@ # CHECK-NEXT: Num Buckets: 1 # CHECK-NEXT: First Hashed Symbol Index: 1 # CHECK-NEXT: Num Mask Words: 1 -# CHECK-NEXT: Shift Count: 6 -# CHECK-NEXT: Bloom Filter: [0x400000000004204] +# CHECK-NEXT: Shift Count: 26 +# CHECK-NEXT: Bloom Filter: [0x400000000000204] # CHECK-NEXT: Buckets: [1] # CHECK-NEXT: Values: [0xB8860BA, 0xB887389] # CHECK-NEXT: } Index: test/ELF/gnu-hash-table.s =================================================================== --- test/ELF/gnu-hash-table.s +++ test/ELF/gnu-hash-table.s @@ -62,7 +62,7 @@ # EMPTY-NEXT: Num Buckets: 1 # EMPTY-NEXT: First Hashed Symbol Index: 2 # EMPTY-NEXT: Num Mask Words: 1 -# EMPTY-NEXT: Shift Count: 6 +# EMPTY-NEXT: Shift Count: 26 # EMPTY-NEXT: Bloom Filter: [0x0] # EMPTY-NEXT: Buckets: [0] # EMPTY-NEXT: Values: [] @@ -121,8 +121,8 @@ # I386-NEXT: Num Buckets: 1 # I386-NEXT: First Hashed Symbol Index: 4 # I386-NEXT: Num Mask Words: 1 -# I386-NEXT: Shift Count: 6 -# I386-NEXT: Bloom Filter: [0x4004204] +# I386-NEXT: Shift Count: 26 +# I386-NEXT: Bloom Filter: [0x4000204] # I386-NEXT: Buckets: [4] # I386-NEXT: Values: [0xB8860BA, 0xB887389] # I386-NEXT: } @@ -181,8 +181,8 @@ # X86_64-NEXT: Num Buckets: 1 # X86_64-NEXT: First Hashed Symbol Index: 4 # X86_64-NEXT: Num Mask Words: 1 -# X86_64-NEXT: Shift Count: 6 -# X86_64-NEXT: Bloom Filter: [0x400000000004204] +# X86_64-NEXT: Shift Count: 26 +# X86_64-NEXT: Bloom Filter: [0x400000000000204] # X86_64-NEXT: Buckets: [4] # X86_64-NEXT: Values: [0xB8860BA, 0xB887389] # X86_64-NEXT: } @@ -241,8 +241,8 @@ # PPC64-NEXT: Num Buckets: 1 # PPC64-NEXT: First Hashed Symbol Index: 4 # PPC64-NEXT: Num Mask Words: 1 -# PPC64-NEXT: Shift Count: 6 -# PPC64-NEXT: Bloom Filter: [0x400000000004204] +# PPC64-NEXT: Shift Count: 26 +# PPC64-NEXT: Bloom Filter: [0x400000000000204] # PPC64-NEXT: Buckets: [4] # PPC64-NEXT: Values: [0xB8860BA, 0xB887389] # PPC64-NEXT: }