Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[utils/TableGen/X86CompressEVEXTablesEmitter.cpp] Make sure the tablegen output for the checkPredicate function is deterministic #84533

Merged
merged 1 commit into from
Mar 10, 2024

Conversation

akyrtzi
Copy link
Contributor

@akyrtzi akyrtzi commented Mar 8, 2024

The output for the checkPredicate function was depending on a std::map iteration that was non-deterministic from run to run, because the keys were pointer values.

Make a change so that the keys are StringRefs so the ordering is stable.

@llvmbot
Copy link
Collaborator

llvmbot commented Mar 8, 2024

@llvm/pr-subscribers-backend-x86

Author: Argyrios Kyrtzidis (akyrtzi)

Changes

The output for the checkPredicate function was depending on a std::map iteration that was not deterministic from run to run, so the contents of X86GenCompressEVEXTables.inc were not deterministic.

Make a change to sort the entries before iterating over them.


Full diff: https://github.com/llvm/llvm-project/pull/84533.diff

1 Files Affected:

  • (modified) llvm/utils/TableGen/X86CompressEVEXTablesEmitter.cpp (+15-3)
diff --git a/llvm/utils/TableGen/X86CompressEVEXTablesEmitter.cpp b/llvm/utils/TableGen/X86CompressEVEXTablesEmitter.cpp
index b96d16b9797cf3..326a9dfbcfefaa 100644
--- a/llvm/utils/TableGen/X86CompressEVEXTablesEmitter.cpp
+++ b/llvm/utils/TableGen/X86CompressEVEXTablesEmitter.cpp
@@ -82,15 +82,27 @@ void X86CompressEVEXTablesEmitter::printTable(const std::vector<Entry> &Table,
 
 void X86CompressEVEXTablesEmitter::printCheckPredicate(
     const PredicateInstMap &PredicateInsts, raw_ostream &OS) {
+  // Create a sorted list of the map entries so that the tablegen output is
+  // deterministic.
+  typedef std::pair<StringRef, const std::vector<const CodeGenInstruction *> *>
+      PredicateInstsTy;
+  std::vector<PredicateInstsTy> SortedPredicateInsts;
+  for (const auto &[Key, Val] : PredicateInsts) {
+    SortedPredicateInsts.push_back({Key->getValueAsString("CondString"), &Val});
+  }
+  llvm::sort(SortedPredicateInsts,
+             [](const PredicateInstsTy &LHS, const PredicateInstsTy &RHS) {
+               return LHS.first < RHS.first;
+             });
 
   OS << "static bool checkPredicate(unsigned Opc, const X86Subtarget "
         "*Subtarget) {\n"
      << "  switch (Opc) {\n"
      << "  default: return true;\n";
-  for (const auto &[Key, Val] : PredicateInsts) {
-    for (const auto &Inst : Val)
+  for (const auto &[Key, Val] : SortedPredicateInsts) {
+    for (const auto &Inst : *Val)
       OS << "  case X86::" << Inst->TheDef->getName() << ":\n";
-    OS << "    return " << Key->getValueAsString("CondString") << ";\n";
+    OS << "    return " << Key << ";\n";
   }
 
   OS << "  }\n";

@KanRobert
Copy link
Contributor

Not understand. I believe std::map is a red-black tree and the iterations on it is deterministic.

@akyrtzi
Copy link
Contributor Author

akyrtzi commented Mar 9, 2024

It's non-deterministic because the keys are pointer values, so ordering for them is not stable between runs.

@KanRobert
Copy link
Contributor

It's non-deterministic because the keys are pointer values, so ordering for them is not stable between runs.

I see. Could we change the type of PredicateInstMap to

std::map<StringRef, std::vector<const CodeGenInstruction *>>
      PredicateInstMap;

where the StringRef is the CondString of the predicate. So that we don't have to resort it after the map is constructed.

…gen output for the `checkPredicate` function is deterministic

The output for the `checkPredicate` function was depending on a `std::map` iteration that was non-deterministic from run to run,
because the keys were pointer values.

Make a change so that the keys are `StringRef`s so the ordering is stable.
@akyrtzi akyrtzi force-pushed the akyrtzi/pr/deterministic-evex-predicate branch from 803bd40 to 20c3748 Compare March 9, 2024 03:58
@akyrtzi
Copy link
Contributor Author

akyrtzi commented Mar 9, 2024

Could we change the type of PredicateInstMap

I like this idea, see updated commit.

Copy link
Contributor

@KanRobert KanRobert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks!

@KanRobert
Copy link
Contributor

Friendly remind: Need to update the description.

@akyrtzi
Copy link
Contributor Author

akyrtzi commented Mar 9, 2024

Updated 👍

@akyrtzi akyrtzi merged commit d2353ae into llvm:main Mar 10, 2024
4 checks passed
@akyrtzi akyrtzi deleted the akyrtzi/pr/deterministic-evex-predicate branch March 10, 2024 06:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants