From cc4889f72ec68319969ba51e214d9940eb9327e5 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Fri, 28 Oct 2011 20:43:56 +0000 Subject: [PATCH] Fix PR9614 for functions with the always_inline attribute. Try to keep the common case (-O0, no always_inline) fast. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@143222 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CodeGenModule.cpp | 9 +++------ test/CodeGen/pr9614.c | 26 +++++++++++++++++--------- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 86378a9afa..c796e0daa9 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -901,18 +901,15 @@ bool CodeGenModule::shouldEmitFunction(const FunctionDecl *F) { if (getFunctionLinkage(F) != llvm::Function::AvailableExternallyLinkage) return true; - if (F->hasAttr()) - return true; - if (CodeGenOpts.OptimizationLevel == 0) + if (CodeGenOpts.OptimizationLevel == 0 && + !F->hasAttr()) return false; // PR9614. Avoid cases where the source code is lying to us. An available // externally function should have an equivalent function somewhere else, // but a function that calls itself is clearly not equivalent to the real // implementation. // This happens in glibc's btowc and in some configure checks. - if (isTriviallyRecursiveViaAsm(F)) - return false; - return true; + return !isTriviallyRecursiveViaAsm(F); } void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD) { diff --git a/test/CodeGen/pr9614.c b/test/CodeGen/pr9614.c index 68a59095ab..e761bec3f9 100644 --- a/test/CodeGen/pr9614.c +++ b/test/CodeGen/pr9614.c @@ -1,15 +1,23 @@ // RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s -extern int foo_alias (void) __asm ("foo"); -inline int foo (void) { +extern void foo_alias (void) __asm ("foo"); +inline void foo (void) { return foo_alias (); } -int f(void) { - return foo(); +extern void bar_alias (void) __asm ("bar"); +inline __attribute__ ((__always_inline__)) void bar (void) { + return bar_alias (); } +void f(void) { + foo(); + bar(); +} + +// CHECK: define void @f() +// CHECK-NEXT: entry: +// CHECK-NEXT: call void @foo() +// CHECK-NEXT: call void @bar() +// CHECK-NEXT: ret void -// CHECK-NOT: define -// CHECK: define i32 @f() -// CHECK: call i32 @foo() -// CHECK-NEXT: ret i32 -// CHECK-NOT: define +// CHECK: declare void @foo() +// CHECK: declare void @bar() -- 2.40.0