[llvm] [CodeGen] Port break-false-deps to new pass manager (PR #194262)

via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 27 00:34:29 PDT 2026


https://github.com/juanvazquez updated https://github.com/llvm/llvm-project/pull/194262

>From cfed85682ce59bea12067d70a13ce37be3dd3f6d Mon Sep 17 00:00:00 2001
From: Juan Vazquez <juvazq at google.com>
Date: Sun, 26 Apr 2026 17:18:03 +0200
Subject: [PATCH] [CodeGen] Port break-false-deps to new pass manager

---
 llvm/include/llvm/CodeGen/BreakFalseDeps.h    | 40 +++++++++
 llvm/include/llvm/CodeGen/Passes.h            |  2 +-
 llvm/include/llvm/InitializePasses.h          |  2 +-
 .../llvm/Passes/MachinePassRegistry.def       |  2 +-
 llvm/lib/CodeGen/BreakFalseDeps.cpp           | 81 ++++++++++++-------
 llvm/lib/CodeGen/CodeGen.cpp                  |  2 +-
 llvm/lib/Passes/PassBuilder.cpp               |  1 +
 llvm/lib/Target/ARM/ARMTargetMachine.cpp      |  2 +-
 llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp |  1 +
 llvm/lib/Target/X86/X86TargetMachine.cpp      |  2 +-
 llvm/test/CodeGen/X86/apx/ndd-false-deps.mir  |  3 +
 .../CodeGen/X86/break-false-dep-crash.mir     |  2 +
 llvm/test/CodeGen/X86/llc-pipeline-npm.ll     |  4 +-
 13 files changed, 109 insertions(+), 35 deletions(-)
 create mode 100644 llvm/include/llvm/CodeGen/BreakFalseDeps.h

diff --git a/llvm/include/llvm/CodeGen/BreakFalseDeps.h b/llvm/include/llvm/CodeGen/BreakFalseDeps.h
new file mode 100644
index 0000000000000..378aeeefaed7b
--- /dev/null
+++ b/llvm/include/llvm/CodeGen/BreakFalseDeps.h
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Some instructions have false dependencies which cause unnecessary stalls.
+// For example, instructions may write part of a register and implicitly
+// need to read the other parts of the register. This may cause unwanted
+// stalls preventing otherwise unrelated instructions from executing in
+// parallel in an out-of-order CPU.
+// This pass is aimed at identifying and avoiding these dependencies.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_BREAKFALSEDEPS_H
+#define LLVM_CODEGEN_BREAKFALSEDEPS_H
+
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineFunctionAnalysisManager.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/Support/Compiler.h"
+
+namespace llvm {
+
+class BreakFalseDepsPass : public PassInfoMixin<BreakFalseDepsPass> {
+public:
+  LLVM_ABI PreservedAnalyses run(MachineFunction &MF,
+                                 MachineFunctionAnalysisManager &MFAM);
+
+  MachineFunctionProperties getRequiredProperties() const {
+    return MachineFunctionProperties().setNoVRegs();
+  }
+};
+
+} // namespace llvm
+
+#endif // LLVM_CODEGEN_BREAKFALSEDEPS_H
diff --git a/llvm/include/llvm/CodeGen/Passes.h b/llvm/include/llvm/CodeGen/Passes.h
index be344c6aaf40e..2fdf792512ec9 100644
--- a/llvm/include/llvm/CodeGen/Passes.h
+++ b/llvm/include/llvm/CodeGen/Passes.h
@@ -556,7 +556,7 @@ LLVM_ABI FunctionPass *createReplaceWithVeclibLegacyPass();
 LLVM_ABI FunctionPass *createExpandIRInstsPass(CodeGenOptLevel);
 
 /// Creates Break False Dependencies pass. \see BreakFalseDeps.cpp
-LLVM_ABI FunctionPass *createBreakFalseDeps();
+LLVM_ABI FunctionPass *createBreakFalseDepsLegacyPass();
 
 // This pass expands indirectbr instructions.
 LLVM_ABI FunctionPass *createIndirectBrExpandPass();
diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h
index 012f1fb0ebd90..4e2324774b641 100644
--- a/llvm/include/llvm/InitializePasses.h
+++ b/llvm/include/llvm/InitializePasses.h
@@ -69,7 +69,7 @@ LLVM_ABI void initializeBranchFolderLegacyPass(PassRegistry &);
 LLVM_ABI void initializeBranchProbabilityInfoWrapperPassPass(PassRegistry &);
 LLVM_ABI void initializeBranchRelaxationLegacyPass(PassRegistry &);
 LLVM_ABI void initializeBreakCriticalEdgesPass(PassRegistry &);
-LLVM_ABI void initializeBreakFalseDepsPass(PassRegistry &);
+LLVM_ABI void initializeBreakFalseDepsLegacyPass(PassRegistry &);
 LLVM_ABI void initializeCanonicalizeFreezeInLoopsPass(PassRegistry &);
 LLVM_ABI void initializeCFGSimplifyPassPass(PassRegistry &);
 LLVM_ABI void initializeCFGuardPass(PassRegistry &);
diff --git a/llvm/include/llvm/Passes/MachinePassRegistry.def b/llvm/include/llvm/Passes/MachinePassRegistry.def
index fd5d4a39a5915..539f9c901de1c 100644
--- a/llvm/include/llvm/Passes/MachinePassRegistry.def
+++ b/llvm/include/llvm/Passes/MachinePassRegistry.def
@@ -108,6 +108,7 @@ MACHINE_FUNCTION_ANALYSIS("virtregmap", VirtRegMapAnalysis())
 #endif
 MACHINE_FUNCTION_PASS("block-placement-stats", MachineBlockPlacementStatsPass())
 MACHINE_FUNCTION_PASS("branch-relaxation", BranchRelaxationPass())
+MACHINE_FUNCTION_PASS("break-false-deps", BreakFalseDepsPass())
 MACHINE_FUNCTION_PASS("dead-mi-elimination", DeadMachineInstructionElimPass())
 MACHINE_FUNCTION_PASS("detect-dead-lanes", DetectDeadLanesPass())
 MACHINE_FUNCTION_PASS("early-ifcvt", EarlyIfConverterPass())
@@ -272,7 +273,6 @@ DUMMY_MACHINE_MODULE_PASS("mir-check-debugify", CheckDebugMachineModulePass)
 #endif
 DUMMY_MACHINE_FUNCTION_PASS("bbsections-prepare", BasicBlockSectionsPass)
 DUMMY_MACHINE_FUNCTION_PASS("bbsections-profile-reader", BasicBlockSectionsProfileReaderPass)
-DUMMY_MACHINE_FUNCTION_PASS("break-false-deps", BreakFalseDepsPass)
 DUMMY_MACHINE_FUNCTION_PASS("cfguard-longjmp", CFGuardLongjmpPass)
 DUMMY_MACHINE_FUNCTION_PASS("cfi-fixup", CFIFixupPass)
 DUMMY_MACHINE_FUNCTION_PASS("cfi-instr-inserter", CFIInstrInserterPass)
diff --git a/llvm/lib/CodeGen/BreakFalseDeps.cpp b/llvm/lib/CodeGen/BreakFalseDeps.cpp
index 9e16897fe7768..be6166fd3c411 100644
--- a/llvm/lib/CodeGen/BreakFalseDeps.cpp
+++ b/llvm/lib/CodeGen/BreakFalseDeps.cpp
@@ -17,6 +17,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "llvm/CodeGen/BreakFalseDeps.h"
 #include "llvm/ADT/DepthFirstIterator.h"
 #include "llvm/CodeGen/LivePhysRegs.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
@@ -33,7 +34,7 @@ using namespace llvm;
 
 namespace {
 
-class BreakFalseDeps : public MachineFunctionPass {
+class BreakFalseDeps {
 private:
   MachineFunction *MF = nullptr;
   const TargetInstrInfo *TII = nullptr;
@@ -49,21 +50,9 @@ class BreakFalseDeps : public MachineFunctionPass {
   ReachingDefInfo *RDI = nullptr;
 
 public:
-  static char ID; // Pass identification, replacement for typeid
-
-  BreakFalseDeps() : MachineFunctionPass(ID) {}
-
-  void getAnalysisUsage(AnalysisUsage &AU) const override {
-    AU.setPreservesAll();
-    AU.addRequired<ReachingDefInfoWrapperPass>();
-    MachineFunctionPass::getAnalysisUsage(AU);
-  }
+  BreakFalseDeps(ReachingDefInfo *RDI) : RDI(RDI) {}
 
-  bool runOnMachineFunction(MachineFunction &MF) override;
-
-  MachineFunctionProperties getRequiredProperties() const override {
-    return MachineFunctionProperties().setNoVRegs();
-  }
+  bool run(MachineFunction &MF);
 
 private:
   /// Process he given basic block.
@@ -93,16 +82,39 @@ class BreakFalseDeps : public MachineFunctionPass {
   void processUndefReads(MachineBasicBlock *);
 };
 
+class BreakFalseDepsLegacy : public MachineFunctionPass {
+public:
+  static char ID; // Pass identification, replacement for typeid
+
+  BreakFalseDepsLegacy() : MachineFunctionPass(ID) {}
+
+  void getAnalysisUsage(AnalysisUsage &AU) const override {
+    AU.setPreservesAll();
+    AU.addRequired<ReachingDefInfoWrapperPass>();
+    MachineFunctionPass::getAnalysisUsage(AU);
+  }
+
+  bool runOnMachineFunction(MachineFunction &MF) override;
+
+  MachineFunctionProperties getRequiredProperties() const override {
+    return MachineFunctionProperties().setNoVRegs();
+  }
+};
+
 } // namespace
 
 #define DEBUG_TYPE "break-false-deps"
 
-char BreakFalseDeps::ID = 0;
-INITIALIZE_PASS_BEGIN(BreakFalseDeps, DEBUG_TYPE, "BreakFalseDeps", false, false)
+char BreakFalseDepsLegacy::ID = 0;
+INITIALIZE_PASS_BEGIN(BreakFalseDepsLegacy, DEBUG_TYPE, "BreakFalseDeps", false,
+                      false)
 INITIALIZE_PASS_DEPENDENCY(ReachingDefInfoWrapperPass)
-INITIALIZE_PASS_END(BreakFalseDeps, DEBUG_TYPE, "BreakFalseDeps", false, false)
+INITIALIZE_PASS_END(BreakFalseDepsLegacy, DEBUG_TYPE, "BreakFalseDeps", false,
+                    false)
 
-FunctionPass *llvm::createBreakFalseDeps() { return new BreakFalseDeps(); }
+FunctionPass *llvm::createBreakFalseDepsLegacyPass() {
+  return new BreakFalseDepsLegacy();
+}
 
 bool BreakFalseDeps::pickBestRegisterForUndef(MachineInstr *MI, unsigned OpIdx,
   unsigned Pref) {
@@ -274,28 +286,43 @@ void BreakFalseDeps::processBasicBlock(MachineBasicBlock *MBB) {
   processUndefReads(MBB);
 }
 
-bool BreakFalseDeps::runOnMachineFunction(MachineFunction &mf) {
-  if (skipFunction(mf.getFunction()))
-    return false;
-  MF = &mf;
+bool BreakFalseDeps::run(MachineFunction &CurMF) {
+  MF = &CurMF;
   TII = MF->getSubtarget().getInstrInfo();
   TRI = MF->getSubtarget().getRegisterInfo();
-  RDI = &getAnalysis<ReachingDefInfoWrapperPass>().getRDI();
 
-  RegClassInfo.runOnMachineFunction(mf, /*Rev=*/true);
+  RegClassInfo.runOnMachineFunction(CurMF, /*Rev=*/true);
 
   LLVM_DEBUG(dbgs() << "********** BREAK FALSE DEPENDENCIES **********\n");
 
   // Skip Dead blocks due to ReachingDefAnalysis has no idea about instructions
   // in them.
   df_iterator_default_set<MachineBasicBlock *> Reachable;
-  for (MachineBasicBlock *MBB : depth_first_ext(&mf, Reachable))
+  for (MachineBasicBlock *MBB : depth_first_ext(&CurMF, Reachable))
     (void)MBB /* Mark all reachable blocks */;
 
   // Traverse the basic blocks.
-  for (MachineBasicBlock &MBB : mf)
+  for (MachineBasicBlock &MBB : CurMF)
     if (Reachable.count(&MBB))
       processBasicBlock(&MBB);
 
   return false;
 }
+
+bool BreakFalseDepsLegacy::runOnMachineFunction(MachineFunction &MF) {
+  if (skipFunction(MF.getFunction()))
+    return false;
+
+  ReachingDefInfo *RDI = &getAnalysis<ReachingDefInfoWrapperPass>().getRDI();
+  BreakFalseDeps Impl(RDI);
+  return Impl.run(MF);
+}
+
+PreservedAnalyses
+BreakFalseDepsPass::run(MachineFunction &MF,
+                        MachineFunctionAnalysisManager &MFAM) {
+  MFPropsModifier _(*this, MF);
+  ReachingDefInfo *RDI = &MFAM.getResult<ReachingDefAnalysis>(MF);
+  BreakFalseDeps(RDI).run(MF);
+  return PreservedAnalyses::all();
+}
diff --git a/llvm/lib/CodeGen/CodeGen.cpp b/llvm/lib/CodeGen/CodeGen.cpp
index bb8bbc4f44eed..00e0bec380402 100644
--- a/llvm/lib/CodeGen/CodeGen.cpp
+++ b/llvm/lib/CodeGen/CodeGen.cpp
@@ -26,7 +26,7 @@ void llvm::initializeCodeGen(PassRegistry &Registry) {
   initializeBasicBlockSectionsProfileReaderWrapperPassPass(Registry);
   initializeBranchFolderLegacyPass(Registry);
   initializeBranchRelaxationLegacyPass(Registry);
-  initializeBreakFalseDepsPass(Registry);
+  initializeBreakFalseDepsLegacyPass(Registry);
   initializeCFGuardLongjmpPass(Registry);
   initializeCFIFixupPass(Registry);
   initializeCFIInstrInserterPass(Registry);
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index f412e9e68307f..4ce03c6bd264d 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -83,6 +83,7 @@
 #include "llvm/CodeGen/BasicBlockSectionsProfileReader.h"
 #include "llvm/CodeGen/BranchFoldingPass.h"
 #include "llvm/CodeGen/BranchRelaxation.h"
+#include "llvm/CodeGen/BreakFalseDeps.h"
 #include "llvm/CodeGen/CodeGenPrepare.h"
 #include "llvm/CodeGen/ComplexDeinterleavingPass.h"
 #include "llvm/CodeGen/DeadMachineInstructionElim.h"
diff --git a/llvm/lib/Target/ARM/ARMTargetMachine.cpp b/llvm/lib/Target/ARM/ARMTargetMachine.cpp
index 9e8c3cdd29fe8..efb87d1e750f2 100644
--- a/llvm/lib/Target/ARM/ARMTargetMachine.cpp
+++ b/llvm/lib/Target/ARM/ARMTargetMachine.cpp
@@ -487,7 +487,7 @@ void ARMPassConfig::addPreSched2() {
       addPass(createARMLoadStoreOptLegacyPass());
 
     addPass(new ARMExecutionDomainFix());
-    addPass(createBreakFalseDeps());
+    addPass(createBreakFalseDepsLegacyPass());
   }
 
   // Expand some pseudo instructions into multiple instructions to allow
diff --git a/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp b/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
index 524cde4a8d4df..aadf423b98d88 100644
--- a/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
+++ b/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
@@ -16,6 +16,7 @@
 #include "X86TargetMachine.h"
 
 #include "llvm/CodeGen/AtomicExpand.h"
+#include "llvm/CodeGen/BreakFalseDeps.h"
 #include "llvm/CodeGen/EarlyIfConversion.h"
 #include "llvm/CodeGen/IndirectBrExpand.h"
 #include "llvm/CodeGen/InterleavedAccess.h"
diff --git a/llvm/lib/Target/X86/X86TargetMachine.cpp b/llvm/lib/Target/X86/X86TargetMachine.cpp
index 4ddadbec5a174..0c641d57a8f1e 100644
--- a/llvm/lib/Target/X86/X86TargetMachine.cpp
+++ b/llvm/lib/Target/X86/X86TargetMachine.cpp
@@ -560,7 +560,7 @@ void X86PassConfig::addPreSched2() {
 void X86PassConfig::addPreEmitPass() {
   if (getOptLevel() != CodeGenOptLevel::None) {
     addPass(new X86ExecutionDomainFix());
-    addPass(createBreakFalseDeps());
+    addPass(createBreakFalseDepsLegacyPass());
   }
 
   addPass(createX86IndirectBranchTrackingLegacyPass());
diff --git a/llvm/test/CodeGen/X86/apx/ndd-false-deps.mir b/llvm/test/CodeGen/X86/apx/ndd-false-deps.mir
index d1c2c40bed494..dad61b4f4b29a 100644
--- a/llvm/test/CodeGen/X86/apx/ndd-false-deps.mir
+++ b/llvm/test/CodeGen/X86/apx/ndd-false-deps.mir
@@ -1,6 +1,9 @@
 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
 # RUN: llc %s -mtriple=x86_64-unknown -mattr=+ndd,+egpr -run-pass=break-false-deps -verify-machineinstrs -o - | FileCheck --check-prefixes=CHECK,RCDEFAULT %s
 # RUN: llc %s -mtriple=x86_64-unknown -mattr=+ndd,+egpr -run-pass=break-false-deps -partial-reg-update-clearance=1 -verify-machineinstrs -o - | FileCheck --check-prefixes=CHECK,RC1 %s
+
+# RUN: llc %s -mtriple=x86_64-unknown -mattr=+ndd,+egpr -passes=break-false-deps -verify-machineinstrs -o - | FileCheck --check-prefixes=CHECK,RCDEFAULT %s
+# RUN: llc %s -mtriple=x86_64-unknown -mattr=+ndd,+egpr -passes=break-false-deps -partial-reg-update-clearance=1 -verify-machineinstrs -o - | FileCheck --check-prefixes=CHECK,RC1 %s
 #
 # Check that BreakFalseDeps detects cases where an ND instruction would cause a partial register write
 # if compressed to a legacy op. MIR has been modified to force different register assignments.
diff --git a/llvm/test/CodeGen/X86/break-false-dep-crash.mir b/llvm/test/CodeGen/X86/break-false-dep-crash.mir
index febc49da1f832..61e47add34165 100644
--- a/llvm/test/CodeGen/X86/break-false-dep-crash.mir
+++ b/llvm/test/CodeGen/X86/break-false-dep-crash.mir
@@ -1,5 +1,7 @@
 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 2
 # RUN: llc -run-pass=break-false-deps -verify-machineinstrs %s -o - | FileCheck %s
+
+# RUN: llc -passes=break-false-deps -verify-machineinstrs %s -o - | FileCheck %s
 #
 # Check that BreakFalseDeps pass does not crash in presense of dead blocks.
 --- |
diff --git a/llvm/test/CodeGen/X86/llc-pipeline-npm.ll b/llvm/test/CodeGen/X86/llc-pipeline-npm.ll
index 90b0978e3eb5c..b7728892b0b96 100644
--- a/llvm/test/CodeGen/X86/llc-pipeline-npm.ll
+++ b/llvm/test/CodeGen/X86/llc-pipeline-npm.ll
@@ -171,7 +171,7 @@
 ; O2-NEXT: fentry-insert
 ; O2-NEXT: xray-instrumentation
 ; O2-NEXT: patchable-function
-; O2-NEXT: BreakFalseDepsPass
+; O2-NEXT: break-false-deps
 ; O2-NEXT: x86-indirect-branch-tracking
 ; O2-NEXT: x86-insert-vzeroupper
 ; O2-NEXT: x86-fixup-bw-insts
@@ -360,7 +360,7 @@
 ; O3-WINDOWS-NEXT: fentry-insert
 ; O3-WINDOWS-NEXT: xray-instrumentation
 ; O3-WINDOWS-NEXT: patchable-function
-; O3-WINDOWS-NEXT: BreakFalseDepsPass
+; O3-WINDOWS-NEXT: break-false-deps
 ; O3-WINDOWS-NEXT: x86-indirect-branch-tracking
 ; O3-WINDOWS-NEXT: x86-insert-vzeroupper
 ; O3-WINDOWS-NEXT: x86-fixup-bw-insts



More information about the llvm-commits mailing list