[llvm] [DA] use NSW arithmetic (PR #116632)

Sebastian Pop via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 29 21:38:59 PST 2025


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

>From 04ec5a0f85a20dae2d532025e2ff72fc4b77316a Mon Sep 17 00:00:00 2001
From: Sebastian Pop <spop at nvidia.com>
Date: Fri, 15 Nov 2024 01:04:58 +0000
Subject: [PATCH] [DA] use NSW arithmetic

DA uses SCEV to solve linear constraints. When it generates SCEVs with negative
strides, i.e., {0,+,-1}, make sure the SCEVs are marked as non wrap arithmetic.
This patch fixes https://github.com/llvm/llvm-project/issues/51512
---
 llvm/lib/Analysis/DependenceAnalysis.cpp      | 10 ++---
 .../Analysis/DependenceAnalysis/PR51512.ll    | 44 +++++++++++++++++++
 2 files changed, 48 insertions(+), 6 deletions(-)
 create mode 100644 llvm/test/Analysis/DependenceAnalysis/PR51512.ll

diff --git a/llvm/lib/Analysis/DependenceAnalysis.cpp b/llvm/lib/Analysis/DependenceAnalysis.cpp
index 6ce2875beeccac..c43642791b6079 100644
--- a/llvm/lib/Analysis/DependenceAnalysis.cpp
+++ b/llvm/lib/Analysis/DependenceAnalysis.cpp
@@ -3119,11 +3119,9 @@ const SCEV *DependenceInfo::addToCoefficient(const SCEV *Expr,
                                              const Loop *TargetLoop,
                                              const SCEV *Value) const {
   const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(Expr);
-  if (!AddRec) // create a new addRec
-    return SE->getAddRecExpr(Expr,
-                             Value,
-                             TargetLoop,
-                             SCEV::FlagAnyWrap); // Worst case, with no info.
+  if (!AddRec)
+    return SE->getAddRecExpr(Expr, Value, TargetLoop, SCEV::FlagNSW);
+
   if (AddRec->getLoop() == TargetLoop) {
     const SCEV *Sum = SE->getAddExpr(AddRec->getStepRecurrence(*SE), Value);
     if (Sum->isZero())
@@ -3134,7 +3132,7 @@ const SCEV *DependenceInfo::addToCoefficient(const SCEV *Expr,
                              AddRec->getNoWrapFlags());
   }
   if (SE->isLoopInvariant(AddRec, TargetLoop))
-    return SE->getAddRecExpr(AddRec, Value, TargetLoop, SCEV::FlagAnyWrap);
+    return SE->getAddRecExpr(AddRec, Value, TargetLoop, SCEV::FlagNSW);
   return SE->getAddRecExpr(
       addToCoefficient(AddRec->getStart(), TargetLoop, Value),
       AddRec->getStepRecurrence(*SE), AddRec->getLoop(),
diff --git a/llvm/test/Analysis/DependenceAnalysis/PR51512.ll b/llvm/test/Analysis/DependenceAnalysis/PR51512.ll
new file mode 100644
index 00000000000000..744ffea57a2e7d
--- /dev/null
+++ b/llvm/test/Analysis/DependenceAnalysis/PR51512.ll
@@ -0,0 +1,44 @@
+; 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
+
+; Check that the testcase does not crash the compiler.
+; See https://github.com/llvm/llvm-project/issues/51512 for details.
+
+define void @foo() {
+; CHECK-LABEL: 'foo'
+; CHECK-NEXT:  Src: store i32 42, ptr %getelementptr, align 1 --> Dst: store i32 42, ptr %getelementptr, align 1
+; CHECK-NEXT:    da analyze - consistent output [0 S]!
+; CHECK-NEXT:  Src: store i32 42, ptr %getelementptr, align 1 --> Dst: store i32 0, ptr %getelementptr5, align 1
+; CHECK-NEXT:    da analyze - output [0 *|<]!
+; CHECK-NEXT:  Src: store i32 0, ptr %getelementptr5, align 1 --> Dst: store i32 0, ptr %getelementptr5, align 1
+; CHECK-NEXT:    da analyze - none!
+;
+bb:
+  %alloca = alloca [2 x [5 x i32]], align 1
+  br label %bb1
+
+bb1:                                              ; preds = %bb7, %bb
+  %phi = phi i32 [ 0, %bb ], [ %add8, %bb7 ]
+  %trunc = trunc i32 %phi to i16
+  %add = add i16 %trunc, 3
+  %getelementptr = getelementptr inbounds [2 x [5 x i32]], ptr %alloca, i16 0, i16 %trunc, i16 %add
+  br label %bb2
+
+bb2:                                              ; preds = %bb2, %bb1
+  %phi3 = phi i32 [ 0, %bb1 ], [ %add6, %bb2 ]
+  store i32 42, ptr %getelementptr, align 1
+  %trunc4 = trunc i32 %phi3 to i16
+  %getelementptr5 = getelementptr inbounds [2 x [5 x i32]], ptr %alloca, i16 0, i16 %trunc4, i16 %add
+  store i32 0, ptr %getelementptr5, align 1
+  %add6 = add nuw nsw i32 %phi3, 1
+  br i1 false, label %bb2, label %bb7
+
+bb7:                                              ; preds = %bb2
+  %add8 = add nuw nsw i32 %phi, 1
+  %icmp = icmp eq i32 %phi, 0
+  br i1 %icmp, label %bb1, label %bb9
+
+bb9:                                              ; preds = %bb7
+  ret void
+}



More information about the llvm-commits mailing list