Skip to content

Commit 7f5b15a

Browse files
committed
[LSR] Move normalization check to normalizeForPostIncUse.
Move the logic added in 3a57152 to normalizeForPostIncUse to catch additional un-invertable cases. This fixes another mis-compile pointed out by @peixin in D153004.
1 parent 6d6f23a commit 7f5b15a

File tree

5 files changed

+26
-21
lines changed

5 files changed

+26
-21
lines changed

llvm/include/llvm/Analysis/ScalarEvolutionNormalization.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ typedef SmallPtrSet<const Loop *, 2> PostIncLoopSet;
5050
typedef function_ref<bool(const SCEVAddRecExpr *)> NormalizePredTy;
5151

5252
/// Normalize \p S to be post-increment for all loops present in \p
53-
/// Loops.
53+
/// Loops. Returns nullptr if the result is not invertible.
5454
const SCEV *normalizeForPostIncUse(const SCEV *S, const PostIncLoopSet &Loops,
5555
ScalarEvolution &SE);
5656

llvm/lib/Analysis/IVUsers.cpp

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -335,14 +335,7 @@ const SCEV *IVUsers::getReplacementExpr(const IVStrideUse &IU) const {
335335
/// getExpr - Return the expression for the use.
336336
const SCEV *IVUsers::getExpr(const IVStrideUse &IU) const {
337337
const SCEV *Replacement = getReplacementExpr(IU);
338-
const SCEV *Normalized =
339-
normalizeForPostIncUse(Replacement, IU.getPostIncLoops(), *SE);
340-
const SCEV *Denormalized =
341-
denormalizeForPostIncUse(Normalized, IU.getPostIncLoops(), *SE);
342-
// If the normalized expression isn't invertible.
343-
if (Denormalized != Replacement)
344-
return nullptr;
345-
return Normalized;
338+
return normalizeForPostIncUse(Replacement, IU.getPostIncLoops(), *SE);
346339
}
347340

348341
static const SCEVAddRecExpr *findAddRecForLoop(const SCEV *S, const Loop *L) {

llvm/lib/Analysis/ScalarEvolutionNormalization.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,13 @@ const SCEV *llvm::normalizeForPostIncUse(const SCEV *S,
102102
auto Pred = [&](const SCEVAddRecExpr *AR) {
103103
return Loops.count(AR->getLoop());
104104
};
105-
return NormalizeDenormalizeRewriter(Normalize, Pred, SE).visit(S);
105+
const SCEV *Normalized =
106+
NormalizeDenormalizeRewriter(Normalize, Pred, SE).visit(S);
107+
const SCEV *Denormalized = denormalizeForPostIncUse(Normalized, Loops, SE);
108+
// If the normalized expression isn't invertible.
109+
if (Denormalized != S)
110+
return nullptr;
111+
return Normalized;
106112
}
107113

108114
const SCEV *llvm::normalizeForPostIncUseIf(const SCEV *S, NormalizePredTy Pred,

llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3361,6 +3361,8 @@ void LSRInstance::CollectFixupsAndInitialFormulae() {
33613361
// S is normalized, so normalize N before folding it into S
33623362
// to keep the result normalized.
33633363
N = normalizeForPostIncUse(N, TmpPostIncLoops, SE);
3364+
if (!N)
3365+
continue;
33643366
Kind = LSRUse::ICmpZero;
33653367
S = SE.getMinusSCEV(N, S);
33663368
} else if (L->isLoopInvariant(NV) &&
@@ -3375,6 +3377,8 @@ void LSRInstance::CollectFixupsAndInitialFormulae() {
33753377
// SCEV can't compute the difference of two unknown pointers.
33763378
N = SE.getUnknown(NV);
33773379
N = normalizeForPostIncUse(N, TmpPostIncLoops, SE);
3380+
if (!N)
3381+
continue;
33783382
Kind = LSRUse::ICmpZero;
33793383
S = SE.getMinusSCEV(N, S);
33803384
assert(!isa<SCEVCouldNotCompute>(S));
@@ -4160,7 +4164,7 @@ getAnyExtendConsideringPostIncUses(ArrayRef<PostIncLoopSet> Loops,
41604164
auto *DenormExpr = denormalizeForPostIncUse(Expr, L, SE);
41614165
const SCEV *NewDenormExpr = SE.getAnyExtendExpr(DenormExpr, ToTy);
41624166
const SCEV *New = normalizeForPostIncUse(NewDenormExpr, L, SE);
4163-
if (Result && New != Result)
4167+
if (!New || (Result && New != Result))
41644168
return nullptr;
41654169
Result = New;
41664170
}

llvm/test/Transforms/LoopStrengthReduce/X86/postinc-iv-used-by-urem-and-udiv.ll

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -142,40 +142,42 @@ define i64 @test_normalization_failure_in_any_extend(ptr %i, i64 %i1, i8 %i25) {
142142
; CHECK: loop.1.header:
143143
; CHECK-NEXT: [[IV_1:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_1_NEXT:%.*]], [[LOOP_1_LATCH:%.*]] ]
144144
; CHECK-NEXT: [[IV_2:%.*]] = phi i64 [ [[I1]], [[ENTRY]] ], [ [[TMP1:%.*]], [[LOOP_1_LATCH]] ]
145+
; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[IV_2]], 2
145146
; CHECK-NEXT: br label [[LOOP_2:%.*]]
146147
; CHECK: loop.2:
147148
; CHECK-NEXT: [[LSR_IV:%.*]] = phi i32 [ [[LSR_IV_NEXT:%.*]], [[LOOP_2]] ], [ 2, [[LOOP_1_HEADER]] ]
148149
; CHECK-NEXT: [[LSR_IV_NEXT]] = add nsw i32 [[LSR_IV]], -1
149150
; CHECK-NEXT: [[C_1:%.*]] = icmp sgt i32 [[LSR_IV_NEXT]], 0
150151
; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_2]], label [[LOOP_3_PREHEADER:%.*]]
151152
; CHECK: loop.3.preheader:
152-
; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[IV_2]], 1
153153
; CHECK-NEXT: br label [[LOOP_3:%.*]]
154154
; CHECK: loop.3:
155-
; CHECK-NEXT: [[LSR_IV5:%.*]] = phi i64 [ [[TMP0]], [[LOOP_3_PREHEADER]] ], [ [[LSR_IV_NEXT6:%.*]], [[LOOP_3]] ]
155+
; CHECK-NEXT: [[LSR_IV5:%.*]] = phi i64 [ 0, [[LOOP_3_PREHEADER]] ], [ [[LSR_IV_NEXT6:%.*]], [[LOOP_3]] ]
156156
; CHECK-NEXT: [[LSR_IV1:%.*]] = phi i64 [ 2, [[LOOP_3_PREHEADER]] ], [ [[LSR_IV_NEXT2:%.*]], [[LOOP_3]] ]
157157
; CHECK-NEXT: [[IV_5:%.*]] = phi i32 [ [[IV_5_NEXT:%.*]], [[LOOP_3]] ], [ 1, [[LOOP_3_PREHEADER]] ]
158158
; CHECK-NEXT: [[IV_5_NEXT]] = add nsw i32 [[IV_5]], -1
159159
; CHECK-NEXT: [[LSR:%.*]] = trunc i32 [[IV_5_NEXT]] to i8
160160
; CHECK-NEXT: [[LSR_IV_NEXT2]] = add nsw i64 [[LSR_IV1]], -1
161161
; CHECK-NEXT: [[TMP:%.*]] = trunc i64 [[LSR_IV_NEXT2]] to i32
162-
; CHECK-NEXT: [[LSR_IV_NEXT6]] = add i64 [[LSR_IV5]], 1
162+
; CHECK-NEXT: [[LSR_IV_NEXT6]] = add nsw i64 [[LSR_IV5]], -1
163163
; CHECK-NEXT: [[C_2:%.*]] = icmp sgt i32 [[TMP]], 0
164164
; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_3]], label [[LOOP_1_LATCH]]
165165
; CHECK: loop.1.latch:
166166
; CHECK-NEXT: [[IV_1_NEXT]] = add nuw nsw i32 [[IV_1]], 1
167-
; CHECK-NEXT: [[TMP1]] = add i64 [[LSR_IV_NEXT6]], 1
167+
; CHECK-NEXT: [[TMP1]] = sub i64 [[TMP0]], [[LSR_IV_NEXT6]]
168168
; CHECK-NEXT: [[C_3:%.*]] = icmp eq i32 [[IV_1_NEXT]], 8
169169
; CHECK-NEXT: br i1 [[C_3]], label [[EXIT:%.*]], label [[LOOP_1_HEADER]]
170170
; CHECK: exit:
171171
; CHECK-NEXT: call void @use.i32(i32 [[IV_5_NEXT]])
172-
; CHECK-NEXT: call void @use(i64 [[LSR_IV_NEXT6]])
172+
; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[IV_2]], 1
173+
; CHECK-NEXT: [[TMP3:%.*]] = sub i64 [[TMP2]], [[LSR_IV_NEXT6]]
174+
; CHECK-NEXT: call void @use(i64 [[TMP3]])
173175
; CHECK-NEXT: call void @use(i64 [[LSR_IV_NEXT2]])
174-
; CHECK-NEXT: [[TMP2:%.*]] = udiv i32 [[IV_5_NEXT]], 53
175-
; CHECK-NEXT: [[TMP3:%.*]] = trunc i32 [[TMP2]] to i8
176-
; CHECK-NEXT: [[TMP4:%.*]] = mul i8 [[TMP3]], 53
177-
; CHECK-NEXT: [[TMP5:%.*]] = sub i8 [[LSR]], [[TMP4]]
178-
; CHECK-NEXT: call void @use.i8(i8 [[TMP5]])
176+
; CHECK-NEXT: [[TMP4:%.*]] = udiv i32 [[IV_5_NEXT]], 53
177+
; CHECK-NEXT: [[TMP5:%.*]] = trunc i32 [[TMP4]] to i8
178+
; CHECK-NEXT: [[TMP6:%.*]] = mul i8 [[TMP5]], 53
179+
; CHECK-NEXT: [[TMP7:%.*]] = sub i8 [[LSR]], [[TMP6]]
180+
; CHECK-NEXT: call void @use.i8(i8 [[TMP7]])
179181
; CHECK-NEXT: [[I26:%.*]] = xor i8 [[I25]], 5
180182
; CHECK-NEXT: [[I27:%.*]] = zext i8 [[I26]] to i64
181183
; CHECK-NEXT: ret i64 [[I27]]

0 commit comments

Comments
 (0)