Files
clang-p2996/clang/test/CodeGenCXX/attr-likelihood-if-branch-weights.cpp
Fangrui Song fd739804e0 [test] Add {{.*}} to make ELF tests immune to dso_local/dso_preemptable/(none) differences
For a default visibility external linkage definition, dso_local is set for ELF
-fno-pic/-fpie and COFF and Mach-O. Since default clang -cc1 for ELF is similar
to -fpic ("PIC Level" is not set), this nuance causes unneeded binary format differences.

To make emitted IR similar, ELF -cc1 -fpic will default to -fno-semantic-interposition,
which sets dso_local for default visibility external linkage definitions.

To make this flip smooth and enable future (dso_local as definition default),
this patch replaces (function) `define ` with `define{{.*}} `,
(variable/constant/alias) `= ` with `={{.*}} `, or inserts appropriate `{{.*}} `.
2020-12-31 00:27:11 -08:00

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]]}