Skip to content

Commit fc516d3

Browse files
committed
[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 #51512
1 parent d66d466 commit fc516d3

File tree

2 files changed

+48
-6
lines changed

2 files changed

+48
-6
lines changed

Diff for: llvm/lib/Analysis/DependenceAnalysis.cpp

+4-6
Original file line numberDiff line numberDiff line change
@@ -3117,11 +3117,9 @@ const SCEV *DependenceInfo::addToCoefficient(const SCEV *Expr,
31173117
const Loop *TargetLoop,
31183118
const SCEV *Value) const {
31193119
const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(Expr);
3120-
if (!AddRec) // create a new addRec
3121-
return SE->getAddRecExpr(Expr,
3122-
Value,
3123-
TargetLoop,
3124-
SCEV::FlagAnyWrap); // Worst case, with no info.
3120+
if (!AddRec)
3121+
return SE->getAddRecExpr(Expr, Value, TargetLoop, SCEV::FlagNSW);
3122+
31253123
if (AddRec->getLoop() == TargetLoop) {
31263124
const SCEV *Sum = SE->getAddExpr(AddRec->getStepRecurrence(*SE), Value);
31273125
if (Sum->isZero())
@@ -3132,7 +3130,7 @@ const SCEV *DependenceInfo::addToCoefficient(const SCEV *Expr,
31323130
AddRec->getNoWrapFlags());
31333131
}
31343132
if (SE->isLoopInvariant(AddRec, TargetLoop))
3135-
return SE->getAddRecExpr(AddRec, Value, TargetLoop, SCEV::FlagAnyWrap);
3133+
return SE->getAddRecExpr(AddRec, Value, TargetLoop, SCEV::FlagNSW);
31363134
return SE->getAddRecExpr(
31373135
addToCoefficient(AddRec->getStart(), TargetLoop, Value),
31383136
AddRec->getStepRecurrence(*SE), AddRec->getLoop(),

Diff for: llvm/test/Analysis/DependenceAnalysis/PR51512.ll

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 5
2+
; RUN: opt < %s -disable-output "-passes=print<da>" -aa-pipeline=basic-aa 2>&1 \
3+
; RUN: | FileCheck %s
4+
5+
; Check that the testcase does not crash the compiler.
6+
; See https://github.com/llvm/llvm-project/issues/51512 for details.
7+
8+
define void @foo() {
9+
; CHECK-LABEL: 'foo'
10+
; CHECK-NEXT: Src: store i32 42, ptr %getelementptr, align 1 --> Dst: store i32 42, ptr %getelementptr, align 1
11+
; CHECK-NEXT: da analyze - consistent output [0 S]!
12+
; CHECK-NEXT: Src: store i32 42, ptr %getelementptr, align 1 --> Dst: store i32 0, ptr %getelementptr5, align 1
13+
; CHECK-NEXT: da analyze - output [0 *|<]!
14+
; CHECK-NEXT: Src: store i32 0, ptr %getelementptr5, align 1 --> Dst: store i32 0, ptr %getelementptr5, align 1
15+
; CHECK-NEXT: da analyze - none!
16+
;
17+
bb:
18+
%alloca = alloca [2 x [5 x i32]], align 1
19+
br label %bb1
20+
21+
bb1: ; preds = %bb7, %bb
22+
%phi = phi i32 [ 0, %bb ], [ %add8, %bb7 ]
23+
%trunc = trunc i32 %phi to i16
24+
%add = add i16 %trunc, 3
25+
%getelementptr = getelementptr inbounds [2 x [5 x i32]], ptr %alloca, i16 0, i16 %trunc, i16 %add
26+
br label %bb2
27+
28+
bb2: ; preds = %bb2, %bb1
29+
%phi3 = phi i32 [ 0, %bb1 ], [ %add6, %bb2 ]
30+
store i32 42, ptr %getelementptr, align 1
31+
%trunc4 = trunc i32 %phi3 to i16
32+
%getelementptr5 = getelementptr inbounds [2 x [5 x i32]], ptr %alloca, i16 0, i16 %trunc4, i16 %add
33+
store i32 0, ptr %getelementptr5, align 1
34+
%add6 = add nuw nsw i32 %phi3, 1
35+
br i1 false, label %bb2, label %bb7
36+
37+
bb7: ; preds = %bb2
38+
%add8 = add nuw nsw i32 %phi, 1
39+
%icmp = icmp eq i32 %phi, 0
40+
br i1 %icmp, label %bb1, label %bb9
41+
42+
bb9: ; preds = %bb7
43+
ret void
44+
}

0 commit comments

Comments
 (0)