[llvm] ARM: Track CPSR liveness in Thumb2SizeReduction without kill flags (PR #223068)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 14 23:53:59 PDT 2026


================
@@ -1045,43 +1013,58 @@ bool Thumb2SizeReduce::ReduceMBB(MachineBasicBlock &MBB,
                                  bool SkipPrologueEpilogue) {
   bool Modified = false;
 
-  // Yes, CPSR could be livein.
-  bool LiveCPSR = MBB.isLiveIn(ARM::CPSR);
-  MachineInstr *BundleMI = nullptr;
+  // Narrowing to a flag-setting form is only legal where CPSR is dead.
+  bool LiveCPSR = any_of(MBB.successors(), [](const MachineBasicBlock *Succ) {
+    return Succ->isLiveIn(ARM::CPSR);
+  });
+
+  DenseMap<const MachineInstr *, bool> CPSRLiveAfter;
+  for (MachineInstr &MI : reverse(MBB.instrs())) {
+    if (MI.isBundle() || MI.isDebugInstr())
+      continue;
+    if (ReduceOpcodeMap.contains(MI.getOpcode()))
+      CPSRLiveAfter[&MI] = LiveCPSR;
+    if (MI.definesRegister(ARM::CPSR, /*TRI=*/nullptr))
+      LiveCPSR = false;
+    if (MI.readsRegister(ARM::CPSR, /*TRI=*/nullptr))
+      LiveCPSR = true;
+  }
 
   CPSRDef = nullptr;
   HighLatencyCPSR = false;
 
+  // Skip some bookkeeping in the common case where the avoidCPSRPartialUpdate
+  // heuristic is unnecessary.
+  bool AvoidPartialCPSR = !MinimizeSize && STI->avoidCPSRPartialUpdate();
----------------
arsenm wrote:

This was the really annoying edge case to deal with and I wanted to explicitly spell out at least some of the machinery dedicated to maintaining it. The real cost is this requires doing 2 walks over the block 

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


More information about the llvm-commits mailing list