[PATCH] D153558: Allow LoopBounds to detect the StepValue for a decrementing loop with a subtract StepInst

Adel Ejjeh via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 22 08:14:04 PDT 2023


aejjehint created this revision.
aejjehint added reviewers: kazu, MaskRay, fhahn.
aejjehint added a project: LLVM.
Herald added subscribers: StephenFan, hiraditya.
Herald added a project: All.
aejjehint requested review of this revision.
Herald added a subscriber: llvm-commits.

This change allows the LoopBounds to correctly identify the StepValue when the loop is decrementing and the stepinst is a subtract operation.


https://reviews.llvm.org/D153558

Files:
  llvm/lib/Analysis/LoopInfo.cpp
  llvm/unittests/Analysis/LoopInfoTest.cpp


Index: llvm/unittests/Analysis/LoopInfoTest.cpp
===================================================================
--- llvm/unittests/Analysis/LoopInfoTest.cpp
+++ llvm/unittests/Analysis/LoopInfoTest.cpp
@@ -746,7 +746,7 @@
         EXPECT_EQ(Bounds->getStepInst().getName(), "inc");
         ConstantInt *StepValue =
             dyn_cast_or_null<ConstantInt>(Bounds->getStepValue());
-        EXPECT_EQ(StepValue, nullptr);
+        EXPECT_TRUE(StepValue && StepValue->getSExtValue() == -1);
         ConstantInt *FinalIVValue =
             dyn_cast<ConstantInt>(&Bounds->getFinalIVValue());
         EXPECT_TRUE(FinalIVValue && FinalIVValue->isZero());
Index: llvm/lib/Analysis/LoopInfo.cpp
===================================================================
--- llvm/lib/Analysis/LoopInfo.cpp
+++ llvm/lib/Analysis/LoopInfo.cpp
@@ -210,14 +210,34 @@
   if (!InitialIVValue || !StepInst)
     return std::nullopt;
 
-  const SCEV *Step = IndDesc.getStep();
-  Value *StepInstOp1 = StepInst->getOperand(1);
-  Value *StepInstOp0 = StepInst->getOperand(0);
+// We need to make sure we get the right step in case the stepinst is a sub
+  // First, try to get the step as a constant int. If that doesn't work, get it
+  // as a scev, but it needs to be inverted if the stepinst is a sub!
   Value *StepValue = nullptr;
-  if (SE.getSCEV(StepInstOp1) == Step)
-    StepValue = StepInstOp1;
-  else if (SE.getSCEV(StepInstOp0) == Step)
-    StepValue = StepInstOp0;
+  if (ConstantInt *StepConst = IndDesc.getConstIntStepValue()) {
+    StepValue = StepConst;
+  } else {
+    const SCEV *Step = IndDesc.getStep();
+    // If the stepinst is a subtract, the SCEV returned for Step will be a
+    // negative number. This will cause the below if/elseif to fail because the
+    // operand in the sub instruction will be a positive number. In this case,
+    // we should check when we have a sub and generate a new SCEV for step that
+    // is equal to -1 * Step.
+    if (StepInst->getOpcode() == Instruction::Sub) {
+      const SCEV *MinusOneSCEV =
+          SE.getConstant(Type::getInt32Ty(SE.getContext()), -1, true);
+      const SCEV *InvertedStep = SE.getMulExpr(MinusOneSCEV, Step);
+      Step = InvertedStep;
+    }
+    Value *StepInstOp1 = StepInst->getOperand(1);
+    Value *StepInstOp0 = StepInst->getOperand(0);
+    if (SE.getSCEV(StepInstOp1) == Step)
+      StepValue = StepInstOp1;
+    else if (SE.getSCEV(StepInstOp0) == Step)
+      StepValue = StepInstOp0;
+    else
+      return std::nullopt;
+  }
 
   Value *FinalIVValue = findFinalIVValue(L, IndVar, *StepInst);
   if (!FinalIVValue)


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D153558.533612.patch
Type: text/x-patch
Size: 2615 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230622/845de5d5/attachment.bin>


More information about the llvm-commits mailing list