llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
28.59k stars 11.82k forks source link

wasm-validate: type mismatch in function, expected [] but got [i32] #43726

Open yowl opened 4 years ago

yowl commented 4 years ago
Bugzilla Link 44381
Version unspecified
OS Windows NT
CC @sbc100

Extended Description

I'm getting this error from wasm-validate, after wasm-ld. Running

E:/GitHub/emsdk/upstream/bin\wasm-ld.exe -o c:\users\scottw~1\appdata\local\temp\emscripten_temp\HelloWasm.wasm --allow-undefined --lto-O0 E:\GitHub\corert\tests\src\Simple\HelloWasm\obj\Debug\wasm\native\HelloWasm.bc E:\GitHub\corert\tests\..\bin\WebAssembly.wasm.Debug/sdk/libPortableRuntime.a E:\GitHub\corert\tests\..\bin\WebAssembly.wasm.Debug/sdk/libbootstrappercpp.a E:\GitHub\corert\tests\..\bin\WebAssembly.wasm.Debug/sdk/libSystem.Private.CoreLib.Native.a -LE:\GitHub\emsdk\upstream\emscripten\system\local\lib -LE:\GitHub\emsdk\upstream\emscripten\system\lib -LC:\Users\ScottWaye.emscripten_cache\wasm-obj C:\Users\ScottWaye.emscripten_cache\wasm-obj\libc.a C:\Users\ScottWaye.emscripten_cache\wasm-obj\libcompiler_rt.a C:\Users\ScottWaye.emscripten_cache\wasm-obj\libc-wasm.a C:\Users\ScottWaye.emscripten_cache\wasm-obj\libc++-noexcept.a C:\Users\ScottWaye.emscripten_cache\wasm-obj\libc++abi-noexcept.a C:\Users\ScottWaye.emscripten_cache\wasm-obj\libdlmalloc-debug.a C:\Users\ScottWaye.emscripten_cache\wasm-obj\libpthread_stub.a C:\Users\ScottWaye.emscripten_cache\wasm-obj\libc_rt_wasm.a --import-memory --import-table -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr --export wasm_call_ctors --export data_end --export main --export malloc --export free --export setThrew --export __errno_location --export fflush --export emscripten_builtin_memalign --export memalign --export emscripten_builtin_free --export _ZSt18uncaught_exceptionv --export _get_environ -z stack-size=5242880 --initial-memory=16777216 --no-entry --global-base=1024

Where the input files are at https://hubsoftwareengineering-my.sharepoint.com/:u:/g/personal/scott_waye_hubse_com/EXx2lfO3PppIr-d5LevShOgBHVY_k944rFkN1TCnRMJJ7Q?e=Lh9dVl (too big for here).

wasm-ld is version LLD 10.0.0 (Cswircachegitchromium.googlesource.com-external-github.com-llvm-llvm--project b5f295ffcec2fa7402e39eb1262acbd55a7d39f5)

This produces a wasm, which can passed to wasm-validate with the output:

c:/users/scottw~1/appdata/local/temp/emscripten_temp/HelloWasm.wasm:01b75a7: error: type mismatch in function, expected [] but got [i32]

wasm-dis does not complain and produces an output ok.

If I run wasm-validate --verbose, then the message appears between these functions:

  OnFunctionName(index: 26584, name: "Internal_CompilerGenerated__Module___InvokeRetVIII<Double__Int32__Int32>")

c:/users/scottw~1/appdata/local/temp/emscripten_temp/HelloWasm.wasm:01b75a7: error: type mismatch in function, expected [] but got [i32] OnFunctionName(index: 26585, name: "Internal_CompilerGeneratedModule___InvokeRetVIIII<S_P_CoreLib_System_Action_1ObjectInt16Int32>")

Not sure if it refers to the function before, after, or neither.

I'm using emscripten and when I run the build from emscripten, the error is different

[wasm-validator error in function $S_P_CoreLib_System_Runtime_RuntimeImports__memset] unexpected true: if block is not returning a value, final element should not flow out a value, on

This function does end in a local.get which I'm not sure is right as the LLVM is void:

define void @​S_P_CoreLib_System_Runtime_RuntimeImports_memset(i8, i8, i32, i32) { Prolog: %Argument0 = getelementptr i8, i8 %0, i32 0 %CastPtr = bitcast i8 %Argument0 to i8* store i8 %1, i8** %CastPtr %Argument1 = getelementptr i8, i8 %0, i32 4 %CastPtr1 = bitcast i8 %Argument1 to i32 store i32 %2, i32 %CastPtr1 %Argument2 = getelementptr i8, i8 %0, i32 8 %CastPtr2 = bitcast i8 %Argument2_ to i32 store i32 %3, i32 %CastPtr2 br label %Block0

Block0: ; preds = %Prolog %Argument0_3 = getelementptr i8, i8 %0, i32 0 %Argument1_4 = getelementptr i8, i8 %0, i32 4 %Argument2_5 = getelementptr i8, i8 %0, i32 8 %CastPtr6 = bitcast i8 %Argument03 to i8** %Loadarg0 = load i8*, i8 %CastPtr6 %CastPtr7 = bitcast i8 %Argument1_4 to i32 %Loadarg1_ = load i32, i32 %CastPtr7 %CastPtr8 = bitcast i8 %Argument25 to i32* %Loadarg2 = load i32, i32 %CastPtr8 %shadowStackTop = getelementptr i8, i8 %0, i32 12 store i8* %shadowStackTop, i8 @​tpShadowStackTop %PInvokeTransitionFrame = alloca { i8, i8, i8 } call void @​RhpPInvoke2({ i8, i8, i8 } %PInvokeTransitionFrame) call void @​memset(i8 %Loadarg0, i32 %Loadarg1, i32 %Loadarg2) call void @​RhpPInvokeReturn2({ i8, i8, i8 } %PInvokeTransitionFrame) call void @"S_P_CoreLib_System_Runtime_RuntimeImports__memset$FinallyD"(i8* %0) br label %BlockE

BlockE: ; preds = %Block0 ret void }

The value pushed to the stack, $5, is the result (if I read the wasm correctly), of the memset call. The LLVM for that call is

call void @​memset(i8* %Loadarg0, i32 %Loadarg1, i32 %Loadarg2_)

so there is no return, I have memset externed (in c#):

    internal static extern unsafe void memset(byte* mem, int value, nuint size);

And this does differ from the c++ definition where it is void. I changed this extern to byte and that does clear the error. So not sure if there's really a problem here or not. The wasm does push a value to the stack when the LLVM does not, but then again there is a mismatch in memset definitions.

Feel free to close if you think its fine.

sbc100 commented 4 years ago

This is almost certainly a bug since wasm-ld should never produce binaries that don't validate.

yowl commented 4 years ago

assigned to @sbc100