Skip to content

Commit 04ec5a0

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 4b2d615 commit 04ec5a0

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
@@ -3119,11 +3119,9 @@ const SCEV *DependenceInfo::addToCoefficient(const SCEV *Expr,
31193119
const Loop *TargetLoop,
31203120
const SCEV *Value) const {
31213121
const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(Expr);
3122-
if (!AddRec) // create a new addRec
3123-
return SE->getAddRecExpr(Expr,
3124-
Value,
3125-
TargetLoop,
3126-
SCEV::FlagAnyWrap); // Worst case, with no info.
3122+
if (!AddRec)
3123+
return SE->getAddRecExpr(Expr, Value, TargetLoop, SCEV::FlagNSW);
3124+
31273125
if (AddRec->getLoop() == TargetLoop) {
31283126
const SCEV *Sum = SE->getAddExpr(AddRec->getStepRecurrence(*SE), Value);
31293127
if (Sum->isZero())
@@ -3134,7 +3132,7 @@ const SCEV *DependenceInfo::addToCoefficient(const SCEV *Expr,
31343132
AddRec->getNoWrapFlags());
31353133
}
31363134
if (SE->isLoopInvariant(AddRec, TargetLoop))
3137-
return SE->getAddRecExpr(AddRec, Value, TargetLoop, SCEV::FlagAnyWrap);
3135+
return SE->getAddRecExpr(AddRec, Value, TargetLoop, SCEV::FlagNSW);
31383136
return SE->getAddRecExpr(
31393137
addToCoefficient(AddRec->getStart(), TargetLoop, Value),
31403138
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)