Skip to content

[CodeGen] Port break-false-deps to new pass manager#194262

Open
juanvazquez wants to merge 1 commit intollvm:mainfrom
juanvazquez:break-false-deps
Open

[CodeGen] Port break-false-deps to new pass manager#194262
juanvazquez wants to merge 1 commit intollvm:mainfrom
juanvazquez:break-false-deps

Conversation

@juanvazquez
Copy link
Copy Markdown
Contributor

No description provided.

@juanvazquez juanvazquez force-pushed the break-false-deps branch 2 times, most recently from cfed856 to c1823cf Compare April 27, 2026 07:41
@juanvazquez juanvazquez marked this pull request as ready for review April 27, 2026 14:59
@llvmbot
Copy link
Copy Markdown
Member

llvmbot commented Apr 27, 2026

@llvm/pr-subscribers-backend-x86

Author: juan.vazquez (juanvazquez)

Changes

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

13 Files Affected:

  • (added) llvm/include/llvm/CodeGen/BreakFalseDeps.h (+40)
  • (modified) llvm/include/llvm/CodeGen/Passes.h (+1-1)
  • (modified) llvm/include/llvm/InitializePasses.h (+1-1)
  • (modified) llvm/include/llvm/Passes/MachinePassRegistry.def (+1-1)
  • (modified) llvm/lib/CodeGen/BreakFalseDeps.cpp (+54-27)
  • (modified) llvm/lib/CodeGen/CodeGen.cpp (+1-1)
  • (modified) llvm/lib/Passes/PassBuilder.cpp (+1)
  • (modified) llvm/lib/Target/ARM/ARMTargetMachine.cpp (+1-1)
  • (modified) llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp (+1)
  • (modified) llvm/lib/Target/X86/X86TargetMachine.cpp (+1-1)
  • (modified) llvm/test/CodeGen/X86/apx/ndd-false-deps.mir (+3)
  • (modified) llvm/test/CodeGen/X86/break-false-dep-crash.mir (+2)
  • (modified) llvm/test/CodeGen/X86/llc-pipeline-npm.ll (+2-2)
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..86291e450b610 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 &CurMF);
 
 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

@llvmbot
Copy link
Copy Markdown
Member

llvmbot commented Apr 27, 2026

@llvm/pr-subscribers-backend-arm

Author: juan.vazquez (juanvazquez)

Changes

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

13 Files Affected:

  • (added) llvm/include/llvm/CodeGen/BreakFalseDeps.h (+40)
  • (modified) llvm/include/llvm/CodeGen/Passes.h (+1-1)
  • (modified) llvm/include/llvm/InitializePasses.h (+1-1)
  • (modified) llvm/include/llvm/Passes/MachinePassRegistry.def (+1-1)
  • (modified) llvm/lib/CodeGen/BreakFalseDeps.cpp (+54-27)
  • (modified) llvm/lib/CodeGen/CodeGen.cpp (+1-1)
  • (modified) llvm/lib/Passes/PassBuilder.cpp (+1)
  • (modified) llvm/lib/Target/ARM/ARMTargetMachine.cpp (+1-1)
  • (modified) llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp (+1)
  • (modified) llvm/lib/Target/X86/X86TargetMachine.cpp (+1-1)
  • (modified) llvm/test/CodeGen/X86/apx/ndd-false-deps.mir (+3)
  • (modified) llvm/test/CodeGen/X86/break-false-dep-crash.mir (+2)
  • (modified) llvm/test/CodeGen/X86/llc-pipeline-npm.ll (+2-2)
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..86291e450b610 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 &CurMF);
 
 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

Comment thread llvm/lib/CodeGen/BreakFalseDeps.cpp Outdated
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We can probably drop the docstring here now that it's in the header file.

Whatever we do, it would be good to not duplicate it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks, I've removed the docstring then. Happy to follow the preferred convention for the repo. Let me know if the preference is another.

PreservedAnalyses
BreakFalseDepsPass::run(MachineFunction &MF,
MachineFunctionAnalysisManager &MFAM) {
MFPropsModifier _(*this, MF);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why exactly is this needed?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Because the pass implements getRequiredProperties.

Kindly let me know if I misunderstood and it's not needed.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 27, 2026

✅ With the latest revision this PR passed the C/C++ code formatter.

@juanvazquez juanvazquez force-pushed the break-false-deps branch 2 times, most recently from 2e92a4f to 8f84d45 Compare April 27, 2026 16:15
@juanvazquez
Copy link
Copy Markdown
Contributor Author

A gentle ping @boomanaiden154, is there anything else I should/could do in this PR to get approval and have it submitted?

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.

3 participants