diff options
author | Dale Johannesen <dalej@apple.com> | 2010-11-19 00:48:58 +0000 |
---|---|---|
committer | Dale Johannesen <dalej@apple.com> | 2010-11-19 00:48:58 +0000 |
commit | 461e704a2c5d19521505dc85fb5022afea8b56dc (patch) | |
tree | 78f7c31edeafa2bdf65711d18b3075806071b3f0 /llvm/lib/Support/FoldingSet.cpp | |
parent | 20b5ea98583a7e00574be4ee32ebac517d918acf (diff) | |
download | bcm5719-llvm-461e704a2c5d19521505dc85fb5022afea8b56dc.tar.gz bcm5719-llvm-461e704a2c5d19521505dc85fb5022afea8b56dc.zip |
Aligned and unaligned copies of the same string
were not hashing to the same value. Analysis
and patch by Frits van Bommel!
llvm-svn: 119770
Diffstat (limited to 'llvm/lib/Support/FoldingSet.cpp')
-rw-r--r-- | llvm/lib/Support/FoldingSet.cpp | 29 |
1 files changed, 22 insertions, 7 deletions
diff --git a/llvm/lib/Support/FoldingSet.cpp b/llvm/lib/Support/FoldingSet.cpp index 29b59522088..11a1de4a953 100644 --- a/llvm/lib/Support/FoldingSet.cpp +++ b/llvm/lib/Support/FoldingSet.cpp @@ -18,6 +18,7 @@ #include "llvm/Support/Allocator.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MathExtras.h" +#include "llvm/System/Host.h" #include <cassert> #include <cstring> using namespace llvm; @@ -110,18 +111,32 @@ void FoldingSetNodeID::AddString(StringRef String) { Pos = (Units + 1) * 4; } else { // Otherwise do it the hard way. - for (Pos += 4; Pos <= Size; Pos += 4) { - unsigned V = ((unsigned char)String[Pos - 4] << 24) | - ((unsigned char)String[Pos - 3] << 16) | - ((unsigned char)String[Pos - 2] << 8) | - (unsigned char)String[Pos - 1]; - Bits.push_back(V); + // To be compatible with above bulk transfer, we need to take endianness + // into account. + if (sys::isBigEndianHost()) { + for (Pos += 4; Pos <= Size; Pos += 4) { + unsigned V = ((unsigned char)String[Pos - 4] << 24) | + ((unsigned char)String[Pos - 3] << 16) | + ((unsigned char)String[Pos - 2] << 8) | + (unsigned char)String[Pos - 1]; + Bits.push_back(V); + } + } else { + assert(sys::isLittleEndianHost() && "Unexpected host endianness"); + for (Pos += 4; Pos <= Size; Pos += 4) { + unsigned V = ((unsigned char)String[Pos - 1] << 24) | + ((unsigned char)String[Pos - 2] << 16) | + ((unsigned char)String[Pos - 3] << 8) | + (unsigned char)String[Pos - 4]; + Bits.push_back(V); + } } } // With the leftover bits. unsigned V = 0; - // Pos will have overshot size by 4 - #bytes left over. + // Pos will have overshot size by 4 - #bytes left over. + // No need to take endianness into account here - this is always executed. switch (Pos - Size) { case 1: V = (V << 8) | (unsigned char)String[Size - 3]; // Fall thru. case 2: V = (V << 8) | (unsigned char)String[Size - 2]; // Fall thru. |