[llvm] [CodeGen] Fix non-determinism in MachineBlockHashInfo hashes (PR #192826)
Vitaly Buka via llvm-commits
llvm-commits at lists.llvm.org
Sun Apr 19 11:09:28 PDT 2026
https://github.com/vitalybuka updated https://github.com/llvm/llvm-project/pull/192826
>From 7de6ee285c3a165772683994b92e63e1d9b1a90e Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Sat, 18 Apr 2026 21:44:41 -0700
Subject: [PATCH 1/4] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20ch?=
=?UTF-8?q?anges=20to=20main=20this=20commit=20is=20based=20on?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.7
[skip ci]
---
.../CodeGen/BasicBlockMatchingAndInference.cpp | 4 ++--
llvm/lib/CodeGen/MachineBlockHashInfo.cpp | 17 +++++++++--------
2 files changed, 11 insertions(+), 10 deletions(-)
diff --git a/llvm/lib/CodeGen/BasicBlockMatchingAndInference.cpp b/llvm/lib/CodeGen/BasicBlockMatchingAndInference.cpp
index bba4c4a220d9e..d956bd475c9e6 100644
--- a/llvm/lib/CodeGen/BasicBlockMatchingAndInference.cpp
+++ b/llvm/lib/CodeGen/BasicBlockMatchingAndInference.cpp
@@ -19,12 +19,12 @@
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/BasicBlockMatchingAndInference.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/CodeGen/BasicBlockSectionsProfileReader.h"
#include "llvm/CodeGen/MachineBlockHashInfo.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/InitializePasses.h"
#include <llvm/Support/CommandLine.h>
-#include <unordered_map>
using namespace llvm;
@@ -70,7 +70,7 @@ class StaleMatcher {
private:
using HashBlockPairType = std::pair<BlendedBlockHash, MachineBasicBlock *>;
- std::unordered_map<uint16_t, std::vector<HashBlockPairType>> OpHashToBlocks;
+ DenseMap<uint16_t, std::vector<HashBlockPairType>> OpHashToBlocks;
};
INITIALIZE_PASS_BEGIN(BasicBlockMatchingAndInference,
diff --git a/llvm/lib/CodeGen/MachineBlockHashInfo.cpp b/llvm/lib/CodeGen/MachineBlockHashInfo.cpp
index 73dfc7c62a95c..3aa3823731396 100644
--- a/llvm/lib/CodeGen/MachineBlockHashInfo.cpp
+++ b/llvm/lib/CodeGen/MachineBlockHashInfo.cpp
@@ -17,7 +17,7 @@
using namespace llvm;
-uint64_t hashBlock(const MachineBasicBlock &MBB, bool HashOperands) {
+static uint64_t hashBlock(const MachineBasicBlock &MBB, bool HashOperands) {
uint64_t Hash = 0;
for (const MachineInstr &MI : MBB) {
if (MI.isMetaInstruction() || MI.isTerminator())
@@ -34,7 +34,7 @@ uint64_t hashBlock(const MachineBasicBlock &MBB, bool HashOperands) {
}
/// Fold a 64-bit integer to a 16-bit one.
-uint16_t fold_64_to_16(const uint64_t Value) {
+static uint16_t fold_64_to_16(const uint64_t Value) {
uint16_t Res = static_cast<uint16_t>(Value);
Res ^= static_cast<uint16_t>(Value >> 16);
Res ^= static_cast<uint16_t>(Value >> 32);
@@ -66,18 +66,19 @@ bool MachineBlockHashInfo::runOnMachineFunction(MachineFunction &F) {
uint16_t Offset = 0;
// Initialize hash components
for (const MachineBasicBlock &MBB : F) {
+ auto &HashInfo = HashInfos[&MBB];
// offset of the machine basic block
- HashInfos[&MBB].Offset = Offset;
- Offset += MBB.size();
+ HashInfo.Offset = Offset + MBB.size();
// Hashing opcodes
- HashInfos[&MBB].OpcodeHash = hashBlock(MBB, /*HashOperands=*/false);
+ HashInfo.OpcodeHash = hashBlock(MBB, /*HashOperands=*/false);
// Hash complete instructions
- HashInfos[&MBB].InstrHash = hashBlock(MBB, /*HashOperands=*/true);
+ HashInfo.InstrHash = hashBlock(MBB, /*HashOperands=*/true);
}
// Initialize neighbor hash
for (const MachineBasicBlock &MBB : F) {
- uint64_t Hash = HashInfos[&MBB].OpcodeHash;
+ auto &HashInfo = HashInfos[&MBB];
+ uint64_t Hash = HashInfo.OpcodeHash;
// Append hashes of successors
for (const MachineBasicBlock *SuccMBB : MBB.successors()) {
uint64_t SuccHash = HashInfos[SuccMBB].OpcodeHash;
@@ -88,7 +89,7 @@ bool MachineBlockHashInfo::runOnMachineFunction(MachineFunction &F) {
uint64_t PredHash = HashInfos[PredMBB].OpcodeHash;
Hash = hashing::detail::hash_16_bytes(Hash, PredHash);
}
- HashInfos[&MBB].NeighborHash = Hash;
+ HashInfo.NeighborHash = Hash;
}
// Assign hashes
>From 4c11ef77e835061eb2a12c93f3f81904ee9829dd Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Sun, 19 Apr 2026 00:16:50 -0700
Subject: [PATCH 2/4] fix
Created using spr 1.3.7
---
llvm/lib/CodeGen/MachineBlockHashInfo.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/CodeGen/MachineBlockHashInfo.cpp b/llvm/lib/CodeGen/MachineBlockHashInfo.cpp
index 804986dac6ad2..2ad31d4fd87a8 100644
--- a/llvm/lib/CodeGen/MachineBlockHashInfo.cpp
+++ b/llvm/lib/CodeGen/MachineBlockHashInfo.cpp
@@ -43,7 +43,7 @@ static uint64_t hashValue(const APInt &I) {
return hashValue(ArrayRef(I.getRawData(), I.getNumWords()));
}
-template <typename T> static uint64_t ignoreValue(const T *I) { return 1; }
+template <typename T> static uint64_t ignoreValue(const T *) { return 1; }
static uint64_t hashCombine() { return 0; }
>From 1980cac4b3a5cc3fb712ea626ed29f0397593d88 Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Sun, 19 Apr 2026 00:28:27 -0700
Subject: [PATCH 3/4] include
Created using spr 1.3.7
---
llvm/lib/CodeGen/MachineBlockHashInfo.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/llvm/lib/CodeGen/MachineBlockHashInfo.cpp b/llvm/lib/CodeGen/MachineBlockHashInfo.cpp
index 2ad31d4fd87a8..b72a1a57b6435 100644
--- a/llvm/lib/CodeGen/MachineBlockHashInfo.cpp
+++ b/llvm/lib/CodeGen/MachineBlockHashInfo.cpp
@@ -14,6 +14,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/Constants.h"
#include "llvm/InitializePasses.h"
#include "llvm/Target/TargetMachine.h"
>From 15021a2c8383592bb1f04e999a35c1c7b9a1624a Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Sun, 19 Apr 2026 11:09:10 -0700
Subject: [PATCH 4/4] stableHashValue
Created using spr 1.3.7
---
llvm/lib/CodeGen/MachineBlockHashInfo.cpp | 103 +---------------------
1 file changed, 3 insertions(+), 100 deletions(-)
diff --git a/llvm/lib/CodeGen/MachineBlockHashInfo.cpp b/llvm/lib/CodeGen/MachineBlockHashInfo.cpp
index b72a1a57b6435..c0dd4968f05b6 100644
--- a/llvm/lib/CodeGen/MachineBlockHashInfo.cpp
+++ b/llvm/lib/CodeGen/MachineBlockHashInfo.cpp
@@ -11,111 +11,14 @@
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/MachineBlockHashInfo.h"
-#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/CodeGen/Passes.h"
-#include "llvm/IR/Constants.h"
#include "llvm/InitializePasses.h"
#include "llvm/Target/TargetMachine.h"
using namespace llvm;
-template <typename T>
-std::enable_if_t<is_integral_or_enum<T>::value, uint64_t>
-hashValue(const T &Val) {
- return static_cast<uint64_t>(Val);
-}
-
-static uint64_t hashValue(StringRef S) {
- uint64_t Hash = 0;
- for (char C : S)
- Hash = hashing::detail::hash_16_bytes(Hash, C);
- return Hash;
-}
-
-template <typename T> uint64_t hashValue(ArrayRef<T> A) {
- uint64_t Hash = 0;
- for (const auto &C : A)
- Hash = hashing::detail::hash_16_bytes(Hash, C);
- return Hash;
-}
-
-static uint64_t hashValue(const APInt &I) {
- return hashValue(ArrayRef(I.getRawData(), I.getNumWords()));
-}
-
-template <typename T> static uint64_t ignoreValue(const T *) { return 1; }
-
-static uint64_t hashCombine() { return 0; }
-
-template <typename T, typename... Ts>
-uint64_t hashCombine(const T &Hash, const Ts &...Args) {
- return hashing::detail::hash_16_bytes(hashValue(Hash), hashCombine(Args...));
-}
-
-// Similar to hash_code llvm::hash_value(const MachineOperand &MO) but stable.
-static uint64_t hashOperand(const MachineOperand &MO) {
- switch (MO.getType()) {
- case MachineOperand::MO_Register:
- // Register operands don't have target flags.
- return hashCombine(MO.getType(), MO.getReg().id(), MO.getSubReg(),
- MO.isDef());
- case MachineOperand::MO_Immediate:
- return hashCombine(MO.getType(), MO.getTargetFlags(), MO.getImm());
- case MachineOperand::MO_CImmediate:
- return hashCombine(MO.getType(), MO.getTargetFlags(),
- MO.getCImm()->getValue());
- case MachineOperand::MO_FPImmediate:
- return hashCombine(MO.getType(), MO.getTargetFlags(),
- MO.getFPImm()->getValue().bitcastToAPInt());
- case MachineOperand::MO_MachineBasicBlock:
- return hashCombine(MO.getType(), MO.getTargetFlags(),
- ignoreValue(MO.getMBB()));
- case MachineOperand::MO_FrameIndex:
- return hashCombine(MO.getType(), MO.getTargetFlags(), MO.getIndex());
- case MachineOperand::MO_ConstantPoolIndex:
- case MachineOperand::MO_TargetIndex:
- return hashCombine(MO.getType(), MO.getTargetFlags(), MO.getIndex(),
- MO.getOffset());
- case MachineOperand::MO_JumpTableIndex:
- return hashCombine(MO.getType(), MO.getTargetFlags(), MO.getIndex());
- case MachineOperand::MO_ExternalSymbol:
- return hashCombine(MO.getType(), MO.getTargetFlags(), MO.getOffset(),
- StringRef(MO.getSymbolName()));
- case MachineOperand::MO_GlobalAddress:
- return hashCombine(MO.getType(), MO.getTargetFlags(),
- ignoreValue(MO.getGlobal()), MO.getOffset());
- case MachineOperand::MO_BlockAddress:
- return hashCombine(MO.getType(), MO.getTargetFlags(),
- ignoreValue(MO.getBlockAddress()), MO.getOffset());
- case MachineOperand::MO_RegisterMask:
- case MachineOperand::MO_RegisterLiveOut:
- return hashCombine(MO.getType(), MO.getTargetFlags(),
- ignoreValue(MO.getRegMask()));
- case MachineOperand::MO_Metadata:
- return hashCombine(MO.getType(), MO.getTargetFlags(),
- ignoreValue(MO.getMetadata()));
- case MachineOperand::MO_MCSymbol:
- return hashCombine(MO.getType(), MO.getTargetFlags(),
- ignoreValue(MO.getMCSymbol()));
- case MachineOperand::MO_DbgInstrRef:
- return hashCombine(MO.getType(), MO.getTargetFlags(),
- MO.getInstrRefInstrIndex(), MO.getInstrRefOpIndex());
- case MachineOperand::MO_CFIIndex:
- return hashCombine(MO.getType(), MO.getTargetFlags(), MO.getCFIIndex());
- case MachineOperand::MO_IntrinsicID:
- return hashCombine(MO.getType(), MO.getTargetFlags(), MO.getIntrinsicID());
- case MachineOperand::MO_Predicate:
- return hashCombine(MO.getType(), MO.getTargetFlags(), MO.getPredicate());
- case MachineOperand::MO_ShuffleMask:
- return hashCombine(MO.getType(), MO.getTargetFlags(), MO.getShuffleMask());
- case MachineOperand::MO_LaneMask:
- return hashCombine(MO.getType(), MO.getTargetFlags(),
- MO.getLaneMask().getAsInteger());
- }
- llvm_unreachable("Invalid machine operand type");
-}
-
static uint64_t hashBlock(const MachineBasicBlock &MBB, bool HashOperands) {
uint64_t Hash = 0;
for (const MachineInstr &MI : MBB) {
@@ -124,8 +27,8 @@ static uint64_t hashBlock(const MachineBasicBlock &MBB, bool HashOperands) {
Hash = hashing::detail::hash_16_bytes(Hash, MI.getOpcode());
if (HashOperands) {
for (unsigned i = 0; i < MI.getNumOperands(); i++) {
- Hash =
- hashing::detail::hash_16_bytes(Hash, hashOperand(MI.getOperand(i)));
+ Hash = hashing::detail::hash_16_bytes(
+ Hash, stableHashValue(MI.getOperand(i)));
}
}
}
More information about the llvm-commits
mailing list