149 lines
2.9 KiB
C++
149 lines
2.9 KiB
C++
|
// RUN: %clang_cc1 -O1 -emit-llvm %s -o - -triple=x86_64-linux-gnu | FileCheck -DLIKELY=2000 -DUNLIKELY=1 %s
|
||
|
// RUN: %clang_cc1 -O1 -emit-llvm %s -triple=x86_64-linux-gnu -mllvm -likely-branch-weight=99 -mllvm -unlikely-branch-weight=42 -o - | FileCheck -DLIKELY=99 -DUNLIKELY=42 %s
|
||
|
|
||
|
extern volatile bool b;
|
||
|
extern volatile int i;
|
||
|
extern bool A();
|
||
|
extern bool B();
|
||
|
|
||
|
bool f() {
|
||
|
// CHECK-LABEL: define{{.*}} zeroext i1 @_Z1fv
|
||
|
// CHECK: br {{.*}} !prof !7
|
||
|
if (b)
|
||
|
[[likely]] {
|
||
|
return A();
|
||
|
}
|
||
|
return B();
|
||
|
}
|
||
|
|
||
|
bool g() {
|
||
|
// CHECK-LABEL: define{{.*}} zeroext i1 @_Z1gv
|
||
|
// CHECK: br {{.*}} !prof !8
|
||
|
if (b)
|
||
|
[[unlikely]] {
|
||
|
return A();
|
||
|
}
|
||
|
|
||
|
return B();
|
||
|
}
|
||
|
|
||
|
bool h() {
|
||
|
// CHECK-LABEL: define{{.*}} zeroext i1 @_Z1hv
|
||
|
// CHECK: br {{.*}} !prof !8
|
||
|
if (b)
|
||
|
[[unlikely]] return A();
|
||
|
|
||
|
return B();
|
||
|
}
|
||
|
|
||
|
void NullStmt() {
|
||
|
// CHECK-LABEL: define{{.*}}NullStmt
|
||
|
// CHECK: br {{.*}} !prof !8
|
||
|
if (b)
|
||
|
[[unlikely]];
|
||
|
else {
|
||
|
// Make sure the branches aren't optimized away.
|
||
|
b = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void IfStmt() {
|
||
|
// CHECK-LABEL: define{{.*}}IfStmt
|
||
|
// CHECK: br {{.*}} !prof !8
|
||
|
if (b)
|
||
|
[[unlikely]] if (B()) {}
|
||
|
|
||
|
// CHECK-NOT: br {{.*}} !prof
|
||
|
// CHECK: br {{.*}} !prof
|
||
|
if (b) {
|
||
|
if (B())
|
||
|
[[unlikely]] { b = false; }
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void WhileStmt() {
|
||
|
// CHECK-LABEL: define{{.*}}WhileStmt
|
||
|
// CHECK: br {{.*}} !prof !8
|
||
|
if (b)
|
||
|
[[unlikely]] while (B()) {}
|
||
|
|
||
|
// CHECK-NOT: br {{.*}} %if.end{{.*}} !prof
|
||
|
if (b)
|
||
|
// CHECK: br {{.*}} !prof !7
|
||
|
while (B())
|
||
|
[[unlikely]] { b = false; }
|
||
|
}
|
||
|
|
||
|
void DoStmt() {
|
||
|
// CHECK-LABEL: define{{.*}}DoStmt
|
||
|
// CHECK: br {{.*}} !prof !8
|
||
|
if (b)
|
||
|
[[unlikely]] do {}
|
||
|
while (B())
|
||
|
;
|
||
|
|
||
|
// CHECK-NOT: br {{.*}} %if.end{{.*}} !prof
|
||
|
if (b)
|
||
|
do
|
||
|
[[unlikely]] {}
|
||
|
while (B());
|
||
|
}
|
||
|
|
||
|
void ForStmt() {
|
||
|
// CHECK-LABEL: define{{.*}}ForStmt
|
||
|
// CHECK: br {{.*}} !prof !8
|
||
|
if (b)
|
||
|
[[unlikely]] for (; B();) {}
|
||
|
|
||
|
// CHECK-NOT: br {{.*}} %if.end{{.*}} !prof
|
||
|
if (b)
|
||
|
// CHECK: br {{.*}} !prof !7
|
||
|
for (; B();)
|
||
|
[[unlikely]] {}
|
||
|
}
|
||
|
|
||
|
void GotoStmt() {
|
||
|
// CHECK-LABEL: define{{.*}}GotoStmt
|
||
|
// CHECK: br {{.*}} !prof !8
|
||
|
if (b)
|
||
|
[[unlikely]] goto end;
|
||
|
else {
|
||
|
// Make sure the branches aren't optimized away.
|
||
|
b = true;
|
||
|
}
|
||
|
end:;
|
||
|
}
|
||
|
|
||
|
void ReturnStmt() {
|
||
|
// CHECK-LABEL: define{{.*}}ReturnStmt
|
||
|
// CHECK: br {{.*}} !prof !8
|
||
|
if (b)
|
||
|
[[unlikely]] return;
|
||
|
else {
|
||
|
// Make sure the branches aren't optimized away.
|
||
|
b = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void SwitchStmt() {
|
||
|
// CHECK-LABEL: define{{.*}}SwitchStmt
|
||
|
// CHECK: br {{.*}} !prof !8
|
||
|
if (b)
|
||
|
[[unlikely]] switch (i) {}
|
||
|
else {
|
||
|
// Make sure the branches aren't optimized away.
|
||
|
b = true;
|
||
|
}
|
||
|
// CHECK-NOT: br {{.*}} %if.end{{.*}} !prof
|
||
|
if (b)
|
||
|
switch (i)
|
||
|
[[unlikely]] {}
|
||
|
else {
|
||
|
// Make sure the branches aren't optimized away.
|
||
|
b = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// CHECK: !7 = !{!"branch_weights", i32 [[UNLIKELY]], i32 [[LIKELY]]}
|
||
|
// CHECK: !8 = !{!"branch_weights", i32 [[LIKELY]], i32 [[UNLIKELY]]}
|