[llvm] [DA] Fix zero coeff bug in Strong SIV test with runtime assumptions (#149991) (PR #155037)

Sebastian Pop via llvm-commits llvm-commits at lists.llvm.org
Fri Nov 28 05:43:34 PST 2025


https://github.com/sebpop updated https://github.com/llvm/llvm-project/pull/155037

>From 802c01072d9faa995fe41c4e21b42ae8e8b3a927 Mon Sep 17 00:00:00 2001
From: Sebastian Pop <spop at nvidia.com>
Date: Tue, 25 Nov 2025 14:11:26 -0500
Subject: [PATCH 1/4] [DA] Fix zero coefficient bug in Strong SIV test using
 runtime assumptions

The Strong SIV test was incorrectly concluding "no dependence" when the
coefficient is symbolic and the delta (difference between source and
destination) is zero.

When delta=0, the Strong SIV test divides delta/coeff to get the distance.
The bug occurs when coeff is an unknown symbolic value: if coeff=0 at runtime,
then 0/0 is undefined and all iterations access the same memory location,
creating a true dependence that was being missed.
---
 .../llvm/Analysis/DependenceAnalysis.h        |  4 +-
 llvm/lib/Analysis/DependenceAnalysis.cpp      | 57 ++++++++++++++++---
 .../Analysis/DependenceAnalysis/DADelin.ll    | 16 ++++--
 .../DependenceAnalysis/zero-coefficient.ll    | 34 +++++++++++
 4 files changed, 98 insertions(+), 13 deletions(-)
 create mode 100644 llvm/test/Analysis/DependenceAnalysis/zero-coefficient.ll

diff --git a/llvm/include/llvm/Analysis/DependenceAnalysis.h b/llvm/include/llvm/Analysis/DependenceAnalysis.h
index 8286d8e8e45cc..e894c30571fe9 100644
--- a/llvm/include/llvm/Analysis/DependenceAnalysis.h
+++ b/llvm/include/llvm/Analysis/DependenceAnalysis.h
@@ -554,7 +554,7 @@ class DependenceInfo {
   /// If the dependence isn't proven to exist,
   /// marks the Result as inconsistent.
   bool testSIV(const SCEV *Src, const SCEV *Dst, unsigned &Level,
-               FullDependence &Result) const;
+               FullDependence &Result, bool UnderRuntimeAssumptions);
 
   /// testRDIV - Tests the RDIV subscript pair (Src and Dst) for dependence.
   /// Things of the form [c1 + a1*i] and [c2 + a2*j]
@@ -584,7 +584,7 @@ class DependenceInfo {
   bool strongSIVtest(const SCEV *Coeff, const SCEV *SrcConst,
                      const SCEV *DstConst, const Loop *CurrentSrcLoop,
                      const Loop *CurrentDstLoop, unsigned Level,
-                     FullDependence &Result) const;
+                     FullDependence &Result, bool UnderRuntimeAssumptions);
 
   /// weakCrossingSIVtest - Tests the weak-crossing SIV subscript pair
   /// (Src and Dst) for dependence.
diff --git a/llvm/lib/Analysis/DependenceAnalysis.cpp b/llvm/lib/Analysis/DependenceAnalysis.cpp
index 253f4d1441098..4ebfb8c01a226 100644
--- a/llvm/lib/Analysis/DependenceAnalysis.cpp
+++ b/llvm/lib/Analysis/DependenceAnalysis.cpp
@@ -1296,7 +1296,8 @@ bool DependenceInfo::testZIV(const SCEV *Src, const SCEV *Dst,
 bool DependenceInfo::strongSIVtest(const SCEV *Coeff, const SCEV *SrcConst,
                                    const SCEV *DstConst, const Loop *CurSrcLoop,
                                    const Loop *CurDstLoop, unsigned Level,
-                                   FullDependence &Result) const {
+                                   FullDependence &Result,
+                                   bool UnderRuntimeAssumptions) {
   if (!isDependenceTestEnabled(DependenceTestType::StrongSIV))
     return false;
 
@@ -1368,7 +1369,38 @@ bool DependenceInfo::strongSIVtest(const SCEV *Coeff, const SCEV *SrcConst,
       Result.DV[Level].Direction &= Dependence::DVEntry::EQ;
     ++StrongSIVsuccesses;
   } else if (Delta->isZero()) {
-    // since 0/X == 0
+    // Check if coefficient could be zero. If so, 0/0 is undefined and we
+    // cannot conclude that only same-iteration dependencies exist.
+    // When coeff=0, all iterations access the same location.
+    if (isa<SCEVUnknown>(Coeff)) {
+      // Use both isKnownNonZero and range analysis to prove coefficient != 0.
+      bool CoeffKnownNonZero = SE->isKnownNonZero(Coeff) ||
+                               isKnownPredicate(CmpInst::ICMP_NE, Coeff,
+                                                SE->getZero(Coeff->getType()));
+      if (!CoeffKnownNonZero) {
+        // Cannot prove at compile time, would need runtime assumption.
+        if (UnderRuntimeAssumptions) {
+          const SCEVPredicate *Pred = SE->getComparePredicate(
+              ICmpInst::ICMP_NE, Coeff, SE->getZero(Coeff->getType()));
+          SmallVector<const SCEVPredicate *, 4> NewPreds(
+              Result.Assumptions.getPredicates());
+          NewPreds.push_back(Pred);
+          Result.Assumptions = SCEVUnionPredicate(NewPreds, *SE);
+          LLVM_DEBUG(dbgs() << "\t    Added runtime assumption: " << *Coeff
+                            << " != 0\n");
+        } else {
+          // Cannot add runtime assumptions, this test cannot handle this case.
+          // Let more complex tests try.
+          LLVM_DEBUG(dbgs() << "\t    Would need runtime assumption " << *Coeff
+                            << " != 0, but not allowed. Failing this test.\n");
+          return false;
+        }
+      } else {
+        LLVM_DEBUG(
+            dbgs() << "\t    Coefficient proven non-zero by SCEV analysis\n");
+      }
+    }
+    // Since 0/X == 0 (where X is known non-zero or assumed non-zero).
     Result.DV[Level].Distance = Delta;
     Result.DV[Level].Direction &= Dependence::DVEntry::EQ;
     ++StrongSIVsuccesses;
@@ -2331,7 +2363,8 @@ bool DependenceInfo::symbolicRDIVtest(const SCEV *A1, const SCEV *A2,
 //
 // Return true if dependence disproved.
 bool DependenceInfo::testSIV(const SCEV *Src, const SCEV *Dst, unsigned &Level,
-                             FullDependence &Result) const {
+                             FullDependence &Result,
+                             bool UnderRuntimeAssumptions) {
   LLVM_DEBUG(dbgs() << "    src = " << *Src << "\n");
   LLVM_DEBUG(dbgs() << "    dst = " << *Dst << "\n");
   const SCEVAddRecExpr *SrcAddRec = dyn_cast<SCEVAddRecExpr>(Src);
@@ -2349,8 +2382,9 @@ bool DependenceInfo::testSIV(const SCEV *Src, const SCEV *Dst, unsigned &Level,
     Level = mapSrcLoop(CurSrcLoop);
     bool disproven;
     if (SrcCoeff == DstCoeff)
-      disproven = strongSIVtest(SrcCoeff, SrcConst, DstConst, CurSrcLoop,
-                                CurDstLoop, Level, Result);
+      disproven =
+          strongSIVtest(SrcCoeff, SrcConst, DstConst, CurSrcLoop, CurDstLoop,
+                        Level, Result, UnderRuntimeAssumptions);
     else if (SrcCoeff == SE->getNegativeSCEV(DstCoeff))
       disproven = weakCrossingSIVtest(SrcCoeff, SrcConst, DstConst, CurSrcLoop,
                                       CurDstLoop, Level, Result);
@@ -3540,6 +3574,10 @@ DependenceInfo::depends(Instruction *Src, Instruction *Dst,
 
   FullDependence Result(Src, Dst, SCEVUnionPredicate(Assume, *SE),
                         PossiblyLoopIndependent, CommonLevels);
+  // Track assumptions before running dependence tests. If new assumptions are
+  // added during tests, we must return the result even if AllEqual to preserve
+  // those assumptions for the caller.
+  size_t AssumptionsBeforeTests = Result.Assumptions.getPredicates().size();
   ++TotalArrayPairs;
 
   for (unsigned P = 0; P < Pairs; ++P) {
@@ -3583,7 +3621,8 @@ DependenceInfo::depends(Instruction *Src, Instruction *Dst,
     case Subscript::SIV: {
       LLVM_DEBUG(dbgs() << ", SIV\n");
       unsigned Level;
-      if (testSIV(Pair[SI].Src, Pair[SI].Dst, Level, Result))
+      if (testSIV(Pair[SI].Src, Pair[SI].Dst, Level, Result,
+                  UnderRuntimeAssumptions))
         return nullptr;
       break;
     }
@@ -3664,6 +3703,8 @@ DependenceInfo::depends(Instruction *Src, Instruction *Dst,
   } else {
     // On the other hand, if all directions are equal and there's no
     // loop-independent dependence possible, then no dependence exists.
+    // However, if we added runtime assumptions during the dependence tests,
+    // we must return the result to preserve those assumptions for the caller.
     bool AllEqual = true;
     for (unsigned II = 1; II <= CommonLevels; ++II) {
       if (Result.getDirection(II) != Dependence::DVEntry::EQ) {
@@ -3671,7 +3712,9 @@ DependenceInfo::depends(Instruction *Src, Instruction *Dst,
         break;
       }
     }
-    if (AllEqual)
+    bool AddedAssumptionsDuringTests =
+        Result.Assumptions.getPredicates().size() > AssumptionsBeforeTests;
+    if (AllEqual && !AddedAssumptionsDuringTests)
       return nullptr;
   }
 
diff --git a/llvm/test/Analysis/DependenceAnalysis/DADelin.ll b/llvm/test/Analysis/DependenceAnalysis/DADelin.ll
index 8f94a455d3724..60ce6a96abd5f 100644
--- a/llvm/test/Analysis/DependenceAnalysis/DADelin.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/DADelin.ll
@@ -646,11 +646,15 @@ exit:
 define void @coeff_may_negative(ptr %a, i32 %k) {
 ; CHECK-LABEL: 'coeff_may_negative'
 ; CHECK-NEXT:  Src: store i8 42, ptr %idx.0, align 1 --> Dst: store i8 42, ptr %idx.0, align 1
-; CHECK-NEXT:    da analyze - none!
+; CHECK-NEXT:    da analyze - consistent output [0]!
+; CHECK-NEXT:    Runtime Assumptions:
+; CHECK-NEXT:    Compare predicate: %k ne) 0
 ; CHECK-NEXT:  Src: store i8 42, ptr %idx.0, align 1 --> Dst: store i8 42, ptr %idx.1, align 1
 ; CHECK-NEXT:    da analyze - output [*|<]!
 ; CHECK-NEXT:  Src: store i8 42, ptr %idx.1, align 1 --> Dst: store i8 42, ptr %idx.1, align 1
-; CHECK-NEXT:    da analyze - none!
+; CHECK-NEXT:    da analyze - consistent output [0]!
+; CHECK-NEXT:    Runtime Assumptions:
+; CHECK-NEXT:    Compare predicate: %k ne) 0
 ;
 entry:
   br label %loop
@@ -685,11 +689,15 @@ exit:
 define void @coeff_positive(ptr %a, i32 %k) {
 ; CHECK-LABEL: 'coeff_positive'
 ; CHECK-NEXT:  Src: store i8 42, ptr %idx.0, align 1 --> Dst: store i8 42, ptr %idx.0, align 1
-; CHECK-NEXT:    da analyze - none!
+; CHECK-NEXT:    da analyze - consistent output [0]!
+; CHECK-NEXT:    Runtime Assumptions:
+; CHECK-NEXT:    Compare predicate: %k ne) 0
 ; CHECK-NEXT:  Src: store i8 42, ptr %idx.0, align 1 --> Dst: store i8 42, ptr %idx.1, align 1
 ; CHECK-NEXT:    da analyze - output [*|<]!
 ; CHECK-NEXT:  Src: store i8 42, ptr %idx.1, align 1 --> Dst: store i8 42, ptr %idx.1, align 1
-; CHECK-NEXT:    da analyze - none!
+; CHECK-NEXT:    da analyze - consistent output [0]!
+; CHECK-NEXT:    Runtime Assumptions:
+; CHECK-NEXT:    Compare predicate: %k ne) 0
 ;
 entry:
   br label %loop
diff --git a/llvm/test/Analysis/DependenceAnalysis/zero-coefficient.ll b/llvm/test/Analysis/DependenceAnalysis/zero-coefficient.ll
new file mode 100644
index 0000000000000..7181e0bfb9a3d
--- /dev/null
+++ b/llvm/test/Analysis/DependenceAnalysis/zero-coefficient.ll
@@ -0,0 +1,34 @@
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 5
+; RUN: opt < %s -disable-output "-passes=print<da>" -aa-pipeline=basic-aa 2>&1 \
+; RUN: | FileCheck %s
+
+; Test case for bug fix where Strong SIV test incorrectly concludes "no dependence"
+; when the coefficient is symbolic (unknown at compile time) and delta is zero.
+;
+; In this case, the array access is A[k*i] with both src and dst at the same
+; location in the same iteration. If k=0, then all iterations access the same
+; element, meaning there IS a dependence between different iterations.
+; The Strong SIV test should add a runtime assumption that k != 0.
+
+define void @test_zero_coefficient(ptr noalias %A, i64 %k) {
+; CHECK-LABEL: 'test_zero_coefficient'
+; CHECK-NEXT:  Src: store i8 42, ptr %idx, align 1 --> Dst: store i8 42, ptr %idx, align 1
+; CHECK-NEXT:    da analyze - consistent output [0]!
+; CHECK-NEXT:    Runtime Assumptions:
+; CHECK-NEXT:    Compare predicate: %k ne) 0
+;
+entry:
+  br label %loop
+
+loop:
+  %i = phi i64 [ 0, %entry ], [ %i.next, %loop ]
+  %off = mul nsw i64 %i, %k
+  %idx = getelementptr inbounds i8, ptr %A, i64 %off
+  store i8 42, ptr %idx, align 1
+  %i.next = add nsw i64 %i, 1
+  %cmp = icmp slt i64 %i.next, 100
+  br i1 %cmp, label %loop, label %exit
+
+exit:
+  ret void
+}

>From 6fadfdc8d271777a1b8813673257609338bb8080 Mon Sep 17 00:00:00 2001
From: Sebastian Pop <spop at nvidia.com>
Date: Fri, 28 Nov 2025 05:35:30 -0500
Subject: [PATCH 2/4] [SCEV] Add SCEVUnionPredicate::getUnionWith method

---
 llvm/include/llvm/Analysis/ScalarEvolution.h | 9 +++++++++
 llvm/lib/Analysis/DependenceAnalysis.cpp     | 5 +----
 2 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/llvm/include/llvm/Analysis/ScalarEvolution.h b/llvm/include/llvm/Analysis/ScalarEvolution.h
index 04ea769bd06d1..f594c26cc5a77 100644
--- a/llvm/include/llvm/Analysis/ScalarEvolution.h
+++ b/llvm/include/llvm/Analysis/ScalarEvolution.h
@@ -427,6 +427,15 @@ class LLVM_ABI SCEVUnionPredicate final : public SCEVPredicate {
 
   ArrayRef<const SCEVPredicate *> getPredicates() const { return Preds; }
 
+  /// Returns a new SCEVUnionPredicate that is the union of this predicate
+  /// and the given predicate \p N.
+  SCEVUnionPredicate getUnionWith(const SCEVPredicate *N,
+                                  ScalarEvolution &SE) const {
+    SCEVUnionPredicate Result(Preds, SE);
+    Result.add(N, SE);
+    return Result;
+  }
+
   /// Implementation of the SCEVPredicate interface
   bool isAlwaysTrue() const override;
   bool implies(const SCEVPredicate *N, ScalarEvolution &SE) const override;
diff --git a/llvm/lib/Analysis/DependenceAnalysis.cpp b/llvm/lib/Analysis/DependenceAnalysis.cpp
index 4ebfb8c01a226..1c684989a3ec6 100644
--- a/llvm/lib/Analysis/DependenceAnalysis.cpp
+++ b/llvm/lib/Analysis/DependenceAnalysis.cpp
@@ -1382,10 +1382,7 @@ bool DependenceInfo::strongSIVtest(const SCEV *Coeff, const SCEV *SrcConst,
         if (UnderRuntimeAssumptions) {
           const SCEVPredicate *Pred = SE->getComparePredicate(
               ICmpInst::ICMP_NE, Coeff, SE->getZero(Coeff->getType()));
-          SmallVector<const SCEVPredicate *, 4> NewPreds(
-              Result.Assumptions.getPredicates());
-          NewPreds.push_back(Pred);
-          Result.Assumptions = SCEVUnionPredicate(NewPreds, *SE);
+          Result.Assumptions = Result.Assumptions.getUnionWith(Pred, *SE);
           LLVM_DEBUG(dbgs() << "\t    Added runtime assumption: " << *Coeff
                             << " != 0\n");
         } else {

>From 266c70611969c29d1a4616c8dd9569fa226d5495 Mon Sep 17 00:00:00 2001
From: Sebastian Pop <spop at nvidia.com>
Date: Fri, 28 Nov 2025 05:43:59 -0500
Subject: [PATCH 3/4] small other fixes

---
 llvm/lib/Analysis/DependenceAnalysis.cpp                  | 5 ++---
 llvm/test/Analysis/DependenceAnalysis/zero-coefficient.ll | 2 +-
 2 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Analysis/DependenceAnalysis.cpp b/llvm/lib/Analysis/DependenceAnalysis.cpp
index 1c684989a3ec6..ab8da08b01c85 100644
--- a/llvm/lib/Analysis/DependenceAnalysis.cpp
+++ b/llvm/lib/Analysis/DependenceAnalysis.cpp
@@ -3510,11 +3510,10 @@ DependenceInfo::depends(Instruction *Src, Instruction *Dst,
                                         SCEVUnionPredicate(Assume, *SE));
   }
 
-  if (!Assume.empty() && !UnderRuntimeAssumptions) {
-    // Runtime assumptions needed but not allowed.
+  // Runtime assumptions needed but not allowed.
+  if (!Assume.empty() && !UnderRuntimeAssumptions)
     return std::make_unique<Dependence>(Src, Dst,
                                         SCEVUnionPredicate(Assume, *SE));
-  }
 
   unsigned Pairs = 1;
   SmallVector<Subscript, 2> Pair(Pairs);
diff --git a/llvm/test/Analysis/DependenceAnalysis/zero-coefficient.ll b/llvm/test/Analysis/DependenceAnalysis/zero-coefficient.ll
index 7181e0bfb9a3d..55f0ecc123e3a 100644
--- a/llvm/test/Analysis/DependenceAnalysis/zero-coefficient.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/zero-coefficient.ll
@@ -2,7 +2,7 @@
 ; RUN: opt < %s -disable-output "-passes=print<da>" -aa-pipeline=basic-aa 2>&1 \
 ; RUN: | FileCheck %s
 
-; Test case for bug fix where Strong SIV test incorrectly concludes "no dependence"
+; Test case for bug #149991 where Strong SIV test incorrectly concludes "no dependence"
 ; when the coefficient is symbolic (unknown at compile time) and delta is zero.
 ;
 ; In this case, the array access is A[k*i] with both src and dst at the same

>From a1059b6f63b8b09b72ae0dcb07b23a850b121bc8 Mon Sep 17 00:00:00 2001
From: Sebastian Pop <spop at nvidia.com>
Date: Fri, 28 Nov 2025 08:31:47 -0500
Subject: [PATCH 4/4] address comments from Ryotaro Kasuga

---
 llvm/lib/Analysis/DependenceAnalysis.cpp      | 38 ++++++++-----------
 .../DependenceAnalysis/MIVCheckConst.ll       |  1 +
 .../Analysis/DependenceAnalysis/StrongSIV.ll  | 10 ++++-
 .../DependenceAnalysis/SymbolicSIV.ll         | 16 ++++++--
 .../DependenceAnalysis/WeakCrossingSIV.ll     |  8 +++-
 .../DependenceAnalysis/WeakZeroDstSIV.ll      |  4 +-
 .../DependenceAnalysis/WeakZeroSrcSIV.ll      |  4 +-
 .../becount-couldnotcompute.ll                |  4 +-
 .../compute-absolute-value.ll                 |  8 +++-
 .../DependenceAnalysis/gcd-miv-overflow.ll    |  4 +-
 .../DependenceAnalysis/monotonicity-cast.ll   |  4 +-
 11 files changed, 64 insertions(+), 37 deletions(-)

diff --git a/llvm/lib/Analysis/DependenceAnalysis.cpp b/llvm/lib/Analysis/DependenceAnalysis.cpp
index ab8da08b01c85..08dc6beeb1406 100644
--- a/llvm/lib/Analysis/DependenceAnalysis.cpp
+++ b/llvm/lib/Analysis/DependenceAnalysis.cpp
@@ -1372,29 +1372,23 @@ bool DependenceInfo::strongSIVtest(const SCEV *Coeff, const SCEV *SrcConst,
     // Check if coefficient could be zero. If so, 0/0 is undefined and we
     // cannot conclude that only same-iteration dependencies exist.
     // When coeff=0, all iterations access the same location.
-    if (isa<SCEVUnknown>(Coeff)) {
-      // Use both isKnownNonZero and range analysis to prove coefficient != 0.
-      bool CoeffKnownNonZero = SE->isKnownNonZero(Coeff) ||
-                               isKnownPredicate(CmpInst::ICMP_NE, Coeff,
-                                                SE->getZero(Coeff->getType()));
-      if (!CoeffKnownNonZero) {
-        // Cannot prove at compile time, would need runtime assumption.
-        if (UnderRuntimeAssumptions) {
-          const SCEVPredicate *Pred = SE->getComparePredicate(
-              ICmpInst::ICMP_NE, Coeff, SE->getZero(Coeff->getType()));
-          Result.Assumptions = Result.Assumptions.getUnionWith(Pred, *SE);
-          LLVM_DEBUG(dbgs() << "\t    Added runtime assumption: " << *Coeff
-                            << " != 0\n");
-        } else {
-          // Cannot add runtime assumptions, this test cannot handle this case.
-          // Let more complex tests try.
-          LLVM_DEBUG(dbgs() << "\t    Would need runtime assumption " << *Coeff
-                            << " != 0, but not allowed. Failing this test.\n");
-          return false;
-        }
+    if (isa<SCEVConstant>(Coeff) || SE->isKnownNonZero(Coeff)) {
+      LLVM_DEBUG(
+          dbgs() << "\t    Coefficient proven non-zero by SCEV analysis\n");
+    } else {
+      // Cannot prove at compile time, would need runtime assumption.
+      if (UnderRuntimeAssumptions) {
+        const SCEVPredicate *Pred = SE->getComparePredicate(
+            ICmpInst::ICMP_NE, Coeff, SE->getZero(Coeff->getType()));
+        Result.Assumptions = Result.Assumptions.getUnionWith(Pred, *SE);
+        LLVM_DEBUG(dbgs() << "\t    Added runtime assumption: " << *Coeff
+                          << " != 0\n");
       } else {
-        LLVM_DEBUG(
-            dbgs() << "\t    Coefficient proven non-zero by SCEV analysis\n");
+        // Cannot add runtime assumptions, this test cannot handle this case.
+        // Let more complex tests try.
+        LLVM_DEBUG(dbgs() << "\t    Would need runtime assumption " << *Coeff
+                          << " != 0, but not allowed. Failing this test.\n");
+        return false;
       }
     }
     // Since 0/X == 0 (where X is known non-zero or assumed non-zero).
diff --git a/llvm/test/Analysis/DependenceAnalysis/MIVCheckConst.ll b/llvm/test/Analysis/DependenceAnalysis/MIVCheckConst.ll
index bcf73683e4dab..d91a916d785c2 100644
--- a/llvm/test/Analysis/DependenceAnalysis/MIVCheckConst.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/MIVCheckConst.ll
@@ -43,6 +43,7 @@ define void @test(ptr %A, ptr %B, i1 %arg, i32 %n, i32 %m) align 2 {
 ; CHECK-NEXT:    Runtime Assumptions:
 ; CHECK-NEXT:    Equal predicate: (zext i7 (4 * (trunc i32 %v1 to i7) * (1 + (trunc i32 %n to i7))) to i32) == 0
 ; CHECK-NEXT:    Equal predicate: (8 * (zext i4 (trunc i32 %v1 to i4) to i32))<nuw><nsw> == 0
+; CHECK-NEXT:    Compare predicate: (8 * %v1) ne) 0
 ; CHECK-NEXT:  Src: %v27 = load <32 x i32>, ptr %v25, align 256 --> Dst: %v32 = load <32 x i32>, ptr %v30, align 128
 ; CHECK-NEXT:    da analyze - input [* S S|<]!
 ; CHECK-NEXT:    Runtime Assumptions:
diff --git a/llvm/test/Analysis/DependenceAnalysis/StrongSIV.ll b/llvm/test/Analysis/DependenceAnalysis/StrongSIV.ll
index 19cef4537a769..b5a20b95034a4 100644
--- a/llvm/test/Analysis/DependenceAnalysis/StrongSIV.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/StrongSIV.ll
@@ -492,13 +492,19 @@ for.end:                                          ; preds = %for.end.loopexit, %
 define void @strong10(ptr %A, ptr %B, i64 %n) nounwind uwtable ssp {
 ; CHECK-LABEL: 'strong10'
 ; CHECK-NEXT:  Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %conv, ptr %arrayidx, align 4
-; CHECK-NEXT:    da analyze - none!
+; CHECK-NEXT:    da analyze - consistent output [0]!
+; CHECK-NEXT:    Runtime Assumptions:
+; CHECK-NEXT:    Compare predicate: (4 * %n) ne) 0
 ; CHECK-NEXT:  Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx3, align 4
 ; CHECK-NEXT:    da analyze - consistent flow [0|<]!
+; CHECK-NEXT:    Runtime Assumptions:
+; CHECK-NEXT:    Compare predicate: (4 * %n) ne) 0
 ; CHECK-NEXT:  Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4
 ; CHECK-NEXT:    da analyze - confused!
 ; CHECK-NEXT:  Src: %0 = load i32, ptr %arrayidx3, align 4 --> Dst: %0 = load i32, ptr %arrayidx3, align 4
-; CHECK-NEXT:    da analyze - none!
+; CHECK-NEXT:    da analyze - consistent input [0]!
+; CHECK-NEXT:    Runtime Assumptions:
+; CHECK-NEXT:    Compare predicate: (4 * %n) ne) 0
 ; CHECK-NEXT:  Src: %0 = load i32, ptr %arrayidx3, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4
 ; CHECK-NEXT:    da analyze - confused!
 ; CHECK-NEXT:  Src: store i32 %0, ptr %B.addr.01, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4
diff --git a/llvm/test/Analysis/DependenceAnalysis/SymbolicSIV.ll b/llvm/test/Analysis/DependenceAnalysis/SymbolicSIV.ll
index e43aa0f407b50..a33a10b5e1c2d 100644
--- a/llvm/test/Analysis/DependenceAnalysis/SymbolicSIV.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/SymbolicSIV.ll
@@ -381,13 +381,17 @@ for.end:                                          ; preds = %for.end.loopexit, %
 define void @symbolicsiv6(ptr %A, ptr %B, i64 %n, i64 %N, i64 %M) nounwind uwtable ssp {
 ; CHECK-LABEL: 'symbolicsiv6'
 ; CHECK-NEXT:  Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %conv, ptr %arrayidx, align 4
-; CHECK-NEXT:    da analyze - none!
+; CHECK-NEXT:    da analyze - consistent output [0]!
+; CHECK-NEXT:    Runtime Assumptions:
+; CHECK-NEXT:    Compare predicate: (16 * %N) ne) 0
 ; CHECK-NEXT:  Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx7, align 4
 ; CHECK-NEXT:    da analyze - flow [*|<]!
 ; CHECK-NEXT:  Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %0, ptr %B.addr.02, align 4
 ; CHECK-NEXT:    da analyze - confused!
 ; CHECK-NEXT:  Src: %0 = load i32, ptr %arrayidx7, align 4 --> Dst: %0 = load i32, ptr %arrayidx7, align 4
-; CHECK-NEXT:    da analyze - none!
+; CHECK-NEXT:    da analyze - consistent input [0]!
+; CHECK-NEXT:    Runtime Assumptions:
+; CHECK-NEXT:    Compare predicate: (16 * %N) ne) 0
 ; CHECK-NEXT:  Src: %0 = load i32, ptr %arrayidx7, align 4 --> Dst: store i32 %0, ptr %B.addr.02, align 4
 ; CHECK-NEXT:    da analyze - confused!
 ; CHECK-NEXT:  Src: store i32 %0, ptr %B.addr.02, align 4 --> Dst: store i32 %0, ptr %B.addr.02, align 4
@@ -437,13 +441,17 @@ for.end:                                          ; preds = %for.end.loopexit, %
 define void @symbolicsiv7(ptr %A, ptr %B, i64 %n, i64 %N, i64 %M) nounwind uwtable ssp {
 ; CHECK-LABEL: 'symbolicsiv7'
 ; CHECK-NEXT:  Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %conv, ptr %arrayidx, align 4
-; CHECK-NEXT:    da analyze - none!
+; CHECK-NEXT:    da analyze - consistent output [0]!
+; CHECK-NEXT:    Runtime Assumptions:
+; CHECK-NEXT:    Compare predicate: (8 * %N) ne) 0
 ; CHECK-NEXT:  Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %1 = load i32, ptr %arrayidx6, align 4
 ; CHECK-NEXT:    da analyze - flow [*|<]!
 ; CHECK-NEXT:  Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %1, ptr %B.addr.02, align 4
 ; CHECK-NEXT:    da analyze - confused!
 ; CHECK-NEXT:  Src: %1 = load i32, ptr %arrayidx6, align 4 --> Dst: %1 = load i32, ptr %arrayidx6, align 4
-; CHECK-NEXT:    da analyze - none!
+; CHECK-NEXT:    da analyze - consistent input [0]!
+; CHECK-NEXT:    Runtime Assumptions:
+; CHECK-NEXT:    Compare predicate: (8 * %N) ne) 0
 ; CHECK-NEXT:  Src: %1 = load i32, ptr %arrayidx6, align 4 --> Dst: store i32 %1, ptr %B.addr.02, align 4
 ; CHECK-NEXT:    da analyze - confused!
 ; CHECK-NEXT:  Src: store i32 %1, ptr %B.addr.02, align 4 --> Dst: store i32 %1, ptr %B.addr.02, align 4
diff --git a/llvm/test/Analysis/DependenceAnalysis/WeakCrossingSIV.ll b/llvm/test/Analysis/DependenceAnalysis/WeakCrossingSIV.ll
index 906505eef51b9..c7accfd46a4d7 100644
--- a/llvm/test/Analysis/DependenceAnalysis/WeakCrossingSIV.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/WeakCrossingSIV.ll
@@ -14,13 +14,17 @@ target triple = "x86_64-apple-macosx10.6.0"
 define void @weakcrossing0(ptr %A, ptr %B, i64 %n) nounwind uwtable ssp {
 ; CHECK-LABEL: 'weakcrossing0'
 ; CHECK-NEXT:  Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %conv, ptr %arrayidx, align 4
-; CHECK-NEXT:    da analyze - none!
+; CHECK-NEXT:    da analyze - consistent output [0]!
+; CHECK-NEXT:    Runtime Assumptions:
+; CHECK-NEXT:    Compare predicate: (4 * %n) ne) 0
 ; CHECK-NEXT:  Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx2, align 4
 ; CHECK-NEXT:    da analyze - flow [0|<]!
 ; CHECK-NEXT:  Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %0, ptr %B.addr.02, align 4
 ; CHECK-NEXT:    da analyze - confused!
 ; CHECK-NEXT:  Src: %0 = load i32, ptr %arrayidx2, align 4 --> Dst: %0 = load i32, ptr %arrayidx2, align 4
-; CHECK-NEXT:    da analyze - none!
+; CHECK-NEXT:    da analyze - consistent input [0]!
+; CHECK-NEXT:    Runtime Assumptions:
+; CHECK-NEXT:    Compare predicate: (-4 * %n) ne) 0
 ; CHECK-NEXT:  Src: %0 = load i32, ptr %arrayidx2, align 4 --> Dst: store i32 %0, ptr %B.addr.02, align 4
 ; CHECK-NEXT:    da analyze - confused!
 ; CHECK-NEXT:  Src: store i32 %0, ptr %B.addr.02, align 4 --> Dst: store i32 %0, ptr %B.addr.02, align 4
diff --git a/llvm/test/Analysis/DependenceAnalysis/WeakZeroDstSIV.ll b/llvm/test/Analysis/DependenceAnalysis/WeakZeroDstSIV.ll
index 71a5ed62b8e21..f8a045c425029 100644
--- a/llvm/test/Analysis/DependenceAnalysis/WeakZeroDstSIV.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/WeakZeroDstSIV.ll
@@ -90,7 +90,9 @@ for.end:                                          ; preds = %for.body
 define void @weakzerodst1(ptr %A, ptr %B, i64 %n) nounwind uwtable ssp {
 ; CHECK-LABEL: 'weakzerodst1'
 ; CHECK-NEXT:  Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %conv, ptr %arrayidx, align 4
-; CHECK-NEXT:    da analyze - none!
+; CHECK-NEXT:    da analyze - consistent output [0]!
+; CHECK-NEXT:    Runtime Assumptions:
+; CHECK-NEXT:    Compare predicate: (4 * %n) ne) 0
 ; CHECK-NEXT:  Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx1, align 4
 ; CHECK-NEXT:    da analyze - flow [p<=|<]!
 ; CHECK-NEXT:  Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %0, ptr %B.addr.02, align 4
diff --git a/llvm/test/Analysis/DependenceAnalysis/WeakZeroSrcSIV.ll b/llvm/test/Analysis/DependenceAnalysis/WeakZeroSrcSIV.ll
index 2ee1a37775f46..4ed0abd8d98a9 100644
--- a/llvm/test/Analysis/DependenceAnalysis/WeakZeroSrcSIV.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/WeakZeroSrcSIV.ll
@@ -94,7 +94,9 @@ define void @weakzerosrc1(ptr %A, ptr %B, i64 %n) nounwind uwtable ssp {
 ; CHECK-NEXT:  Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %0, ptr %B.addr.02, align 4
 ; CHECK-NEXT:    da analyze - confused!
 ; CHECK-NEXT:  Src: %0 = load i32, ptr %arrayidx1, align 4 --> Dst: %0 = load i32, ptr %arrayidx1, align 4
-; CHECK-NEXT:    da analyze - none!
+; CHECK-NEXT:    da analyze - consistent input [0]!
+; CHECK-NEXT:    Runtime Assumptions:
+; CHECK-NEXT:    Compare predicate: (4 * %n) ne) 0
 ; CHECK-NEXT:  Src: %0 = load i32, ptr %arrayidx1, align 4 --> Dst: store i32 %0, ptr %B.addr.02, align 4
 ; CHECK-NEXT:    da analyze - confused!
 ; CHECK-NEXT:  Src: store i32 %0, ptr %B.addr.02, align 4 --> Dst: store i32 %0, ptr %B.addr.02, align 4
diff --git a/llvm/test/Analysis/DependenceAnalysis/becount-couldnotcompute.ll b/llvm/test/Analysis/DependenceAnalysis/becount-couldnotcompute.ll
index 49fbad3510ae6..1674badd4d6b9 100644
--- a/llvm/test/Analysis/DependenceAnalysis/becount-couldnotcompute.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/becount-couldnotcompute.ll
@@ -7,7 +7,9 @@
 define void @test(i64 %conv, ptr %a) {
 ; CHECK-LABEL: 'test'
 ; CHECK-NEXT:  Src: %ld = load i32, ptr %arrayidx12, align 4 --> Dst: %ld = load i32, ptr %arrayidx12, align 4
-; CHECK-NEXT:    da analyze - none!
+; CHECK-NEXT:    da analyze - consistent input [0]!
+; CHECK-NEXT:    Runtime Assumptions:
+; CHECK-NEXT:    Compare predicate: (4 + (4 * %conv)) ne) 0
 ;
 entry:
   %sub = add i64 %conv, 1
diff --git a/llvm/test/Analysis/DependenceAnalysis/compute-absolute-value.ll b/llvm/test/Analysis/DependenceAnalysis/compute-absolute-value.ll
index 783150af2cd13..f3ce956545482 100644
--- a/llvm/test/Analysis/DependenceAnalysis/compute-absolute-value.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/compute-absolute-value.ll
@@ -16,11 +16,15 @@
 define void @unknown_sign(ptr %a, i64 %k) {
 ; CHECK-LABEL: 'unknown_sign'
 ; CHECK-NEXT:  Src: store i8 1, ptr %idx.0, align 1 --> Dst: store i8 1, ptr %idx.0, align 1
-; CHECK-NEXT:    da analyze - none!
+; CHECK-NEXT:    da analyze - consistent output [0]!
+; CHECK-NEXT:    Runtime Assumptions:
+; CHECK-NEXT:    Compare predicate: (-1 * %k) ne) 0
 ; CHECK-NEXT:  Src: store i8 1, ptr %idx.0, align 1 --> Dst: store i8 2, ptr %idx.1, align 1
 ; CHECK-NEXT:    da analyze - output [*|<]!
 ; CHECK-NEXT:  Src: store i8 2, ptr %idx.1, align 1 --> Dst: store i8 2, ptr %idx.1, align 1
-; CHECK-NEXT:    da analyze - none!
+; CHECK-NEXT:    da analyze - consistent output [0]!
+; CHECK-NEXT:    Runtime Assumptions:
+; CHECK-NEXT:    Compare predicate: (-1 * %k) ne) 0
 ;
 entry:
   %k.neg = sub nsw i64 0, %k
diff --git a/llvm/test/Analysis/DependenceAnalysis/gcd-miv-overflow.ll b/llvm/test/Analysis/DependenceAnalysis/gcd-miv-overflow.ll
index 9169ac323d834..891e73bb0f31e 100644
--- a/llvm/test/Analysis/DependenceAnalysis/gcd-miv-overflow.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/gcd-miv-overflow.ll
@@ -24,7 +24,9 @@
 define void @gcdmiv_coef_ovfl(ptr %A, i64 %m) {
 ; CHECK-ALL-LABEL: 'gcdmiv_coef_ovfl'
 ; CHECK-ALL-NEXT:  Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.0, align 1
-; CHECK-ALL-NEXT:    da analyze - none!
+; CHECK-ALL-NEXT:    da analyze - consistent output [0]!
+; CHECK-ALL-NEXT:    Runtime Assumptions:
+; CHECK-ALL-NEXT:    Compare predicate: (3 * %m) ne) 0
 ; CHECK-ALL-NEXT:  Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 2, ptr %gep.1, align 1
 ; CHECK-ALL-NEXT:    da analyze - output [*|<]!
 ; CHECK-ALL-NEXT:  Src: store i8 2, ptr %gep.1, align 1 --> Dst: store i8 2, ptr %gep.1, align 1
diff --git a/llvm/test/Analysis/DependenceAnalysis/monotonicity-cast.ll b/llvm/test/Analysis/DependenceAnalysis/monotonicity-cast.ll
index e43d00d0bf651..966e4462fb887 100644
--- a/llvm/test/Analysis/DependenceAnalysis/monotonicity-cast.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/monotonicity-cast.ll
@@ -14,7 +14,9 @@ define void @sext_nsw(ptr %a, i8 %start, i8 %step) {
 ; CHECK-NEXT:      Monotonicity: MultivariateSignedMonotonic
 ; CHECK-EMPTY:
 ; CHECK-NEXT:  Src: store i8 0, ptr %idx, align 1 --> Dst: store i8 0, ptr %idx, align 1
-; CHECK-NEXT:    da analyze - none!
+; CHECK-NEXT:    da analyze - consistent output [0]!
+; CHECK-NEXT:    Runtime Assumptions:
+; CHECK-NEXT:    Compare predicate: (sext i8 %step to i64) ne) 0
 ;
 entry:
   br label %loop



More information about the llvm-commits mailing list