[llvm] Fix clang crash with -print-changed=dot-cfg (PR #148844)

Ruoyu Qiu via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 22 02:09:30 PDT 2025


https://github.com/cabbaken updated https://github.com/llvm/llvm-project/pull/148844

>From aa2a56a651903a27084f1ba4fe97e7913118caac Mon Sep 17 00:00:00 2001
From: Ruoyu Qiu <qiuruoyu at xiaomi.com>
Date: Tue, 15 Jul 2025 12:49:04 +0000
Subject: [PATCH 1/3] Fix clang crash with -print-changed=dot-cfg

Remove unnecessary comparison of Before and After `DCData`,
which will cause an error when create `DotCfgDiff`.

Signed-off-by: Ruoyu Qiu <cabbaken at outlook.com>
---
 llvm/lib/Passes/StandardInstrumentations.cpp | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/llvm/lib/Passes/StandardInstrumentations.cpp b/llvm/lib/Passes/StandardInstrumentations.cpp
index 0623e66772047..bbd8ca430139c 100644
--- a/llvm/lib/Passes/StandardInstrumentations.cpp
+++ b/llvm/lib/Passes/StandardInstrumentations.cpp
@@ -1991,6 +1991,11 @@ DotCfgDiff::DotCfgDiff(StringRef Title, const FuncDataT<DCData> &Before,
       EdgesMap.insert({Key, BeforeColour});
     }
   }
+  if (Before == After) {
+    for (auto &I : Nodes)
+      I.finalize(*this);
+    return;
+  }
 
   // Handle each basic block in the after IR
   for (auto &A : After.getData()) {

>From 88a7e60d0e05dff6678c2f7bb6bff6010e58e629 Mon Sep 17 00:00:00 2001
From: Ruoyu Qiu <cabbaken at outlook.com>
Date: Mon, 21 Jul 2025 05:21:05 +0000
Subject: [PATCH 2/3] Modify testcase and add support numberic label which has
 empty EntryBlockName

Signed-off-by: Ruoyu Qiu <cabbaken at outlook.com>
---
 llvm/lib/Passes/StandardInstrumentations.cpp               | 7 ++++++-
 .../Other/ChangePrinters/DotCfg/print-changed-dot-cfg.ll   | 2 +-
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Passes/StandardInstrumentations.cpp b/llvm/lib/Passes/StandardInstrumentations.cpp
index bbd8ca430139c..0abf77b65e5a4 100644
--- a/llvm/lib/Passes/StandardInstrumentations.cpp
+++ b/llvm/lib/Passes/StandardInstrumentations.cpp
@@ -727,8 +727,13 @@ template <typename T>
 template <typename FunctionT>
 bool IRComparer<T>::generateFunctionData(IRDataT<T> &Data, const FunctionT &F) {
   if (shouldGenerateData(F)) {
-    FuncDataT<T> FD(F.front().getName().str());
     int I = 0;
+    std::string FDEntryBlockName = F.front().getName().str();
+    // Basic block with numberic label will be empty here.
+    if (FDEntryBlockName.empty()) {
+      FDEntryBlockName = formatv("{0}", I);
+    }
+    FuncDataT<T> FD(FDEntryBlockName);
     for (const auto &B : F) {
       std::string BBName = B.getName().str();
       if (BBName.empty()) {
diff --git a/llvm/test/Other/ChangePrinters/DotCfg/print-changed-dot-cfg.ll b/llvm/test/Other/ChangePrinters/DotCfg/print-changed-dot-cfg.ll
index a3d5c60fe932d..535d8aee497a3 100644
--- a/llvm/test/Other/ChangePrinters/DotCfg/print-changed-dot-cfg.ll
+++ b/llvm/test/Other/ChangePrinters/DotCfg/print-changed-dot-cfg.ll
@@ -110,7 +110,7 @@
 ; RUN: FileCheck %s -input-file=%t/passes.html --check-prefix=CHECK-DOT-CFG-QUIET-MULT-PASSES-FILTER-FUNC
 
 define i32 @g() {
-entry:
+1:
   %a = add i32 2, 3
   ret i32 %a
 }

>From 5284f4f54407b783ad82bf55511645f6a710cf84 Mon Sep 17 00:00:00 2001
From: Ruoyu Qiu <cabbaken at outlook.com>
Date: Tue, 22 Jul 2025 09:07:15 +0000
Subject: [PATCH 3/3] Fix the missng numeric label in initial IR pdf

Signed-off-by: Ruoyu Qiu <cabbaken at outlook.com>
---
 llvm/lib/Passes/StandardInstrumentations.cpp | 24 +++++++++++---------
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/llvm/lib/Passes/StandardInstrumentations.cpp b/llvm/lib/Passes/StandardInstrumentations.cpp
index 0abf77b65e5a4..ce2d3a1722e28 100644
--- a/llvm/lib/Passes/StandardInstrumentations.cpp
+++ b/llvm/lib/Passes/StandardInstrumentations.cpp
@@ -728,11 +728,11 @@ template <typename FunctionT>
 bool IRComparer<T>::generateFunctionData(IRDataT<T> &Data, const FunctionT &F) {
   if (shouldGenerateData(F)) {
     int I = 0;
-    std::string FDEntryBlockName = F.front().getName().str();
     // Basic block with numberic label will be empty here.
-    if (FDEntryBlockName.empty()) {
+    std::string FDEntryBlockName = F.front().getName().str();
+    if (FDEntryBlockName.empty())
       FDEntryBlockName = formatv("{0}", I);
-    }
+
     FuncDataT<T> FD(FDEntryBlockName);
     for (const auto &B : F) {
       std::string BBName = B.getName().str();
@@ -1792,18 +1792,20 @@ class DotCfgDiffNode {
   // Create a node in Dot difference graph \p G representing the basic block
   // represented by \p BD with colour \p Colour (where it exists).
   DotCfgDiffNode(DotCfgDiff &G, unsigned N, const BlockDataT<DCData> &BD,
-                 StringRef Colour)
-      : Graph(G), N(N), Data{&BD, nullptr}, Colour(Colour) {}
+                 StringRef Label, StringRef Colour)
+      : Graph(G), N(N), Data{&BD, nullptr}, Label(Label), Colour(Colour) {}
   DotCfgDiffNode(const DotCfgDiffNode &DN)
       : Graph(DN.Graph), N(DN.N), Data{DN.Data[0], DN.Data[1]},
-        Colour(DN.Colour), EdgesMap(DN.EdgesMap), Children(DN.Children),
-        Edges(DN.Edges) {}
+        Label(DN.Label), Colour(DN.Colour), EdgesMap(DN.EdgesMap),
+        Children(DN.Children), Edges(DN.Edges) {}
 
   unsigned getIndex() const { return N; }
 
   // The label of the basic block
   StringRef getLabel() const {
     assert(Data[0] && "Expected Data[0] to be set.");
+    assert((Data[0]->getLabel().empty() || Data[0]->getLabel() == Label) &&
+           "Unexpected label");
     return Data[0]->getLabel();
   }
   // Return the colour for this block
@@ -1841,6 +1843,7 @@ class DotCfgDiffNode {
   DotCfgDiff &Graph;
   const unsigned N;
   const BlockDataT<DCData> *Data[2];
+  StringRef Label;
   StringRef Colour;
   std::map<const unsigned, std::pair<std::string, StringRef>> EdgesMap;
   std::vector<unsigned> Children;
@@ -1889,7 +1892,7 @@ class DotCfgDiff {
 
   void createNode(StringRef Label, const BlockDataT<DCData> &BD, StringRef C) {
     unsigned Pos = Nodes.size();
-    Nodes.emplace_back(*this, Pos, BD, C);
+    Nodes.emplace_back(*this, Pos, BD, Label, C);
     NodePosition.insert({Label, Pos});
   }
 
@@ -1951,10 +1954,9 @@ std::string DotCfgDiffNode::getBodyContent() const {
   // Drop leading newline, if present.
   if (BS.front() == '\n')
     BS1 = BS1.drop_front(1);
-  // Get label.
-  StringRef Label = BS1.take_until([](char C) { return C == ':'; });
   // drop predecessors as they can be big and are redundant
-  BS1 = BS1.drop_until([](char C) { return C == '\n'; }).drop_front();
+  if(BS1.str().find(Label) != std::string::npos)
+    BS1 = BS1.drop_until([](char C) { return C == '\n'; }).drop_front();
 
   std::string S = "<FONT COLOR=\"" + Colour.str() + "\">" + Label.str() + ":";
 



More information about the llvm-commits mailing list