Imported Upstream version 6.10.0.49

Former-commit-id: 1d6753294b2993e1fbf92de9366bb9544db4189b
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2020-01-16 16:38:04 +00:00
parent d94e79959b
commit 468663ddbb
48518 changed files with 2789335 additions and 61176 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,21 @@
; RUN: opt -analyze -branch-prob < %s | FileCheck %s
; RUN: opt < %s -passes='print<branch-prob>' -disable-output 2>&1 | FileCheck %s
declare i32 @llvm.experimental.deoptimize.i32(...)
define i32 @test1(i32 %a, i32 %b) {
; CHECK-LABEL: Printing analysis {{.*}} for function 'test1':
entry:
%cond = icmp eq i32 %a, 42
br i1 %cond, label %exit, label %deopt
; CHECK: edge entry -> exit probability is 0x7fffffff / 0x80000000 = 100.00% [HOT edge]
; CHECK: edge entry -> deopt probability is 0x00000001 / 0x80000000 = 0.00%
deopt:
%rval = call i32(...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
ret i32 %rval
exit:
ret i32 %b
}

View File

@ -0,0 +1,264 @@
; RUN: opt < %s -analyze -branch-prob | FileCheck %s
; RUN: opt < %s -analyze -lazy-branch-prob | FileCheck %s
; RUN: opt < %s -passes='print<branch-prob>' -disable-output 2>&1 | FileCheck %s
declare i32 @strcmp(i8*, i8*)
declare i32 @strncmp(i8*, i8*, i32)
declare i32 @strcasecmp(i8*, i8*)
declare i32 @strncasecmp(i8*, i8*, i32)
declare i32 @memcmp(i8*, i8*)
declare i32 @nonstrcmp(i8*, i8*)
; Check that the result of strcmp is considered more likely to be nonzero than
; zero, and equally likely to be (nonzero) positive or negative.
define i32 @test_strcmp_eq(i8* %p, i8* %q) {
; CHECK: Printing analysis {{.*}} for function 'test_strcmp_eq'
entry:
%val = call i32 @strcmp(i8* %p, i8* %q)
%cond = icmp eq i32 %val, 0
br i1 %cond, label %then, label %else
; CHECK: edge entry -> then probability is 0x30000000 / 0x80000000 = 37.50%
; CHECK: edge entry -> else probability is 0x50000000 / 0x80000000 = 62.50%
then:
br label %exit
; CHECK: edge then -> exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
else:
br label %exit
; CHECK: edge else -> exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
exit:
%result = phi i32 [ 0, %then ], [ 1, %else ]
ret i32 %result
}
define i32 @test_strcmp_ne(i8* %p, i8* %q) {
; CHECK: Printing analysis {{.*}} for function 'test_strcmp_ne'
entry:
%val = call i32 @strcmp(i8* %p, i8* %q)
%cond = icmp ne i32 %val, 0
br i1 %cond, label %then, label %else
; CHECK: edge entry -> then probability is 0x50000000 / 0x80000000 = 62.50%
; CHECK: edge entry -> else probability is 0x30000000 / 0x80000000 = 37.50%
then:
br label %exit
; CHECK: edge then -> exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
else:
br label %exit
; CHECK: edge else -> exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
exit:
%result = phi i32 [ 0, %then ], [ 1, %else ]
ret i32 %result
}
define i32 @test_strcmp_sgt(i8* %p, i8* %q) {
; CHECK: Printing analysis {{.*}} for function 'test_strcmp_sgt'
entry:
%val = call i32 @strcmp(i8* %p, i8* %q)
%cond = icmp sgt i32 %val, 0
br i1 %cond, label %then, label %else
; CHECK: edge entry -> then probability is 0x40000000 / 0x80000000 = 50.00%
; CHECK: edge entry -> else probability is 0x40000000 / 0x80000000 = 50.00%
then:
br label %exit
; CHECK: edge then -> exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
else:
br label %exit
; CHECK: edge else -> exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
exit:
%result = phi i32 [ 0, %then ], [ 1, %else ]
ret i32 %result
}
define i32 @test_strcmp_slt(i8* %p, i8* %q) {
; CHECK: Printing analysis {{.*}} for function 'test_strcmp_slt'
entry:
%val = call i32 @strcmp(i8* %p, i8* %q)
%cond = icmp slt i32 %val, 0
br i1 %cond, label %then, label %else
; CHECK: edge entry -> then probability is 0x40000000 / 0x80000000 = 50.00%
; CHECK: edge entry -> else probability is 0x40000000 / 0x80000000 = 50.00%
then:
br label %exit
; CHECK: edge then -> exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
else:
br label %exit
; CHECK: edge else -> exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
exit:
%result = phi i32 [ 0, %then ], [ 1, %else ]
ret i32 %result
}
; Similarly check other library functions that have the same behaviour
define i32 @test_strncmp_sgt(i8* %p, i8* %q) {
; CHECK: Printing analysis {{.*}} for function 'test_strncmp_sgt'
entry:
%val = call i32 @strncmp(i8* %p, i8* %q, i32 4)
%cond = icmp sgt i32 %val, 0
br i1 %cond, label %then, label %else
; CHECK: edge entry -> then probability is 0x40000000 / 0x80000000 = 50.00%
; CHECK: edge entry -> else probability is 0x40000000 / 0x80000000 = 50.00%
then:
br label %exit
; CHECK: edge then -> exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
else:
br label %exit
; CHECK: edge else -> exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
exit:
%result = phi i32 [ 0, %then ], [ 1, %else ]
ret i32 %result
}
define i32 @test_strcasecmp_sgt(i8* %p, i8* %q) {
; CHECK: Printing analysis {{.*}} for function 'test_strcasecmp_sgt'
entry:
%val = call i32 @strcasecmp(i8* %p, i8* %q)
%cond = icmp sgt i32 %val, 0
br i1 %cond, label %then, label %else
; CHECK: edge entry -> then probability is 0x40000000 / 0x80000000 = 50.00%
; CHECK: edge entry -> else probability is 0x40000000 / 0x80000000 = 50.00%
then:
br label %exit
; CHECK: edge then -> exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
else:
br label %exit
; CHECK: edge else -> exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
exit:
%result = phi i32 [ 0, %then ], [ 1, %else ]
ret i32 %result
}
define i32 @test_strncasecmp_sgt(i8* %p, i8* %q) {
; CHECK: Printing analysis {{.*}} for function 'test_strncasecmp_sgt'
entry:
%val = call i32 @strncasecmp(i8* %p, i8* %q, i32 4)
%cond = icmp sgt i32 %val, 0
br i1 %cond, label %then, label %else
; CHECK: edge entry -> then probability is 0x40000000 / 0x80000000 = 50.00%
; CHECK: edge entry -> else probability is 0x40000000 / 0x80000000 = 50.00%
then:
br label %exit
; CHECK: edge then -> exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
else:
br label %exit
; CHECK: edge else -> exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
exit:
%result = phi i32 [ 0, %then ], [ 1, %else ]
ret i32 %result
}
define i32 @test_memcmp_sgt(i8* %p, i8* %q) {
; CHECK: Printing analysis {{.*}} for function 'test_memcmp_sgt'
entry:
%val = call i32 @memcmp(i8* %p, i8* %q)
%cond = icmp sgt i32 %val, 0
br i1 %cond, label %then, label %else
; CHECK: edge entry -> then probability is 0x40000000 / 0x80000000 = 50.00%
; CHECK: edge entry -> else probability is 0x40000000 / 0x80000000 = 50.00%
then:
br label %exit
; CHECK: edge then -> exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
else:
br label %exit
; CHECK: edge else -> exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
exit:
%result = phi i32 [ 0, %then ], [ 1, %else ]
ret i32 %result
}
; Check that for the result of a call to a non-library function the default
; heuristic is applied, i.e. positive more likely than negative, nonzero more
; likely than zero.
define i32 @test_nonstrcmp_eq(i8* %p, i8* %q) {
; CHECK: Printing analysis {{.*}} for function 'test_nonstrcmp_eq'
entry:
%val = call i32 @nonstrcmp(i8* %p, i8* %q)
%cond = icmp eq i32 %val, 0
br i1 %cond, label %then, label %else
; CHECK: edge entry -> then probability is 0x30000000 / 0x80000000 = 37.50%
; CHECK: edge entry -> else probability is 0x50000000 / 0x80000000 = 62.50%
then:
br label %exit
; CHECK: edge then -> exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
else:
br label %exit
; CHECK: edge else -> exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
exit:
%result = phi i32 [ 0, %then ], [ 1, %else ]
ret i32 %result
}
define i32 @test_nonstrcmp_ne(i8* %p, i8* %q) {
; CHECK: Printing analysis {{.*}} for function 'test_nonstrcmp_ne'
entry:
%val = call i32 @nonstrcmp(i8* %p, i8* %q)
%cond = icmp ne i32 %val, 0
br i1 %cond, label %then, label %else
; CHECK: edge entry -> then probability is 0x50000000 / 0x80000000 = 62.50%
; CHECK: edge entry -> else probability is 0x30000000 / 0x80000000 = 37.50%
then:
br label %exit
; CHECK: edge then -> exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
else:
br label %exit
; CHECK: edge else -> exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
exit:
%result = phi i32 [ 0, %then ], [ 1, %else ]
ret i32 %result
}
define i32 @test_nonstrcmp_sgt(i8* %p, i8* %q) {
; CHECK: Printing analysis {{.*}} for function 'test_nonstrcmp_sgt'
entry:
%val = call i32 @nonstrcmp(i8* %p, i8* %q)
%cond = icmp sgt i32 %val, 0
br i1 %cond, label %then, label %else
; CHECK: edge entry -> then probability is 0x50000000 / 0x80000000 = 62.50%
; CHECK: edge entry -> else probability is 0x30000000 / 0x80000000 = 37.50%
then:
br label %exit
; CHECK: edge then -> exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
else:
br label %exit
; CHECK: edge else -> exit probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
exit:
%result = phi i32 [ 0, %then ], [ 1, %else ]
ret i32 %result
}

View File

@ -0,0 +1,403 @@
; Test the static branch probability heuristics for no-return functions.
; RUN: opt < %s -analyze -branch-prob | FileCheck %s
; RUN: opt < %s -passes='print<branch-prob>' --disable-output 2>&1 | FileCheck %s
declare void @g1()
declare void @g2()
declare void @g3()
declare void @g4()
declare i32 @g5()
define void @test1(i32 %a, i32 %b) {
entry:
br label %do.body
; CHECK: edge entry -> do.body probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
do.body:
%i.0 = phi i32 [ 0, %entry ], [ %inc3, %do.end ]
call void @g1()
br label %do.body1
; CHECK: edge do.body -> do.body1 probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
do.body1:
%j.0 = phi i32 [ 0, %do.body ], [ %inc, %do.body1 ]
call void @g2()
%inc = add nsw i32 %j.0, 1
%cmp = icmp slt i32 %inc, %b
br i1 %cmp, label %do.body1, label %do.end
; CHECK: edge do.body1 -> do.body1 probability is 0x7c000000 / 0x80000000 = 96.88% [HOT edge]
; CHECK: edge do.body1 -> do.end probability is 0x04000000 / 0x80000000 = 3.12%
do.end:
call void @g3()
%inc3 = add nsw i32 %i.0, 1
%cmp4 = icmp slt i32 %inc3, %a
br i1 %cmp4, label %do.body, label %do.end5
; CHECK: edge do.end -> do.body probability is 0x7c000000 / 0x80000000 = 96.88% [HOT edge]
; CHECK: edge do.end -> do.end5 probability is 0x04000000 / 0x80000000 = 3.12%
do.end5:
call void @g4()
ret void
}
define void @test2(i32 %a, i32 %b) {
entry:
%cmp9 = icmp sgt i32 %a, 0
br i1 %cmp9, label %for.body.lr.ph, label %for.end6
; CHECK: edge entry -> for.body.lr.ph probability is 0x50000000 / 0x80000000 = 62.50%
; CHECK: edge entry -> for.end6 probability is 0x30000000 / 0x80000000 = 37.50%
for.body.lr.ph:
%cmp27 = icmp sgt i32 %b, 0
br label %for.body
; CHECK: edge for.body.lr.ph -> for.body probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
for.body:
%i.010 = phi i32 [ 0, %for.body.lr.ph ], [ %inc5, %for.end ]
call void @g1()
br i1 %cmp27, label %for.body3, label %for.end
; CHECK: edge for.body -> for.body3 probability is 0x50000000 / 0x80000000 = 62.50%
; CHECK: edge for.body -> for.end probability is 0x30000000 / 0x80000000 = 37.50%
for.body3:
%j.08 = phi i32 [ %inc, %for.body3 ], [ 0, %for.body ]
call void @g2()
%inc = add nsw i32 %j.08, 1
%exitcond = icmp eq i32 %inc, %b
br i1 %exitcond, label %for.end, label %for.body3
; CHECK: edge for.body3 -> for.end probability is 0x04000000 / 0x80000000 = 3.12%
; CHECK: edge for.body3 -> for.body3 probability is 0x7c000000 / 0x80000000 = 96.88% [HOT edge]
for.end:
call void @g3()
%inc5 = add nsw i32 %i.010, 1
%exitcond11 = icmp eq i32 %inc5, %a
br i1 %exitcond11, label %for.end6, label %for.body
; CHECK: edge for.end -> for.end6 probability is 0x04000000 / 0x80000000 = 3.12%
; CHECK: edge for.end -> for.body probability is 0x7c000000 / 0x80000000 = 96.88% [HOT edge]
for.end6:
call void @g4()
ret void
}
define void @test3(i32 %a, i32 %b, i32* %c) {
entry:
br label %do.body
; CHECK: edge entry -> do.body probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
do.body:
%i.0 = phi i32 [ 0, %entry ], [ %inc4, %if.end ]
call void @g1()
%0 = load i32, i32* %c, align 4
%cmp = icmp slt i32 %0, 42
br i1 %cmp, label %do.body1, label %if.end
; CHECK: edge do.body -> do.body1 probability is 0x40000000 / 0x80000000 = 50.00%
; CHECK: edge do.body -> if.end probability is 0x40000000 / 0x80000000 = 50.00%
do.body1:
%j.0 = phi i32 [ %inc, %do.body1 ], [ 0, %do.body ]
call void @g2()
%inc = add nsw i32 %j.0, 1
%cmp2 = icmp slt i32 %inc, %b
br i1 %cmp2, label %do.body1, label %if.end
; CHECK: edge do.body1 -> do.body1 probability is 0x7c000000 / 0x80000000 = 96.88% [HOT edge]
; CHECK: edge do.body1 -> if.end probability is 0x04000000 / 0x80000000 = 3.12%
if.end:
call void @g3()
%inc4 = add nsw i32 %i.0, 1
%cmp5 = icmp slt i32 %inc4, %a
br i1 %cmp5, label %do.body, label %do.end6
; CHECK: edge if.end -> do.body probability is 0x7c000000 / 0x80000000 = 96.88% [HOT edge]
; CHECK: edge if.end -> do.end6 probability is 0x04000000 / 0x80000000 = 3.12%
do.end6:
call void @g4()
ret void
}
define void @test4(i32 %a, i32 %b, i32* %c) {
entry:
br label %do.body
; CHECK: edge entry -> do.body probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
do.body:
%i.0 = phi i32 [ 0, %entry ], [ %inc4, %do.end ]
call void @g1()
%0 = load i32, i32* %c, align 4
%cmp = icmp slt i32 %0, 42
br i1 %cmp, label %return, label %do.body1
; CHECK: edge do.body -> return probability is 0x04000000 / 0x80000000 = 3.12%
; CHECK: edge do.body -> do.body1 probability is 0x7c000000 / 0x80000000 = 96.88% [HOT edge]
do.body1:
%j.0 = phi i32 [ %inc, %do.body1 ], [ 0, %do.body ]
call void @g2()
%inc = add nsw i32 %j.0, 1
%cmp2 = icmp slt i32 %inc, %b
br i1 %cmp2, label %do.body1, label %do.end
; CHECK: edge do.body1 -> do.body1 probability is 0x7c000000 / 0x80000000 = 96.88% [HOT edge]
; CHECK: edge do.body1 -> do.end probability is 0x04000000 / 0x80000000 = 3.12%
do.end:
call void @g3()
%inc4 = add nsw i32 %i.0, 1
%cmp5 = icmp slt i32 %inc4, %a
br i1 %cmp5, label %do.body, label %do.end6
; CHECK: edge do.end -> do.body probability is 0x7c000000 / 0x80000000 = 96.88% [HOT edge]
; CHECK: edge do.end -> do.end6 probability is 0x04000000 / 0x80000000 = 3.12%
do.end6:
call void @g4()
br label %return
; CHECK: edge do.end6 -> return probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
return:
ret void
}
define void @test5(i32 %a, i32 %b, i32* %c) {
entry:
br label %do.body
; CHECK: edge entry -> do.body probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
do.body:
%i.0 = phi i32 [ 0, %entry ], [ %inc4, %do.end ]
call void @g1()
br label %do.body1
; CHECK: edge do.body -> do.body1 probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
do.body1:
%j.0 = phi i32 [ 0, %do.body ], [ %inc, %if.end ]
%0 = load i32, i32* %c, align 4
%cmp = icmp slt i32 %0, 42
br i1 %cmp, label %return, label %if.end
; CHECK: edge do.body1 -> return probability is 0x04000000 / 0x80000000 = 3.12%
; CHECK: edge do.body1 -> if.end probability is 0x7c000000 / 0x80000000 = 96.88% [HOT edge]
if.end:
call void @g2()
%inc = add nsw i32 %j.0, 1
%cmp2 = icmp slt i32 %inc, %b
br i1 %cmp2, label %do.body1, label %do.end
; CHECK: edge if.end -> do.body1 probability is 0x7c000000 / 0x80000000 = 96.88% [HOT edge]
; CHECK: edge if.end -> do.end probability is 0x04000000 / 0x80000000 = 3.12%
do.end:
call void @g3()
%inc4 = add nsw i32 %i.0, 1
%cmp5 = icmp slt i32 %inc4, %a
br i1 %cmp5, label %do.body, label %do.end6
; CHECK: edge do.end -> do.body probability is 0x7c000000 / 0x80000000 = 96.88% [HOT edge]
; CHECK: edge do.end -> do.end6 probability is 0x04000000 / 0x80000000 = 3.12%
do.end6:
call void @g4()
br label %return
; CHECK: edge do.end6 -> return probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
return:
ret void
}
define void @test6(i32 %a, i32 %b, i32* %c) {
entry:
br label %do.body
; CHECK: edge entry -> do.body probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
do.body:
%i.0 = phi i32 [ 0, %entry ], [ %inc4, %do.end ]
call void @g1()
br label %do.body1
; CHECK: edge do.body -> do.body1 probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
do.body1:
%j.0 = phi i32 [ 0, %do.body ], [ %inc, %do.cond ]
call void @g2()
%0 = load i32, i32* %c, align 4
%cmp = icmp slt i32 %0, 42
br i1 %cmp, label %return, label %do.cond
; CHECK: edge do.body1 -> return probability is 0x04000000 / 0x80000000 = 3.12%
; CHECK: edge do.body1 -> do.cond probability is 0x7c000000 / 0x80000000 = 96.88% [HOT edge]
do.cond:
%inc = add nsw i32 %j.0, 1
%cmp2 = icmp slt i32 %inc, %b
br i1 %cmp2, label %do.body1, label %do.end
; CHECK: edge do.cond -> do.body1 probability is 0x7c000000 / 0x80000000 = 96.88% [HOT edge]
; CHECK: edge do.cond -> do.end probability is 0x04000000 / 0x80000000 = 3.12%
do.end:
call void @g3()
%inc4 = add nsw i32 %i.0, 1
%cmp5 = icmp slt i32 %inc4, %a
br i1 %cmp5, label %do.body, label %do.end6
; CHECK: edge do.end -> do.body probability is 0x7c000000 / 0x80000000 = 96.88% [HOT edge]
; CHECK: edge do.end -> do.end6 probability is 0x04000000 / 0x80000000 = 3.12%
do.end6:
call void @g4()
br label %return
; CHECK: edge do.end6 -> return probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
return:
ret void
}
define void @test7(i32 %a, i32 %b, i32* %c) {
entry:
%cmp10 = icmp sgt i32 %a, 0
br i1 %cmp10, label %for.body.lr.ph, label %for.end7
; CHECK: edge entry -> for.body.lr.ph probability is 0x50000000 / 0x80000000 = 62.50%
; CHECK: edge entry -> for.end7 probability is 0x30000000 / 0x80000000 = 37.50%
for.body.lr.ph:
%cmp38 = icmp sgt i32 %b, 0
br label %for.body
; CHECK: edge for.body.lr.ph -> for.body probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
for.body:
%i.011 = phi i32 [ 0, %for.body.lr.ph ], [ %inc6, %for.inc5 ]
%0 = load i32, i32* %c, align 4
%cmp1 = icmp eq i32 %0, %i.011
br i1 %cmp1, label %for.inc5, label %if.end
; CHECK: edge for.body -> for.inc5 probability is 0x40000000 / 0x80000000 = 50.00%
; CHECK: edge for.body -> if.end probability is 0x40000000 / 0x80000000 = 50.00%
if.end:
call void @g1()
br i1 %cmp38, label %for.body4, label %for.end
; CHECK: edge if.end -> for.body4 probability is 0x50000000 / 0x80000000 = 62.50%
; CHECK: edge if.end -> for.end probability is 0x30000000 / 0x80000000 = 37.50%
for.body4:
%j.09 = phi i32 [ %inc, %for.body4 ], [ 0, %if.end ]
call void @g2()
%inc = add nsw i32 %j.09, 1
%exitcond = icmp eq i32 %inc, %b
br i1 %exitcond, label %for.end, label %for.body4
; CHECK: edge for.body4 -> for.end probability is 0x04000000 / 0x80000000 = 3.12%
; CHECK: edge for.body4 -> for.body4 probability is 0x7c000000 / 0x80000000 = 96.88% [HOT edge]
for.end:
call void @g3()
br label %for.inc5
; CHECK: edge for.end -> for.inc5 probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
for.inc5:
%inc6 = add nsw i32 %i.011, 1
%exitcond12 = icmp eq i32 %inc6, %a
br i1 %exitcond12, label %for.end7, label %for.body
; CHECK: edge for.inc5 -> for.end7 probability is 0x04000000 / 0x80000000 = 3.12%
; CHECK: edge for.inc5 -> for.body probability is 0x7c000000 / 0x80000000 = 96.88% [HOT edge]
for.end7:
call void @g4()
ret void
}
define void @test8(i32 %a, i32 %b, i32* %c) {
entry:
%cmp18 = icmp sgt i32 %a, 0
br i1 %cmp18, label %for.body.lr.ph, label %for.end15
; CHECK: edge entry -> for.body.lr.ph probability is 0x50000000 / 0x80000000 = 62.50%
; CHECK: edge entry -> for.end15 probability is 0x30000000 / 0x80000000 = 37.50%
for.body.lr.ph:
%cmp216 = icmp sgt i32 %b, 0
%arrayidx5 = getelementptr inbounds i32, i32* %c, i64 1
%arrayidx9 = getelementptr inbounds i32, i32* %c, i64 2
br label %for.body
; CHECK: edge for.body.lr.ph -> for.body probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
for.body:
%i.019 = phi i32 [ 0, %for.body.lr.ph ], [ %inc14, %for.end ]
call void @g1()
br i1 %cmp216, label %for.body3, label %for.end
; CHECK: edge for.body -> for.body3 probability is 0x50000000 / 0x80000000 = 62.50%
; CHECK: edge for.body -> for.end probability is 0x30000000 / 0x80000000 = 37.50%
for.body3:
%j.017 = phi i32 [ 0, %for.body ], [ %inc, %for.inc ]
%0 = load i32, i32* %c, align 4
%cmp4 = icmp eq i32 %0, %j.017
br i1 %cmp4, label %for.inc, label %if.end
; CHECK: edge for.body3 -> for.inc probability is 0x40000000 / 0x80000000 = 50.00%
; CHECK: edge for.body3 -> if.end probability is 0x40000000 / 0x80000000 = 50.00%
if.end:
%1 = load i32, i32* %arrayidx5, align 4
%cmp6 = icmp eq i32 %1, %j.017
br i1 %cmp6, label %for.inc, label %if.end8
; CHECK: edge if.end -> for.inc probability is 0x40000000 / 0x80000000 = 50.00%
; CHECK: edge if.end -> if.end8 probability is 0x40000000 / 0x80000000 = 50.00%
if.end8:
%2 = load i32, i32* %arrayidx9, align 4
%cmp10 = icmp eq i32 %2, %j.017
br i1 %cmp10, label %for.inc, label %if.end12
; CHECK: edge if.end8 -> for.inc probability is 0x40000000 / 0x80000000 = 50.00%
; CHECK: edge if.end8 -> if.end12 probability is 0x40000000 / 0x80000000 = 50.00%
if.end12:
call void @g2()
br label %for.inc
; CHECK: edge if.end12 -> for.inc probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
for.inc:
%inc = add nsw i32 %j.017, 1
%exitcond = icmp eq i32 %inc, %b
br i1 %exitcond, label %for.end, label %for.body3
; CHECK: edge for.inc -> for.end probability is 0x04000000 / 0x80000000 = 3.12%
; CHECK: edge for.inc -> for.body3 probability is 0x7c000000 / 0x80000000 = 96.88% [HOT edge]
for.end:
call void @g3()
%inc14 = add nsw i32 %i.019, 1
%exitcond20 = icmp eq i32 %inc14, %a
br i1 %exitcond20, label %for.end15, label %for.body
; CHECK: edge for.end -> for.end15 probability is 0x04000000 / 0x80000000 = 3.12%
; CHECK: edge for.end -> for.body probability is 0x7c000000 / 0x80000000 = 96.88% [HOT edge]
for.end15:
call void @g4()
ret void
}
; Test that an irreducible loop gets heavily weighted back-edges.
define void @test9(i32 %i, i32 %x, i32 %c) {
entry:
%tobool = icmp eq i32 %c, 0
br i1 %tobool, label %if.end, label %midloop
; CHECK: edge entry -> if.end probability is 0x30000000 / 0x80000000 = 37.50%
; CHECK: edge entry -> midloop probability is 0x50000000 / 0x80000000 = 62.50%
if.end:
br label %for.cond
; CHECK: edge if.end -> for.cond probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
for.cond:
%i.addr.0 = phi i32 [ %inc, %for.inc ], [ 0, %if.end ]
%cmp = icmp slt i32 %i.addr.0, %x
br i1 %cmp, label %midloop, label %end
; CHECK: edge for.cond -> midloop probability is 0x7c000000 / 0x80000000 = 96.88% [HOT edge]
; CHECK: edge for.cond -> end probability is 0x04000000 / 0x80000000 = 3.12%
midloop:
%i.addr.1 = phi i32 [ %i, %entry ], [ %i.addr.0, %for.cond ]
%call1 = call i32 @g5()
%tobool2 = icmp eq i32 %call1, 0
br i1 %tobool2, label %for.inc, label %end
; CHECK: edge midloop -> for.inc probability is 0x7c000000 / 0x80000000 = 96.88% [HOT edge]
; CHECK: edge midloop -> end probability is 0x04000000 / 0x80000000 = 3.12%
for.inc:
%inc = add nsw i32 %i.addr.1, 1
br label %for.cond
; CHECK: edge for.inc -> for.cond probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
end:
ret void
}

View File

@ -0,0 +1,125 @@
; Test the static branch probability heuristics for no-return functions.
; RUN: opt < %s -analyze -branch-prob | FileCheck %s
; RUN: opt < %s -passes='print<branch-prob>' -disable-output 2>&1 | FileCheck %s
declare void @abort() noreturn
define i32 @test1(i32 %a, i32 %b) {
; CHECK: Printing analysis {{.*}} for function 'test1'
entry:
%cond = icmp eq i32 %a, 42
br i1 %cond, label %exit, label %abort
; CHECK: edge entry -> exit probability is 0x7fffffff / 0x80000000 = 100.00% [HOT edge]
; CHECK: edge entry -> abort probability is 0x00000001 / 0x80000000 = 0.00%
abort:
call void @abort() noreturn
unreachable
exit:
ret i32 %b
}
define i32 @test2(i32 %a, i32 %b) {
; CHECK: Printing analysis {{.*}} for function 'test2'
entry:
switch i32 %a, label %exit [i32 1, label %case_a
i32 2, label %case_b
i32 3, label %case_c
i32 4, label %case_d]
; CHECK: edge entry -> exit probability is 0x7ffffffc / 0x80000000 = 100.00% [HOT edge]
; CHECK: edge entry -> case_a probability is 0x00000001 / 0x80000000 = 0.00%
; CHECK: edge entry -> case_b probability is 0x00000001 / 0x80000000 = 0.00%
; CHECK: edge entry -> case_c probability is 0x00000001 / 0x80000000 = 0.00%
; CHECK: edge entry -> case_d probability is 0x00000001 / 0x80000000 = 0.00%
case_a:
br label %case_b
case_b:
br label %case_c
case_c:
br label %case_d
case_d:
call void @abort() noreturn
unreachable
exit:
ret i32 %b
}
define i32 @test3(i32 %a, i32 %b) {
; CHECK: Printing analysis {{.*}} for function 'test3'
; Make sure we unify across multiple conditional branches.
entry:
%cond1 = icmp eq i32 %a, 42
br i1 %cond1, label %exit, label %dom
; CHECK: edge entry -> exit probability is 0x7fffffff / 0x80000000 = 100.00% [HOT edge]
; CHECK: edge entry -> dom probability is 0x00000001 / 0x80000000 = 0.00%
dom:
%cond2 = icmp ult i32 %a, 42
br i1 %cond2, label %idom1, label %idom2
; CHECK: edge dom -> idom1 probability is 0x40000000 / 0x80000000 = 50.00%
; CHECK: edge dom -> idom2 probability is 0x40000000 / 0x80000000 = 50.00%
idom1:
br label %abort
idom2:
br label %abort
abort:
call void @abort() noreturn
unreachable
exit:
ret i32 %b
}
@_ZTIi = external global i8*
; CHECK-LABEL: throwSmallException
; CHECK-NOT: invoke i32 @smallFunction
define i32 @throwSmallException(i32 %idx, i32 %limit) #0 personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
entry:
%cmp = icmp sge i32 %idx, %limit
br i1 %cmp, label %if.then, label %if.end
; CHECK: edge entry -> if.then probability is 0x00000001 / 0x80000000 = 0.00%
; CHECK: edge entry -> if.end probability is 0x7fffffff / 0x80000000 = 100.00% [HOT edge]
if.then: ; preds = %entry
%exception = call i8* @__cxa_allocate_exception(i64 1) #0
invoke i32 @smallFunction(i32 %idx)
to label %invoke.cont unwind label %lpad
; CHECK: edge if.then -> invoke.cont probability is 0x7ffff800 / 0x80000000 = 100.00% [HOT edge]
; CHECK: edge if.then -> lpad probability is 0x00000800 / 0x80000000 = 0.00%
invoke.cont: ; preds = %if.then
call void @__cxa_throw(i8* %exception, i8* bitcast (i8** @_ZTIi to i8*), i8* null) #1
unreachable
lpad: ; preds = %if.then
%ll = landingpad { i8*, i32 }
cleanup
ret i32 %idx
if.end: ; preds = %entry
ret i32 %idx
}
@a = global i32 4
define i32 @smallFunction(i32 %a) {
entry:
%r = load volatile i32, i32* @a
ret i32 %r
}
attributes #0 = { nounwind }
attributes #1 = { noreturn }
declare i8* @__cxa_allocate_exception(i64)
declare i32 @__gxx_personality_v0(...)
declare void @__cxa_throw(i8*, i8*, i8*)

View File

@ -0,0 +1,59 @@
; RUN: opt < %s -analyze -branch-prob | FileCheck %s
; RUN: opt < %s -passes='print<branch-prob>' -disable-output 2>&1 | FileCheck %s
; Since neither of while.body's out-edges is an exit or a back edge,
; calcLoopBranchHeuristics should return early without setting the weights.
; calcFloatingPointHeuristics, which is run later, sets the weights.
;
; CHECK: edge while.body -> if.then probability is 0x50000000 / 0x80000000 = 62.50%
; CHECK: edge while.body -> if.else probability is 0x30000000 / 0x80000000 = 37.50%
define void @foo1(i32 %n, i32* nocapture %b, i32* nocapture %c, i32* nocapture %d, float* nocapture readonly %f0, float* nocapture readonly %f1) {
entry:
%tobool8 = icmp eq i32 %n, 0
br i1 %tobool8, label %while.end, label %while.body.lr.ph
while.body.lr.ph:
%0 = sext i32 %n to i64
br label %while.body
while.body:
%indvars.iv = phi i64 [ %0, %while.body.lr.ph ], [ %indvars.iv.next, %if.end ]
%b.addr.011 = phi i32* [ %b, %while.body.lr.ph ], [ %b.addr.1, %if.end ]
%d.addr.010 = phi i32* [ %d, %while.body.lr.ph ], [ %incdec.ptr4, %if.end ]
%c.addr.09 = phi i32* [ %c, %while.body.lr.ph ], [ %c.addr.1, %if.end ]
%indvars.iv.next = add nsw i64 %indvars.iv, -1
%arrayidx = getelementptr inbounds float, float* %f0, i64 %indvars.iv.next
%1 = load float, float* %arrayidx, align 4
%arrayidx2 = getelementptr inbounds float, float* %f1, i64 %indvars.iv.next
%2 = load float, float* %arrayidx2, align 4
%cmp = fcmp une float %1, %2
br i1 %cmp, label %if.then, label %if.else
if.then:
%incdec.ptr = getelementptr inbounds i32, i32* %b.addr.011, i64 1
%3 = load i32, i32* %b.addr.011, align 4
%add = add nsw i32 %3, 12
store i32 %add, i32* %b.addr.011, align 4
br label %if.end
if.else:
%incdec.ptr3 = getelementptr inbounds i32, i32* %c.addr.09, i64 1
%4 = load i32, i32* %c.addr.09, align 4
%sub = add nsw i32 %4, -13
store i32 %sub, i32* %c.addr.09, align 4
br label %if.end
if.end:
%c.addr.1 = phi i32* [ %c.addr.09, %if.then ], [ %incdec.ptr3, %if.else ]
%b.addr.1 = phi i32* [ %incdec.ptr, %if.then ], [ %b.addr.011, %if.else ]
%incdec.ptr4 = getelementptr inbounds i32, i32* %d.addr.010, i64 1
store i32 14, i32* %d.addr.010, align 4
%5 = trunc i64 %indvars.iv.next to i32
%tobool = icmp eq i32 %5, 0
br i1 %tobool, label %while.end, label %while.body
while.end:
ret void
}

View File

@ -0,0 +1,85 @@
; RUN: opt < %s -analyze -branch-prob | FileCheck %s
; RUN: opt < %s -passes='print<branch-prob>' -disable-output 2>&1 | FileCheck %s
; In this test, the else clause is taken about 90% of the time. This was not
; reflected in the probability computation because the weight is larger than
; the branch weight cap (about 2 billion).
;
; CHECK: edge for.body -> if.then probability is 0x0cccba45 / 0x80000000 = 10.00%
; CHECK: edge for.body -> if.else probability is 0x733345bb / 0x80000000 = 90.00% [HOT edge]
@y = common global i64 0, align 8
@x = common global i64 0, align 8
@.str = private unnamed_addr constant [17 x i8] c"x = %lu\0Ay = %lu\0A\00", align 1
; Function Attrs: inlinehint nounwind uwtable
define i32 @main() #0 {
entry:
%retval = alloca i32, align 4
%i = alloca i64, align 8
store i32 0, i32* %retval
store i64 0, i64* @y, align 8
store i64 0, i64* @x, align 8
call void @srand(i32 422304) #3
store i64 0, i64* %i, align 8
br label %for.cond
for.cond: ; preds = %for.inc, %entry
%0 = load i64, i64* %i, align 8
%cmp = icmp ult i64 %0, 13000000000
br i1 %cmp, label %for.body, label %for.end, !prof !1
for.body: ; preds = %for.cond
%call = call i32 @rand() #3
%conv = sitofp i32 %call to double
%mul = fmul double %conv, 1.000000e+02
%div = fdiv double %mul, 0x41E0000000000000
%cmp1 = fcmp ogt double %div, 9.000000e+01
br i1 %cmp1, label %if.then, label %if.else, !prof !2
if.then: ; preds = %for.body
%1 = load i64, i64* @x, align 8
%inc = add i64 %1, 1
store i64 %inc, i64* @x, align 8
br label %if.end
if.else: ; preds = %for.body
%2 = load i64, i64* @y, align 8
%inc3 = add i64 %2, 1
store i64 %inc3, i64* @y, align 8
br label %if.end
if.end: ; preds = %if.else, %if.then
br label %for.inc
for.inc: ; preds = %if.end
%3 = load i64, i64* %i, align 8
%inc4 = add i64 %3, 1
store i64 %inc4, i64* %i, align 8
br label %for.cond
for.end: ; preds = %for.cond
%4 = load i64, i64* @x, align 8
%5 = load i64, i64* @y, align 8
%call5 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str, i32 0, i32 0), i64 %4, i64 %5)
ret i32 0
}
; Function Attrs: nounwind
declare void @srand(i32) #1
; Function Attrs: nounwind
declare i32 @rand() #1
declare i32 @printf(i8*, ...) #2
attributes #0 = { inlinehint nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #2 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #3 = { nounwind }
!llvm.ident = !{!0}
!0 = !{!"clang version 3.7.0 (trunk 236218) (llvm/trunk 236235)"}
!1 = !{!"branch_weights", i32 -1044967295, i32 1}
!2 = !{!"branch_weights", i32 433323762, i32 -394957723}