[llvm] [ExpandVectorPredication] Be more precise reporting changes (PR #102313)

Roger Ferrer Ibáñez via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 8 02:19:01 PDT 2024


https://github.com/rofirrim updated https://github.com/llvm/llvm-project/pull/102313

>From 61ccb24a9be3d451dd686e9a79957f54402624c8 Mon Sep 17 00:00:00 2001
From: Roger Ferrer Ibanez <rofirrim at gmail.com>
Date: Tue, 6 Aug 2024 21:13:37 +0200
Subject: [PATCH 1/2] [ExpandVectorPredication] Be more precise reporting
 changes

This is used by PreISelIntrinsicLowering. With this change,
PreISelIntrinsicLowering does not have to assume that there were
changes just because we encountered a VP intrinsic.
---
 llvm/lib/CodeGen/ExpandVectorPredication.cpp  | 41 ++++++++++++-------
 llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp |  4 +-
 2 files changed, 28 insertions(+), 17 deletions(-)

diff --git a/llvm/lib/CodeGen/ExpandVectorPredication.cpp b/llvm/lib/CodeGen/ExpandVectorPredication.cpp
index 5ffdbcda93e753..dab5958355e068 100644
--- a/llvm/lib/CodeGen/ExpandVectorPredication.cpp
+++ b/llvm/lib/CodeGen/ExpandVectorPredication.cpp
@@ -160,11 +160,15 @@ struct CachingVPExpander {
   Value *convertEVLToMask(IRBuilder<> &Builder, Value *EVLParam,
                           ElementCount ElemCount);
 
-  Value *foldEVLIntoMask(VPIntrinsic &VPI);
+  /// If needed, folds the EVL in the mask operand and discards the EVL
+  /// parameter. Returns a pair of the value of the intrinsic after the change
+  /// (if any) and whether the mask was actually folded.
+  std::pair<Value *, bool> foldEVLIntoMask(VPIntrinsic &VPI);
 
   /// "Remove" the %evl parameter of \p PI by setting it to the static vector
-  /// length of the operation.
-  void discardEVLParameter(VPIntrinsic &PI);
+  /// length of the operation. Returns true if the %evl (if any) was effectively
+  /// changed.
+  bool discardEVLParameter(VPIntrinsic &PI);
 
   /// Lower this VP binary operator to a unpredicated binary operator.
   Value *expandPredicationInBinaryOperator(IRBuilder<> &Builder,
@@ -206,6 +210,9 @@ struct CachingVPExpander {
   CachingVPExpander(const TargetTransformInfo &TTI)
       : TTI(TTI), UsingTTIOverrides(anyExpandVPOverridesSet()) {}
 
+  /// Applies the legalization strategy for this intrinsic. Returns true
+  /// if any change happened as part of executing the legalization strategy.
+  /// Returns false if the intrinsic is legal.
   bool expandVectorPredication(VPIntrinsic &VPI);
 };
 
@@ -645,15 +652,15 @@ Value *CachingVPExpander::expandPredicationInComparison(IRBuilder<> &Builder,
   return NewCmp;
 }
 
-void CachingVPExpander::discardEVLParameter(VPIntrinsic &VPI) {
+bool CachingVPExpander::discardEVLParameter(VPIntrinsic &VPI) {
   LLVM_DEBUG(dbgs() << "Discard EVL parameter in " << VPI << "\n");
 
   if (VPI.canIgnoreVectorLengthParam())
-    return;
+    return false;
 
   Value *EVLParam = VPI.getVectorLengthParam();
   if (!EVLParam)
-    return;
+    return false;
 
   ElementCount StaticElemCount = VPI.getStaticVectorLength();
   Value *MaxEVL = nullptr;
@@ -672,16 +679,17 @@ void CachingVPExpander::discardEVLParameter(VPIntrinsic &VPI) {
     MaxEVL = ConstantInt::get(Int32Ty, StaticElemCount.getFixedValue(), false);
   }
   VPI.setVectorLengthParam(MaxEVL);
+  return true;
 }
 
-Value *CachingVPExpander::foldEVLIntoMask(VPIntrinsic &VPI) {
+std::pair<Value *, bool> CachingVPExpander::foldEVLIntoMask(VPIntrinsic &VPI) {
   LLVM_DEBUG(dbgs() << "Folding vlen for " << VPI << '\n');
 
   IRBuilder<> Builder(&VPI);
 
   // Ineffective %evl parameter and so nothing to do here.
   if (VPI.canIgnoreVectorLengthParam())
-    return &VPI;
+    return {&VPI, false};
 
   // Only VP intrinsics can have an %evl parameter.
   Value *OldMaskParam = VPI.getMaskParam();
@@ -704,7 +712,7 @@ Value *CachingVPExpander::foldEVLIntoMask(VPIntrinsic &VPI) {
          "transformation did not render the evl param ineffective!");
 
   // Reassess the modified instruction.
-  return &VPI;
+  return {&VPI, true};
 }
 
 Value *CachingVPExpander::expandPredication(VPIntrinsic &VPI) {
@@ -812,16 +820,22 @@ bool CachingVPExpander::expandVectorPredication(VPIntrinsic &VPI) {
   auto Strategy = getVPLegalizationStrategy(VPI);
   sanitizeStrategy(VPI, Strategy);
 
+  bool Changed = false;
+
   // Transform the EVL parameter.
   switch (Strategy.EVLParamStrategy) {
   case VPLegalization::Legal:
     break;
   case VPLegalization::Discard:
-    discardEVLParameter(VPI);
+    if (discardEVLParameter(VPI))
+      Changed = true;
     break;
   case VPLegalization::Convert:
-    if (foldEVLIntoMask(VPI))
+    if (auto [NewVPI, Folded] = foldEVLIntoMask(VPI); Folded) {
+      (void)NewVPI;
+      Changed = true;
       ++NumFoldedVL;
+    }
     break;
   }
 
@@ -834,13 +848,12 @@ bool CachingVPExpander::expandVectorPredication(VPIntrinsic &VPI) {
   case VPLegalization::Convert:
     if (Value *V = expandPredication(VPI); V != &VPI) {
       ++NumLoweredVPOps;
-      // Return true if and only if the intrinsic was actually removed.
-      return true;
+      Changed = true;
     }
     break;
   }
 
-  return false;
+  return Changed;
 }
 } // namespace
 
diff --git a/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp b/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp
index 0d3dd650b8ee68..6418c54f0b18f0 100644
--- a/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp
+++ b/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp
@@ -357,14 +357,12 @@ bool PreISelIntrinsicLowering::lowerIntrinsics(Module &M) const {
 #define BEGIN_REGISTER_VP_INTRINSIC(VPID, MASKPOS, VLENPOS)                    \
   case Intrinsic::VPID:
 #include "llvm/IR/VPIntrinsics.def"
-      forEachCall(F, [&](CallInst *CI) {
+      Changed |= forEachCall(F, [&](CallInst *CI) {
         Function *Parent = CI->getParent()->getParent();
         const TargetTransformInfo &TTI = LookupTTI(*Parent);
         auto *VPI = cast<VPIntrinsic>(CI);
         return expandVectorPredicationIntrinsic(*VPI, TTI);
       });
-      // Not all intrinsics are removed, but the code is changed in any case.
-      Changed = true;
       break;
     case Intrinsic::objc_autorelease:
       Changed |= lowerObjCCall(F, "objc_autorelease");

>From c5d50bf7bb3724b9868cecb7598b8ca26ee2598b Mon Sep 17 00:00:00 2001
From: Roger Ferrer Ibanez <roger.ferrer at bsc.es>
Date: Thu, 8 Aug 2024 09:18:28 +0000
Subject: [PATCH 2/2] [ExpandVectorPredication] Return details about the kind
 of expansion

This way PreISelIntrinsicLowering can know whether the intrinsic
was effectively removed or just updated.
---
 .../llvm/CodeGen/ExpandVectorPredication.h    | 19 +++++++++++----
 llvm/lib/CodeGen/ExpandVectorPredication.cpp  | 24 +++++++++----------
 llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp | 10 ++++++--
 3 files changed, 35 insertions(+), 18 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/ExpandVectorPredication.h b/llvm/include/llvm/CodeGen/ExpandVectorPredication.h
index c42c644c99e91e..3aafb22eab6bea 100644
--- a/llvm/include/llvm/CodeGen/ExpandVectorPredication.h
+++ b/llvm/include/llvm/CodeGen/ExpandVectorPredication.h
@@ -16,10 +16,21 @@ namespace llvm {
 class TargetTransformInfo;
 class VPIntrinsic;
 
-/// Expand a vector predication intrinsic. Returns true if the intrinsic was
-/// removed/replaced.
-bool expandVectorPredicationIntrinsic(VPIntrinsic &VPI,
-                                      const TargetTransformInfo &TTI);
+/// Represents the details the expansion of a VP intrinsic.
+enum class VPExpansionDetails {
+  /// No change happened during expansion.
+  IntrinsicUnchanged,
+  /// At least one operand was updated.
+  IntrinsicUpdated,
+  /// The whole intrinsic was replaced.
+  IntrinsicReplaced,
+};
+
+/// Expand a vector predication intrinsic. Returns the kind of expansion
+/// that was applied to the intrinsic.
+VPExpansionDetails
+expandVectorPredicationIntrinsic(VPIntrinsic &VPI,
+                                 const TargetTransformInfo &TTI);
 
 } // end namespace llvm
 
diff --git a/llvm/lib/CodeGen/ExpandVectorPredication.cpp b/llvm/lib/CodeGen/ExpandVectorPredication.cpp
index dab5958355e068..675d88d6d38cd9 100644
--- a/llvm/lib/CodeGen/ExpandVectorPredication.cpp
+++ b/llvm/lib/CodeGen/ExpandVectorPredication.cpp
@@ -210,10 +210,9 @@ struct CachingVPExpander {
   CachingVPExpander(const TargetTransformInfo &TTI)
       : TTI(TTI), UsingTTIOverrides(anyExpandVPOverridesSet()) {}
 
-  /// Applies the legalization strategy for this intrinsic. Returns true
-  /// if any change happened as part of executing the legalization strategy.
-  /// Returns false if the intrinsic is legal.
-  bool expandVectorPredication(VPIntrinsic &VPI);
+  /// Expand llvm.vp.* intrinsics as requested by \p TTI.
+  /// Returns the details of the expansion.
+  VPExpansionDetails expandVectorPredication(VPIntrinsic &VPI);
 };
 
 //// CachingVPExpander {
@@ -815,12 +814,12 @@ CachingVPExpander::getVPLegalizationStrategy(const VPIntrinsic &VPI) const {
   return VPStrat;
 }
 
-/// Expand llvm.vp.* intrinsics as requested by \p TTI.
-bool CachingVPExpander::expandVectorPredication(VPIntrinsic &VPI) {
+VPExpansionDetails
+CachingVPExpander::expandVectorPredication(VPIntrinsic &VPI) {
   auto Strategy = getVPLegalizationStrategy(VPI);
   sanitizeStrategy(VPI, Strategy);
 
-  bool Changed = false;
+  VPExpansionDetails Changed = VPExpansionDetails::IntrinsicUnchanged;
 
   // Transform the EVL parameter.
   switch (Strategy.EVLParamStrategy) {
@@ -828,12 +827,12 @@ bool CachingVPExpander::expandVectorPredication(VPIntrinsic &VPI) {
     break;
   case VPLegalization::Discard:
     if (discardEVLParameter(VPI))
-      Changed = true;
+      Changed = VPExpansionDetails::IntrinsicUpdated;
     break;
   case VPLegalization::Convert:
     if (auto [NewVPI, Folded] = foldEVLIntoMask(VPI); Folded) {
       (void)NewVPI;
-      Changed = true;
+      Changed = VPExpansionDetails::IntrinsicUpdated;
       ++NumFoldedVL;
     }
     break;
@@ -848,7 +847,7 @@ bool CachingVPExpander::expandVectorPredication(VPIntrinsic &VPI) {
   case VPLegalization::Convert:
     if (Value *V = expandPredication(VPI); V != &VPI) {
       ++NumLoweredVPOps;
-      Changed = true;
+      Changed = VPExpansionDetails::IntrinsicReplaced;
     }
     break;
   }
@@ -857,7 +856,8 @@ bool CachingVPExpander::expandVectorPredication(VPIntrinsic &VPI) {
 }
 } // namespace
 
-bool llvm::expandVectorPredicationIntrinsic(VPIntrinsic &VPI,
-                                            const TargetTransformInfo &TTI) {
+VPExpansionDetails
+llvm::expandVectorPredicationIntrinsic(VPIntrinsic &VPI,
+                                       const TargetTransformInfo &TTI) {
   return CachingVPExpander(TTI).expandVectorPredication(VPI);
 }
diff --git a/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp b/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp
index 6418c54f0b18f0..9626e785086982 100644
--- a/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp
+++ b/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp
@@ -357,11 +357,17 @@ bool PreISelIntrinsicLowering::lowerIntrinsics(Module &M) const {
 #define BEGIN_REGISTER_VP_INTRINSIC(VPID, MASKPOS, VLENPOS)                    \
   case Intrinsic::VPID:
 #include "llvm/IR/VPIntrinsics.def"
-      Changed |= forEachCall(F, [&](CallInst *CI) {
+      forEachCall(F, [&](CallInst *CI) {
         Function *Parent = CI->getParent()->getParent();
         const TargetTransformInfo &TTI = LookupTTI(*Parent);
         auto *VPI = cast<VPIntrinsic>(CI);
-        return expandVectorPredicationIntrinsic(*VPI, TTI);
+        VPExpansionDetails ED = expandVectorPredicationIntrinsic(*VPI, TTI);
+        // Expansion of VP intrinsics may change the IR but not actually
+        // replace the intrinsic, so update Changed for the pass
+        // and compute Removed for forEachCall.
+        Changed |= ED != VPExpansionDetails::IntrinsicUnchanged;
+        bool Removed = ED == VPExpansionDetails::IntrinsicReplaced;
+        return Removed;
       });
       break;
     case Intrinsic::objc_autorelease:



More information about the llvm-commits mailing list