From: David Majnemer Date: Thu, 25 Jun 2015 23:50:40 +0000 (+0000) Subject: [CodeGen] Restrict isTriviallyRecursive to predefined lib functions forwarding to... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f478e62b2cb8037d50e38deedfec39973ae88d0b;p=clang [CodeGen] Restrict isTriviallyRecursive to predefined lib functions forwarding to lib functions isTriviallyRecursive is only supposed to guard functions part of the implementation. This fixes PR23953. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@240735 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index bd7b44e413..d19d0ed886 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -1425,7 +1425,7 @@ namespace { return false; } unsigned BuiltinID = FD->getBuiltinID(); - if (!BuiltinID) + if (!BuiltinID || !BI.isLibFunction(BuiltinID)) return true; StringRef BuiltinName = BI.GetName(BuiltinID); if (BuiltinName.startswith("__builtin_") && @@ -1454,7 +1454,12 @@ CodeGenModule::isTriviallyRecursive(const FunctionDecl *FD) { Name = FD->getName(); } - FunctionIsDirectlyRecursive Walker(Name, Context.BuiltinInfo); + auto &BI = Context.BuiltinInfo; + unsigned BuiltinID = Context.Idents.get(Name).getBuiltinID(); + if (!BuiltinID || !BI.isPredefinedLibFunction(BuiltinID)) + return false; + + FunctionIsDirectlyRecursive Walker(Name, BI); Walker.TraverseFunctionDecl(const_cast(FD)); return Walker.Result; } diff --git a/test/CodeGen/pr9614.c b/test/CodeGen/pr9614.c index 53abef1801..de21dbbb23 100644 --- a/test/CodeGen/pr9614.c +++ b/test/CodeGen/pr9614.c @@ -4,26 +4,35 @@ extern void foo_alias (void) __asm ("foo"); inline void foo (void) { return foo_alias (); } -extern void bar_alias (void) __asm ("bar"); -inline __attribute__ ((__always_inline__)) void bar (void) { - return bar_alias (); +extern int abs_alias (int) __asm ("abs"); +inline __attribute__ ((__always_inline__)) int abs (int x) { + return abs_alias(x); } extern char *strrchr_foo (const char *__s, int __c) __asm ("strrchr"); extern inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) char * strrchr_foo (const char *__s, int __c) { return __builtin_strrchr (__s, __c); } + +extern inline void __attribute__((always_inline, __gnu_inline__)) +prefetch(void) { + __builtin_prefetch(0, 0, 1); +} + void f(void) { foo(); - bar(); + abs(0); strrchr_foo("", '.'); + prefetch(); } // CHECK-LABEL: define void @f() // CHECK: call void @foo() -// CHECK-NEXT: call void @bar() -// CHECK-NEXT: call i8* @strrchr( -// CHECK-NEXT: ret void +// CHECK: call i32 @abs(i32 0) +// CHECK: call i8* @strrchr( +// CHECK: call void @llvm.prefetch( +// CHECK: ret void // CHECK: declare void @foo() -// CHECK: declare void @bar() +// CHECK: declare i32 @abs(i32 // CHECK: declare i8* @strrchr(i8*, i32) +// CHECK: declare void @llvm.prefetch(