]> granicus.if.org Git - clang/commitdiff
Teach __builtin_unpredictable to work through implicit casts.
authorErich Keane <erich.keane@intel.com>
Wed, 12 Dec 2018 20:30:53 +0000 (20:30 +0000)
committerErich Keane <erich.keane@intel.com>
Wed, 12 Dec 2018 20:30:53 +0000 (20:30 +0000)
The __builtin_unpredictable implementation is confused by any implicit
casts, which happen in C++.  This patch strips those off so that
if/switch statements now work with it in C++.

Change-Id: I73c3bf4f1775cd906703880944f4fcdc29fffb0a

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@348969 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CodeGenFunction.cpp
test/CodeGen/builtin-unpredictable.c

index 905e7501e01c18a054b748ebd86dbd36ce6ffa03..3f898b19e67e69d2c3ef8e793bd145a71eddd02b 100644 (file)
@@ -1701,7 +1701,7 @@ void CodeGenFunction::EmitBranchOnBoolExpr(const Expr *Cond,
   // create metadata that specifies that the branch is unpredictable.
   // Don't bother if not optimizing because that metadata would not be used.
   llvm::MDNode *Unpredictable = nullptr;
-  auto *Call = dyn_cast<CallExpr>(Cond);
+  auto *Call = dyn_cast<CallExpr>(Cond->IgnoreImpCasts());
   if (Call && CGM.getCodeGenOpts().OptimizationLevel != 0) {
     auto *FD = dyn_cast_or_null<FunctionDecl>(Call->getCalleeDecl());
     if (FD && FD->getBuiltinID() == Builtin::BI__builtin_unpredictable) {
index 30709b0cac68a7ae1ffe273bf65f1b59afb4b002..bdd62e972b058ce7e808dbafe59aa9e7f307cb49 100644 (file)
@@ -1,10 +1,15 @@
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -disable-llvm-passes -o - %s -O1 | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -disable-llvm-passes -o - %s -O1 | FileCheck %s 
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -disable-llvm-passes -o - -x c++ %s -O1 | FileCheck %s 
 // RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s -O0 | FileCheck %s --check-prefix=CHECK_O0
 
 // When optimizing, the builtin should be converted to metadata.
 // When not optimizing, there should be no metadata created for the builtin.
 // In both cases, the builtin should be removed from the code.
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 void foo();
 void branch(int x) {
 // CHECK-LABEL: define void @branch(
@@ -42,5 +47,10 @@ int unpredictable_switch(int x) {
   return 0;
 }
 
+#ifdef __cplusplus
+}
+#endif
+
+
 // CHECK: [[METADATA]] = !{}