llvm.org GIT mirror llvm / 037e821
[FunctionAttrs][ArgumentPromotion][GlobalOpt] Disable some optimisations passes for naked functions - Fix for bug 36078. - Prevent the functionattrs, function-attrs, globalopt and argpromotion passes from changing naked functions. - These passes can perform some alterations to the functions that should not be applied. An example is removing parameters that are seemingly not used because they are only referenced in the inline assembly. Another example is marking the function as fastcc. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@325788 91177308-0d34-0410-b5e6-96231b3b80d8 Luke Cheeseman 1 year, 6 months ago
6 changed file(s) with 86 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
816816 unsigned MaxElements,
817817 Optional>
818818 ReplaceCallSite) {
819 // Don't perform argument promotion for naked functions; otherwise we can end
820 // up removing parameters that are seemingly 'not used' as they are referred
821 // to in the assembly.
822 if(F->hasFnAttribute(Attribute::Naked))
823 return nullptr;
824
819825 // Make sure that it is local to this module.
820826 if (!F->hasLocalLinkage())
821827 return nullptr;
11351135 bool HasUnknownCall = false;
11361136 for (LazyCallGraph::Node &N : C) {
11371137 Function &F = N.getFunction();
1138 if (F.hasFnAttribute(Attribute::OptimizeNone)) {
1138 if (F.hasFnAttribute(Attribute::OptimizeNone) ||
1139 F.hasFnAttribute(Attribute::Naked)) {
11391140 // Treat any function we're trying not to optimize as if it were an
11401141 // indirect call and omit it from the node set used below.
11411142 HasUnknownCall = true;
12201221 bool ExternalNode = false;
12211222 for (CallGraphNode *I : SCC) {
12221223 Function *F = I->getFunction();
1223 if (!F || F->hasFnAttribute(Attribute::OptimizeNone)) {
1224 if (!F || F->hasFnAttribute(Attribute::OptimizeNone) ||
1225 F->hasFnAttribute(Attribute::Naked)) {
12241226 // External node or function we're trying not to optimize - we both avoid
12251227 // transform them and avoid leveraging information they provide.
12261228 ExternalNode = true;
22202220 for (Module::iterator FI = M.begin(), E = M.end(); FI != E; ) {
22212221 Function *F = &*FI++;
22222222
2223 // Don't perform global opt pass on naked functions; we don't want fast
2224 // calling conventions for naked functions.
2225 if (F->hasFnAttribute(Attribute::Naked))
2226 continue;
2227
22232228 // Functions without names cannot be referenced outside this module.
22242229 if (!F->hasName() && !F->isDeclaration() && !F->hasLocalLinkage())
22252230 F->setLinkage(GlobalValue::InternalLinkage);
0 ; RUN: opt < %s -argpromotion -S | FileCheck %s
1
2 ; Don't promote paramaters of/arguments to naked functions
3
4 @g = common global i32 0, align 4
5
6 define i32 @bar() {
7 entry:
8 %call = call i32 @foo(i32* @g)
9 ; CHECK: %call = call i32 @foo(i32* @g)
10 ret i32 %call
11 }
12
13 define internal i32 @foo(i32*) #0 {
14 entry:
15 %retval = alloca i32, align 4
16 call void asm sideeffect "ldr r0, [r0] \0Abx lr \0A", ""()
17 unreachable
18 }
19
20 ; CHECK: define internal i32 @foo(i32*)
21
22 attributes #0 = { naked }
0 ; RUN: opt -S -functionattrs %s | FileCheck %s
1 ; RUN: opt -S -passes='function-attrs' %s | FileCheck %s
2
3 ; Don't change the attributes of parameters of naked functions, in particular
4 ; don't mark them as readnone
5
6 @g = common global i32 0, align 4
7
8 define i32 @bar() {
9 entry:
10 %call = call i32 @foo(i32* @g)
11 ; CHECK: %call = call i32 @foo(i32* @g)
12 ret i32 %call
13 }
14
15 define internal i32 @foo(i32*) #0 {
16 entry:
17 %retval = alloca i32, align 4
18 call void asm sideeffect "ldr r0, [r0] \0Abx lr \0A", ""()
19 unreachable
20 }
21
22 ; CHECK: define internal i32 @foo(i32*)
23
24 attributes #0 = { naked }
0 ; RUN: opt < %s -globalopt -S | FileCheck %s
1
2 ; Check that naked functions don't get marked with fast calling conventions
3
4 @g = common global i32 0, align 4
5
6 define i32 @bar() {
7 entry:
8 %call = call i32 @foo(i32* @g)
9 ; CHECK: %call = call i32 @foo(i32* @g)
10 ret i32 %call
11 }
12
13 define internal i32 @foo(i32*) #0 {
14 entry:
15 %retval = alloca i32, align 4
16 call void asm sideeffect "ldr r0, [r0] \0Abx lr \0A", ""()
17 unreachable
18 }
19
20 ; CHECK: define internal i32 @foo(i32*)
21
22 attributes #0 = { naked }