[llvm] r326376 - [GlobalOpt] don't change CC of musttail calle(e|r)

Jonas Devlieghere via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 28 14:28:44 PST 2018


Author: jdevlieghere
Date: Wed Feb 28 14:28:44 2018
New Revision: 326376

URL: http://llvm.org/viewvc/llvm-project?rev=326376&view=rev
Log:
[GlobalOpt] don't change CC of musttail calle(e|r)

When the function has musttail call - its cc is fixed to be equal to the
cc of the musttail callee. In such case (and in the case of the musttail
callee), GlobalOpt should not change the cc to fastcc as it will break
the invariant.

This fixes PR36546

Patch by: Fedor Indutny (indutny)

Differential revision: https://reviews.llvm.org/D43859

Added:
    llvm/trunk/test/Transforms/GlobalOpt/musttail_cc.ll
Modified:
    llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp

Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp?rev=326376&r1=326375&r2=326376&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Wed Feb 28 14:28:44 2018
@@ -2115,8 +2115,31 @@ static void RemoveNestAttribute(Function
 /// GHC, or anyregcc.
 static bool hasChangeableCC(Function *F) {
   CallingConv::ID CC = F->getCallingConv();
+
   // FIXME: Is it worth transforming x86_stdcallcc and x86_fastcallcc?
-  return CC == CallingConv::C || CC == CallingConv::X86_ThisCall;
+  if (CC != CallingConv::C && CC != CallingConv::X86_ThisCall)
+    return false;
+
+  // FIXME: Change CC for the whole chain of musttail calls when possible.
+  //
+  // Can't change CC of the function that either has musttail calls, or is a
+  // musttail callee itself
+  for (User *U : F->users()) {
+    if (isa<BlockAddress>(U))
+      continue;
+    CallInst* CI = dyn_cast<CallInst>(U);
+    if (!CI)
+      continue;
+
+    if (CI->isMustTailCall())
+      return false;
+  }
+
+  for (BasicBlock &BB : *F)
+    if (BB.getTerminatingMustTailCall())
+      return false;
+
+  return true;
 }
 
 /// Return true if the block containing the call site has a BlockFrequency of

Added: llvm/trunk/test/Transforms/GlobalOpt/musttail_cc.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalOpt/musttail_cc.ll?rev=326376&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/GlobalOpt/musttail_cc.ll (added)
+++ llvm/trunk/test/Transforms/GlobalOpt/musttail_cc.ll Wed Feb 28 14:28:44 2018
@@ -0,0 +1,34 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+; PR36546
+
+; Check that musttail callee preserves its calling convention
+
+define i32 @test(i32 %a) {
+  ; CHECK: %ca = musttail call i32 @foo(i32 %a)
+  %ca = musttail call i32 @foo(i32 %a)
+  ret i32 %ca
+}
+
+; CHECK-LABEL: define internal i32 @foo(i32 %a)
+define internal i32 @foo(i32 %a) {
+  ret i32 %a
+}
+
+; Check that musttail caller preserves its calling convention
+
+define i32 @test2(i32 %a) {
+  %ca = call i32 @foo1(i32 %a)
+  ret i32 %ca
+}
+
+; CHECK-LABEL: define internal i32 @foo1(i32 %a)
+define internal i32 @foo1(i32 %a) {
+  ; CHECK: %ca = musttail call i32 @foo2(i32 %a)
+  %ca = musttail call i32 @foo2(i32 %a)
+  ret i32 %ca
+}
+
+; CHECK-LABEL: define internal i32 @foo2(i32 %a)
+define internal i32 @foo2(i32 %a) {
+  ret i32 %a
+}




More information about the llvm-commits mailing list