From: Heejin Ahn Date: Tue, 9 Jul 2019 02:10:33 +0000 (+0000) Subject: [WebAssembly] Make sret parameter work with AddMissingPrototypes X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9fce1e40c7fcab2d761005d556678640db912457;p=llvm [WebAssembly] Make sret parameter work with AddMissingPrototypes Summary: Even with functions with `no-prototype` attribute, there can be an argument `sret` (structure return) attribute, which is an optimization when a function return type is a struct. Fixes PR42420. Reviewers: sbc100 Subscribers: dschuff, jgravelle-google, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D64318 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@365426 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/WebAssembly/WebAssemblyAddMissingPrototypes.cpp b/lib/Target/WebAssembly/WebAssemblyAddMissingPrototypes.cpp index 3e13369f33e..b7a701f1578 100644 --- a/lib/Target/WebAssembly/WebAssemblyAddMissingPrototypes.cpp +++ b/lib/Target/WebAssembly/WebAssemblyAddMissingPrototypes.cpp @@ -78,10 +78,13 @@ bool WebAssemblyAddMissingPrototypes::runOnModule(Module &M) { report_fatal_error( "Functions with 'no-prototype' attribute must take varargs: " + F.getName()); - if (F.getFunctionType()->getNumParams() != 0) - report_fatal_error( - "Functions with 'no-prototype' attribute should not have params: " + - F.getName()); + unsigned NumParams = F.getFunctionType()->getNumParams(); + if (NumParams != 0) { + if (!(NumParams == 1 && F.arg_begin()->hasStructRetAttr())) + report_fatal_error("Functions with 'no-prototype' attribute should " + "not have params: " + + F.getName()); + } // Create a function prototype based on the first call site (first bitcast) // that we find. diff --git a/test/CodeGen/WebAssembly/add-prototypes.ll b/test/CodeGen/WebAssembly/add-prototypes.ll index f42e4827d2f..84d7657e983 100644 --- a/test/CodeGen/WebAssembly/add-prototypes.ll +++ b/test/CodeGen/WebAssembly/add-prototypes.ll @@ -56,6 +56,17 @@ define void @as_paramater() { ret void } +; Check if a sret parameter works in a no-prototype function. +; CHECK-LABEL: @sret_param +; CHECK: call void @make_struct_foo(%struct.foo* sret %foo) +%struct.foo = type { i32, i32 } +declare void @make_struct_foo(%struct.foo* sret, ...) #1 +define void @sret_param() { + %foo = alloca %struct.foo, align 4 + call void bitcast (void (%struct.foo*, ...)* @make_struct_foo to void (%struct.foo*)*)(%struct.foo* sret %foo) + ret void +} + declare void @func_param(i64 (...)*) ; CHECK: declare void @func_not_called()