From: Dan Gohman Date: Fri, 2 Oct 2015 20:54:23 +0000 (+0000) Subject: [WebAssembly] Support calls marked as "tail", fastcc, and coldcc. X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=commitdiff_plain;h=a05446bfec76ed32a7b7c3b8eeb525939e137673 [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 &Outs = CLI.Outs; SmallVectorImpl &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).