From 6482263d9bd6156fa43be3d85d1fd5c94994ae75 Mon Sep 17 00:00:00 2001 From: a00917109 Date: Wed, 22 Oct 2025 15:41:15 -0400 Subject: [PATCH] [DA] Check if the multiplication overflows in strong SIV test --- llvm/lib/Analysis/DependenceAnalysis.cpp | 13 +- .../Analysis/DependenceAnalysis/StrongSIV.ll | 206 ++++++++++++++++++ 2 files changed, 218 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Analysis/DependenceAnalysis.cpp b/llvm/lib/Analysis/DependenceAnalysis.cpp index a572eefddd20e..4592b34e85d22 100644 --- a/llvm/lib/Analysis/DependenceAnalysis.cpp +++ b/llvm/lib/Analysis/DependenceAnalysis.cpp @@ -1582,6 +1582,15 @@ 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. @@ -1697,7 +1706,9 @@ bool DependenceInfo::strongSIVtest(const SCEV *Coeff, const SCEV *SrcConst, const SCEV *AbsCoeff = absSCEVNoSignedOverflow(Coeff, *SE); if (!AbsDelta || !AbsCoeff) return false; - const SCEV *Product = SE->getMulExpr(UpperBound, AbsCoeff); + const SCEV *Product = mulSCEVNoSignedOverflow(UpperBound, AbsCoeff, *SE); + if (!Product) + return false; return isKnownPredicate(CmpInst::ICMP_SGT, AbsDelta, Product); }(); if (IsDeltaLarge) { diff --git a/llvm/test/Analysis/DependenceAnalysis/StrongSIV.ll b/llvm/test/Analysis/DependenceAnalysis/StrongSIV.ll index 44bd9b7727910..3aec8e1ccabac 100644 --- a/llvm/test/Analysis/DependenceAnalysis/StrongSIV.ll +++ b/llvm/test/Analysis/DependenceAnalysis/StrongSIV.ll @@ -1,6 +1,8 @@ ; 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" -aa-pipeline=basic-aa -da-enable-dependence-test=strong-siv 2>&1 \ +; RUN: | FileCheck %s --check-prefix=CHECK-STRONG-SIV 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" @@ -25,6 +27,20 @@ define void @strong0(ptr %A, ptr %B, i64 %n) nounwind uwtable ssp { ; CHECK-NEXT: Src: store i32 %2, ptr %B.addr.02, align 4 --> Dst: store i32 %2, ptr %B.addr.02, align 4 ; CHECK-NEXT: da analyze - none! ; +; CHECK-STRONG-SIV-LABEL: 'strong0' +; CHECK-STRONG-SIV-NEXT: Src: store i32 %1, ptr %arrayidx, align 4 --> Dst: store i32 %1, ptr %arrayidx, align 4 +; CHECK-STRONG-SIV-NEXT: da analyze - none! +; CHECK-STRONG-SIV-NEXT: Src: store i32 %1, ptr %arrayidx, align 4 --> Dst: %2 = load i32, ptr %arrayidx3, align 4 +; CHECK-STRONG-SIV-NEXT: da analyze - consistent flow [2]! +; CHECK-STRONG-SIV-NEXT: Src: store i32 %1, ptr %arrayidx, align 4 --> Dst: store i32 %2, ptr %B.addr.02, align 4 +; CHECK-STRONG-SIV-NEXT: da analyze - confused! +; CHECK-STRONG-SIV-NEXT: Src: %2 = load i32, ptr %arrayidx3, align 4 --> Dst: %2 = load i32, ptr %arrayidx3, align 4 +; CHECK-STRONG-SIV-NEXT: da analyze - none! +; CHECK-STRONG-SIV-NEXT: Src: %2 = load i32, ptr %arrayidx3, align 4 --> Dst: store i32 %2, ptr %B.addr.02, align 4 +; CHECK-STRONG-SIV-NEXT: da analyze - confused! +; CHECK-STRONG-SIV-NEXT: Src: store i32 %2, ptr %B.addr.02, align 4 --> Dst: store i32 %2, ptr %B.addr.02, align 4 +; CHECK-STRONG-SIV-NEXT: da analyze - none! +; entry: %cmp1 = icmp sgt i64 %n, 0 br i1 %cmp1, label %for.body.preheader, label %for.end @@ -74,6 +90,20 @@ define void @strong1(ptr %A, ptr %B, i32 %n) nounwind uwtable ssp { ; 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-STRONG-SIV-LABEL: 'strong1' +; CHECK-STRONG-SIV-NEXT: Src: store i32 %conv2, ptr %arrayidx, align 4 --> Dst: store i32 %conv2, ptr %arrayidx, align 4 +; CHECK-STRONG-SIV-NEXT: da analyze - none! +; CHECK-STRONG-SIV-NEXT: Src: store i32 %conv2, ptr %arrayidx, align 4 --> Dst: %1 = load i32, ptr %arrayidx3, align 4 +; CHECK-STRONG-SIV-NEXT: da analyze - consistent flow [2]! +; CHECK-STRONG-SIV-NEXT: Src: store i32 %conv2, ptr %arrayidx, align 4 --> Dst: store i32 %1, ptr %B.addr.02, align 4 +; CHECK-STRONG-SIV-NEXT: da analyze - confused! +; CHECK-STRONG-SIV-NEXT: Src: %1 = load i32, ptr %arrayidx3, align 4 --> Dst: %1 = load i32, ptr %arrayidx3, align 4 +; CHECK-STRONG-SIV-NEXT: da analyze - none! +; CHECK-STRONG-SIV-NEXT: Src: %1 = load i32, ptr %arrayidx3, align 4 --> Dst: store i32 %1, ptr %B.addr.02, align 4 +; CHECK-STRONG-SIV-NEXT: da analyze - confused! +; CHECK-STRONG-SIV-NEXT: Src: store i32 %1, ptr %B.addr.02, align 4 --> Dst: store i32 %1, ptr %B.addr.02, align 4 +; CHECK-STRONG-SIV-NEXT: da analyze - none! +; entry: %cmp1 = icmp sgt i32 %n, 0 br i1 %cmp1, label %for.body.preheader, label %for.end @@ -124,6 +154,20 @@ define void @strong2(ptr %A, ptr %B, i64 %n) nounwind uwtable ssp { ; 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-STRONG-SIV-LABEL: 'strong2' +; 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: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx1, align 4 +; CHECK-STRONG-SIV-NEXT: da analyze - consistent flow [2]! +; 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 %arrayidx1, align 4 --> Dst: %0 = load i32, ptr %arrayidx1, align 4 +; CHECK-STRONG-SIV-NEXT: da analyze - none! +; CHECK-STRONG-SIV-NEXT: Src: %0 = load i32, ptr %arrayidx1, 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! +; entry: %cmp1 = icmp eq i64 %n, 0 br i1 %cmp1, label %for.end, label %for.body.preheader @@ -173,6 +217,20 @@ define void @strong3(ptr %A, ptr %B, i32 %n) nounwind uwtable ssp { ; CHECK-NEXT: Src: store i32 %2, ptr %B.addr.02, align 4 --> Dst: store i32 %2, ptr %B.addr.02, align 4 ; CHECK-NEXT: da analyze - none! ; +; CHECK-STRONG-SIV-LABEL: 'strong3' +; CHECK-STRONG-SIV-NEXT: Src: store i32 %1, ptr %arrayidx, align 4 --> Dst: store i32 %1, ptr %arrayidx, align 4 +; CHECK-STRONG-SIV-NEXT: da analyze - none! +; CHECK-STRONG-SIV-NEXT: Src: store i32 %1, ptr %arrayidx, align 4 --> Dst: %2 = load i32, ptr %arrayidx2, align 4 +; CHECK-STRONG-SIV-NEXT: da analyze - consistent flow [2]! +; CHECK-STRONG-SIV-NEXT: Src: store i32 %1, ptr %arrayidx, align 4 --> Dst: store i32 %2, ptr %B.addr.02, align 4 +; CHECK-STRONG-SIV-NEXT: da analyze - confused! +; CHECK-STRONG-SIV-NEXT: Src: %2 = load i32, ptr %arrayidx2, align 4 --> Dst: %2 = load i32, ptr %arrayidx2, align 4 +; CHECK-STRONG-SIV-NEXT: da analyze - none! +; CHECK-STRONG-SIV-NEXT: Src: %2 = load i32, ptr %arrayidx2, align 4 --> Dst: store i32 %2, ptr %B.addr.02, align 4 +; CHECK-STRONG-SIV-NEXT: da analyze - confused! +; CHECK-STRONG-SIV-NEXT: Src: store i32 %2, ptr %B.addr.02, align 4 --> Dst: store i32 %2, ptr %B.addr.02, align 4 +; CHECK-STRONG-SIV-NEXT: da analyze - none! +; entry: %cmp1 = icmp sgt i32 %n, 0 br i1 %cmp1, label %for.body.preheader, label %for.end @@ -223,6 +281,20 @@ define void @strong4(ptr %A, ptr %B, i64 %n) 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-STRONG-SIV-LABEL: 'strong4' +; 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: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx1, align 4 +; CHECK-STRONG-SIV-NEXT: da analyze - none! +; CHECK-STRONG-SIV-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 +; CHECK-STRONG-SIV-NEXT: da analyze - confused! +; CHECK-STRONG-SIV-NEXT: Src: %0 = load i32, ptr %arrayidx1, align 4 --> Dst: %0 = load i32, ptr %arrayidx1, align 4 +; CHECK-STRONG-SIV-NEXT: da analyze - none! +; CHECK-STRONG-SIV-NEXT: Src: %0 = load i32, ptr %arrayidx1, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 +; CHECK-STRONG-SIV-NEXT: da analyze - confused! +; CHECK-STRONG-SIV-NEXT: Src: store i32 %0, ptr %B.addr.01, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 +; CHECK-STRONG-SIV-NEXT: da analyze - none! +; entry: br label %for.body @@ -265,6 +337,20 @@ define void @strong5(ptr %A, ptr %B, i64 %n) 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-STRONG-SIV-LABEL: 'strong5' +; 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: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx1, align 4 +; CHECK-STRONG-SIV-NEXT: da analyze - consistent flow [19]! +; CHECK-STRONG-SIV-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 +; CHECK-STRONG-SIV-NEXT: da analyze - confused! +; CHECK-STRONG-SIV-NEXT: Src: %0 = load i32, ptr %arrayidx1, align 4 --> Dst: %0 = load i32, ptr %arrayidx1, align 4 +; CHECK-STRONG-SIV-NEXT: da analyze - none! +; CHECK-STRONG-SIV-NEXT: Src: %0 = load i32, ptr %arrayidx1, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 +; CHECK-STRONG-SIV-NEXT: da analyze - confused! +; CHECK-STRONG-SIV-NEXT: Src: store i32 %0, ptr %B.addr.01, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 +; CHECK-STRONG-SIV-NEXT: da analyze - none! +; entry: br label %for.body @@ -307,6 +393,20 @@ define void @strong6(ptr %A, ptr %B, i64 %n) 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-STRONG-SIV-LABEL: 'strong6' +; 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: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx2, align 4 +; CHECK-STRONG-SIV-NEXT: da analyze - consistent flow [3]! +; CHECK-STRONG-SIV-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %0, ptr %B.addr.01, 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: Src: %0 = load i32, ptr %arrayidx2, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 +; CHECK-STRONG-SIV-NEXT: da analyze - confused! +; CHECK-STRONG-SIV-NEXT: Src: store i32 %0, ptr %B.addr.01, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 +; CHECK-STRONG-SIV-NEXT: da analyze - none! +; entry: br label %for.body @@ -351,6 +451,20 @@ define void @strong7(ptr %A, ptr %B, i64 %n) 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-STRONG-SIV-LABEL: 'strong7' +; 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: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx2, align 4 +; CHECK-STRONG-SIV-NEXT: da analyze - none! +; CHECK-STRONG-SIV-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %0, ptr %B.addr.01, 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: Src: %0 = load i32, ptr %arrayidx2, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 +; CHECK-STRONG-SIV-NEXT: da analyze - confused! +; CHECK-STRONG-SIV-NEXT: Src: store i32 %0, ptr %B.addr.01, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 +; CHECK-STRONG-SIV-NEXT: da analyze - none! +; entry: br label %for.body @@ -395,6 +509,20 @@ define void @strong8(ptr %A, ptr %B, i64 %n) 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-STRONG-SIV-LABEL: 'strong8' +; 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: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx1, align 4 +; CHECK-STRONG-SIV-NEXT: da analyze - flow [*|<]! +; CHECK-STRONG-SIV-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 +; CHECK-STRONG-SIV-NEXT: da analyze - confused! +; CHECK-STRONG-SIV-NEXT: Src: %0 = load i32, ptr %arrayidx1, align 4 --> Dst: %0 = load i32, ptr %arrayidx1, align 4 +; CHECK-STRONG-SIV-NEXT: da analyze - none! +; CHECK-STRONG-SIV-NEXT: Src: %0 = load i32, ptr %arrayidx1, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 +; CHECK-STRONG-SIV-NEXT: da analyze - confused! +; CHECK-STRONG-SIV-NEXT: Src: store i32 %0, ptr %B.addr.01, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 +; CHECK-STRONG-SIV-NEXT: da analyze - none! +; entry: br label %for.body @@ -437,6 +565,20 @@ define void @strong9(ptr %A, ptr %B, i64 %n) nounwind uwtable ssp { ; 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-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: 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: 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: 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! +; entry: %cmp1 = icmp eq i64 %n, 0 br i1 %cmp1, label %for.end, label %for.body.preheader @@ -488,6 +630,20 @@ define void @strong10(ptr %A, ptr %B, i64 %n) 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-STRONG-SIV-LABEL: 'strong10' +; 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: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: %0 = load i32, ptr %arrayidx3, align 4 +; CHECK-STRONG-SIV-NEXT: da analyze - consistent flow [0|<]! +; CHECK-STRONG-SIV-NEXT: Src: store i32 %conv, ptr %arrayidx, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 +; CHECK-STRONG-SIV-NEXT: da analyze - confused! +; CHECK-STRONG-SIV-NEXT: Src: %0 = load i32, ptr %arrayidx3, align 4 --> Dst: %0 = load i32, ptr %arrayidx3, align 4 +; CHECK-STRONG-SIV-NEXT: da analyze - none! +; CHECK-STRONG-SIV-NEXT: Src: %0 = load i32, ptr %arrayidx3, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 +; CHECK-STRONG-SIV-NEXT: da analyze - confused! +; CHECK-STRONG-SIV-NEXT: Src: store i32 %0, ptr %B.addr.01, align 4 --> Dst: store i32 %0, ptr %B.addr.01, align 4 +; CHECK-STRONG-SIV-NEXT: da analyze - none! +; entry: br label %for.body @@ -512,3 +668,53 @@ for.body: ; preds = %entry, %for.body for.end: ; preds = %for.body ret void } + +;; for (long unsigned i = 0; i < 9223372036854775806; i++) { +;; for (long unsigned j = 0; j < 2147483640; j++) { +;; A[i] = 0; +;; A[j] = 0; +;; } +;; } + +define dso_local void @strong11(ptr %A) local_unnamed_addr #0 { +; 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 - none! +; CHECK-NEXT: Src: store i32 0, ptr %arrayidx, align 4 --> Dst: store i32 0, ptr %arrayidx4, align 4 +; CHECK-NEXT: da analyze - none! +; CHECK-NEXT: Src: store i32 0, ptr %arrayidx4, align 4 --> Dst: store i32 0, ptr %arrayidx4, align 4 +; CHECK-NEXT: da analyze - consistent output [S 0]! +; +; 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: Src: store i32 0, ptr %arrayidx, align 4 --> Dst: store i32 0, ptr %arrayidx4, align 4 +; CHECK-STRONG-SIV-NEXT: da analyze - consistent output [* *|<]! +; CHECK-STRONG-SIV-NEXT: Src: store i32 0, ptr %arrayidx4, align 4 --> Dst: store i32 0, ptr %arrayidx4, align 4 +; CHECK-STRONG-SIV-NEXT: da analyze - consistent output [S 0]! +; +entry: + br label %for.cond1.preheader + +for.cond1.preheader: ; preds = %entry, %for.inc5 + %i.014 = phi i64 [ 0, %entry ], [ %inc6, %for.inc5 ] + %arrayidx = getelementptr inbounds nuw i32, ptr %A, i64 %i.014 + br label %for.body3 + +for.body3: ; preds = %for.cond1.preheader, %for.body3 + %j.013 = phi i64 [ 0, %for.cond1.preheader ], [ %inc, %for.body3 ] + store i32 0, ptr %arrayidx, align 4 + %arrayidx4 = getelementptr inbounds nuw i32, ptr %A, i64 %j.013 + store i32 0, ptr %arrayidx4, align 4 + %inc = add nuw nsw i64 %j.013, 1 + %exitcond.not = icmp eq i64 %inc, 2147483640 + br i1 %exitcond.not, label %for.inc5, label %for.body3 + +for.inc5: ; preds = %for.body3 + %inc6 = add nuw nsw i64 %i.014, 1 + %exitcond15.not = icmp eq i64 %inc6, 9223372036854775806 + br i1 %exitcond15.not, label %for.end7, label %for.cond1.preheader + +for.end7: ; preds = %for.inc5 + ret void +}