| From 2dd17ff08165e6118e70f00e22b2c36d2d4e0a9a Mon Sep 17 00:00:00 2001 |
| From: George Burgess IV <george.burgess.iv@gmail.com> |
| Date: Wed, 15 Apr 2020 11:05:22 -0700 |
| Subject: [PATCH] [CodeGen] only add nobuiltin to inline builtins if we'll emit |
| them |
| |
| There are some inline builtin definitions that we can't emit |
| (isTriviallyRecursive & callers go into why). Marking these |
| nobuiltin is only useful if we actually emit the body, so don't mark |
| these as such unless we _do_ plan on emitting that. |
| |
| This suboptimality was encountered in Linux (see some discussion on |
| D71082, and https://github.com/ClangBuiltLinux/linux/issues/979). |
| |
| Differential Revision: https://reviews.llvm.org/D78162 |
| --- |
| clang/lib/CodeGen/CodeGenModule.cpp | 3 ++- |
| .../memcpy-no-nobuiltin-if-not-emitted.c | 25 +++++++++++++++++++ |
| 2 files changed, 27 insertions(+), 1 deletion(-) |
| create mode 100644 clang/test/CodeGen/memcpy-no-nobuiltin-if-not-emitted.c |
| |
| diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp |
| index 39aa5c1c512..73a3212bcd4 100644 |
| --- a/clang/lib/CodeGen/CodeGenModule.cpp |
| +++ b/clang/lib/CodeGen/CodeGenModule.cpp |
| @@ -1908,7 +1908,8 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD, llvm::Function *F, |
| else if (const auto *SA = FD->getAttr<SectionAttr>()) |
| F->setSection(SA->getName()); |
| |
| - if (FD->isInlineBuiltinDeclaration()) { |
| + // If we plan on emitting this inline builtin, we can't treat it as a builtin. |
| + if (FD->isInlineBuiltinDeclaration() && shouldEmitFunction(FD)) { |
| F->addAttribute(llvm::AttributeList::FunctionIndex, |
| llvm::Attribute::NoBuiltin); |
| } |
| diff --git a/clang/test/CodeGen/memcpy-no-nobuiltin-if-not-emitted.c b/clang/test/CodeGen/memcpy-no-nobuiltin-if-not-emitted.c |
| new file mode 100644 |
| index 00000000000..b4c1376c5bb |
| --- /dev/null |
| +++ b/clang/test/CodeGen/memcpy-no-nobuiltin-if-not-emitted.c |
| @@ -0,0 +1,25 @@ |
| +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -S -emit-llvm -o - %s | FileCheck %s |
| +// |
| +// Verifies that clang doesn't mark an inline builtin definition as `nobuiltin` |
| +// if the builtin isn't emittable. |
| + |
| +typedef unsigned long size_t; |
| + |
| +// always_inline is used so clang will emit this body. Otherwise, we need >= |
| +// -O1. |
| +#define AVAILABLE_EXTERNALLY extern inline __attribute__((always_inline)) \ |
| + __attribute__((gnu_inline)) |
| + |
| +AVAILABLE_EXTERNALLY void *memcpy(void *a, const void *b, size_t c) { |
| + return __builtin_memcpy(a, b, c); |
| +} |
| + |
| +// CHECK-LABEL: define void @foo |
| +void foo(void *a, const void *b, size_t c) { |
| + // Clang will always _emit_ this as memcpy. LLVM turns it into @llvm.memcpy |
| + // later on if optimizations are enabled. |
| + // CHECK: call i8* @memcpy |
| + memcpy(a, b, c); |
| +} |
| + |
| +// CHECK-NOT: nobuiltin |
| -- |
| 2.26.0.110.g2183baf09c-goog |
| |