[llvm] [NFC][SLP] Make choice of dyn_cast_or_null vs dyn_cast_or_present consistent (PR #228180)

Ryan Buchner via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 1 16:49:36 PDT 2026


https://github.com/bababuck updated https://github.com/llvm/llvm-project/pull/228180

>From 485f8cddd27d703542d5c2bcd4ff9c98a4df011b Mon Sep 17 00:00:00 2001
From: bababuck <buchner.ryan at gmail.com>
Date: Thu, 1 Oct 2026 11:05:09 -0700
Subject: [PATCH 1/4] [NFC][SLP] Make choice of dyn_cast_or_null vs
 dyn_cast_or_present consistent

Are functionally idenitical (dyn_cast_or_null is wrapper around dyn_cast_or_present).
Should be consistent within SLPVectorizer which one we choose to use.
---
 llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index c78cb9863e8a1..3635b5fd54620 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -2298,7 +2298,7 @@ class slpvectorizer::BoUpSLP {
       salvageDebugInfo(*I);
       ArrayRef<TreeEntry *> Entries = getTreeEntries(I);
       for (Use &U : I->operands()) {
-        if (auto *OpI = dyn_cast_if_present<Instruction>(U.get());
+        if (auto *OpI = dyn_cast_or_null<Instruction>(U.get());
             OpI && !DeletedInstructions.contains(OpI) && OpI->hasOneUser() &&
             wouldInstructionBeTriviallyDead(OpI, TLI) &&
             !ExternalUseReplacements.contains(OpI) &&
@@ -11340,7 +11340,7 @@ class InstructionsCompatibilityAnalysis {
       }
       // If some of the RHS operands better match most of LHS - swap such
       // operands to increase matching rate.
-      if (auto *BestLHS = dyn_cast_if_present<Instruction>(BestFrontOp)) {
+      if (auto *BestLHS = dyn_cast_or_null<Instruction>(BestFrontOp)) {
         const unsigned BestOpcode = BestLHS->getOpcode();
         for (auto [OpL, OpR] : zip(Operands.front(), Operands.back())) {
           auto *OpRI = dyn_cast<Instruction>(OpR);
@@ -20246,7 +20246,7 @@ InstructionCost BoUpSLP::getTreeCost(InstructionCost TreeCost,
     Value *Usr = EU.User;
     if (Usr && match(Usr, m_OneUse(m_ZExtOrSExt(m_Value()))))
       Usr = cast<Instruction>(Usr)->user_back();
-    auto *User = dyn_cast_if_present<GetElementPtrInst>(Usr);
+    auto *User = dyn_cast_or_null<GetElementPtrInst>(Usr);
     // Only a GEP that feeds a single load/store of a fixed access type drives
     // a real memory address computation.
     Type *AccessTy = nullptr;
@@ -20470,7 +20470,7 @@ InstructionCost BoUpSLP::getTreeCost(InstructionCost TreeCost,
         Entry->getOpcode() == Instruction::Load) {
       // Checks if the user of the external scalar is phi in loop body.
       auto IsPhiInLoop = [&](const ExternalUser &U) {
-        if (auto *Phi = dyn_cast_if_present<PHINode>(U.User)) {
+        if (auto *Phi = dyn_cast_or_null<PHINode>(U.User)) {
           auto *I = cast<Instruction>(U.Scalar);
           const Loop *L = LI->getLoopFor(Phi->getParent());
           return L && (Phi->getParent() == I->getParent() ||

>From a980ce81488d6e16599e0560a6983c6cbbe8786f Mon Sep 17 00:00:00 2001
From: bababuck <buchner.ryan at gmail.com>
Date: Thu, 1 Oct 2026 11:47:19 -0700
Subject: [PATCH 2/4] _or_null -> _is_present

---
 .../Transforms/Vectorize/SLPVectorizer.cpp    | 26 +++++++++----------
 .../SLPCompatibilityAnalysis.cpp              |  2 +-
 2 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index 3635b5fd54620..b0c9f59ea858a 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -2298,7 +2298,7 @@ class slpvectorizer::BoUpSLP {
       salvageDebugInfo(*I);
       ArrayRef<TreeEntry *> Entries = getTreeEntries(I);
       for (Use &U : I->operands()) {
-        if (auto *OpI = dyn_cast_or_null<Instruction>(U.get());
+        if (auto *OpI = dyn_cast_if_present<Instruction>(U.get());
             OpI && !DeletedInstructions.contains(OpI) && OpI->hasOneUser() &&
             wouldInstructionBeTriviallyDead(OpI, TLI) &&
             !ExternalUseReplacements.contains(OpI) &&
@@ -2325,7 +2325,7 @@ class slpvectorizer::BoUpSLP {
     // Process the dead instruction list until empty.
     while (!DeadInsts.empty()) {
       Value *V = DeadInsts.pop_back_val();
-      Instruction *VI = cast_or_null<Instruction>(V);
+      Instruction *VI = cast_if_present<Instruction>(V);
       if (!VI || !VI->getParent())
         continue;
       assert(isInstructionTriviallyDead(VI, TLI) &&
@@ -6698,7 +6698,7 @@ static bool areTwoInsertFromSameBuildVector(
       if ((IE1 != VU && !IE1->hasOneUse()) || IsReusedIdx)
         IE1 = nullptr;
       else
-        IE1 = dyn_cast_or_null<InsertElementInst>(GetBaseOperand(IE1));
+        IE1 = dyn_cast_if_present<InsertElementInst>(GetBaseOperand(IE1));
     }
     if (IE2 && IE2 != VU) {
       unsigned Idx2 = getElementIndex(IE2).value_or(*Idx1);
@@ -6707,7 +6707,7 @@ static bool areTwoInsertFromSameBuildVector(
       if ((IE2 != V && !IE2->hasOneUse()) || IsReusedIdx)
         IE2 = nullptr;
       else
-        IE2 = dyn_cast_or_null<InsertElementInst>(GetBaseOperand(IE2));
+        IE2 = dyn_cast_if_present<InsertElementInst>(GetBaseOperand(IE2));
     }
   } while (!IsReusedIdx && (IE1 || IE2));
   return false;
@@ -11340,7 +11340,7 @@ class InstructionsCompatibilityAnalysis {
       }
       // If some of the RHS operands better match most of LHS - swap such
       // operands to increase matching rate.
-      if (auto *BestLHS = dyn_cast_or_null<Instruction>(BestFrontOp)) {
+      if (auto *BestLHS = dyn_cast_if_present<Instruction>(BestFrontOp)) {
         const unsigned BestOpcode = BestLHS->getOpcode();
         for (auto [OpL, OpR] : zip(Operands.front(), Operands.back())) {
           auto *OpRI = dyn_cast<Instruction>(OpR);
@@ -20246,7 +20246,7 @@ InstructionCost BoUpSLP::getTreeCost(InstructionCost TreeCost,
     Value *Usr = EU.User;
     if (Usr && match(Usr, m_OneUse(m_ZExtOrSExt(m_Value()))))
       Usr = cast<Instruction>(Usr)->user_back();
-    auto *User = dyn_cast_or_null<GetElementPtrInst>(Usr);
+    auto *User = dyn_cast_if_present<GetElementPtrInst>(Usr);
     // Only a GEP that feeds a single load/store of a fixed access type drives
     // a real memory address computation.
     Type *AccessTy = nullptr;
@@ -20353,7 +20353,7 @@ InstructionCost BoUpSLP::getTreeCost(InstructionCost TreeCost,
     // If found user is an insertelement, do not calculate extract cost but try
     // to detect it as a final shuffled/identity match.
     // TODO: what if a user is insertvalue when REVEC is enabled?
-    if (auto *VU = dyn_cast_or_null<InsertElementInst>(EU.User);
+    if (auto *VU = dyn_cast_if_present<InsertElementInst>(EU.User);
         VU && VU->getOperand(1) == EU.Scalar) {
       if (auto *FTy = dyn_cast<FixedVectorType>(VU->getType())) {
         if (!UsedInserts.insert(VU).second)
@@ -20470,7 +20470,7 @@ InstructionCost BoUpSLP::getTreeCost(InstructionCost TreeCost,
         Entry->getOpcode() == Instruction::Load) {
       // Checks if the user of the external scalar is phi in loop body.
       auto IsPhiInLoop = [&](const ExternalUser &U) {
-        if (auto *Phi = dyn_cast_or_null<PHINode>(U.User)) {
+        if (auto *Phi = dyn_cast_if_present<PHINode>(U.User)) {
           auto *I = cast<Instruction>(U.Scalar);
           const Loop *L = LI->getLoopFor(Phi->getParent());
           return L && (Phi->getParent() == I->getParent() ||
@@ -20631,7 +20631,7 @@ InstructionCost BoUpSLP::getTreeCost(InstructionCost TreeCost,
       }
     } else {
       ExtraCost = ScaleCost(ExtraCost, *Entry, EU.Scalar,
-                            cast_or_null<Instruction>(EU.User));
+                            cast_if_present<Instruction>(EU.User));
     }
 
     ExtractCost += ExtraCost;
@@ -21081,7 +21081,7 @@ BoUpSLP::isGatherShuffledSingleRegisterEntry(
   const BasicBlock *TEInsertBlock = nullptr;
   // Main node of PHI entries keeps the correct order of operands/incoming
   // blocks.
-  if (auto *PHI = dyn_cast_or_null<PHINode>(
+  if (auto *PHI = dyn_cast_if_present<PHINode>(
           TEUseEI.UserTE->hasState() ? TEUseEI.UserTE->getMainOp() : nullptr);
       PHI && TEUseEI.UserTE->State != TreeEntry::SplitVectorize) {
     TEInsertBlock = PHI->getIncomingBlock(TEUseEI.EdgeIdx);
@@ -22033,7 +22033,7 @@ Instruction &BoUpSLP::getLastInstructionInBundle(const TreeEntry *E) {
     Res = FindLastInst();
     if (ArrayRef<TreeEntry *> Entries = getTreeEntries(Res); !Entries.empty()) {
       for (auto *E : Entries) {
-        auto *I = dyn_cast_or_null<Instruction>(E->VectorizedValue);
+        auto *I = dyn_cast_if_present<Instruction>(E->VectorizedValue);
         if (!I)
           I = &getLastInstructionInBundle(E);
         if (Res->getParent() == I->getParent() && Res->comesBefore(I))
@@ -22327,7 +22327,7 @@ Value *BoUpSLP::gather(
   SmallVector<int> Mask(VL.size());
   std::iota(Mask.begin(), Mask.end(), 0);
   Value *OriginalRoot = Root;
-  if (auto *SV = dyn_cast_or_null<ShuffleVectorInst>(Root);
+  if (auto *SV = dyn_cast_if_present<ShuffleVectorInst>(Root);
       SV && isa<PoisonValue>(SV->getOperand(1)) &&
       SV->getOperand(0)->getType() == VecTy) {
     Root = SV->getOperand(0);
@@ -24154,7 +24154,7 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E) {
               break;
             Op = Ins;
             Ins =
-                dyn_cast_or_null<Instruction>(Ins->getUniqueUndroppableUser());
+                dyn_cast_if_present<Instruction>(Ins->getUniqueUndroppableUser());
           } while (Ins && Ins->getOperand(0) == Op);
           SmallBitVector UseMask =
               buildUseMask(NumElts, InsertMask, UseMask::UndefsAsMask);
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPCompatibilityAnalysis.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPCompatibilityAnalysis.cpp
index 5dcf2f357e990..fb14107d9d07b 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPCompatibilityAnalysis.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer/SLPCompatibilityAnalysis.cpp
@@ -275,7 +275,7 @@ bool BinOpSameOpcodeHelper::add(const Instruction *I) {
   }
   MaskType InterchangeableMask = OpcodeInMaskForm;
   auto [C, Pos] = isBinOpWithConstant(I);
-  if (auto *CI = dyn_cast_or_null<ConstantInt>(C)) {
+  if (auto *CI = dyn_cast_if_present<ConstantInt>(C)) {
     constexpr MaskType CanBeAll =
         XorBIT | OrBIT | AndBIT | SubBIT | AddBIT | MulBIT | AShrBIT | ShlBIT;
     const APInt &CIValue = CI->getValue();

>From e46411f3864d5770b9b2b5db3370f97a78e2a230 Mon Sep 17 00:00:00 2001
From: bababuck <buchner.ryan at gmail.com>
Date: Thu, 1 Oct 2026 16:07:43 -0700
Subject: [PATCH 3/4] Drop if_present where allowable

---
 llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index b0c9f59ea858a..46eb00286ce10 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -2298,7 +2298,7 @@ class slpvectorizer::BoUpSLP {
       salvageDebugInfo(*I);
       ArrayRef<TreeEntry *> Entries = getTreeEntries(I);
       for (Use &U : I->operands()) {
-        if (auto *OpI = dyn_cast_if_present<Instruction>(U.get());
+        if (auto *OpI = dyn_cast<Instruction>(U.get());
             OpI && !DeletedInstructions.contains(OpI) && OpI->hasOneUser() &&
             wouldInstructionBeTriviallyDead(OpI, TLI) &&
             !ExternalUseReplacements.contains(OpI) &&
@@ -2325,7 +2325,7 @@ class slpvectorizer::BoUpSLP {
     // Process the dead instruction list until empty.
     while (!DeadInsts.empty()) {
       Value *V = DeadInsts.pop_back_val();
-      Instruction *VI = cast_if_present<Instruction>(V);
+      Instruction *VI = cast<Instruction>(V);
       if (!VI || !VI->getParent())
         continue;
       assert(isInstructionTriviallyDead(VI, TLI) &&
@@ -21081,8 +21081,9 @@ BoUpSLP::isGatherShuffledSingleRegisterEntry(
   const BasicBlock *TEInsertBlock = nullptr;
   // Main node of PHI entries keeps the correct order of operands/incoming
   // blocks.
-  if (auto *PHI = dyn_cast_if_present<PHINode>(
-          TEUseEI.UserTE->hasState() ? TEUseEI.UserTE->getMainOp() : nullptr);
+  if (auto *PHI = TEUseEI.UserTE->hasState()
+                      ? dyn_cast<PHINode>(TEUseEI.UserTE->getMainOp())
+                      : nullptr;
       PHI && TEUseEI.UserTE->State != TreeEntry::SplitVectorize) {
     TEInsertBlock = PHI->getIncomingBlock(TEUseEI.EdgeIdx);
     TEInsertPt = TEInsertBlock->getTerminator();

>From 9e63a369e3602dcd2b9f4463897d1a3202ee09bc Mon Sep 17 00:00:00 2001
From: bababuck <buchner.ryan at gmail.com>
Date: Thu, 1 Oct 2026 16:49:18 -0700
Subject: [PATCH 4/4] Lint

---
 llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index 46eb00286ce10..6c8ae75a133a6 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -24154,8 +24154,8 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E) {
             if (!Ins->hasOneUse())
               break;
             Op = Ins;
-            Ins =
-                dyn_cast_if_present<Instruction>(Ins->getUniqueUndroppableUser());
+            Ins = dyn_cast_if_present<Instruction>(
+                Ins->getUniqueUndroppableUser());
           } while (Ins && Ins->getOperand(0) == Op);
           SmallBitVector UseMask =
               buildUseMask(NumElts, InsertMask, UseMask::UndefsAsMask);



More information about the llvm-commits mailing list