-
Notifications
You must be signed in to change notification settings - Fork 11.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ScalarEvolution] Handle <= and >= in non infinite loops
Extend scalar evolution to handle >= and <= if a loop is known to be finite and the induction variable guards the condition. Specifically, with these assumptions lhs <= rhs is equivalent to lhs < rhs + 1 and lhs >= rhs to lhs > rhs -1. In the case of lhs <= rhs, this is true since the only case these are not equivalent is when rhs == unsigned/signed intmax, which would have resulted in an infinite loop. In the case of lhs >= rhs, this is true since the only case these are not equivalent is when rhs == unsigned/signed intmin, which would again have resulted in an infinite loop. Reviewed By: lebedev.ri Differential Revision: https://reviews.llvm.org/D118090
- Loading branch information
Showing
3 changed files
with
198 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
175 changes: 175 additions & 0 deletions
175
llvm/test/Analysis/ScalarEvolution/finite-trip-count.ll
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py | ||
; RUN: opt < %s -disable-output "-passes=print<scalar-evolution>" -scalar-evolution-max-iterations=0 -scalar-evolution-classify-expressions=0 2>&1 | FileCheck %s | ||
|
||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" | ||
target triple = "x86_64-unknown-linux-gnu" | ||
|
||
declare void @non_exit_use(i32 %i) #0 | ||
|
||
define void @SLE(i32 %len) willreturn { | ||
; CHECK-LABEL: 'SLE' | ||
; CHECK-NEXT: Determining loop execution counts for: @SLE | ||
; CHECK-NEXT: Loop %for.body: backedge-taken count is (0 smax (1 + %len)<nsw>) | ||
; CHECK-NEXT: Loop %for.body: max backedge-taken count is 2147483647 | ||
; CHECK-NEXT: Loop %for.body: Predicated backedge-taken count is (0 smax (1 + %len)<nsw>) | ||
; CHECK-NEXT: Predicates: | ||
; | ||
entry: | ||
br label %for.body | ||
|
||
for.body: | ||
%iv = phi i32 [ %inc, %for.body ], [ 0, %entry ] | ||
call void @non_exit_use(i32 %iv) nounwind willreturn | ||
%inc = add i32 %iv, 1 | ||
%cmp = icmp sle i32 %iv, %len | ||
br i1 %cmp, label %for.body, label %for.end | ||
|
||
for.end: | ||
ret void | ||
} | ||
|
||
define void @SLE_infinite(i32 %len) { | ||
; CHECK-LABEL: 'SLE_infinite' | ||
; CHECK-NEXT: Determining loop execution counts for: @SLE_infinite | ||
; CHECK-NEXT: Loop %for.body: Unpredictable backedge-taken count. | ||
; CHECK-NEXT: Loop %for.body: Unpredictable max backedge-taken count. | ||
; | ||
entry: | ||
br label %for.body | ||
|
||
for.body: | ||
%iv = phi i32 [ %inc, %for.body ], [ 0, %entry ] | ||
call void @non_exit_use(i32 %iv) nounwind willreturn | ||
%inc = add i32 %iv, 1 | ||
%cmp = icmp sle i32 %iv, %len | ||
br i1 %cmp, label %for.body, label %for.end | ||
|
||
for.end: | ||
ret void | ||
} | ||
|
||
define void @ULE(i32 %len) willreturn { | ||
; CHECK-LABEL: 'ULE' | ||
; CHECK-NEXT: Determining loop execution counts for: @ULE | ||
; CHECK-NEXT: Loop %for.body: backedge-taken count is (1 + %len)<nuw> | ||
; CHECK-NEXT: Loop %for.body: max backedge-taken count is -1 | ||
; CHECK-NEXT: Loop %for.body: Predicated backedge-taken count is (1 + %len)<nuw> | ||
; CHECK-NEXT: Predicates: | ||
; | ||
entry: | ||
br label %for.body | ||
|
||
for.body: | ||
%iv = phi i32 [ %inc, %for.body ], [ 0, %entry ] | ||
call void @non_exit_use(i32 %iv) nounwind willreturn | ||
%inc = add i32 %iv, 1 | ||
%cmp = icmp ule i32 %iv, %len | ||
br i1 %cmp, label %for.body, label %for.end | ||
|
||
for.end: | ||
ret void | ||
} | ||
|
||
define void @ULE_infinite(i32 %len) { | ||
; CHECK-LABEL: 'ULE_infinite' | ||
; CHECK-NEXT: Determining loop execution counts for: @ULE_infinite | ||
; CHECK-NEXT: Loop %for.body: Unpredictable backedge-taken count. | ||
; CHECK-NEXT: Loop %for.body: Unpredictable max backedge-taken count. | ||
; | ||
entry: | ||
br label %for.body | ||
|
||
for.body: | ||
%iv = phi i32 [ %inc, %for.body ], [ 0, %entry ] | ||
call void @non_exit_use(i32 %iv) nounwind willreturn | ||
%inc = add i32 %iv, 1 | ||
%cmp = icmp ule i32 %iv, %len | ||
br i1 %cmp, label %for.body, label %for.end | ||
|
||
for.end: | ||
ret void | ||
} | ||
|
||
define void @SGE(i32 %end) willreturn { | ||
; CHECK-LABEL: 'SGE' | ||
; CHECK-NEXT: Determining loop execution counts for: @SGE | ||
; CHECK-NEXT: Loop %for.body: backedge-taken count is (100 + (-1 * (100 smin (-1 + %end)<nsw>))) | ||
; CHECK-NEXT: Loop %for.body: max backedge-taken count is -2147483548 | ||
; CHECK-NEXT: Loop %for.body: Predicated backedge-taken count is (100 + (-1 * (100 smin (-1 + %end)<nsw>))) | ||
; CHECK-NEXT: Predicates: | ||
; | ||
entry: | ||
br label %for.body | ||
|
||
for.body: | ||
%iv = phi i32 [ %inc, %for.body ], [ 100, %entry ] | ||
call void @non_exit_use(i32 %iv) nounwind willreturn | ||
%inc = add i32 %iv, -1 | ||
%cmp = icmp sge i32 %iv, %end | ||
br i1 %cmp, label %for.body, label %for.end | ||
|
||
for.end: | ||
ret void | ||
} | ||
|
||
define void @SGE_infinite(i32 %end) { | ||
; CHECK-LABEL: 'SGE_infinite' | ||
; CHECK-NEXT: Determining loop execution counts for: @SGE_infinite | ||
; CHECK-NEXT: Loop %for.body: Unpredictable backedge-taken count. | ||
; CHECK-NEXT: Loop %for.body: Unpredictable max backedge-taken count. | ||
; | ||
entry: | ||
br label %for.body | ||
|
||
for.body: | ||
%iv = phi i32 [ %inc, %for.body ], [ 100, %entry ] | ||
call void @non_exit_use(i32 %iv) nounwind willreturn | ||
%inc = add i32 %iv, -1 | ||
%cmp = icmp sge i32 %iv, %end | ||
br i1 %cmp, label %for.body, label %for.end | ||
|
||
for.end: | ||
ret void | ||
} | ||
|
||
define void @UGE(i32 %end) willreturn { | ||
; CHECK-LABEL: 'UGE' | ||
; CHECK-NEXT: Determining loop execution counts for: @UGE | ||
; CHECK-NEXT: Loop %for.body: backedge-taken count is (100 + (-1 * (100 umin (-1 + %end)))<nsw>)<nsw> | ||
; CHECK-NEXT: Loop %for.body: max backedge-taken count is 100 | ||
; CHECK-NEXT: Loop %for.body: Predicated backedge-taken count is (100 + (-1 * (100 umin (-1 + %end)))<nsw>)<nsw> | ||
; CHECK-NEXT: Predicates: | ||
; | ||
entry: | ||
br label %for.body | ||
|
||
for.body: | ||
%iv = phi i32 [ %inc, %for.body ], [ 100, %entry ] | ||
call void @non_exit_use(i32 %iv) nounwind willreturn | ||
%inc = add i32 %iv, -1 | ||
%cmp = icmp uge i32 %iv, %end | ||
br i1 %cmp, label %for.body, label %for.end | ||
|
||
for.end: | ||
ret void | ||
} | ||
|
||
define void @UGE_infinite(i32 %end) { | ||
; CHECK-LABEL: 'UGE_infinite' | ||
; CHECK-NEXT: Determining loop execution counts for: @UGE_infinite | ||
; CHECK-NEXT: Loop %for.body: Unpredictable backedge-taken count. | ||
; CHECK-NEXT: Loop %for.body: Unpredictable max backedge-taken count. | ||
; | ||
entry: | ||
br label %for.body | ||
|
||
for.body: | ||
%iv = phi i32 [ %inc, %for.body ], [ 100, %entry ] | ||
call void @non_exit_use(i32 %iv) nounwind willreturn | ||
%inc = add i32 %iv, -1 | ||
%cmp = icmp uge i32 %iv, %end | ||
br i1 %cmp, label %for.body, label %for.end | ||
|
||
for.end: | ||
ret void | ||
} |