[WebAssembly] Implement calls with void return types.
authorDan Gohman <dan433584@gmail.com>
Wed, 9 Sep 2015 16:13:47 +0000 (16:13 +0000)
committerDan Gohman <dan433584@gmail.com>
Wed, 9 Sep 2015 16:13:47 +0000 (16:13 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@247158 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/WebAssembly/WebAssemblyISD.def
lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
lib/Target/WebAssembly/WebAssemblyInstrCall.td
lib/Target/WebAssembly/WebAssemblyInstrInfo.td
test/CodeGen/WebAssembly/call.ll

index 0bc9b2f55b10347866c442bb97bd151284ad15dd..24e613e7711ca66144a67d966c31bcadf1c4a274 100644 (file)
@@ -14,7 +14,8 @@
 
 // NOTE: NO INCLUDE GUARD DESIRED!
 
-HANDLE_NODETYPE(CALL)
+HANDLE_NODETYPE(CALL1)
+HANDLE_NODETYPE(CALL0)
 HANDLE_NODETYPE(RETURN)
 HANDLE_NODETYPE(ARGUMENT)
 HANDLE_NODETYPE(Wrapper)
index 7e9e1b0e016b256767470a4411f5fad741936fd9..12dce113c3ecbbf15b76f1811ef971720d44d8b9 100644 (file)
@@ -261,7 +261,9 @@ WebAssemblyTargetLowering::LowerCall(CallLoweringInfo &CLI,
     Tys.push_back(In.VT);
   Tys.push_back(MVT::Other);
   SDVTList TyList = DAG.getVTList(Tys);
-  SDValue Res = DAG.getNode(WebAssemblyISD::CALL, DL, TyList, Ops);
+  SDValue Res =
+      DAG.getNode(Ins.empty() ? WebAssemblyISD::CALL0 : WebAssemblyISD::CALL1,
+                  DL, TyList, Ops);
   if (Ins.empty()) {
     Chain = Res;
   } else {
index abb7f21512a7915d47e537404132c6d2f72fcbf4..d3430f225eef2b00e51338ff62958e149367bcd2 100644 (file)
@@ -23,14 +23,16 @@ def : I<(outs), (ins i64imm:$amt1, i64imm:$amt2),
 
 multiclass CALL<WebAssemblyRegClass vt> {
   def CALL_#vt : I<(outs vt:$dst), (ins Int32:$callee, variable_ops),
-                   [(set vt:$dst, (WebAssemblycall Int32:$callee))]>;
+                   [(set vt:$dst, (WebAssemblycall1 Int32:$callee))]>;
 }
 let Uses = [SP32, SP64], isCall = 1 in {
   defm : CALL<Int32>;
   defm : CALL<Int64>;
   defm : CALL<Float32>;
   defm : CALL<Float64>;
-  // FIXME: void.
+
+  def CALL_VOID : I<(outs), (ins Int32:$callee, variable_ops),
+                    [(WebAssemblycall0 Int32:$callee)]>;
 } // Uses = [SP32,SP64], isCall = 1
 
 /*
index d73e66ea985d1c5d3e86cbc83836b8e796a7d0d0..409c8525f93706f5f4619ba690aafe83a6bd071b 100644 (file)
@@ -28,7 +28,8 @@ def HasSIMD128 : Predicate<"Subtarget->hasSIMD128()">,
 def SDT_WebAssemblyCallSeqStart : SDCallSeqStart<[SDTCisVT<0, iPTR>]>;
 def SDT_WebAssemblyCallSeqEnd :
     SDCallSeqEnd<[SDTCisVT<0, iPTR>, SDTCisVT<1, iPTR>]>;
-def SDT_WebAssemblyCall     : SDTypeProfile<1, -1, [SDTCisPtrTy<1>]>;
+def SDT_WebAssemblyCall0    : SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>;
+def SDT_WebAssemblyCall1    : SDTypeProfile<1, -1, [SDTCisPtrTy<1>]>;
 def SDT_WebAssemblyArgument : SDTypeProfile<1, 1, [SDTCisVT<1, i32>]>;
 def SDT_WebAssemblyReturn   : SDTypeProfile<0, -1, []>;
 def SDT_WebAssemblyWrapper  : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>,
@@ -44,9 +45,12 @@ def WebAssemblycallseq_start :
 def WebAssemblycallseq_end :
     SDNode<"ISD::CALLSEQ_END", SDT_WebAssemblyCallSeqEnd,
            [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
-def WebAssemblycall      : SDNode<"WebAssemblyISD::CALL",
-                                  SDT_WebAssemblyCall,
-                                  [SDNPHasChain, SDNPVariadic]>;
+def WebAssemblycall0 : SDNode<"WebAssemblyISD::CALL0",
+                              SDT_WebAssemblyCall0,
+                              [SDNPHasChain, SDNPVariadic]>;
+def WebAssemblycall1 : SDNode<"WebAssemblyISD::CALL1",
+                              SDT_WebAssemblyCall1,
+                              [SDNPHasChain, SDNPVariadic]>;
 def WebAssemblyargument : SDNode<"WebAssemblyISD::ARGUMENT",
                                  SDT_WebAssemblyArgument>;
 def WebAssemblyreturn   : SDNode<"WebAssemblyISD::RETURN",
index d628ec09630b563c5756ea0233542f89144cf11c..14a41b0feb597cb748fdbcaf47a8e411e164fb0f 100644 (file)
@@ -11,6 +11,7 @@ declare i32 @i32_binary(i32, i32)
 declare i64 @i64_nullary()
 declare float @float_nullary()
 declare double @double_nullary()
+declare void @void_nullary()
 
 ; CHECK-LABEL: (func $call_i32_nullary
 ; CHECK-NEXT: (result i32)
@@ -52,6 +53,15 @@ define double @call_double_nullary() {
   ret double %r
 }
 
+; CHECK-LABEL: (func $call_void_nullary
+; CHECK-NEXT: (setlocal @0 (global $void_nullary))
+; CHECK-NEXT: (call @0)
+; CHECK-NEXT: (return)
+define void @call_void_nullary() {
+  call void @void_nullary()
+  ret void
+}
+
 ; CHECK-LABEL: (func $call_i32_unary
 ; CHECK-NEXT: (param i32) (result i32)
 ; CHECK-NEXT: (setlocal @0 (argument 0))