[llvm] [Instrumentation] Support MachineFunction in ChangeReporter (PR #80946)

via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 6 23:36:07 PST 2024


https://github.com/paperchalice created https://github.com/llvm/llvm-project/pull/80946

None

>From 6a3d14fe2ec27b31a622e719d6a8db61c57c5ce5 Mon Sep 17 00:00:00 2001
From: PaperChalice <liujunchang97 at outlook.com>
Date: Wed, 7 Feb 2024 15:09:38 +0800
Subject: [PATCH] [Instrumentation] Support MachineFunction in ChangeReporter

---
 .../llvm/Passes/StandardInstrumentations.h    |  22 ++-
 llvm/lib/CodeGen/MachinePassManager.cpp       |   4 +-
 llvm/lib/Passes/StandardInstrumentations.cpp  | 129 ++++++++++++++--
 .../DotCfg/print-changed-dot-cfg.mir          | 138 ++++++++++++++++++
 llvm/test/Other/change-printer.mir            | 112 ++++++++++++++
 5 files changed, 392 insertions(+), 13 deletions(-)
 create mode 100644 llvm/test/Other/ChangePrinters/DotCfg/print-changed-dot-cfg.mir
 create mode 100644 llvm/test/Other/change-printer.mir

diff --git a/llvm/include/llvm/Passes/StandardInstrumentations.h b/llvm/include/llvm/Passes/StandardInstrumentations.h
index 8c6a44876d545..daf8c10102626 100644
--- a/llvm/include/llvm/Passes/StandardInstrumentations.h
+++ b/llvm/include/llvm/Passes/StandardInstrumentations.h
@@ -18,6 +18,7 @@
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
 #include "llvm/IR/BasicBlock.h"
 #include "llvm/IR/OptBisect.h"
 #include "llvm/IR/PassTimingInfo.h"
@@ -33,6 +34,7 @@ namespace llvm {
 
 class Module;
 class Function;
+class MachineFunction;
 class PassInstrumentationCallbacks;
 
 /// Instrumentation to print IR before/after passes.
@@ -209,6 +211,8 @@ template <typename IRUnitT> class ChangeReporter {
 
   // Called on the first IR processed.
   virtual void handleInitialIR(Any IR) = 0;
+  // Called on the first MIR processed.
+  virtual void handleInitialMIR(const MachineFunction *IR) = 0;
   // Called before and after a pass to get the representation of the IR.
   virtual void generateIRRepresentation(Any IR, StringRef PassID,
                                         IRUnitT &Output) = 0;
@@ -229,6 +233,8 @@ template <typename IRUnitT> class ChangeReporter {
   std::vector<IRUnitT> BeforeStack;
   // Is this the first IR seen?
   bool InitialIR = true;
+  // Is this the first MIR seen?
+  bool InitialMIR = true;
 
   // Run in verbose mode, printing everything?
   const bool VerboseMode;
@@ -243,6 +249,8 @@ class TextChangeReporter : public ChangeReporter<IRUnitT> {
 
   // Print a module dump of the first IR that is changed.
   void handleInitialIR(Any IR) override;
+  // Print a module dump of the first MIR that is changed.
+  void handleInitialMIR(const MachineFunction *IR) override;
   // Report that the IR was omitted because it did not change.
   void omitAfter(StringRef PassID, std::string &Name) override;
   // Report that the pass was invalidated.
@@ -289,6 +297,8 @@ class IRChangedTester : public IRChangedPrinter {
 
   // Check initial IR
   void handleInitialIR(Any IR) override;
+  // Check initial MIR
+  void handleInitialMIR(const MachineFunction *IR) override;
   // Do nothing.
   void omitAfter(StringRef PassID, std::string &Name) override;
   // Do nothing.
@@ -313,6 +323,11 @@ template <typename T> class BlockDataT {
     B.print(SS, nullptr, true, true);
   }
 
+  BlockDataT(const MachineBasicBlock &B) : Label(B.getName().str()), Data(B) {
+    raw_string_ostream SS(Body);
+    B.print(SS);
+  }
+
   bool operator==(const BlockDataT &That) const { return Body == That.Body; }
   bool operator!=(const BlockDataT &That) const { return Body != That.Body; }
 
@@ -364,6 +379,7 @@ template <typename T> class OrderedChangedData {
 class EmptyData {
 public:
   EmptyData(const BasicBlock &) {}
+  EmptyData(const MachineBasicBlock &) {}
 };
 
 // The data saved for comparing functions.
@@ -405,7 +421,8 @@ template <typename T> class IRComparer {
 
 protected:
   // Generate the data for \p F into \p Data.
-  static bool generateFunctionData(IRDataT<T> &Data, const Function &F);
+  template <typename FunctionT>
+  static bool generateFunctionData(IRDataT<T> &Data, const FunctionT &F);
 
   const IRDataT<T> &Before;
   const IRDataT<T> &After;
@@ -475,6 +492,7 @@ class DCData {
 public:
   // Fill the map with the transitions from basic block \p B.
   DCData(const BasicBlock &B);
+  DCData(const MachineBasicBlock &B);
 
   // Return an iterator to the names of the successor blocks.
   StringMap<std::string>::const_iterator begin() const {
@@ -514,6 +532,8 @@ class DotCfgChangeReporter : public ChangeReporter<IRDataT<DCData>> {
 
   // Called on the first IR processed.
   void handleInitialIR(Any IR) override;
+  // Called on the first MIR processed.
+  void handleInitialMIR(const MachineFunction *IR) override;
   // Called before and after a pass to get the representation of the IR.
   void generateIRRepresentation(Any IR, StringRef PassID,
                                 IRDataT<DCData> &Output) override;
diff --git a/llvm/lib/CodeGen/MachinePassManager.cpp b/llvm/lib/CodeGen/MachinePassManager.cpp
index 0770eba660b45..d4a00764b715f 100644
--- a/llvm/lib/CodeGen/MachinePassManager.cpp
+++ b/llvm/lib/CodeGen/MachinePassManager.cpp
@@ -90,7 +90,9 @@ Error MachineFunctionPassManager::run(Module &M,
       for (unsigned I = Begin, E = Idx; I != E; ++I) {
         auto *P = Passes[I].get();
 
-        if (!PI.runBeforePass<MachineFunction>(*P, MF))
+        // Keep BeforeStack empty in ChangeReporter
+        if (P->name() != FreeMachineFunctionPass::name() &&
+            !PI.runBeforePass<MachineFunction>(*P, MF))
           continue;
 
         // TODO: EmitSizeRemarks
diff --git a/llvm/lib/Passes/StandardInstrumentations.cpp b/llvm/lib/Passes/StandardInstrumentations.cpp
index 697988b3fc7c0..c90850ce19571 100644
--- a/llvm/lib/Passes/StandardInstrumentations.cpp
+++ b/llvm/lib/Passes/StandardInstrumentations.cpp
@@ -20,6 +20,7 @@
 #include "llvm/Analysis/LazyCallGraph.h"
 #include "llvm/Analysis/LoopInfo.h"
 #include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/Function.h"
 #include "llvm/IR/Module.h"
@@ -180,6 +181,12 @@ const Module *unwrapModule(Any IR, bool Force = false) {
     return F->getParent();
   }
 
+  if (const auto *MF = unwrapIR<MachineFunction>(IR)) {
+    if (!Force && !isFunctionInPrintList(MF->getName()))
+      return nullptr;
+    return MF->getFunction().getParent();
+  }
+
   llvm_unreachable("Unknown IR unit");
 }
 
@@ -215,6 +222,12 @@ void printIR(raw_ostream &OS, const Loop *L) {
   printLoop(const_cast<Loop &>(*L), OS);
 }
 
+void printIR(raw_ostream &OS, const MachineFunction *MF) {
+  if (!isFunctionInPrintList(MF->getName()))
+    return;
+  MF->print(OS);
+}
+
 std::string getIRName(Any IR) {
   if (unwrapIR<Module>(IR))
     return "[module]";
@@ -262,6 +275,9 @@ bool shouldPrintIR(Any IR) {
 
   if (const auto *L = unwrapIR<Loop>(IR))
     return isFunctionInPrintList(L->getHeader()->getParent()->getName());
+
+  if (const auto *MF = unwrapIR<MachineFunction>(IR))
+    return isFunctionInPrintList(MF->getName());
   llvm_unreachable("Unknown wrapped IR type");
 }
 
@@ -297,6 +313,11 @@ void unwrapAndPrint(raw_ostream &OS, Any IR) {
     printIR(OS, L);
     return;
   }
+
+  if (const auto *MF = unwrapIR<MachineFunction>(IR)) {
+    printIR(OS, MF);
+    return;
+  }
   llvm_unreachable("Unknown wrapped IR type");
 }
 
@@ -305,7 +326,8 @@ bool isIgnored(StringRef PassID) {
   return isSpecialPass(PassID,
                        {"PassManager", "PassAdaptor", "AnalysisManagerProxy",
                         "DevirtSCCRepeatedPass", "ModuleInlinerWrapperPass",
-                        "VerifierPass", "PrintModulePass"});
+                        "VerifierPass", "PrintModulePass", "PrintMIRPass",
+                        "PrintMIRPreparePass"});
 }
 
 std::string makeHTMLReady(StringRef SR) {
@@ -362,6 +384,14 @@ void ChangeReporter<T>::saveIRBeforePass(Any IR, StringRef PassID,
       handleInitialIR(IR);
   }
 
+  if (InitialMIR) {
+    if (const auto *MF = unwrapIR<MachineFunction>(IR)) {
+      InitialMIR = false;
+      if (VerboseMode)
+        handleInitialMIR(MF);
+    }
+  }
+
   // Always need to place something on the stack because invalidated passes
   // are not given the IR so it cannot be determined whether the pass was for
   // something that was filtered out.
@@ -448,6 +478,17 @@ template <typename T> void TextChangeReporter<T>::handleInitialIR(Any IR) {
   M->print(Out, nullptr);
 }
 
+template <typename T>
+void TextChangeReporter<T>::handleInitialMIR(const MachineFunction *IR) {
+  // Print all available machine functions.
+  const auto &MMI = IR->getMMI();
+  const auto &M = *MMI.getModule();
+  Out << "*** MIR Dump At Start ***\n";
+  for (const Function &F : M)
+    if (auto *MF = MMI.getMachineFunction(F))
+      MF->print(Out);
+}
+
 template <typename T>
 void TextChangeReporter<T>::omitAfter(StringRef PassID, std::string &Name) {
   Out << formatv("*** IR Dump After {0} on {1} omitted because no change ***\n",
@@ -546,6 +587,12 @@ void IRChangedTester::handleInitialIR(Any IR) {
   handleIR(S, "Initial IR");
 }
 
+void IRChangedTester::handleInitialMIR(const MachineFunction *IR) {
+  std::string S;
+  generateIRRepresentation(IR, "Initial MIR", S);
+  handleIR(S, "Initial MIR");
+}
+
 void IRChangedTester::omitAfter(StringRef PassID, std::string &Name) {}
 void IRChangedTester::handleInvalidated(StringRef PassID) {}
 void IRChangedTester::handleFiltered(StringRef PassID, std::string &Name) {}
@@ -664,20 +711,38 @@ template <typename T> void IRComparer<T>::analyzeIR(Any IR, IRDataT<T> &Data) {
     return;
   }
 
-  const auto *F = unwrapIR<Function>(IR);
-  if (!F) {
-    const auto *L = unwrapIR<Loop>(IR);
-    assert(L && "Unknown IR unit.");
-    F = L->getHeader()->getParent();
+  if (const auto *F = unwrapIR<Function>(IR)) {
+    generateFunctionData(Data, *F);
+    return;
+  }
+
+  if (const auto *L = unwrapIR<Loop>(IR)) {
+    auto *F = L->getHeader()->getParent();
+    generateFunctionData(Data, *F);
+    return;
   }
-  assert(F && "Unknown IR unit.");
-  generateFunctionData(Data, *F);
+
+  if (const auto *MF = unwrapIR<MachineFunction>(IR)) {
+    generateFunctionData(Data, *MF);
+    return;
+  }
+
+  llvm_unreachable("Unknown IR unit");
+}
+
+static bool shouldGenerateData(const Function &F) {
+  return !F.isDeclaration() && isFunctionInPrintList(F.getName());
+}
+
+static bool shouldGenerateData(const MachineFunction &MF) {
+  return isFunctionInPrintList(MF.getName());
 }
 
 template <typename T>
-bool IRComparer<T>::generateFunctionData(IRDataT<T> &Data, const Function &F) {
-  if (!F.isDeclaration() && isFunctionInPrintList(F.getName())) {
-    FuncDataT<T> FD(F.getEntryBlock().getName().str());
+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;
     for (const auto &B : F) {
       std::string BBName = B.getName().str();
@@ -722,6 +787,12 @@ static SmallString<32> getIRFileDisplayName(Any IR) {
     ResultStream << "-loop-";
     stable_hash LoopNameHash = stable_hash_combine_string(L->getName());
     write_hex(ResultStream, LoopNameHash, HexPrintStyle::Lower, MaxHashWidth);
+  } else if (const auto *MF = unwrapIR<MachineFunction>(IR)) {
+    ResultStream << "-machine-function-";
+    stable_hash MachineFunctionNameHash =
+        stable_hash_combine_string(MF->getName());
+    write_hex(ResultStream, MachineFunctionNameHash, HexPrintStyle::Lower,
+              MaxHashWidth);
   } else {
     llvm_unreachable("Unknown wrapped IR type");
   }
@@ -2122,6 +2193,11 @@ DCData::DCData(const BasicBlock &B) {
       addSuccessorLabel(Succ->getName().str(), "");
 }
 
+DCData::DCData(const MachineBasicBlock &B) {
+  for (const MachineBasicBlock *Succ : successors(&B))
+    addSuccessorLabel(Succ->getName().str(), "");
+}
+
 DotCfgChangeReporter::DotCfgChangeReporter(bool Verbose)
     : ChangeReporter<IRDataT<DCData>>(Verbose) {}
 
@@ -2210,6 +2286,37 @@ void DotCfgChangeReporter::handleInitialIR(Any IR) {
   ++N;
 }
 
+void DotCfgChangeReporter::handleInitialMIR(const MachineFunction *IR) {
+  assert(HTML && "Expected outstream to be set");
+  *HTML << "<button type=\"button\" class=\"collapsible\">0. "
+        << "Initial MIR (by machine function)</button>\n"
+        << "<div class=\"content\">\n"
+        << "  <p>\n";
+
+  auto &MMI = IR->getMMI();
+  const auto *M = MMI.getModule();
+  for (const auto &F : *M) {
+    if (const auto *MF = MMI.getMachineFunction(F)) {
+      // Create representation of IR
+      IRDataT<DCData> Data;
+      IRComparer<DCData>::analyzeIR(llvm::Any(MF), Data);
+      // Now compare it against itself, which will have everything the
+      // same and will generate the files.
+      IRComparer<DCData>(Data, Data)
+          .compare(getModuleForComparison(IR),
+                   [&](bool InModule, unsigned Minor,
+                       const FuncDataT<DCData> &Before,
+                       const FuncDataT<DCData> &After) -> void {
+                     handleFunctionCompare("", " ", "Initial MIR", "", InModule,
+                                           Minor, Before, After);
+                   });
+      ++N;
+    }
+  }
+  *HTML << "  </p>\n"
+        << "</div><br/>\n";
+}
+
 void DotCfgChangeReporter::generateIRRepresentation(Any IR, StringRef PassID,
                                                     IRDataT<DCData> &Data) {
   IRComparer<DCData>::analyzeIR(IR, Data);
diff --git a/llvm/test/Other/ChangePrinters/DotCfg/print-changed-dot-cfg.mir b/llvm/test/Other/ChangePrinters/DotCfg/print-changed-dot-cfg.mir
new file mode 100644
index 0000000000000..c7edd29a6107b
--- /dev/null
+++ b/llvm/test/Other/ChangePrinters/DotCfg/print-changed-dot-cfg.mir
@@ -0,0 +1,138 @@
+# REQUIRES: x86-registered-target
+# Simple functionality check.
+# RUN: rm -rf %t && mkdir -p %t
+# RUN: llc -filetype=null -print-changed=dot-cfg -passes=no-op-machine-function -dot-cfg-dir=%t %s
+# RUN: ls %t/*.pdf %t/passes.html | count 5
+
+--- |
+  ; ModuleID = './print-changed-dot-cfg.ll'
+  source_filename = "./print-changed-dot-cfg.ll"
+  target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+  
+  define i32 @g() {
+  entry:
+    %a = add i32 2, 3
+    ret i32 %a
+  }
+  
+  define i32 @f() {
+  entry:
+    %a = add i32 2, 5
+    ret i32 %a
+  }
+
+...
+---
+name:            g
+alignment:       16
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+failedISel:      false
+tracksRegLiveness: true
+hasWinCFI:       false
+callsEHReturn:   false
+callsUnwindInit: false
+hasEHCatchret:   false
+hasEHScopes:     false
+hasEHFunclets:   false
+isOutlined:      false
+debugInstrRef:   true
+failsVerification: false
+tracksDebugUserValues: false
+registers:
+  - { id: 0, class: gr32, preferred-register: '' }
+liveins:         []
+frameInfo:
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    1
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  functionContext: ''
+  maxCallFrameSize: 4294967295
+  cvBytesOfCalleeSavedRegisters: 0
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  hasTailCall:     false
+  localFrameSize:  0
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      []
+stack:           []
+entry_values:    []
+callSites:       []
+debugValueSubstitutions: []
+constants:       []
+machineFunctionInfo: {}
+body:             |
+  bb.0.entry:
+    %0:gr32 = MOV32ri 5
+    $eax = COPY %0
+    RET 0, $eax
+
+...
+---
+name:            f
+alignment:       16
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+failedISel:      false
+tracksRegLiveness: true
+hasWinCFI:       false
+callsEHReturn:   false
+callsUnwindInit: false
+hasEHCatchret:   false
+hasEHScopes:     false
+hasEHFunclets:   false
+isOutlined:      false
+debugInstrRef:   true
+failsVerification: false
+tracksDebugUserValues: false
+registers:
+  - { id: 0, class: gr32, preferred-register: '' }
+liveins:         []
+frameInfo:
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    1
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  functionContext: ''
+  maxCallFrameSize: 4294967295
+  cvBytesOfCalleeSavedRegisters: 0
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  hasTailCall:     false
+  localFrameSize:  0
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      []
+stack:           []
+entry_values:    []
+callSites:       []
+debugValueSubstitutions: []
+constants:       []
+machineFunctionInfo: {}
+body:             |
+  bb.0.entry:
+    %0:gr32 = MOV32ri 7
+    $eax = COPY %0
+    RET 0, $eax
+
+...
diff --git a/llvm/test/Other/change-printer.mir b/llvm/test/Other/change-printer.mir
new file mode 100644
index 0000000000000..8b6dfe515c18b
--- /dev/null
+++ b/llvm/test/Other/change-printer.mir
@@ -0,0 +1,112 @@
+# REQUIRES: x86-registered-target
+# RUN: llc -mtriple=x86_64-unknown-linux-gnu -filetype=null %s \
+# RUN: -p no-op-machine-function -print-changed 2>&1 | FileCheck %s --check-prefix=CHECK-NO-OP
+
+# RUN: llc -mtriple=x86_64-unknown-linux-gnu -filetype=null %s \
+# RUN: -p dead-mi-elimination -print-changed 2>&1 | FileCheck %s --check-prefix=CHECK-SIMPLE
+
+--- |
+  ; ModuleID = 'main.ll'
+  source_filename = "main.cpp"
+  target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+  target triple = "x86_64-unknown-linux-gnu"
+  
+  define noundef i32 @_Z4testv() {
+  0:
+    %1 = alloca i32, align 4
+    %2 = alloca i32, align 4
+    %3 = alloca i32, align 4
+    store i32 0, ptr %1, align 4
+    store i32 1, ptr %2, align 4
+    %4 = load i32, ptr %1, align 4
+    %5 = load i32, ptr %2, align 4
+    %6 = add nsw i32 %4, %5
+    store i32 %6, ptr %3, align 4
+    %7 = load i32, ptr %3, align 4
+    ret i32 %7
+  }
+...
+---
+name:            _Z4testv
+alignment:       16
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+failedISel:      false
+tracksRegLiveness: true
+hasWinCFI:       false
+callsEHReturn:   false
+callsUnwindInit: false
+hasEHCatchret:   false
+hasEHScopes:     false
+hasEHFunclets:   false
+isOutlined:      false
+debugInstrRef:   false
+failsVerification: false
+tracksDebugUserValues: false
+registers:
+  - { id: 0, class: gr32, preferred-register: '' }
+  - { id: 1, class: gr32, preferred-register: '' }
+  - { id: 2, class: gr32, preferred-register: '' }
+  - { id: 3, class: gr32, preferred-register: '' }
+  - { id: 4, class: gr32, preferred-register: '' }
+  - { id: 5, class: gr32, preferred-register: '' }
+  - { id: 6, class: gr32, preferred-register: '' }
+  - { id: 7, class: gr32, preferred-register: '' }
+liveins:         []
+frameInfo:
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    4
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  functionContext: ''
+  maxCallFrameSize: 4294967295
+  cvBytesOfCalleeSavedRegisters: 0
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  hasTailCall:     false
+  localFrameSize:  0
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      []
+stack:
+  - { id: 0, name: '', type: default, offset: 0, size: 4, alignment: 4, 
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true, 
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+  - { id: 1, name: '', type: default, offset: 0, size: 4, alignment: 4, 
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true, 
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+  - { id: 2, name: '', type: default, offset: 0, size: 4, alignment: 4, 
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true, 
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+entry_values:    []
+callSites:       []
+debugValueSubstitutions: []
+constants:       []
+machineFunctionInfo: {}
+body:             |
+  bb.0 (%ir-block.0):
+    MOV32mi %stack.0, 1, $noreg, 0, $noreg, 0 :: (store (s32) into %ir.1)
+    MOV32mi %stack.1, 1, $noreg, 0, $noreg, 1 :: (store (s32) into %ir.2)
+    %6:gr32 = MOV32rm %stack.0, 1, $noreg, 0, $noreg :: (load (s32) from %ir.1)
+    %5:gr32 = ADD32rm %6, %stack.1, 1, $noreg, 0, $noreg, implicit-def $eflags :: (load (s32) from %ir.2)
+    MOV32mr %stack.2, 1, $noreg, 0, $noreg, %5 :: (store (s32) into %ir.3)
+    %1:gr32 = MOV32rm %stack.2, 1, $noreg, 0, $noreg :: (load (s32) from %ir.3)
+    %7:gr32 = MOV32rm %stack.0, 1, $noreg, 0, $noreg :: (load (s32) from %ir.1)
+    $eax = COPY %1
+    RET64 implicit $eax
+
+...
+
+# CHECK-NO-OP: *** IR Dump After NoOpMachineFunctionPass on _Z4testv omitted because no change ***
+
+# CHECK-SIMPLE: *** IR Dump After DeadMachineInstructionElimPass on _Z4testv ***
+# CHECK-SIMPLE-NOT: %7:gr32 = MOV32rm %stack.0, 1, $noreg, 0, $noreg :: (load (s32) from %ir.1)



More information about the llvm-commits mailing list