[llvm] [CodeGen] Add target-independent conditional-compare formation pass (PR #219359)

via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 27 21:23:21 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-aarch64

Author: Feng Zou (fzou1)

<details>
<summary>Changes</summary>

Unify the X86ConditionalCompares and AArch64ConditionalCompares passes into a single target-independent MachineConditionalCompares pass in lib/CodeGen, modeled on EarlyIfConversion. The pass folds a CFG triangle of chained short-circuit conditions into a conditional-compare chain (CCMP/CTEST on X86; CCMP/CCMN/FCCMP on AArch64), eliminating a branch.

All target-specific behavior is delegated through new hooks:
  - TargetInstrInfo::getConditionalCompareFlagReg / canConvertToCCMP / convertToCCMP / getCCMPCodeSizeDelta
  - TargetSubtargetInfo::enableCCMPFormation and a CCmpConvHeuristics tuning struct (a code-size-delta path when minimizing size).

The engine (SSACCmpConv) is heuristics-free and stores condition codes opaquely, round-tripping them through the target hooks. The driver carries the shared MachineTraceMetrics cost model: a 3/4-misprediction- penalty branch-delay budget plus a resource-depth check, applied identically on both targets. The only per-target difference is the CCmpConvHeuristics tuning struct: AArch64 enables the MinSize code-size-delta path (getCCMPCodeSizeDelta), while X86 leaves it off. This reproduces each target's historical cost model.

Both targets are migrated onto the new pass (legacy and new-PM, registered as "machine-ccmp") and their private passes removed. X86 gains new-PM support for the first time; AArch64 keeps its dual registration via the generic pass.

Assisted-by: Claude Opus 4.8 (1M context) <noreply@<!-- -->anthropic.com>

---

Patch is 108.92 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/219359.diff


34 Files Affected:

- (added) llvm/include/llvm/CodeGen/MachineConditionalCompares.h (+25) 
- (modified) llvm/include/llvm/CodeGen/Passes.h (+4) 
- (modified) llvm/include/llvm/CodeGen/TargetInstrInfo.h (+72) 
- (modified) llvm/include/llvm/CodeGen/TargetSubtargetInfo.h (+15) 
- (modified) llvm/include/llvm/InitializePasses.h (+1) 
- (modified) llvm/include/llvm/Passes/MachinePassRegistry.def (+1) 
- (modified) llvm/lib/CodeGen/CMakeLists.txt (+1) 
- (modified) llvm/lib/CodeGen/CodeGen.cpp (+1) 
- (renamed) llvm/lib/CodeGen/MachineConditionalCompares.cpp (+215-445) 
- (modified) llvm/lib/Passes/PassBuilder.cpp (+1) 
- (modified) llvm/lib/Target/AArch64/AArch64.h (-9) 
- (modified) llvm/lib/Target/AArch64/AArch64InstrInfo.cpp (+316) 
- (modified) llvm/lib/Target/AArch64/AArch64InstrInfo.h (+14) 
- (modified) llvm/lib/Target/AArch64/AArch64PassRegistry.def (-1) 
- (modified) llvm/lib/Target/AArch64/AArch64Subtarget.cpp (+14) 
- (modified) llvm/lib/Target/AArch64/AArch64Subtarget.h (+4) 
- (modified) llvm/lib/Target/AArch64/AArch64TargetMachine.cpp (+1-6) 
- (modified) llvm/lib/Target/AArch64/CMakeLists.txt (-1) 
- (modified) llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp (+2) 
- (modified) llvm/lib/Target/X86/X86InstrInfo.cpp (+262) 
- (modified) llvm/lib/Target/X86/X86InstrInfo.h (+12) 
- (modified) llvm/lib/Target/X86/X86Subtarget.cpp (+9) 
- (modified) llvm/lib/Target/X86/X86Subtarget.h (+2) 
- (modified) llvm/lib/Target/X86/X86TargetMachine.cpp (+1) 
- (modified) llvm/test/CodeGen/AArch64/O3-pipeline.ll (+3-1) 
- (modified) llvm/test/CodeGen/AArch64/arm64-ccmp.ll (+2-2) 
- (modified) llvm/test/CodeGen/AArch64/ccmp-look-through-copy.mir (+2-2) 
- (modified) llvm/test/CodeGen/AArch64/ccmp-successor-probs.mir (+2-2) 
- (added) llvm/test/CodeGen/X86/apx/ccmp-cost-model.mir (+164) 
- (added) llvm/test/CodeGen/X86/apx/ccmp-look-through-copy.mir (+41) 
- (added) llvm/test/CodeGen/X86/apx/ccmp-reject.mir (+411) 
- (modified) llvm/test/CodeGen/X86/apx/ccmp.ll (+18-11) 
- (modified) llvm/test/CodeGen/X86/llc-pipeline-npm.ll (+2) 
- (modified) llvm/test/CodeGen/X86/opt-pipeline.ll (+3) 


``````````diff
diff --git a/llvm/include/llvm/CodeGen/MachineConditionalCompares.h b/llvm/include/llvm/CodeGen/MachineConditionalCompares.h
new file mode 100644
index 0000000000000..63ddf90617710
--- /dev/null
+++ b/llvm/include/llvm/CodeGen/MachineConditionalCompares.h
@@ -0,0 +1,25 @@
+//===- llvm/CodeGen/MachineConditionalCompares.h ---------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINECONDITIONALCOMPARES_H
+#define LLVM_CODEGEN_MACHINECONDITIONALCOMPARES_H
+
+#include "llvm/CodeGen/MachinePassManager.h"
+
+namespace llvm {
+
+class MachineConditionalComparesPass
+    : public OptionalPassInfoMixin<MachineConditionalComparesPass> {
+public:
+  LLVM_ABI PreservedAnalyses run(MachineFunction &MF,
+                                 MachineFunctionAnalysisManager &MFAM);
+};
+
+} // namespace llvm
+
+#endif // LLVM_CODEGEN_MACHINECONDITIONALCOMPARES_H
diff --git a/llvm/include/llvm/CodeGen/Passes.h b/llvm/include/llvm/CodeGen/Passes.h
index 8c2b923aeb807..a912caebcd853 100644
--- a/llvm/include/llvm/CodeGen/Passes.h
+++ b/llvm/include/llvm/CodeGen/Passes.h
@@ -321,6 +321,10 @@ LLVM_ABI extern char &EarlyIfPredicatorID;
 /// critical-path and resource depth.
 LLVM_ABI extern char &MachineCombinerID;
 
+/// MachineConditionalCompares - This pass performs target-independent
+/// conditional-compare formation on SSA form, reducing branching.
+LLVM_ABI extern char &MachineConditionalComparesLegacyID;
+
 /// StackSlotColoring - This pass performs stack coloring and merging.
 /// It merges disjoint allocas to reduce the stack size.
 LLVM_ABI extern char &StackColoringLegacyID;
diff --git a/llvm/include/llvm/CodeGen/TargetInstrInfo.h b/llvm/include/llvm/CodeGen/TargetInstrInfo.h
index 4749d06501cb2..635564acd0107 100644
--- a/llvm/include/llvm/CodeGen/TargetInstrInfo.h
+++ b/llvm/include/llvm/CodeGen/TargetInstrInfo.h
@@ -1050,6 +1050,78 @@ class LLVM_ABI TargetInstrInfo : public MCInstrInfo {
     llvm_unreachable("Target didn't implement TargetInstrInfo::insertSelect!");
   }
 
+  /// Carries the state that canConvertToCCMP() computes and convertToCCMP()
+  /// consumes when the target-independent conditional-compare formation pass
+  /// (see MachineConditionalCompares) folds a CFG triangle into a conditional
+  /// compare. All fields except CmpMI are target-owned scratch; the generic
+  /// pass never interprets them.
+  struct CCmpConvInfo {
+    /// The convertible compare instruction found in CmpBB.
+    MachineInstr *CmpMI = nullptr;
+    /// Opaque target scratch (parsed condition codes, chosen opcode, operand
+    /// layout, etc.). Sized to hold the needs of any target.
+    int64_t TargetData[5] = {};
+  };
+
+  /// Return the physical flag/status register clobbered by conditional-compare
+  /// candidates (EFLAGS on X86, NZCV on AArch64), or a null register if the
+  /// target does not support conditional-compare formation. Used by the generic
+  /// MachineConditionalCompares pass to scan for flag reads/defs.
+  virtual MCRegister getConditionalCompareFlagReg() const {
+    return MCRegister();
+  }
+
+  /// Analyze whether the compare controlling CmpBB's terminator can be folded
+  /// into a conditional compare merged into Head (a triangle Head->CmpBB->Tail).
+  ///
+  /// HeadCond and CmpBBCond are the opaque condition-operand arrays returned by
+  /// analyzeBranch; the generic caller never interprets them. HeadTBBIsCmpBB is
+  /// true when analyzeBranch's TBB for Head is CmpBB (else it is Tail), and
+  /// CmpBBTBBIsTail is true when analyzeBranch's TBB for CmpBB is Tail; the
+  /// target uses these to apply its own condition-code inversion.
+  ///
+  /// On success, fills Info (including Info.CmpMI) and returns true.
+  virtual bool canConvertToCCMP(MachineBasicBlock &Head,
+                                MachineBasicBlock &CmpBB,
+                                ArrayRef<MachineOperand> HeadCond,
+                                bool HeadTBBIsCmpBB,
+                                ArrayRef<MachineOperand> CmpBBCond,
+                                bool CmpBBTBBIsTail,
+                                const MachineRegisterInfo &MRI,
+                                CCmpConvInfo &Info) const {
+    return false;
+  }
+
+  /// Emit the conditional compare that replaces Info.CmpMI, using the target
+  /// data stashed by canConvertToCCMP(). This is invoked after the generic pass
+  /// has spliced CmpBB into Head and removed Head's branch, so the target only
+  /// performs the instruction rewrite (and any Head-terminator fixup, e.g.
+  /// synthesizing a compare for a cbz/cbnz head, or re-inserting a conditional
+  /// branch when the folded compare was itself a terminator).
+  ///
+  /// SpliceLoc is the first instruction spliced from CmpBB into Head (the splice
+  /// boundary), the insertion point for any synthesized Head compare. HeadTermDL
+  /// is the debug location of the (now-removed) Head terminator. HeadCond is the
+  /// condition array captured before the branch was removed. The generic caller
+  /// erases Info.CmpMI and fixes up Head's terminator afterwards. Returns the
+  /// new conditional-compare instruction.
+  virtual MachineInstr *convertToCCMP(MachineBasicBlock &Head,
+                                      MachineBasicBlock::iterator SpliceLoc,
+                                      const DebugLoc &HeadTermDL,
+                                      ArrayRef<MachineOperand> HeadCond,
+                                      const CCmpConvInfo &Info,
+                                      MachineRegisterInfo &MRI) const {
+    llvm_unreachable("Target didn't implement TargetInstrInfo::convertToCCMP!");
+  }
+
+  /// Return the expected code-size delta (in number of instructions) of
+  /// converting the candidate described by Info into a conditional compare.
+  /// Used by the MinSize heuristic. Defaults to 0 (no size change assumed).
+  virtual int getCCMPCodeSizeDelta(const CCmpConvInfo &Info,
+                                   ArrayRef<MachineOperand> HeadCond) const {
+    return 0;
+  }
+
   /// Given an instruction marked as `isSelect = true`, attempt to optimize MI
   /// by merging it with one of its operands. Returns nullptr on failure.
   ///
diff --git a/llvm/include/llvm/CodeGen/TargetSubtargetInfo.h b/llvm/include/llvm/CodeGen/TargetSubtargetInfo.h
index 0dc8b339e8ebb..7cf3e1c8d4568 100644
--- a/llvm/include/llvm/CodeGen/TargetSubtargetInfo.h
+++ b/llvm/include/llvm/CodeGen/TargetSubtargetInfo.h
@@ -343,6 +343,21 @@ class LLVM_ABI TargetSubtargetInfo : public MCSubtargetInfo {
   /// Enable the use of the early if conversion pass.
   virtual bool enableEarlyIfConversion() const { return false; }
 
+  /// Per-target tuning for the conditional-compare formation pass
+  /// (MachineConditionalCompares). The defaults reproduce the historical
+  /// AArch64 cost model.
+  struct CCmpConvHeuristics {
+    /// Convert whenever it does not grow code when the function is MinSize.
+    bool UseCodeSizeDeltaOnMinSize = false;
+  };
+
+  /// Enable the target-independent conditional-compare formation pass
+  /// (MachineConditionalCompares) for this subtarget.
+  virtual bool enableCCMPFormation() const { return false; }
+
+  /// Return the tunable heuristics for conditional-compare formation.
+  virtual CCmpConvHeuristics getCCmpConvHeuristics() const { return {}; }
+
   /// Return PBQPConstraint(s) for the target.
   ///
   /// Override to provide custom PBQP constraints.
diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h
index dec7a5ff0845d..09aa8caf5aaf6 100644
--- a/llvm/include/llvm/InitializePasses.h
+++ b/llvm/include/llvm/InitializePasses.h
@@ -199,6 +199,7 @@ initializeMachineBranchProbabilityInfoWrapperPassPass(PassRegistry &);
 LLVM_ABI void initializeMachineCFGPrinterLegacyPass(PassRegistry &);
 LLVM_ABI void initializeMachineCSELegacyPass(PassRegistry &);
 LLVM_ABI void initializeMachineCombinerLegacyPass(PassRegistry &);
+LLVM_ABI void initializeMachineConditionalComparesLegacyPass(PassRegistry &);
 LLVM_ABI void initializeMachineCopyPropagationLegacyPass(PassRegistry &);
 LLVM_ABI void initializeMachineCycleInfoPrinterLegacyPass(PassRegistry &);
 LLVM_ABI void initializeMachineCycleInfoWrapperPassPass(PassRegistry &);
diff --git a/llvm/include/llvm/Passes/MachinePassRegistry.def b/llvm/include/llvm/Passes/MachinePassRegistry.def
index 1bdfd72c9d736..88828667c036f 100644
--- a/llvm/include/llvm/Passes/MachinePassRegistry.def
+++ b/llvm/include/llvm/Passes/MachinePassRegistry.def
@@ -92,6 +92,7 @@ MACHINE_FUNCTION_PASS("legalizer", LegalizerPass())
 MACHINE_FUNCTION_PASS("load-store-opt", LoadStoreOptPass())
 MACHINE_FUNCTION_PASS("localizer", LocalizerPass())
 MACHINE_FUNCTION_PASS("localstackalloc", LocalStackSlotAllocationPass())
+MACHINE_FUNCTION_PASS("machine-ccmp", MachineConditionalComparesPass())
 MACHINE_FUNCTION_PASS("machine-combiner", MachineCombinerPass())
 MACHINE_FUNCTION_PASS("machine-cp", MachineCopyPropagationPass())
 MACHINE_FUNCTION_PASS("machine-cse", MachineCSEPass())
diff --git a/llvm/lib/CodeGen/CMakeLists.txt b/llvm/lib/CodeGen/CMakeLists.txt
index 99dfb4bb09df7..b39d9a1a8b71c 100644
--- a/llvm/lib/CodeGen/CMakeLists.txt
+++ b/llvm/lib/CodeGen/CMakeLists.txt
@@ -125,6 +125,7 @@ add_llvm_component_library(LLVMCodeGen
   MachineBranchProbabilityInfo.cpp
   MachineCFGPrinter.cpp
   MachineCombiner.cpp
+  MachineConditionalCompares.cpp
   MachineConvergenceVerifier.cpp
   MachineCopyPropagation.cpp
   MachineCSE.cpp
diff --git a/llvm/lib/CodeGen/CodeGen.cpp b/llvm/lib/CodeGen/CodeGen.cpp
index 7fb2fca6b6494..a7ebd7ae6e0ed 100644
--- a/llvm/lib/CodeGen/CodeGen.cpp
+++ b/llvm/lib/CodeGen/CodeGen.cpp
@@ -89,6 +89,7 @@ void llvm::initializeCodeGen(PassRegistry &Registry) {
   initializeMachineCFGPrinterLegacyPass(Registry);
   initializeMachineCSELegacyPass(Registry);
   initializeMachineCombinerLegacyPass(Registry);
+  initializeMachineConditionalComparesLegacyPass(Registry);
   initializeMachineDominanceFrontierWrapperPassPass(Registry);
   initializeMachineCopyPropagationLegacyPass(Registry);
   initializeMachineCycleInfoPrinterLegacyPass(Registry);
diff --git a/llvm/lib/Target/AArch64/AArch64ConditionalCompares.cpp b/llvm/lib/CodeGen/MachineConditionalCompares.cpp
similarity index 55%
rename from llvm/lib/Target/AArch64/AArch64ConditionalCompares.cpp
rename to llvm/lib/CodeGen/MachineConditionalCompares.cpp
index f490b5f94fe0d..ec06a55014703 100644
--- a/llvm/lib/Target/AArch64/AArch64ConditionalCompares.cpp
+++ b/llvm/lib/CodeGen/MachineConditionalCompares.cpp
@@ -1,4 +1,4 @@
-//===-- AArch64ConditionalCompares.cpp --- CCMP formation for AArch64 -----===//
+//===-- MachineConditionalCompares.cpp --- CCMP formation -----------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -6,32 +6,41 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// This file implements the AArch64ConditionalCompares pass which reduces
-// branching and code size by using the conditional compare instructions CCMP,
-// CCMN, and FCMP.
+// This file implements the target-independent MachineConditionalCompares pass
+// which reduces branching by using the conditional-compare instructions
+// (CCMP/CTEST on X86; CCMP/CCMN/FCCMP on AArch64).
 //
 // The CFG transformations for forming conditional compares are very similar to
 // if-conversion, and this pass should run immediately before the early
-// if-conversion pass.
+// if-conversion pass. The transform itself is target-independent; the
+// recognition of a convertible compare and the emission of the conditional
+// compare are delegated to the target via TargetInstrInfo hooks
+// (getConditionalCompareFlagReg / canConvertToCCMP / convertToCCMP /
+// getCCMPCodeSizeDelta) and the pass is gated and tuned per target via
+// TargetSubtargetInfo (enableCCMPFormation / getCCmpConvHeuristics).
 //
 //===----------------------------------------------------------------------===//
 
-#include "AArch64.h"
+#include "llvm/CodeGen/MachineConditionalCompares.h"
 #include "llvm/ADT/DepthFirstIterator.h"
+#include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/Statistic.h"
+#include "llvm/Analysis/OptimizationRemarkEmitter.h"
 #include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
 #include "llvm/CodeGen/MachineDominators.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineInstrBundle.h"
 #include "llvm/CodeGen/MachineLoopInfo.h"
-#include "llvm/CodeGen/MachinePassManager.h"
+#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/MachineTraceMetrics.h"
 #include "llvm/CodeGen/Passes.h"
 #include "llvm/CodeGen/TargetInstrInfo.h"
 #include "llvm/CodeGen/TargetRegisterInfo.h"
 #include "llvm/CodeGen/TargetSubtargetInfo.h"
+#include "llvm/IR/Function.h"
 #include "llvm/InitializePasses.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
@@ -39,17 +48,17 @@
 
 using namespace llvm;
 
-#define DEBUG_TYPE "aarch64-ccmp"
+#define DEBUG_TYPE "machine-ccmp"
 
 // Absolute maximum number of instructions allowed per speculated block.
 // This bypasses all other heuristics, so it should be set fairly high.
 static cl::opt<unsigned> BlockInstrLimit(
-    "aarch64-ccmp-limit", cl::init(30), cl::Hidden,
+    "machine-ccmp-limit", cl::init(30), cl::Hidden,
     cl::desc("Maximum number of instructions per speculated block."));
 
 // Stress testing mode - disable heuristics.
-static cl::opt<bool> Stress("aarch64-stress-ccmp", cl::Hidden,
-                            cl::desc("Turn all knobs to 11"));
+static cl::opt<bool> Stress("stress-machine-ccmp", cl::Hidden,
+                            cl::desc("Turn all knobs to 11"), cl::init(false));
 
 STATISTIC(NumConsidered, "Number of ccmps considered");
 STATISTIC(NumPhiRejs, "Number of ccmps rejected (PHI)");
@@ -57,16 +66,8 @@ STATISTIC(NumPhysRejs, "Number of ccmps rejected (Physregs)");
 STATISTIC(NumPhi2Rejs, "Number of ccmps rejected (PHI2)");
 STATISTIC(NumHeadBranchRejs, "Number of ccmps rejected (Head branch)");
 STATISTIC(NumCmpBranchRejs, "Number of ccmps rejected (CmpBB branch)");
-STATISTIC(NumCmpTermRejs, "Number of ccmps rejected (CmpBB is cbz...)");
-STATISTIC(NumImmRangeRejs, "Number of ccmps rejected (Imm out of range)");
-STATISTIC(NumLiveDstRejs, "Number of ccmps rejected (Cmp dest live)");
-STATISTIC(NumMultNZCVUses, "Number of ccmps rejected (NZCV used)");
-STATISTIC(NumUnknNZCVDefs, "Number of ccmps rejected (NZCV def unknown)");
-
 STATISTIC(NumSpeculateRejs, "Number of ccmps rejected (Can't speculate)");
-
 STATISTIC(NumConverted, "Number of ccmp instructions created");
-STATISTIC(NumCompBranches, "Number of cbz/cbnz branches converted");
 
 //===----------------------------------------------------------------------===//
 //                                 SSACCmpConv
@@ -132,14 +133,17 @@ STATISTIC(NumCompBranches, "Number of cbz/cbnz branches converted");
 // between Head and Tail, just like if-converting a diamond.
 //
 // FIXME: Handle PHIs in Tail by turning them into selects (if-conversion).
-
+//
 namespace {
 class SSACCmpConv {
-  MachineFunction *MF;
   const TargetInstrInfo *TII;
   const TargetRegisterInfo *TRI;
   MachineRegisterInfo *MRI;
   const MachineBranchProbabilityInfo *MBPI;
+  MachineOptimizationRemarkEmitter *ORE;
+
+  /// The physical flag/status register clobbered by ccmp candidates.
+  MCRegister FlagReg;
 
 public:
   /// The first block containing a conditional branch, dominating everything
@@ -156,17 +160,16 @@ class SSACCmpConv {
   MachineInstr *CmpMI;
 
 private:
-  /// The branch condition in Head as determined by analyzeBranch.
+  /// The branch condition in Head as determined by analyzeBranch. Stored
+  /// opaquely; only round-tripped through the target hooks.
   SmallVector<MachineOperand, 4> HeadCond;
 
-  /// The condition code that makes Head branch to CmpBB.
-  AArch64CC::CondCode HeadCmpBBCC;
-
-  /// The branch condition in CmpBB.
+  /// The branch condition in CmpBB as determined by analyzeBranch. Stored
+  /// opaquely; only round-tripped through the target hooks.
   SmallVector<MachineOperand, 4> CmpBBCond;
 
-  /// The condition code that makes CmpBB branch to Tail.
-  AArch64CC::CondCode CmpBBTailCC;
+  /// Target-owned recognition/emission state produced by canConvertToCCMP().
+  TargetInstrInfo::CCmpConvInfo Info;
 
   /// Check if the Tail PHIs are trivially convertible.
   bool trivialTailPHIs();
@@ -174,42 +177,40 @@ class SSACCmpConv {
   /// Remove CmpBB from the Tail PHIs.
   void updateTailPHIs();
 
-  /// Check if an operand defining DstReg is dead.
-  bool isDeadDef(unsigned DstReg);
-
-  /// Find the compare instruction in MBB that controls the conditional branch.
-  /// Return NULL if a convertible instruction can't be found.
-  MachineInstr *findConvertibleCompare(MachineBasicBlock *MBB);
-
   /// Return true if all non-terminator instructions in MBB can be safely
   /// speculated.
   bool canSpeculateInstrs(MachineBasicBlock *MBB, const MachineInstr *CmpMI);
 
 public:
-  /// runOnMachineFunction - Initialize per-function data structures.
-  void runOnMachineFunction(MachineFunction &MF,
-                            const MachineBranchProbabilityInfo *MBPI) {
-    this->MF = &MF;
+  /// Initialize per-function data structures.
+  void init(MachineFunction &MF, const MachineBranchProbabilityInfo *MBPI,
+            MachineOptimizationRemarkEmitter *ORE) {
     this->MBPI = MBPI;
+    this->ORE = ORE;
     TII = MF.getSubtarget().getInstrInfo();
     TRI = MF.getSubtarget().getRegisterInfo();
     MRI = &MF.getRegInfo();
+    FlagReg = TII->getConditionalCompareFlagReg();
   }
 
-  /// If the sub-CFG headed by MBB can be cmp-converted, initialize the
-  /// internal state, and return true.
+  /// If the sub-CFG headed by MBB can be cmp-converted, initialize the internal
+  /// state, and return true.
   bool canConvert(MachineBasicBlock *MBB);
 
-  /// Cmo-convert the last block passed to canConvertCmp(), assuming
-  /// it is possible. Add any erased blocks to RemovedBlocks.
+  /// Cmp-convert the last block passed to canConvert(), assuming it is
+  /// possible. Add any erased blocks to RemovedBlocks.
   void convert(SmallVectorImpl<MachineBasicBlock *> &RemovedBlocks);
 
-  /// Return the expected code size delta if the conversion into a
-  /// conditional compare is performed.
-  int expectedCodeSizeDelta() const;
+  /// Return the expected code size delta if the conversion into a conditional
+  /// compare is performed.
+  int expectedCodeSizeDelta() const {
+    return TII->getCCMPCodeSizeDelta(Info, HeadCond);
+  }
 };
 } // end anonymous namespace
 
+// Detect a chain of vreg-to-vreg copies feeding Reg, returning the original
+// value. This lets trivialTailPHIs() see copy-equivalent PHI operands as equal.
 static Register lookThroughCopies(Register Reg, MachineRegisterInfo *MRI) {
   MachineInstr *MI;
   while ((MI = MRI->getUniqueVRegDef(Reg)) &&
@@ -224,14 +225,12 @@ static Register lookThroughCopies(Register Reg, MachineRegisterInfo *MRI) {
 // Check that all PHIs in Tail are selecting the same value from Head and CmpBB.
 // This means that no if-conversion is required when merging CmpBB into Head.
 bool SSACCmpConv::trivialTailPHIs() {
-  for (auto &I : *Tail) {
-    if (!I.isPHI())
-      break;
+  for (auto &I : Tail->phis()) {
     unsigned HeadReg = 0, CmpBBReg = 0;
     // PHI operands come in (VReg, MBB) pairs.
-    for (unsigned oi = 1, oe = I.getNumOperands(); oi != oe; oi += 2) {
-      MachineBasicBlock *MBB = I.getOperand(oi + 1).getMBB();
-      Register Reg = lookThroughCopies(I.getOperand(oi).getReg(), MRI);
+    for (unsigned Idx = 1, End = I.getNumOperands(); Idx != End; Idx += 2) {
+      MachineBasicBlock *MBB = I.getOperand(Idx + 1).getMBB();
+      Register Reg = lookThroughCopies(I.getOperand(Idx).getReg(), MRI);
       if (MBB == Head) {
         assert((!HeadReg || HeadReg...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/219359


More information about the llvm-commits mailing list