diff --git a/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp b/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp index 65d6c4f3f88..59d69e48b77 100644 --- a/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp +++ b/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp @@ -1524,6 +1524,7 @@ void WebAssemblyCFGStackify::fixEndsAtEndOfFunction(MachineFunction &MF) { } case WebAssembly::END_BLOCK: case WebAssembly::END_LOOP: + case WebAssembly::DELEGATE: EndToBegin[&MI]->getOperand(0).setImm(int32_t(RetType)); continue; default: diff --git a/test/CodeGen/WebAssembly/cfg-stackify-eh.mir b/test/CodeGen/WebAssembly/cfg-stackify-eh.mir index be40d79e697..fd75e0b6f14 100644 --- a/test/CodeGen/WebAssembly/cfg-stackify-eh.mir +++ b/test/CodeGen/WebAssembly/cfg-stackify-eh.mir @@ -9,6 +9,9 @@ define void @rethrow_arg_test() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) { ret void } + define i32 @fix_end_function_test() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) { + ret i32 0 + } ... --- @@ -43,7 +46,7 @@ body: | ; CHECK: bb.2 (landing-pad): ; CHECK: CATCH ; CHECK: RETHROW 0 - EH_LABEL + EH_LABEL %1:i32 = CATCH &__cpp_exception, implicit-def dead $arguments RETHROW 0, implicit-def dead $arguments @@ -53,3 +56,61 @@ body: | ; CHECK: END_TRY RETURN implicit-def dead $arguments ... + +--- +# This function has i32 return type and the end of the function is unreachable, +# so CFGStackify's fixEndsAtEndOfFunction() propagates the return type while +# they encounter 'end' or 'delegate'. This is a regression test for a bug that +# we only handled 'end' but not 'delegate'. +# CHECK-LABEL: name: fix_end_function_test +name: fix_end_function_test +liveins: + - { reg: '$arguments' } +machineFunctionInfo: + params: [ ] + results: [ i32 ] + wasmEHFuncInfo: + 3: 4 +body: | + ; CHECK: TRY 127 + ; CHECK: TRY 127 + ; CHECK: CALL @foo + ; CHECK: TRY 64 + ; CHECK: CALL @foo + ; CHECK: DELEGATE + ; CHECK: RETURN + ; CHECK: CATCH + ;; This TRY should have the return type i32 (127) + ; CHECK: TRY 127 + ; CHECK: RETHROW + ; CHECK: DELEGATE + ; CHECK: END_TRY + ; CHECK: CATCH + ; CHECK: RETHROW + ; CHECK: END_TRY + bb.0: + successors: %bb.1, %bb.3 + EH_LABEL + CALL @foo, implicit-def dead $arguments, implicit $sp32, implicit $sp64 + EH_LABEL + + bb.1: + successors: %bb.2, %bb.4 + EH_LABEL + CALL @foo, implicit-def dead $arguments, implicit $sp32, implicit $sp64 + EH_LABEL + + bb.2: + %0:i32 = CONST_I32 3, implicit-def dead $arguments + RETURN %0:i32, implicit-def dead $arguments + + bb.3 (landing-pad): + EH_LABEL + %0:i32 = CATCH &__cpp_exception, implicit-def dead $arguments + RETHROW 0, implicit-def dead $arguments + + bb.4 (landing-pad): + EH_LABEL + %1:i32 = CATCH &__cpp_exception, implicit-def dead $arguments + RETHROW 0, implicit-def dead $arguments +...