[llvm] [X86][APX] Reuse EFLAGS across multi-predecessor blocks via NF in optimizeCompareInstr (PR #208184)
Phoebe Wang via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 13 23:04:30 PDT 2026
================
@@ -5474,10 +5560,35 @@ bool X86InstrInfo::optimizeCompareInstr(MachineInstr &CmpInstr, Register SrcReg,
if (MI || Sub)
break;
- // Reached begin of basic block. Continue in predecessor if there is
- // exactly one.
- if (MBB->pred_size() != 1)
- return false;
+ // Reached the begin of the basic block. If it has exactly one predecessor,
+ // continue the backward scan there. Otherwise (multiple predecessors), try
+ // to reuse EFLAGS from a dominating producer (handled below).
+ if (MBB->pred_size() != 1) {
+ // The block has multiple predecessors. We can still reuse EFLAGS from an
+ // equivalent flag producer that dominates CmpInstr, provided every path
+ // from that producer to CmpInstr only clobbers EFLAGS via instructions
+ // that have an NF (no-flags) variant (which requires APX). This handles
+ // patterns like (CMP duplicated by CodeGenPrepare across a diamond):
+ // entry: cmp %x, C ; br
+ // bb1: imul ... ; clobbers EFLAGS -> {nf} imul
+ // bb2: ...
+ // bb3: cmp %x, C ; <-- redundant, reuse EFLAGS from entry
+ // cmovcc ...
+ //
+ // Only attempt this when no NF conversion has been collected yet. An NF
+ // conversion grows code size, and any already collected lies on the
+ // single-predecessor chain to CmpInstr, i.e. the unconditional path the
+ // compare removal saves, so converting it is pure added cost. Conversions
+ // the dominating walk collects instead lie on the mutually exclusive
+ // diamond arms and are only conditionally executed.
+ if (HasNF && InstsToUpdate.empty())
----------------
phoebewang wrote:
Why InstsToUpdate must be empty?
https://github.com/llvm/llvm-project/pull/208184
More information about the llvm-commits
mailing list