[llvm] [DA] runtime predicates for delinearization bounds checks (PR #170713)

via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 4 10:21:19 PST 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-analysis

Author: Sebastian Pop (sebpop)

<details>
<summary>Changes</summary>

When compile-time checks fail, rely on runtime SCEV predicates, instead of failing delinearization entirely.  This allows delinearization to succeed in more cases where compile-time proofs are not possible, enabling more precise dependence analysis under runtime assumptions.

---

Patch is 84.18 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/170713.diff


29 Files Affected:

- (modified) llvm/include/llvm/Analysis/Delinearization.h (+8-5) 
- (modified) llvm/include/llvm/Analysis/DependenceAnalysis.h (+6-3) 
- (modified) llvm/lib/Analysis/Delinearization.cpp (+37-9) 
- (modified) llvm/lib/Analysis/DependenceAnalysis.cpp (+21-18) 
- (modified) llvm/test/Analysis/DependenceAnalysis/Banerjee.ll (+58-14) 
- (modified) llvm/test/Analysis/DependenceAnalysis/Constraints.ll (+28-7) 
- (modified) llvm/test/Analysis/DependenceAnalysis/DADelin.ll (+32-1) 
- (modified) llvm/test/Analysis/DependenceAnalysis/DifferentOffsets.ll (+6) 
- (modified) llvm/test/Analysis/DependenceAnalysis/ExactRDIV.ll (+16-4) 
- (modified) llvm/test/Analysis/DependenceAnalysis/GCD.ll (+57-9) 
- (modified) llvm/test/Analysis/DependenceAnalysis/Invariant.ll (+1-2) 
- (modified) llvm/test/Analysis/DependenceAnalysis/MismatchingNestLevels.ll (+4) 
- (modified) llvm/test/Analysis/DependenceAnalysis/NonCanonicalizedSubscript.ll (+5-2) 
- (modified) llvm/test/Analysis/DependenceAnalysis/Preliminary.ll (+9) 
- (modified) llvm/test/Analysis/DependenceAnalysis/PreliminaryNoValidityCheckFixedSize.ll (+9) 
- (modified) llvm/test/Analysis/DependenceAnalysis/Propagating.ll (+36-10) 
- (modified) llvm/test/Analysis/DependenceAnalysis/SimpleSIVNoValidityCheck.ll (+27) 
- (modified) llvm/test/Analysis/DependenceAnalysis/StrongSIV.ll (+3) 
- (modified) llvm/test/Analysis/DependenceAnalysis/SymbolicSIV.ll (+14) 
- (modified) llvm/test/Analysis/DependenceAnalysis/WeakCrossingSIV.ll (+4) 
- (modified) llvm/test/Analysis/DependenceAnalysis/WeakZeroDstSIV.ll (+1) 
- (modified) llvm/test/Analysis/DependenceAnalysis/WeakZeroSrcSIV.ll (+1) 
- (modified) llvm/test/Analysis/DependenceAnalysis/becount-couldnotcompute.ll (+1) 
- (modified) llvm/test/Analysis/DependenceAnalysis/compute-absolute-value.ll (+4) 
- (modified) llvm/test/Analysis/DependenceAnalysis/gcd-miv-overflow.ll (+7) 
- (modified) llvm/test/Analysis/DependenceAnalysis/monotonicity-cast.ll (+2) 
- (modified) llvm/test/Analysis/DependenceAnalysis/monotonicity-no-wrap-flags.ll (+2) 
- (modified) llvm/test/Analysis/DependenceAnalysis/zero-coefficient.ll (+1) 
- (modified) llvm/test/Transforms/LoopInterchange/loop-interchange-optimization-remarks.ll (+7-7) 


``````````diff
diff --git a/llvm/include/llvm/Analysis/Delinearization.h b/llvm/include/llvm/Analysis/Delinearization.h
index 8fb30925b1ba7..7346128c0b510 100644
--- a/llvm/include/llvm/Analysis/Delinearization.h
+++ b/llvm/include/llvm/Analysis/Delinearization.h
@@ -26,6 +26,7 @@ class GetElementPtrInst;
 class Instruction;
 class ScalarEvolution;
 class SCEV;
+class SCEVPredicate;
 
 /// Compute the array dimensions Sizes from the set of Terms extracted from
 /// the memory access function of this SCEVAddRecExpr (second step of
@@ -144,11 +145,13 @@ bool delinearizeFixedSizeArray(ScalarEvolution &SE, const SCEV *Expr,
 /// Check that each subscript in \p Subscripts is within the corresponding size
 /// in \p Sizes. For the outermost dimension, the subscript being negative is
 /// allowed. If \p Ptr is not nullptr, it may be used to get information from
-/// the IR pointer value, which may help in the validation.
-bool validateDelinearizationResult(ScalarEvolution &SE,
-                                   ArrayRef<const SCEV *> Sizes,
-                                   ArrayRef<const SCEV *> Subscripts,
-                                   const Value *Ptr = nullptr);
+/// the IR pointer value, which may help in the validation. If \p Assume is not
+/// nullptr and a compile-time check fails, runtime predicates are added to
+/// \p Assume instead of returning false.
+bool validateDelinearizationResult(
+    ScalarEvolution &SE, ArrayRef<const SCEV *> Sizes,
+    ArrayRef<const SCEV *> Subscripts, const Value *Ptr = nullptr,
+    SmallVectorImpl<const SCEVPredicate *> *Assume = nullptr);
 
 /// Gathers the individual index expressions from a GEP instruction.
 ///
diff --git a/llvm/include/llvm/Analysis/DependenceAnalysis.h b/llvm/include/llvm/Analysis/DependenceAnalysis.h
index 6dec24fc9f104..80095e91fcc6b 100644
--- a/llvm/include/llvm/Analysis/DependenceAnalysis.h
+++ b/llvm/include/llvm/Analysis/DependenceAnalysis.h
@@ -754,7 +754,8 @@ class DependenceInfo {
   /// Given a linear access function, tries to recover subscripts
   /// for each dimension of the array element access.
   bool tryDelinearize(Instruction *Src, Instruction *Dst,
-                      SmallVectorImpl<Subscript> &Pair);
+                      SmallVectorImpl<Subscript> &Pair,
+                      SmallVectorImpl<const SCEVPredicate *> &Assume);
 
   /// Tries to delinearize \p Src and \p Dst access functions for a fixed size
   /// multi-dimensional array. Calls delinearizeFixedSizeArray() to delinearize
@@ -762,7 +763,8 @@ class DependenceInfo {
   bool tryDelinearizeFixedSize(Instruction *Src, Instruction *Dst,
                                const SCEV *SrcAccessFn, const SCEV *DstAccessFn,
                                SmallVectorImpl<const SCEV *> &SrcSubscripts,
-                               SmallVectorImpl<const SCEV *> &DstSubscripts);
+                               SmallVectorImpl<const SCEV *> &DstSubscripts,
+                               SmallVectorImpl<const SCEVPredicate *> &Assume);
 
   /// Tries to delinearize access function for a multi-dimensional array with
   /// symbolic runtime sizes.
@@ -771,7 +773,8 @@ class DependenceInfo {
   tryDelinearizeParametricSize(Instruction *Src, Instruction *Dst,
                                const SCEV *SrcAccessFn, const SCEV *DstAccessFn,
                                SmallVectorImpl<const SCEV *> &SrcSubscripts,
-                               SmallVectorImpl<const SCEV *> &DstSubscripts);
+                               SmallVectorImpl<const SCEV *> &DstSubscripts,
+                               SmallVectorImpl<const SCEVPredicate *> &Assume);
 
   /// checkSubscript - Helper function for checkSrcSubscript and
   /// checkDstSubscript to avoid duplicate code
diff --git a/llvm/lib/Analysis/Delinearization.cpp b/llvm/lib/Analysis/Delinearization.cpp
index 7bf83ccf9c172..68928c62ab569 100644
--- a/llvm/lib/Analysis/Delinearization.cpp
+++ b/llvm/lib/Analysis/Delinearization.cpp
@@ -753,24 +753,34 @@ static bool isKnownLessThan(ScalarEvolution *SE, const SCEV *S,
   return SE->isKnownNegative(LimitedBound);
 }
 
-bool llvm::validateDelinearizationResult(ScalarEvolution &SE,
-                                         ArrayRef<const SCEV *> Sizes,
-                                         ArrayRef<const SCEV *> Subscripts,
-                                         const Value *Ptr) {
+bool llvm::validateDelinearizationResult(
+    ScalarEvolution &SE, ArrayRef<const SCEV *> Sizes,
+    ArrayRef<const SCEV *> Subscripts, const Value *Ptr,
+    SmallVectorImpl<const SCEVPredicate *> *Assume) {
   // Sizes and Subscripts are as follows:
-  //
   //   Sizes:      [UNK][S_2]...[S_n]
   //   Subscripts: [I_1][I_2]...[I_n]
   //
   // where the size of the outermost dimension is unknown (UNK).
 
+  // Unify types of two SCEVs to the wider type.
+  auto UnifyTypes =
+      [&](const SCEV *&A,
+          const SCEV *&B) -> std::pair<const SCEV *, const SCEV *> {
+    Type *WiderType = SE.getWiderType(A->getType(), B->getType());
+    return {SE.getNoopOrSignExtend(A, WiderType),
+            SE.getNoopOrSignExtend(B, WiderType)};
+  };
+
   auto AddOverflow = [&](const SCEV *A, const SCEV *B) -> const SCEV * {
+    std::tie(A, B) = UnifyTypes(A, B);
     if (!SE.willNotOverflow(Instruction::Add, /*IsSigned=*/true, A, B))
       return nullptr;
     return SE.getAddExpr(A, B);
   };
 
   auto MulOverflow = [&](const SCEV *A, const SCEV *B) -> const SCEV * {
+    std::tie(A, B) = UnifyTypes(A, B);
     if (!SE.willNotOverflow(Instruction::Mul, /*IsSigned=*/true, A, B))
       return nullptr;
     return SE.getMulExpr(A, B);
@@ -780,10 +790,28 @@ bool llvm::validateDelinearizationResult(ScalarEvolution &SE,
   for (size_t I = 1; I < Sizes.size(); ++I) {
     const SCEV *Size = Sizes[I - 1];
     const SCEV *Subscript = Subscripts[I];
-    if (!isKnownNonNegative(&SE, Subscript, Ptr))
-      return false;
-    if (!isKnownLessThan(&SE, Subscript, Size))
-      return false;
+
+    // Check Subscript >= 0.
+    if (!isKnownNonNegative(&SE, Subscript, Ptr)) {
+      if (!Assume)
+        return false;
+      const SCEVPredicate *Pred = SE.getComparePredicate(
+          ICmpInst::ICMP_SGE, Subscript, SE.getZero(Subscript->getType()));
+      Assume->push_back(Pred);
+    }
+
+    // Check Subscript < Size.
+    if (!isKnownLessThan(&SE, Subscript, Size)) {
+      if (!Assume)
+        return false;
+      // Need to unify types before creating the predicate.
+      Type *WiderType = SE.getWiderType(Subscript->getType(), Size->getType());
+      const SCEV *SubscriptExt = SE.getNoopOrSignExtend(Subscript, WiderType);
+      const SCEV *SizeExt = SE.getNoopOrSignExtend(Size, WiderType);
+      const SCEVPredicate *Pred =
+          SE.getComparePredicate(ICmpInst::ICMP_SLT, SubscriptExt, SizeExt);
+      Assume->push_back(Pred);
+    }
   }
 
   // The offset computation is as follows:
diff --git a/llvm/lib/Analysis/DependenceAnalysis.cpp b/llvm/lib/Analysis/DependenceAnalysis.cpp
index 9b9c80a9b3266..858cbafdc3a0a 100644
--- a/llvm/lib/Analysis/DependenceAnalysis.cpp
+++ b/llvm/lib/Analysis/DependenceAnalysis.cpp
@@ -3176,8 +3176,9 @@ const SCEV *DependenceInfo::getUpperBound(BoundInfo *Bound) const {
 /// source and destination array references are recurrences on a nested loop,
 /// this function flattens the nested recurrences into separate recurrences
 /// for each loop level.
-bool DependenceInfo::tryDelinearize(Instruction *Src, Instruction *Dst,
-                                    SmallVectorImpl<Subscript> &Pair) {
+bool DependenceInfo::tryDelinearize(
+    Instruction *Src, Instruction *Dst, SmallVectorImpl<Subscript> &Pair,
+    SmallVectorImpl<const SCEVPredicate *> &Assume) {
   assert(isLoadOrStore(Src) && "instruction is not load or store");
   assert(isLoadOrStore(Dst) && "instruction is not load or store");
   Value *SrcPtr = getLoadStorePointerOperand(Src);
@@ -3197,9 +3198,9 @@ bool DependenceInfo::tryDelinearize(Instruction *Src, Instruction *Dst,
   SmallVector<const SCEV *, 4> SrcSubscripts, DstSubscripts;
 
   if (!tryDelinearizeFixedSize(Src, Dst, SrcAccessFn, DstAccessFn,
-                               SrcSubscripts, DstSubscripts) &&
+                               SrcSubscripts, DstSubscripts, Assume) &&
       !tryDelinearizeParametricSize(Src, Dst, SrcAccessFn, DstAccessFn,
-                                    SrcSubscripts, DstSubscripts))
+                                    SrcSubscripts, DstSubscripts, Assume))
     return false;
 
   assert(isLoopInvariant(SrcBase, SrcLoop) &&
@@ -3245,7 +3246,8 @@ bool DependenceInfo::tryDelinearize(Instruction *Src, Instruction *Dst,
 bool DependenceInfo::tryDelinearizeFixedSize(
     Instruction *Src, Instruction *Dst, const SCEV *SrcAccessFn,
     const SCEV *DstAccessFn, SmallVectorImpl<const SCEV *> &SrcSubscripts,
-    SmallVectorImpl<const SCEV *> &DstSubscripts) {
+    SmallVectorImpl<const SCEV *> &DstSubscripts,
+    SmallVectorImpl<const SCEVPredicate *> &Assume) {
   LLVM_DEBUG({
     const SCEVUnknown *SrcBase =
         dyn_cast<SCEVUnknown>(SE->getPointerBase(SrcAccessFn));
@@ -3285,10 +3287,12 @@ bool DependenceInfo::tryDelinearizeFixedSize(
   // dimensions. For example some C language usage/interpretation make it
   // impossible to verify this at compile-time. As such we can only delinearize
   // iff the subscripts are positive and are less than the range of the
-  // dimension.
+  // dimension. If compile-time checks fail, add runtime predicates.
   if (!DisableDelinearizationChecks) {
-    if (!validateDelinearizationResult(*SE, SrcSizes, SrcSubscripts, SrcPtr) ||
-        !validateDelinearizationResult(*SE, DstSizes, DstSubscripts, DstPtr)) {
+    if (!validateDelinearizationResult(*SE, SrcSizes, SrcSubscripts, SrcPtr,
+                                       &Assume) ||
+        !validateDelinearizationResult(*SE, DstSizes, DstSubscripts, DstPtr,
+                                       &Assume)) {
       SrcSubscripts.clear();
       DstSubscripts.clear();
       return false;
@@ -3305,7 +3309,8 @@ bool DependenceInfo::tryDelinearizeFixedSize(
 bool DependenceInfo::tryDelinearizeParametricSize(
     Instruction *Src, Instruction *Dst, const SCEV *SrcAccessFn,
     const SCEV *DstAccessFn, SmallVectorImpl<const SCEV *> &SrcSubscripts,
-    SmallVectorImpl<const SCEV *> &DstSubscripts) {
+    SmallVectorImpl<const SCEV *> &DstSubscripts,
+    SmallVectorImpl<const SCEVPredicate *> &Assume) {
 
   Value *SrcPtr = getLoadStorePointerOperand(Src);
   Value *DstPtr = getLoadStorePointerOperand(Dst);
@@ -3346,15 +3351,13 @@ bool DependenceInfo::tryDelinearizeParametricSize(
       SrcSubscripts.size() != DstSubscripts.size())
     return false;
 
-  // Statically check that the array bounds are in-range. The first subscript we
-  // don't have a size for and it cannot overflow into another subscript, so is
-  // always safe. The others need to be 0 <= subscript[i] < bound, for both src
-  // and dst.
-  // FIXME: It may be better to record these sizes and add them as constraints
-  // to the dependency checks.
+  // Check that the array bounds are in-range. If compile-time checks fail,
+  // add runtime predicates.
   if (!DisableDelinearizationChecks)
-    if (!validateDelinearizationResult(*SE, Sizes, SrcSubscripts, SrcPtr) ||
-        !validateDelinearizationResult(*SE, Sizes, DstSubscripts, DstPtr))
+    if (!validateDelinearizationResult(*SE, Sizes, SrcSubscripts, SrcPtr,
+                                       &Assume) ||
+        !validateDelinearizationResult(*SE, Sizes, DstSubscripts, DstPtr,
+                                       &Assume))
       return false;
 
   return true;
@@ -3507,7 +3510,7 @@ DependenceInfo::depends(Instruction *Src, Instruction *Dst,
                                           SCEVUnionPredicate(Assume, *SE));
 
   if (Delinearize) {
-    if (tryDelinearize(Src, Dst, Pair)) {
+    if (tryDelinearize(Src, Dst, Pair, Assume)) {
       LLVM_DEBUG(dbgs() << "    delinearized\n");
       Pairs = Pair.size();
     }
diff --git a/llvm/test/Analysis/DependenceAnalysis/Banerjee.ll b/llvm/test/Analysis/DependenceAnalysis/Banerjee.ll
index 6dde8844c6040..6e75887db06d4 100644
--- a/llvm/test/Analysis/DependenceAnalysis/Banerjee.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/Banerjee.ll
@@ -46,9 +46,14 @@ define void @banerjee0(ptr %A, ptr %B, i64 %m, i64 %n) nounwind uwtable ssp {
 ;
 ; DELIN-LABEL: 'banerjee0'
 ; DELIN-NEXT:  Src: store i64 0, ptr %arrayidx, align 8 --> Dst: store i64 0, ptr %arrayidx, align 8
-; DELIN-NEXT:    da analyze - none!
+; DELIN-NEXT:    da analyze - consistent output [0 0]!
+; DELIN-NEXT:    Runtime Assumptions:
+; DELIN-NEXT:    Compare predicate: {1,+,1}<nuw><nsw><%for.body3> slt) 10
+; DELIN-NEXT:    Compare predicate: {1,+,1}<nuw><nsw><%for.body3> slt) 10
 ; DELIN-NEXT:  Src: store i64 0, ptr %arrayidx, align 8 --> Dst: %0 = load i64, ptr %arrayidx6, align 8
-; DELIN-NEXT:    da analyze - flow [<= <>]!
+; DELIN-NEXT:    da analyze - consistent flow [0 1]!
+; DELIN-NEXT:    Runtime Assumptions:
+; DELIN-NEXT:    Compare predicate: {1,+,1}<nuw><nsw><%for.body3> slt) 10
 ; DELIN-NEXT:  Src: store i64 0, ptr %arrayidx, align 8 --> Dst: store i64 %0, ptr %B.addr.11, align 8
 ; DELIN-NEXT:    da analyze - confused!
 ; DELIN-NEXT:  Src: %0 = load i64, ptr %arrayidx6, align 8 --> Dst: %0 = load i64, ptr %arrayidx6, align 8
@@ -132,12 +137,18 @@ define void @banerjee1(ptr %A, ptr %B, i64 %m, i64 %n) nounwind uwtable ssp {
 ; DELIN-LABEL: 'banerjee1'
 ; DELIN-NEXT:  Src: store i64 0, ptr %arrayidx, align 8 --> Dst: store i64 0, ptr %arrayidx, align 8
 ; DELIN-NEXT:    da analyze - output [* *]!
+; DELIN-NEXT:    Runtime Assumptions:
+; DELIN-NEXT:    Compare predicate: {1,+,1}<nuw><nsw><%for.body3> slt) 10
 ; DELIN-NEXT:  Src: store i64 0, ptr %arrayidx, align 8 --> Dst: %2 = load i64, ptr %arrayidx6, align 8
 ; DELIN-NEXT:    da analyze - flow [* <>]!
+; DELIN-NEXT:    Runtime Assumptions:
+; DELIN-NEXT:    Compare predicate: {1,+,1}<nuw><nsw><%for.body3> slt) 10
 ; DELIN-NEXT:  Src: store i64 0, ptr %arrayidx, align 8 --> Dst: store i64 %2, ptr %B.addr.12, align 8
 ; DELIN-NEXT:    da analyze - confused!
 ; DELIN-NEXT:  Src: %2 = load i64, ptr %arrayidx6, align 8 --> Dst: %2 = load i64, ptr %arrayidx6, align 8
 ; DELIN-NEXT:    da analyze - input [* *]!
+; DELIN-NEXT:    Runtime Assumptions:
+; DELIN-NEXT:    Compare predicate: {0,+,1}<nuw><nsw><%for.body3> slt) 10
 ; DELIN-NEXT:  Src: %2 = load i64, ptr %arrayidx6, align 8 --> Dst: store i64 %2, ptr %B.addr.12, align 8
 ; DELIN-NEXT:    da analyze - confused!
 ; DELIN-NEXT:  Src: store i64 %2, ptr %B.addr.12, align 8 --> Dst: store i64 %2, ptr %B.addr.12, align 8
@@ -320,11 +331,16 @@ define void @banerjee3(ptr %A, ptr %B, i64 %m, i64 %n) nounwind uwtable ssp {
 ; DELIN-NEXT:  Src: store i64 0, ptr %arrayidx, align 8 --> Dst: store i64 0, ptr %arrayidx, align 8
 ; DELIN-NEXT:    da analyze - none!
 ; DELIN-NEXT:  Src: store i64 0, ptr %arrayidx, align 8 --> Dst: %0 = load i64, ptr %arrayidx7, align 8
-; DELIN-NEXT:    da analyze - flow [> >]!
+; DELIN-NEXT:    da analyze - consistent flow [-9 -9]!
+; DELIN-NEXT:    Runtime Assumptions:
+; DELIN-NEXT:    Compare predicate: {9,+,1}<nuw><nsw><%for.body3> slt) 10
 ; DELIN-NEXT:  Src: store i64 0, ptr %arrayidx, align 8 --> Dst: store i64 %0, ptr %B.addr.11, align 8
 ; DELIN-NEXT:    da analyze - confused!
 ; DELIN-NEXT:  Src: %0 = load i64, ptr %arrayidx7, align 8 --> Dst: %0 = load i64, ptr %arrayidx7, align 8
-; DELIN-NEXT:    da analyze - none!
+; DELIN-NEXT:    da analyze - consistent input [0 0]!
+; DELIN-NEXT:    Runtime Assumptions:
+; DELIN-NEXT:    Compare predicate: {9,+,1}<nuw><nsw><%for.body3> slt) 10
+; DELIN-NEXT:    Compare predicate: {9,+,1}<nuw><nsw><%for.body3> slt) 10
 ; DELIN-NEXT:  Src: %0 = load i64, ptr %arrayidx7, align 8 --> Dst: store i64 %0, ptr %B.addr.11, align 8
 ; DELIN-NEXT:    da analyze - confused!
 ; DELIN-NEXT:  Src: store i64 %0, ptr %B.addr.11, align 8 --> Dst: store i64 %0, ptr %B.addr.11, align 8
@@ -490,11 +506,16 @@ define void @banerjee5(ptr %A, ptr %B, i64 %m, i64 %n) nounwind uwtable ssp {
 ; DELIN-NEXT:  Src: store i64 0, ptr %arrayidx, align 8 --> Dst: store i64 0, ptr %arrayidx, align 8
 ; DELIN-NEXT:    da analyze - none!
 ; DELIN-NEXT:  Src: store i64 0, ptr %arrayidx, align 8 --> Dst: %0 = load i64, ptr %arrayidx6, align 8
-; DELIN-NEXT:    da analyze - flow [< <]!
+; DELIN-NEXT:    da analyze - consistent flow [9 9]!
+; DELIN-NEXT:    Runtime Assumptions:
+; DELIN-NEXT:    Compare predicate: {-9,+,1}<nsw><%for.body3> sge) 0
 ; DELIN-NEXT:  Src: store i64 0, ptr %arrayidx, align 8 --> Dst: store i64 %0, ptr %B.addr.11, align 8
 ; DELIN-NEXT:    da analyze - confused!
 ; DELIN-NEXT:  Src: %0 = load i64, ptr %arrayidx6, align 8 --> Dst: %0 = load i64, ptr %arrayidx6, align 8
-; DELIN-NEXT:    da analyze - none!
+; DELIN-NEXT:    da analyze - consistent input [0 0]!
+; DELIN-NEXT:    Runtime Assumptions:
+; DELIN-NEXT:    Compare predicate: {-9,+,1}<nsw><%for.body3> sge) 0
+; DELIN-NEXT:    Compare predicate: {-9,+,1}<nsw><%for.body3> sge) 0
 ; DELIN-NEXT:  Src: %0 = load i64, ptr %arrayidx6, align 8 --> Dst: store i64 %0, ptr %B.addr.11, align 8
 ; DELIN-NEXT:    da analyze - confused!
 ; DELIN-NEXT:  Src: store i64 %0, ptr %B.addr.11, align 8 --> Dst: store i64 %0, ptr %B.addr.11, align 8
@@ -575,11 +596,16 @@ define void @banerjee6(ptr %A, ptr %B, i64 %m, i64 %n) nounwind uwtable ssp {
 ; DELIN-NEXT:  Src: store i64 0, ptr %arrayidx, align 8 --> Dst: store i64 0, ptr %arrayidx, align 8
 ; DELIN-NEXT:    da analyze - none!
 ; DELIN-NEXT:  Src: store i64 0, ptr %arrayidx, align 8 --> Dst: %0 = load i64, ptr %arrayidx7, align 8
-; DELIN-NEXT:    da analyze - flow [=> <>]!
+; DELIN-NEXT:    da analyze - consistent flow [0 -9]!
+; DELIN-NEXT:    Runtime Assumptions:
+; DELIN-NEXT:    Compare predicate: {9,+,1}<nuw><nsw><%for.body3> slt) 10
 ; DELIN-NEXT:  Src: store i64 0, ptr %arrayidx, align 8 --> Dst: store i64 %0, ptr %B.addr.11, align 8
 ; DELIN-NEXT:    da analyze - confused!
 ; DELIN-NEXT:  Src: %0 = load i64, ptr %arrayidx7, align 8 --> Dst: %0 = load i64, ptr %arrayidx7, align 8
-; DELIN-NEXT:    da analyze - none!
+; DELIN-NEXT:    da analyze - consistent input [0 0]!
+; DELIN-NEXT:    Runtime Assumptions:
+; DELIN-NEXT:    Compare predicate: {9,+,1}<nuw><nsw><%for.body3> slt) 10
+; DELIN-NEXT:    Compare predicate: {9,+,1}<nuw><nsw><%for.body3> slt) 10
 ; DELIN-NEXT:  Src: %0 = load i64, ptr %arrayidx7, align 8 --> Dst: store i64 %0, ptr %B.addr.11, align 8
 ; DELIN-NEXT:    da analyze - confused!
 ; DELIN-NEXT:  Src: store i64 %0, ptr %B.addr.11, align 8 --> Dst: store i64 %0, ptr %B.addr.11, align 8
@@ -745,11 +771,16 @@ define void @banerjee8(ptr %A, ptr %B, i64 %m, i64 %n) nounwind uwtable ssp {
 ; DELIN-NEXT:  Src: store i64 0, ptr %arrayidx, align 8 --> Dst: store i64 0, ptr %arrayidx, align 8
 ; DELIN-NEXT:    da analyze - none!
 ; DELIN-NEXT:  Src: store i64 0, ptr %arrayidx, align 8 --> Dst: %0 = load i64, ptr %arrayidx7, align 8
-; DELIN-NEXT:    da analyze - flow [> <>]!
+; DELIN-NEXT:    da analyze - consistent flow [-1 -1]!
+; DELIN-NEXT:    Runtime Assumptions:
+; DELIN-NEXT:    Compare predicate: {1,+,1}<nuw><nsw><%for.body3> slt) 10
 ; DELIN-NEXT:  Src: store i64 0, ptr %arrayidx, align 8 --> Dst: store i64 %0, ptr %B.addr.11, align 8
 ; DELIN-NEXT:    da analyze - confused!
 ; DELIN-NEXT:  Src: %0 = load i64, ptr %arrayidx7, align 8 --> Dst: %0 = load i64, ptr %arrayidx7, align 8
-; DELIN-NEXT:    da analyze - none!
+; DELIN-NEXT:    da analyze - consistent input [0 0]!
+; DELIN-NEXT:    Runtime Assumptions:
+; DELIN-NEXT:    Compare predicate: {1,+,1}<nuw><nsw><%for.body3> slt) 10
+; DELIN-NEXT:    Compare predicate: {1,+,1}<nuw><nsw><%for.body3> slt) 10
 ; DELIN-NEXT:  Src: %0 = load i64, ptr %arrayidx7, align 8 --> Dst: store i64 %0, ptr %B.addr.11, align 8
 ; DELIN-NEXT:    da analyze - confused!
 ; DELIN-NEXT:  Src: store i64 %0, ptr %B.addr.11, align 8 --> Dst: store i64 %0, ptr %B.addr.11, align 8
@@ -828,9 +859,14 @@ define void @banerjee9(ptr %A, ptr %B, i64 %m, i64 %n) nounwind uwtable ssp {
 ;
 ; DELIN-LABEL: 'banerjee9'
 ; DELIN-NEXT:  Src: store i64 0, ptr %arrayidx, align 8 --> Dst: store i64 0, ptr %arrayidx, align 8
-; DELIN-NEXT:    da analyze - output [* *]!
+; DELIN-NEXT:    da analyze - consistent output [0 0]!
+; DELIN-NEXT:    Runtime Assumptions:
+; DELI...
[truncated]

``````````

</details>


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


More information about the llvm-commits mailing list