[llvm] [LV] Don't predicate divs with invariant divisor when folding tail (PR #98904)

via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 24 03:34:40 PDT 2024


================
@@ -3348,40 +3348,48 @@ bool LoopVectorizationCostModel::isPredicatedInst(Instruction *I) const {
     return false;
 
   // Can we prove this instruction is safe to unconditionally execute?
-  // If not, we must use some form of predication.
+  if (I->getOpcode() == Instruction::Call)
+    return Legal->isMaskRequired(I);
+
+  if (isa<LoadInst, StoreInst>(I) && !Legal->isMaskRequired(I))
+    return false;
+
+  // TODO: We can use the loop-preheader as context point here and get
+  // context sensitive reasoning
+  if (isa<BranchInst, PHINode>(I) || isSafeToSpeculativelyExecute(I))
+    return false;
+
+  // If the instruction was executed conditionally in the original scalar loop,
+  // predication is needed.
+  if (Legal->blockNeedsPredication(I->getParent()))
+    return true;
+
+  // Tail folding may introduce additional predication, but we're guaranteed to
+  // always have at least one active lane. If the instruction in the original
+  // scalar loop was executed unconditionally, it may not need predication,
+  // depending on its operands.
   switch(I->getOpcode()) {
   default:
-    return false;
+    llvm_unreachable(
+        "instruction should have been considered to not require predication "
+        "by earlier checks");
   case Instruction::Load:
+    // If the address is loop invariant no predication is needed.
+    return !Legal->isInvariant(getLoadStorePointerOperand(I));
   case Instruction::Store: {
-    if (!Legal->isMaskRequired(I))
-      return false;
-    // When we know the load's address is loop invariant and the instruction
-    // in the original scalar loop was unconditionally executed then we
-    // don't need to mark it as a predicated instruction. Tail folding may
-    // introduce additional predication, but we're guaranteed to always have
-    // at least one active lane.  We call Legal->blockNeedsPredication here
-    // because it doesn't query tail-folding.  For stores, we need to prove
+    // For stores, we need to prove
     // both speculation safety (which follows from the same argument as loads),
     // but also must prove the value being stored is correct.  The easiest
     // form of the later is to require that all values stored are the same.
-    if (Legal->isInvariant(getLoadStorePointerOperand(I)) &&
-        (isa<LoadInst>(I) ||
-         (isa<StoreInst>(I) &&
-          TheLoop->isLoopInvariant(cast<StoreInst>(I)->getValueOperand()))) &&
-        !Legal->blockNeedsPredication(I->getParent()))
-      return false;
-    return true;
+    return !(Legal->isInvariant(getLoadStorePointerOperand(I)) &&
+             TheLoop->isLoopInvariant(cast<StoreInst>(I)->getValueOperand()));
   }
   case Instruction::UDiv:
   case Instruction::SDiv:
   case Instruction::SRem:
   case Instruction::URem:
-    // TODO: We can use the loop-preheader as context point here and get
-    // context sensitive reasoning
-    return !isSafeToSpeculativelyExecute(I);
-  case Instruction::Call:
-    return Legal->isMaskRequired(I);
+    // If the divisor is loop-invariant no predication is needed.
+    return !TheLoop->isLoopInvariant(I->getOperand(1));
----------------
ayalz wrote:

```suggestion
    return !TheLoop->isLoopInvariant(I->getOperand(1));
  case Instruction::Call:
    // Side-effects of a Call are assumed to be non-invariant, needing a (fold-tail) mask.
    return true;
```

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


More information about the llvm-commits mailing list