From 3c6e419198f3916b76f88d2bef8aa04dd2114574 Mon Sep 17 00:00:00 2001 From: Philip Reames Date: Mon, 7 Jun 2021 14:46:57 -0700 Subject: [PATCH] [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 --- llvm/lib/Analysis/ScalarEvolution.cpp | 2 +- .../trip-count-unknown-stride.ll | 29 ++++++++++++++++--- llvm/test/Transforms/LoopVectorize/pr38697.ll | 2 +- 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp index 273b2ec63220..57a6c83ddd46 100644 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -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 = [&]() { diff --git a/llvm/test/Analysis/ScalarEvolution/trip-count-unknown-stride.ll b/llvm/test/Analysis/ScalarEvolution/trip-count-unknown-stride.ll index fa9c7832adbe..7d41a1f3e546 100644 --- a/llvm/test/Analysis/ScalarEvolution/trip-count-unknown-stride.ll +++ b/llvm/test/Analysis/ScalarEvolution/trip-count-unknown-stride.ll @@ -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 +} diff --git a/llvm/test/Transforms/LoopVectorize/pr38697.ll b/llvm/test/Transforms/LoopVectorize/pr38697.ll index 72b698613c6e..69dcdb08ece6 100644 --- a/llvm/test/Transforms/LoopVectorize/pr38697.ll +++ b/llvm/test/Transforms/LoopVectorize/pr38697.ll @@ -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: