Index: lib/Target/WebAssembly/WebAssemblyFastISel.cpp =================================================================== --- lib/Target/WebAssembly/WebAssemblyFastISel.cpp +++ lib/Target/WebAssembly/WebAssemblyFastISel.cpp @@ -700,9 +700,12 @@ if (Func && Func->isIntrinsic()) return false; + bool IsDirect = Func != nullptr; + if (!IsDirect && isa(Call->getCalledValue())) + return false; + FunctionType *FuncTy = Call->getFunctionType(); unsigned Opc; - bool IsDirect = Func != nullptr; bool IsVoid = FuncTy->getReturnType()->isVoidTy(); unsigned ResultReg; if (IsVoid) { Index: test/CodeGen/WebAssembly/call.ll =================================================================== --- test/CodeGen/WebAssembly/call.ll +++ test/CodeGen/WebAssembly/call.ll @@ -150,6 +150,22 @@ ret void } +; CHECK-LABEL: call_constexpr: +; CHECK-NEXT: i32.const $push[[L0:[0-9]+]]=, 2{{$}} +; CHECK-NEXT: i32.const $push[[L1:[0-9]+]]=, 3{{$}} +; CHECK-NEXT: call vararg_func@FUNCTION, $pop[[L0]], $pop[[L1]]{{$}} +; CHECK-NEXT: call other_void_nullary@FUNCTION{{$}} +; CHECK-NEXT: call void_nullary@FUNCTION{{$}} +; CHECK-NEXT: return{{$}} +declare void @vararg_func(...) +declare void @other_void_nullary() +define void @call_constexpr() { + call void bitcast (void (...)* @vararg_func to void (i32, i32)*)(i32 2, i32 3) + call void select (i1 0, void ()* @void_nullary, void ()* @other_void_nullary)() + call void inttoptr (i32 ptrtoint (void ()* @void_nullary to i32) to void ()*)() + ret void +} + ; TODO: test the following: ; - More argument combinations. ; - Tail call.