diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 269917b4427b..8f29663613da 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -22,6 +22,7 @@ #include "clang/Basic/TargetBuiltins.h" #include "llvm/Intrinsics.h" #include "llvm/Target/TargetData.h" + using namespace clang; using namespace CodeGen; using namespace llvm; @@ -311,11 +312,16 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, return RValue::get(Result); } case Builtin::BI__builtin_expect: { - // FIXME: pass expect through to LLVM Value *ArgValue = EmitScalarExpr(E->getArg(0)); - if (E->getArg(1)->HasSideEffects(getContext())) - (void)EmitScalarExpr(E->getArg(1)); - return RValue::get(ArgValue); + const llvm::Type *ArgType = ArgValue->getType(); + + Value *FnExpect = CGM.getIntrinsic(Intrinsic::expect, &ArgType, 1); + Value *ExpectedValue = EmitScalarExpr(E->getArg(1)); + + Value *Result = Builder.CreateCall2(FnExpect, ArgValue, ExpectedValue, + "expval"); + return RValue::get(Result); + } case Builtin::BI__builtin_bswap32: case Builtin::BI__builtin_bswap64: { diff --git a/clang/test/CodeGen/builtin-expect.c b/clang/test/CodeGen/builtin-expect.c index 88479d90a092..664c6b6a470e 100644 --- a/clang/test/CodeGen/builtin-expect.c +++ b/clang/test/CodeGen/builtin-expect.c @@ -19,3 +19,29 @@ int main() { // CHECK: call void @isigprocmask() // CHECK: [[C:%.*]] = call i64 (...)* @bar() + + +// CHECK: @test1 +int test1(int x) { +// CHECK: @llvm.expect + if (__builtin_expect (x, 1)) + return 0; + return x; +} + +// CHECK: @test2 +int test2(int x) { +// CHECK: @llvm.expect + switch(__builtin_expect(x, 5)) { + default: + return 0; + case 0: + case 1: + case 2: + return 1; + case 5: + return 5; + }; + + return 0; +}