[PATCH] D43859: [GlobalOpt] don't change CC of musttail calle(e|r) PR36546

Fedor Indutny via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 27 22:50:25 PST 2018


indutny created this revision.
indutny added reviewers: aprantl, JDevlieghere.

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.


Repository:
  rL LLVM

https://reviews.llvm.org/D43859

Files:
  lib/Transforms/IPO/GlobalOpt.cpp
  test/Transforms/GlobalOpt/musttail_cc.ll


Index: test/Transforms/GlobalOpt/musttail_cc.ll
===================================================================
--- /dev/null
+++ test/Transforms/GlobalOpt/musttail_cc.ll
@@ -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 i32 @foo2(i32 %a) {
+  ret i32 %a
+}
Index: lib/Transforms/IPO/GlobalOpt.cpp
===================================================================
--- lib/Transforms/IPO/GlobalOpt.cpp
+++ lib/Transforms/IPO/GlobalOpt.cpp
@@ -2115,6 +2115,24 @@
 /// GHC, or anyregcc.
 static bool hasChangeableCC(Function *F) {
   CallingConv::ID CC = F->getCallingConv();
+
+  // 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;
+
   // FIXME: Is it worth transforming x86_stdcallcc and x86_fastcallcc?
   return CC == CallingConv::C || CC == CallingConv::X86_ThisCall;
 }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D43859.136228.patch
Type: text/x-patch
Size: 1873 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180228/ffa7490f/attachment.bin>


More information about the llvm-commits mailing list