From 88599bf6f460ec1585aadf13dfc0d0ed50d86392 Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Thu, 30 Aug 2018 01:01:30 +0000 Subject: [WebAssembly] Be a little more conservative in WebAssemblyFixFunctionBitcasts We don't have enough information to know if struct types being bitcast will cause validation failures or not, so be conservative and allow such cases to persist (fot now). Fixes: https://bugs.llvm.org/show_bug.cgi?id=38711 Subscribers: dschuff, jgravelle-google, aheejin, sunfish, llvm-commits Differential Revision: https://reviews.llvm.org/D51460 llvm-svn: 341010 --- llvm/test/CodeGen/WebAssembly/function-bitcasts.ll | 43 ++++++++++++++++++++-- .../WebAssembly/unsupported-function-bitcasts.ll | 40 ++++++++++++++------ 2 files changed, 68 insertions(+), 15 deletions(-) (limited to 'llvm/test/CodeGen/WebAssembly') diff --git a/llvm/test/CodeGen/WebAssembly/function-bitcasts.ll b/llvm/test/CodeGen/WebAssembly/function-bitcasts.ll index 233a2b4468f..0e7fcd5d570 100644 --- a/llvm/test/CodeGen/WebAssembly/function-bitcasts.ll +++ b/llvm/test/CodeGen/WebAssembly/function-bitcasts.ll @@ -6,6 +6,7 @@ target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" target triple = "wasm32-unknown-unknown" declare void @has_i32_arg(i32) +declare void @has_struct_arg({i32}) declare i32 @has_i32_ret() declare void @vararg(...) declare void @plain(i32) @@ -16,9 +17,10 @@ declare void @foo2() declare void @foo3() ; CHECK-LABEL: test: -; CHECK-NEXT: call .Lhas_i32_arg_bitcast@FUNCTION{{$}} -; CHECK-NEXT: call .Lhas_i32_arg_bitcast@FUNCTION{{$}} +; CHECK-NEXT: call .Lhas_i32_arg_bitcast.2@FUNCTION{{$}} +; CHECK-NEXT: call .Lhas_i32_arg_bitcast.2@FUNCTION{{$}} ; CHECK-NEXT: call .Lhas_i32_ret_bitcast@FUNCTION{{$}} +; CHECK-NEXT: i32.call $drop=, has_i32_ret@FUNCTION ; CHECK-NEXT: i32.const $push[[L0:[0-9]+]]=, 0 ; CHECK-NEXT: call .Lfoo0_bitcast@FUNCTION, $pop[[L0]]{{$}} ; CHECK-NEXT: i32.const $push[[L1:[0-9]+]]=, 0 @@ -36,6 +38,7 @@ entry: call void bitcast (void (i32)* @has_i32_arg to void ()*)() call void bitcast (void (i32)* @has_i32_arg to void ()*)() call void bitcast (i32 ()* @has_i32_ret to void ()*)() + call i32 bitcast (i32 ()* @has_i32_ret to i32 ()*)() call void bitcast (void ()* @foo0 to void (i32)*)(i32 0) %p = bitcast void ()* @foo0 to void (i32)* call void %p(i32 0) @@ -51,6 +54,30 @@ entry: ret void } +; CHECK-LABEL: test_structs: +; CHECK: call .Lhas_i32_arg_bitcast.1@FUNCTION, $pop{{[0-9]+}}, $pop{{[0-9]+$}} +; CHECK: call .Lhas_i32_arg_bitcast@FUNCTION, $0, $pop2 +; CHECK: call .Lhas_struct_arg_bitcast@FUNCTION{{$}} +define void @test_structs() { +entry: + call void bitcast (void (i32)* @has_i32_arg to void (i32, {i32})*)(i32 5, {i32} {i32 6}) + call {i32, i64} bitcast (void (i32)* @has_i32_arg to {i32, i64} (i32)*)(i32 7) + call void bitcast (void ({i32})* @has_struct_arg to void ()*)() + ret void +} + +; CHECK-LABEL: test_structs_unhandled: +; CHECK: call has_struct_arg@FUNCTION, $pop{{[0-9]+$}} +; CHECK: call has_struct_arg@FUNCTION, $pop{{[0-9]+$}} +; CHECK: call has_i32_ret@FUNCTION, $pop{{[0-9]+$}} +define void @test_structs_unhandled() { +entry: + call void @has_struct_arg({i32} {i32 3}) + call void bitcast (void ({i32})* @has_struct_arg to void ({i64})*)({i64} {i64 4}) + call {i32, i32} bitcast (i32 ()* @has_i32_ret to {i32, i32} ()*)() + ret void +} + ; CHECK-LABEL: test_varargs: ; CHECK: set_global ; CHECK: i32.const $push[[L3:[0-9]+]]=, 0{{$}} @@ -113,7 +140,7 @@ define void @test_argument() { ; CHECK: i32.const $push[[L3:[0-9]+]]=, call_func@FUNCTION{{$}} ; CHECK-NEXT: i32.const $push[[L2:[0-9]+]]=, has_i32_arg@FUNCTION{{$}} ; CHECK-NEXT: call "__invoke_void_i32()*"@FUNCTION, $pop[[L3]], $pop[[L2]]{{$}} -; CHECK: i32.const $push[[L4:[0-9]+]]=, .Lhas_i32_arg_bitcast@FUNCTION{{$}} +; CHECK: i32.const $push[[L4:[0-9]+]]=, .Lhas_i32_arg_bitcast.2@FUNCTION{{$}} ; CHECK-NEXT: call __invoke_void@FUNCTION, $pop[[L4]]{{$}} declare i32 @personality(...) define void @test_invoke() personality i32 (...)* @personality { @@ -139,6 +166,16 @@ end: } ; CHECK-LABEL: .Lhas_i32_arg_bitcast: +; CHECK-NEXT: .param i32, i32 +; CHECK-NEXT: call has_i32_arg@FUNCTION, $1{{$}} +; CHECK-NEXT: end_function + +; CHECK-LABEL: .Lhas_i32_arg_bitcast.1: +; CHECK-NEXT: .param i32, i32 +; CHECK-NEXT: call has_i32_arg@FUNCTION, $0{{$}} +; CHECK-NEXT: end_function + +; CHECK-LABEL: .Lhas_i32_arg_bitcast.2: ; CHECK-NEXT: call has_i32_arg@FUNCTION, $0{{$}} ; CHECK-NEXT: end_function diff --git a/llvm/test/CodeGen/WebAssembly/unsupported-function-bitcasts.ll b/llvm/test/CodeGen/WebAssembly/unsupported-function-bitcasts.ll index 6bc478c596d..b8642b97501 100644 --- a/llvm/test/CodeGen/WebAssembly/unsupported-function-bitcasts.ll +++ b/llvm/test/CodeGen/WebAssembly/unsupported-function-bitcasts.ll @@ -9,28 +9,31 @@ target triple = "wasm32-unknown-unknown" declare i32 @has_i64_arg(i64) declare i32 @has_ptr_arg(i8*) +; CHECK-LABEL: test_invalid_rtn: +; CHECK-NEXT: i32.const $push[[L0:[0-9]+]]=, 0{{$}} +; CHECK-NEXT: i32.call $push[[L1:[0-9]+]]=, .Lhas_i64_arg_bitcast_invalid.2@FUNCTION, $pop[[L0]]{{$}} +; CHECK-NEXT: drop $pop[[L1]]{{$}} +; CHECK-NEXT: i64.const $push[[L0:[0-9]+]]=, 0{{$}} +; CHECK-NEXT: i64.call $push[[L1:[0-9]+]]=, .Lhas_i64_arg_bitcast_invalid@FUNCTION, $pop[[L0]]{{$}} +; CHECK-NEXT: drop $pop[[L1]]{{$}} +; CHECK-NEXT: end_function define void @test_invalid_rtn() { entry: call i32 bitcast (i32 (i64)* @has_i64_arg to i32 (i32)*)(i32 0) + call [1 x i64] bitcast (i32 (i64)* @has_i64_arg to [1 x i64] (i64)*)(i64 0) ret void } -; CHECK-LABEL: test_invalid_rtn: -; CHECK-NEXT: i32.const $push[[L0:[0-9]+]]=, 0{{$}} -; CHECK-NEXT: i32.call $push1=, .Lhas_i64_arg_bitcast_invalid@FUNCTION, $pop[[L0]]{{$}} -; CHECK-NEXT: drop $pop1 -; CHECK-NEXT: end_function -define void @test_invalid_arg() { -entry: - call i32 bitcast (i32 (i8*)* @has_ptr_arg to i32 (i8)*)(i8 2) - call i32 bitcast (i32 (i8*)* @has_ptr_arg to i32 (i32)*)(i32 2) - call i32 bitcast (i32 (i8*)* @has_ptr_arg to i32 (i64)*)(i64 3) +; CHECK-LABEL: test_struct_rtn: +; CHECK: call has_i64_arg@FUNCTION, $pop6, $pop0 +define void @test_struct_rtn() { + call {i32, i32} bitcast (i32 (i64)* @has_i64_arg to {i32, i32} (i64)*)(i64 0) ret void } ; CHECK-LABEL: test_invalid_arg: ; CHECK-NEXT: i32.const $push[[L0:[0-9]+]]=, 2{{$}} -; CHECK-NEXT: i32.call $push[[L1:[0-9]+]]=, .Lhas_ptr_arg_bitcast_invalid.1@FUNCTION, $pop[[L0]]{{$}} +; CHECK-NEXT: i32.call $push[[L1:[0-9]+]]=, .Lhas_ptr_arg_bitcast_invalid.4@FUNCTION, $pop[[L0]]{{$}} ; CHECK-NEXT: drop $pop[[L1]]{{$}} ; CHECK-NEXT: i32.const $push[[L0:[0-9]+]]=, 2{{$}} ; CHECK-NEXT: i32.call $push[[L1:[0-9]+]]=, has_ptr_arg@FUNCTION, $pop[[L0]]{{$}} @@ -39,8 +42,21 @@ entry: ; CHECK-NEXT: i32.call $push[[L1:[0-9]+]]=, .Lhas_ptr_arg_bitcast_invalid@FUNCTION, $pop[[L0]]{{$}} ; CHECK-NEXT: drop $pop[[L1]]{{$}} ; CHECK-NEXT: end_function +define void @test_invalid_arg() { +entry: + call i32 bitcast (i32 (i8*)* @has_ptr_arg to i32 (i8)*)(i8 2) + call i32 bitcast (i32 (i8*)* @has_ptr_arg to i32 (i32)*)(i32 2) + call i32 bitcast (i32 (i8*)* @has_ptr_arg to i32 (i64)*)(i64 3) + ret void +} ; CHECK-LABEL: .Lhas_i64_arg_bitcast_invalid: +; CHECK-NEXT: .param i64 +; CHECK-NEXT: .result i64 +; CHECK-NEXT: unreachable +; CHECK-NEXT: end_function + +; CHECK-LABEL: .Lhas_i64_arg_bitcast_invalid.2: ; CHECK-NEXT: .param i32 ; CHECK-NEXT: .result i32 ; CHECK-NEXT: unreachable @@ -52,7 +68,7 @@ entry: ; CHECK-NEXT: unreachable ; CHECK-NEXT: end_function -; CHECK-LABEL: .Lhas_ptr_arg_bitcast_invalid.1: +; CHECK-LABEL: .Lhas_ptr_arg_bitcast_invalid.4: ; CHECK-NEXT: .param i32 ; CHECK-NEXT: .result i32 ; CHECK-NEXT: unreachable -- cgit v1.2.3