forked from OSchip/llvm-project
[SCEV] Properly guard reasoning about infinite loops being UB on mustprogress
Noticed via code inspection. We changed the semantics of the IR when we added mustprogress, and we appear to have not updated this location. Differential Revision: https://reviews.llvm.org/D103834
This commit is contained in:
parent
d32cc150fe
commit
3c6e419198
|
@ -11470,7 +11470,7 @@ ScalarEvolution::howManyLessThans(const SCEV *LHS, const SCEV *RHS,
|
|||
// A[i] = i;
|
||||
//
|
||||
if (PredicatedIV || !NoWrap || isKnownNonPositive(Stride) ||
|
||||
!loopHasNoSideEffects(L))
|
||||
!loopIsFiniteByAssumption(L))
|
||||
return getCouldNotCompute();
|
||||
} else if (!Stride->isOne() && !NoWrap) {
|
||||
auto isUBOnWrap = [&]() {
|
||||
|
|
|
@ -13,8 +13,7 @@
|
|||
|
||||
target datalayout = "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128"
|
||||
|
||||
; Function Attrs: norecurse nounwind
|
||||
define void @foo1(i32* nocapture %A, i32 %n, i32 %s) #0 {
|
||||
define void @foo1(i32* nocapture %A, i32 %n, i32 %s) mustprogress {
|
||||
entry:
|
||||
%cmp4 = icmp sgt i32 %n, 0
|
||||
br i1 %cmp4, label %for.body, label %for.end
|
||||
|
@ -42,8 +41,7 @@ for.end: ; preds = %for.body, %entry
|
|||
; loops with unknown stride.
|
||||
; CHECK: max backedge-taken count is -1
|
||||
|
||||
; Function Attrs: norecurse nounwind
|
||||
define void @foo2(i32* nocapture %A, i32 %n, i32 %s) #0 {
|
||||
define void @foo2(i32* nocapture %A, i32 %n, i32 %s) mustprogress {
|
||||
entry:
|
||||
br label %for.body
|
||||
|
||||
|
@ -61,3 +59,26 @@ for.end: ; preds = %for.body, %entry
|
|||
ret void
|
||||
}
|
||||
|
||||
; Check that without mustprogress we don't make assumptions about infinite
|
||||
; loops being UB.
|
||||
; CHECK: Determining loop execution counts for: @foo3
|
||||
; CHECK: Loop %for.body: Unpredictable backedge-taken count.
|
||||
; CHECK: Loop %for.body: Unpredictable max backedge-taken count.
|
||||
|
||||
define void @foo3(i32* nocapture %A, i32 %n, i32 %s) {
|
||||
entry:
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %entry, %for.body
|
||||
%i.05 = phi i32 [ %add, %for.body ], [ 0, %entry ]
|
||||
%arrayidx = getelementptr inbounds i32, i32* %A, i32 %i.05
|
||||
%0 = load i32, i32* %arrayidx, align 4
|
||||
%inc = add nsw i32 %0, 1
|
||||
store i32 %inc, i32* %arrayidx, align 4
|
||||
%add = add nsw i32 %i.05, %s
|
||||
%cmp = icmp slt i32 %add, %n
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.end: ; preds = %for.body, %entry
|
||||
ret void
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ target triple = "x86_64-unknown-linux-gnu"
|
|||
|
||||
; Verify that a 'udiv' does not appear in the 'loop1.preheader' block, and that
|
||||
; a 'udiv' has been inserted at the top of the 'while.body.preheader' block.
|
||||
define void @testCountIncrLoop(i8* %ptr, i32 %lim, i32 %count, i32 %val) {
|
||||
define void @testCountIncrLoop(i8* %ptr, i32 %lim, i32 %count, i32 %val) mustprogress {
|
||||
; CHECK-LABEL: @testCountIncrLoop(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK: loop1.preheader:
|
||||
|
|
Loading…
Reference in New Issue