[llvm] [DA] Widening SCEV expressions in strong SIV test to prevent overflow (PR #164704)
    Alireza Torabian via llvm-commits 
    llvm-commits at lists.llvm.org
       
    Fri Oct 24 12:33:35 PDT 2025
    
    
  
https://github.com/1997alireza updated https://github.com/llvm/llvm-project/pull/164704
>From 6482263d9bd6156fa43be3d85d1fd5c94994ae75 Mon Sep 17 00:00:00 2001
From: a00917109 <alireza.torabian at huawei.com>
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<da>" -aa-pipeline=basic-aa 2>&1 \
 ; RUN: | FileCheck %s
+; RUN: opt < %s -disable-output "-passes=print<da>" -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
+}
    
    
More information about the llvm-commits
mailing list