From: Eli Friedman Date: Sat, 1 Jun 2019 00:08:54 +0000 (+0000) Subject: [CodeGen] Fix hashing for MO_ExternalSymbol MachineOperands. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=22f0ee179f0a27a56b349a6e0098096f08b777e8;p=llvm [CodeGen] Fix hashing for MO_ExternalSymbol MachineOperands. We were hashing the string pointer, not the string, so two instructions could be identical (isIdenticalTo), but have different hash codes. This showed up as a very rare, non-deterministic assertion failure rehashing a DenseMap constructed by MachineOutliner. So there's no "real" testcase, just a unittest which checks that the hash function behaves correctly. I'm a little scared fixing this is going to cause a regression in outlining or MachineCSE, but hopefully we won't run into any issues. Differential Revision: https://reviews.llvm.org/D61975 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@362281 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/MachineOperand.cpp b/lib/CodeGen/MachineOperand.cpp index a83459e6917..9458745733f 100644 --- a/lib/CodeGen/MachineOperand.cpp +++ b/lib/CodeGen/MachineOperand.cpp @@ -361,7 +361,7 @@ hash_code llvm::hash_value(const MachineOperand &MO) { return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex()); case MachineOperand::MO_ExternalSymbol: return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getOffset(), - MO.getSymbolName()); + StringRef(MO.getSymbolName())); case MachineOperand::MO_GlobalAddress: return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getGlobal(), MO.getOffset()); diff --git a/unittests/CodeGen/MachineOperandTest.cpp b/unittests/CodeGen/MachineOperandTest.cpp index cfedfa9c883..faa471f2260 100644 --- a/unittests/CodeGen/MachineOperandTest.cpp +++ b/unittests/CodeGen/MachineOperandTest.cpp @@ -398,4 +398,14 @@ TEST(MachineOperandTest, PrintPredicate) { ASSERT_TRUE(OS.str() == "intpred(eq)"); } +TEST(MachineOperandTest, HashValue) { + char SymName1[] = "test"; + char SymName2[] = "test"; + MachineOperand MO1 = MachineOperand::CreateES(SymName1); + MachineOperand MO2 = MachineOperand::CreateES(SymName2); + ASSERT_NE(SymName1, SymName2); + ASSERT_EQ(hash_value(MO1), hash_value(MO2)); + ASSERT_TRUE(MO1.isIdenticalTo(MO2)); +} + } // end namespace