From: Dan Gohman <dan433584@gmail.com>
Date: Fri, 2 Oct 2015 20:54:23 +0000 (+0000)
Subject: [WebAssembly] Support calls marked as "tail", fastcc, and coldcc.
X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=a05446bfec76ed32a7b7c3b8eeb525939e137673;p=oota-llvm.git

[WebAssembly] Support calls marked as "tail", fastcc, and coldcc.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@249184 91177308-0d34-0410-b5e6-96231b3b80d8
---

diff --git a/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
index c9be0b3f2df..475d13ceefa 100644
--- a/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ b/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -229,13 +229,23 @@ WebAssemblyTargetLowering::LowerCall(CallLoweringInfo &CLI,
   MachineFunction &MF = DAG.getMachineFunction();
 
   CallingConv::ID CallConv = CLI.CallConv;
-  if (CallConv != CallingConv::C)
-    fail(DL, DAG, "WebAssembly doesn't support non-C calling conventions");
-  if (CLI.IsTailCall || MF.getTarget().Options.GuaranteedTailCallOpt)
-    fail(DL, DAG, "WebAssembly doesn't support tail call yet");
+  if (CallConv != CallingConv::C &&
+      CallConv != CallingConv::Fast &&
+      CallConv != CallingConv::Cold)
+    fail(DL, DAG,
+         "WebAssembly doesn't support language-specific or target-specific "
+         "calling conventions yet");
   if (CLI.IsPatchPoint)
     fail(DL, DAG, "WebAssembly doesn't support patch point yet");
 
+  // WebAssembly doesn't currently support explicit tail calls. If they are
+  // required, fail. Otherwise, just disable them.
+  if ((CallConv == CallingConv::Fast && CLI.IsTailCall &&
+       MF.getTarget().Options.GuaranteedTailCallOpt) ||
+      (CLI.CS && CLI.CS->isMustTailCall()))
+    fail(DL, DAG, "WebAssembly doesn't support tail call yet");
+  CLI.IsTailCall = false;
+
   SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
   SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
 
diff --git a/test/CodeGen/WebAssembly/call.ll b/test/CodeGen/WebAssembly/call.ll
index bf2ae7615ad..60195a9c3e4 100644
--- a/test/CodeGen/WebAssembly/call.ll
+++ b/test/CodeGen/WebAssembly/call.ll
@@ -98,8 +98,31 @@ define i32 @call_indirect_i32(i32 ()* %callee) {
   ret i32 %t
 }
 
+; CHECK-LABEL: (func $tail_call_void_nullary
+; CHECK-NEXT: (call $void_nullary)
+; CHECK-NEXT: (return)
+define void @tail_call_void_nullary() {
+  tail call void @void_nullary()
+  ret void
+}
+
+; CHECK-LABEL: (func $fastcc_tail_call_void_nullary
+; CHECK-NEXT: (call $void_nullary)
+; CHECK-NEXT: (return)
+define void @fastcc_tail_call_void_nullary() {
+  tail call fastcc void @void_nullary()
+  ret void
+}
+
+; CHECK-LABEL: (func $coldcc_tail_call_void_nullary
+; CHECK-NEXT: (call $void_nullary)
+; CHECK-NEXT: (return)
+define void @coldcc_tail_call_void_nullary() {
+  tail call coldcc void @void_nullary()
+  ret void
+}
+
 ; FIXME test the following:
-;  - Functions without return.
 ;  - More argument combinations.
 ;  - Tail call.
 ;  - Interesting returns (struct, multiple).