From 0d4e33d2114e074fa3d84b85bf33df706bb3e5f6 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 20 Jan 2017 20:50:29 +0000 Subject: [PATCH] [WebAssembly] Don't create bitcast-wrappers for varargs. WebAssembly varargs functions use a significantly different ABI than non-varargs functions, and the current code in WebAssemblyFixFunctionBitcasts doesn't handle that difference. For now, just avoid creating wrapper functions in the presence of varargs. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@292645 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../WebAssemblyFixFunctionBitcasts.cpp | 5 +++++ test/CodeGen/WebAssembly/function-bitcasts.ll | 17 +++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/lib/Target/WebAssembly/WebAssemblyFixFunctionBitcasts.cpp b/lib/Target/WebAssembly/WebAssemblyFixFunctionBitcasts.cpp index adf904ee026..cdbd9ea4b09 100644 --- a/lib/Target/WebAssembly/WebAssemblyFixFunctionBitcasts.cpp +++ b/lib/Target/WebAssembly/WebAssemblyFixFunctionBitcasts.cpp @@ -148,6 +148,11 @@ bool FixFunctionBitcasts::runOnModule(Module &M) { if (!Ty) continue; + // Wasm varargs are not ABI-compatible with non-varargs. Just ignore + // such casts for now. + if (Ty->isVarArg() || F->isVarArg()) + continue; + auto Pair = Wrappers.insert(std::make_pair(std::make_pair(F, Ty), nullptr)); if (Pair.second) Pair.first->second = CreateWrapper(F, Ty); diff --git a/test/CodeGen/WebAssembly/function-bitcasts.ll b/test/CodeGen/WebAssembly/function-bitcasts.ll index e4f8f3fb6ca..9cafdd5bc2c 100644 --- a/test/CodeGen/WebAssembly/function-bitcasts.ll +++ b/test/CodeGen/WebAssembly/function-bitcasts.ll @@ -22,6 +22,15 @@ target triple = "wasm32-unknown-unknown" ; CHECK-NEXT: call foo3@FUNCTION{{$}} ; CHECK-NEXT: .endfunc +; CHECK-LABEL: test_varargs: +; CHECK-NEXT: .local i32 +; CHECK: store +; CHECK: i32.const $push[[L3:[0-9]+]]=, 0{{$}} +; CHECK-NEXT: call vararg@FUNCTION, $pop[[L3]]{{$}} +; CHECK-NEXT: i32.const $push[[L4:[0-9]+]]=, 0{{$}} +; CHECK-NEXT: i32.store 0($[[L5:[0-9]+]]), $pop[[L4]]{{$}} +; CHECK-NEXT: call plain@FUNCTION, $[[L5]]{{$}} + ; CHECK-LABEL: .Lbitcast: ; CHECK-NEXT: .local i32 ; CHECK-NEXT: call has_i32_arg@FUNCTION, $0{{$}} @@ -45,6 +54,8 @@ target triple = "wasm32-unknown-unknown" declare void @has_i32_arg(i32) declare i32 @has_i32_ret() +declare void @vararg(...) +declare void @plain(i32) declare void @foo0() declare void @foo1() @@ -70,3 +81,9 @@ entry: ret void } + +define void @test_varargs() { + call void bitcast (void (...)* @vararg to void (i32)*)(i32 0) + call void (...) bitcast (void (i32)* @plain to void (...)*)(i32 0) + ret void +} -- 2.40.0