[llvm] [DA] Introduce domain for monotonicity (PR #170684)
Ryotaro Kasuga via llvm-commits
llvm-commits at lists.llvm.org
Thu Dec 4 08:35:57 PST 2025
https://github.com/kasuga-fj updated https://github.com/llvm/llvm-project/pull/170684
>From 3dbf4fddbb1faf47006232b98f993d80902b9a8c Mon Sep 17 00:00:00 2001
From: Ryotaro Kasuga <kasuga.ryotaro at fujitsu.com>
Date: Thu, 4 Dec 2025 10:29:06 +0000
Subject: [PATCH 1/5] move monotonicity definition to header file
---
.../llvm/Analysis/DependenceAnalysis.h | 160 +++++++++++++++++
llvm/lib/Analysis/DependenceAnalysis.cpp | 164 ------------------
2 files changed, 160 insertions(+), 164 deletions(-)
diff --git a/llvm/include/llvm/Analysis/DependenceAnalysis.h b/llvm/include/llvm/Analysis/DependenceAnalysis.h
index 6dec24fc9f104..18c76dcc6658b 100644
--- a/llvm/include/llvm/Analysis/DependenceAnalysis.h
+++ b/llvm/include/llvm/Analysis/DependenceAnalysis.h
@@ -41,6 +41,7 @@
#include "llvm/ADT/SmallBitVector.h"
#include "llvm/Analysis/ScalarEvolution.h"
+#include "llvm/Analysis/ScalarEvolutionExpressions.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Pass.h"
@@ -332,6 +333,165 @@ class LLVM_ABI FullDependence final : public Dependence {
friend class DependenceInfo;
};
+/// The property of monotonicity of a SCEV. To define the monotonicity, assume
+/// a SCEV defined within N-nested loops. Let i_k denote the iteration number
+/// of the k-th loop. Then we can regard the SCEV as an N-ary function:
+///
+/// F(i_1, i_2, ..., i_N)
+///
+/// The domain of i_k is the closed range [0, BTC_k], where BTC_k is the
+/// backedge-taken count of the k-th loop.
+///
+/// A function F is said to be "monotonically increasing with respect to the
+/// k-th loop" if x <= y implies the following condition:
+///
+/// F(i_1, ..., i_{k-1}, x, i_{k+1}, ..., i_N) <=
+/// F(i_1, ..., i_{k-1}, y, i_{k+1}, ..., i_N)
+///
+/// where i_1, ..., i_{k-1}, i_{k+1}, ..., i_N, x, and y are elements of their
+/// respective domains.
+///
+/// Likewise F is "monotonically decreasing with respect to the k-th loop"
+/// if x <= y implies
+///
+/// F(i_1, ..., i_{k-1}, x, i_{k+1}, ..., i_N) >=
+/// F(i_1, ..., i_{k-1}, y, i_{k+1}, ..., i_N)
+///
+/// A function F that is monotonically increasing or decreasing with respect to
+/// the k-th loop is simply called "monotonic with respect to k-th loop".
+///
+/// A function F is said to be "multivariate monotonic" when it is monotonic
+/// with respect to all of the N loops.
+///
+/// Since integer comparison can be either signed or unsigned, we need to
+/// distinguish monotonicity in the signed sense from that in the unsigned
+/// sense. Note that the inequality "x <= y" merely indicates loop progression
+/// and is not affected by the difference between signed and unsigned order.
+///
+/// Currently we only consider monotonicity in a signed sense.
+enum class SCEVMonotonicityType {
+ /// We don't know anything about the monotonicity of the SCEV.
+ Unknown,
+
+ /// The SCEV is loop-invariant with respect to the outermost loop. In other
+ /// words, the function F corresponding to the SCEV is a constant function.
+ Invariant,
+
+ /// The function F corresponding to the SCEV is multivariate monotonic in a
+ /// signed sense. Note that the multivariate monotonic function may also be a
+ /// constant function. The order employed in the definition of monotonicity
+ /// is not strict order.
+ MultivariateSignedMonotonic,
+};
+
+struct SCEVMonotonicity {
+ SCEVMonotonicity(SCEVMonotonicityType Type,
+ const SCEV *FailurePoint = nullptr);
+
+ SCEVMonotonicityType getType() const { return Type; }
+
+ const SCEV *getFailurePoint() const { return FailurePoint; }
+
+ bool isUnknown() const { return Type == SCEVMonotonicityType::Unknown; }
+
+ void print(raw_ostream &OS, unsigned Depth) const;
+
+private:
+ SCEVMonotonicityType Type;
+
+ /// The subexpression that caused Unknown. Mainly for debugging purpose.
+ const SCEV *FailurePoint;
+};
+
+/// Check the monotonicity of a SCEV. Since dependence tests (SIV, MIV, etc.)
+/// assume that subscript expressions are (multivariate) monotonic, we need to
+/// verify this property before applying those tests. Violating this assumption
+/// may cause them to produce incorrect results.
+struct SCEVMonotonicityChecker
+ : public SCEVVisitor<SCEVMonotonicityChecker, SCEVMonotonicity> {
+
+ SCEVMonotonicityChecker(ScalarEvolution *SE) : SE(SE) {}
+
+ /// Check the monotonicity of \p Expr. \p Expr must be integer type. If \p
+ /// OutermostLoop is not null, \p Expr must be defined in \p OutermostLoop or
+ /// one of its nested loops.
+ SCEVMonotonicity checkMonotonicity(const SCEV *Expr,
+ const Loop *OutermostLoop);
+
+private:
+ ScalarEvolution *SE;
+
+ /// The outermost loop that DA is analyzing.
+ const Loop *OutermostLoop;
+
+ /// A helper to classify \p Expr as either Invariant or Unknown.
+ SCEVMonotonicity invariantOrUnknown(const SCEV *Expr);
+
+ /// Return true if \p Expr is loop-invariant with respect to the outermost
+ /// loop.
+ bool isLoopInvariant(const SCEV *Expr) const;
+
+ /// A helper to create an Unknown SCEVMonotonicity.
+ SCEVMonotonicity createUnknown(const SCEV *FailurePoint) {
+ return SCEVMonotonicity(SCEVMonotonicityType::Unknown, FailurePoint);
+ }
+
+ SCEVMonotonicity visitAddRecExpr(const SCEVAddRecExpr *Expr);
+
+ SCEVMonotonicity visitConstant(const SCEVConstant *) {
+ return SCEVMonotonicity(SCEVMonotonicityType::Invariant);
+ }
+ SCEVMonotonicity visitVScale(const SCEVVScale *) {
+ return SCEVMonotonicity(SCEVMonotonicityType::Invariant);
+ }
+
+ // TODO: Handle more cases.
+ SCEVMonotonicity visitZeroExtendExpr(const SCEVZeroExtendExpr *Expr) {
+ return invariantOrUnknown(Expr);
+ }
+ SCEVMonotonicity visitSignExtendExpr(const SCEVSignExtendExpr *Expr) {
+ return invariantOrUnknown(Expr);
+ }
+ SCEVMonotonicity visitAddExpr(const SCEVAddExpr *Expr) {
+ return invariantOrUnknown(Expr);
+ }
+ SCEVMonotonicity visitMulExpr(const SCEVMulExpr *Expr) {
+ return invariantOrUnknown(Expr);
+ }
+ SCEVMonotonicity visitPtrToIntExpr(const SCEVPtrToIntExpr *Expr) {
+ return invariantOrUnknown(Expr);
+ }
+ SCEVMonotonicity visitTruncateExpr(const SCEVTruncateExpr *Expr) {
+ return invariantOrUnknown(Expr);
+ }
+ SCEVMonotonicity visitUDivExpr(const SCEVUDivExpr *Expr) {
+ return invariantOrUnknown(Expr);
+ }
+ SCEVMonotonicity visitSMaxExpr(const SCEVSMaxExpr *Expr) {
+ return invariantOrUnknown(Expr);
+ }
+ SCEVMonotonicity visitUMaxExpr(const SCEVUMaxExpr *Expr) {
+ return invariantOrUnknown(Expr);
+ }
+ SCEVMonotonicity visitSMinExpr(const SCEVSMinExpr *Expr) {
+ return invariantOrUnknown(Expr);
+ }
+ SCEVMonotonicity visitUMinExpr(const SCEVUMinExpr *Expr) {
+ return invariantOrUnknown(Expr);
+ }
+ SCEVMonotonicity visitSequentialUMinExpr(const SCEVSequentialUMinExpr *Expr) {
+ return invariantOrUnknown(Expr);
+ }
+ SCEVMonotonicity visitUnknown(const SCEVUnknown *Expr) {
+ return invariantOrUnknown(Expr);
+ }
+ SCEVMonotonicity visitCouldNotCompute(const SCEVCouldNotCompute *Expr) {
+ return invariantOrUnknown(Expr);
+ }
+
+ friend struct SCEVVisitor<SCEVMonotonicityChecker, SCEVMonotonicity>;
+};
+
/// DependenceInfo - This class is the main dependence-analysis driver.
class DependenceInfo {
public:
diff --git a/llvm/lib/Analysis/DependenceAnalysis.cpp b/llvm/lib/Analysis/DependenceAnalysis.cpp
index b0cfaf6e5272b..d6ac813ba702e 100644
--- a/llvm/lib/Analysis/DependenceAnalysis.cpp
+++ b/llvm/lib/Analysis/DependenceAnalysis.cpp
@@ -50,7 +50,6 @@
#include "llvm/Analysis/Delinearization.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/ScalarEvolution.h"
-#include "llvm/Analysis/ScalarEvolutionExpressions.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/Module.h"
@@ -216,169 +215,6 @@ void DependenceAnalysisWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequiredTransitive<LoopInfoWrapperPass>();
}
-namespace {
-
-/// The property of monotonicity of a SCEV. To define the monotonicity, assume
-/// a SCEV defined within N-nested loops. Let i_k denote the iteration number
-/// of the k-th loop. Then we can regard the SCEV as an N-ary function:
-///
-/// F(i_1, i_2, ..., i_N)
-///
-/// The domain of i_k is the closed range [0, BTC_k], where BTC_k is the
-/// backedge-taken count of the k-th loop.
-///
-/// A function F is said to be "monotonically increasing with respect to the
-/// k-th loop" if x <= y implies the following condition:
-///
-/// F(i_1, ..., i_{k-1}, x, i_{k+1}, ..., i_N) <=
-/// F(i_1, ..., i_{k-1}, y, i_{k+1}, ..., i_N)
-///
-/// where i_1, ..., i_{k-1}, i_{k+1}, ..., i_N, x, and y are elements of their
-/// respective domains.
-///
-/// Likewise F is "monotonically decreasing with respect to the k-th loop"
-/// if x <= y implies
-///
-/// F(i_1, ..., i_{k-1}, x, i_{k+1}, ..., i_N) >=
-/// F(i_1, ..., i_{k-1}, y, i_{k+1}, ..., i_N)
-///
-/// A function F that is monotonically increasing or decreasing with respect to
-/// the k-th loop is simply called "monotonic with respect to k-th loop".
-///
-/// A function F is said to be "multivariate monotonic" when it is monotonic
-/// with respect to all of the N loops.
-///
-/// Since integer comparison can be either signed or unsigned, we need to
-/// distinguish monotonicity in the signed sense from that in the unsigned
-/// sense. Note that the inequality "x <= y" merely indicates loop progression
-/// and is not affected by the difference between signed and unsigned order.
-///
-/// Currently we only consider monotonicity in a signed sense.
-enum class SCEVMonotonicityType {
- /// We don't know anything about the monotonicity of the SCEV.
- Unknown,
-
- /// The SCEV is loop-invariant with respect to the outermost loop. In other
- /// words, the function F corresponding to the SCEV is a constant function.
- Invariant,
-
- /// The function F corresponding to the SCEV is multivariate monotonic in a
- /// signed sense. Note that the multivariate monotonic function may also be a
- /// constant function. The order employed in the definition of monotonicity
- /// is not strict order.
- MultivariateSignedMonotonic,
-};
-
-struct SCEVMonotonicity {
- SCEVMonotonicity(SCEVMonotonicityType Type,
- const SCEV *FailurePoint = nullptr);
-
- SCEVMonotonicityType getType() const { return Type; }
-
- const SCEV *getFailurePoint() const { return FailurePoint; }
-
- bool isUnknown() const { return Type == SCEVMonotonicityType::Unknown; }
-
- void print(raw_ostream &OS, unsigned Depth) const;
-
-private:
- SCEVMonotonicityType Type;
-
- /// The subexpression that caused Unknown. Mainly for debugging purpose.
- const SCEV *FailurePoint;
-};
-
-/// Check the monotonicity of a SCEV. Since dependence tests (SIV, MIV, etc.)
-/// assume that subscript expressions are (multivariate) monotonic, we need to
-/// verify this property before applying those tests. Violating this assumption
-/// may cause them to produce incorrect results.
-struct SCEVMonotonicityChecker
- : public SCEVVisitor<SCEVMonotonicityChecker, SCEVMonotonicity> {
-
- SCEVMonotonicityChecker(ScalarEvolution *SE) : SE(SE) {}
-
- /// Check the monotonicity of \p Expr. \p Expr must be integer type. If \p
- /// OutermostLoop is not null, \p Expr must be defined in \p OutermostLoop or
- /// one of its nested loops.
- SCEVMonotonicity checkMonotonicity(const SCEV *Expr,
- const Loop *OutermostLoop);
-
-private:
- ScalarEvolution *SE;
-
- /// The outermost loop that DA is analyzing.
- const Loop *OutermostLoop;
-
- /// A helper to classify \p Expr as either Invariant or Unknown.
- SCEVMonotonicity invariantOrUnknown(const SCEV *Expr);
-
- /// Return true if \p Expr is loop-invariant with respect to the outermost
- /// loop.
- bool isLoopInvariant(const SCEV *Expr) const;
-
- /// A helper to create an Unknown SCEVMonotonicity.
- SCEVMonotonicity createUnknown(const SCEV *FailurePoint) {
- return SCEVMonotonicity(SCEVMonotonicityType::Unknown, FailurePoint);
- }
-
- SCEVMonotonicity visitAddRecExpr(const SCEVAddRecExpr *Expr);
-
- SCEVMonotonicity visitConstant(const SCEVConstant *) {
- return SCEVMonotonicity(SCEVMonotonicityType::Invariant);
- }
- SCEVMonotonicity visitVScale(const SCEVVScale *) {
- return SCEVMonotonicity(SCEVMonotonicityType::Invariant);
- }
-
- // TODO: Handle more cases.
- SCEVMonotonicity visitZeroExtendExpr(const SCEVZeroExtendExpr *Expr) {
- return invariantOrUnknown(Expr);
- }
- SCEVMonotonicity visitSignExtendExpr(const SCEVSignExtendExpr *Expr) {
- return invariantOrUnknown(Expr);
- }
- SCEVMonotonicity visitAddExpr(const SCEVAddExpr *Expr) {
- return invariantOrUnknown(Expr);
- }
- SCEVMonotonicity visitMulExpr(const SCEVMulExpr *Expr) {
- return invariantOrUnknown(Expr);
- }
- SCEVMonotonicity visitPtrToIntExpr(const SCEVPtrToIntExpr *Expr) {
- return invariantOrUnknown(Expr);
- }
- SCEVMonotonicity visitTruncateExpr(const SCEVTruncateExpr *Expr) {
- return invariantOrUnknown(Expr);
- }
- SCEVMonotonicity visitUDivExpr(const SCEVUDivExpr *Expr) {
- return invariantOrUnknown(Expr);
- }
- SCEVMonotonicity visitSMaxExpr(const SCEVSMaxExpr *Expr) {
- return invariantOrUnknown(Expr);
- }
- SCEVMonotonicity visitUMaxExpr(const SCEVUMaxExpr *Expr) {
- return invariantOrUnknown(Expr);
- }
- SCEVMonotonicity visitSMinExpr(const SCEVSMinExpr *Expr) {
- return invariantOrUnknown(Expr);
- }
- SCEVMonotonicity visitUMinExpr(const SCEVUMinExpr *Expr) {
- return invariantOrUnknown(Expr);
- }
- SCEVMonotonicity visitSequentialUMinExpr(const SCEVSequentialUMinExpr *Expr) {
- return invariantOrUnknown(Expr);
- }
- SCEVMonotonicity visitUnknown(const SCEVUnknown *Expr) {
- return invariantOrUnknown(Expr);
- }
- SCEVMonotonicity visitCouldNotCompute(const SCEVCouldNotCompute *Expr) {
- return invariantOrUnknown(Expr);
- }
-
- friend struct SCEVVisitor<SCEVMonotonicityChecker, SCEVMonotonicity>;
-};
-
-} // anonymous namespace
-
// Used to test the dependence analyzer.
// Looks through the function, noting instructions that may access memory.
// Calls depends() on every possible pair and prints out the result.
>From 34b46d0743a745e1e675396cd0979bfdce009805 Mon Sep 17 00:00:00 2001
From: Ryotaro Kasuga <kasuga.ryotaro at fujitsu.com>
Date: Fri, 28 Nov 2025 02:25:39 +0900
Subject: [PATCH 2/5] remove -da-enable-monotonicity-check
---
llvm/lib/Analysis/DependenceAnalysis.cpp | 24 -------------------
.../DependenceAnalysis/monotonicity-cast.ll | 15 +++++++-----
.../monotonicity-delinearize.ll | 6 ++---
.../monotonicity-invariant.ll | 5 ++--
.../monotonicity-no-wrap-flags.ll | 15 ++++++------
.../DependenceAnalysis/non-monotonic.ll | 19 ++++-----------
6 files changed, 26 insertions(+), 58 deletions(-)
diff --git a/llvm/lib/Analysis/DependenceAnalysis.cpp b/llvm/lib/Analysis/DependenceAnalysis.cpp
index d6ac813ba702e..359118ce93d55 100644
--- a/llvm/lib/Analysis/DependenceAnalysis.cpp
+++ b/llvm/lib/Analysis/DependenceAnalysis.cpp
@@ -154,13 +154,6 @@ static cl::opt<DependenceTestType> EnableDependenceTest(
clEnumValN(DependenceTestType::BanerjeeMIV, "banerjee-miv",
"Enable only Banerjee MIV test.")));
-// TODO: This flag is disabled by default because it is still under development.
-// Enable it or delete this flag when the feature is ready.
-static cl::opt<bool> EnableMonotonicityCheck(
- "da-enable-monotonicity-check", cl::init(false), cl::Hidden,
- cl::desc("Check if the subscripts are monotonic. If it's not, dependence "
- "is reported as unknown."));
-
static cl::opt<bool> DumpMonotonicityReport(
"da-dump-monotonicity-report", cl::init(false), cl::Hidden,
cl::desc(
@@ -3057,19 +3050,10 @@ bool DependenceInfo::tryDelinearize(Instruction *Src, Instruction *Dst,
// resize Pair to contain as many pairs of subscripts as the delinearization
// has found, and then initialize the pairs following the delinearization.
Pair.resize(Size);
- SCEVMonotonicityChecker MonChecker(SE);
- const Loop *OutermostLoop = SrcLoop ? SrcLoop->getOutermostLoop() : nullptr;
for (int I = 0; I < Size; ++I) {
Pair[I].Src = SrcSubscripts[I];
Pair[I].Dst = DstSubscripts[I];
unifySubscriptType(&Pair[I]);
-
- if (EnableMonotonicityCheck) {
- if (MonChecker.checkMonotonicity(Pair[I].Src, OutermostLoop).isUnknown())
- return false;
- if (MonChecker.checkMonotonicity(Pair[I].Dst, OutermostLoop).isUnknown())
- return false;
- }
}
return true;
@@ -3334,14 +3318,6 @@ DependenceInfo::depends(Instruction *Src, Instruction *Dst,
Pair[0].Src = SrcEv;
Pair[0].Dst = DstEv;
- SCEVMonotonicityChecker MonChecker(SE);
- const Loop *OutermostLoop = SrcLoop ? SrcLoop->getOutermostLoop() : nullptr;
- if (EnableMonotonicityCheck)
- if (MonChecker.checkMonotonicity(Pair[0].Src, OutermostLoop).isUnknown() ||
- MonChecker.checkMonotonicity(Pair[0].Dst, OutermostLoop).isUnknown())
- return std::make_unique<Dependence>(Src, Dst,
- SCEVUnionPredicate(Assume, *SE));
-
if (Delinearize) {
if (tryDelinearize(Src, Dst, Pair)) {
LLVM_DEBUG(dbgs() << " delinearized\n");
diff --git a/llvm/test/Analysis/DependenceAnalysis/monotonicity-cast.ll b/llvm/test/Analysis/DependenceAnalysis/monotonicity-cast.ll
index 966e4462fb887..4d8b4e472fcd0 100644
--- a/llvm/test/Analysis/DependenceAnalysis/monotonicity-cast.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/monotonicity-cast.ll
@@ -1,6 +1,5 @@
; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 6
-; RUN: opt < %s -disable-output -passes="print<da>" -da-dump-monotonicity-report \
-; RUN: -da-enable-monotonicity-check 2>&1 | FileCheck %s
+; RUN: opt < %s -disable-output -passes="print<da>" -da-dump-monotonicity-report 2>&1 | FileCheck %s
; int8_t offset = start;
; for (int i = 0; i < 100; i++, offset += step)
@@ -51,7 +50,9 @@ define void @sext_may_wrap(ptr %a, i8 %start, i8 %step) {
; CHECK-NEXT: Reason: (sext i8 {%start,+,%step}<%loop> to i64)
; CHECK-EMPTY:
; CHECK-NEXT: Src: store i8 0, ptr %idx, align 1 --> Dst: store i8 0, ptr %idx, align 1
-; CHECK-NEXT: da analyze - confused!
+; CHECK-NEXT: da analyze - consistent output [0]!
+; CHECK-NEXT: Runtime Assumptions:
+; CHECK-NEXT: Compare predicate: %step ne) 0
;
entry:
br label %loop
@@ -121,7 +122,7 @@ define void @zext_cross_zero(ptr %a) {
; CHECK-NEXT: Reason: (zext i8 {-1,+,1}<nsw><%loop> to i64)
; CHECK-EMPTY:
; CHECK-NEXT: Src: store i8 0, ptr %idx, align 1 --> Dst: store i8 0, ptr %idx, align 1
-; CHECK-NEXT: da analyze - confused!
+; CHECK-NEXT: da analyze - none!
;
entry:
br label %loop
@@ -155,7 +156,9 @@ define void @zext_nneg_nsw(ptr %a, i8 %step) {
; CHECK-NEXT: Reason: (zext i8 {0,+,%step}<nsw><%loop> to i64)
; CHECK-EMPTY:
; CHECK-NEXT: Src: store i8 0, ptr %idx, align 1 --> Dst: store i8 0, ptr %idx, align 1
-; CHECK-NEXT: da analyze - confused!
+; CHECK-NEXT: da analyze - consistent output [0]!
+; CHECK-NEXT: Runtime Assumptions:
+; CHECK-NEXT: Compare predicate: %step ne) 0
;
entry:
br label %loop
@@ -190,7 +193,7 @@ define void @offset_truncated_to_i1(ptr %a) {
; CHECK-NEXT: Reason: (zext i1 {false,+,true}<%loop> to i64)
; CHECK-EMPTY:
; CHECK-NEXT: Src: store i8 0, ptr %idx, align 1 --> Dst: store i8 0, ptr %idx, align 1
-; CHECK-NEXT: da analyze - confused!
+; CHECK-NEXT: da analyze - none!
;
entry:
br label %loop
diff --git a/llvm/test/Analysis/DependenceAnalysis/monotonicity-delinearize.ll b/llvm/test/Analysis/DependenceAnalysis/monotonicity-delinearize.ll
index 71ea4e95059a0..26300154ec965 100644
--- a/llvm/test/Analysis/DependenceAnalysis/monotonicity-delinearize.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/monotonicity-delinearize.ll
@@ -1,6 +1,5 @@
; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 6
-; RUN: opt < %s -disable-output -passes="print<da>" -da-dump-monotonicity-report \
-; RUN: -da-enable-monotonicity-check 2>&1 | FileCheck %s
+; RUN: opt < %s -disable-output -passes="print<da>" -da-dump-monotonicity-report 2>&1 | FileCheck %s
; The offset SCEV will be delinearized into a 2D array access, like as follows:
;
@@ -16,6 +15,7 @@
; if (i < (1ll << 57))
; A[i][j] = 0;
;
+; FIXME: Delinearization result must be discarded.
define void @linearized_offset_wrap(ptr %a) {
; CHECK-LABEL: 'linearized_offset_wrap'
; CHECK-NEXT: Monotonicity check:
@@ -25,7 +25,7 @@ define void @linearized_offset_wrap(ptr %a) {
; CHECK-NEXT: Reason: {{\{\{}}0,+,32}<%loop.i.header>,+,1}<nw><%loop.j.header>
; CHECK-EMPTY:
; CHECK-NEXT: Src: store i8 0, ptr %gep, align 1 --> Dst: store i8 0, ptr %gep, align 1
-; CHECK-NEXT: da analyze - confused!
+; CHECK-NEXT: da analyze - none!
;
entry:
br label %loop.i.header
diff --git a/llvm/test/Analysis/DependenceAnalysis/monotonicity-invariant.ll b/llvm/test/Analysis/DependenceAnalysis/monotonicity-invariant.ll
index e5b6ddbaca6fe..bd6830f90aadd 100644
--- a/llvm/test/Analysis/DependenceAnalysis/monotonicity-invariant.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/monotonicity-invariant.ll
@@ -1,6 +1,5 @@
; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 6
-; RUN: opt < %s -disable-output -passes="print<da>" -da-dump-monotonicity-report \
-; RUN: -da-enable-monotonicity-check 2>&1 | FileCheck %s
+; RUN: opt < %s -disable-output -passes="print<da>" -da-dump-monotonicity-report 2>&1 | FileCheck %s
; for (int i = 0; i < n; i++)
; a[x] = 0;
@@ -41,7 +40,7 @@ define void @single_loop_variant(ptr %a, i64 %x, i64 %y, i64 %n) {
; CHECK-NEXT: Reason: %offset
; CHECK-EMPTY:
; CHECK-NEXT: Src: store i8 0, ptr %idx, align 1 --> Dst: store i8 0, ptr %idx, align 1
-; CHECK-NEXT: da analyze - confused!
+; CHECK-NEXT: da analyze - output [*]!
;
entry:
%guard = icmp sgt i64 %n, 0
diff --git a/llvm/test/Analysis/DependenceAnalysis/monotonicity-no-wrap-flags.ll b/llvm/test/Analysis/DependenceAnalysis/monotonicity-no-wrap-flags.ll
index df42c757a3b63..8c376c0a98cc0 100644
--- a/llvm/test/Analysis/DependenceAnalysis/monotonicity-no-wrap-flags.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/monotonicity-no-wrap-flags.ll
@@ -1,6 +1,5 @@
; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 6
-; RUN: opt < %s -disable-output -passes="print<da>" -da-dump-monotonicity-report \
-; RUN: -da-enable-monotonicity-check 2>&1 | FileCheck %s
+; RUN: opt < %s -disable-output -passes="print<da>" -da-dump-monotonicity-report 2>&1 | FileCheck %s
; for (int i = 0; i < n; i++)
; a[i] = 0;
@@ -46,7 +45,7 @@ define void @single_loop_nuw(ptr %a, i64 %begin, i64 %end) {
; CHECK-NEXT: Reason: {%begin,+,1}<nuw><%loop>
; CHECK-EMPTY:
; CHECK-NEXT: Src: store i8 0, ptr %idx, align 1 --> Dst: store i8 0, ptr %idx, align 1
-; CHECK-NEXT: da analyze - confused!
+; CHECK-NEXT: da analyze - none!
;
entry:
%guard = icmp ult i64 %begin, %end
@@ -211,7 +210,7 @@ define void @nested_loop_nuw(ptr %a, i64 %begin0, i64 %end0, i64 %begin1, i64 %e
; CHECK-NEXT: Reason: {{\{\{}}(%begin0 + %begin1),+,1}<nw><%loop.i.header>,+,1}<nw><%loop.j>
; CHECK-EMPTY:
; CHECK-NEXT: Src: store i8 0, ptr %idx, align 1 --> Dst: store i8 0, ptr %idx, align 1
-; CHECK-NEXT: da analyze - confused!
+; CHECK-NEXT: da analyze - output [* *]!
;
entry:
%guard.i.0 = icmp slt i64 0, %begin0
@@ -317,7 +316,7 @@ define void @step_is_variant(ptr %a) {
; CHECK-NEXT: Reason: %offset.i
; CHECK-EMPTY:
; CHECK-NEXT: Src: store i8 0, ptr %idx, align 1 --> Dst: store i8 0, ptr %idx, align 1
-; CHECK-NEXT: da analyze - confused!
+; CHECK-NEXT: da analyze - output [* *]!
;
entry:
br label %loop.i.header
@@ -367,7 +366,7 @@ define void @step_is_variant2(ptr %a) {
; CHECK-NEXT: Reason: %offset.i
; CHECK-EMPTY:
; CHECK-NEXT: Src: store i8 0, ptr %idx, align 1 --> Dst: store i8 0, ptr %idx, align 1
-; CHECK-NEXT: da analyze - confused!
+; CHECK-NEXT: da analyze - output [* *]!
;
entry:
br label %loop.i.header
@@ -415,7 +414,7 @@ define void @conditional_store0(ptr %a, i64 %n, i64 %m) {
; CHECK-NEXT: Reason: {{\{\{}}0,+,1}<nuw><nsw><%loop.i.header>,+,1}<nw><%loop.j.header>
; CHECK-EMPTY:
; CHECK-NEXT: Src: store i8 0, ptr %idx, align 1 --> Dst: store i8 0, ptr %idx, align 1
-; CHECK-NEXT: da analyze - confused!
+; CHECK-NEXT: da analyze - output [* *]!
;
entry:
%guard.i = icmp sgt i64 %n, 0
@@ -533,7 +532,7 @@ define void @outer_loop_may_wrap(ptr %a) {
; CHECK-NEXT: Reason: {9223372036854775552,+,1024}<%loop.i.header>
; CHECK-EMPTY:
; CHECK-NEXT: Src: store i8 0, ptr %gep, align 1 --> Dst: store i8 0, ptr %gep, align 1
-; CHECK-NEXT: da analyze - confused!
+; CHECK-NEXT: da analyze - none!
;
entry:
br label %loop.i.header
diff --git a/llvm/test/Analysis/DependenceAnalysis/non-monotonic.ll b/llvm/test/Analysis/DependenceAnalysis/non-monotonic.ll
index 6247336456d2c..5dfe3072f88ae 100644
--- a/llvm/test/Analysis/DependenceAnalysis/non-monotonic.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/non-monotonic.ll
@@ -1,9 +1,8 @@
; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 6
-; RUN: opt < %s -disable-output -passes="print<da>" -da-dump-monotonicity-report \
-; RUN: -da-enable-monotonicity-check 2>&1 | FileCheck %s
-; RUN: opt < %s -disable-output -passes="print<da>" 2>&1 | FileCheck %s -check-prefix=DISABLE-CHECK
+; RUN: opt < %s -disable-output -passes="print<da>" -da-dump-monotonicity-report 2>&1 | FileCheck %s
+
+; FIXME: Enable monotonicity check
-;
; for (i = 0; i < (1ULL << 60); i++) {
; A[i] = 1;
;
@@ -38,17 +37,9 @@ define void @f(ptr %A) {
; 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: Src: store i8 1, ptr %idx.0, align 1 --> Dst: store i8 2, ptr %idx.1, align 1
-; CHECK-NEXT: da analyze - confused!
+; CHECK-NEXT: da analyze - none!
; CHECK-NEXT: Src: store i8 2, ptr %idx.1, align 1 --> Dst: store i8 2, ptr %idx.1, align 1
-; CHECK-NEXT: da analyze - confused!
-;
-; DISABLE-CHECK-LABEL: 'f'
-; DISABLE-CHECK-NEXT: Src: store i8 1, ptr %idx.0, align 1 --> Dst: store i8 1, ptr %idx.0, align 1
-; DISABLE-CHECK-NEXT: da analyze - none!
-; DISABLE-CHECK-NEXT: Src: store i8 1, ptr %idx.0, align 1 --> Dst: store i8 2, ptr %idx.1, align 1
-; DISABLE-CHECK-NEXT: da analyze - none!
-; DISABLE-CHECK-NEXT: Src: store i8 2, ptr %idx.1, align 1 --> Dst: store i8 2, ptr %idx.1, align 1
-; DISABLE-CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - none!
;
entry:
br label %loop.header
>From 38c0bacd3aa3951f6d52941d681a0424cd6201fe Mon Sep 17 00:00:00 2001
From: Ryotaro Kasuga <kasuga.ryotaro at fujitsu.com>
Date: Fri, 28 Nov 2025 03:12:19 +0900
Subject: [PATCH 3/5] introduce domain for monotonicity
---
.../llvm/Analysis/DependenceAnalysis.h | 47 ++++++++--
llvm/lib/Analysis/DependenceAnalysis.cpp | 71 ++++++++++----
.../DependenceAnalysis/monotonicity-cast.ll | 42 +++++++--
.../monotonicity-delinearize.ll | 8 +-
.../DependenceAnalysis/monotonicity-domain.ll | 93 +++++++++++++++++++
.../monotonicity-invariant.ll | 23 ++++-
.../monotonicity-no-wrap-flags.ll | 83 +++++++++++++----
.../DependenceAnalysis/non-monotonic.ll | 13 ++-
8 files changed, 319 insertions(+), 61 deletions(-)
create mode 100644 llvm/test/Analysis/DependenceAnalysis/monotonicity-domain.ll
diff --git a/llvm/include/llvm/Analysis/DependenceAnalysis.h b/llvm/include/llvm/Analysis/DependenceAnalysis.h
index 18c76dcc6658b..7a17fba4dd6e7 100644
--- a/llvm/include/llvm/Analysis/DependenceAnalysis.h
+++ b/llvm/include/llvm/Analysis/DependenceAnalysis.h
@@ -339,8 +339,7 @@ class LLVM_ABI FullDependence final : public Dependence {
///
/// F(i_1, i_2, ..., i_N)
///
-/// The domain of i_k is the closed range [0, BTC_k], where BTC_k is the
-/// backedge-taken count of the k-th loop.
+/// For the domain of F, see the comment of SCEVMonotonicityDomain.
///
/// A function F is said to be "monotonically increasing with respect to the
/// k-th loop" if x <= y implies the following condition:
@@ -384,6 +383,28 @@ enum class SCEVMonotonicityType {
MultivariateSignedMonotonic,
};
+/// The domain for checking monotonicity of a SCEV which is represented as a
+/// function F(i_1, i_2, ..., i_N). Given a domain D, we say "F is multivariate
+/// monotonic over the domain D" if F is multivariate monotonic over D.
+enum class SCEVMonotonicityDomain {
+ /// [0, BTC_1] x [0, BTC_2] x ... x [0, BTC_N], where BTC_k is the exact
+ /// backedge-taken count for the k-th loop. This domain is well-defined only
+ /// when all loops have exact backedge-taken counts.
+ EntireDomain,
+
+ /// [L_1, U_1] x [L_2, U_2] x ... x [L_N, U_N].
+ /// When we say "F is multivariate monotonic over effective domain", it means:
+ ///
+ /// \exists L_k, U_k for all k, such that
+ /// - F is multivariate monotonic over [L_1, U_1] x ... x [L_N, U_N] and
+ /// - [L_1, U_1] x ... x [L_N, U_N] is a superset of where F is actually
+ /// executed.
+ ///
+ /// That is, we only implied the existence of such L_k and U_k, without any
+ /// specific values.
+ EffectiveDomain,
+};
+
struct SCEVMonotonicity {
SCEVMonotonicity(SCEVMonotonicityType Type,
const SCEV *FailurePoint = nullptr);
@@ -416,13 +437,25 @@ struct SCEVMonotonicityChecker
/// OutermostLoop is not null, \p Expr must be defined in \p OutermostLoop or
/// one of its nested loops.
SCEVMonotonicity checkMonotonicity(const SCEV *Expr,
- const Loop *OutermostLoop);
+ const Loop *OutermostLoop,
+ SCEVMonotonicityDomain Domain);
private:
ScalarEvolution *SE;
- /// The outermost loop that DA is analyzing.
- const Loop *OutermostLoop;
+ struct Context {
+ /// The outermost loop that DA is analyzing.
+ const Loop *OutermostLoop;
+
+ bool FoundInnermostAddRec = false;
+
+ SCEVMonotonicityDomain Domain;
+
+ void clear() {
+ OutermostLoop = nullptr;
+ FoundInnermostAddRec = false;
+ }
+ } Ctx;
/// A helper to classify \p Expr as either Invariant or Unknown.
SCEVMonotonicity invariantOrUnknown(const SCEV *Expr);
@@ -496,7 +529,7 @@ struct SCEVMonotonicityChecker
class DependenceInfo {
public:
DependenceInfo(Function *F, AAResults *AA, ScalarEvolution *SE, LoopInfo *LI)
- : AA(AA), SE(SE), LI(LI), F(F) {}
+ : AA(AA), SE(SE), LI(LI), F(F), MonChecker(SE) {}
/// Handle transitive invalidation when the cached analysis results go away.
LLVM_ABI bool invalidate(Function &F, const PreservedAnalyses &PA,
@@ -520,6 +553,8 @@ class DependenceInfo {
ScalarEvolution *SE;
LoopInfo *LI;
Function *F;
+ SmallVector<const SCEVPredicate *, 4> Assumptions;
+ SCEVMonotonicityChecker MonChecker;
/// Subscript - This private struct represents a pair of subscripts from
/// a pair of potentially multi-dimensional array references. We use a
diff --git a/llvm/lib/Analysis/DependenceAnalysis.cpp b/llvm/lib/Analysis/DependenceAnalysis.cpp
index 359118ce93d55..02cc1325693b7 100644
--- a/llvm/lib/Analysis/DependenceAnalysis.cpp
+++ b/llvm/lib/Analysis/DependenceAnalysis.cpp
@@ -228,10 +228,19 @@ static void dumpExampleDependence(raw_ostream &OS, DependenceInfo *DA,
const Loop *OutermostLoop = L ? L->getOutermostLoop() : nullptr;
const SCEV *PtrSCEV = SE.getSCEVAtScope(Ptr, L);
const SCEV *AccessFn = SE.removePointerBase(PtrSCEV);
- SCEVMonotonicity Mon = Checker.checkMonotonicity(AccessFn, OutermostLoop);
OS.indent(2) << "Inst: " << Inst << "\n";
OS.indent(4) << "Expr: " << *AccessFn << "\n";
- Mon.print(OS, 4);
+ for (SCEVMonotonicityDomain Domain :
+ {SCEVMonotonicityDomain::EffectiveDomain,
+ SCEVMonotonicityDomain::EntireDomain}) {
+ OS.indent(4) << (Domain == SCEVMonotonicityDomain::EffectiveDomain
+ ? "EffectiveDomain"
+ : "EntireDomain")
+ << "\n";
+ SCEVMonotonicity Mon =
+ Checker.checkMonotonicity(AccessFn, OutermostLoop, Domain);
+ Mon.print(OS, 6);
+ }
}
OS << "\n";
}
@@ -459,7 +468,7 @@ void SCEVMonotonicity::print(raw_ostream &OS, unsigned Depth) const {
}
bool SCEVMonotonicityChecker::isLoopInvariant(const SCEV *Expr) const {
- return !OutermostLoop || SE->isLoopInvariant(Expr, OutermostLoop);
+ return !Ctx.OutermostLoop || SE->isLoopInvariant(Expr, Ctx.OutermostLoop);
}
SCEVMonotonicity SCEVMonotonicityChecker::invariantOrUnknown(const SCEV *Expr) {
@@ -470,11 +479,14 @@ SCEVMonotonicity SCEVMonotonicityChecker::invariantOrUnknown(const SCEV *Expr) {
SCEVMonotonicity
SCEVMonotonicityChecker::checkMonotonicity(const SCEV *Expr,
- const Loop *OutermostLoop) {
+ const Loop *OutermostLoop,
+ SCEVMonotonicityDomain Domain) {
assert((!OutermostLoop || OutermostLoop->isOutermost()) &&
"OutermostLoop must be outermost");
assert(Expr->getType()->isIntegerTy() && "Expr must be integer type");
- this->OutermostLoop = OutermostLoop;
+ Ctx.clear();
+ Ctx.OutermostLoop = OutermostLoop;
+ Ctx.Domain = Domain;
return visit(Expr);
}
@@ -491,20 +503,45 @@ SCEVMonotonicityChecker::checkMonotonicity(const SCEV *Expr,
/// AddRec.
SCEVMonotonicity
SCEVMonotonicityChecker::visitAddRecExpr(const SCEVAddRecExpr *Expr) {
- if (!Expr->isAffine() || !Expr->hasNoSignedWrap())
- return createUnknown(Expr);
-
- const SCEV *Start = Expr->getStart();
- const SCEV *Step = Expr->getStepRecurrence(*SE);
-
- SCEVMonotonicity StartMon = visit(Start);
- if (StartMon.isUnknown())
- return StartMon;
+ auto Res = [&]() {
+ if (!Expr->isAffine() || !Expr->hasNoSignedWrap())
+ return createUnknown(Expr);
+
+ const SCEV *Start = Expr->getStart();
+ const SCEV *Step = Expr->getStepRecurrence(*SE);
+
+ SCEVMonotonicity StartMon = visit(Start);
+ if (StartMon.isUnknown())
+ return StartMon;
+
+ if (!isLoopInvariant(Step))
+ return createUnknown(Expr);
+
+ if (Ctx.Domain == SCEVMonotonicityDomain::EntireDomain) {
+ // If we have a conditional branch like the following:
+ //
+ // for (i = 0; i < N; i++)
+ // if (i < 10)
+ // for (j = 0; j < M; j++)
+ // A[i + j] = ...;
+ //
+ // The addrec for `i + j` will be like
+ // `{{0,+,1}<nsw><loop.i>,+,1}<nsw><loop.j>`. This doesn't imply `N + M`
+ // doesn't overflow, since the nsw for the j-loop is meaningful only when
+ // `i < 10`. Thus we cannot conclude the monotonicity over EntireDomain.
+ if (Ctx.FoundInnermostAddRec)
+ return createUnknown(Expr);
+
+ // By definition, the exact backedge-taken count must exist.
+ if (!SE->hasLoopInvariantBackedgeTakenCount(Expr->getLoop()))
+ return createUnknown(Expr);
+ }
- if (!isLoopInvariant(Step))
- return createUnknown(Expr);
+ return SCEVMonotonicity(SCEVMonotonicityType::MultivariateSignedMonotonic);
+ }();
- return SCEVMonotonicity(SCEVMonotonicityType::MultivariateSignedMonotonic);
+ Ctx.FoundInnermostAddRec = true;
+ return Res;
}
//===----------------------------------------------------------------------===//
diff --git a/llvm/test/Analysis/DependenceAnalysis/monotonicity-cast.ll b/llvm/test/Analysis/DependenceAnalysis/monotonicity-cast.ll
index 4d8b4e472fcd0..57280a99932ce 100644
--- a/llvm/test/Analysis/DependenceAnalysis/monotonicity-cast.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/monotonicity-cast.ll
@@ -10,7 +10,10 @@ define void @sext_nsw(ptr %a, i8 %start, i8 %step) {
; CHECK-NEXT: Monotonicity check:
; CHECK-NEXT: Inst: store i8 0, ptr %idx, align 1
; CHECK-NEXT: Expr: {(sext i8 %start to i64),+,(sext i8 %step to i64)}<nsw><%loop>
-; CHECK-NEXT: Monotonicity: MultivariateSignedMonotonic
+; CHECK-NEXT: EffectiveDomain
+; CHECK-NEXT: Monotonicity: MultivariateSignedMonotonic
+; CHECK-NEXT: EntireDomain
+; 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 - consistent output [0]!
@@ -46,8 +49,12 @@ define void @sext_may_wrap(ptr %a, i8 %start, i8 %step) {
; CHECK-NEXT: Monotonicity check:
; CHECK-NEXT: Inst: store i8 0, ptr %idx, align 1
; CHECK-NEXT: Expr: (sext i8 {%start,+,%step}<%loop> to i64)
-; CHECK-NEXT: Monotonicity: Unknown
-; CHECK-NEXT: Reason: (sext i8 {%start,+,%step}<%loop> to i64)
+; CHECK-NEXT: EffectiveDomain
+; CHECK-NEXT: Monotonicity: Unknown
+; CHECK-NEXT: Reason: (sext i8 {%start,+,%step}<%loop> to i64)
+; CHECK-NEXT: EntireDomain
+; CHECK-NEXT: Monotonicity: Unknown
+; CHECK-NEXT: Reason: (sext i8 {%start,+,%step}<%loop> to i64)
; CHECK-EMPTY:
; CHECK-NEXT: Src: store i8 0, ptr %idx, align 1 --> Dst: store i8 0, ptr %idx, align 1
; CHECK-NEXT: da analyze - consistent output [0]!
@@ -80,7 +87,10 @@ define void @zext_pos(ptr %a) {
; CHECK-NEXT: Monotonicity check:
; CHECK-NEXT: Inst: store i8 0, ptr %idx, align 1
; CHECK-NEXT: Expr: {0,+,1}<nuw><nsw><%loop>
-; CHECK-NEXT: Monotonicity: MultivariateSignedMonotonic
+; CHECK-NEXT: EffectiveDomain
+; CHECK-NEXT: Monotonicity: MultivariateSignedMonotonic
+; CHECK-NEXT: EntireDomain
+; 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!
@@ -118,8 +128,12 @@ define void @zext_cross_zero(ptr %a) {
; CHECK-NEXT: Monotonicity check:
; CHECK-NEXT: Inst: store i8 0, ptr %idx, align 1
; CHECK-NEXT: Expr: (zext i8 {-1,+,1}<nsw><%loop> to i64)
-; CHECK-NEXT: Monotonicity: Unknown
-; CHECK-NEXT: Reason: (zext i8 {-1,+,1}<nsw><%loop> to i64)
+; CHECK-NEXT: EffectiveDomain
+; CHECK-NEXT: Monotonicity: Unknown
+; CHECK-NEXT: Reason: (zext i8 {-1,+,1}<nsw><%loop> to i64)
+; CHECK-NEXT: EntireDomain
+; CHECK-NEXT: Monotonicity: Unknown
+; CHECK-NEXT: Reason: (zext i8 {-1,+,1}<nsw><%loop> to i64)
; 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!
@@ -152,8 +166,12 @@ define void @zext_nneg_nsw(ptr %a, i8 %step) {
; CHECK-NEXT: Monotonicity check:
; CHECK-NEXT: Inst: store i8 0, ptr %idx, align 1
; CHECK-NEXT: Expr: (zext i8 {0,+,%step}<nsw><%loop> to i64)
-; CHECK-NEXT: Monotonicity: Unknown
-; CHECK-NEXT: Reason: (zext i8 {0,+,%step}<nsw><%loop> to i64)
+; CHECK-NEXT: EffectiveDomain
+; CHECK-NEXT: Monotonicity: Unknown
+; CHECK-NEXT: Reason: (zext i8 {0,+,%step}<nsw><%loop> to i64)
+; CHECK-NEXT: EntireDomain
+; CHECK-NEXT: Monotonicity: Unknown
+; CHECK-NEXT: Reason: (zext i8 {0,+,%step}<nsw><%loop> to i64)
; CHECK-EMPTY:
; CHECK-NEXT: Src: store i8 0, ptr %idx, align 1 --> Dst: store i8 0, ptr %idx, align 1
; CHECK-NEXT: da analyze - consistent output [0]!
@@ -189,8 +207,12 @@ define void @offset_truncated_to_i1(ptr %a) {
; CHECK-NEXT: Monotonicity check:
; CHECK-NEXT: Inst: store i8 0, ptr %idx, align 1
; CHECK-NEXT: Expr: (zext i1 {false,+,true}<%loop> to i64)
-; CHECK-NEXT: Monotonicity: Unknown
-; CHECK-NEXT: Reason: (zext i1 {false,+,true}<%loop> to i64)
+; CHECK-NEXT: EffectiveDomain
+; CHECK-NEXT: Monotonicity: Unknown
+; CHECK-NEXT: Reason: (zext i1 {false,+,true}<%loop> to i64)
+; CHECK-NEXT: EntireDomain
+; CHECK-NEXT: Monotonicity: Unknown
+; CHECK-NEXT: Reason: (zext i1 {false,+,true}<%loop> to i64)
; 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!
diff --git a/llvm/test/Analysis/DependenceAnalysis/monotonicity-delinearize.ll b/llvm/test/Analysis/DependenceAnalysis/monotonicity-delinearize.ll
index 26300154ec965..4b71cb76094bb 100644
--- a/llvm/test/Analysis/DependenceAnalysis/monotonicity-delinearize.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/monotonicity-delinearize.ll
@@ -21,8 +21,12 @@ define void @linearized_offset_wrap(ptr %a) {
; CHECK-NEXT: Monotonicity check:
; CHECK-NEXT: Inst: store i8 0, ptr %gep, align 1
; CHECK-NEXT: Expr: {{\{\{}}0,+,32}<%loop.i.header>,+,1}<nw><%loop.j.header>
-; CHECK-NEXT: Monotonicity: Unknown
-; CHECK-NEXT: Reason: {{\{\{}}0,+,32}<%loop.i.header>,+,1}<nw><%loop.j.header>
+; CHECK-NEXT: EffectiveDomain
+; CHECK-NEXT: Monotonicity: Unknown
+; CHECK-NEXT: Reason: {{\{\{}}0,+,32}<%loop.i.header>,+,1}<nw><%loop.j.header>
+; CHECK-NEXT: EntireDomain
+; CHECK-NEXT: Monotonicity: Unknown
+; CHECK-NEXT: Reason: {{\{\{}}0,+,32}<%loop.i.header>,+,1}<nw><%loop.j.header>
; CHECK-EMPTY:
; CHECK-NEXT: Src: store i8 0, ptr %gep, align 1 --> Dst: store i8 0, ptr %gep, align 1
; CHECK-NEXT: da analyze - none!
diff --git a/llvm/test/Analysis/DependenceAnalysis/monotonicity-domain.ll b/llvm/test/Analysis/DependenceAnalysis/monotonicity-domain.ll
new file mode 100644
index 0000000000000..820795ebd665a
--- /dev/null
+++ b/llvm/test/Analysis/DependenceAnalysis/monotonicity-domain.ll
@@ -0,0 +1,93 @@
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -disable-output -passes="print<da>" -da-dump-monotonicity-report 2>&1 | FileCheck %s
+
+; for (i = 0; i < INT64_MAX - 1; i++)
+; if (i < 1000)
+; for (j = 0; j < 2000; j++)
+; a[i + j] = 0;
+;
+define void @nsw_under_loop_guard(ptr %a) {
+; CHECK-LABEL: 'nsw_under_loop_guard'
+; CHECK-NEXT: Monotonicity check:
+; CHECK-NEXT: Inst: store i8 0, ptr %idx, align 1
+; CHECK-NEXT: Expr: {{\{\{}}0,+,1}<nuw><nsw><%loop.i.header>,+,1}<nuw><nsw><%loop.j>
+; CHECK-NEXT: EffectiveDomain
+; CHECK-NEXT: Monotonicity: MultivariateSignedMonotonic
+; CHECK-NEXT: EntireDomain
+; CHECK-NEXT: Monotonicity: Unknown
+; CHECK-NEXT: Reason: {{\{\{}}0,+,1}<nuw><nsw><%loop.i.header>,+,1}<nuw><nsw><%loop.j>
+; 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!
+;
+entry:
+ br label %loop.i.header
+
+loop.i.header:
+ %i = phi i64 [ 0 , %entry ], [ %i.next, %loop.i.latch ]
+ br label %loop.j.pr
+
+loop.j.pr:
+ %guard.j = icmp slt i64 %i, 1000
+ br i1 %guard.j, label %loop.j, label %loop.i.latch
+
+loop.j:
+ %j = phi i64 [ 0, %loop.j.pr ], [ %j.next, %loop.j ]
+ %offset = add nsw i64 %i, %j
+ %idx = getelementptr inbounds i8, ptr %a, i64 %offset
+ store i8 0, ptr %idx
+ %j.next = add nsw i64 %j, 1
+ %ec.j = icmp eq i64 %j.next, 2000
+ br i1 %ec.j, label %loop.i.latch, label %loop.j
+
+loop.i.latch:
+ %i.next = add nsw i64 %i, 1
+ %ec.i = icmp eq i64 %i.next, 9223372036854775807
+ br i1 %ec.i, label %exit, label %loop.i.header
+
+exit:
+ ret void
+}
+
+; for (i = 0; i < 100; i++)
+; for (j = 0; j < i; j++)
+; a[i + j] = 0;
+;
+define void @btc_is_not_invariant(ptr %a) {
+; CHECK-LABEL: 'btc_is_not_invariant'
+; CHECK-NEXT: Monotonicity check:
+; CHECK-NEXT: Inst: store i8 0, ptr %idx, align 1
+; CHECK-NEXT: Expr: {{\{\{}}0,+,1}<nuw><nsw><%loop.i.header>,+,1}<nuw><nsw><%loop.j>
+; CHECK-NEXT: EffectiveDomain
+; CHECK-NEXT: Monotonicity: MultivariateSignedMonotonic
+; CHECK-NEXT: EntireDomain
+; CHECK-NEXT: Monotonicity: Unknown
+; CHECK-NEXT: Reason: {{\{\{}}0,+,1}<nuw><nsw><%loop.i.header>,+,1}<nuw><nsw><%loop.j>
+; CHECK-EMPTY:
+; CHECK-NEXT: Src: store i8 0, ptr %idx, align 1 --> Dst: store i8 0, ptr %idx, align 1
+; CHECK-NEXT: da analyze - output [* *]!
+;
+entry:
+ br label %loop.i.header
+
+loop.i.header:
+ %i = phi i64 [ 0 , %entry ], [ %i.next, %loop.i.latch ]
+ br label %loop.j
+
+loop.j:
+ %j = phi i64 [ 0, %loop.i.header ], [ %j.next, %loop.j ]
+ %offset = add nsw i64 %i, %j
+ %idx = getelementptr inbounds i8, ptr %a, i64 %offset
+ store i8 0, ptr %idx
+ %j.next = add nsw i64 %j, 1
+ %ec.j = icmp eq i64 %j.next, %i
+ br i1 %ec.j, label %loop.i.latch, label %loop.j
+
+loop.i.latch:
+ %i.next = add nsw i64 %i, 1
+ %ec.i = icmp eq i64 %i.next, 100
+ br i1 %ec.i, label %exit, label %loop.i.header
+
+exit:
+ ret void
+}
diff --git a/llvm/test/Analysis/DependenceAnalysis/monotonicity-invariant.ll b/llvm/test/Analysis/DependenceAnalysis/monotonicity-invariant.ll
index bd6830f90aadd..fccd57984aa3c 100644
--- a/llvm/test/Analysis/DependenceAnalysis/monotonicity-invariant.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/monotonicity-invariant.ll
@@ -8,7 +8,10 @@ define void @single_loop_invariant(ptr %a, i64 %x, i64 %n) {
; CHECK-NEXT: Monotonicity check:
; CHECK-NEXT: Inst: store i8 0, ptr %idx, align 1
; CHECK-NEXT: Expr: %x
-; CHECK-NEXT: Monotonicity: Invariant
+; CHECK-NEXT: EffectiveDomain
+; CHECK-NEXT: Monotonicity: Invariant
+; CHECK-NEXT: EntireDomain
+; CHECK-NEXT: Monotonicity: Invariant
; CHECK-EMPTY:
; CHECK-NEXT: Src: store i8 0, ptr %idx, align 1 --> Dst: store i8 0, ptr %idx, align 1
; CHECK-NEXT: da analyze - consistent output [S]!
@@ -36,8 +39,12 @@ define void @single_loop_variant(ptr %a, i64 %x, i64 %y, i64 %n) {
; CHECK-NEXT: Monotonicity check:
; CHECK-NEXT: Inst: store i8 0, ptr %idx, align 1
; CHECK-NEXT: Expr: %offset
-; CHECK-NEXT: Monotonicity: Unknown
-; CHECK-NEXT: Reason: %offset
+; CHECK-NEXT: EffectiveDomain
+; CHECK-NEXT: Monotonicity: Unknown
+; CHECK-NEXT: Reason: %offset
+; CHECK-NEXT: EntireDomain
+; CHECK-NEXT: Monotonicity: Unknown
+; CHECK-NEXT: Reason: %offset
; CHECK-EMPTY:
; CHECK-NEXT: Src: store i8 0, ptr %idx, align 1 --> Dst: store i8 0, ptr %idx, align 1
; CHECK-NEXT: da analyze - output [*]!
@@ -68,7 +75,10 @@ define void @invariant_plus_monotonic0(ptr %a, i64 %x, i64 %n, i64 %m) {
; CHECK-NEXT: Monotonicity check:
; CHECK-NEXT: Inst: store i8 0, ptr %idx, align 1
; CHECK-NEXT: Expr: {%x,+,1}<nsw><%loop.i.header>
-; CHECK-NEXT: Monotonicity: MultivariateSignedMonotonic
+; CHECK-NEXT: EffectiveDomain
+; CHECK-NEXT: Monotonicity: MultivariateSignedMonotonic
+; CHECK-NEXT: EntireDomain
+; 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 - consistent output [0 S]!
@@ -112,7 +122,10 @@ define void @invariant_plus_monotonic1(ptr %a, i64 %x, i64 %n, i64 %m) {
; CHECK-NEXT: Monotonicity check:
; CHECK-NEXT: Inst: store i8 0, ptr %idx, align 1
; CHECK-NEXT: Expr: {%x,+,1}<nsw><%loop.j>
-; CHECK-NEXT: Monotonicity: MultivariateSignedMonotonic
+; CHECK-NEXT: EffectiveDomain
+; CHECK-NEXT: Monotonicity: MultivariateSignedMonotonic
+; CHECK-NEXT: EntireDomain
+; 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 - consistent output [S 0]!
diff --git a/llvm/test/Analysis/DependenceAnalysis/monotonicity-no-wrap-flags.ll b/llvm/test/Analysis/DependenceAnalysis/monotonicity-no-wrap-flags.ll
index 8c376c0a98cc0..2572bdb36880a 100644
--- a/llvm/test/Analysis/DependenceAnalysis/monotonicity-no-wrap-flags.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/monotonicity-no-wrap-flags.ll
@@ -9,7 +9,10 @@ define void @single_loop_nsw(ptr %a, i64 %n) {
; CHECK-NEXT: Monotonicity check:
; CHECK-NEXT: Inst: store i8 0, ptr %idx, align 1
; CHECK-NEXT: Expr: {0,+,1}<nuw><nsw><%loop>
-; CHECK-NEXT: Monotonicity: MultivariateSignedMonotonic
+; CHECK-NEXT: EffectiveDomain
+; CHECK-NEXT: Monotonicity: MultivariateSignedMonotonic
+; CHECK-NEXT: EntireDomain
+; 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!
@@ -41,8 +44,12 @@ define void @single_loop_nuw(ptr %a, i64 %begin, i64 %end) {
; CHECK-NEXT: Monotonicity check:
; CHECK-NEXT: Inst: store i8 0, ptr %idx, align 1
; CHECK-NEXT: Expr: {%begin,+,1}<nuw><%loop>
-; CHECK-NEXT: Monotonicity: Unknown
-; CHECK-NEXT: Reason: {%begin,+,1}<nuw><%loop>
+; CHECK-NEXT: EffectiveDomain
+; CHECK-NEXT: Monotonicity: Unknown
+; CHECK-NEXT: Reason: {%begin,+,1}<nuw><%loop>
+; CHECK-NEXT: EntireDomain
+; CHECK-NEXT: Monotonicity: Unknown
+; CHECK-NEXT: Reason: {%begin,+,1}<nuw><%loop>
; 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!
@@ -72,7 +79,11 @@ define void @nested_loop_nsw0(ptr %a, i64 %n, i64 %m) {
; CHECK-NEXT: Monotonicity check:
; CHECK-NEXT: Inst: store i8 0, ptr %idx, align 1
; CHECK-NEXT: Expr: {{\{\{}}0,+,1}<nuw><nsw><%loop.i.header>,+,1}<nuw><nsw><%loop.j>
-; CHECK-NEXT: Monotonicity: MultivariateSignedMonotonic
+; CHECK-NEXT: EffectiveDomain
+; CHECK-NEXT: Monotonicity: MultivariateSignedMonotonic
+; CHECK-NEXT: EntireDomain
+; CHECK-NEXT: Monotonicity: Unknown
+; CHECK-NEXT: Reason: {{\{\{}}0,+,1}<nuw><nsw><%loop.i.header>,+,1}<nuw><nsw><%loop.j>
; CHECK-EMPTY:
; CHECK-NEXT: Src: store i8 0, ptr %idx, align 1 --> Dst: store i8 0, ptr %idx, align 1
; CHECK-NEXT: da analyze - output [* *]!
@@ -116,7 +127,11 @@ define void @nested_loop_nsw1(ptr %a, i64 %n, i64 %m) {
; CHECK-NEXT: Monotonicity check:
; CHECK-NEXT: Inst: store i8 0, ptr %idx, align 1
; CHECK-NEXT: Expr: {{\{\{}}(-1 + %n),+,-1}<nsw><%loop.i.header>,+,1}<nsw><%loop.j>
-; CHECK-NEXT: Monotonicity: MultivariateSignedMonotonic
+; CHECK-NEXT: EffectiveDomain
+; CHECK-NEXT: Monotonicity: MultivariateSignedMonotonic
+; CHECK-NEXT: EntireDomain
+; CHECK-NEXT: Monotonicity: Unknown
+; CHECK-NEXT: Reason: {{\{\{}}(-1 + %n),+,-1}<nsw><%loop.i.header>,+,1}<nsw><%loop.j>
; CHECK-EMPTY:
; CHECK-NEXT: Src: store i8 0, ptr %idx, align 1 --> Dst: store i8 0, ptr %idx, align 1
; CHECK-NEXT: da analyze - output [* *]!
@@ -160,7 +175,11 @@ define void @nested_loop_nsw2(ptr %a, i64 %n, i64 %m) {
; CHECK-NEXT: Monotonicity check:
; CHECK-NEXT: Inst: store i8 0, ptr %idx, align 1
; CHECK-NEXT: Expr: {{\{\{}}0,+,1}<nuw><nsw><%loop.i.header>,+,-1}<nsw><%loop.j>
-; CHECK-NEXT: Monotonicity: MultivariateSignedMonotonic
+; CHECK-NEXT: EffectiveDomain
+; CHECK-NEXT: Monotonicity: MultivariateSignedMonotonic
+; CHECK-NEXT: EntireDomain
+; CHECK-NEXT: Monotonicity: Unknown
+; CHECK-NEXT: Reason: {{\{\{}}0,+,1}<nuw><nsw><%loop.i.header>,+,-1}<nsw><%loop.j>
; CHECK-EMPTY:
; CHECK-NEXT: Src: store i8 0, ptr %idx, align 1 --> Dst: store i8 0, ptr %idx, align 1
; CHECK-NEXT: da analyze - output [* *]!
@@ -206,8 +225,12 @@ define void @nested_loop_nuw(ptr %a, i64 %begin0, i64 %end0, i64 %begin1, i64 %e
; CHECK-NEXT: Monotonicity check:
; CHECK-NEXT: Inst: store i8 0, ptr %idx, align 1
; CHECK-NEXT: Expr: {{\{\{}}(%begin0 + %begin1),+,1}<nw><%loop.i.header>,+,1}<nw><%loop.j>
-; CHECK-NEXT: Monotonicity: Unknown
-; CHECK-NEXT: Reason: {{\{\{}}(%begin0 + %begin1),+,1}<nw><%loop.i.header>,+,1}<nw><%loop.j>
+; CHECK-NEXT: EffectiveDomain
+; CHECK-NEXT: Monotonicity: Unknown
+; CHECK-NEXT: Reason: {{\{\{}}(%begin0 + %begin1),+,1}<nw><%loop.i.header>,+,1}<nw><%loop.j>
+; CHECK-NEXT: EntireDomain
+; CHECK-NEXT: Monotonicity: Unknown
+; CHECK-NEXT: Reason: {{\{\{}}(%begin0 + %begin1),+,1}<nw><%loop.i.header>,+,1}<nw><%loop.j>
; CHECK-EMPTY:
; CHECK-NEXT: Src: store i8 0, ptr %idx, align 1 --> Dst: store i8 0, ptr %idx, align 1
; CHECK-NEXT: da analyze - output [* *]!
@@ -259,7 +282,11 @@ define void @nested_loop_step(ptr %a, i64 %n, i64 %m, i64 %step) {
; CHECK-NEXT: Monotonicity check:
; CHECK-NEXT: Inst: store i8 0, ptr %idx, align 1
; CHECK-NEXT: Expr: {{\{\{}}0,+,1}<nuw><nsw><%loop.i.header>,+,%step}<nsw><%loop.j>
-; CHECK-NEXT: Monotonicity: MultivariateSignedMonotonic
+; CHECK-NEXT: EffectiveDomain
+; CHECK-NEXT: Monotonicity: MultivariateSignedMonotonic
+; CHECK-NEXT: EntireDomain
+; CHECK-NEXT: Monotonicity: Unknown
+; CHECK-NEXT: Reason: {{\{\{}}0,+,1}<nuw><nsw><%loop.i.header>,+,%step}<nsw><%loop.j>
; CHECK-EMPTY:
; CHECK-NEXT: Src: store i8 0, ptr %idx, align 1 --> Dst: store i8 0, ptr %idx, align 1
; CHECK-NEXT: da analyze - output [* *]!
@@ -312,8 +339,12 @@ define void @step_is_variant(ptr %a) {
; CHECK-NEXT: Monotonicity check:
; CHECK-NEXT: Inst: store i8 0, ptr %idx, align 1
; CHECK-NEXT: Expr: {%offset.i,+,1}<nuw><nsw><%loop.j>
-; CHECK-NEXT: Monotonicity: Unknown
-; CHECK-NEXT: Reason: %offset.i
+; CHECK-NEXT: EffectiveDomain
+; CHECK-NEXT: Monotonicity: Unknown
+; CHECK-NEXT: Reason: %offset.i
+; CHECK-NEXT: EntireDomain
+; CHECK-NEXT: Monotonicity: Unknown
+; CHECK-NEXT: Reason: %offset.i
; CHECK-EMPTY:
; CHECK-NEXT: Src: store i8 0, ptr %idx, align 1 --> Dst: store i8 0, ptr %idx, align 1
; CHECK-NEXT: da analyze - output [* *]!
@@ -362,8 +393,12 @@ define void @step_is_variant2(ptr %a) {
; CHECK-NEXT: Monotonicity check:
; CHECK-NEXT: Inst: store i8 0, ptr %idx, align 1
; CHECK-NEXT: Expr: {%offset.i,+,1}<nsw><%loop.j>
-; CHECK-NEXT: Monotonicity: Unknown
-; CHECK-NEXT: Reason: %offset.i
+; CHECK-NEXT: EffectiveDomain
+; CHECK-NEXT: Monotonicity: Unknown
+; CHECK-NEXT: Reason: %offset.i
+; CHECK-NEXT: EntireDomain
+; CHECK-NEXT: Monotonicity: Unknown
+; CHECK-NEXT: Reason: %offset.i
; CHECK-EMPTY:
; CHECK-NEXT: Src: store i8 0, ptr %idx, align 1 --> Dst: store i8 0, ptr %idx, align 1
; CHECK-NEXT: da analyze - output [* *]!
@@ -410,8 +445,12 @@ define void @conditional_store0(ptr %a, i64 %n, i64 %m) {
; CHECK-NEXT: Monotonicity check:
; CHECK-NEXT: Inst: store i8 0, ptr %idx, align 1
; CHECK-NEXT: Expr: {{\{\{}}0,+,1}<nuw><nsw><%loop.i.header>,+,1}<nw><%loop.j.header>
-; CHECK-NEXT: Monotonicity: Unknown
-; CHECK-NEXT: Reason: {{\{\{}}0,+,1}<nuw><nsw><%loop.i.header>,+,1}<nw><%loop.j.header>
+; CHECK-NEXT: EffectiveDomain
+; CHECK-NEXT: Monotonicity: Unknown
+; CHECK-NEXT: Reason: {{\{\{}}0,+,1}<nuw><nsw><%loop.i.header>,+,1}<nw><%loop.j.header>
+; CHECK-NEXT: EntireDomain
+; CHECK-NEXT: Monotonicity: Unknown
+; CHECK-NEXT: Reason: {{\{\{}}0,+,1}<nuw><nsw><%loop.i.header>,+,1}<nw><%loop.j.header>
; CHECK-EMPTY:
; CHECK-NEXT: Src: store i8 0, ptr %idx, align 1 --> Dst: store i8 0, ptr %idx, align 1
; CHECK-NEXT: da analyze - output [* *]!
@@ -466,7 +505,11 @@ define void @conditional_store1(ptr %a, i64 %n, i64 %m) {
; CHECK-NEXT: Monotonicity check:
; CHECK-NEXT: Inst: store i8 0, ptr %idx, align 1
; CHECK-NEXT: Expr: {{\{\{}}0,+,1}<nuw><nsw><%loop.i.header>,+,1}<nuw><nsw><%loop.j.header>
-; CHECK-NEXT: Monotonicity: MultivariateSignedMonotonic
+; CHECK-NEXT: EffectiveDomain
+; CHECK-NEXT: Monotonicity: MultivariateSignedMonotonic
+; CHECK-NEXT: EntireDomain
+; CHECK-NEXT: Monotonicity: Unknown
+; CHECK-NEXT: Reason: {{\{\{}}0,+,1}<nuw><nsw><%loop.i.header>,+,1}<nuw><nsw><%loop.j.header>
; CHECK-EMPTY:
; CHECK-NEXT: Src: store i8 0, ptr %idx, align 1 --> Dst: store i8 0, ptr %idx, align 1
; CHECK-NEXT: da analyze - output [* *]!
@@ -528,8 +571,12 @@ define void @outer_loop_may_wrap(ptr %a) {
; CHECK-NEXT: Monotonicity check:
; CHECK-NEXT: Inst: store i8 0, ptr %gep, align 1
; CHECK-NEXT: Expr: {{\{\{}}9223372036854775552,+,1024}<%loop.i.header>,+,1}<nuw><nsw><%loop.j.header>
-; CHECK-NEXT: Monotonicity: Unknown
-; CHECK-NEXT: Reason: {9223372036854775552,+,1024}<%loop.i.header>
+; CHECK-NEXT: EffectiveDomain
+; CHECK-NEXT: Monotonicity: Unknown
+; CHECK-NEXT: Reason: {9223372036854775552,+,1024}<%loop.i.header>
+; CHECK-NEXT: EntireDomain
+; CHECK-NEXT: Monotonicity: Unknown
+; CHECK-NEXT: Reason: {9223372036854775552,+,1024}<%loop.i.header>
; CHECK-EMPTY:
; CHECK-NEXT: Src: store i8 0, ptr %gep, align 1 --> Dst: store i8 0, ptr %gep, align 1
; CHECK-NEXT: da analyze - none!
diff --git a/llvm/test/Analysis/DependenceAnalysis/non-monotonic.ll b/llvm/test/Analysis/DependenceAnalysis/non-monotonic.ll
index 5dfe3072f88ae..74c332fcb8fa3 100644
--- a/llvm/test/Analysis/DependenceAnalysis/non-monotonic.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/non-monotonic.ll
@@ -28,11 +28,18 @@ define void @f(ptr %A) {
; CHECK-NEXT: Monotonicity check:
; CHECK-NEXT: Inst: store i8 1, ptr %idx.0, align 1
; CHECK-NEXT: Expr: {0,+,1}<nuw><nsw><%loop.header>
-; CHECK-NEXT: Monotonicity: MultivariateSignedMonotonic
+; CHECK-NEXT: EffectiveDomain
+; CHECK-NEXT: Monotonicity: MultivariateSignedMonotonic
+; CHECK-NEXT: EntireDomain
+; CHECK-NEXT: Monotonicity: MultivariateSignedMonotonic
; CHECK-NEXT: Inst: store i8 2, ptr %idx.1, align 1
; CHECK-NEXT: Expr: {4611686018427387904,+,32}<%loop.header>
-; CHECK-NEXT: Monotonicity: Unknown
-; CHECK-NEXT: Reason: {4611686018427387904,+,32}<%loop.header>
+; CHECK-NEXT: EffectiveDomain
+; CHECK-NEXT: Monotonicity: Unknown
+; CHECK-NEXT: Reason: {4611686018427387904,+,32}<%loop.header>
+; CHECK-NEXT: EntireDomain
+; CHECK-NEXT: Monotonicity: Unknown
+; CHECK-NEXT: Reason: {4611686018427387904,+,32}<%loop.header>
; CHECK-EMPTY:
; 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!
>From 3fb1bd1de4f88b9972c9d3b4c6c9d1bae60fe38a Mon Sep 17 00:00:00 2001
From: Ryotaro Kasuga <kasuga.ryotaro at fujitsu.com>
Date: Thu, 4 Dec 2025 12:56:28 +0000
Subject: [PATCH 4/5] apply monotonicity check for strong siv
---
.../llvm/Analysis/DependenceAnalysis.h | 16 ++-
llvm/lib/Analysis/DependenceAnalysis.cpp | 133 ++++++++++--------
.../Analysis/DependenceAnalysis/BasePtrBug.ll | 4 +-
.../Analysis/DependenceAnalysis/DADelin.ll | 20 +--
.../DependenceAnalysis/MIVCheckConst.ll | 5 +-
.../NonCanonicalizedSubscript.ll | 2 +-
.../DependenceAnalysis/Preliminary.ll | 10 +-
.../PreliminaryNoValidityCheckFixedSize.ll | 4 +-
.../SimpleSIVNoValidityCheck.ll | 12 +-
.../Analysis/DependenceAnalysis/StrongSIV.ll | 40 +++---
.../DependenceAnalysis/SymbolicRDIV.ll | 36 ++---
.../DependenceAnalysis/SymbolicSIV.ll | 66 ++++-----
.../DependenceAnalysis/WeakCrossingSIV.ll | 22 ++-
.../DependenceAnalysis/WeakZeroDstSIV.ll | 10 +-
.../DependenceAnalysis/WeakZeroSrcSIV.ll | 10 +-
.../becount-couldnotcompute.ll | 4 +-
.../DependenceAnalysis/monotonicity-cast.ll | 4 +-
.../monotonicity-no-wrap-flags.ll | 2 +-
18 files changed, 198 insertions(+), 202 deletions(-)
diff --git a/llvm/include/llvm/Analysis/DependenceAnalysis.h b/llvm/include/llvm/Analysis/DependenceAnalysis.h
index 7a17fba4dd6e7..a6a7928418120 100644
--- a/llvm/include/llvm/Analysis/DependenceAnalysis.h
+++ b/llvm/include/llvm/Analysis/DependenceAnalysis.h
@@ -765,10 +765,9 @@ class DependenceInfo {
/// Returns true if any possible dependence is disproved.
/// If there might be a dependence, returns false.
/// Sets appropriate direction and distance.
- bool strongSIVtest(const SCEV *Coeff, const SCEV *SrcConst,
- const SCEV *DstConst, const Loop *CurrentSrcLoop,
- const Loop *CurrentDstLoop, unsigned Level,
- FullDependence &Result, bool UnderRuntimeAssumptions);
+ bool strongSIVtest(const SCEVAddRecExpr *Src, const SCEVAddRecExpr *Dst,
+ unsigned Level, FullDependence &Result,
+ bool UnderRuntimeAssumptions);
/// weakCrossingSIVtest - Tests the weak-crossing SIV subscript pair
/// (Src and Dst) for dependence.
@@ -972,6 +971,15 @@ class DependenceInfo {
/// checkDstSubscript to avoid duplicate code
bool checkSubscript(const SCEV *Expr, const Loop *LoopNest,
SmallBitVector &Loops, bool IsSrc);
+
+ /// Returns true if \p Expr is multivariate monotonic over \p Domain.
+ bool isMonotonic(const SCEV *Expr, SCEVMonotonicityDomain Domain,
+ const Loop *OutermostLoop);
+
+ /// Returns true if both \p Src and \p Dst are monotonic over \p Domain.
+ bool isMonotonicPair(const SCEV *Src, const SCEV *Dst,
+ SCEVMonotonicityDomain Domain,
+ const Loop *OutermostLoop);
}; // class DependenceInfo
/// AnalysisPass to compute dependence information in a function
diff --git a/llvm/lib/Analysis/DependenceAnalysis.cpp b/llvm/lib/Analysis/DependenceAnalysis.cpp
index 02cc1325693b7..933a3b9673a12 100644
--- a/llvm/lib/Analysis/DependenceAnalysis.cpp
+++ b/llvm/lib/Analysis/DependenceAnalysis.cpp
@@ -1070,32 +1070,6 @@ static const SCEV *minusSCEVNoSignedOverflow(const SCEV *A, const SCEV *B,
return nullptr;
}
-/// Returns \p A * \p B if it guaranteed not to signed wrap. Otherwise returns
-/// nullptr. \p A and \p B must have the same integer type.
-static const SCEV *mulSCEVNoSignedOverflow(const SCEV *A, const SCEV *B,
- ScalarEvolution &SE) {
- if (SE.willNotOverflow(Instruction::Mul, /*Signed=*/true, A, B))
- return SE.getMulExpr(A, B);
- return nullptr;
-}
-
-/// Returns the absolute value of \p A. In the context of dependence analysis,
-/// we need an absolute value in a mathematical sense. If \p A is the signed
-/// minimum value, we cannot represent it unless extending the original type.
-/// Thus if we cannot prove that \p A is not the signed minimum value, returns
-/// nullptr.
-static const SCEV *absSCEVNoSignedOverflow(const SCEV *A, ScalarEvolution &SE) {
- IntegerType *Ty = cast<IntegerType>(A->getType());
- if (!Ty)
- return nullptr;
-
- const SCEV *SMin =
- SE.getConstant(APInt::getSignedMinValue(Ty->getBitWidth()));
- if (!SE.isKnownPredicate(CmpInst::ICMP_NE, A, SMin))
- return nullptr;
- return SE.getAbsExpr(A, /*IsNSW=*/true);
-}
-
/// Returns true iff \p Test is enabled.
static bool isDependenceTestEnabled(DependenceTestType Test) {
if (EnableDependenceTest == DependenceTestType::All)
@@ -1103,6 +1077,28 @@ static bool isDependenceTestEnabled(DependenceTestType Test) {
return EnableDependenceTest == Test;
}
+bool DependenceInfo::isMonotonic(const SCEV *Expr,
+ SCEVMonotonicityDomain Domain,
+ const Loop *OutermostLoop) {
+ SCEVMonotonicity Mon =
+ MonChecker.checkMonotonicity(Expr, OutermostLoop, Domain);
+ switch (Mon.getType()) {
+ case SCEVMonotonicityType::Invariant:
+ case SCEVMonotonicityType::MultivariateSignedMonotonic:
+ return true;
+ case SCEVMonotonicityType::Unknown:
+ return false;
+ }
+ llvm_unreachable("Unknown SCEVMonotonicityType");
+}
+
+bool DependenceInfo::isMonotonicPair(const SCEV *Src, const SCEV *Dst,
+ SCEVMonotonicityDomain Domain,
+ const Loop *OutermostLoop) {
+ return isMonotonic(Src, Domain, OutermostLoop) &&
+ isMonotonic(Dst, Domain, OutermostLoop);
+}
+
// testZIV -
// When we have a pair of subscripts of the form [c1] and [c2],
// where c1 and c2 are both loop invariant, we attack it using
@@ -1132,6 +1128,15 @@ bool DependenceInfo::testZIV(const SCEV *Src, const SCEV *Dst,
return false; // possibly dependent
}
+static std::pair<const SCEV *, const SCEV *>
+evaluateFirstAndLast(ScalarEvolution &SE, const SCEVAddRecExpr *Expr,
+ const SCEV *BTC) {
+ const SCEV *Zero = SE.getZero(Expr->getType());
+ const SCEV *First = Expr->evaluateAtIteration(Zero, SE);
+ const SCEV *Last = Expr->evaluateAtIteration(BTC, SE);
+ return std::make_pair(First, Last);
+}
+
// strongSIVtest -
// From the paper, Practical Dependence Testing, Section 4.2.1
//
@@ -1159,14 +1164,19 @@ bool DependenceInfo::testZIV(const SCEV *Src, const SCEV *Dst,
// { > if d < 0
//
// Return true if dependence disproved.
-bool DependenceInfo::strongSIVtest(const SCEV *Coeff, const SCEV *SrcConst,
- const SCEV *DstConst, const Loop *CurSrcLoop,
- const Loop *CurDstLoop, unsigned Level,
+bool DependenceInfo::strongSIVtest(const SCEVAddRecExpr *Src,
+ const SCEVAddRecExpr *Dst, unsigned Level,
FullDependence &Result,
bool UnderRuntimeAssumptions) {
if (!isDependenceTestEnabled(DependenceTestType::StrongSIV))
return false;
+ const SCEV *Coeff = Src->getStepRecurrence(*SE);
+ const SCEV *SrcConst = Src->getStart();
+ const SCEV *DstConst = Dst->getStart();
+ const Loop *CurSrcLoop = Src->getLoop();
+ assert(Coeff == Dst->getStepRecurrence(*SE) &&
+ "Strong SIV requires identical coefficients");
LLVM_DEBUG(dbgs() << "\tStrong SIV test\n");
LLVM_DEBUG(dbgs() << "\t Coeff = " << *Coeff);
LLVM_DEBUG(dbgs() << ", " << *Coeff->getType() << "\n");
@@ -1178,38 +1188,52 @@ bool DependenceInfo::strongSIVtest(const SCEV *Coeff, const SCEV *SrcConst,
assert(0 < Level && Level <= CommonLevels && "level out of range");
Level--;
- const SCEV *Delta = minusSCEVNoSignedOverflow(SrcConst, DstConst, *SE);
- if (!Delta) {
- Result.Consistent = false;
- return false;
- }
- LLVM_DEBUG(dbgs() << "\t Delta = " << *Delta);
- LLVM_DEBUG(dbgs() << ", " << *Delta->getType() << "\n");
-
- // check that |Delta| < iteration count
- bool IsDeltaLarge = [&] {
- const SCEV *UpperBound = collectUpperBound(CurSrcLoop, Delta->getType());
- if (!UpperBound)
+ // Check max(Src) < min(Dst) || max(Dst) < min(Src).
+ bool CheckByRange = [&]() {
+ if (!isMonotonicPair(Src, Dst, SCEVMonotonicityDomain::EntireDomain,
+ CurSrcLoop->getOutermostLoop()))
return false;
- LLVM_DEBUG(dbgs() << "\t UpperBound = " << *UpperBound);
- LLVM_DEBUG(dbgs() << ", " << *UpperBound->getType() << "\n");
- const SCEV *AbsDelta = absSCEVNoSignedOverflow(Delta, *SE);
- const SCEV *AbsCoeff = absSCEVNoSignedOverflow(Coeff, *SE);
- if (!AbsDelta || !AbsCoeff)
- return false;
- const SCEV *Product = mulSCEVNoSignedOverflow(UpperBound, AbsCoeff, *SE);
- if (!Product)
- return false;
- return isKnownPredicate(CmpInst::ICMP_SGT, AbsDelta, Product);
+ const SCEV *BTC = collectUpperBound(CurSrcLoop, Src->getType());
+ assert(BTC && "Must have upper bound for monotonicity over EntireDomain");
+ const auto [SrcFirst, SrcLast] = evaluateFirstAndLast(*SE, Src, BTC);
+ const auto [DstFirst, DstLast] = evaluateFirstAndLast(*SE, Dst, BTC);
+
+ // 0 <= a, so SrcFirst <= SrcLast and DstFirst <= DstLast
+ if (SE->isKnownNonNegative(Coeff))
+ return SE->isKnownPredicate(ICmpInst::ICMP_SLT, SrcLast, DstFirst) ||
+ SE->isKnownPredicate(ICmpInst::ICMP_SLT, DstLast, SrcFirst);
+
+ // a <= 0, so SrcLast <= SrcFirst and DstLast <= DstFirst
+ if (SE->isKnownNonPositive(Coeff))
+ return SE->isKnownPredicate(ICmpInst::ICMP_SLT, SrcFirst, DstLast) ||
+ SE->isKnownPredicate(ICmpInst::ICMP_SLT, DstFirst, SrcLast);
+
+ return SE->isKnownPredicate(ICmpInst::ICMP_SLT,
+ SE->getSMaxExpr(SrcFirst, SrcLast),
+ SE->getSMinExpr(DstFirst, DstLast)) ||
+ SE->isKnownPredicate(ICmpInst::ICMP_SLT,
+ SE->getSMaxExpr(DstFirst, DstLast),
+ SE->getSMinExpr(SrcFirst, SrcLast));
}();
- if (IsDeltaLarge) {
+ if (CheckByRange) {
// Distance greater than trip count - no dependence
++StrongSIVindependence;
++StrongSIVsuccesses;
return true;
}
+ if (!isMonotonicPair(Src, Dst, SCEVMonotonicityDomain::EffectiveDomain,
+ CurSrcLoop->getOutermostLoop()))
+ return false;
+ const SCEV *Delta = minusSCEVNoSignedOverflow(SrcConst, DstConst, *SE);
+ if (!Delta) {
+ Result.Consistent = false;
+ return false;
+ }
+ LLVM_DEBUG(dbgs() << "\t Delta = " << *Delta);
+ LLVM_DEBUG(dbgs() << ", " << *Delta->getType() << "\n");
+
// Can we compute distance?
if (isa<SCEVConstant>(Delta) && isa<SCEVConstant>(Coeff)) {
APInt ConstDelta = cast<SCEVConstant>(Delta)->getAPInt();
@@ -2239,9 +2263,8 @@ 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, UnderRuntimeAssumptions);
+ disproven = strongSIVtest(SrcAddRec, DstAddRec, Level, Result,
+ UnderRuntimeAssumptions);
else if (SrcCoeff == SE->getNegativeSCEV(DstCoeff))
disproven = weakCrossingSIVtest(SrcCoeff, SrcConst, DstConst, CurSrcLoop,
CurDstLoop, Level, Result);
diff --git a/llvm/test/Analysis/DependenceAnalysis/BasePtrBug.ll b/llvm/test/Analysis/DependenceAnalysis/BasePtrBug.ll
index 81e461a5e092d..18544005cbb00 100644
--- a/llvm/test/Analysis/DependenceAnalysis/BasePtrBug.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/BasePtrBug.ll
@@ -18,11 +18,11 @@ define void @test1(ptr nocapture %A, ptr nocapture %B, i32 %N) #0 {
; CHECK-NEXT: Src: %0 = load i32, ptr %gep.0, align 4 --> Dst: %0 = load i32, ptr %gep.0, align 4
; CHECK-NEXT: da analyze - none!
; CHECK-NEXT: Src: %0 = load i32, ptr %gep.0, align 4 --> Dst: %1 = load i32, ptr %gep.1, align 4
-; CHECK-NEXT: da analyze - input [*|<]!
+; CHECK-NEXT: da analyze - consistent input [*|<]!
; CHECK-NEXT: Src: %0 = load i32, ptr %gep.0, align 4 --> Dst: store i32 %add, ptr %gep.B, align 4
; CHECK-NEXT: da analyze - confused!
; CHECK-NEXT: Src: %1 = load i32, ptr %gep.1, align 4 --> Dst: %1 = load i32, ptr %gep.1, align 4
-; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - consistent input [*]!
; CHECK-NEXT: Src: %1 = load i32, ptr %gep.1, align 4 --> Dst: store i32 %add, ptr %gep.B, align 4
; CHECK-NEXT: da analyze - confused!
; CHECK-NEXT: Src: store i32 %add, ptr %gep.B, align 4 --> Dst: store i32 %add, ptr %gep.B, align 4
diff --git a/llvm/test/Analysis/DependenceAnalysis/DADelin.ll b/llvm/test/Analysis/DependenceAnalysis/DADelin.ll
index 429e37de0a453..919a18b2fe976 100644
--- a/llvm/test/Analysis/DependenceAnalysis/DADelin.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/DADelin.ll
@@ -646,15 +646,11 @@ 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 - consistent output [0]!
-; CHECK-NEXT: Runtime Assumptions:
-; CHECK-NEXT: Compare predicate: %k ne) 0
+; CHECK-NEXT: da analyze - consistent output [*]!
; 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: da analyze - consistent 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 - consistent output [0]!
-; CHECK-NEXT: Runtime Assumptions:
-; CHECK-NEXT: Compare predicate: %k ne) 0
+; CHECK-NEXT: da analyze - consistent output [*]!
;
entry:
br label %loop
@@ -689,15 +685,11 @@ 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 - consistent output [0]!
-; CHECK-NEXT: Runtime Assumptions:
-; CHECK-NEXT: Compare predicate: %k ne) 0
+; CHECK-NEXT: da analyze - consistent output [*]!
; 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: da analyze - consistent 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 - consistent output [0]!
-; CHECK-NEXT: Runtime Assumptions:
-; CHECK-NEXT: Compare predicate: %k ne) 0
+; CHECK-NEXT: da analyze - consistent output [*]!
;
entry:
br label %loop
diff --git a/llvm/test/Analysis/DependenceAnalysis/MIVCheckConst.ll b/llvm/test/Analysis/DependenceAnalysis/MIVCheckConst.ll
index d91a916d785c2..64f75dcf1522e 100644
--- a/llvm/test/Analysis/DependenceAnalysis/MIVCheckConst.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/MIVCheckConst.ll
@@ -39,18 +39,17 @@ define void @test(ptr %A, ptr %B, i1 %arg, i32 %n, i32 %m) align 2 {
; CHECK-NEXT: Src: %v1 = load i32, ptr %B, align 4 --> Dst: %v32 = load <32 x i32>, ptr %v30, align 128
; CHECK-NEXT: da analyze - confused!
; CHECK-NEXT: Src: %v27 = load <32 x i32>, ptr %v25, align 256 --> Dst: %v27 = load <32 x i32>, ptr %v25, align 256
-; CHECK-NEXT: da analyze - consistent input [0 S S]!
+; CHECK-NEXT: da analyze - consistent input [* S S]!
; 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:
; 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: Src: %v32 = load <32 x i32>, ptr %v30, align 128 --> Dst: %v32 = load <32 x i32>, ptr %v30, align 128
-; CHECK-NEXT: da analyze - consistent input [0 S S]!
+; CHECK-NEXT: da analyze - consistent input [* S S]!
;
entry:
%v1 = load i32, ptr %B, align 4
diff --git a/llvm/test/Analysis/DependenceAnalysis/NonCanonicalizedSubscript.ll b/llvm/test/Analysis/DependenceAnalysis/NonCanonicalizedSubscript.ll
index 0cee9aa90236a..1db0d4170ee09 100644
--- a/llvm/test/Analysis/DependenceAnalysis/NonCanonicalizedSubscript.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/NonCanonicalizedSubscript.ll
@@ -61,7 +61,7 @@ define void @coupled_miv_type_mismatch(i32 %n) {
; CHECK-NEXT: Src: %2 = load i32, ptr %arrayidx5, align 4 --> Dst: store i32 %add6, ptr %arrayidx10, align 4
; CHECK-NEXT: da analyze - anti [< >]!
; CHECK-NEXT: Src: store i32 %add6, ptr %arrayidx10, align 4 --> Dst: store i32 %add6, ptr %arrayidx10, align 4
-; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - consistent output [0 *]!
;
entry:
br label %for.cond
diff --git a/llvm/test/Analysis/DependenceAnalysis/Preliminary.ll b/llvm/test/Analysis/DependenceAnalysis/Preliminary.ll
index 8cb0e2ac770dc..de525d7c0cd2f 100644
--- a/llvm/test/Analysis/DependenceAnalysis/Preliminary.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/Preliminary.ll
@@ -448,7 +448,7 @@ define void @p4(ptr %A, ptr %B, i64 %n) nounwind uwtable ssp {
; CHECK-NEXT: Src: %0 = load i32, ptr %arrayidx5, 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
-; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - consistent output [*]!
;
entry:
%cmp1 = icmp sgt i64 %n, 0
@@ -501,7 +501,7 @@ define void @p5(ptr %A, ptr %B, i64 %n) nounwind uwtable ssp {
; CHECK-NEXT: Src: %0 = load i32, ptr %arrayidx5, 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
-; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - consistent output [*]!
;
entry:
%cmp1 = icmp sgt i64 %n, 0
@@ -727,11 +727,11 @@ entry:
define void @foo(ptr %s, i32 %size) nounwind uwtable ssp {
; CHECK-LABEL: 'foo'
; CHECK-NEXT: Src: %1 = load i32, ptr %0, align 4 --> Dst: %1 = load i32, ptr %0, align 4
-; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - consistent input [*]!
; CHECK-NEXT: Src: %1 = load i32, ptr %0, align 4 --> Dst: store i32 %1, ptr %i.02, align 4
-; CHECK-NEXT: da analyze - consistent anti [1]!
+; CHECK-NEXT: da analyze - consistent anti [*|<]!
; CHECK-NEXT: Src: store i32 %1, ptr %i.02, align 4 --> Dst: store i32 %1, ptr %i.02, align 4
-; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - consistent output [*]!
;
entry:
%idx.ext = zext i32 %size to i64
diff --git a/llvm/test/Analysis/DependenceAnalysis/PreliminaryNoValidityCheckFixedSize.ll b/llvm/test/Analysis/DependenceAnalysis/PreliminaryNoValidityCheckFixedSize.ll
index 8cd29e691a7ef..0cf2f8049f2a0 100644
--- a/llvm/test/Analysis/DependenceAnalysis/PreliminaryNoValidityCheckFixedSize.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/PreliminaryNoValidityCheckFixedSize.ll
@@ -20,11 +20,11 @@ define void @p2(i64 %n, ptr %A, ptr %B) nounwind uwtable ssp {
; CHECK-NEXT: Src: store i64 %i.011, ptr %arrayidx8, align 8 --> Dst: store i64 %i.011, ptr %arrayidx8, align 8
; CHECK-NEXT: da analyze - none!
; CHECK-NEXT: Src: store i64 %i.011, ptr %arrayidx8, align 8 --> Dst: %0 = load i64, ptr %arrayidx17, align 8
-; CHECK-NEXT: da analyze - flow [-3 -2] / assuming 1 loop level(s) fused: [-3 -2 -1]!
+; CHECK-NEXT: da analyze - flow [* *|<] / assuming 1 loop level(s) fused: [* * -1|<]!
; CHECK-NEXT: Src: store i64 %i.011, ptr %arrayidx8, align 8 --> Dst: store i64 %0, ptr %B.addr.24, align 8
; CHECK-NEXT: da analyze - confused!
; CHECK-NEXT: Src: %0 = load i64, ptr %arrayidx17, align 8 --> Dst: %0 = load i64, ptr %arrayidx17, align 8
-; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - consistent input [* * 0]!
; CHECK-NEXT: Src: %0 = load i64, ptr %arrayidx17, align 8 --> Dst: store i64 %0, ptr %B.addr.24, align 8
; CHECK-NEXT: da analyze - confused!
; CHECK-NEXT: Src: store i64 %0, ptr %B.addr.24, align 8 --> Dst: store i64 %0, ptr %B.addr.24, align 8
diff --git a/llvm/test/Analysis/DependenceAnalysis/SimpleSIVNoValidityCheck.ll b/llvm/test/Analysis/DependenceAnalysis/SimpleSIVNoValidityCheck.ll
index 181a4494b036e..b04a206255f90 100644
--- a/llvm/test/Analysis/DependenceAnalysis/SimpleSIVNoValidityCheck.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/SimpleSIVNoValidityCheck.ll
@@ -78,11 +78,11 @@ for.end14: ; preds = %entry, %for.inc12
define void @t2(i32 signext %n, i32 signext %m, ptr %a) {
; CHECK-LABEL: 't2'
; CHECK-NEXT: Src: %21 = load i32, ptr %arrayidx28, align 4 --> Dst: %21 = load i32, ptr %arrayidx28, align 4
-; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - consistent input [0 0 0 * 0]!
; CHECK-NEXT: Src: %21 = load i32, ptr %arrayidx28, align 4 --> Dst: store i32 %21, ptr %arrayidx38, align 4
-; CHECK-NEXT: da analyze - consistent anti [1 -2 0 -3 2]!
+; CHECK-NEXT: da analyze - consistent anti [1 -2 0 * 2]!
; CHECK-NEXT: Src: store i32 %21, ptr %arrayidx38, align 4 --> Dst: store i32 %21, ptr %arrayidx38, align 4
-; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - consistent output [0 0 0 * 0]!
;
; LIN-LABEL: 't2'
; LIN-NEXT: Src: %21 = load i32, ptr %arrayidx28, align 4 --> Dst: %21 = load i32, ptr %arrayidx28, align 4
@@ -208,11 +208,11 @@ for.end50: ; preds = %entry, %for.inc48
define void @t3(i64 %n, i64 %m, i64 %lb, ptr %a) {
; CHECK-LABEL: 't3'
; CHECK-NEXT: Src: %2 = load i32, ptr %arrayidx6, align 4 --> Dst: %2 = load i32, ptr %arrayidx6, align 4
-; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - consistent input [* *]!
; CHECK-NEXT: Src: %2 = load i32, ptr %arrayidx6, align 4 --> Dst: store i32 %2, ptr %arrayidx8, align 4
-; CHECK-NEXT: da analyze - anti [1 *]!
+; CHECK-NEXT: da analyze - consistent anti [* *|<]!
; CHECK-NEXT: Src: store i32 %2, ptr %arrayidx8, align 4 --> Dst: store i32 %2, ptr %arrayidx8, align 4
-; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - consistent output [* *]!
;
; LIN-LABEL: 't3'
; LIN-NEXT: Src: %2 = load i32, ptr %arrayidx6, align 4 --> Dst: %2 = load i32, ptr %arrayidx6, align 4
diff --git a/llvm/test/Analysis/DependenceAnalysis/StrongSIV.ll b/llvm/test/Analysis/DependenceAnalysis/StrongSIV.ll
index 02fbaf2910c70..c591f15751536 100644
--- a/llvm/test/Analysis/DependenceAnalysis/StrongSIV.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/StrongSIV.ll
@@ -114,17 +114,17 @@ for.end: ; preds = %for.end.loopexit, %
define void @strong2(ptr %A, ptr %B, i64 %n) nounwind uwtable ssp {
; CHECK-LABEL: 'strong2'
; 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 [*]!
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx1, align 4
-; CHECK-NEXT: da analyze - consistent flow [2]!
+; CHECK-NEXT: da analyze - consistent 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 %arrayidx1, align 4 --> Dst: %0 = load i32, ptr %arrayidx1, align 4
-; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - consistent input [*]!
; 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
-; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - consistent output [*]!
;
entry:
%cmp1 = icmp eq i64 %n, 0
@@ -385,9 +385,9 @@ for.end: ; preds = %for.body
define void @strong8(ptr %A, ptr %B, i64 %n) nounwind uwtable ssp {
; CHECK-LABEL: 'strong8'
; 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 [*]!
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx1, align 4
-; CHECK-NEXT: da analyze - flow [*|<]!
+; CHECK-NEXT: da analyze - consistent flow [*|<]!
; 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 %arrayidx1, align 4 --> Dst: %0 = load i32, ptr %arrayidx1, align 4
@@ -427,31 +427,31 @@ for.end: ; preds = %for.body
define void @strong9(ptr %A, ptr %B, i64 %n) nounwind uwtable ssp {
; CHECK-ALL-LABEL: 'strong9'
; CHECK-ALL-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %conv, ptr %arrayidx, align 4
-; CHECK-ALL-NEXT: da analyze - none!
+; CHECK-ALL-NEXT: da analyze - consistent output [*]!
; CHECK-ALL-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx2, align 4
; CHECK-ALL-NEXT: da analyze - none!
; CHECK-ALL-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %0, ptr %B.addr.02, align 4
; CHECK-ALL-NEXT: da analyze - confused!
; CHECK-ALL-NEXT: Src: %0 = load i32, ptr %arrayidx2, align 4 --> Dst: %0 = load i32, ptr %arrayidx2, align 4
-; CHECK-ALL-NEXT: da analyze - none!
+; CHECK-ALL-NEXT: da analyze - consistent input [*]!
; CHECK-ALL-NEXT: Src: %0 = load i32, ptr %arrayidx2, align 4 --> Dst: store i32 %0, ptr %B.addr.02, align 4
; CHECK-ALL-NEXT: da analyze - confused!
; CHECK-ALL-NEXT: Src: store i32 %0, ptr %B.addr.02, align 4 --> Dst: store i32 %0, ptr %B.addr.02, align 4
-; CHECK-ALL-NEXT: da analyze - none!
+; CHECK-ALL-NEXT: da analyze - consistent output [*]!
;
; CHECK-STRONG-SIV-LABEL: 'strong9'
; CHECK-STRONG-SIV-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %conv, ptr %arrayidx, align 4
-; CHECK-STRONG-SIV-NEXT: da analyze - none!
+; CHECK-STRONG-SIV-NEXT: da analyze - consistent output [*]!
; CHECK-STRONG-SIV-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx2, align 4
-; CHECK-STRONG-SIV-NEXT: da analyze - flow [*|<]!
+; CHECK-STRONG-SIV-NEXT: da analyze - consistent flow [*|<]!
; CHECK-STRONG-SIV-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %0, ptr %B.addr.02, align 4
; CHECK-STRONG-SIV-NEXT: da analyze - confused!
; CHECK-STRONG-SIV-NEXT: Src: %0 = load i32, ptr %arrayidx2, align 4 --> Dst: %0 = load i32, ptr %arrayidx2, align 4
-; CHECK-STRONG-SIV-NEXT: da analyze - none!
+; CHECK-STRONG-SIV-NEXT: da analyze - consistent input [*]!
; CHECK-STRONG-SIV-NEXT: Src: %0 = load i32, ptr %arrayidx2, align 4 --> Dst: store i32 %0, ptr %B.addr.02, align 4
; CHECK-STRONG-SIV-NEXT: da analyze - confused!
; CHECK-STRONG-SIV-NEXT: Src: store i32 %0, ptr %B.addr.02, align 4 --> Dst: store i32 %0, ptr %B.addr.02, align 4
-; CHECK-STRONG-SIV-NEXT: da analyze - none!
+; CHECK-STRONG-SIV-NEXT: da analyze - consistent output [*]!
;
entry:
%cmp1 = icmp eq i64 %n, 0
@@ -492,19 +492,13 @@ 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 - consistent output [0]!
-; CHECK-NEXT: Runtime Assumptions:
-; CHECK-NEXT: Compare predicate: (4 * %n) ne) 0
+; CHECK-NEXT: da analyze - consistent output [*]!
; 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: da analyze - consistent flow [*|<]!
; 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 - consistent input [0]!
-; CHECK-NEXT: Runtime Assumptions:
-; CHECK-NEXT: Compare predicate: (4 * %n) ne) 0
+; CHECK-NEXT: da analyze - consistent input [*]!
; 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
@@ -548,7 +542,7 @@ define void @strong11(ptr %A) nounwind uwtable ssp {
;
; CHECK-STRONG-SIV-LABEL: 'strong11'
; CHECK-STRONG-SIV-NEXT: Src: store i32 0, ptr %arrayidx, align 4 --> Dst: store i32 0, ptr %arrayidx, align 4
-; CHECK-STRONG-SIV-NEXT: da analyze - consistent output [0 S]!
+; CHECK-STRONG-SIV-NEXT: da analyze - consistent output [* S]!
;
entry:
br label %for.cond1.preheader
diff --git a/llvm/test/Analysis/DependenceAnalysis/SymbolicRDIV.ll b/llvm/test/Analysis/DependenceAnalysis/SymbolicRDIV.ll
index 8b9aa257a7c57..4f495122d1bcd 100644
--- a/llvm/test/Analysis/DependenceAnalysis/SymbolicRDIV.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/SymbolicRDIV.ll
@@ -15,17 +15,17 @@ target triple = "x86_64-apple-macosx10.6.0"
define void @symbolicrdiv0(ptr %A, ptr %B, i64 %n1, i64 %n2) nounwind uwtable ssp {
; CHECK-LABEL: 'symbolicrdiv0'
; 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 [*]!
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx8, align 4
; CHECK-NEXT: da analyze - none!
; 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 %arrayidx8, align 4 --> Dst: %0 = load i32, ptr %arrayidx8, align 4
-; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - consistent input [*]!
; CHECK-NEXT: Src: %0 = load i32, ptr %arrayidx8, 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
-; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - consistent output [*]!
;
entry:
%cmp4 = icmp eq i64 %n1, 0
@@ -84,17 +84,17 @@ for.end11: ; preds = %for.end11.loopexit,
define void @symbolicrdiv1(ptr %A, ptr %B, i64 %n1, i64 %n2) nounwind uwtable ssp {
; CHECK-LABEL: 'symbolicrdiv1'
; 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 [*]!
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx9, align 4
; CHECK-NEXT: da analyze - none!
; 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 %arrayidx9, align 4 --> Dst: %0 = load i32, ptr %arrayidx9, align 4
-; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - consistent input [*]!
; CHECK-NEXT: Src: %0 = load i32, ptr %arrayidx9, 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
-; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - consistent output [*]!
;
entry:
%cmp4 = icmp eq i64 %n1, 0
@@ -155,17 +155,17 @@ for.end12: ; preds = %for.end12.loopexit,
define void @symbolicrdiv2(ptr %A, ptr %B, i64 %n1, i64 %n2) nounwind uwtable ssp {
; CHECK-LABEL: 'symbolicrdiv2'
; 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 [*]!
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx7, align 4
; CHECK-NEXT: da analyze - none!
; 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 [*]!
; 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
-; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - consistent output [*]!
;
entry:
%cmp4 = icmp eq i64 %n1, 0
@@ -224,17 +224,17 @@ for.end10: ; preds = %for.end10.loopexit,
define void @symbolicrdiv3(ptr %A, ptr %B, i64 %n1, i64 %n2) nounwind uwtable ssp {
; CHECK-LABEL: 'symbolicrdiv3'
; 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 [*]!
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx6, align 4
; CHECK-NEXT: da analyze - none!
; 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 %arrayidx6, align 4 --> Dst: %0 = load i32, ptr %arrayidx6, align 4
-; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - consistent input [*]!
; CHECK-NEXT: Src: %0 = load i32, ptr %arrayidx6, 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
-; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - consistent output [*]!
;
entry:
%cmp4 = icmp eq i64 %n1, 0
@@ -291,17 +291,17 @@ for.end9: ; preds = %for.end9.loopexit,
define void @symbolicrdiv4(ptr %A, ptr %B, i64 %n1, i64 %n2) nounwind uwtable ssp {
; CHECK-LABEL: 'symbolicrdiv4'
; 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 [*]!
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx7, align 4
; CHECK-NEXT: da analyze - none!
; 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 [*]!
; 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
-; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - consistent output [*]!
;
entry:
%cmp4 = icmp eq i64 %n1, 0
@@ -359,17 +359,17 @@ for.end10: ; preds = %for.end10.loopexit,
define void @symbolicrdiv5(ptr %A, ptr %B, i64 %n1, i64 %n2) nounwind uwtable ssp {
; CHECK-LABEL: 'symbolicrdiv5'
; 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 [*]!
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx7, align 4
; CHECK-NEXT: da analyze - none!
; 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 [*]!
; 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
-; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - consistent output [*]!
;
entry:
%cmp4 = icmp eq i64 %n1, 0
diff --git a/llvm/test/Analysis/DependenceAnalysis/SymbolicSIV.ll b/llvm/test/Analysis/DependenceAnalysis/SymbolicSIV.ll
index a33a10b5e1c2d..ac2290bc5a8db 100644
--- a/llvm/test/Analysis/DependenceAnalysis/SymbolicSIV.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/SymbolicSIV.ll
@@ -13,17 +13,17 @@ target triple = "x86_64-apple-macosx10.6.0"
define void @symbolicsiv0(ptr %A, ptr %B, i64 %n) nounwind uwtable ssp {
; CHECK-LABEL: 'symbolicsiv0'
; 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 [*]!
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx4, align 4
; CHECK-NEXT: da analyze - none!
; 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 %arrayidx4, align 4 --> Dst: %0 = load i32, ptr %arrayidx4, align 4
-; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - consistent input [*]!
; CHECK-NEXT: Src: %0 = load i32, ptr %arrayidx4, 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
-; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - consistent output [*]!
;
entry:
%cmp1 = icmp eq i64 %n, 0
@@ -65,17 +65,17 @@ for.end: ; preds = %for.end.loopexit, %
define void @symbolicsiv1(ptr %A, ptr %B, i64 %n) nounwind uwtable ssp {
; CHECK-LABEL: 'symbolicsiv1'
; 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 [*]!
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx5, align 4
; CHECK-NEXT: da analyze - none!
; 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 %arrayidx5, align 4 --> Dst: %0 = load i32, ptr %arrayidx5, align 4
-; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - consistent input [*]!
; CHECK-NEXT: Src: %0 = load i32, ptr %arrayidx5, 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
-; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - consistent output [*]!
;
entry:
%cmp1 = icmp eq i64 %n, 0
@@ -119,17 +119,17 @@ for.end: ; preds = %for.end.loopexit, %
define void @symbolicsiv2(ptr %A, ptr %B, i64 %n) nounwind uwtable ssp {
; CHECK-LABEL: 'symbolicsiv2'
; 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 [*]!
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx3, align 4
; CHECK-NEXT: da analyze - none!
; 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 %arrayidx3, align 4 --> Dst: %0 = load i32, ptr %arrayidx3, align 4
-; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - consistent input [*]!
; CHECK-NEXT: Src: %0 = load i32, ptr %arrayidx3, 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
-; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - consistent output [*]!
;
entry:
%cmp1 = icmp eq i64 %n, 0
@@ -171,17 +171,17 @@ for.end: ; preds = %for.end.loopexit, %
define void @symbolicsiv3(ptr %A, ptr %B, i64 %n) nounwind uwtable ssp {
; CHECK-LABEL: 'symbolicsiv3'
; 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 [*]!
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx3, align 4
; CHECK-NEXT: da analyze - none!
; 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 %arrayidx3, align 4 --> Dst: %0 = load i32, ptr %arrayidx3, align 4
-; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - consistent input [*]!
; CHECK-NEXT: Src: %0 = load i32, ptr %arrayidx3, 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
-; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - consistent output [*]!
;
entry:
%cmp1 = icmp eq i64 %n, 0
@@ -224,17 +224,17 @@ for.end: ; preds = %for.end.loopexit, %
define void @symbolicsiv4(ptr %A, ptr %B, i64 %n) nounwind uwtable ssp {
; CHECK-LABEL: 'symbolicsiv4'
; 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 [*]!
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx3, align 4
; CHECK-NEXT: da analyze - none!
; 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 %arrayidx3, align 4 --> Dst: %0 = load i32, ptr %arrayidx3, align 4
-; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - consistent input [*]!
; CHECK-NEXT: Src: %0 = load i32, ptr %arrayidx3, 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
-; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - consistent output [*]!
;
entry:
%cmp1 = icmp eq i64 %n, 0
@@ -276,17 +276,17 @@ for.end: ; preds = %for.end.loopexit, %
define void @symbolicsiv5(ptr %A, ptr %B, i64 %n) nounwind uwtable ssp {
; CHECK-LABEL: 'symbolicsiv5'
; 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 [*]!
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx4, align 4
; CHECK-NEXT: da analyze - none!
; 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 %arrayidx4, align 4 --> Dst: %0 = load i32, ptr %arrayidx4, align 4
-; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - consistent input [*]!
; CHECK-NEXT: Src: %0 = load i32, ptr %arrayidx4, 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
-; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - consistent output [*]!
;
entry:
%cmp1 = icmp eq i64 %n, 0
@@ -330,17 +330,17 @@ for.end: ; preds = %for.end.loopexit, %
define void @weaktest(ptr %A, ptr %B, i64 %n) nounwind uwtable ssp {
; CHECK-LABEL: 'weaktest'
; 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 [*]!
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx2, 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 %arrayidx2, align 4 --> Dst: %0 = load i32, ptr %arrayidx2, align 4
-; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - consistent input [*]!
; 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
-; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - consistent output [*]!
;
entry:
%cmp1 = icmp eq i64 %n, 0
@@ -381,21 +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 - consistent output [0]!
-; CHECK-NEXT: Runtime Assumptions:
-; CHECK-NEXT: Compare predicate: (16 * %N) ne) 0
+; CHECK-NEXT: da analyze - consistent output [*]!
; 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: da analyze - consistent 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 - consistent input [0]!
-; CHECK-NEXT: Runtime Assumptions:
-; CHECK-NEXT: Compare predicate: (16 * %N) ne) 0
+; CHECK-NEXT: da analyze - consistent input [*]!
; 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
-; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - consistent output [*]!
;
entry:
%cmp1 = icmp eq i64 %n, 0
@@ -441,21 +437,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 - consistent output [0]!
-; CHECK-NEXT: Runtime Assumptions:
-; CHECK-NEXT: Compare predicate: (8 * %N) ne) 0
+; CHECK-NEXT: da analyze - consistent output [*]!
; 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: da analyze - consistent 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 - consistent input [0]!
-; CHECK-NEXT: Runtime Assumptions:
-; CHECK-NEXT: Compare predicate: (8 * %N) ne) 0
+; CHECK-NEXT: da analyze - consistent input [*]!
; 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
-; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - consistent output [*]!
;
entry:
%cmp1 = icmp eq i64 %n, 0
diff --git a/llvm/test/Analysis/DependenceAnalysis/WeakCrossingSIV.ll b/llvm/test/Analysis/DependenceAnalysis/WeakCrossingSIV.ll
index c7accfd46a4d7..b7657339fb5fe 100644
--- a/llvm/test/Analysis/DependenceAnalysis/WeakCrossingSIV.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/WeakCrossingSIV.ll
@@ -14,21 +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 - consistent output [0]!
-; CHECK-NEXT: Runtime Assumptions:
-; CHECK-NEXT: Compare predicate: (4 * %n) ne) 0
+; CHECK-NEXT: da analyze - consistent output [*]!
; 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 - consistent input [0]!
-; CHECK-NEXT: Runtime Assumptions:
-; CHECK-NEXT: Compare predicate: (-4 * %n) ne) 0
+; CHECK-NEXT: da analyze - consistent input [*]!
; 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
-; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - consistent output [*]!
;
entry:
%cmp1 = icmp eq i64 %n, 0
@@ -70,17 +66,17 @@ for.end: ; preds = %for.end.loopexit, %
define void @weakcrossing1(ptr %A, ptr %B, i64 %n) nounwind uwtable ssp {
; CHECK-LABEL: 'weakcrossing1'
; 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 [*]!
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx2, 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 %arrayidx2, align 4 --> Dst: %0 = load i32, ptr %arrayidx2, align 4
-; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - consistent input [*]!
; 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
-; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - consistent output [*]!
;
entry:
%cmp1 = icmp eq i64 %n, 0
@@ -247,17 +243,17 @@ for.end: ; preds = %for.body
define void @weakcrossing5(ptr %A, ptr %B, i64 %n) nounwind uwtable ssp {
; CHECK-LABEL: 'weakcrossing5'
; 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 [*]!
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %1 = load i32, ptr %arrayidx2, align 4
; CHECK-NEXT: da analyze - none!
; 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 %arrayidx2, align 4 --> Dst: %1 = load i32, ptr %arrayidx2, align 4
-; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - consistent input [*]!
; CHECK-NEXT: Src: %1 = load i32, ptr %arrayidx2, 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
-; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - consistent output [*]!
;
entry:
%cmp1 = icmp eq i64 %n, 0
diff --git a/llvm/test/Analysis/DependenceAnalysis/WeakZeroDstSIV.ll b/llvm/test/Analysis/DependenceAnalysis/WeakZeroDstSIV.ll
index f8a045c425029..51d21c21fb57a 100644
--- a/llvm/test/Analysis/DependenceAnalysis/WeakZeroDstSIV.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/WeakZeroDstSIV.ll
@@ -90,9 +90,7 @@ 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 - consistent output [0]!
-; CHECK-NEXT: Runtime Assumptions:
-; CHECK-NEXT: Compare predicate: (4 * %n) ne) 0
+; CHECK-NEXT: da analyze - consistent output [*]!
; 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
@@ -102,7 +100,7 @@ define void @weakzerodst1(ptr %A, ptr %B, i64 %n) nounwind uwtable ssp {
; 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
-; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - consistent output [*]!
;
entry:
%cmp1 = icmp eq i64 %n, 0
@@ -310,7 +308,7 @@ for.end: ; preds = %for.body
define void @weakzerodst6(ptr %A, ptr %B, i64 %n) nounwind uwtable ssp {
; CHECK-LABEL: 'weakzerodst6'
; 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 [*]!
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx1, align 4
; CHECK-NEXT: da analyze - none!
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %0, ptr %B.addr.02, align 4
@@ -320,7 +318,7 @@ define void @weakzerodst6(ptr %A, ptr %B, i64 %n) nounwind uwtable ssp {
; 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
-; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - consistent output [*]!
;
entry:
%cmp1 = icmp eq i64 %n, 0
diff --git a/llvm/test/Analysis/DependenceAnalysis/WeakZeroSrcSIV.ll b/llvm/test/Analysis/DependenceAnalysis/WeakZeroSrcSIV.ll
index 4ed0abd8d98a9..4c2e062643e2a 100644
--- a/llvm/test/Analysis/DependenceAnalysis/WeakZeroSrcSIV.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/WeakZeroSrcSIV.ll
@@ -94,13 +94,11 @@ 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 - consistent input [0]!
-; CHECK-NEXT: Runtime Assumptions:
-; CHECK-NEXT: Compare predicate: (4 * %n) ne) 0
+; CHECK-NEXT: da analyze - consistent input [*]!
; 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
-; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - consistent output [*]!
;
entry:
%cmp1 = icmp eq i64 %n, 0
@@ -314,11 +312,11 @@ define void @weakzerosrc6(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 [*]!
; 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
-; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - consistent output [*]!
;
entry:
%cmp1 = icmp eq i64 %n, 0
diff --git a/llvm/test/Analysis/DependenceAnalysis/becount-couldnotcompute.ll b/llvm/test/Analysis/DependenceAnalysis/becount-couldnotcompute.ll
index 1674badd4d6b9..5672e2c7b7c8b 100644
--- a/llvm/test/Analysis/DependenceAnalysis/becount-couldnotcompute.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/becount-couldnotcompute.ll
@@ -7,9 +7,7 @@
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 - consistent input [0]!
-; CHECK-NEXT: Runtime Assumptions:
-; CHECK-NEXT: Compare predicate: (4 + (4 * %conv)) ne) 0
+; CHECK-NEXT: da analyze - consistent input [*]!
;
entry:
%sub = add i64 %conv, 1
diff --git a/llvm/test/Analysis/DependenceAnalysis/monotonicity-cast.ll b/llvm/test/Analysis/DependenceAnalysis/monotonicity-cast.ll
index 57280a99932ce..c7405cda0e2a2 100644
--- a/llvm/test/Analysis/DependenceAnalysis/monotonicity-cast.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/monotonicity-cast.ll
@@ -57,9 +57,7 @@ define void @sext_may_wrap(ptr %a, i8 %start, i8 %step) {
; CHECK-NEXT: Reason: (sext i8 {%start,+,%step}<%loop> to i64)
; CHECK-EMPTY:
; CHECK-NEXT: Src: store i8 0, ptr %idx, align 1 --> Dst: store i8 0, ptr %idx, align 1
-; CHECK-NEXT: da analyze - consistent output [0]!
-; CHECK-NEXT: Runtime Assumptions:
-; CHECK-NEXT: Compare predicate: %step ne) 0
+; CHECK-NEXT: da analyze - consistent output [*]!
;
entry:
br label %loop
diff --git a/llvm/test/Analysis/DependenceAnalysis/monotonicity-no-wrap-flags.ll b/llvm/test/Analysis/DependenceAnalysis/monotonicity-no-wrap-flags.ll
index 2572bdb36880a..c89188c8d6412 100644
--- a/llvm/test/Analysis/DependenceAnalysis/monotonicity-no-wrap-flags.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/monotonicity-no-wrap-flags.ll
@@ -52,7 +52,7 @@ define void @single_loop_nuw(ptr %a, i64 %begin, i64 %end) {
; CHECK-NEXT: Reason: {%begin,+,1}<nuw><%loop>
; 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 [*]!
;
entry:
%guard = icmp ult i64 %begin, %end
>From e54ced2335bf69193557205f710dade3a831ca43 Mon Sep 17 00:00:00 2001
From: Ryotaro Kasuga <kasuga.ryotaro at fujitsu.com>
Date: Thu, 4 Dec 2025 13:22:55 +0000
Subject: [PATCH 5/5] apply monotonicity check for symbolic rdiv
---
.../llvm/Analysis/DependenceAnalysis.h | 4 +-
llvm/lib/Analysis/DependenceAnalysis.cpp | 147 +++++-------------
.../Analysis/DependenceAnalysis/StrongSIV.ll | 53 +++----
.../DependenceAnalysis/SymbolicRDIV.ll | 14 +-
.../DependenceAnalysis/SymbolicSIV.ll | 12 +-
.../DependenceAnalysis/exact-siv-overflow.ll | 2 +-
.../DependenceAnalysis/gcd-miv-overflow.ll | 2 +-
.../DependenceAnalysis/monotonicity-cast.ll | 2 +-
.../DependenceAnalysis/non-monotonic.ll | 2 +-
.../run-specific-dependence-test.ll | 2 +-
.../DependenceAnalysis/strong-siv-overflow.ll | 25 ++-
.../symbolic-rdiv-overflow.ll | 10 +-
12 files changed, 88 insertions(+), 187 deletions(-)
diff --git a/llvm/include/llvm/Analysis/DependenceAnalysis.h b/llvm/include/llvm/Analysis/DependenceAnalysis.h
index a6a7928418120..9df99b8df9eb6 100644
--- a/llvm/include/llvm/Analysis/DependenceAnalysis.h
+++ b/llvm/include/llvm/Analysis/DependenceAnalysis.h
@@ -849,9 +849,7 @@ class DependenceInfo {
/// Works in some cases that exactRDIVtest doesn't,
/// and vice versa. Can also be used as a backup for
/// ordinary SIV tests.
- bool symbolicRDIVtest(const SCEV *SrcCoeff, const SCEV *DstCoeff,
- const SCEV *SrcConst, const SCEV *DstConst,
- const Loop *SrcLoop, const Loop *DstLoop) const;
+ bool symbolicRDIVtest(const SCEVAddRecExpr *Src, const SCEVAddRecExpr *Dst);
/// gcdMIVtest - Tests an MIV subscript pair for dependence.
/// Returns true if any possible dependence is disproved.
diff --git a/llvm/lib/Analysis/DependenceAnalysis.cpp b/llvm/lib/Analysis/DependenceAnalysis.cpp
index 933a3b9673a12..d7eb344e1cf21 100644
--- a/llvm/lib/Analysis/DependenceAnalysis.cpp
+++ b/llvm/lib/Analysis/DependenceAnalysis.cpp
@@ -2101,136 +2101,64 @@ bool DependenceInfo::exactRDIVtest(const SCEV *SrcCoeff, const SCEV *DstCoeff,
// backup for the RDIV test. Note that i and j can be the same variable,
// letting this test serve as a backup for the various SIV tests.
//
-// For a dependence to exist, c1 + a1*i must equal c2 + a2*j for some
-// 0 <= i <= N1 and some 0 <= j <= N2, where N1 and N2 are the (normalized)
-// loop bounds for the i and j loops, respectively. So, ...
-//
-// c1 + a1*i = c2 + a2*j
-// a1*i - a2*j = c2 - c1
-//
-// To test for a dependence, we compute c2 - c1 and make sure it's in the
-// range of the maximum and minimum possible values of a1*i - a2*j.
-// Considering the signs of a1 and a2, we have 4 possible cases:
+// To test for a dependence, we compare the minimum/maximum values of c1 + a1*i
+// and c2 + a2*j.
+// Considering the signs of a1 and a2, we have 4 possible cases (0 <= i <= N1
+// and 0 <= j <= N2):
//
// 1) If a1 >= 0 and a2 >= 0, then
-// a1*0 - a2*N2 <= c2 - c1 <= a1*N1 - a2*0
-// -a2*N2 <= c2 - c1 <= a1*N1
+// a1*N1 + c1 <= a2*0 + c2 or a2*N2 + c2 <= a1*0 + c1
//
// 2) If a1 >= 0 and a2 <= 0, then
-// a1*0 - a2*0 <= c2 - c1 <= a1*N1 - a2*N2
-// 0 <= c2 - c1 <= a1*N1 - a2*N2
+// a1*N1 + c1 <= a2*N2 + c2 or a2*0 + c2 <= a1*0 + c1
//
// 3) If a1 <= 0 and a2 >= 0, then
-// a1*N1 - a2*N2 <= c2 - c1 <= a1*0 - a2*0
-// a1*N1 - a2*N2 <= c2 - c1 <= 0
+// a1*0 + c1 <= a2*0 + c2 or a2*N2 + c2 <= a1*N1 + c1
//
// 4) If a1 <= 0 and a2 <= 0, then
-// a1*N1 - a2*0 <= c2 - c1 <= a1*0 - a2*N2
-// a1*N1 <= c2 - c1 <= -a2*N2
+// a1*0 + c1 <= a2*N2 + c2 or a2*0 + c2 <= a1*N1 + c1
//
// return true if dependence disproved
-bool DependenceInfo::symbolicRDIVtest(const SCEV *A1, const SCEV *A2,
- const SCEV *C1, const SCEV *C2,
- const Loop *Loop1,
- const Loop *Loop2) const {
+bool DependenceInfo::symbolicRDIVtest(const SCEVAddRecExpr *Src,
+ const SCEVAddRecExpr *Dst) {
if (!isDependenceTestEnabled(DependenceTestType::SymbolicRDIV))
return false;
+ const SCEV *A1 = Src->getStepRecurrence(*SE);
+ const SCEV *A2 = Dst->getStepRecurrence(*SE);
+ const Loop *Loop1 = Src->getLoop();
+ const Loop *Loop2 = Dst->getLoop();
+
+ if (!isMonotonicPair(Src, Dst, SCEVMonotonicityDomain::EntireDomain,
+ Loop1->getOutermostLoop()))
+ return false;
+
++SymbolicRDIVapplications;
LLVM_DEBUG(dbgs() << "\ttry symbolic RDIV test\n");
LLVM_DEBUG(dbgs() << "\t A1 = " << *A1);
LLVM_DEBUG(dbgs() << ", type = " << *A1->getType() << "\n");
LLVM_DEBUG(dbgs() << "\t A2 = " << *A2 << "\n");
- LLVM_DEBUG(dbgs() << "\t C1 = " << *C1 << "\n");
- LLVM_DEBUG(dbgs() << "\t C2 = " << *C2 << "\n");
const SCEV *N1 = collectUpperBound(Loop1, A1->getType());
const SCEV *N2 = collectUpperBound(Loop2, A1->getType());
LLVM_DEBUG(if (N1) dbgs() << "\t N1 = " << *N1 << "\n");
LLVM_DEBUG(if (N2) dbgs() << "\t N2 = " << *N2 << "\n");
- const SCEV *C2_C1 = SE->getMinusSCEV(C2, C1);
- const SCEV *C1_C2 = SE->getMinusSCEV(C1, C2);
- LLVM_DEBUG(dbgs() << "\t C2 - C1 = " << *C2_C1 << "\n");
- LLVM_DEBUG(dbgs() << "\t C1 - C2 = " << *C1_C2 << "\n");
+ auto [SrcFirst, SrcLast] = evaluateFirstAndLast(*SE, Src, N1);
+ auto [DstFirst, DstLast] = evaluateFirstAndLast(*SE, Dst, N2);
+
+ auto IsKnownSLT = [&](const SCEV *LHS, const SCEV *RHS) {
+ return SE->isKnownPredicate(CmpInst::ICMP_SLT, LHS, RHS);
+ };
+
if (SE->isKnownNonNegative(A1)) {
- if (SE->isKnownNonNegative(A2)) {
- // A1 >= 0 && A2 >= 0
- if (N1) {
- // make sure that c2 - c1 <= a1*N1
- const SCEV *A1N1 = SE->getMulExpr(A1, N1);
- LLVM_DEBUG(dbgs() << "\t A1*N1 = " << *A1N1 << "\n");
- if (isKnownPredicate(CmpInst::ICMP_SGT, C2_C1, A1N1)) {
- ++SymbolicRDIVindependence;
- return true;
- }
- }
- if (N2) {
- // make sure that -a2*N2 <= c2 - c1, or a2*N2 >= c1 - c2
- const SCEV *A2N2 = SE->getMulExpr(A2, N2);
- LLVM_DEBUG(dbgs() << "\t A2*N2 = " << *A2N2 << "\n");
- if (isKnownPredicate(CmpInst::ICMP_SLT, A2N2, C1_C2)) {
- ++SymbolicRDIVindependence;
- return true;
- }
- }
- } else if (SE->isKnownNonPositive(A2)) {
- // a1 >= 0 && a2 <= 0
- if (N1 && N2) {
- // make sure that c2 - c1 <= a1*N1 - a2*N2
- const SCEV *A1N1 = SE->getMulExpr(A1, N1);
- const SCEV *A2N2 = SE->getMulExpr(A2, N2);
- const SCEV *A1N1_A2N2 = SE->getMinusSCEV(A1N1, A2N2);
- LLVM_DEBUG(dbgs() << "\t A1*N1 - A2*N2 = " << *A1N1_A2N2 << "\n");
- if (isKnownPredicate(CmpInst::ICMP_SGT, C2_C1, A1N1_A2N2)) {
- ++SymbolicRDIVindependence;
- return true;
- }
- }
- // make sure that 0 <= c2 - c1
- if (SE->isKnownNegative(C2_C1)) {
- ++SymbolicRDIVindependence;
- return true;
- }
- }
+ if (SE->isKnownNonNegative(A2))
+ return IsKnownSLT(SrcLast, DstFirst) || IsKnownSLT(DstLast, SrcFirst);
+ if (SE->isKnownNonPositive(A2))
+ return IsKnownSLT(SrcLast, DstLast) || IsKnownSLT(DstFirst, SrcFirst);
} else if (SE->isKnownNonPositive(A1)) {
- if (SE->isKnownNonNegative(A2)) {
- // a1 <= 0 && a2 >= 0
- if (N1 && N2) {
- // make sure that a1*N1 - a2*N2 <= c2 - c1
- const SCEV *A1N1 = SE->getMulExpr(A1, N1);
- const SCEV *A2N2 = SE->getMulExpr(A2, N2);
- const SCEV *A1N1_A2N2 = SE->getMinusSCEV(A1N1, A2N2);
- LLVM_DEBUG(dbgs() << "\t A1*N1 - A2*N2 = " << *A1N1_A2N2 << "\n");
- if (isKnownPredicate(CmpInst::ICMP_SGT, A1N1_A2N2, C2_C1)) {
- ++SymbolicRDIVindependence;
- return true;
- }
- }
- // make sure that c2 - c1 <= 0
- if (SE->isKnownPositive(C2_C1)) {
- ++SymbolicRDIVindependence;
- return true;
- }
- } else if (SE->isKnownNonPositive(A2)) {
- // a1 <= 0 && a2 <= 0
- if (N1) {
- // make sure that a1*N1 <= c2 - c1
- const SCEV *A1N1 = SE->getMulExpr(A1, N1);
- LLVM_DEBUG(dbgs() << "\t A1*N1 = " << *A1N1 << "\n");
- if (isKnownPredicate(CmpInst::ICMP_SGT, A1N1, C2_C1)) {
- ++SymbolicRDIVindependence;
- return true;
- }
- }
- if (N2) {
- // make sure that c2 - c1 <= -a2*N2, or c1 - c2 >= a2*N2
- const SCEV *A2N2 = SE->getMulExpr(A2, N2);
- LLVM_DEBUG(dbgs() << "\t A2*N2 = " << *A2N2 << "\n");
- if (isKnownPredicate(CmpInst::ICMP_SLT, C1_C2, A2N2)) {
- ++SymbolicRDIVindependence;
- return true;
- }
- }
- }
+ if (SE->isKnownNonNegative(A2))
+ return IsKnownSLT(SrcFirst, DstFirst) || IsKnownSLT(DstLast, SrcLast);
+ if (SE->isKnownNonPositive(A2))
+ return IsKnownSLT(SrcFirst, DstLast) || IsKnownSLT(DstFirst, SrcLast);
}
return false;
}
@@ -2272,8 +2200,7 @@ bool DependenceInfo::testSIV(const SCEV *Src, const SCEV *Dst, unsigned &Level,
disproven = exactSIVtest(SrcCoeff, DstCoeff, SrcConst, DstConst,
CurSrcLoop, CurDstLoop, Level, Result);
return disproven || gcdMIVtest(Src, Dst, Result) ||
- symbolicRDIVtest(SrcCoeff, DstCoeff, SrcConst, DstConst, CurSrcLoop,
- CurDstLoop);
+ symbolicRDIVtest(SrcAddRec, DstAddRec);
}
if (SrcAddRec) {
const SCEV *SrcConst = SrcAddRec->getStart();
@@ -2361,9 +2288,7 @@ bool DependenceInfo::testRDIV(const SCEV *Src, const SCEV *Dst,
llvm_unreachable("RDIV expected at least one AddRec");
return exactRDIVtest(SrcCoeff, DstCoeff, SrcConst, DstConst, SrcLoop, DstLoop,
Result) ||
- gcdMIVtest(Src, Dst, Result) ||
- symbolicRDIVtest(SrcCoeff, DstCoeff, SrcConst, DstConst, SrcLoop,
- DstLoop);
+ gcdMIVtest(Src, Dst, Result);
}
// Tests the single-subscript MIV pair (Src and Dst) for dependence.
diff --git a/llvm/test/Analysis/DependenceAnalysis/StrongSIV.ll b/llvm/test/Analysis/DependenceAnalysis/StrongSIV.ll
index c591f15751536..da59bc520b1ad 100644
--- a/llvm/test/Analysis/DependenceAnalysis/StrongSIV.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/StrongSIV.ll
@@ -425,33 +425,19 @@ for.end: ; preds = %for.body
;; *B++ = A[i + 2*n];
define void @strong9(ptr %A, ptr %B, i64 %n) nounwind uwtable ssp {
-; CHECK-ALL-LABEL: 'strong9'
-; CHECK-ALL-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %conv, ptr %arrayidx, align 4
-; CHECK-ALL-NEXT: da analyze - consistent output [*]!
-; CHECK-ALL-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx2, align 4
-; CHECK-ALL-NEXT: da analyze - none!
-; CHECK-ALL-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %0, ptr %B.addr.02, align 4
-; CHECK-ALL-NEXT: da analyze - confused!
-; CHECK-ALL-NEXT: Src: %0 = load i32, ptr %arrayidx2, align 4 --> Dst: %0 = load i32, ptr %arrayidx2, align 4
-; CHECK-ALL-NEXT: da analyze - consistent input [*]!
-; CHECK-ALL-NEXT: Src: %0 = load i32, ptr %arrayidx2, align 4 --> Dst: store i32 %0, ptr %B.addr.02, align 4
-; CHECK-ALL-NEXT: da analyze - confused!
-; CHECK-ALL-NEXT: Src: store i32 %0, ptr %B.addr.02, align 4 --> Dst: store i32 %0, ptr %B.addr.02, align 4
-; CHECK-ALL-NEXT: da analyze - consistent output [*]!
-;
-; CHECK-STRONG-SIV-LABEL: 'strong9'
-; CHECK-STRONG-SIV-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %conv, ptr %arrayidx, align 4
-; CHECK-STRONG-SIV-NEXT: da analyze - consistent output [*]!
-; CHECK-STRONG-SIV-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx2, align 4
-; CHECK-STRONG-SIV-NEXT: da analyze - consistent flow [*|<]!
-; CHECK-STRONG-SIV-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %0, ptr %B.addr.02, align 4
-; CHECK-STRONG-SIV-NEXT: da analyze - confused!
-; CHECK-STRONG-SIV-NEXT: Src: %0 = load i32, ptr %arrayidx2, align 4 --> Dst: %0 = load i32, ptr %arrayidx2, align 4
-; CHECK-STRONG-SIV-NEXT: da analyze - consistent input [*]!
-; CHECK-STRONG-SIV-NEXT: Src: %0 = load i32, ptr %arrayidx2, align 4 --> Dst: store i32 %0, ptr %B.addr.02, align 4
-; CHECK-STRONG-SIV-NEXT: da analyze - confused!
-; CHECK-STRONG-SIV-NEXT: Src: store i32 %0, ptr %B.addr.02, align 4 --> Dst: store i32 %0, ptr %B.addr.02, align 4
-; CHECK-STRONG-SIV-NEXT: da analyze - consistent output [*]!
+; CHECK-LABEL: 'strong9'
+; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %conv, ptr %arrayidx, align 4
+; CHECK-NEXT: da analyze - consistent output [*]!
+; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx2, align 4
+; CHECK-NEXT: da analyze - consistent 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 %arrayidx2, align 4 --> Dst: %0 = load i32, ptr %arrayidx2, align 4
+; CHECK-NEXT: da analyze - consistent input [*]!
+; 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
+; CHECK-NEXT: da analyze - consistent output [*]!
;
entry:
%cmp1 = icmp eq i64 %n, 0
@@ -536,13 +522,9 @@ for.end: ; preds = %for.body
;; A[i] = 0;
define void @strong11(ptr %A) nounwind uwtable ssp {
-; CHECK-ALL-LABEL: 'strong11'
-; CHECK-ALL-NEXT: Src: store i32 0, ptr %arrayidx, align 4 --> Dst: store i32 0, ptr %arrayidx, align 4
-; CHECK-ALL-NEXT: da analyze - none!
-;
-; CHECK-STRONG-SIV-LABEL: 'strong11'
-; CHECK-STRONG-SIV-NEXT: Src: store i32 0, ptr %arrayidx, align 4 --> Dst: store i32 0, ptr %arrayidx, align 4
-; CHECK-STRONG-SIV-NEXT: da analyze - consistent output [* S]!
+; CHECK-LABEL: 'strong11'
+; CHECK-NEXT: Src: store i32 0, ptr %arrayidx, align 4 --> Dst: store i32 0, ptr %arrayidx, align 4
+; CHECK-NEXT: da analyze - consistent output [* S]!
;
entry:
br label %for.cond1.preheader
@@ -568,3 +550,6 @@ for.cond.cleanup3: ; preds = %for.body4.us, %for.
%exitcond19.not = icmp eq i64 %inc8, 9223372036854775806
br i1 %exitcond19.not, label %for.cond.cleanup, label %for.cond1.preheader
}
+;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+; CHECK-ALL: {{.*}}
+; CHECK-STRONG-SIV: {{.*}}
diff --git a/llvm/test/Analysis/DependenceAnalysis/SymbolicRDIV.ll b/llvm/test/Analysis/DependenceAnalysis/SymbolicRDIV.ll
index 4f495122d1bcd..4e14f97240cf2 100644
--- a/llvm/test/Analysis/DependenceAnalysis/SymbolicRDIV.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/SymbolicRDIV.ll
@@ -17,7 +17,7 @@ define void @symbolicrdiv0(ptr %A, ptr %B, i64 %n1, i64 %n2) nounwind uwtable ss
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %conv, ptr %arrayidx, align 4
; CHECK-NEXT: da analyze - consistent output [*]!
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx8, align 4
-; CHECK-NEXT: da analyze - none!
+; 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 %arrayidx8, align 4 --> Dst: %0 = load i32, ptr %arrayidx8, align 4
@@ -86,7 +86,7 @@ define void @symbolicrdiv1(ptr %A, ptr %B, i64 %n1, i64 %n2) nounwind uwtable ss
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %conv, ptr %arrayidx, align 4
; CHECK-NEXT: da analyze - consistent output [*]!
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx9, align 4
-; CHECK-NEXT: da analyze - none!
+; 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 %arrayidx9, align 4 --> Dst: %0 = load i32, ptr %arrayidx9, align 4
@@ -157,7 +157,7 @@ define void @symbolicrdiv2(ptr %A, ptr %B, i64 %n1, i64 %n2) nounwind uwtable ss
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %conv, ptr %arrayidx, align 4
; CHECK-NEXT: da analyze - consistent output [*]!
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx7, align 4
-; CHECK-NEXT: da analyze - none!
+; 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
@@ -226,7 +226,7 @@ define void @symbolicrdiv3(ptr %A, ptr %B, i64 %n1, i64 %n2) nounwind uwtable ss
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %conv, ptr %arrayidx, align 4
; CHECK-NEXT: da analyze - consistent output [*]!
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx6, align 4
-; CHECK-NEXT: da analyze - none!
+; 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 %arrayidx6, align 4 --> Dst: %0 = load i32, ptr %arrayidx6, align 4
@@ -293,7 +293,7 @@ define void @symbolicrdiv4(ptr %A, ptr %B, i64 %n1, i64 %n2) nounwind uwtable ss
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %conv, ptr %arrayidx, align 4
; CHECK-NEXT: da analyze - consistent output [*]!
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx7, align 4
-; CHECK-NEXT: da analyze - none!
+; 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
@@ -361,7 +361,7 @@ define void @symbolicrdiv5(ptr %A, ptr %B, i64 %n1, i64 %n2) nounwind uwtable ss
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %conv, ptr %arrayidx, align 4
; CHECK-NEXT: da analyze - consistent output [*]!
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx7, align 4
-; CHECK-NEXT: da analyze - none!
+; 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
@@ -429,7 +429,7 @@ define void @symbolicrdiv6(ptr %A, ptr %B, i64 %n1, i64 %n2) nounwind uwtable ss
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %conv, ptr %arrayidx, align 4
; CHECK-NEXT: da analyze - output [* *]!
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx4, align 4
-; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - flow [* *|<]!
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %0, ptr %B.addr.12, align 4
; CHECK-NEXT: da analyze - confused!
; CHECK-NEXT: Src: %0 = load i32, ptr %arrayidx4, align 4 --> Dst: %0 = load i32, ptr %arrayidx4, align 4
diff --git a/llvm/test/Analysis/DependenceAnalysis/SymbolicSIV.ll b/llvm/test/Analysis/DependenceAnalysis/SymbolicSIV.ll
index ac2290bc5a8db..9117673336a0b 100644
--- a/llvm/test/Analysis/DependenceAnalysis/SymbolicSIV.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/SymbolicSIV.ll
@@ -15,7 +15,7 @@ define void @symbolicsiv0(ptr %A, ptr %B, i64 %n) nounwind uwtable ssp {
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %conv, ptr %arrayidx, align 4
; CHECK-NEXT: da analyze - consistent output [*]!
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx4, align 4
-; CHECK-NEXT: da analyze - none!
+; 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 %arrayidx4, align 4 --> Dst: %0 = load i32, ptr %arrayidx4, align 4
@@ -67,7 +67,7 @@ define void @symbolicsiv1(ptr %A, ptr %B, i64 %n) nounwind uwtable ssp {
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %conv, ptr %arrayidx, align 4
; CHECK-NEXT: da analyze - consistent output [*]!
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx5, align 4
-; CHECK-NEXT: da analyze - none!
+; 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 %arrayidx5, align 4 --> Dst: %0 = load i32, ptr %arrayidx5, align 4
@@ -121,7 +121,7 @@ define void @symbolicsiv2(ptr %A, ptr %B, i64 %n) nounwind uwtable ssp {
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %conv, ptr %arrayidx, align 4
; CHECK-NEXT: da analyze - consistent output [*]!
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx3, align 4
-; CHECK-NEXT: da analyze - none!
+; 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 %arrayidx3, align 4 --> Dst: %0 = load i32, ptr %arrayidx3, align 4
@@ -173,7 +173,7 @@ define void @symbolicsiv3(ptr %A, ptr %B, i64 %n) nounwind uwtable ssp {
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %conv, ptr %arrayidx, align 4
; CHECK-NEXT: da analyze - consistent output [*]!
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx3, align 4
-; CHECK-NEXT: da analyze - none!
+; 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 %arrayidx3, align 4 --> Dst: %0 = load i32, ptr %arrayidx3, align 4
@@ -226,7 +226,7 @@ define void @symbolicsiv4(ptr %A, ptr %B, i64 %n) nounwind uwtable ssp {
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %conv, ptr %arrayidx, align 4
; CHECK-NEXT: da analyze - consistent output [*]!
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx3, align 4
-; CHECK-NEXT: da analyze - none!
+; 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 %arrayidx3, align 4 --> Dst: %0 = load i32, ptr %arrayidx3, align 4
@@ -278,7 +278,7 @@ define void @symbolicsiv5(ptr %A, ptr %B, i64 %n) nounwind uwtable ssp {
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %conv, ptr %arrayidx, align 4
; CHECK-NEXT: da analyze - consistent output [*]!
; CHECK-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx4, align 4
-; CHECK-NEXT: da analyze - none!
+; 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 %arrayidx4, align 4 --> Dst: %0 = load i32, ptr %arrayidx4, align 4
diff --git a/llvm/test/Analysis/DependenceAnalysis/exact-siv-overflow.ll b/llvm/test/Analysis/DependenceAnalysis/exact-siv-overflow.ll
index 59e2ed3c7e35f..c14f9a4820bf8 100644
--- a/llvm/test/Analysis/DependenceAnalysis/exact-siv-overflow.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/exact-siv-overflow.ll
@@ -28,7 +28,7 @@ define void @exactsiv_const_ovfl(ptr %A) {
; CHECK-NEXT: Src: store i8 0, ptr %idx.0, align 1 --> Dst: store i8 0, ptr %idx.0, align 1
; CHECK-NEXT: da analyze - none!
; CHECK-NEXT: Src: store i8 0, ptr %idx.0, align 1 --> Dst: store i8 1, ptr %idx.1, align 1
-; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: da analyze - output [*|<]!
; CHECK-NEXT: Src: store i8 1, ptr %idx.1, align 1 --> Dst: store i8 1, ptr %idx.1, align 1
; CHECK-NEXT: da analyze - none!
;
diff --git a/llvm/test/Analysis/DependenceAnalysis/gcd-miv-overflow.ll b/llvm/test/Analysis/DependenceAnalysis/gcd-miv-overflow.ll
index ff8f32b9c8276..ea04cc9a7de84 100644
--- a/llvm/test/Analysis/DependenceAnalysis/gcd-miv-overflow.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/gcd-miv-overflow.ll
@@ -83,7 +83,7 @@ define void @gcdmiv_delta_ovfl(ptr %A) {
; CHECK-ALL-NEXT: Src: store i8 0, ptr %idx.0, align 1 --> Dst: store i8 0, ptr %idx.0, align 1
; CHECK-ALL-NEXT: da analyze - none!
; CHECK-ALL-NEXT: Src: store i8 0, ptr %idx.0, align 1 --> Dst: store i8 1, ptr %idx.1, align 1
-; CHECK-ALL-NEXT: da analyze - none!
+; CHECK-ALL-NEXT: da analyze - output [*|<]!
; CHECK-ALL-NEXT: Src: store i8 1, ptr %idx.1, align 1 --> Dst: store i8 1, ptr %idx.1, align 1
; CHECK-ALL-NEXT: da analyze - none!
;
diff --git a/llvm/test/Analysis/DependenceAnalysis/monotonicity-cast.ll b/llvm/test/Analysis/DependenceAnalysis/monotonicity-cast.ll
index c7405cda0e2a2..f70f12c259b42 100644
--- a/llvm/test/Analysis/DependenceAnalysis/monotonicity-cast.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/monotonicity-cast.ll
@@ -213,7 +213,7 @@ define void @offset_truncated_to_i1(ptr %a) {
; CHECK-NEXT: Reason: (zext i1 {false,+,true}<%loop> to i64)
; 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 [*]!
;
entry:
br label %loop
diff --git a/llvm/test/Analysis/DependenceAnalysis/non-monotonic.ll b/llvm/test/Analysis/DependenceAnalysis/non-monotonic.ll
index 74c332fcb8fa3..a41302f7be937 100644
--- a/llvm/test/Analysis/DependenceAnalysis/non-monotonic.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/non-monotonic.ll
@@ -46,7 +46,7 @@ define void @f(ptr %A) {
; CHECK-NEXT: Src: store i8 1, ptr %idx.0, align 1 --> Dst: store i8 2, ptr %idx.1, align 1
; CHECK-NEXT: da analyze - none!
; 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 [*]!
;
entry:
br label %loop.header
diff --git a/llvm/test/Analysis/DependenceAnalysis/run-specific-dependence-test.ll b/llvm/test/Analysis/DependenceAnalysis/run-specific-dependence-test.ll
index 120edf0c32f1c..bd1a40e4c8c17 100644
--- a/llvm/test/Analysis/DependenceAnalysis/run-specific-dependence-test.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/run-specific-dependence-test.ll
@@ -518,7 +518,7 @@ define void @symbolic_rdiv(ptr %a) {
; CHECK-SYMBOLIC-RDIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.0, align 1
; CHECK-SYMBOLIC-RDIV-NEXT: da analyze - consistent output [*]!
; CHECK-SYMBOLIC-RDIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 2, ptr %gep.1, align 1
-; CHECK-SYMBOLIC-RDIV-NEXT: da analyze - none!
+; CHECK-SYMBOLIC-RDIV-NEXT: da analyze - consistent output [|<]!
; CHECK-SYMBOLIC-RDIV-NEXT: Src: store i8 2, ptr %gep.1, align 1 --> Dst: store i8 2, ptr %gep.1, align 1
; CHECK-SYMBOLIC-RDIV-NEXT: da analyze - consistent output [*]!
;
diff --git a/llvm/test/Analysis/DependenceAnalysis/strong-siv-overflow.ll b/llvm/test/Analysis/DependenceAnalysis/strong-siv-overflow.ll
index 6fd71ac8fe414..201f13b95ecae 100644
--- a/llvm/test/Analysis/DependenceAnalysis/strong-siv-overflow.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/strong-siv-overflow.ll
@@ -15,21 +15,13 @@
; FIXME: DependenceAnalysis fails to detect the dependency between the two
; stores, and the issue is not caused by the Strong SIV.
define void @strongsiv_const_ovfl(ptr %A) {
-; CHECK-ALL-LABEL: 'strongsiv_const_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: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 2, ptr %gep.1, align 1
-; CHECK-ALL-NEXT: da analyze - none!
-; CHECK-ALL-NEXT: Src: store i8 2, ptr %gep.1, align 1 --> Dst: store i8 2, ptr %gep.1, align 1
-; CHECK-ALL-NEXT: da analyze - none!
-;
-; CHECK-STRONG-SIV-LABEL: 'strongsiv_const_ovfl'
-; CHECK-STRONG-SIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.0, align 1
-; CHECK-STRONG-SIV-NEXT: da analyze - none!
-; CHECK-STRONG-SIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 2, ptr %gep.1, align 1
-; CHECK-STRONG-SIV-NEXT: da analyze - consistent output [1]!
-; CHECK-STRONG-SIV-NEXT: Src: store i8 2, ptr %gep.1, align 1 --> Dst: store i8 2, ptr %gep.1, align 1
-; CHECK-STRONG-SIV-NEXT: da analyze - none!
+; CHECK-LABEL: 'strongsiv_const_ovfl'
+; CHECK-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.0, align 1
+; CHECK-NEXT: da analyze - none!
+; CHECK-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 2, ptr %gep.1, align 1
+; CHECK-NEXT: da analyze - consistent output [1]!
+; CHECK-NEXT: Src: store i8 2, ptr %gep.1, align 1 --> Dst: store i8 2, ptr %gep.1, align 1
+; CHECK-NEXT: da analyze - none!
;
entry:
br label %loop.header
@@ -69,4 +61,5 @@ exit:
ret void
}
;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
-; CHECK: {{.*}}
+; CHECK-ALL: {{.*}}
+; CHECK-STRONG-SIV: {{.*}}
diff --git a/llvm/test/Analysis/DependenceAnalysis/symbolic-rdiv-overflow.ll b/llvm/test/Analysis/DependenceAnalysis/symbolic-rdiv-overflow.ll
index 75be96380f078..5a29feed2deb4 100644
--- a/llvm/test/Analysis/DependenceAnalysis/symbolic-rdiv-overflow.ll
+++ b/llvm/test/Analysis/DependenceAnalysis/symbolic-rdiv-overflow.ll
@@ -20,15 +20,15 @@ define void @symbolicrdiv_prod_ovfl(ptr %A) {
; 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: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 2, ptr %gep.1, align 1
-; CHECK-ALL-NEXT: da analyze - none!
+; 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
; CHECK-ALL-NEXT: da analyze - none!
;
; CHECK-SYMBOLIC-RDIV-LABEL: 'symbolicrdiv_prod_ovfl'
; CHECK-SYMBOLIC-RDIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.0, align 1
-; CHECK-SYMBOLIC-RDIV-NEXT: da analyze - none!
+; CHECK-SYMBOLIC-RDIV-NEXT: da analyze - consistent output [*]!
; CHECK-SYMBOLIC-RDIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 2, ptr %gep.1, align 1
-; CHECK-SYMBOLIC-RDIV-NEXT: da analyze - none!
+; CHECK-SYMBOLIC-RDIV-NEXT: da analyze - consistent output [*|<]!
; CHECK-SYMBOLIC-RDIV-NEXT: Src: store i8 2, ptr %gep.1, align 1 --> Dst: store i8 2, ptr %gep.1, align 1
; CHECK-SYMBOLIC-RDIV-NEXT: da analyze - consistent output [*]!
;
@@ -87,7 +87,7 @@ define void @symbolicrdiv_delta_ovfl(ptr %A) {
; 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: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 2, ptr %gep.1, align 1
-; CHECK-ALL-NEXT: da analyze - none!
+; 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
; CHECK-ALL-NEXT: da analyze - none!
;
@@ -95,7 +95,7 @@ define void @symbolicrdiv_delta_ovfl(ptr %A) {
; CHECK-SYMBOLIC-RDIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.0, align 1
; CHECK-SYMBOLIC-RDIV-NEXT: da analyze - consistent output [*]!
; CHECK-SYMBOLIC-RDIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 2, ptr %gep.1, align 1
-; CHECK-SYMBOLIC-RDIV-NEXT: da analyze - none!
+; CHECK-SYMBOLIC-RDIV-NEXT: da analyze - consistent output [*|<]!
; CHECK-SYMBOLIC-RDIV-NEXT: Src: store i8 2, ptr %gep.1, align 1 --> Dst: store i8 2, ptr %gep.1, align 1
; CHECK-SYMBOLIC-RDIV-NEXT: da analyze - consistent output [*]!
;
More information about the llvm-commits
mailing list