[llvm] r325788 - [FunctionAttrs][ArgumentPromotion][GlobalOpt] Disable some optimisations passes for naked functions

Luke Cheeseman via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 22 06:42:08 PST 2018


Author: lukecheeseman
Date: Thu Feb 22 06:42:08 2018
New Revision: 325788

URL: http://llvm.org/viewvc/llvm-project?rev=325788&view=rev
Log:
[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.


Added:
    llvm/trunk/test/Transforms/ArgumentPromotion/naked_functions.ll
    llvm/trunk/test/Transforms/FunctionAttrs/naked_functions.ll
    llvm/trunk/test/Transforms/GlobalOpt/naked_functions.ll
Modified:
    llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp
    llvm/trunk/lib/Transforms/IPO/FunctionAttrs.cpp
    llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp

Modified: llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp?rev=325788&r1=325787&r2=325788&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp Thu Feb 22 06:42:08 2018
@@ -817,6 +817,12 @@ promoteArguments(Function *F, function_r
                  unsigned MaxElements,
                  Optional<function_ref<void(CallSite OldCS, CallSite NewCS)>>
                      ReplaceCallSite) {
+  // Don't perform argument promotion for naked functions; otherwise we can end
+  // up removing parameters that are seemingly 'not used' as they are referred
+  // to in the assembly.
+  if(F->hasFnAttribute(Attribute::Naked))
+    return nullptr;
+
   // Make sure that it is local to this module.
   if (!F->hasLocalLinkage())
     return nullptr;

Modified: llvm/trunk/lib/Transforms/IPO/FunctionAttrs.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/FunctionAttrs.cpp?rev=325788&r1=325787&r2=325788&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/FunctionAttrs.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/FunctionAttrs.cpp Thu Feb 22 06:42:08 2018
@@ -1136,7 +1136,8 @@ PreservedAnalyses PostOrderFunctionAttrs
   bool HasUnknownCall = false;
   for (LazyCallGraph::Node &N : C) {
     Function &F = N.getFunction();
-    if (F.hasFnAttribute(Attribute::OptimizeNone)) {
+    if (F.hasFnAttribute(Attribute::OptimizeNone) ||
+        F.hasFnAttribute(Attribute::Naked)) {
       // Treat any function we're trying not to optimize as if it were an
       // indirect call and omit it from the node set used below.
       HasUnknownCall = true;
@@ -1221,7 +1222,8 @@ static bool runImpl(CallGraphSCC &SCC, A
   bool ExternalNode = false;
   for (CallGraphNode *I : SCC) {
     Function *F = I->getFunction();
-    if (!F || F->hasFnAttribute(Attribute::OptimizeNone)) {
+    if (!F || F->hasFnAttribute(Attribute::OptimizeNone) ||
+        F->hasFnAttribute(Attribute::Naked)) {
       // External node or function we're trying not to optimize - we both avoid
       // transform them and avoid leveraging information they provide.
       ExternalNode = true;

Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp?rev=325788&r1=325787&r2=325788&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Thu Feb 22 06:42:08 2018
@@ -2221,6 +2221,11 @@ OptimizeFunctions(Module &M, TargetLibra
   for (Module::iterator FI = M.begin(), E = M.end(); FI != E; ) {
     Function *F = &*FI++;
 
+    // Don't perform global opt pass on naked functions; we don't want fast
+    // calling conventions for naked functions.
+    if (F->hasFnAttribute(Attribute::Naked))
+      continue;
+
     // Functions without names cannot be referenced outside this module.
     if (!F->hasName() && !F->isDeclaration() && !F->hasLocalLinkage())
       F->setLinkage(GlobalValue::InternalLinkage);

Added: llvm/trunk/test/Transforms/ArgumentPromotion/naked_functions.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ArgumentPromotion/naked_functions.ll?rev=325788&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/ArgumentPromotion/naked_functions.ll (added)
+++ llvm/trunk/test/Transforms/ArgumentPromotion/naked_functions.ll Thu Feb 22 06:42:08 2018
@@ -0,0 +1,23 @@
+; RUN: opt < %s -argpromotion -S | FileCheck %s
+
+; Don't promote paramaters of/arguments to naked functions
+
+ at g = common global i32 0, align 4
+
+define i32 @bar() {
+entry:
+  %call = call i32 @foo(i32* @g)
+; CHECK: %call = call i32 @foo(i32* @g)
+  ret i32 %call
+}
+
+define internal i32 @foo(i32*) #0 {
+entry:
+  %retval = alloca i32, align 4
+  call void asm sideeffect "ldr r0, [r0] \0Abx lr        \0A", ""()
+  unreachable
+}
+
+; CHECK: define internal i32 @foo(i32*)
+
+attributes #0 = { naked }

Added: llvm/trunk/test/Transforms/FunctionAttrs/naked_functions.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/FunctionAttrs/naked_functions.ll?rev=325788&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/FunctionAttrs/naked_functions.ll (added)
+++ llvm/trunk/test/Transforms/FunctionAttrs/naked_functions.ll Thu Feb 22 06:42:08 2018
@@ -0,0 +1,25 @@
+; RUN: opt -S -functionattrs %s | FileCheck %s
+; RUN: opt -S -passes='function-attrs' %s | FileCheck %s
+
+; Don't change the attributes of parameters of naked functions, in particular
+; don't mark them as readnone
+
+ at g = common global i32 0, align 4
+
+define i32 @bar() {
+entry:
+  %call = call i32 @foo(i32* @g)
+; CHECK: %call = call i32 @foo(i32* @g)
+  ret i32 %call
+}
+
+define internal i32 @foo(i32*) #0 {
+entry:
+  %retval = alloca i32, align 4
+  call void asm sideeffect "ldr r0, [r0] \0Abx lr        \0A", ""()
+  unreachable
+}
+
+; CHECK: define internal i32 @foo(i32*)
+
+attributes #0 = { naked }

Added: llvm/trunk/test/Transforms/GlobalOpt/naked_functions.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalOpt/naked_functions.ll?rev=325788&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/GlobalOpt/naked_functions.ll (added)
+++ llvm/trunk/test/Transforms/GlobalOpt/naked_functions.ll Thu Feb 22 06:42:08 2018
@@ -0,0 +1,23 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+
+; Check that naked functions don't get marked with fast calling conventions
+
+ at g = common global i32 0, align 4
+
+define i32 @bar() {
+entry:
+  %call = call i32 @foo(i32* @g)
+; CHECK: %call = call i32 @foo(i32* @g)
+  ret i32 %call
+}
+
+define internal i32 @foo(i32*) #0 {
+entry:
+  %retval = alloca i32, align 4
+  call void asm sideeffect "ldr r0, [r0] \0Abx lr        \0A", ""()
+  unreachable
+}
+
+; CHECK: define internal i32 @foo(i32*)
+
+attributes #0 = { naked }




More information about the llvm-commits mailing list