[llvm] [IVDescriptors][NFC] Refactor getReductionOpChain to remove the dependency of non-arithmetic reductions on getOpcode. (PR #118777)

Mel Chen via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 5 01:56:31 PST 2024


https://github.com/Mel-Chen created https://github.com/llvm/llvm-project/pull/118777

Non-arithmetic reductions do not require the use of binary opcodes.
As a first step toward removing the dependency of non-arithmetic reductions on `getOpcode` function, this patch refactors the `getReductionOpChain` function.

In the future, once all users of `getOpcode` function are refactored, an assertion can be added to `getOpcode` function to ensure that only arithmetic reductions rely on it.

>From 1282bd9986cc60af20ca3dac29ddeb839d955620 Mon Sep 17 00:00:00 2001
From: Mel Chen <mel.chen at sifive.com>
Date: Thu, 5 Dec 2024 01:34:22 -0800
Subject: [PATCH] [IVDescriptors][NFC] Refactor getReductionOpChain to remove
 the dependency of non-arithmetic reductions on getOpcode.

---
 llvm/include/llvm/Analysis/IVDescriptors.h |  3 +++
 llvm/lib/Analysis/IVDescriptors.cpp        | 15 ++++++++++-----
 2 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/llvm/include/llvm/Analysis/IVDescriptors.h b/llvm/include/llvm/Analysis/IVDescriptors.h
index 5d992faf99d27f..913cd8db894cf0 100644
--- a/llvm/include/llvm/Analysis/IVDescriptors.h
+++ b/llvm/include/llvm/Analysis/IVDescriptors.h
@@ -213,6 +213,9 @@ class RecurrenceDescriptor {
   /// Returns true if the recurrence kind is a floating point kind.
   static bool isFloatingPointRecurrenceKind(RecurKind Kind);
 
+  /// Returns true if the recurrence kind is arithmetic.
+  static bool isArithmeticRecurrenceKind(RecurKind Kind);
+
   /// Returns true if the recurrence kind is an integer min/max kind.
   static bool isIntMinMaxRecurrenceKind(RecurKind Kind) {
     return Kind == RecurKind::UMin || Kind == RecurKind::UMax ||
diff --git a/llvm/lib/Analysis/IVDescriptors.cpp b/llvm/lib/Analysis/IVDescriptors.cpp
index e1eb219cf977e1..103f1d3149121b 100644
--- a/llvm/lib/Analysis/IVDescriptors.cpp
+++ b/llvm/lib/Analysis/IVDescriptors.cpp
@@ -60,6 +60,11 @@ bool RecurrenceDescriptor::isFloatingPointRecurrenceKind(RecurKind Kind) {
   return (Kind != RecurKind::None) && !isIntegerRecurrenceKind(Kind);
 }
 
+bool RecurrenceDescriptor::isArithmeticRecurrenceKind(RecurKind Kind) {
+  return (Kind != RecurKind::None) && !isMinMaxRecurrenceKind(Kind) &&
+         !isAnyOfRecurrenceKind(Kind);
+}
+
 /// Determines if Phi may have been type-promoted. If Phi has a single user
 /// that ANDs the Phi with a type mask, return the user. RT is updated to
 /// account for the narrower bit width represented by the mask, and the AND
@@ -1063,7 +1068,7 @@ unsigned RecurrenceDescriptor::getOpcode(RecurKind Kind) {
 SmallVector<Instruction *, 4>
 RecurrenceDescriptor::getReductionOpChain(PHINode *Phi, Loop *L) const {
   SmallVector<Instruction *, 4> ReductionOperations;
-  unsigned RedOp = getOpcode();
+  bool IsArithmetic = isArithmeticRecurrenceKind(Kind);
 
   // Search down from the Phi to the LoopExitInstr, looking for instructions
   // with a single user of the correct type for the reduction.
@@ -1081,7 +1086,7 @@ RecurrenceDescriptor::getReductionOpChain(PHINode *Phi, Loop *L) const {
   // more expensive than out-of-loop reductions, and need to be costed more
   // carefully.
   unsigned ExpectedUses = 1;
-  if (RedOp == Instruction::ICmp || RedOp == Instruction::FCmp)
+  if (!IsArithmetic)
     ExpectedUses = 2;
 
   auto getNextInstruction = [&](Instruction *Cur) -> Instruction * {
@@ -1089,7 +1094,7 @@ RecurrenceDescriptor::getReductionOpChain(PHINode *Phi, Loop *L) const {
       Instruction *UI = cast<Instruction>(User);
       if (isa<PHINode>(UI))
         continue;
-      if (RedOp == Instruction::ICmp || RedOp == Instruction::FCmp) {
+      if (!IsArithmetic) {
         // We are expecting a icmp/select pair, which we go to the next select
         // instruction if we can. We already know that Cur has 2 uses.
         if (isa<SelectInst>(UI))
@@ -1101,7 +1106,7 @@ RecurrenceDescriptor::getReductionOpChain(PHINode *Phi, Loop *L) const {
     return nullptr;
   };
   auto isCorrectOpcode = [&](Instruction *Cur) {
-    if (RedOp == Instruction::ICmp || RedOp == Instruction::FCmp) {
+    if (!IsArithmetic) {
       Value *LHS, *RHS;
       return SelectPatternResult::isMinOrMax(
           matchSelectPattern(Cur, LHS, RHS).Flavor);
@@ -1110,7 +1115,7 @@ RecurrenceDescriptor::getReductionOpChain(PHINode *Phi, Loop *L) const {
     if (isFMulAddIntrinsic(Cur))
       return true;
 
-    return Cur->getOpcode() == RedOp;
+    return Cur->getOpcode() == getOpcode();
   };
 
   // Attempt to look through Phis which are part of the reduction chain



More information about the llvm-commits mailing list