diff --git a/llvm/lib/Analysis/DependenceAnalysis.cpp b/llvm/lib/Analysis/DependenceAnalysis.cpp index 0a8c2f82e162f..853bd66c8a7f8 100644 --- a/llvm/lib/Analysis/DependenceAnalysis.cpp +++ b/llvm/lib/Analysis/DependenceAnalysis.cpp @@ -122,11 +122,49 @@ static cl::opt MIVMaxLevelThreshold( cl::desc("Maximum depth allowed for the recursive algorithm used to " "explore MIV direction vectors.")); -static cl::opt RunSIVRoutinesOnly( - "da-run-siv-routines-only", cl::init(false), cl::ReallyHidden, - cl::desc("Run only SIV routines and disable others (ZIV, RDIV, and MIV). " - "The purpose is mainly to exclude the influence of those routines " - "in regression tests for SIV routines.")); +namespace { + +/// Types of dependence test routines. +enum class DependenceTestType { + All, + StrongSIV, + WeakCrossingSIV, + ExactSIV, + WeakZeroSIV, + ExactRDIV, + SymbolicRDIV, + GCDMIV, + BanerjeeMIV, +}; + +} // anonymous namespace + +static cl::opt EnableDependenceTest( + "da-enable-dependence-test", cl::init(DependenceTestType::All), + cl::ReallyHidden, + cl::desc("Run only specified dependence test routine and disable others. " + "The purpose is mainly to exclude the influence of other " + "dependence test routines in regression tests. If set to All, all " + "dependence test routines are enabled."), + cl::values(clEnumValN(DependenceTestType::All, "all", + "Enable all dependence test routines."), + clEnumValN(DependenceTestType::StrongSIV, "strong-siv", + "Enable only Strong SIV test."), + clEnumValN(DependenceTestType::WeakCrossingSIV, + "weak-crossing-siv", + "Enable only Weak-Crossing SIV test."), + clEnumValN(DependenceTestType::ExactSIV, "exact-siv", + "Enable only Exact SIV test."), + clEnumValN(DependenceTestType::WeakZeroSIV, "weak-zero-siv", + "Enable only Weak-Zero SIV test."), + clEnumValN(DependenceTestType::ExactRDIV, "exact-rdiv", + "Enable only Exact RDIV test."), + clEnumValN(DependenceTestType::SymbolicRDIV, "symbolic-rdiv", + "Enable only Symbolic RDIV test."), + clEnumValN(DependenceTestType::GCDMIV, "gcd-miv", + "Enable only GCD MIV test."), + 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. @@ -1544,6 +1582,13 @@ static const SCEV *minusSCEVNoSignedOverflow(const SCEV *A, const SCEV *B, return nullptr; } +/// Returns true iff \p Test is enabled. +static bool isDependenceTestEnabled(DependenceTestType Test) { + if (EnableDependenceTest == DependenceTestType::All) + return true; + return EnableDependenceTest == Test; +} + // 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 @@ -1605,6 +1650,9 @@ bool DependenceInfo::strongSIVtest(const SCEV *Coeff, const SCEV *SrcConst, const Loop *CurDstLoop, unsigned Level, FullDependence &Result, Constraint &NewConstraint) const { + if (!isDependenceTestEnabled(DependenceTestType::StrongSIV)) + return false; + LLVM_DEBUG(dbgs() << "\tStrong SIV test\n"); LLVM_DEBUG(dbgs() << "\t Coeff = " << *Coeff); LLVM_DEBUG(dbgs() << ", " << *Coeff->getType() << "\n"); @@ -1739,6 +1787,9 @@ bool DependenceInfo::weakCrossingSIVtest( const Loop *CurSrcLoop, const Loop *CurDstLoop, unsigned Level, FullDependence &Result, Constraint &NewConstraint, const SCEV *&SplitIter) const { + if (!isDependenceTestEnabled(DependenceTestType::WeakCrossingSIV)) + return false; + LLVM_DEBUG(dbgs() << "\tWeak-Crossing SIV test\n"); LLVM_DEBUG(dbgs() << "\t Coeff = " << *Coeff << "\n"); LLVM_DEBUG(dbgs() << "\t SrcConst = " << *SrcConst << "\n"); @@ -1997,6 +2048,9 @@ bool DependenceInfo::exactSIVtest(const SCEV *SrcCoeff, const SCEV *DstCoeff, const Loop *CurDstLoop, unsigned Level, FullDependence &Result, Constraint &NewConstraint) const { + if (!isDependenceTestEnabled(DependenceTestType::ExactSIV)) + return false; + LLVM_DEBUG(dbgs() << "\tExact SIV test\n"); LLVM_DEBUG(dbgs() << "\t SrcCoeff = " << *SrcCoeff << " = AM\n"); LLVM_DEBUG(dbgs() << "\t DstCoeff = " << *DstCoeff << " = BM\n"); @@ -2176,6 +2230,9 @@ bool DependenceInfo::weakZeroSrcSIVtest( const SCEV *DstCoeff, const SCEV *SrcConst, const SCEV *DstConst, const Loop *CurSrcLoop, const Loop *CurDstLoop, unsigned Level, FullDependence &Result, Constraint &NewConstraint) const { + if (!isDependenceTestEnabled(DependenceTestType::WeakZeroSIV)) + return false; + // For the WeakSIV test, it's possible the loop isn't common to // the Src and Dst loops. If it isn't, then there's no need to // record a direction. @@ -2284,6 +2341,9 @@ bool DependenceInfo::weakZeroDstSIVtest( const SCEV *SrcCoeff, const SCEV *SrcConst, const SCEV *DstConst, const Loop *CurSrcLoop, const Loop *CurDstLoop, unsigned Level, FullDependence &Result, Constraint &NewConstraint) const { + if (!isDependenceTestEnabled(DependenceTestType::WeakZeroSIV)) + return false; + // For the WeakSIV test, it's possible the loop isn't common to the // Src and Dst loops. If it isn't, then there's no need to record a direction. LLVM_DEBUG(dbgs() << "\tWeak-Zero (dst) SIV test\n"); @@ -2367,8 +2427,9 @@ bool DependenceInfo::exactRDIVtest(const SCEV *SrcCoeff, const SCEV *DstCoeff, const SCEV *SrcConst, const SCEV *DstConst, const Loop *SrcLoop, const Loop *DstLoop, FullDependence &Result) const { - if (RunSIVRoutinesOnly) + if (!isDependenceTestEnabled(DependenceTestType::ExactRDIV)) return false; + LLVM_DEBUG(dbgs() << "\tExact RDIV test\n"); LLVM_DEBUG(dbgs() << "\t SrcCoeff = " << *SrcCoeff << " = AM\n"); LLVM_DEBUG(dbgs() << "\t DstCoeff = " << *DstCoeff << " = BM\n"); @@ -2513,8 +2574,9 @@ bool DependenceInfo::symbolicRDIVtest(const SCEV *A1, const SCEV *A2, const SCEV *C1, const SCEV *C2, const Loop *Loop1, const Loop *Loop2) const { - if (RunSIVRoutinesOnly) + if (!isDependenceTestEnabled(DependenceTestType::SymbolicRDIV)) return false; + ++SymbolicRDIVapplications; LLVM_DEBUG(dbgs() << "\ttry symbolic RDIV test\n"); LLVM_DEBUG(dbgs() << "\t A1 = " << *A1); @@ -2828,8 +2890,9 @@ bool DependenceInfo::accumulateCoefficientsGCD(const SCEV *Expr, // to "a common divisor". bool DependenceInfo::gcdMIVtest(const SCEV *Src, const SCEV *Dst, FullDependence &Result) const { - if (RunSIVRoutinesOnly) + if (!isDependenceTestEnabled(DependenceTestType::GCDMIV)) return false; + LLVM_DEBUG(dbgs() << "starting gcd\n"); ++GCDapplications; unsigned BitWidth = SE->getTypeSizeInBits(Src->getType()); @@ -2996,8 +3059,9 @@ bool DependenceInfo::gcdMIVtest(const SCEV *Src, const SCEV *Dst, bool DependenceInfo::banerjeeMIVtest(const SCEV *Src, const SCEV *Dst, const SmallBitVector &Loops, FullDependence &Result) const { - if (RunSIVRoutinesOnly) + if (!isDependenceTestEnabled(DependenceTestType::BanerjeeMIV)) return false; + LLVM_DEBUG(dbgs() << "starting Banerjee\n"); ++BanerjeeApplications; LLVM_DEBUG(dbgs() << " Src = " << *Src << '\n'); diff --git a/llvm/test/Analysis/DependenceAnalysis/ExactSIV.ll b/llvm/test/Analysis/DependenceAnalysis/ExactSIV.ll index e8e7cb11bb23e..b6b44ad4bfc53 100644 --- a/llvm/test/Analysis/DependenceAnalysis/ExactSIV.ll +++ b/llvm/test/Analysis/DependenceAnalysis/ExactSIV.ll @@ -1,8 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 5 ; RUN: opt < %s -disable-output "-passes=print" -aa-pipeline=basic-aa 2>&1 \ ; RUN: | FileCheck %s -; RUN: opt < %s -disable-output "-passes=print" -da-run-siv-routines-only 2>&1 \ -; RUN: | FileCheck %s --check-prefix=CHECK-SIV-ONLY target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" target triple = "x86_64-apple-macosx10.6.0" @@ -27,20 +25,6 @@ define void @exact0(ptr %A, ptr %B) nounwind uwtable ssp { ; CHECK-NEXT: Src: store i32 %0, ptr %B.addr.01, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 ; CHECK-NEXT: da analyze - none! ; -; CHECK-SIV-ONLY-LABEL: 'exact0' -; CHECK-SIV-ONLY-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %conv, ptr %arrayidx, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - none! -; CHECK-SIV-ONLY-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx2, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - flow [<=|<]! -; CHECK-SIV-ONLY-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - confused! -; CHECK-SIV-ONLY-NEXT: Src: %0 = load i32, ptr %arrayidx2, align 4 --> Dst: %0 = load i32, ptr %arrayidx2, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - none! -; CHECK-SIV-ONLY-NEXT: Src: %0 = load i32, ptr %arrayidx2, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - confused! -; CHECK-SIV-ONLY-NEXT: Src: store i32 %0, ptr %B.addr.01, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - none! -; entry: br label %for.body @@ -85,20 +69,6 @@ define void @exact1(ptr %A, ptr %B) nounwind uwtable ssp { ; CHECK-NEXT: Src: store i32 %0, ptr %B.addr.01, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 ; CHECK-NEXT: da analyze - none! ; -; CHECK-SIV-ONLY-LABEL: 'exact1' -; CHECK-SIV-ONLY-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %conv, ptr %arrayidx, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - none! -; CHECK-SIV-ONLY-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx3, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - none! -; CHECK-SIV-ONLY-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - confused! -; CHECK-SIV-ONLY-NEXT: Src: %0 = load i32, ptr %arrayidx3, align 4 --> Dst: %0 = load i32, ptr %arrayidx3, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - none! -; CHECK-SIV-ONLY-NEXT: Src: %0 = load i32, ptr %arrayidx3, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - confused! -; CHECK-SIV-ONLY-NEXT: Src: store i32 %0, ptr %B.addr.01, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - none! -; entry: br label %for.body @@ -144,20 +114,6 @@ define void @exact2(ptr %A, ptr %B) nounwind uwtable ssp { ; CHECK-NEXT: Src: store i32 %0, ptr %B.addr.01, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 ; CHECK-NEXT: da analyze - none! ; -; CHECK-SIV-ONLY-LABEL: 'exact2' -; CHECK-SIV-ONLY-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %conv, ptr %arrayidx, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - none! -; CHECK-SIV-ONLY-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx1, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - none! -; CHECK-SIV-ONLY-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - confused! -; CHECK-SIV-ONLY-NEXT: Src: %0 = load i32, ptr %arrayidx1, align 4 --> Dst: %0 = load i32, ptr %arrayidx1, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - none! -; CHECK-SIV-ONLY-NEXT: Src: %0 = load i32, ptr %arrayidx1, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - confused! -; CHECK-SIV-ONLY-NEXT: Src: store i32 %0, ptr %B.addr.01, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - none! -; entry: br label %for.body @@ -201,20 +157,6 @@ define void @exact3(ptr %A, ptr %B) nounwind uwtable ssp { ; CHECK-NEXT: Src: store i32 %0, ptr %B.addr.01, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 ; CHECK-NEXT: da analyze - none! ; -; CHECK-SIV-ONLY-LABEL: 'exact3' -; CHECK-SIV-ONLY-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %conv, ptr %arrayidx, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - none! -; CHECK-SIV-ONLY-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx1, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - flow [>]! -; CHECK-SIV-ONLY-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - confused! -; CHECK-SIV-ONLY-NEXT: Src: %0 = load i32, ptr %arrayidx1, align 4 --> Dst: %0 = load i32, ptr %arrayidx1, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - none! -; CHECK-SIV-ONLY-NEXT: Src: %0 = load i32, ptr %arrayidx1, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - confused! -; CHECK-SIV-ONLY-NEXT: Src: store i32 %0, ptr %B.addr.01, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - none! -; entry: br label %for.body @@ -258,20 +200,6 @@ define void @exact4(ptr %A, ptr %B) nounwind uwtable ssp { ; CHECK-NEXT: Src: store i32 %0, ptr %B.addr.01, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 ; CHECK-NEXT: da analyze - none! ; -; CHECK-SIV-ONLY-LABEL: 'exact4' -; CHECK-SIV-ONLY-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %conv, ptr %arrayidx, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - none! -; CHECK-SIV-ONLY-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx1, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - flow [>]! -; CHECK-SIV-ONLY-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - confused! -; CHECK-SIV-ONLY-NEXT: Src: %0 = load i32, ptr %arrayidx1, align 4 --> Dst: %0 = load i32, ptr %arrayidx1, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - none! -; CHECK-SIV-ONLY-NEXT: Src: %0 = load i32, ptr %arrayidx1, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - confused! -; CHECK-SIV-ONLY-NEXT: Src: store i32 %0, ptr %B.addr.01, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - none! -; entry: br label %for.body @@ -315,20 +243,6 @@ define void @exact5(ptr %A, ptr %B) nounwind uwtable ssp { ; CHECK-NEXT: Src: store i32 %0, ptr %B.addr.01, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 ; CHECK-NEXT: da analyze - none! ; -; CHECK-SIV-ONLY-LABEL: 'exact5' -; CHECK-SIV-ONLY-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %conv, ptr %arrayidx, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - none! -; CHECK-SIV-ONLY-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx1, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - flow [=>|<]! -; CHECK-SIV-ONLY-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - confused! -; CHECK-SIV-ONLY-NEXT: Src: %0 = load i32, ptr %arrayidx1, align 4 --> Dst: %0 = load i32, ptr %arrayidx1, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - none! -; CHECK-SIV-ONLY-NEXT: Src: %0 = load i32, ptr %arrayidx1, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - confused! -; CHECK-SIV-ONLY-NEXT: Src: store i32 %0, ptr %B.addr.01, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - none! -; entry: br label %for.body @@ -372,20 +286,6 @@ define void @exact6(ptr %A, ptr %B) nounwind uwtable ssp { ; CHECK-NEXT: Src: store i32 %0, ptr %B.addr.01, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 ; CHECK-NEXT: da analyze - none! ; -; CHECK-SIV-ONLY-LABEL: 'exact6' -; CHECK-SIV-ONLY-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %conv, ptr %arrayidx, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - none! -; CHECK-SIV-ONLY-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx1, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - flow [=>|<]! -; CHECK-SIV-ONLY-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - confused! -; CHECK-SIV-ONLY-NEXT: Src: %0 = load i32, ptr %arrayidx1, align 4 --> Dst: %0 = load i32, ptr %arrayidx1, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - none! -; CHECK-SIV-ONLY-NEXT: Src: %0 = load i32, ptr %arrayidx1, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - confused! -; CHECK-SIV-ONLY-NEXT: Src: store i32 %0, ptr %B.addr.01, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - none! -; entry: br label %for.body @@ -429,20 +329,6 @@ define void @exact7(ptr %A, ptr %B) nounwind uwtable ssp { ; CHECK-NEXT: Src: store i32 %0, ptr %B.addr.01, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 ; CHECK-NEXT: da analyze - none! ; -; CHECK-SIV-ONLY-LABEL: 'exact7' -; CHECK-SIV-ONLY-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %conv, ptr %arrayidx, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - none! -; CHECK-SIV-ONLY-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx1, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - flow [*|<]! -; CHECK-SIV-ONLY-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - confused! -; CHECK-SIV-ONLY-NEXT: Src: %0 = load i32, ptr %arrayidx1, align 4 --> Dst: %0 = load i32, ptr %arrayidx1, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - none! -; CHECK-SIV-ONLY-NEXT: Src: %0 = load i32, ptr %arrayidx1, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - confused! -; CHECK-SIV-ONLY-NEXT: Src: store i32 %0, ptr %B.addr.01, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - none! -; entry: br label %for.body @@ -486,20 +372,6 @@ define void @exact8(ptr %A, ptr %B) nounwind uwtable ssp { ; CHECK-NEXT: Src: store i32 %0, ptr %B.addr.01, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 ; CHECK-NEXT: da analyze - none! ; -; CHECK-SIV-ONLY-LABEL: 'exact8' -; CHECK-SIV-ONLY-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %conv, ptr %arrayidx, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - none! -; CHECK-SIV-ONLY-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx2, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - none! -; CHECK-SIV-ONLY-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - confused! -; CHECK-SIV-ONLY-NEXT: Src: %0 = load i32, ptr %arrayidx2, align 4 --> Dst: %0 = load i32, ptr %arrayidx2, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - none! -; CHECK-SIV-ONLY-NEXT: Src: %0 = load i32, ptr %arrayidx2, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - confused! -; CHECK-SIV-ONLY-NEXT: Src: store i32 %0, ptr %B.addr.01, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - none! -; entry: br label %for.body @@ -543,20 +415,6 @@ define void @exact9(ptr %A, ptr %B) nounwind uwtable ssp { ; CHECK-NEXT: Src: store i32 %0, ptr %B.addr.01, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 ; CHECK-NEXT: da analyze - none! ; -; CHECK-SIV-ONLY-LABEL: 'exact9' -; CHECK-SIV-ONLY-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %conv, ptr %arrayidx, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - none! -; CHECK-SIV-ONLY-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx2, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - flow [>]! -; CHECK-SIV-ONLY-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - confused! -; CHECK-SIV-ONLY-NEXT: Src: %0 = load i32, ptr %arrayidx2, align 4 --> Dst: %0 = load i32, ptr %arrayidx2, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - none! -; CHECK-SIV-ONLY-NEXT: Src: %0 = load i32, ptr %arrayidx2, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - confused! -; CHECK-SIV-ONLY-NEXT: Src: store i32 %0, ptr %B.addr.01, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - none! -; entry: br label %for.body @@ -600,20 +458,6 @@ define void @exact10(ptr %A, ptr %B) nounwind uwtable ssp { ; CHECK-NEXT: Src: store i32 %0, ptr %B.addr.01, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 ; CHECK-NEXT: da analyze - none! ; -; CHECK-SIV-ONLY-LABEL: 'exact10' -; CHECK-SIV-ONLY-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %conv, ptr %arrayidx, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - none! -; CHECK-SIV-ONLY-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx2, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - flow [>]! -; CHECK-SIV-ONLY-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - confused! -; CHECK-SIV-ONLY-NEXT: Src: %0 = load i32, ptr %arrayidx2, align 4 --> Dst: %0 = load i32, ptr %arrayidx2, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - none! -; CHECK-SIV-ONLY-NEXT: Src: %0 = load i32, ptr %arrayidx2, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - confused! -; CHECK-SIV-ONLY-NEXT: Src: store i32 %0, ptr %B.addr.01, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - none! -; entry: br label %for.body @@ -657,20 +501,6 @@ define void @exact11(ptr %A, ptr %B) nounwind uwtable ssp { ; CHECK-NEXT: Src: store i32 %0, ptr %B.addr.01, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 ; CHECK-NEXT: da analyze - none! ; -; CHECK-SIV-ONLY-LABEL: 'exact11' -; CHECK-SIV-ONLY-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %conv, ptr %arrayidx, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - none! -; CHECK-SIV-ONLY-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx2, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - flow [=>|<]! -; CHECK-SIV-ONLY-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - confused! -; CHECK-SIV-ONLY-NEXT: Src: %0 = load i32, ptr %arrayidx2, align 4 --> Dst: %0 = load i32, ptr %arrayidx2, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - none! -; CHECK-SIV-ONLY-NEXT: Src: %0 = load i32, ptr %arrayidx2, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - confused! -; CHECK-SIV-ONLY-NEXT: Src: store i32 %0, ptr %B.addr.01, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - none! -; entry: br label %for.body @@ -714,20 +544,6 @@ define void @exact12(ptr %A, ptr %B) nounwind uwtable ssp { ; CHECK-NEXT: Src: store i32 %0, ptr %B.addr.01, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 ; CHECK-NEXT: da analyze - none! ; -; CHECK-SIV-ONLY-LABEL: 'exact12' -; CHECK-SIV-ONLY-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %conv, ptr %arrayidx, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - none! -; CHECK-SIV-ONLY-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx2, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - flow [=>|<]! -; CHECK-SIV-ONLY-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - confused! -; CHECK-SIV-ONLY-NEXT: Src: %0 = load i32, ptr %arrayidx2, align 4 --> Dst: %0 = load i32, ptr %arrayidx2, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - none! -; CHECK-SIV-ONLY-NEXT: Src: %0 = load i32, ptr %arrayidx2, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - confused! -; CHECK-SIV-ONLY-NEXT: Src: store i32 %0, ptr %B.addr.01, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - none! -; entry: br label %for.body @@ -771,20 +587,6 @@ define void @exact13(ptr %A, ptr %B) nounwind uwtable ssp { ; CHECK-NEXT: Src: store i32 %0, ptr %B.addr.01, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 ; CHECK-NEXT: da analyze - none! ; -; CHECK-SIV-ONLY-LABEL: 'exact13' -; CHECK-SIV-ONLY-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %conv, ptr %arrayidx, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - none! -; CHECK-SIV-ONLY-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx2, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - flow [*|<]! -; CHECK-SIV-ONLY-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - confused! -; CHECK-SIV-ONLY-NEXT: Src: %0 = load i32, ptr %arrayidx2, align 4 --> Dst: %0 = load i32, ptr %arrayidx2, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - none! -; CHECK-SIV-ONLY-NEXT: Src: %0 = load i32, ptr %arrayidx2, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - confused! -; CHECK-SIV-ONLY-NEXT: Src: store i32 %0, ptr %B.addr.01, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 -; CHECK-SIV-ONLY-NEXT: da analyze - none! -; entry: br label %for.body @@ -807,123 +609,3 @@ for.body: ; preds = %entry, %for.body for.end: ; preds = %for.body ret void } - -;; max_i = INT64_MAX/6 // 1537228672809129301 -;; for (long long i = 0; i <= max_i; i++) { -;; A[-6*i + INT64_MAX] = 0; -;; if (i) -;; A[3*i - 2] = 1; -;; } -;; -;; FIXME: DependencyAnalsysis currently detects no dependency between -;; `A[-6*i + INT64_MAX]` and `A[3*i - 2]`, but it does exist. For example, -;; -;; | memory location | -6*i + INT64_MAX | 3*i - 2 -;; |------------------------|------------------------|----------- -;; | A[1] | i = max_i | i = 1 -;; | A[4611686018427387901] | i = 768614336404564651 | i = max_i -;; -;; Actually, -;; * 1 = -6*max_i + INT64_MAX = 3*1 - 2 -;; * 4611686018427387901 = -6*768614336404564651 + INT64_MAX = 3*max_i - 2 -;; - -define void @exact14(ptr %A) { -; CHECK-LABEL: 'exact14' -; 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: Src: store i8 1, ptr %idx.1, align 1 --> Dst: store i8 1, ptr %idx.1, align 1 -; CHECK-NEXT: da analyze - none! -; -; CHECK-SIV-ONLY-LABEL: 'exact14' -; CHECK-SIV-ONLY-NEXT: Src: store i8 0, ptr %idx.0, align 1 --> Dst: store i8 0, ptr %idx.0, align 1 -; CHECK-SIV-ONLY-NEXT: da analyze - none! -; CHECK-SIV-ONLY-NEXT: Src: store i8 0, ptr %idx.0, align 1 --> Dst: store i8 1, ptr %idx.1, align 1 -; CHECK-SIV-ONLY-NEXT: da analyze - output [*|<]! -; CHECK-SIV-ONLY-NEXT: Src: store i8 1, ptr %idx.1, align 1 --> Dst: store i8 1, ptr %idx.1, align 1 -; CHECK-SIV-ONLY-NEXT: da analyze - none! -; -entry: - br label %loop.header - -loop.header: - %i = phi i64 [ 0, %entry ], [ %i.inc, %loop.latch ] - %subscript.0 = phi i64 [ 9223372036854775807, %entry ], [ %subscript.0.next, %loop.latch ] - %subscript.1 = phi i64 [ -2, %entry ], [ %subscript.1.next, %loop.latch ] - %idx.0 = getelementptr inbounds i8, ptr %A, i64 %subscript.0 - store i8 0, ptr %idx.0 - %cond.store = icmp ne i64 %i, 0 - br i1 %cond.store, label %if.store, label %loop.latch - -if.store: - %idx.1 = getelementptr inbounds i8, ptr %A, i64 %subscript.1 - store i8 1, ptr %idx.1 - br label %loop.latch - -loop.latch: - %i.inc = add nuw nsw i64 %i, 1 - %subscript.0.next = add nsw i64 %subscript.0, -6 - %subscript.1.next = add nsw i64 %subscript.1, 3 - %exitcond = icmp sgt i64 %i.inc, 1537228672809129301 - br i1 %exitcond, label %exit, label %loop.header - -exit: - ret void -} - -;; A generalized version of @exact14. -;; -;; for (long long i = 0; i <= n / 6; i++) { -;; A[-6*i + n] = 0; -;; if (i) -;; A[3*i - 2] = 1; -;; } - -define void @exact15(ptr %A, i64 %n) { -; CHECK-LABEL: 'exact15' -; 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 - 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! -; -; CHECK-SIV-ONLY-LABEL: 'exact15' -; CHECK-SIV-ONLY-NEXT: Src: store i8 0, ptr %idx.0, align 1 --> Dst: store i8 0, ptr %idx.0, align 1 -; CHECK-SIV-ONLY-NEXT: da analyze - none! -; CHECK-SIV-ONLY-NEXT: Src: store i8 0, ptr %idx.0, align 1 --> Dst: store i8 1, ptr %idx.1, align 1 -; CHECK-SIV-ONLY-NEXT: da analyze - output [*|<]! -; CHECK-SIV-ONLY-NEXT: Src: store i8 1, ptr %idx.1, align 1 --> Dst: store i8 1, ptr %idx.1, align 1 -; CHECK-SIV-ONLY-NEXT: da analyze - none! -; -entry: - %bound = sdiv i64 %n, 6 - %guard = icmp sgt i64 %n, 0 - br i1 %guard, label %loop.header, label %exit - -loop.header: - %i = phi i64 [ 0, %entry ], [ %i.inc, %loop.latch ] - %subscript.0 = phi i64 [ %n, %entry ], [ %subscript.0.next, %loop.latch ] - %subscript.1 = phi i64 [ -2, %entry ], [ %subscript.1.next, %loop.latch ] - %idx.0 = getelementptr inbounds i8, ptr %A, i64 %subscript.0 - store i8 0, ptr %idx.0 - %cond.store = icmp ne i64 %i, 0 - br i1 %cond.store, label %if.store, label %loop.latch - -if.store: - %idx.1 = getelementptr inbounds i8, ptr %A, i64 %subscript.1 - store i8 1, ptr %idx.1 - br label %loop.latch - -loop.latch: - %i.inc = add nuw nsw i64 %i, 1 - %subscript.0.next = add nsw i64 %subscript.0, -6 - %subscript.1.next = add nsw i64 %subscript.1, 3 - %exitcond = icmp sgt i64 %i.inc, %bound - br i1 %exitcond, label %exit, label %loop.header - -exit: - ret void -} diff --git a/llvm/test/Analysis/DependenceAnalysis/exact-siv-overflow.ll b/llvm/test/Analysis/DependenceAnalysis/exact-siv-overflow.ll new file mode 100644 index 0000000000000..59e2ed3c7e35f --- /dev/null +++ b/llvm/test/Analysis/DependenceAnalysis/exact-siv-overflow.ll @@ -0,0 +1,124 @@ +; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 6 +; RUN: opt < %s -disable-output "-passes=print" 2>&1 | FileCheck %s +; RUN: opt < %s -disable-output "-passes=print" -da-enable-dependence-test=exact-siv 2>&1 \ +; RUN: | FileCheck %s --check-prefix=CHECK-EXACT-SIV + +;; max_i = INT64_MAX/6 // 1537228672809129301 +;; for (long long i = 0; i <= max_i; i++) { +;; A[-6*i + INT64_MAX] = 0; +;; if (i) +;; A[3*i - 2] = 1; +;; } +;; +;; FIXME: DependencyAnalsysis currently detects no dependency between +;; `A[-6*i + INT64_MAX]` and `A[3*i - 2]`, but it does exist. For example, +;; +;; | memory location | -6*i + INT64_MAX | 3*i - 2 +;; |------------------------|------------------------|----------- +;; | A[1] | i = max_i | i = 1 +;; | A[4611686018427387901] | i = 768614336404564651 | i = max_i +;; +;; Actually, +;; * 1 = -6*max_i + INT64_MAX = 3*1 - 2 +;; * 4611686018427387901 = -6*768614336404564651 + INT64_MAX = 3*max_i - 2 +;; + +define void @exactsiv_const_ovfl(ptr %A) { +; CHECK-LABEL: 'exactsiv_const_ovfl' +; 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: Src: store i8 1, ptr %idx.1, align 1 --> Dst: store i8 1, ptr %idx.1, align 1 +; CHECK-NEXT: da analyze - none! +; +; CHECK-EXACT-SIV-LABEL: 'exactsiv_const_ovfl' +; CHECK-EXACT-SIV-NEXT: Src: store i8 0, ptr %idx.0, align 1 --> Dst: store i8 0, ptr %idx.0, align 1 +; CHECK-EXACT-SIV-NEXT: da analyze - consistent output [*]! +; CHECK-EXACT-SIV-NEXT: Src: store i8 0, ptr %idx.0, align 1 --> Dst: store i8 1, ptr %idx.1, align 1 +; CHECK-EXACT-SIV-NEXT: da analyze - output [*|<]! +; CHECK-EXACT-SIV-NEXT: Src: store i8 1, ptr %idx.1, align 1 --> Dst: store i8 1, ptr %idx.1, align 1 +; CHECK-EXACT-SIV-NEXT: da analyze - consistent output [*]! +; +entry: + br label %loop.header + +loop.header: + %i = phi i64 [ 0, %entry ], [ %i.inc, %loop.latch ] + %subscript.0 = phi i64 [ 9223372036854775807, %entry ], [ %subscript.0.next, %loop.latch ] + %subscript.1 = phi i64 [ -2, %entry ], [ %subscript.1.next, %loop.latch ] + %idx.0 = getelementptr inbounds i8, ptr %A, i64 %subscript.0 + store i8 0, ptr %idx.0 + %cond.store = icmp ne i64 %i, 0 + br i1 %cond.store, label %if.store, label %loop.latch + +if.store: + %idx.1 = getelementptr inbounds i8, ptr %A, i64 %subscript.1 + store i8 1, ptr %idx.1 + br label %loop.latch + +loop.latch: + %i.inc = add nuw nsw i64 %i, 1 + %subscript.0.next = add nsw i64 %subscript.0, -6 + %subscript.1.next = add nsw i64 %subscript.1, 3 + %exitcond = icmp sgt i64 %i.inc, 1537228672809129301 + br i1 %exitcond, label %exit, label %loop.header + +exit: + ret void +} + +;; A generalized version of the above case. +;; +;; for (long long i = 0; i <= n / 6; i++) { +;; A[-6*i + n] = 0; +;; if (i) +;; A[3*i - 2] = 1; +;; } + +define void @exactsiv_param_ovfl(ptr %A, i64 %n) { +; CHECK-LABEL: 'exactsiv_param_ovfl' +; 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 - 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! +; +; CHECK-EXACT-SIV-LABEL: 'exactsiv_param_ovfl' +; CHECK-EXACT-SIV-NEXT: Src: store i8 0, ptr %idx.0, align 1 --> Dst: store i8 0, ptr %idx.0, align 1 +; CHECK-EXACT-SIV-NEXT: da analyze - consistent output [*]! +; CHECK-EXACT-SIV-NEXT: Src: store i8 0, ptr %idx.0, align 1 --> Dst: store i8 1, ptr %idx.1, align 1 +; CHECK-EXACT-SIV-NEXT: da analyze - output [*|<]! +; CHECK-EXACT-SIV-NEXT: Src: store i8 1, ptr %idx.1, align 1 --> Dst: store i8 1, ptr %idx.1, align 1 +; CHECK-EXACT-SIV-NEXT: da analyze - consistent output [*]! +; +entry: + %bound = sdiv i64 %n, 6 + %guard = icmp sgt i64 %n, 0 + br i1 %guard, label %loop.header, label %exit + +loop.header: + %i = phi i64 [ 0, %entry ], [ %i.inc, %loop.latch ] + %subscript.0 = phi i64 [ %n, %entry ], [ %subscript.0.next, %loop.latch ] + %subscript.1 = phi i64 [ -2, %entry ], [ %subscript.1.next, %loop.latch ] + %idx.0 = getelementptr inbounds i8, ptr %A, i64 %subscript.0 + store i8 0, ptr %idx.0 + %cond.store = icmp ne i64 %i, 0 + br i1 %cond.store, label %if.store, label %loop.latch + +if.store: + %idx.1 = getelementptr inbounds i8, ptr %A, i64 %subscript.1 + store i8 1, ptr %idx.1 + br label %loop.latch + +loop.latch: + %i.inc = add nuw nsw i64 %i, 1 + %subscript.0.next = add nsw i64 %subscript.0, -6 + %subscript.1.next = add nsw i64 %subscript.1, 3 + %exitcond = icmp sgt i64 %i.inc, %bound + br i1 %exitcond, label %exit, label %loop.header + +exit: + ret void +} diff --git a/llvm/test/Analysis/DependenceAnalysis/run-specific-dependence-test.ll b/llvm/test/Analysis/DependenceAnalysis/run-specific-dependence-test.ll new file mode 100644 index 0000000000000..8bfbf930a9ef6 --- /dev/null +++ b/llvm/test/Analysis/DependenceAnalysis/run-specific-dependence-test.ll @@ -0,0 +1,783 @@ +; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 6 +; RUN: opt < %s -disable-output "-passes=print" -da-enable-dependence-test=all 2>&1 \ +; RUN: | FileCheck %s --check-prefix=CHECK-ALL +; RUN: opt < %s -disable-output "-passes=print" -da-enable-dependence-test=strong-siv 2>&1 \ +; RUN: | FileCheck %s --check-prefix=CHECK-STRONG-SIV +; RUN: opt < %s -disable-output "-passes=print" -da-enable-dependence-test=weak-crossing-siv 2>&1 \ +; RUN: | FileCheck %s --check-prefix=CHECK-WEAK-CROSSING-SIV +; RUN: opt < %s -disable-output "-passes=print" -da-enable-dependence-test=exact-siv 2>&1 \ +; RUN: | FileCheck %s --check-prefix=CHECK-EXACT-SIV +; RUN: opt < %s -disable-output "-passes=print" -da-enable-dependence-test=weak-zero-siv 2>&1 \ +; RUN: | FileCheck %s --check-prefix=CHECK-WEAK-ZERO-SIV +; RUN: opt < %s -disable-output "-passes=print" -da-enable-dependence-test=exact-rdiv 2>&1 \ +; RUN: | FileCheck %s --check-prefix=CHECK-EXACT-RDIV +; RUN: opt < %s -disable-output "-passes=print" -da-enable-dependence-test=symbolic-rdiv 2>&1 \ +; RUN: | FileCheck %s --check-prefix=CHECK-SYMBOLIC-RDIV +; RUN: opt < %s -disable-output "-passes=print" -da-enable-dependence-test=gcd-miv 2>&1 \ +; RUN: | FileCheck %s --check-prefix=CHECK-GCD-MIV +; RUN: opt < %s -disable-output "-passes=print" -da-enable-dependence-test=banerjee-miv 2>&1 \ +; RUN: | FileCheck %s --check-prefix=CHECK-BANERJEE-MIV + +; for (i = 0; i < 10; i++) +; a[i] = 0; +define void @strong_siv(ptr %a) { +; CHECK-ALL-LABEL: 'strong_siv' +; CHECK-ALL-NEXT: Src: store i8 0, ptr %gep, align 1 --> Dst: store i8 0, ptr %gep, align 1 +; CHECK-ALL-NEXT: da analyze - none! +; +; CHECK-STRONG-SIV-LABEL: 'strong_siv' +; CHECK-STRONG-SIV-NEXT: Src: store i8 0, ptr %gep, align 1 --> Dst: store i8 0, ptr %gep, align 1 +; CHECK-STRONG-SIV-NEXT: da analyze - none! +; +; CHECK-WEAK-CROSSING-SIV-LABEL: 'strong_siv' +; CHECK-WEAK-CROSSING-SIV-NEXT: Src: store i8 0, ptr %gep, align 1 --> Dst: store i8 0, ptr %gep, align 1 +; CHECK-WEAK-CROSSING-SIV-NEXT: da analyze - consistent output [*]! +; +; CHECK-EXACT-SIV-LABEL: 'strong_siv' +; CHECK-EXACT-SIV-NEXT: Src: store i8 0, ptr %gep, align 1 --> Dst: store i8 0, ptr %gep, align 1 +; CHECK-EXACT-SIV-NEXT: da analyze - consistent output [*]! +; +; CHECK-WEAK-ZERO-SIV-LABEL: 'strong_siv' +; CHECK-WEAK-ZERO-SIV-NEXT: Src: store i8 0, ptr %gep, align 1 --> Dst: store i8 0, ptr %gep, align 1 +; CHECK-WEAK-ZERO-SIV-NEXT: da analyze - consistent output [*]! +; +; CHECK-EXACT-RDIV-LABEL: 'strong_siv' +; CHECK-EXACT-RDIV-NEXT: Src: store i8 0, ptr %gep, align 1 --> Dst: store i8 0, ptr %gep, align 1 +; CHECK-EXACT-RDIV-NEXT: da analyze - consistent output [*]! +; +; CHECK-SYMBOLIC-RDIV-LABEL: 'strong_siv' +; CHECK-SYMBOLIC-RDIV-NEXT: Src: store i8 0, ptr %gep, align 1 --> Dst: store i8 0, ptr %gep, align 1 +; CHECK-SYMBOLIC-RDIV-NEXT: da analyze - consistent output [*]! +; +; CHECK-GCD-MIV-LABEL: 'strong_siv' +; CHECK-GCD-MIV-NEXT: Src: store i8 0, ptr %gep, align 1 --> Dst: store i8 0, ptr %gep, align 1 +; CHECK-GCD-MIV-NEXT: da analyze - consistent output [*]! +; +; CHECK-BANERJEE-MIV-LABEL: 'strong_siv' +; CHECK-BANERJEE-MIV-NEXT: Src: store i8 0, ptr %gep, align 1 --> Dst: store i8 0, ptr %gep, align 1 +; CHECK-BANERJEE-MIV-NEXT: da analyze - consistent output [*]! +; +entry: + br label %loop + +loop: + %i = phi i64 [ 0, %entry ], [ %i.inc, %loop ] + %gep = getelementptr i8, ptr %a, i64 %i + store i8 0, ptr %gep + %i.inc = add i64 %i, 1 + %ec = icmp eq i64 %i.inc, 10 + br i1 %ec, label %exit, label %loop + +exit: + ret void +} + +; for (i = 0; i < 10; i++) { +; a[i] = 1; +; a[10 - i] = 2; +; } +define void @weak_crossing_siv(ptr %a) { +; CHECK-ALL-LABEL: 'weak_crossing_siv' +; 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 - output [*|<] splitable! +; CHECK-ALL-NEXT: da analyze - split level = 1, iteration = 5! +; 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: 'weak_crossing_siv' +; 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 [*|<]! +; 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-WEAK-CROSSING-SIV-LABEL: 'weak_crossing_siv' +; CHECK-WEAK-CROSSING-SIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.0, align 1 +; CHECK-WEAK-CROSSING-SIV-NEXT: da analyze - consistent output [*]! +; CHECK-WEAK-CROSSING-SIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-WEAK-CROSSING-SIV-NEXT: da analyze - output [*|<] splitable! +; CHECK-WEAK-CROSSING-SIV-NEXT: da analyze - split level = 1, iteration = 5! +; CHECK-WEAK-CROSSING-SIV-NEXT: Src: store i8 2, ptr %gep.1, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-WEAK-CROSSING-SIV-NEXT: da analyze - consistent output [*]! +; +; CHECK-EXACT-SIV-LABEL: 'weak_crossing_siv' +; CHECK-EXACT-SIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.0, align 1 +; CHECK-EXACT-SIV-NEXT: da analyze - consistent output [*]! +; CHECK-EXACT-SIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-EXACT-SIV-NEXT: da analyze - consistent output [*|<]! +; CHECK-EXACT-SIV-NEXT: Src: store i8 2, ptr %gep.1, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-EXACT-SIV-NEXT: da analyze - consistent output [*]! +; +; CHECK-WEAK-ZERO-SIV-LABEL: 'weak_crossing_siv' +; CHECK-WEAK-ZERO-SIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.0, align 1 +; CHECK-WEAK-ZERO-SIV-NEXT: da analyze - consistent output [*]! +; CHECK-WEAK-ZERO-SIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-WEAK-ZERO-SIV-NEXT: da analyze - consistent output [*|<]! +; CHECK-WEAK-ZERO-SIV-NEXT: Src: store i8 2, ptr %gep.1, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-WEAK-ZERO-SIV-NEXT: da analyze - consistent output [*]! +; +; CHECK-EXACT-RDIV-LABEL: 'weak_crossing_siv' +; CHECK-EXACT-RDIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.0, align 1 +; CHECK-EXACT-RDIV-NEXT: da analyze - consistent output [*]! +; CHECK-EXACT-RDIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-EXACT-RDIV-NEXT: da analyze - consistent output [*|<]! +; CHECK-EXACT-RDIV-NEXT: Src: store i8 2, ptr %gep.1, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-EXACT-RDIV-NEXT: da analyze - consistent output [*]! +; +; CHECK-SYMBOLIC-RDIV-LABEL: 'weak_crossing_siv' +; 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 - 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 [*]! +; +; CHECK-GCD-MIV-LABEL: 'weak_crossing_siv' +; CHECK-GCD-MIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.0, align 1 +; CHECK-GCD-MIV-NEXT: da analyze - consistent output [*]! +; CHECK-GCD-MIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-GCD-MIV-NEXT: da analyze - consistent output [*|<]! +; CHECK-GCD-MIV-NEXT: Src: store i8 2, ptr %gep.1, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-GCD-MIV-NEXT: da analyze - consistent output [*]! +; +; CHECK-BANERJEE-MIV-LABEL: 'weak_crossing_siv' +; CHECK-BANERJEE-MIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.0, align 1 +; CHECK-BANERJEE-MIV-NEXT: da analyze - consistent output [*]! +; CHECK-BANERJEE-MIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-BANERJEE-MIV-NEXT: da analyze - consistent output [*|<]! +; CHECK-BANERJEE-MIV-NEXT: Src: store i8 2, ptr %gep.1, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-BANERJEE-MIV-NEXT: da analyze - consistent output [*]! +; +entry: + br label %loop + +loop: + %i = phi i64 [ 0, %entry ], [ %i.inc, %loop ] + %i.sub10 = sub i64 10, %i + %gep.0 = getelementptr i8, ptr %a, i64 %i + %gep.1 = getelementptr i8, ptr %a, i64 %i.sub10 + store i8 1, ptr %gep.0 + store i8 2, ptr %gep.1 + %i.inc = add i64 %i, 1 + %ec = icmp eq i64 %i.inc, 10 + br i1 %ec, label %exit, label %loop + +exit: + ret void +} + +; for (i = 0; i < 10; i++) { +; a[2 * i + 0] = 1; +; a[2 * i + 1] = 2; +; } +define void @exact_siv(ptr %a) { +; CHECK-ALL-LABEL: 'exact_siv' +; 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: 'exact_siv' +; 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 - none! +; 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-WEAK-CROSSING-SIV-LABEL: 'exact_siv' +; CHECK-WEAK-CROSSING-SIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.0, align 1 +; CHECK-WEAK-CROSSING-SIV-NEXT: da analyze - consistent output [*]! +; CHECK-WEAK-CROSSING-SIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-WEAK-CROSSING-SIV-NEXT: da analyze - consistent output [*|<]! +; CHECK-WEAK-CROSSING-SIV-NEXT: Src: store i8 2, ptr %gep.1, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-WEAK-CROSSING-SIV-NEXT: da analyze - consistent output [*]! +; +; CHECK-EXACT-SIV-LABEL: 'exact_siv' +; CHECK-EXACT-SIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.0, align 1 +; CHECK-EXACT-SIV-NEXT: da analyze - consistent output [*]! +; CHECK-EXACT-SIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-EXACT-SIV-NEXT: da analyze - consistent output [*|<]! +; CHECK-EXACT-SIV-NEXT: Src: store i8 2, ptr %gep.1, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-EXACT-SIV-NEXT: da analyze - consistent output [*]! +; +; CHECK-WEAK-ZERO-SIV-LABEL: 'exact_siv' +; CHECK-WEAK-ZERO-SIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.0, align 1 +; CHECK-WEAK-ZERO-SIV-NEXT: da analyze - consistent output [*]! +; CHECK-WEAK-ZERO-SIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-WEAK-ZERO-SIV-NEXT: da analyze - consistent output [*|<]! +; CHECK-WEAK-ZERO-SIV-NEXT: Src: store i8 2, ptr %gep.1, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-WEAK-ZERO-SIV-NEXT: da analyze - consistent output [*]! +; +; CHECK-EXACT-RDIV-LABEL: 'exact_siv' +; CHECK-EXACT-RDIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.0, align 1 +; CHECK-EXACT-RDIV-NEXT: da analyze - consistent output [*]! +; CHECK-EXACT-RDIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-EXACT-RDIV-NEXT: da analyze - consistent output [*|<]! +; CHECK-EXACT-RDIV-NEXT: Src: store i8 2, ptr %gep.1, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-EXACT-RDIV-NEXT: da analyze - consistent output [*]! +; +; CHECK-SYMBOLIC-RDIV-LABEL: 'exact_siv' +; 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 - 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 [*]! +; +; CHECK-GCD-MIV-LABEL: 'exact_siv' +; CHECK-GCD-MIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.0, align 1 +; CHECK-GCD-MIV-NEXT: da analyze - consistent output [*]! +; CHECK-GCD-MIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-GCD-MIV-NEXT: da analyze - none! +; CHECK-GCD-MIV-NEXT: Src: store i8 2, ptr %gep.1, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-GCD-MIV-NEXT: da analyze - consistent output [*]! +; +; CHECK-BANERJEE-MIV-LABEL: 'exact_siv' +; CHECK-BANERJEE-MIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.0, align 1 +; CHECK-BANERJEE-MIV-NEXT: da analyze - consistent output [*]! +; CHECK-BANERJEE-MIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-BANERJEE-MIV-NEXT: da analyze - consistent output [*|<]! +; CHECK-BANERJEE-MIV-NEXT: Src: store i8 2, ptr %gep.1, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-BANERJEE-MIV-NEXT: da analyze - consistent output [*]! +; +entry: + br label %loop + +loop: + %i = phi i64 [ 0, %entry ], [ %i.inc, %loop ] + %offset.0 = mul i64 2, %i + %offset.1 = add i64 %offset.0, 1 + %gep.0 = getelementptr i8, ptr %a, i64 %offset.0 + %gep.1 = getelementptr i8, ptr %a, i64 %offset.1 + store i8 1, ptr %gep.0 + store i8 2, ptr %gep.1 + %i.inc = add i64 %i, 1 + %ec = icmp eq i64 %i.inc, 10 + br i1 %ec, label %exit, label %loop + +exit: + ret void +} + +; for (i = 0; i < 10; i++) { +; a[10] = 1; +; a[i] = 2; +; } +define void @weak_zero_siv(ptr %a) { +; CHECK-ALL-LABEL: 'weak_zero_siv' +; 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 - consistent output [S]! +; 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: 'weak_zero_siv' +; 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 - consistent output [S]! +; 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 [*|<]! +; 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-WEAK-CROSSING-SIV-LABEL: 'weak_zero_siv' +; CHECK-WEAK-CROSSING-SIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.0, align 1 +; CHECK-WEAK-CROSSING-SIV-NEXT: da analyze - consistent output [S]! +; CHECK-WEAK-CROSSING-SIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-WEAK-CROSSING-SIV-NEXT: da analyze - consistent output [*|<]! +; CHECK-WEAK-CROSSING-SIV-NEXT: Src: store i8 2, ptr %gep.1, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-WEAK-CROSSING-SIV-NEXT: da analyze - consistent output [*]! +; +; CHECK-EXACT-SIV-LABEL: 'weak_zero_siv' +; CHECK-EXACT-SIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.0, align 1 +; CHECK-EXACT-SIV-NEXT: da analyze - consistent output [S]! +; CHECK-EXACT-SIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-EXACT-SIV-NEXT: da analyze - consistent output [*|<]! +; CHECK-EXACT-SIV-NEXT: Src: store i8 2, ptr %gep.1, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-EXACT-SIV-NEXT: da analyze - consistent output [*]! +; +; CHECK-WEAK-ZERO-SIV-LABEL: 'weak_zero_siv' +; CHECK-WEAK-ZERO-SIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.0, align 1 +; CHECK-WEAK-ZERO-SIV-NEXT: da analyze - consistent output [S]! +; CHECK-WEAK-ZERO-SIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-WEAK-ZERO-SIV-NEXT: da analyze - none! +; CHECK-WEAK-ZERO-SIV-NEXT: Src: store i8 2, ptr %gep.1, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-WEAK-ZERO-SIV-NEXT: da analyze - consistent output [*]! +; +; CHECK-EXACT-RDIV-LABEL: 'weak_zero_siv' +; CHECK-EXACT-RDIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.0, align 1 +; CHECK-EXACT-RDIV-NEXT: da analyze - consistent output [S]! +; CHECK-EXACT-RDIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-EXACT-RDIV-NEXT: da analyze - consistent output [*|<]! +; CHECK-EXACT-RDIV-NEXT: Src: store i8 2, ptr %gep.1, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-EXACT-RDIV-NEXT: da analyze - consistent output [*]! +; +; CHECK-SYMBOLIC-RDIV-LABEL: 'weak_zero_siv' +; 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 [S]! +; 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 - 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 [*]! +; +; CHECK-GCD-MIV-LABEL: 'weak_zero_siv' +; CHECK-GCD-MIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.0, align 1 +; CHECK-GCD-MIV-NEXT: da analyze - consistent output [S]! +; CHECK-GCD-MIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-GCD-MIV-NEXT: da analyze - consistent output [*|<]! +; CHECK-GCD-MIV-NEXT: Src: store i8 2, ptr %gep.1, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-GCD-MIV-NEXT: da analyze - consistent output [*]! +; +; CHECK-BANERJEE-MIV-LABEL: 'weak_zero_siv' +; CHECK-BANERJEE-MIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.0, align 1 +; CHECK-BANERJEE-MIV-NEXT: da analyze - consistent output [S]! +; CHECK-BANERJEE-MIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-BANERJEE-MIV-NEXT: da analyze - consistent output [*|<]! +; CHECK-BANERJEE-MIV-NEXT: Src: store i8 2, ptr %gep.1, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-BANERJEE-MIV-NEXT: da analyze - consistent output [*]! +; +entry: + br label %loop + +loop: + %i = phi i64 [ 0, %entry ], [ %i.inc, %loop ] + %gep.0 = getelementptr i8, ptr %a, i64 10 + %gep.1 = getelementptr i8, ptr %a, i64 %i + store i8 1, ptr %gep.0 + store i8 2, ptr %gep.1 + %i.inc = add i64 %i, 1 + %ec = icmp eq i64 %i.inc, 10 + br i1 %ec, label %exit, label %loop + +exit: + ret void +} + +; for (i = 0; i < 10; i++) +; a[2 * i + 0] = 1; +; for (i = 0; i < 20; i++) +; a[2 * i + 1] = 2; +define void @exact_rdiv(ptr %a) { +; CHECK-ALL-LABEL: 'exact_rdiv' +; 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: 'exact_rdiv' +; 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 [|<]! +; 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-WEAK-CROSSING-SIV-LABEL: 'exact_rdiv' +; CHECK-WEAK-CROSSING-SIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.0, align 1 +; CHECK-WEAK-CROSSING-SIV-NEXT: da analyze - consistent output [*]! +; CHECK-WEAK-CROSSING-SIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-WEAK-CROSSING-SIV-NEXT: da analyze - consistent output [|<]! +; CHECK-WEAK-CROSSING-SIV-NEXT: Src: store i8 2, ptr %gep.1, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-WEAK-CROSSING-SIV-NEXT: da analyze - consistent output [*]! +; +; CHECK-EXACT-SIV-LABEL: 'exact_rdiv' +; CHECK-EXACT-SIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.0, align 1 +; CHECK-EXACT-SIV-NEXT: da analyze - consistent output [*]! +; CHECK-EXACT-SIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-EXACT-SIV-NEXT: da analyze - consistent output [|<]! +; CHECK-EXACT-SIV-NEXT: Src: store i8 2, ptr %gep.1, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-EXACT-SIV-NEXT: da analyze - consistent output [*]! +; +; CHECK-WEAK-ZERO-SIV-LABEL: 'exact_rdiv' +; CHECK-WEAK-ZERO-SIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.0, align 1 +; CHECK-WEAK-ZERO-SIV-NEXT: da analyze - consistent output [*]! +; CHECK-WEAK-ZERO-SIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-WEAK-ZERO-SIV-NEXT: da analyze - consistent output [|<]! +; CHECK-WEAK-ZERO-SIV-NEXT: Src: store i8 2, ptr %gep.1, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-WEAK-ZERO-SIV-NEXT: da analyze - consistent output [*]! +; +; CHECK-EXACT-RDIV-LABEL: 'exact_rdiv' +; CHECK-EXACT-RDIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.0, align 1 +; CHECK-EXACT-RDIV-NEXT: da analyze - consistent output [*]! +; CHECK-EXACT-RDIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-EXACT-RDIV-NEXT: da analyze - none! +; CHECK-EXACT-RDIV-NEXT: Src: store i8 2, ptr %gep.1, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-EXACT-RDIV-NEXT: da analyze - consistent output [*]! +; +; CHECK-SYMBOLIC-RDIV-LABEL: 'exact_rdiv' +; 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 - 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 [*]! +; +; CHECK-GCD-MIV-LABEL: 'exact_rdiv' +; CHECK-GCD-MIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.0, align 1 +; CHECK-GCD-MIV-NEXT: da analyze - consistent output [*]! +; CHECK-GCD-MIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-GCD-MIV-NEXT: da analyze - none! +; CHECK-GCD-MIV-NEXT: Src: store i8 2, ptr %gep.1, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-GCD-MIV-NEXT: da analyze - consistent output [*]! +; +; CHECK-BANERJEE-MIV-LABEL: 'exact_rdiv' +; CHECK-BANERJEE-MIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.0, align 1 +; CHECK-BANERJEE-MIV-NEXT: da analyze - consistent output [*]! +; CHECK-BANERJEE-MIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-BANERJEE-MIV-NEXT: da analyze - consistent output [|<]! +; CHECK-BANERJEE-MIV-NEXT: Src: store i8 2, ptr %gep.1, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-BANERJEE-MIV-NEXT: da analyze - consistent output [*]! +; +entry: + br label %loop.0 + +loop.0: + %i.0 = phi i64 [ 0, %entry ], [ %i.0.inc, %loop.0 ] + %offset.0 = phi i64 [ 0, %entry ], [ %offset.0.next, %loop.0 ] + %gep.0 = getelementptr i8, ptr %a, i64 %offset.0 + store i8 1, ptr %gep.0 + %i.0.inc = add i64 %i.0, 1 + %offset.0.next = add i64 %offset.0, 2 + %ec.0 = icmp eq i64 %i.0.inc, 10 + br i1 %ec.0, label %loop.1, label %loop.0 + +loop.1: + %i.1 = phi i64 [ 0, %loop.0 ], [ %i.1.inc, %loop.1 ] + %offset.1 = phi i64 [ 1, %loop.0 ], [ %offset.1.next, %loop.1 ] + %gep.1 = getelementptr i8, ptr %a, i64 %offset.1 + store i8 2, ptr %gep.1 + %i.1.inc = add i64 %i.1, 1 + %offset.1.next = add i64 %offset.1, 2 + %ec.1 = icmp eq i64 %i.1.inc, 20 + br i1 %ec.1, label %exit, label %loop.1 + +exit: + ret void +} + +; for (i = 0; i < 10; i++) +; a[i + 1] = 1; +; for (i = 0; i < 20; i++) +; a[-i] = 2; +define void @symbolic_rdiv(ptr %a) { +; CHECK-ALL-LABEL: 'symbolic_rdiv' +; 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: 'symbolic_rdiv' +; 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 [|<]! +; 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-WEAK-CROSSING-SIV-LABEL: 'symbolic_rdiv' +; CHECK-WEAK-CROSSING-SIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.0, align 1 +; CHECK-WEAK-CROSSING-SIV-NEXT: da analyze - consistent output [*]! +; CHECK-WEAK-CROSSING-SIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-WEAK-CROSSING-SIV-NEXT: da analyze - consistent output [|<]! +; CHECK-WEAK-CROSSING-SIV-NEXT: Src: store i8 2, ptr %gep.1, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-WEAK-CROSSING-SIV-NEXT: da analyze - consistent output [*]! +; +; CHECK-EXACT-SIV-LABEL: 'symbolic_rdiv' +; CHECK-EXACT-SIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.0, align 1 +; CHECK-EXACT-SIV-NEXT: da analyze - consistent output [*]! +; CHECK-EXACT-SIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-EXACT-SIV-NEXT: da analyze - consistent output [|<]! +; CHECK-EXACT-SIV-NEXT: Src: store i8 2, ptr %gep.1, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-EXACT-SIV-NEXT: da analyze - consistent output [*]! +; +; CHECK-WEAK-ZERO-SIV-LABEL: 'symbolic_rdiv' +; CHECK-WEAK-ZERO-SIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.0, align 1 +; CHECK-WEAK-ZERO-SIV-NEXT: da analyze - consistent output [*]! +; CHECK-WEAK-ZERO-SIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-WEAK-ZERO-SIV-NEXT: da analyze - consistent output [|<]! +; CHECK-WEAK-ZERO-SIV-NEXT: Src: store i8 2, ptr %gep.1, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-WEAK-ZERO-SIV-NEXT: da analyze - consistent output [*]! +; +; CHECK-EXACT-RDIV-LABEL: 'symbolic_rdiv' +; CHECK-EXACT-RDIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.0, align 1 +; CHECK-EXACT-RDIV-NEXT: da analyze - consistent output [*]! +; CHECK-EXACT-RDIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-EXACT-RDIV-NEXT: da analyze - none! +; CHECK-EXACT-RDIV-NEXT: Src: store i8 2, ptr %gep.1, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-EXACT-RDIV-NEXT: da analyze - consistent output [*]! +; +; CHECK-SYMBOLIC-RDIV-LABEL: 'symbolic_rdiv' +; 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: 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 [*]! +; +; CHECK-GCD-MIV-LABEL: 'symbolic_rdiv' +; CHECK-GCD-MIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.0, align 1 +; CHECK-GCD-MIV-NEXT: da analyze - consistent output [*]! +; CHECK-GCD-MIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-GCD-MIV-NEXT: da analyze - consistent output [|<]! +; CHECK-GCD-MIV-NEXT: Src: store i8 2, ptr %gep.1, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-GCD-MIV-NEXT: da analyze - consistent output [*]! +; +; CHECK-BANERJEE-MIV-LABEL: 'symbolic_rdiv' +; CHECK-BANERJEE-MIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.0, align 1 +; CHECK-BANERJEE-MIV-NEXT: da analyze - consistent output [*]! +; CHECK-BANERJEE-MIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-BANERJEE-MIV-NEXT: da analyze - consistent output [|<]! +; CHECK-BANERJEE-MIV-NEXT: Src: store i8 2, ptr %gep.1, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-BANERJEE-MIV-NEXT: da analyze - consistent output [*]! +; +entry: + br label %loop.0 + +loop.0: + %i.0 = phi i64 [ 0, %entry ], [ %i.0.inc, %loop.0 ] + %i.0.inc = add i64 %i.0, 1 + %gep.0 = getelementptr i8, ptr %a, i64 %i.0.inc + store i8 1, ptr %gep.0 + %ec.0 = icmp eq i64 %i.0.inc, 10 + br i1 %ec.0, label %loop.1, label %loop.0 + +loop.1: + %i.1 = phi i64 [ 0, %loop.0 ], [ %i.1.inc, %loop.1 ] + %i.1.neg = sub i64 0, %i.1 + %gep.1 = getelementptr i8, ptr %a, i64 %i.1.neg + store i8 2, ptr %gep.1 + %i.1.inc = add i64 %i.1, 1 + %ec.1 = icmp eq i64 %i.1.inc, 20 + br i1 %ec.1, label %exit, label %loop.1 + +exit: + ret void +} + +; for (i = 0; i < 10; i++) +; for (j = 0; j < 10; j++) { +; a[2*i + 2*j + 0] = 1; +; a[2*i + 2*j + 1] = 2; +; } +define void @gcd_miv(ptr %a) { +; CHECK-ALL-LABEL: 'gcd_miv' +; 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 - output [* *]! +; 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 - output [* *]! +; +; CHECK-STRONG-SIV-LABEL: 'gcd_miv' +; 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 - output [* *]! +; 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 - output [* *|<]! +; 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 - output [* *]! +; +; CHECK-WEAK-CROSSING-SIV-LABEL: 'gcd_miv' +; CHECK-WEAK-CROSSING-SIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.0, align 1 +; CHECK-WEAK-CROSSING-SIV-NEXT: da analyze - output [* *]! +; CHECK-WEAK-CROSSING-SIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-WEAK-CROSSING-SIV-NEXT: da analyze - output [* *|<]! +; CHECK-WEAK-CROSSING-SIV-NEXT: Src: store i8 2, ptr %gep.1, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-WEAK-CROSSING-SIV-NEXT: da analyze - output [* *]! +; +; CHECK-EXACT-SIV-LABEL: 'gcd_miv' +; CHECK-EXACT-SIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.0, align 1 +; CHECK-EXACT-SIV-NEXT: da analyze - output [* *]! +; CHECK-EXACT-SIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-EXACT-SIV-NEXT: da analyze - output [* *|<]! +; CHECK-EXACT-SIV-NEXT: Src: store i8 2, ptr %gep.1, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-EXACT-SIV-NEXT: da analyze - output [* *]! +; +; CHECK-WEAK-ZERO-SIV-LABEL: 'gcd_miv' +; CHECK-WEAK-ZERO-SIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.0, align 1 +; CHECK-WEAK-ZERO-SIV-NEXT: da analyze - output [* *]! +; CHECK-WEAK-ZERO-SIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-WEAK-ZERO-SIV-NEXT: da analyze - output [* *|<]! +; CHECK-WEAK-ZERO-SIV-NEXT: Src: store i8 2, ptr %gep.1, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-WEAK-ZERO-SIV-NEXT: da analyze - output [* *]! +; +; CHECK-EXACT-RDIV-LABEL: 'gcd_miv' +; CHECK-EXACT-RDIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.0, align 1 +; CHECK-EXACT-RDIV-NEXT: da analyze - output [* *]! +; CHECK-EXACT-RDIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-EXACT-RDIV-NEXT: da analyze - output [* *|<]! +; CHECK-EXACT-RDIV-NEXT: Src: store i8 2, ptr %gep.1, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-EXACT-RDIV-NEXT: da analyze - output [* *]! +; +; CHECK-SYMBOLIC-RDIV-LABEL: 'gcd_miv' +; 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 - 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 - 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 - output [* *]! +; +; CHECK-GCD-MIV-LABEL: 'gcd_miv' +; CHECK-GCD-MIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.0, align 1 +; CHECK-GCD-MIV-NEXT: da analyze - output [* *]! +; CHECK-GCD-MIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-GCD-MIV-NEXT: da analyze - none! +; CHECK-GCD-MIV-NEXT: Src: store i8 2, ptr %gep.1, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-GCD-MIV-NEXT: da analyze - output [* *]! +; +; CHECK-BANERJEE-MIV-LABEL: 'gcd_miv' +; CHECK-BANERJEE-MIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.0, align 1 +; CHECK-BANERJEE-MIV-NEXT: da analyze - output [* *]! +; CHECK-BANERJEE-MIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-BANERJEE-MIV-NEXT: da analyze - output [<> <>]! +; CHECK-BANERJEE-MIV-NEXT: Src: store i8 2, ptr %gep.1, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-BANERJEE-MIV-NEXT: da analyze - output [* *]! +; +entry: + br label %loop.i.header + +loop.i.header: + %i = phi i64 [ 0, %entry ], [ %i.inc, %loop.i.latch ] + %offset.0.i = phi i64 [ 0, %entry ], [ %offset.0.i.next, %loop.i.latch ] + %offset.1.i = phi i64 [ 1, %entry ], [ %offset.1.i.next, %loop.i.latch ] + br label %loop.j + +loop.j: + %j = phi i64 [ 0, %loop.i.header ], [ %j.inc, %loop.j ] + %offset.0 = phi i64 [ %offset.0.i, %loop.i.header ], [ %offset.0.next, %loop.j ] + %offset.1 = phi i64 [ %offset.1.i, %loop.i.header ], [ %offset.1.next, %loop.j ] + %gep.0 = getelementptr i8, ptr %a, i64 %offset.0 + %gep.1 = getelementptr i8, ptr %a, i64 %offset.1 + store i8 1, ptr %gep.0 + store i8 2, ptr %gep.1 + %j.inc = add i64 %j, 1 + %offset.0.next = add i64 %offset.0, 2 + %offset.1.next = add i64 %offset.1, 2 + %ec.j = icmp eq i64 %j.inc, 10 + br i1 %ec.j, label %loop.i.latch, label %loop.j + +loop.i.latch: + %i.inc = add i64 %i, 1 + %offset.0.i.next = add i64 %offset.0.i, 2 + %offset.1.i.next = add i64 %offset.1.i, 2 + %ec.i = icmp eq i64 %i.inc, 10 + br i1 %ec.i, label %exit, label %loop.i.header + +exit: + ret void +} + +; for (i = 0; i < 10; i++) +; for (j = 0; j < 10; j++) { +; a[i + j] = 1; +; a[i + j + 100] = 2; +; } +define void @banerjee_miv(ptr %a) { +; CHECK-ALL-LABEL: 'banerjee_miv' +; 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 - output [* *]! +; 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 - output [* *]! +; +; CHECK-STRONG-SIV-LABEL: 'banerjee_miv' +; 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 - output [* *]! +; 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 - output [* *|<]! +; 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 - output [* *]! +; +; CHECK-WEAK-CROSSING-SIV-LABEL: 'banerjee_miv' +; CHECK-WEAK-CROSSING-SIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.0, align 1 +; CHECK-WEAK-CROSSING-SIV-NEXT: da analyze - output [* *]! +; CHECK-WEAK-CROSSING-SIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-WEAK-CROSSING-SIV-NEXT: da analyze - output [* *|<]! +; CHECK-WEAK-CROSSING-SIV-NEXT: Src: store i8 2, ptr %gep.1, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-WEAK-CROSSING-SIV-NEXT: da analyze - output [* *]! +; +; CHECK-EXACT-SIV-LABEL: 'banerjee_miv' +; CHECK-EXACT-SIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.0, align 1 +; CHECK-EXACT-SIV-NEXT: da analyze - output [* *]! +; CHECK-EXACT-SIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-EXACT-SIV-NEXT: da analyze - output [* *|<]! +; CHECK-EXACT-SIV-NEXT: Src: store i8 2, ptr %gep.1, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-EXACT-SIV-NEXT: da analyze - output [* *]! +; +; CHECK-WEAK-ZERO-SIV-LABEL: 'banerjee_miv' +; CHECK-WEAK-ZERO-SIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.0, align 1 +; CHECK-WEAK-ZERO-SIV-NEXT: da analyze - output [* *]! +; CHECK-WEAK-ZERO-SIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-WEAK-ZERO-SIV-NEXT: da analyze - output [* *|<]! +; CHECK-WEAK-ZERO-SIV-NEXT: Src: store i8 2, ptr %gep.1, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-WEAK-ZERO-SIV-NEXT: da analyze - output [* *]! +; +; CHECK-EXACT-RDIV-LABEL: 'banerjee_miv' +; CHECK-EXACT-RDIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.0, align 1 +; CHECK-EXACT-RDIV-NEXT: da analyze - output [* *]! +; CHECK-EXACT-RDIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-EXACT-RDIV-NEXT: da analyze - output [* *|<]! +; CHECK-EXACT-RDIV-NEXT: Src: store i8 2, ptr %gep.1, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-EXACT-RDIV-NEXT: da analyze - output [* *]! +; +; CHECK-SYMBOLIC-RDIV-LABEL: 'banerjee_miv' +; 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 - 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 - 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 - output [* *]! +; +; CHECK-GCD-MIV-LABEL: 'banerjee_miv' +; CHECK-GCD-MIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.0, align 1 +; CHECK-GCD-MIV-NEXT: da analyze - output [* *]! +; CHECK-GCD-MIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-GCD-MIV-NEXT: da analyze - output [* *|<]! +; CHECK-GCD-MIV-NEXT: Src: store i8 2, ptr %gep.1, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-GCD-MIV-NEXT: da analyze - output [* *]! +; +; CHECK-BANERJEE-MIV-LABEL: 'banerjee_miv' +; CHECK-BANERJEE-MIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.0, align 1 +; CHECK-BANERJEE-MIV-NEXT: da analyze - output [* *]! +; CHECK-BANERJEE-MIV-NEXT: Src: store i8 1, ptr %gep.0, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-BANERJEE-MIV-NEXT: da analyze - none! +; CHECK-BANERJEE-MIV-NEXT: Src: store i8 2, ptr %gep.1, align 1 --> Dst: store i8 2, ptr %gep.1, align 1 +; CHECK-BANERJEE-MIV-NEXT: da analyze - output [* *]! +; +entry: + br label %loop.i.header + +loop.i.header: + %i = phi i64 [ 0, %entry ], [ %i.inc, %loop.i.latch ] + br label %loop.j + +loop.j: + %j = phi i64 [ 0, %loop.i.header ], [ %j.inc, %loop.j ] + %offset.0 = add i64 %i, %j + %offset.1 = add i64 %offset.0, 100 + %gep.0 = getelementptr i8, ptr %a, i64 %offset.0 + %gep.1 = getelementptr i8, ptr %a, i64 %offset.1 + store i8 1, ptr %gep.0 + store i8 2, ptr %gep.1 + %j.inc = add i64 %j, 1 + %ec.j = icmp eq i64 %j.inc, 10 + br i1 %ec.j, label %loop.i.latch, label %loop.j + +loop.i.latch: + %i.inc = add i64 %i, 1 + %ec.i = icmp eq i64 %i.inc, 10 + br i1 %ec.i, label %exit, label %loop.i.header + +exit: + ret void +}