[llvm] [llvm-dis] Fix non-deterministic disassembly across multiple inputs (PR #110988)

Peter Waller via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 7 02:05:32 PDT 2024


https://github.com/peterwaller-arm updated https://github.com/llvm/llvm-project/pull/110988

>From 7bde46ea935cc812ba9f3fb8b41b89fffd95e1bc Mon Sep 17 00:00:00 2001
From: Peter Waller <peter.waller at arm.com>
Date: Thu, 3 Oct 2024 13:17:08 +0100
Subject: [PATCH] [llvm-dis] Fix non-deterministic disassembly across multiple
 inputs

Prior to this patch, the LLVMContext was shared across inputs to
llvm-dis.

Consequently, NamedStructTypes was shared across inputs, which impacts
StructType::setName - if a name was reused across inputs, it would get
renamed during construction of the struct type, leading to tricky to
diagnose confusion.
---
 .../tools/llvm-dis/multiple-files-equivalent.ll   | 15 +++++++++++++++
 llvm/tools/llvm-dis/llvm-dis.cpp                  | 10 ++++++----
 2 files changed, 21 insertions(+), 4 deletions(-)
 create mode 100644 llvm/test/tools/llvm-dis/multiple-files-equivalent.ll

diff --git a/llvm/test/tools/llvm-dis/multiple-files-equivalent.ll b/llvm/test/tools/llvm-dis/multiple-files-equivalent.ll
new file mode 100644
index 00000000000000..21f7abb67b2866
--- /dev/null
+++ b/llvm/test/tools/llvm-dis/multiple-files-equivalent.ll
@@ -0,0 +1,15 @@
+; RUN: llvm-as -o %t0 %s
+; RUN: cp %t0 %t1
+; RUN: llvm-dis %t0 %t1
+; RUN: FileCheck %s < %t0.ll
+; RUN: FileCheck %s < %t1.ll
+
+; Test that if we disassemble the same bitcode twice, the type names are
+; unchanged between the two. This protects against a bug whereby state was
+; preserved across inputs and the types ended up with different names.
+
+; CHECK: %Foo = type { ptr }
+%Foo = type { ptr }
+
+; CHECK: @foo = global %Foo zeroinitializer
+ at foo = global %Foo zeroinitializer
diff --git a/llvm/tools/llvm-dis/llvm-dis.cpp b/llvm/tools/llvm-dis/llvm-dis.cpp
index 744201289b4a42..49acc9cd456ff4 100644
--- a/llvm/tools/llvm-dis/llvm-dis.cpp
+++ b/llvm/tools/llvm-dis/llvm-dis.cpp
@@ -191,10 +191,6 @@ int main(int argc, char **argv) {
   if (LoadBitcodeIntoNewDbgInfoFormat == cl::boolOrDefault::BOU_UNSET)
     LoadBitcodeIntoNewDbgInfoFormat = cl::boolOrDefault::BOU_TRUE;
 
-  LLVMContext Context;
-  Context.setDiagnosticHandler(
-      std::make_unique<LLVMDisDiagnosticHandler>(argv[0]));
-
   if (InputFilenames.size() < 1) {
     InputFilenames.push_back("-");
   } else if (InputFilenames.size() > 1 && !OutputFilename.empty()) {
@@ -204,6 +200,12 @@ int main(int argc, char **argv) {
   }
 
   for (const auto &InputFilename : InputFilenames) {
+    // Use a fresh context for each input to avoid state
+    // cross-contamination across inputs (e.g. type name collisions).
+    LLVMContext Context;
+    Context.setDiagnosticHandler(
+        std::make_unique<LLVMDisDiagnosticHandler>(argv[0]));
+
     ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
         MemoryBuffer::getFileOrSTDIN(InputFilename);
     if (std::error_code EC = BufferOrErr.getError()) {



More information about the llvm-commits mailing list