forked from OSchip/llvm-project
Revert "Simplify handling of builtin with inline redefinition"
This reverts commit 3d6f49a569
.
Broke bot: https://lab.llvm.org/buildbot/#/builders/5/builds/12360
This commit is contained in:
parent
fd582eeffe
commit
0d76d4833d
|
@ -1294,11 +1294,6 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn,
|
|||
FunctionArgList Args;
|
||||
QualType ResTy = BuildFunctionArgList(GD, Args);
|
||||
|
||||
// Give a different name to inline builtin to avoid conflict with actual
|
||||
// builtins.
|
||||
if (FD->isInlineBuiltinDeclaration() && Fn)
|
||||
Fn->setName(Fn->getName() + ".inline");
|
||||
|
||||
// Check if we should generate debug info for this function.
|
||||
if (FD->hasAttr<NoDebugAttr>()) {
|
||||
// Clear non-distinct debug info that was possibly attached to the function
|
||||
|
|
|
@ -3169,11 +3169,6 @@ bool CodeGenModule::shouldEmitFunction(GlobalDecl GD) {
|
|||
}
|
||||
}
|
||||
|
||||
// Inline builtins declaration must be emitted. They often are fortified
|
||||
// functions.
|
||||
if (F->isInlineBuiltinDeclaration())
|
||||
return true;
|
||||
|
||||
// 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 through asm label/`__builtin_` trickery is
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
|
||||
|
||||
// RUN: %clang_cc1 -triple x86_64 -S -emit-llvm -o - %s | FileCheck %s
|
||||
//
|
||||
// Verifies that clang detects memcpy inline version and uses it instead of the builtin.
|
||||
|
||||
typedef unsigned long size_t;
|
||||
|
||||
// Clang requires these attributes for a function to be redefined.
|
||||
#define AVAILABLE_EXTERNALLY extern inline __attribute__((always_inline)) __attribute__((gnu_inline))
|
||||
|
||||
// Clang recognizes an inline builtin and renames it to prevent conflict with builtins.
|
||||
AVAILABLE_EXTERNALLY void *memcpy(void *a, const void *b, size_t c) {
|
||||
asm("# memcpy.inline marker");
|
||||
return __builtin_memcpy(a, b, c);
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @foo(
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: [[A_ADDR_I:%.*]] = alloca i8*, align 8
|
||||
// CHECK-NEXT: [[B_ADDR_I:%.*]] = alloca i8*, align 8
|
||||
// CHECK-NEXT: [[C_ADDR_I:%.*]] = alloca i64, align 8
|
||||
// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i8*, align 8
|
||||
// CHECK-NEXT: [[B_ADDR:%.*]] = alloca i8*, align 8
|
||||
// CHECK-NEXT: [[C_ADDR:%.*]] = alloca i64, align 8
|
||||
// CHECK-NEXT: store i8* [[A:%.*]], i8** [[A_ADDR]], align 8
|
||||
// CHECK-NEXT: store i8* [[B:%.*]], i8** [[B_ADDR]], align 8
|
||||
// CHECK-NEXT: store i64 [[C:%.*]], i64* [[C_ADDR]], align 8
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = load i8*, i8** [[A_ADDR]], align 8
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = load i8*, i8** [[B_ADDR]], align 8
|
||||
// CHECK-NEXT: [[TMP2:%.*]] = load i64, i64* [[C_ADDR]], align 8
|
||||
// CHECK-NEXT: store i8* [[TMP0]], i8** [[A_ADDR_I]], align 8
|
||||
// CHECK-NEXT: store i8* [[TMP1]], i8** [[B_ADDR_I]], align 8
|
||||
// CHECK-NEXT: store i64 [[TMP2]], i64* [[C_ADDR_I]], align 8
|
||||
// CHECK-NEXT: call void asm sideeffect "# memcpy.inline marker", "~{dirflag},~{fpsr},~{flags}"() #[[ATTR2:[0-9]+]], !srcloc !2
|
||||
// CHECK-NEXT: [[TMP3:%.*]] = load i8*, i8** [[A_ADDR_I]], align 8
|
||||
// CHECK-NEXT: [[TMP4:%.*]] = load i8*, i8** [[B_ADDR_I]], align 8
|
||||
// CHECK-NEXT: [[TMP5:%.*]] = load i64, i64* [[C_ADDR_I]], align 8
|
||||
// CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 [[TMP3]], i8* align 1 [[TMP4]], i64 [[TMP5]], i1 false) #[[ATTR2]]
|
||||
// CHECK-NEXT: ret void
|
||||
//
|
||||
void foo(void *a, const void *b, size_t c) {
|
||||
memcpy(a, b, 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
|
|
@ -4,8 +4,7 @@
|
|||
//
|
||||
// CHECK-WITH-DECL-NOT: @llvm.memcpy
|
||||
// CHECK-NO-DECL: @llvm.memcpy
|
||||
// CHECK-SELF-REF-DECL-LABEL: define dso_local i8* @memcpy.inline
|
||||
// CHECK-SELF-REF-DECL: @memcpy(
|
||||
// CHECK-SELF-REF-DECL: @llvm.memcpy
|
||||
//
|
||||
#include <memcpy-nobuiltin.inc>
|
||||
void test(void *dest, void const *from, size_t n) {
|
||||
|
|
|
@ -32,14 +32,14 @@ void f(void) {
|
|||
|
||||
// CHECK-LABEL: define{{.*}} void @f()
|
||||
// CHECK: call void @foo()
|
||||
// CHECK: call i32 @abs(i32 %0)
|
||||
// CHECK: call i32 @abs(i32 0)
|
||||
// CHECK: call i8* @strrchr(
|
||||
// CHECK: call void @llvm.prefetch.p0i8(
|
||||
// CHECK: call i8* @memchr(
|
||||
// CHECK: ret void
|
||||
|
||||
// CHECK: declare void @foo()
|
||||
// CHECK: declare i32 @abs(i32
|
||||
// CHECK: declare i8* @strrchr(i8*, i32)
|
||||
// CHECK: declare i8* @memchr(
|
||||
// CHECK: declare i32 @abs(i32
|
||||
// CHECK: declare void @llvm.prefetch.p0i8(
|
||||
|
|
Loading…
Reference in New Issue