Skip to content

Commit 0d74b6c

Browse files
committed
[clang codegen] Emit !unpredictable metadata more consistently.
Conditional operators that emit a branch go through a codepath which attaches metadata to that branch. But if we take a shortcut to emit a select directly, we end up skipping that code, and don't emit the metadata. This patch adds code to attach metadata to those select instructions. While I'm here, also refactor the code for computing the metadata a bit.
1 parent 82a3646 commit 0d74b6c

File tree

5 files changed

+48
-29
lines changed

5 files changed

+48
-29
lines changed

clang/lib/CodeGen/CGExprScalar.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5338,7 +5338,15 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
53385338
assert(!RHS && "LHS and RHS types must match");
53395339
return nullptr;
53405340
}
5341-
return Builder.CreateSelect(CondV, LHS, RHS, "cond");
5341+
llvm::Value *Select = Builder.CreateSelect(CondV, LHS, RHS, "cond");
5342+
if (auto *SelectI = dyn_cast<llvm::Instruction>(Select)) {
5343+
if (llvm::MDNode *Unpredictable =
5344+
CGF.getUnpredictableMetadata(condExpr)) {
5345+
SelectI->setMetadata(llvm::LLVMContext::MD_unpredictable,
5346+
Unpredictable);
5347+
}
5348+
}
5349+
return Select;
53425350
}
53435351

53445352
// If the top of the logical operator nest, reset the MCDC temp to 0.

clang/lib/CodeGen/CGStmt.cpp

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2257,17 +2257,8 @@ void CodeGenFunction::EmitSwitchStmt(const SwitchStmt &S) {
22572257
EmitBlock(SwitchExit.getBlock(), true);
22582258
incrementProfileCounter(&S);
22592259

2260-
// If the switch has a condition wrapped by __builtin_unpredictable,
2261-
// create metadata that specifies that the switch is unpredictable.
2262-
// Don't bother if not optimizing because that metadata would not be used.
2263-
auto *Call = dyn_cast<CallExpr>(S.getCond());
2264-
if (Call && CGM.getCodeGenOpts().OptimizationLevel != 0) {
2265-
auto *FD = dyn_cast_or_null<FunctionDecl>(Call->getCalleeDecl());
2266-
if (FD && FD->getBuiltinID() == Builtin::BI__builtin_unpredictable) {
2267-
llvm::MDBuilder MDHelper(getLLVMContext());
2268-
SwitchInsn->setMetadata(llvm::LLVMContext::MD_unpredictable,
2269-
MDHelper.createUnpredictable());
2270-
}
2260+
if (llvm::MDNode *Unpredictable = getUnpredictableMetadata(S.getCond())) {
2261+
SwitchInsn->setMetadata(llvm::LLVMContext::MD_unpredictable, Unpredictable);
22712262
}
22722263

22732264
if (SwitchWeights) {

clang/lib/CodeGen/CodeGenFunction.cpp

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1820,6 +1820,21 @@ void CodeGenFunction::EmitBranchToCounterBlock(
18201820
EmitBranch(NextBlock);
18211821
}
18221822

1823+
llvm::MDNode *CodeGenFunction::getUnpredictableMetadata(const Expr *Cond) {
1824+
// If the branch has a condition wrapped by __builtin_unpredictable,
1825+
// create metadata that specifies that the branch is unpredictable.
1826+
// Don't bother if not optimizing because that metadata would not be used.
1827+
auto *Call = dyn_cast<CallExpr>(Cond->IgnoreImpCasts());
1828+
if (Call && CGM.getCodeGenOpts().OptimizationLevel != 0) {
1829+
auto *FD = dyn_cast_or_null<FunctionDecl>(Call->getCalleeDecl());
1830+
if (FD && FD->getBuiltinID() == Builtin::BI__builtin_unpredictable) {
1831+
llvm::MDBuilder MDHelper(getLLVMContext());
1832+
return MDHelper.createUnpredictable();
1833+
}
1834+
}
1835+
return nullptr;
1836+
}
1837+
18231838
/// EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g. for an if
18241839
/// statement) to the specified blocks. Based on the condition, this might try
18251840
/// to simplify the codegen of the conditional based on the branch.
@@ -2046,19 +2061,7 @@ void CodeGenFunction::EmitBranchOnBoolExpr(
20462061
}
20472062

20482063
llvm::MDNode *Weights = nullptr;
2049-
llvm::MDNode *Unpredictable = nullptr;
2050-
2051-
// If the branch has a condition wrapped by __builtin_unpredictable,
2052-
// create metadata that specifies that the branch is unpredictable.
2053-
// Don't bother if not optimizing because that metadata would not be used.
2054-
auto *Call = dyn_cast<CallExpr>(Cond->IgnoreImpCasts());
2055-
if (Call && CGM.getCodeGenOpts().OptimizationLevel != 0) {
2056-
auto *FD = dyn_cast_or_null<FunctionDecl>(Call->getCalleeDecl());
2057-
if (FD && FD->getBuiltinID() == Builtin::BI__builtin_unpredictable) {
2058-
llvm::MDBuilder MDHelper(getLLVMContext());
2059-
Unpredictable = MDHelper.createUnpredictable();
2060-
}
2061-
}
2064+
llvm::MDNode *Unpredictable = getUnpredictableMetadata(Cond);
20622065

20632066
// If there is a Likelihood knowledge for the cond, lower it.
20642067
// Note that if not optimizing this won't emit anything.

clang/lib/CodeGen/CodeGenFunction.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5044,6 +5044,11 @@ class CodeGenFunction : public CodeGenTypeCache {
50445044
Stmt::Likelihood LH = Stmt::LH_None,
50455045
const Expr *CntrIdx = nullptr);
50465046

5047+
// getUnpredictableMetadata - If the expression is a call to
5048+
// __builtin_unpredictable, get the corresponding metadata. Otherwise returns
5049+
// nullptr.
5050+
llvm::MDNode *getUnpredictableMetadata(const Expr *Cond);
5051+
50475052
/// EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g. for an
50485053
/// if statement) to the specified blocks. Based on the condition, this might
50495054
/// try to simplify the codegen of the conditional based on the branch.

clang/test/CodeGen/builtin-unpredictable.c

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -disable-llvm-passes -o - %s -O1 | FileCheck %s
2-
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -disable-llvm-passes -o - -x c++ %s -O1 | FileCheck %s
1+
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -disable-llvm-passes -o - %s -O1 | FileCheck %s
2+
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -disable-llvm-passes -o - -x c++ %s -O1 | FileCheck %s
33
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s -O0 | FileCheck %s --check-prefix=CHECK_O0
44

55
// When optimizing, the builtin should be converted to metadata.
@@ -18,7 +18,7 @@ void branch(int x) {
1818
// CHECK: !unpredictable [[METADATA:.+]]
1919

2020
// CHECK_O0-NOT: builtin_unpredictable
21-
// CHECK_O0-NOT: !unpredictable
21+
// CHECK_O0-NOT: !unpredictable
2222

2323
if (__builtin_unpredictable(x > 0))
2424
foo ();
@@ -31,7 +31,7 @@ int unpredictable_switch(int x) {
3131
// CHECK: !unpredictable [[METADATA:.+]]
3232

3333
// CHECK_O0-NOT: builtin_unpredictable
34-
// CHECK_O0-NOT: !unpredictable
34+
// CHECK_O0-NOT: !unpredictable
3535

3636
switch(__builtin_unpredictable(x)) {
3737
default:
@@ -47,6 +47,18 @@ int unpredictable_switch(int x) {
4747
return 0;
4848
}
4949

50+
int unpredictable_select(int x) {
51+
// CHECK-LABEL: @unpredictable_select(
52+
53+
// CHECK-NOT: builtin_unpredictable
54+
// CHECK: !unpredictable [[METADATA:.+]]
55+
56+
// CHECK_O0-NOT: builtin_unpredictable
57+
// CHECK_O0-NOT: !unpredictable
58+
59+
return __builtin_unpredictable(x) ? 1 : 33;
60+
}
61+
5062
#ifdef __cplusplus
5163
}
5264
#endif

0 commit comments

Comments
 (0)