mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 11:42:57 +01:00
a5495e778b
Currently, `getExact` fails if it sees two exit counts in different blocks. There is no solid reason to do so, given that we only calculate exact non-taken count for exiting blocks that dominate latch. Using this fact, we can simply take min out of all exits of all blocks to get the exact taken count. This patch makes the calculation more optimistic with enforcing our assumption with asserts. It allows us to calculate exact backedge taken count in trivial loops like for (int i = 0; i < 100; i++) { if (i > 50) break; . . . } Differential Revision: https://reviews.llvm.org/D44676 Reviewed By: fhahn llvm-svn: 328611
178 lines
5.4 KiB
LLVM
178 lines
5.4 KiB
LLVM
; RUN: opt -S -analyze -scalar-evolution < %s | FileCheck %s
|
|
|
|
define void @s32_max1(i32 %n, i32* %p) {
|
|
entry:
|
|
%add = add i32 %n, 1
|
|
br label %do.body
|
|
|
|
do.body:
|
|
%i.0 = phi i32 [ %n, %entry ], [ %inc, %do.body ]
|
|
%arrayidx = getelementptr i32, i32* %p, i32 %i.0
|
|
store i32 %i.0, i32* %arrayidx, align 4
|
|
%inc = add i32 %i.0, 1
|
|
%cmp = icmp slt i32 %i.0, %add
|
|
br i1 %cmp, label %do.body, label %do.end ; taken either 0 or 1 times
|
|
|
|
; CHECK-LABEL: Determining loop execution counts for: @s32_max1
|
|
; CHECK-NEXT: Loop %do.body: backedge-taken count is ((-1 * %n) + ((1 + %n) smax %n))
|
|
; CHECK-NEXT: Loop %do.body: max backedge-taken count is 1, actual taken count either this or zero.
|
|
|
|
do.end:
|
|
ret void
|
|
}
|
|
|
|
define void @s32_max2(i32 %n, i32* %p) {
|
|
entry:
|
|
%add = add i32 %n, 2
|
|
br label %do.body
|
|
|
|
do.body:
|
|
%i.0 = phi i32 [ %n, %entry ], [ %inc, %do.body ]
|
|
%arrayidx = getelementptr i32, i32* %p, i32 %i.0
|
|
store i32 %i.0, i32* %arrayidx, align 4
|
|
%inc = add i32 %i.0, 1
|
|
%cmp = icmp slt i32 %i.0, %add
|
|
br i1 %cmp, label %do.body, label %do.end ; taken either 0 or 2 times
|
|
|
|
; CHECK-LABEL: Determining loop execution counts for: @s32_max2
|
|
; CHECK-NEXT: Loop %do.body: backedge-taken count is ((-1 * %n) + ((2 + %n) smax %n))
|
|
; CHECK-NEXT: Loop %do.body: max backedge-taken count is 2, actual taken count either this or zero.
|
|
|
|
do.end:
|
|
ret void
|
|
}
|
|
|
|
define void @s32_maxx(i32 %n, i32 %x, i32* %p) {
|
|
entry:
|
|
%add = add i32 %x, %n
|
|
br label %do.body
|
|
|
|
do.body:
|
|
%i.0 = phi i32 [ %n, %entry ], [ %inc, %do.body ]
|
|
%arrayidx = getelementptr i32, i32* %p, i32 %i.0
|
|
store i32 %i.0, i32* %arrayidx, align 4
|
|
%inc = add i32 %i.0, 1
|
|
%cmp = icmp slt i32 %i.0, %add
|
|
br i1 %cmp, label %do.body, label %do.end ; taken either 0 or x times
|
|
|
|
; CHECK-LABEL: Determining loop execution counts for: @s32_maxx
|
|
; CHECK-NEXT: Loop %do.body: backedge-taken count is ((-1 * %n) + ((%n + %x) smax %n))
|
|
; CHECK-NEXT: Loop %do.body: max backedge-taken count is -1{{$}}
|
|
|
|
do.end:
|
|
ret void
|
|
}
|
|
|
|
define void @s32_max2_unpredictable_exit(i32 %n, i32 %x, i32* %p) {
|
|
entry:
|
|
%add = add i32 %n, 2
|
|
br label %do.body
|
|
|
|
do.body:
|
|
%i.0 = phi i32 [ %n, %entry ], [ %inc, %if.end ]
|
|
%cmp = icmp eq i32 %i.0, %x
|
|
br i1 %cmp, label %do.end, label %if.end ; unpredictable
|
|
|
|
if.end:
|
|
%arrayidx = getelementptr i32, i32* %p, i32 %i.0
|
|
store i32 %i.0, i32* %arrayidx, align 4
|
|
%inc = add i32 %i.0, 1
|
|
%cmp1 = icmp slt i32 %i.0, %add
|
|
br i1 %cmp1, label %do.body, label %do.end ; taken either 0 or 2 times
|
|
|
|
; CHECK-LABEL: Determining loop execution counts for: @s32_max2_unpredictable_exit
|
|
; CHECK-NEXT: Loop %do.body: <multiple exits> backedge-taken count is (-1 + (-1 * ((-1 + (-1 * ((2 + %n) smax %n)) + %n) umax (-1 + (-1 * %x) + %n))))
|
|
; CHECK-NEXT: Loop %do.body: max backedge-taken count is 2{{$}}
|
|
|
|
do.end:
|
|
ret void
|
|
}
|
|
|
|
define void @u32_max1(i32 %n, i32* %p) {
|
|
entry:
|
|
%add = add i32 %n, 1
|
|
br label %do.body
|
|
|
|
do.body:
|
|
%i.0 = phi i32 [ %n, %entry ], [ %inc, %do.body ]
|
|
%arrayidx = getelementptr i32, i32* %p, i32 %i.0
|
|
store i32 %i.0, i32* %arrayidx, align 4
|
|
%inc = add i32 %i.0, 1
|
|
%cmp = icmp ult i32 %i.0, %add
|
|
br i1 %cmp, label %do.body, label %do.end ; taken either 0 or 1 times
|
|
|
|
; CHECK-LABEL: Determining loop execution counts for: @u32_max1
|
|
; CHECK-NEXT: Loop %do.body: backedge-taken count is ((-1 * %n) + ((1 + %n) umax %n))
|
|
; CHECK-NEXT: Loop %do.body: max backedge-taken count is 1, actual taken count either this or zero.
|
|
|
|
do.end:
|
|
ret void
|
|
}
|
|
|
|
define void @u32_max2(i32 %n, i32* %p) {
|
|
entry:
|
|
%add = add i32 %n, 2
|
|
br label %do.body
|
|
|
|
do.body:
|
|
%i.0 = phi i32 [ %n, %entry ], [ %inc, %do.body ]
|
|
%arrayidx = getelementptr i32, i32* %p, i32 %i.0
|
|
store i32 %i.0, i32* %arrayidx, align 4
|
|
%inc = add i32 %i.0, 1
|
|
%cmp = icmp ult i32 %i.0, %add
|
|
br i1 %cmp, label %do.body, label %do.end ; taken either 0 or 2 times
|
|
|
|
; CHECK-LABEL: Determining loop execution counts for: @u32_max2
|
|
; CHECK-NEXT: Loop %do.body: backedge-taken count is ((-1 * %n) + ((2 + %n) umax %n))
|
|
; CHECK-NEXT: Loop %do.body: max backedge-taken count is 2, actual taken count either this or zero.
|
|
|
|
do.end:
|
|
ret void
|
|
}
|
|
|
|
define void @u32_maxx(i32 %n, i32 %x, i32* %p) {
|
|
entry:
|
|
%add = add i32 %x, %n
|
|
br label %do.body
|
|
|
|
do.body:
|
|
%i.0 = phi i32 [ %n, %entry ], [ %inc, %do.body ]
|
|
%arrayidx = getelementptr i32, i32* %p, i32 %i.0
|
|
store i32 %i.0, i32* %arrayidx, align 4
|
|
%inc = add i32 %i.0, 1
|
|
%cmp = icmp ult i32 %i.0, %add
|
|
br i1 %cmp, label %do.body, label %do.end ; taken either 0 or x times
|
|
|
|
; CHECK-LABEL: Determining loop execution counts for: @u32_maxx
|
|
; CHECK-NEXT: Loop %do.body: backedge-taken count is ((-1 * %n) + ((%n + %x) umax %n))
|
|
; CHECK-NEXT: Loop %do.body: max backedge-taken count is -1{{$}}
|
|
|
|
do.end:
|
|
ret void
|
|
}
|
|
|
|
define void @u32_max2_unpredictable_exit(i32 %n, i32 %x, i32* %p) {
|
|
entry:
|
|
%add = add i32 %n, 2
|
|
br label %do.body
|
|
|
|
do.body:
|
|
%i.0 = phi i32 [ %n, %entry ], [ %inc, %if.end ]
|
|
%cmp = icmp eq i32 %i.0, %x
|
|
br i1 %cmp, label %do.end, label %if.end ; unpredictable
|
|
|
|
if.end:
|
|
%arrayidx = getelementptr i32, i32* %p, i32 %i.0
|
|
store i32 %i.0, i32* %arrayidx, align 4
|
|
%inc = add i32 %i.0, 1
|
|
%cmp1 = icmp ult i32 %i.0, %add
|
|
br i1 %cmp1, label %do.body, label %do.end ; taken either 0 or 2 times
|
|
|
|
; CHECK-LABEL: Determining loop execution counts for: @u32_max2_unpredictable_exit
|
|
; CHECK-NEXT: Loop %do.body: <multiple exits> backedge-taken count is (-1 + (-1 * ((-1 + (-1 * ((2 + %n) umax %n)) + %n) umax (-1 + (-1 * %x) + %n))))
|
|
; CHECK-NEXT: Loop %do.body: max backedge-taken count is 2{{$}}
|
|
|
|
do.end:
|
|
ret void
|
|
}
|