blob: 4f0009e29056683434f4be940d1a57952f5fd1d8 [file] [log] [blame]
// 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]]}