[llvm] [BPI] Refine libcall heuristic (PR #79941)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Jan 29 19:53:05 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-analysis
Author: None (lcvon007)
<details>
<summary>Changes</summary>
The return value of fread, fwrite, read and write is likely to
be equal to the count parameter and many system library calls
like mkdir, chown, mkdir etc will return 0 when it runs
successfully, so it can predict the branch probability better
to use these information.
---
Patch is 41.48 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/79941.diff
2 Files Affected:
- (modified) llvm/lib/Analysis/BranchProbabilityInfo.cpp (+95-13)
- (modified) llvm/test/Analysis/BranchProbabilityInfo/libfunc_call.ll (+927-15)
``````````diff
diff --git a/llvm/lib/Analysis/BranchProbabilityInfo.cpp b/llvm/lib/Analysis/BranchProbabilityInfo.cpp
index 6448ed66dc51c..388d446605050 100644
--- a/llvm/lib/Analysis/BranchProbabilityInfo.cpp
+++ b/llvm/lib/Analysis/BranchProbabilityInfo.cpp
@@ -162,11 +162,53 @@ static const ProbabilityTable ICmpWithOneTable{
/// probably false given that what exactly is returned for nonzero values is
/// not specified. Any kind of comparison other than equality we know
/// nothing about.
-static const ProbabilityTable ICmpWithLibCallTable{
+static const ProbabilityTable ICmpWithCmpLibCallTable{
{CmpInst::ICMP_EQ, {ZeroUntakenProb, ZeroTakenProb}},
{CmpInst::ICMP_NE, {ZeroTakenProb, ZeroUntakenProb}},
};
+// LibCall Heuristics
+static const uint32_t LIBH_TAKEN_WEIGHT = 999;
+static const uint32_t LIBH_NONTAKEN_WEIGHT = 1;
+static const BranchProbability
+ LibTakenProb(LIBH_TAKEN_WEIGHT, LIBH_TAKEN_WEIGHT + LIBH_NONTAKEN_WEIGHT);
+static const BranchProbability LibUntakenProb(LIBH_NONTAKEN_WEIGHT,
+ LIBH_TAKEN_WEIGHT +
+ LIBH_NONTAKEN_WEIGHT);
+
+/// The return value of fread, fwrite, read and write will be mostly equal to
+/// the count parameter. So a comparison using eq is probably true when
+/// comparing return value and count parameter.
+static const ProbabilityTable ICmpWithRWLibcallEqTable{
+ {CmpInst::ICMP_EQ, {LibTakenProb, LibUntakenProb}}, /// X == Y -> likely
+ {CmpInst::ICMP_NE, {LibUntakenProb, LibTakenProb}}, /// X != Y -> Unlikely
+ {CmpInst::ICMP_SLT, {LibUntakenProb, LibTakenProb}}, /// X < Y -> Unlikely
+};
+
+/// The return value of fread and fwrite will be zero when size or count
+/// parameter is zero and it's less possible in program. The return value of
+/// read and write will only be -1 when they run failed. So a comparison
+/// with 0 or -1 is probably false.
+static const ProbabilityTable ICmpWithRWLibcallZeroTable{
+ {CmpInst::ICMP_EQ,
+ {LibUntakenProb, LibTakenProb}}, /// X == 0 or -1 -> Unlikely
+ {CmpInst::ICMP_NE,
+ {LibTakenProb, LibUntakenProb}}, /// X != 0 or -1 -> Likely
+};
+
+/// The return value of fread, fwrite, read and write will be mostly not less
+/// than 1. So a comparison that is slt 1 is probably false.
+static const ProbabilityTable ICmpWithRWLibcallOneTable{
+ {CmpInst::ICMP_SLT, {LibUntakenProb, LibTakenProb}}, /// X < 1 -> Unlikely
+};
+
+/// Most system library call like chmod, chown, mkdir etc will return 0 when
+/// they run successfully. So a comparison with 0 is probably true.
+static const ProbabilityTable ICmpWithSysLibcallTable{
+ {CmpInst::ICMP_EQ, {LibTakenProb, LibUntakenProb}}, /// X == 0 -> Likely
+ {CmpInst::ICMP_NE, {LibUntakenProb, LibTakenProb}}, /// X != 0 -> Unlikely
+};
+
// Floating-Point Heuristics (FPH)
static const uint32_t FPH_TAKEN_WEIGHT = 20;
static const uint32_t FPH_NONTAKEN_WEIGHT = 12;
@@ -977,10 +1019,15 @@ bool BranchProbabilityInfo::calcZeroHeuristics(const BasicBlock *BB,
return dyn_cast<ConstantInt>(V);
};
- Value *RHS = CI->getOperand(1);
- ConstantInt *CV = GetConstantInt(RHS);
- if (!CV)
+ auto IsSameValue = [&](Value *Lhs, Value *Rhs) -> bool {
+ if (Lhs == Rhs)
+ return true;
+ auto *LhsCV = GetConstantInt(Lhs);
+ auto *RhsCV = GetConstantInt(Rhs);
+ if (LhsCV && RhsCV && LhsCV->getZExtValue() == RhsCV->getZExtValue())
+ return true;
return false;
+ };
// If the LHS is the result of AND'ing a value with a single bit bitmask,
// we don't have information about probabilities.
@@ -996,16 +1043,51 @@ bool BranchProbabilityInfo::calcZeroHeuristics(const BasicBlock *BB,
if (CallInst *Call = dyn_cast<CallInst>(CI->getOperand(0)))
if (Function *CalledFn = Call->getCalledFunction())
TLI->getLibFunc(*CalledFn, Func);
-
+ Value *RHS = CI->getOperand(1);
+ ConstantInt *CV = GetConstantInt(RHS);
ProbabilityTable::const_iterator Search;
- if (Func == LibFunc_strcasecmp ||
- Func == LibFunc_strcmp ||
- Func == LibFunc_strncasecmp ||
- Func == LibFunc_strncmp ||
- Func == LibFunc_memcmp ||
- Func == LibFunc_bcmp) {
- Search = ICmpWithLibCallTable.find(CI->getPredicate());
- if (Search == ICmpWithLibCallTable.end())
+ if (Func == LibFunc_fread || Func == LibFunc_fwrite || Func == LibFunc_read ||
+ Func == LibFunc_write) {
+ const uint32_t CountOpId = 2;
+ auto *Call = dyn_cast<CallInst>(CI->getOperand(0));
+ if (CV && (CV->isZero() || CV->isMinusOne())) {
+ Search = ICmpWithRWLibcallZeroTable.find(CI->getPredicate());
+ if (Search == ICmpWithRWLibcallZeroTable.end())
+ return false;
+ } else if (CV && CV->isOne()) {
+ Search = ICmpWithRWLibcallOneTable.find(CI->getPredicate());
+ if (Search == ICmpWithRWLibcallOneTable.end())
+ return false;
+ } else if (IsSameValue(Call->getOperand(CountOpId), RHS)) {
+ Search = ICmpWithRWLibcallEqTable.find(CI->getPredicate());
+ if (Search == ICmpWithRWLibcallEqTable.end())
+ return false;
+ } else
+ return false;
+ } else if (!CV)
+ return false;
+ else if (Func == LibFunc_strcasecmp || Func == LibFunc_strcmp ||
+ Func == LibFunc_strncasecmp || Func == LibFunc_strncmp ||
+ Func == LibFunc_memcmp || Func == LibFunc_bcmp) {
+ Search = ICmpWithCmpLibCallTable.find(CI->getPredicate());
+ if (Search == ICmpWithCmpLibCallTable.end())
+ return false;
+ } else if (CV->isZero() &&
+ (Func == LibFunc_chmod || Func == LibFunc_chown ||
+ Func == LibFunc_closedir || Func == LibFunc_fclose ||
+ Func == LibFunc_ferror || Func == LibFunc_fflush ||
+ Func == LibFunc_fseek || Func == LibFunc_fseeko ||
+ Func == LibFunc_fsetpos || Func == LibFunc_fstat ||
+ Func == LibFunc_fstatvfs || Func == LibFunc_ftrylockfile ||
+ Func == LibFunc_lchown || Func == LibFunc_lstat ||
+ Func == LibFunc_mkdir || Func == LibFunc_remove ||
+ Func == LibFunc_rename || Func == LibFunc_rmdir ||
+ Func == LibFunc_setvbuf || Func == LibFunc_stat ||
+ Func == LibFunc_statvfs || Func == LibFunc_unlink ||
+ Func == LibFunc_unsetenv || Func == LibFunc_utime ||
+ Func == LibFunc_utimes)) {
+ Search = ICmpWithSysLibcallTable.find(CI->getPredicate());
+ if (Search == ICmpWithSysLibcallTable.end())
return false;
} else if (CV->isZero()) {
Search = ICmpWithZeroTable.find(CI->getPredicate());
diff --git a/llvm/test/Analysis/BranchProbabilityInfo/libfunc_call.ll b/llvm/test/Analysis/BranchProbabilityInfo/libfunc_call.ll
index c342edcc64afc..6acbed9e77963 100644
--- a/llvm/test/Analysis/BranchProbabilityInfo/libfunc_call.ll
+++ b/llvm/test/Analysis/BranchProbabilityInfo/libfunc_call.ll
@@ -7,13 +7,41 @@ declare i32 @strncasecmp(ptr, ptr, i32)
declare i32 @memcmp(ptr, ptr)
declare i32 @bcmp(ptr, ptr)
declare i32 @nonstrcmp(ptr, ptr)
+declare i64 @fread(ptr, i64, i64, ptr)
+declare i64 @fwrite(ptr, i64, i64, ptr)
+declare i64 @read(i32, ptr, i64)
+declare i64 @write(i32, ptr, i64)
+declare i32 @chmod(ptr, i32)
+declare i32 @chown(ptr, i32, i32)
+declare i32 @closedir(ptr)
+declare i32 @fclose(ptr)
+declare i32 @ferror(ptr)
+declare i32 @fflush(ptr)
+declare i32 @fseek(ptr, i64, i32)
+declare i32 @fseeko(ptr, i64, i32)
+declare i32 @fstat(i32, ptr)
+declare i32 @fstatvfs(i32, ptr)
+declare i32 @ftrylockfile(ptr)
+declare i32 @lchown(ptr)
+declare i32 @lstat(ptr, ptr)
+declare i32 @mkdir(ptr, i32)
+declare i32 @remove(ptr)
+declare i32 @rename(ptr, ptr)
+declare i32 @rmdir(ptr)
+declare i32 @setvbuf(ptr, ptr, i32, i64)
+declare i32 @stat(ptr, ptr)
+declare i32 @statvfs(ptr, ptr)
+declare i32 @unlink(ptr)
+declare i32 @unsetenv(ptr)
+declare i32 @utime(ptr, ptr)
+declare i32 @utimes(ptr, ptr)
; 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(ptr %p, ptr %q) {
-; CHECK: Printing analysis {{.*}} for function 'test_strcmp_eq'
+; CHECK-LABEL: Printing analysis {{.*}} for function 'test_strcmp_eq'
entry:
%val = call i32 @strcmp(ptr %p, ptr %q)
%cond = icmp eq i32 %val, 0
@@ -35,7 +63,7 @@ exit:
}
define i32 @test_strcmp_eq5(ptr %p, ptr %q) {
-; CHECK: Printing analysis {{.*}} for function 'test_strcmp_eq5'
+; CHECK-LABEL: Printing analysis {{.*}} for function 'test_strcmp_eq5'
entry:
%val = call i32 @strcmp(ptr %p, ptr %q)
%cond = icmp eq i32 %val, 5
@@ -57,7 +85,7 @@ exit:
}
define i32 @test_strcmp_ne(ptr %p, ptr %q) {
-; CHECK: Printing analysis {{.*}} for function 'test_strcmp_ne'
+; CHECK-LABEL: Printing analysis {{.*}} for function 'test_strcmp_ne'
entry:
%val = call i32 @strcmp(ptr %p, ptr %q)
%cond = icmp ne i32 %val, 0
@@ -79,7 +107,7 @@ exit:
}
define i32 @test_strcmp_sgt(ptr %p, ptr %q) {
-; CHECK: Printing analysis {{.*}} for function 'test_strcmp_sgt'
+; CHECK-LABEL: Printing analysis {{.*}} for function 'test_strcmp_sgt'
entry:
%val = call i32 @strcmp(ptr %p, ptr %q)
%cond = icmp sgt i32 %val, 0
@@ -101,7 +129,7 @@ exit:
}
define i32 @test_strcmp_slt(ptr %p, ptr %q) {
-; CHECK: Printing analysis {{.*}} for function 'test_strcmp_slt'
+; CHECK-LABEL: Printing analysis {{.*}} for function 'test_strcmp_slt'
entry:
%val = call i32 @strcmp(ptr %p, ptr %q)
%cond = icmp slt i32 %val, 0
@@ -126,7 +154,7 @@ exit:
; Similarly check other library functions that have the same behaviour
define i32 @test_strncmp_sgt(ptr %p, ptr %q) {
-; CHECK: Printing analysis {{.*}} for function 'test_strncmp_sgt'
+; CHECK-LABEL: Printing analysis {{.*}} for function 'test_strncmp_sgt'
entry:
%val = call i32 @strncmp(ptr %p, ptr %q, i32 4)
%cond = icmp sgt i32 %val, 0
@@ -148,7 +176,7 @@ exit:
}
define i32 @test_strcasecmp_sgt(ptr %p, ptr %q) {
-; CHECK: Printing analysis {{.*}} for function 'test_strcasecmp_sgt'
+; CHECK-LABEL: Printing analysis {{.*}} for function 'test_strcasecmp_sgt'
entry:
%val = call i32 @strcasecmp(ptr %p, ptr %q)
%cond = icmp sgt i32 %val, 0
@@ -170,7 +198,7 @@ exit:
}
define i32 @test_strncasecmp_sgt(ptr %p, ptr %q) {
-; CHECK: Printing analysis {{.*}} for function 'test_strncasecmp_sgt'
+; CHECK-LABEL: Printing analysis {{.*}} for function 'test_strncasecmp_sgt'
entry:
%val = call i32 @strncasecmp(ptr %p, ptr %q, i32 4)
%cond = icmp sgt i32 %val, 0
@@ -192,7 +220,7 @@ exit:
}
define i32 @test_memcmp_sgt(ptr %p, ptr %q) {
-; CHECK: Printing analysis {{.*}} for function 'test_memcmp_sgt'
+; CHECK-LABEL: Printing analysis {{.*}} for function 'test_memcmp_sgt'
entry:
%val = call i32 @memcmp(ptr %p, ptr %q)
%cond = icmp sgt i32 %val, 0
@@ -219,7 +247,7 @@ exit:
; likely than zero.
define i32 @test_nonstrcmp_eq(ptr %p, ptr %q) {
-; CHECK: Printing analysis {{.*}} for function 'test_nonstrcmp_eq'
+; CHECK-LABEL: Printing analysis {{.*}} for function 'test_nonstrcmp_eq'
entry:
%val = call i32 @nonstrcmp(ptr %p, ptr %q)
%cond = icmp eq i32 %val, 0
@@ -241,7 +269,7 @@ exit:
}
define i32 @test_nonstrcmp_ne(ptr %p, ptr %q) {
-; CHECK: Printing analysis {{.*}} for function 'test_nonstrcmp_ne'
+; CHECK-LABEL: Printing analysis {{.*}} for function 'test_nonstrcmp_ne'
entry:
%val = call i32 @nonstrcmp(ptr %p, ptr %q)
%cond = icmp ne i32 %val, 0
@@ -263,7 +291,7 @@ exit:
}
define i32 @test_nonstrcmp_sgt(ptr %p, ptr %q) {
-; CHECK: Printing analysis {{.*}} for function 'test_nonstrcmp_sgt'
+; CHECK-LABEL: Printing analysis {{.*}} for function 'test_nonstrcmp_sgt'
entry:
%val = call i32 @nonstrcmp(ptr %p, ptr %q)
%cond = icmp sgt i32 %val, 0
@@ -286,7 +314,7 @@ exit:
define i32 @test_bcmp_eq(ptr %p, ptr %q) {
-; CHECK: Printing analysis {{.*}} for function 'test_bcmp_eq'
+; CHECK-LABEL: Printing analysis {{.*}} for function 'test_bcmp_eq'
entry:
%val = call i32 @bcmp(ptr %p, ptr %q)
%cond = icmp eq i32 %val, 0
@@ -308,7 +336,7 @@ exit:
}
define i32 @test_bcmp_eq5(ptr %p, ptr %q) {
-; CHECK: Printing analysis {{.*}} for function 'test_bcmp_eq5'
+; CHECK-LABEL: Printing analysis {{.*}} for function 'test_bcmp_eq5'
entry:
%val = call i32 @bcmp(ptr %p, ptr %q)
%cond = icmp eq i32 %val, 5
@@ -332,7 +360,7 @@ exit:
define i32 @test_bcmp_ne(ptr %p, ptr %q) {
-; CHECK: Printing analysis {{.*}} for function 'test_bcmp_ne'
+; CHECK-LABEL: Printing analysis {{.*}} for function 'test_bcmp_ne'
entry:
%val = call i32 @bcmp(ptr %p, ptr %q)
%cond = icmp ne i32 %val, 0
@@ -352,3 +380,887 @@ exit:
%result = phi i32 [ 0, %then ], [ 1, %else ]
ret i32 %result
}
+
+define i32 @test_fread_eq_zero(i64 %size, i64 %count, ptr %p, ptr %q) {
+; CHECK-LABEL: Printing analysis {{.*}} for function 'test_fread_eq_zero'
+entry:
+ %val = call i64 @fread(ptr %p, i64 %size, i64 %count, ptr %q)
+ %cond = icmp eq i64 %val, 0
+ br i1 %cond, label %then, label %else
+; CHECK: edge %entry -> %then probability is 0x0020c49c / 0x80000000 = 0.10%
+; CHECK: edge %entry -> %else probability is 0x7fdf3b64 / 0x80000000 = 99.90%
+
+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_fread_ne_zero(i64 %size, i64 %count, ptr %p, ptr %q) {
+; CHECK-LABEL: Printing analysis {{.*}} for function 'test_fread_ne_zero'
+entry:
+ %val = call i64 @fread(ptr %p, i64 %size, i64 %count, ptr %q)
+ %cond = icmp ne i64 %val, 0
+ br i1 %cond, label %then, label %else
+; CHECK: edge %entry -> %then probability is 0x7fdf3b64 / 0x80000000 = 99.90%
+; CHECK: edge %entry -> %else probability is 0x0020c49c / 0x80000000 = 0.10%
+
+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_fread_slt_one(i64 %size, i64 %count, ptr %p, ptr %q) {
+; CHECK-LABEL: Printing analysis {{.*}} for function 'test_fread_slt_one'
+entry:
+ %val = call i64 @fread(ptr %p, i64 %size, i64 %count, ptr %q)
+ %cond = icmp slt i64 %val, 1
+ br i1 %cond, label %then, label %else
+; CHECK: edge %entry -> %then probability is 0x0020c49c / 0x80000000 = 0.10%
+; CHECK: edge %entry -> %else probability is 0x7fdf3b64 / 0x80000000 = 99.90%
+
+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_fread_eq_count(i64 %size, i64 %count, ptr %p, ptr %q) {
+; CHECK-LABEL: Printing analysis {{.*}} for function 'test_fread_eq_count'
+entry:
+ %val = call i64 @fread(ptr %p, i64 %size, i64 %count, ptr %q)
+ %cond = icmp eq i64 %val, %count
+ br i1 %cond, label %then, label %else
+; CHECK: edge %entry -> %then probability is 0x7fdf3b64 / 0x80000000 = 99.90%
+; CHECK: edge %entry -> %else probability is 0x0020c49c / 0x80000000 = 0.10%
+
+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_fread_ne_count(i64 %size, i64 %count, ptr %p, ptr %q) {
+; CHECK-LABEL: Printing analysis {{.*}} for function 'test_fread_ne_count'
+entry:
+ %val = call i64 @fread(ptr %p, i64 %size, i64 %count, ptr %q)
+ %cond = icmp ne i64 %val, %count
+ br i1 %cond, label %then, label %else
+; CHECK: edge %entry -> %then probability is 0x0020c49c / 0x80000000 = 0.10%
+; CHECK: edge %entry -> %else probability is 0x7fdf3b64 / 0x80000000 = 99.90%
+
+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_fread_eq_const_count(i64 %size, ptr %p, ptr %q) {
+; CHECK-LABEL: Printing analysis {{.*}} for function 'test_fread_eq_const_count'
+entry:
+ %val = call i64 @fread(ptr %p, i64 %size, i64 10, ptr %q)
+ %cond = icmp eq i64 %val, 10
+ br i1 %cond, label %then, label %else
+; CHECK: edge %entry -> %then probability is 0x7fdf3b64 / 0x80000000 = 99.90%
+; CHECK: edge %entry -> %else probability is 0x0020c49c / 0x80000000 = 0.10%
+
+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_fread_ne_const_count(i64 %size, ptr %p, ptr %q) {
+; CHECK-LABEL: Printing analysis {{.*}} for function 'test_fread_ne_const_count'
+entry:
+ %val = call i64 @fread(ptr %p, i64 %size, i64 10, ptr %q)
+ %cond = icmp ne i64 %val, 10
+ br i1 %cond, label %then, label %else
+; CHECK: edge %entry -> %then probability is 0x0020c49c / 0x80000000 = 0.10%
+; CHECK: edge %entry -> %else probability is 0x7fdf3b64 / 0x80000000 = 99.90%
+
+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_fread_slt_count(i64 %size, i64 %count, ptr %p, ptr %q) {
+; CHECK-LABEL: Printing analysis {{.*}} for function 'test_fread_slt_count'
+entry:
+ %val = call i64 @fread(ptr %p, i64 %size, i64 %count, ptr %q)
+ %cond = icmp slt i64 %val, %count
+ br i1 %cond, label %then, label %else
+; CHECK: edge %entry -> %then probability is 0x0020c49c / 0x80000000 = 0.10%
+; CHECK: edge %entry -> %else probability is 0x7fdf3b64 / 0x80000000 = 99.90%
+
+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_fread_slt_const_count(i64 %size, ptr %p, ptr %q) {
+; CHECK-LABEL: Printing analysis {{.*}} for function 'test_fread_slt_const_count'
+entry:
+ %val = call i64 @fread(ptr %p, i64 %size, i64 10, ptr %q)
+ %cond = icmp slt i64 %val, 10
+ br i1 %cond, label %then, label %else
+; CHECK: edge %entry -> %then probability is 0x0020c49c / 0x80000000 = 0.10%
+; CHECK: edge %entry -> %else probability is 0x7fdf3b64 / 0x80000000 = 99.90%
+
+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
+}
+
+; fwrite only tests eq predicate
+define i32 @test_fwrite_eq_zero(i64 %size, i64 %count, ptr %p, ptr %q) {
+; CHECK-LABEL: Printing analysis {{.*}} for function 'test_fwrite_eq_zero'
+entry:
+ %val = call i64 @fwrite(ptr %p, i64 %size, i64 %count, ptr %q)
+ %cond = icmp eq i64 %val, 0
+ br i1 %cond, label %then, label %else
+; CHECK: edge %entry -> %then probability is 0x0020c49c / 0x80000000 = 0.10%
+; CHECK: edge %entry -> %else probability is 0x7fdf3b64 / 0x80000000 = 99.90%
+
+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
+}
+
...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/79941
More information about the llvm-commits
mailing list