[llvm] [LV] Create in-loop sub reductions (PR #147026)

Benjamin Maxwell via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 17 10:18:47 PDT 2025


================
@@ -362,17 +363,24 @@ bool RecurrenceDescriptor::AddReductionVar(
     if (Cur != Phi && IsAPhi && Cur->getParent() == Phi->getParent())
       return false;
 
-    // Reductions of instructions such as Div, and Sub is only possible if the
+    // Reductions of instructions such as Div is only possible if the
     // LHS is the reduction variable.
-    if (!Cur->isCommutative() && !IsAPhi && !isa<SelectInst>(Cur) &&
-        !isa<ICmpInst>(Cur) && !isa<FCmpInst>(Cur) &&
+    if ((Kind != RecurKind::Sub && !Cur->isCommutative()) && !IsAPhi &&
+        !isa<SelectInst>(Cur) && !isa<ICmpInst>(Cur) && !isa<FCmpInst>(Cur) &&
         !VisitedInsts.count(dyn_cast<Instruction>(Cur->getOperand(0))))
       return false;
 
     // Any reduction instruction must be of one of the allowed kinds. We ignore
     // the starting value (the Phi or an AND instruction if the Phi has been
     // type-promoted).
     if (Cur != Start) {
+      // Normally the recur kind is expected to stay the same across all
+      // reduction instructions. Add and sub can appear in chained reductions so
+      // accept a sub if the recur kind is add, and vice versa.
+      if (Kind == RecurKind::Add && Cur->getOpcode() == Instruction::Sub)
+        Kind = RecurKind::Sub;
+      else if (Kind == RecurKind::Sub && Cur->getOpcode() == Instruction::Add)
+        Kind = RecurKind::Add;
----------------
MacDue wrote:

Forgot to mention, but this also requires updating `isReductionPHI()` to attempt to match `Add` reductions first:

```
  if (AddReductionVar(Phi, RecurKind::Add, TheLoop, FMF, RedDes, DB, AC, DT,
                      SE)) {
    LLVM_DEBUG(dbgs() << "Found an ADD reduction PHI." << *Phi << "\n");
    return true;
  }
  if (AddReductionVar(Phi, RecurKind::Sub, TheLoop, FMF, RedDes, DB, AC, DT,
                      SE)) {
    LLVM_DEBUG(dbgs() << "Found a SUB reduction PHI." << *Phi << "\n");
    return true;
  }
```

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


More information about the llvm-commits mailing list