From: Benjamin Kramer Date: Sun, 3 Feb 2013 17:44:25 +0000 (+0000) Subject: CodeGen: Mark the runtime function __dynamic_cast as readonly & nounwind. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=21f6b39cca88f0a027c6f5cde24575165c2d5e40;p=clang CodeGen: Mark the runtime function __dynamic_cast as readonly & nounwind. This allows the optimizer to CSE dynamic_casts. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@174289 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp index 8b7f2342c4..853e25ec8c 100644 --- a/lib/CodeGen/CGExprCXX.cpp +++ b/lib/CodeGen/CGExprCXX.cpp @@ -1689,11 +1689,16 @@ static llvm::Constant *getDynamicCastFn(CodeGenFunction &CGF) { CGF.ConvertType(CGF.getContext().getPointerDiffType()); llvm::Type *Args[4] = { Int8PtrTy, Int8PtrTy, Int8PtrTy, PtrDiffTy }; - - llvm::FunctionType *FTy = - llvm::FunctionType::get(Int8PtrTy, Args, false); - - return CGF.CGM.CreateRuntimeFunction(FTy, "__dynamic_cast"); + + llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, Args, false); + + // Mark the function as nounwind readonly. + llvm::Attribute::AttrKind FuncAttrs[] = { llvm::Attribute::NoUnwind, + llvm::Attribute::ReadOnly }; + llvm::AttributeSet Attrs = llvm::AttributeSet::get( + CGF.getLLVMContext(), llvm::AttributeSet::FunctionIndex, FuncAttrs); + + return CGF.CGM.CreateRuntimeFunction(FTy, "__dynamic_cast", Attrs); } static llvm::Constant *getBadCastFn(CodeGenFunction &CGF) { diff --git a/test/CodeGenCXX/dynamic-cast.cpp b/test/CodeGenCXX/dynamic-cast.cpp index 813e36e941..77cfce1d46 100644 --- a/test/CodeGenCXX/dynamic-cast.cpp +++ b/test/CodeGenCXX/dynamic-cast.cpp @@ -16,3 +16,5 @@ const B& f(A *a) { } return fail; } + +// CHECK: declare i8* @__dynamic_cast(i8*, i8*, i8*, i64) nounwind readonly