From 6594d058b9e03bd5d0e3cfcdad0050b042dc5778 Mon Sep 17 00:00:00 2001 From: Sergei Barannikov Date: Mon, 30 Jan 2023 06:39:37 +0300 Subject: [PATCH] [WebAssembly] Convert some tests to opaque pointers (NFC) --- llvm/test/CodeGen/WebAssembly/lower-em-ehsjlj.ll | 119 +++++++-------- .../CodeGen/WebAssembly/lower-em-exceptions.ll | 124 ++++++++------- llvm/test/CodeGen/WebAssembly/lower-em-sjlj.ll | 166 +++++++++------------ llvm/test/CodeGen/WebAssembly/lower-wasm-ehsjlj.ll | 92 ++++++------ llvm/test/CodeGen/WebAssembly/lower-wasm-sjlj.ll | 106 ++++++------- llvm/test/CodeGen/WebAssembly/wasmehprepare.ll | 90 +++++------ 6 files changed, 326 insertions(+), 371 deletions(-) diff --git a/llvm/test/CodeGen/WebAssembly/lower-em-ehsjlj.ll b/llvm/test/CodeGen/WebAssembly/lower-em-ehsjlj.ll index 961d628..7cf05cc 100644 --- a/llvm/test/CodeGen/WebAssembly/lower-em-ehsjlj.ll +++ b/llvm/test/CodeGen/WebAssembly/lower-em-ehsjlj.ll @@ -1,5 +1,5 @@ -; RUN: opt -opaque-pointers=0 < %s -wasm-lower-em-ehsjlj -enable-emscripten-cxx-exceptions -enable-emscripten-sjlj -S | FileCheck %s -; RUN: llc -opaque-pointers=0 < %s -enable-emscripten-cxx-exceptions -enable-emscripten-sjlj -verify-machineinstrs +; RUN: opt < %s -wasm-lower-em-ehsjlj -enable-emscripten-cxx-exceptions -enable-emscripten-sjlj -S | FileCheck %s +; RUN: llc < %s -enable-emscripten-cxx-exceptions -enable-emscripten-sjlj -verify-machineinstrs ; Tests for cases when exception handling and setjmp/longjmp handling are mixed. @@ -7,24 +7,23 @@ target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" target triple = "wasm32-unknown-unknown" %struct.__jmp_buf_tag = type { [6 x i32], i32, [32 x i32] } -@_ZTIi = external constant i8* +@_ZTIi = external constant ptr ; There is a function call (@foo) that can either throw an exception or longjmp ; and there is also a setjmp call. When @foo throws, we have to check both for ; exception and longjmp and jump to exception or longjmp handling BB depending ; on the result. -define void @setjmp_longjmp_exception() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { +define void @setjmp_longjmp_exception() personality ptr @__gxx_personality_v0 { ; CHECK-LABEL: @setjmp_longjmp_exception entry: %buf = alloca [1 x %struct.__jmp_buf_tag], align 16 - %arraydecay = getelementptr inbounds [1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* %buf, i32 0, i32 0 - %call = call i32 @setjmp(%struct.__jmp_buf_tag* %arraydecay) #0 + %call = call i32 @setjmp(ptr %buf) #0 invoke void @foo() to label %try.cont unwind label %lpad ; CHECK: entry.split.split: ; CHECK: %[[CMP0:.*]] = icmp ne i32 %__THREW__.val, 0 -; CHECK-NEXT: %__threwValue.val = load i32, i32* @__threwValue +; CHECK-NEXT: %__threwValue.val = load i32, ptr @__threwValue ; CHECK-NEXT: %[[CMP1:.*]] = icmp ne i32 %__threwValue.val, 0 ; CHECK-NEXT: %[[CMP:.*]] = and i1 %[[CMP0]], %[[CMP1]] ; CHECK-NEXT: br i1 %[[CMP]], label %if.then1, label %if.else1 @@ -36,12 +35,12 @@ entry: ; CHECK: lpad: lpad: ; preds = %entry - %0 = landingpad { i8*, i32 } - catch i8* null - %1 = extractvalue { i8*, i32 } %0, 0 - %2 = extractvalue { i8*, i32 } %0, 1 -; CHECK-NOT: call {{.*}} void @__invoke_void(void ()* @__cxa_end_catch) - %3 = call i8* @__cxa_begin_catch(i8* %1) #2 + %0 = landingpad { ptr, i32 } + catch ptr null + %1 = extractvalue { ptr, i32 } %0, 0 + %2 = extractvalue { ptr, i32 } %0, 1 +; CHECK-NOT: call {{.*}} void @__invoke_void(ptr @__cxa_end_catch) + %3 = call ptr @__cxa_begin_catch(ptr %1) #2 call void @__cxa_end_catch() br label %try.cont @@ -57,7 +56,7 @@ try.cont: ; preds = %lpad, %entry ; have any setjmp calls, we only handle exceptions in this function. But because ; sjlj is enabled, we check if the thrown value is longjmp and if so rethrow it ; by calling @emscripten_longjmp. -define void @rethrow_longjmp() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { +define void @rethrow_longjmp() personality ptr @__gxx_personality_v0 { ; CHECK-LABEL: @rethrow_longjmp entry: invoke void @foo() @@ -74,7 +73,7 @@ entry: ; CHECK: rethrow.longjmp: ; CHECK-NEXT: %threw.phi = phi i32 [ %__THREW__.val, %entry ] -; CHECK-NEXT: %__threwValue.val = load i32, i32* @__threwValue, align 4 +; CHECK-NEXT: %__threwValue.val = load i32, ptr @__threwValue, align 4 ; CHECK-NEXT: call void @emscripten_longjmp(i32 %threw.phi, i32 %__threwValue.val ; CHECK-NEXT: unreachable @@ -83,11 +82,11 @@ entry: ; CHECK-NEXT: br i1 %cmp, label %lpad, label %try.cont lpad: ; preds = %entry - %0 = landingpad { i8*, i32 } - catch i8* null - %1 = extractvalue { i8*, i32 } %0, 0 - %2 = extractvalue { i8*, i32 } %0, 1 - %3 = call i8* @__cxa_begin_catch(i8* %1) #5 + %0 = landingpad { ptr, i32 } + catch ptr null + %1 = extractvalue { ptr, i32 } %0, 0 + %2 = extractvalue { ptr, i32 } %0, 1 + %3 = call ptr @__cxa_begin_catch(ptr %1) #5 call void @__cxa_end_catch() br label %try.cont @@ -104,8 +103,7 @@ define void @rethrow_exception() { ; CHECK-LABEL: @rethrow_exception entry: %buf = alloca [1 x %struct.__jmp_buf_tag], align 16 - %arraydecay = getelementptr inbounds [1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* %buf, i32 0, i32 0 - %call = call i32 @setjmp(%struct.__jmp_buf_tag* %arraydecay) #0 + %call = call i32 @setjmp(ptr %buf) #0 %cmp = icmp ne i32 %call, 0 br i1 %cmp, label %return, label %if.end @@ -118,10 +116,9 @@ if.end: ; preds = %entry ; CHECK-NEXT: br i1 %cmp.eq.one, label %rethrow.exn, label %normal ; CHECK: rethrow.exn: -; CHECK-NEXT: %exn = call i8* @__cxa_find_matching_catch_2() -; CHECK-NEXT: %[[BUF:.*]] = bitcast i32* %setjmpTable{{.*}} to i8* -; CHECK-NEXT: call void @free(i8* %[[BUF]]) -; CHECK-NEXT: call void @__resumeException(i8* %exn) +; CHECK-NEXT: %exn = call ptr @__cxa_find_matching_catch_2() +; CHECK-NEXT: call void @free(ptr %setjmpTable{{.*}}) +; CHECK-NEXT: call void @__resumeException(ptr %exn) ; CHECK-NEXT: unreachable ; CHECK: normal: @@ -137,8 +134,7 @@ define void @rethrow_exception2() { ; CHECK-LABEL: @rethrow_exception2 entry: %buf = alloca [1 x %struct.__jmp_buf_tag], align 16 - %arraydecay = getelementptr inbounds [1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* %buf, i32 0, i32 0 - %call = call i32 @setjmp(%struct.__jmp_buf_tag* %arraydecay) #0 + %call = call i32 @setjmp(ptr %buf) #0 %cmp = icmp ne i32 %call, 0 br i1 %cmp, label %throw, label %if.end @@ -147,13 +143,12 @@ if.end: ; preds = %entry br label %throw throw: ; preds = %if.end, %entry - call void @__cxa_throw(i8* null, i8* null, i8* null) #1 + call void @__cxa_throw(ptr null, ptr null, ptr null) #1 unreachable ; CHECK: throw: -; CHECK: %[[BUF:.*]] = bitcast i32* %setjmpTable{{.*}} to i8* -; CHECK-NEXT: call void @free(i8* %[[BUF]]) -; CHECK-NEXT: call void @__cxa_throw(i8* null, i8* null, i8* null) +; CHECK-NEXT: call void @free(ptr %setjmpTable{{.*}}) +; CHECK-NEXT: call void @__cxa_throw(ptr null, ptr null, ptr null) ; CHECK-NEXT: unreachable } @@ -161,7 +156,7 @@ throw: ; preds = %if.end, %entry ; that can possibly longjmp (instead of throwing exception) so we have to ; rethrow them. Here we test if we correclty generate only one 'rethrow.longjmp' ; BB and share it for multiple calls. -define void @rethrow_longjmp_multi() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { +define void @rethrow_longjmp_multi() personality ptr @__gxx_personality_v0 { ; CHECK-LABEL: @rethrow_longjmp_multi entry: invoke void @foo() @@ -172,11 +167,11 @@ bb: ; preds = %entry to label %try.cont unwind label %lpad lpad: ; preds = %bb, %entry - %0 = landingpad { i8*, i32 } - catch i8* null - %1 = extractvalue { i8*, i32 } %0, 0 - %2 = extractvalue { i8*, i32 } %0, 1 - %3 = call i8* @__cxa_begin_catch(i8* %1) #5 + %0 = landingpad { ptr, i32 } + catch ptr null + %1 = extractvalue { ptr, i32 } %0, 0 + %2 = extractvalue { ptr, i32 } %0, 1 + %3 = call ptr @__cxa_begin_catch(ptr %1) #5 call void @__cxa_end_catch() br label %try.cont @@ -186,7 +181,7 @@ try.cont: ; preds = %lpad, %bb ; CHECK: rethrow.longjmp: ; CHECK-NEXT: %threw.phi = phi i32 [ %__THREW__.val, %entry ], [ %__THREW__.val1, %bb ] -; CHECK-NEXT: %__threwValue.val = load i32, i32* @__threwValue, align 4 +; CHECK-NEXT: %__threwValue.val = load i32, ptr @__threwValue, align 4 ; CHECK-NEXT: call void @emscripten_longjmp(i32 %threw.phi, i32 %__threwValue.val) ; CHECK-NEXT: unreachable } @@ -199,8 +194,7 @@ define void @rethrow_exception_multi() { ; CHECK-LABEL: @rethrow_exception_multi entry: %buf = alloca [1 x %struct.__jmp_buf_tag], align 16 - %arraydecay = getelementptr inbounds [1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* %buf, i32 0, i32 0 - %call = call i32 @setjmp(%struct.__jmp_buf_tag* %arraydecay) #0 + %call = call i32 @setjmp(ptr %buf) #0 %cmp = icmp ne i32 %call, 0 br i1 %cmp, label %return, label %if.end @@ -213,10 +207,9 @@ return: ; preds = %entry, %if.end ret void ; CHECK: rethrow.exn: -; CHECK-NEXT: %exn = call i8* @__cxa_find_matching_catch_2() -; CHECK-NEXT: %{{.*}} = bitcast i32* %setjmpTable{{.*}} to i8* -; CHECK-NEXT: tail call void @free(i8* %{{.*}}) -; CHECK-NEXT: call void @__resumeException(i8* %exn) +; CHECK-NEXT: %exn = call ptr @__cxa_find_matching_catch_2() +; CHECK-NEXT: tail call void @free(ptr %setjmpTable{{.*}}) +; CHECK-NEXT: call void @__resumeException(ptr %exn) ; CHECK-NEXT: unreachable } @@ -227,20 +220,18 @@ return: ; preds = %entry, %if.end ; throw 3; ; } catch (...) { ; } -define void @setjmp_with_throw_try_catch() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { +define void @setjmp_with_throw_try_catch() personality ptr @__gxx_personality_v0 { ; CHECK-LABEL: @setjmp_with_throw_try_catch entry: %buf = alloca [1 x %struct.__jmp_buf_tag], align 16 - %arraydecay = getelementptr inbounds [1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* %buf, i32 0, i32 0 - %call = call i32 @setjmp(%struct.__jmp_buf_tag* %arraydecay) #0 + %call = call i32 @setjmp(ptr %buf) #0 %cmp = icmp ne i32 %call, 0 br i1 %cmp, label %try.cont, label %if.end if.end: ; preds = %entry - %exception = call i8* @__cxa_allocate_exception(i32 4) #2 - %0 = bitcast i8* %exception to i32* - store i32 3, i32* %0, align 16 - invoke void @__cxa_throw(i8* %exception, i8* bitcast (i8** @_ZTIi to i8*), i8* null) #1 + %exception = call ptr @__cxa_allocate_exception(i32 4) #2 + store i32 3, ptr %exception, align 16 + invoke void @__cxa_throw(ptr %exception, ptr @_ZTIi, ptr null) #1 to label %unreachable unwind label %lpad ; When invoke @__cxa_throw is converted to a call to the invoke wrapper, ; "noreturn" attribute should be removed, and there should be no 'free' call @@ -249,15 +240,15 @@ if.end: ; preds = %entry ; noreturn instructions, because they are supposed to return. ; CHECK: if.end: ; CHECK-NOT: tail call void @free -; CHECK-NOT: call cc99 void @"__invoke_void_i8*_i8*_i8*"(void (i8*, i8*, i8*)* @__cxa_throw, i8* %exception, i8* bitcast (i8** @_ZTIi to i8*), i8* null) # -; CHECK: call cc99 void @"__invoke_void_i8*_i8*_i8*"(void (i8*, i8*, i8*)* @__cxa_throw, i8* %exception, i8* bitcast (i8** @_ZTIi to i8*), i8* null) +; CHECK-NOT: call cc99 void @__invoke_void_ptr_ptr_ptr(ptr @__cxa_throw, ptr %exception, ptr @_ZTIi, ptr null) # +; CHECK: call cc99 void @__invoke_void_ptr_ptr_ptr(ptr @__cxa_throw, ptr %exception, ptr @_ZTIi, ptr null) lpad: ; preds = %if.end - %1 = landingpad { i8*, i32 } - catch i8* null - %2 = extractvalue { i8*, i32 } %1, 0 - %3 = extractvalue { i8*, i32 } %1, 1 - %4 = call i8* @__cxa_begin_catch(i8* %2) #2 + %0 = landingpad { ptr, i32 } + catch ptr null + %1 = extractvalue { ptr, i32 } %0, 0 + %2 = extractvalue { ptr, i32 } %0, 1 + %3 = call ptr @__cxa_begin_catch(ptr %1) #2 call void @__cxa_end_catch() br label %try.cont @@ -270,14 +261,14 @@ unreachable: ; preds = %if.end declare void @foo() ; Function Attrs: returns_twice -declare i32 @setjmp(%struct.__jmp_buf_tag*) +declare i32 @setjmp(ptr) ; Function Attrs: noreturn -declare void @longjmp(%struct.__jmp_buf_tag*, i32) +declare void @longjmp(ptr, i32) declare i32 @__gxx_personality_v0(...) -declare i8* @__cxa_begin_catch(i8*) +declare ptr @__cxa_begin_catch(ptr) declare void @__cxa_end_catch() -declare void @__cxa_throw(i8*, i8*, i8*) -declare i8* @__cxa_allocate_exception(i32) +declare void @__cxa_throw(ptr, ptr, ptr) +declare ptr @__cxa_allocate_exception(i32) attributes #0 = { returns_twice } attributes #1 = { noreturn } diff --git a/llvm/test/CodeGen/WebAssembly/lower-em-exceptions.ll b/llvm/test/CodeGen/WebAssembly/lower-em-exceptions.ll index 184dc98..1d75baf 100644 --- a/llvm/test/CodeGen/WebAssembly/lower-em-exceptions.ll +++ b/llvm/test/CodeGen/WebAssembly/lower-em-exceptions.ll @@ -1,27 +1,27 @@ -; RUN: opt -opaque-pointers=0 < %s -wasm-lower-em-ehsjlj -enable-emscripten-cxx-exceptions -S | FileCheck %s -DPTR=i32 -; RUN: opt -opaque-pointers=0 < %s -wasm-lower-em-ehsjlj -enable-emscripten-cxx-exceptions -S --mattr=+atomics,+bulk-memory | FileCheck %s -DPTR=i32 -; RUN: opt -opaque-pointers=0 < %s -wasm-lower-em-ehsjlj -enable-emscripten-cxx-exceptions --mtriple=wasm64-unknown-unknown -data-layout="e-m:e-p:64:64-i64:64-n32:64-S128" -S | FileCheck %s -DPTR=i64 +; RUN: opt < %s -wasm-lower-em-ehsjlj -enable-emscripten-cxx-exceptions -S | FileCheck %s -DPTR=i32 +; RUN: opt < %s -wasm-lower-em-ehsjlj -enable-emscripten-cxx-exceptions -S --mattr=+atomics,+bulk-memory | FileCheck %s -DPTR=i32 +; RUN: opt < %s -wasm-lower-em-ehsjlj -enable-emscripten-cxx-exceptions --mtriple=wasm64-unknown-unknown -data-layout="e-m:e-p:64:64-i64:64-n32:64-S128" -S | FileCheck %s -DPTR=i64 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" target triple = "wasm32-unknown-unknown" -@_ZTIi = external constant i8* -@_ZTIc = external constant i8* +@_ZTIi = external constant ptr +@_ZTIc = external constant ptr ; CHECK: @__THREW__ = external thread_local global [[PTR]] ; __threwValue is only used in Emscripten SjLj, so it shouldn't be generated. ; CHECK-NOT: @__threwValue = ; Test invoke instruction with clauses (try-catch block) -define void @clause() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { +define void @clause() personality ptr @__gxx_personality_v0 { ; CHECK-LABEL: @clause( entry: invoke void @foo(i32 3) to label %invoke.cont unwind label %lpad ; CHECK: entry: -; CHECK-NEXT: store [[PTR]] 0, [[PTR]]* @__THREW__ -; CHECK-NEXT: call cc{{.*}} void @__invoke_void_i32(void (i32)* @foo, i32 3) -; CHECK-NEXT: %[[__THREW__VAL:.*]] = load [[PTR]], [[PTR]]* @__THREW__ -; CHECK-NEXT: store [[PTR]] 0, [[PTR]]* @__THREW__ +; CHECK-NEXT: store [[PTR]] 0, ptr @__THREW__ +; CHECK-NEXT: call cc{{.*}} void @__invoke_void_i32(ptr @foo, i32 3) +; CHECK-NEXT: %[[__THREW__VAL:.*]] = load [[PTR]], ptr @__THREW__ +; CHECK-NEXT: store [[PTR]] 0, ptr @__THREW__ ; CHECK-NEXT: %cmp = icmp eq [[PTR]] %[[__THREW__VAL]], 1 ; CHECK-NEXT: br i1 %cmp, label %lpad, label %invoke.cont @@ -29,32 +29,31 @@ invoke.cont: ; preds = %entry br label %try.cont lpad: ; preds = %entry - %0 = landingpad { i8*, i32 } - catch i8* bitcast (i8** @_ZTIi to i8*) - catch i8* null - %1 = extractvalue { i8*, i32 } %0, 0 - %2 = extractvalue { i8*, i32 } %0, 1 + %0 = landingpad { ptr, i32 } + catch ptr @_ZTIi + catch ptr null + %1 = extractvalue { ptr, i32 } %0, 0 + %2 = extractvalue { ptr, i32 } %0, 1 br label %catch.dispatch ; CHECK: lpad: -; CHECK-NEXT: %[[FMC:.*]] = call i8* @__cxa_find_matching_catch_4(i8* bitcast (i8** @_ZTIi to i8*), i8* null) -; CHECK-NEXT: %[[IVI1:.*]] = insertvalue { i8*, i32 } poison, i8* %[[FMC]], 0 +; CHECK-NEXT: %[[FMC:.*]] = call ptr @__cxa_find_matching_catch_4(ptr @_ZTIi, ptr null) +; CHECK-NEXT: %[[IVI1:.*]] = insertvalue { ptr, i32 } poison, ptr %[[FMC]], 0 ; CHECK-NEXT: %[[TEMPRET0_VAL:.*]] = call i32 @getTempRet0() -; CHECK-NEXT: %[[IVI2:.*]] = insertvalue { i8*, i32 } %[[IVI1]], i32 %[[TEMPRET0_VAL]], 1 -; CHECK-NEXT: extractvalue { i8*, i32 } %[[IVI2]], 0 -; CHECK-NEXT: %[[CDR:.*]] = extractvalue { i8*, i32 } %[[IVI2]], 1 +; CHECK-NEXT: %[[IVI2:.*]] = insertvalue { ptr, i32 } %[[IVI1]], i32 %[[TEMPRET0_VAL]], 1 +; CHECK-NEXT: extractvalue { ptr, i32 } %[[IVI2]], 0 +; CHECK-NEXT: %[[CDR:.*]] = extractvalue { ptr, i32 } %[[IVI2]], 1 catch.dispatch: ; preds = %lpad - %3 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*)) + %3 = call i32 @llvm.eh.typeid.for(ptr @_ZTIi) %matches = icmp eq i32 %2, %3 br i1 %matches, label %catch1, label %catch ; CHECK: catch.dispatch: -; CHECK-NEXT: %[[TYPEID:.*]] = call i32 @llvm_eh_typeid_for(i8* bitcast (i8** @_ZTIi to i8*)) +; CHECK-NEXT: %[[TYPEID:.*]] = call i32 @llvm_eh_typeid_for(ptr @_ZTIi) ; CHECK-NEXT: %matches = icmp eq i32 %[[CDR]], %[[TYPEID]] catch1: ; preds = %catch.dispatch - %4 = call i8* @__cxa_begin_catch(i8* %1) - %5 = bitcast i8* %4 to i32* - %6 = load i32, i32* %5, align 4 + %4 = call ptr @__cxa_begin_catch(ptr %1) + %5 = load i32, ptr %4, align 4 call void @__cxa_end_catch() br label %try.cont @@ -62,7 +61,7 @@ try.cont: ; preds = %catch, %catch1, %in ret void catch: ; preds = %catch.dispatch - %7 = call i8* @__cxa_begin_catch(i8* %1) + %6 = call ptr @__cxa_begin_catch(ptr %1) call void @__cxa_end_catch() br label %try.cont } @@ -71,16 +70,16 @@ catch: ; preds = %catch.dispatch ; Currently we don't support exception specifications correctly in JS glue code, ; so we ignore all filters here. ; See https://bugs.llvm.org/show_bug.cgi?id=50396. -define void @filter() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { +define void @filter() personality ptr @__gxx_personality_v0 { ; CHECK-LABEL: @filter( entry: invoke void @foo(i32 3) to label %invoke.cont unwind label %lpad ; CHECK: entry: -; CHECK-NEXT: store [[PTR]] 0, [[PTR]]* @__THREW__ -; CHECK-NEXT: call cc{{.*}} void @__invoke_void_i32(void (i32)* @foo, i32 3) -; CHECK-NEXT: %[[__THREW__VAL:.*]] = load [[PTR]], [[PTR]]* @__THREW__ -; CHECK-NEXT: store [[PTR]] 0, [[PTR]]* @__THREW__ +; CHECK-NEXT: store [[PTR]] 0, ptr @__THREW__ +; CHECK-NEXT: call cc{{.*}} void @__invoke_void_i32(ptr @foo, i32 3) +; CHECK-NEXT: %[[__THREW__VAL:.*]] = load [[PTR]], ptr @__THREW__ +; CHECK-NEXT: store [[PTR]] 0, ptr @__THREW__ ; CHECK-NEXT: %cmp = icmp eq [[PTR]] %[[__THREW__VAL]], 1 ; CHECK-NEXT: br i1 %cmp, label %lpad, label %invoke.cont @@ -88,66 +87,65 @@ invoke.cont: ; preds = %entry ret void lpad: ; preds = %entry - %0 = landingpad { i8*, i32 } - filter [2 x i8*] [i8* bitcast (i8** @_ZTIi to i8*), i8* bitcast (i8** @_ZTIc to i8*)] - %1 = extractvalue { i8*, i32 } %0, 0 - %2 = extractvalue { i8*, i32 } %0, 1 + %0 = landingpad { ptr, i32 } + filter [2 x ptr] [ptr @_ZTIi, ptr @_ZTIc] + %1 = extractvalue { ptr, i32 } %0, 0 + %2 = extractvalue { ptr, i32 } %0, 1 br label %filter.dispatch ; CHECK: lpad: ; We now temporarily ignore filters because of the bug, so we pass nothing to ; __cxa_find_matching_catch -; CHECK-NEXT: %[[FMC:.*]] = call i8* @__cxa_find_matching_catch_2() +; CHECK-NEXT: %[[FMC:.*]] = call ptr @__cxa_find_matching_catch_2() filter.dispatch: ; preds = %lpad %ehspec.fails = icmp slt i32 %2, 0 br i1 %ehspec.fails, label %ehspec.unexpected, label %eh.resume ehspec.unexpected: ; preds = %filter.dispatch - call void @__cxa_call_unexpected(i8* %1) #4 + call void @__cxa_call_unexpected(ptr %1) #4 unreachable eh.resume: ; preds = %filter.dispatch - %lpad.val = insertvalue { i8*, i32 } poison, i8* %1, 0 - %lpad.val3 = insertvalue { i8*, i32 } %lpad.val, i32 %2, 1 - resume { i8*, i32 } %lpad.val3 + %lpad.val = insertvalue { ptr, i32 } poison, ptr %1, 0 + %lpad.val3 = insertvalue { ptr, i32 } %lpad.val, i32 %2, 1 + resume { ptr, i32 } %lpad.val3 ; CHECK: eh.resume: ; CHECK-NEXT: insertvalue ; CHECK-NEXT: %[[LPAD_VAL:.*]] = insertvalue -; CHECK-NEXT: %[[LOW:.*]] = extractvalue { i8*, i32 } %[[LPAD_VAL]], 0 -; CHECK-NEXT: call void @__resumeException(i8* %[[LOW]]) +; CHECK-NEXT: %[[LOW:.*]] = extractvalue { ptr, i32 } %[[LPAD_VAL]], 0 +; CHECK-NEXT: call void @__resumeException(ptr %[[LOW]]) ; CHECK-NEXT: unreachable } ; Test if argument attributes indices in newly created call instructions are correct -define void @arg_attributes() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { +define void @arg_attributes() personality ptr @__gxx_personality_v0 { ; CHECK-LABEL: @arg_attributes( entry: - %0 = invoke noalias i8* @bar(i8 signext 1, i8 zeroext 2) + %0 = invoke noalias ptr @bar(i8 signext 1, i8 zeroext 2) to label %invoke.cont unwind label %lpad ; CHECK: entry: -; CHECK-NEXT: store [[PTR]] 0, [[PTR]]* @__THREW__ -; CHECK-NEXT: %0 = call cc{{.*}} noalias i8* @"__invoke_i8*_i8_i8"(i8* (i8, i8)* @bar, i8 signext 1, i8 zeroext 2) +; CHECK-NEXT: store [[PTR]] 0, ptr @__THREW__ +; CHECK-NEXT: %0 = call cc{{.*}} noalias ptr @__invoke_ptr_i8_i8(ptr @bar, i8 signext 1, i8 zeroext 2) invoke.cont: ; preds = %entry br label %try.cont lpad: ; preds = %entry - %1 = landingpad { i8*, i32 } - catch i8* bitcast (i8** @_ZTIi to i8*) - catch i8* null - %2 = extractvalue { i8*, i32 } %1, 0 - %3 = extractvalue { i8*, i32 } %1, 1 + %1 = landingpad { ptr, i32 } + catch ptr @_ZTIi + catch ptr null + %2 = extractvalue { ptr, i32 } %1, 0 + %3 = extractvalue { ptr, i32 } %1, 1 br label %catch.dispatch catch.dispatch: ; preds = %lpad - %4 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*)) + %4 = call i32 @llvm.eh.typeid.for(ptr @_ZTIi) %matches = icmp eq i32 %3, %4 br i1 %matches, label %catch1, label %catch catch1: ; preds = %catch.dispatch - %5 = call i8* @__cxa_begin_catch(i8* %2) - %6 = bitcast i8* %5 to i32* - %7 = load i32, i32* %6, align 4 + %5 = call ptr @__cxa_begin_catch(ptr %2) + %6 = load i32, ptr %5, align 4 call void @__cxa_end_catch() br label %try.cont @@ -155,22 +153,22 @@ try.cont: ; preds = %catch, %catch1, %in ret void catch: ; preds = %catch.dispatch - %8 = call i8* @__cxa_begin_catch(i8* %2) + %7 = call ptr @__cxa_begin_catch(ptr %2) call void @__cxa_end_catch() br label %try.cont } declare void @foo(i32) -declare i8* @bar(i8, i8) +declare ptr @bar(i8, i8) declare i32 @__gxx_personality_v0(...) -declare i32 @llvm.eh.typeid.for(i8*) -declare i8* @__cxa_begin_catch(i8*) +declare i32 @llvm.eh.typeid.for(ptr) +declare ptr @__cxa_begin_catch(ptr) declare void @__cxa_end_catch() -declare void @__cxa_call_unexpected(i8*) +declare void @__cxa_call_unexpected(ptr) ; JS glue functions and invoke wrappers declaration ; CHECK-DAG: declare i32 @getTempRet0() -; CHECK-DAG: declare void @__resumeException(i8*) -; CHECK-DAG: declare void @__invoke_void_i32(void (i32)*, i32) -; CHECK-DAG: declare i8* @__cxa_find_matching_catch_4(i8*, i8*) +; CHECK-DAG: declare void @__resumeException(ptr) +; CHECK-DAG: declare void @__invoke_void_i32(ptr, i32) +; CHECK-DAG: declare ptr @__cxa_find_matching_catch_4(ptr, ptr) diff --git a/llvm/test/CodeGen/WebAssembly/lower-em-sjlj.ll b/llvm/test/CodeGen/WebAssembly/lower-em-sjlj.ll index d06a9d4..b571de4 100644 --- a/llvm/test/CodeGen/WebAssembly/lower-em-sjlj.ll +++ b/llvm/test/CodeGen/WebAssembly/lower-em-sjlj.ll @@ -1,6 +1,6 @@ -; RUN: opt -opaque-pointers=0 < %s -wasm-lower-em-ehsjlj -enable-emscripten-sjlj -S | FileCheck %s -DPTR=i32 -; RUN: opt -opaque-pointers=0 < %s -wasm-lower-em-ehsjlj -enable-emscripten-sjlj -S --mattr=+atomics,+bulk-memory | FileCheck %s -DPTR=i32 -; RUN: opt -opaque-pointers=0 < %s -wasm-lower-em-ehsjlj -enable-emscripten-sjlj --mtriple=wasm64-unknown-unknown -data-layout="e-m:e-p:64:64-i64:64-n32:64-S128" -S | FileCheck %s -DPTR=i64 +; RUN: opt < %s -wasm-lower-em-ehsjlj -enable-emscripten-sjlj -S | FileCheck %s -DPTR=i32 +; RUN: opt < %s -wasm-lower-em-ehsjlj -enable-emscripten-sjlj -S --mattr=+atomics,+bulk-memory | FileCheck %s -DPTR=i32 +; RUN: opt < %s -wasm-lower-em-ehsjlj -enable-emscripten-sjlj --mtriple=wasm64-unknown-unknown -data-layout="e-m:e-p:64:64-i64:64-n32:64-S128" -S | FileCheck %s -DPTR=i64 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" target triple = "wasm32-unknown-unknown" @@ -8,45 +8,40 @@ target triple = "wasm32-unknown-unknown" %struct.__jmp_buf_tag = type { [6 x i32], i32, [32 x i32] } @global_var = global i32 0, align 4 -@global_longjmp_ptr = global void (%struct.__jmp_buf_tag*, i32)* @longjmp, align 4 +@global_longjmp_ptr = global ptr @longjmp, align 4 ; CHECK-DAG: @__THREW__ = external thread_local global [[PTR]] ; CHECK-DAG: @__threwValue = external thread_local global i32 -; CHECK-DAG: @global_longjmp_ptr = global void (%struct.__jmp_buf_tag*, i32)* bitcast (void ([[PTR]], i32)* @emscripten_longjmp to void (%struct.__jmp_buf_tag*, i32)*) +; CHECK-DAG: @global_longjmp_ptr = global ptr @emscripten_longjmp ; Test a simple setjmp - longjmp sequence define void @setjmp_longjmp() { ; CHECK-LABEL: @setjmp_longjmp entry: %buf = alloca [1 x %struct.__jmp_buf_tag], align 16 - %arraydecay = getelementptr inbounds [1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* %buf, i32 0, i32 0 - %call = call i32 @setjmp(%struct.__jmp_buf_tag* %arraydecay) #0 - %arraydecay1 = getelementptr inbounds [1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* %buf, i32 0, i32 0 - call void @longjmp(%struct.__jmp_buf_tag* %arraydecay1, i32 1) #1 + %call = call i32 @setjmp(ptr %buf) #0 + call void @longjmp(ptr %buf, i32 1) #1 unreachable ; CHECK: entry: -; CHECK-NEXT: %[[MALLOCCALL:.*]] = tail call i8* @malloc([[PTR]] 40) -; CHECK-NEXT: %[[SETJMP_TABLE:.*]] = bitcast i8* %[[MALLOCCALL]] to i32* -; CHECK-NEXT: store i32 0, i32* %[[SETJMP_TABLE]] +; CHECK-NEXT: %[[MALLOCCALL:.*]] = tail call ptr @malloc([[PTR]] 40) +; CHECK-NEXT: store i32 0, ptr %[[MALLOCCALL]] ; CHECK-NEXT: %[[SETJMP_TABLE_SIZE:.*]] = add i32 4, 0 ; CHECK-NEXT: br label %entry.split ; CHECK: entry.split ; CHECK-NEXT: %[[BUF:.*]] = alloca [1 x %struct.__jmp_buf_tag] -; CHECK-NEXT: %[[ARRAYDECAY:.*]] = getelementptr inbounds [1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* %[[BUF]], i32 0, i32 0 -; CHECK-NEXT: %[[SETJMP_TABLE1:.*]] = call i32* @saveSetjmp(%struct.__jmp_buf_tag* %[[ARRAYDECAY]], i32 1, i32* %[[SETJMP_TABLE]], i32 %[[SETJMP_TABLE_SIZE]]) +; CHECK-NEXT: %[[SETJMP_TABLE1:.*]] = call ptr @saveSetjmp(ptr %[[BUF]], i32 1, ptr %[[MALLOCCALL]], i32 %[[SETJMP_TABLE_SIZE]]) ; CHECK-NEXT: %[[SETJMP_TABLE_SIZE1:.*]] = call i32 @getTempRet0() ; CHECK-NEXT: br label %entry.split.split ; CHECK: entry.split.split: ; CHECK-NEXT: phi i32 [ 0, %entry.split ], [ %[[LONGJMP_RESULT:.*]], %if.end ] -; CHECK-NEXT: %[[ARRAYDECAY1:.*]] = getelementptr inbounds [1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* %[[BUF]], i32 0, i32 0 -; CHECK-NEXT: %[[JMPBUF:.*]] = ptrtoint %struct.__jmp_buf_tag* %[[ARRAYDECAY1]] to [[PTR]] -; CHECK-NEXT: store [[PTR]] 0, [[PTR]]* @__THREW__ -; CHECK-NEXT: call cc{{.*}} void @__invoke_void_[[PTR]]_i32(void ([[PTR]], i32)* @emscripten_longjmp, [[PTR]] %[[JMPBUF]], i32 1) -; CHECK-NEXT: %[[__THREW__VAL:.*]] = load [[PTR]], [[PTR]]* @__THREW__ -; CHECK-NEXT: store [[PTR]] 0, [[PTR]]* @__THREW__ +; CHECK-NEXT: %[[JMPBUF:.*]] = ptrtoint ptr %[[BUF]] to [[PTR]] +; CHECK-NEXT: store [[PTR]] 0, ptr @__THREW__ +; CHECK-NEXT: call cc{{.*}} void @__invoke_void_[[PTR]]_i32(ptr @emscripten_longjmp, [[PTR]] %[[JMPBUF]], i32 1) +; CHECK-NEXT: %[[__THREW__VAL:.*]] = load [[PTR]], ptr @__THREW__ +; CHECK-NEXT: store [[PTR]] 0, ptr @__THREW__ ; CHECK-NEXT: %[[CMP0:.*]] = icmp ne [[PTR]] %__THREW__.val, 0 -; CHECK-NEXT: %[[THREWVALUE_VAL:.*]] = load i32, i32* @__threwValue +; CHECK-NEXT: %[[THREWVALUE_VAL:.*]] = load i32, ptr @__threwValue ; CHECK-NEXT: %[[CMP1:.*]] = icmp ne i32 %[[THREWVALUE_VAL]], 0 ; CHECK-NEXT: %[[CMP:.*]] = and i1 %[[CMP0]], %[[CMP1]] ; CHECK-NEXT: br i1 %[[CMP]], label %if.then1, label %if.else1 @@ -55,9 +50,9 @@ entry: ; CHECK-NEXT: unreachable ; CHECK: if.then1: -; CHECK-NEXT: %[[__THREW__VAL_P:.*]] = inttoptr [[PTR]] %[[__THREW__VAL]] to [[PTR]]* -; CHECK-NEXT: %[[__THREW__VAL_P_LOADED:.*]] = load [[PTR]], [[PTR]]* %[[__THREW__VAL_P]] -; CHECK-NEXT: %[[LABEL:.*]] = call i32 @testSetjmp([[PTR]] %[[__THREW__VAL_P_LOADED]], i32* %[[SETJMP_TABLE1]], i32 %[[SETJMP_TABLE_SIZE1]]) +; CHECK-NEXT: %[[__THREW__VAL_P:.*]] = inttoptr [[PTR]] %[[__THREW__VAL]] to ptr +; CHECK-NEXT: %[[__THREW__VAL_P_LOADED:.*]] = load [[PTR]], ptr %[[__THREW__VAL_P]] +; CHECK-NEXT: %[[LABEL:.*]] = call i32 @testSetjmp([[PTR]] %[[__THREW__VAL_P_LOADED]], ptr %[[SETJMP_TABLE1]], i32 %[[SETJMP_TABLE_SIZE1]]) ; CHECK-NEXT: %[[CMP:.*]] = icmp eq i32 %[[LABEL]], 0 ; CHECK-NEXT: br i1 %[[CMP]], label %call.em.longjmp, label %if.end2 @@ -74,8 +69,7 @@ entry: ; CHECK: call.em.longjmp: ; CHECK-NEXT: %threw.phi = phi [[PTR]] [ %[[__THREW__VAL]], %if.then1 ] ; CHECK-NEXT: %threwvalue.phi = phi i32 [ %[[THREWVALUE_VAL]], %if.then1 ] -; CHECK-NEXT: %{{.*}} = bitcast i32* %[[SETJMP_TABLE1]] to i8* -; CHECK-NEXT: tail call void @free(i8* %{{.*}}) +; CHECK-NEXT: tail call void @free(ptr %[[SETJMP_TABLE1]]) ; CHECK-NEXT: call void @emscripten_longjmp([[PTR]] %threw.phi, i32 %threwvalue.phi) ; CHECK-NEXT: unreachable @@ -89,19 +83,17 @@ define void @setjmp_longjmpable_call() { ; CHECK-LABEL: @setjmp_longjmpable_call entry: %buf = alloca [1 x %struct.__jmp_buf_tag], align 16 - %arraydecay = getelementptr inbounds [1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* %buf, i32 0, i32 0 - %call = call i32 @setjmp(%struct.__jmp_buf_tag* %arraydecay) #0 + %call = call i32 @setjmp(ptr %buf) #0 call void @foo() ret void ; CHECK: entry: -; CHECK: %[[SETJMP_TABLE:.*]] = call i32* @saveSetjmp( +; CHECK: %[[SETJMP_TABLE:.*]] = call ptr @saveSetjmp( ; CHECK: entry.split.split: -; CHECK: @__invoke_void(void ()* @foo) +; CHECK: @__invoke_void(ptr @foo) ; CHECK: entry.split.split.split: -; CHECK-NEXT: %[[BUF:.*]] = bitcast i32* %[[SETJMP_TABLE]] to i8* -; CHECK-NEXT: tail call void @free(i8* %[[BUF]]) +; CHECK-NEXT: tail call void @free(ptr %[[SETJMP_TABLE]]) ; CHECK-NEXT: ret void } @@ -113,30 +105,27 @@ define void @setjmp_multiple_longjmpable_calls() { ; CHECK-LABEL: @setjmp_multiple_longjmpable_calls entry: %buf = alloca [1 x %struct.__jmp_buf_tag], align 16 - %arraydecay = getelementptr inbounds [1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* %buf, i32 0, i32 0 - %call = call i32 @setjmp(%struct.__jmp_buf_tag* %arraydecay) #0 + %call = call i32 @setjmp(ptr %buf) #0 call void @foo() call void @foo() ret void ; CHECK: call.em.longjmp: -; CHECK-NEXT: %threw.phi = phi [[PTR]] [ %__THREW__.val, %if.then1 ], [ %__THREW__.val4, %if.then15 ] -; CHECK-NEXT: %threwvalue.phi = phi i32 [ %__threwValue.val, %if.then1 ], [ %__threwValue.val8, %if.then15 ] -; CHECK-NEXT: %{{.*}} = bitcast i32* %[[SETJMP_TABLE1]] to i8* -; CHECK-NEXT: tail call void @free(i8* %{{.*}}) +; CHECK-NEXT: %threw.phi = phi [[PTR]] [ %__THREW__.val, %if.then1 ], [ %__THREW__.val3, %if.then14 ] +; CHECK-NEXT: %threwvalue.phi = phi i32 [ %__threwValue.val, %if.then1 ], [ %__threwValue.val7, %if.then14 ] +; CHECK-NEXT: tail call void @free(ptr %[[SETJMP_TABLE1]]) ; CHECK-NEXT: call void @emscripten_longjmp([[PTR]] %threw.phi, i32 %threwvalue.phi) ; CHECK-NEXT: unreachable } ; Test a case where a function has a setjmp call but no other calls that can ; longjmp. We don't need to do any transformation in this case. -define i32 @setjmp_only(i8* %ptr) { +define i32 @setjmp_only(ptr %ptr) { ; CHECK-LABEL: @setjmp_only entry: %buf = alloca [1 x %struct.__jmp_buf_tag], align 16 - %arraydecay = getelementptr inbounds [1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* %buf, i32 0, i32 0 - %call = call i32 @setjmp(%struct.__jmp_buf_tag* %arraydecay) #0 + %call = call i32 @setjmp(ptr %buf) #0 ; free cannot longjmp - call void @free(i8* %ptr) + call void @free(ptr %ptr) ret i32 %call ; CHECK: entry: ; CHECK-NOT: @malloc @@ -156,34 +145,31 @@ entry: %cmp = icmp sgt i32 %n, 5 br i1 %cmp, label %if.then, label %if.end ; CHECK: entry: -; CHECK: %[[SETJMP_TABLE0:.*]] = bitcast i8* ; CHECK: %[[SETJMP_TABLE_SIZE0:.*]] = add i32 4, 0 if.then: ; preds = %entry - %0 = load i32, i32* @global_var, align 4 - %arraydecay = getelementptr inbounds [1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* %buf, i32 0, i32 0 - %call = call i32 @setjmp(%struct.__jmp_buf_tag* %arraydecay) #0 - store i32 %0, i32* @global_var, align 4 + %0 = load i32, ptr @global_var, align 4 + %call = call i32 @setjmp(ptr %buf) #0 + store i32 %0, ptr @global_var, align 4 br label %if.end ; CHECK: if.then: -; CHECK: %[[VAR0:.*]] = load i32, i32* @global_var, align 4 -; CHECK: %[[SETJMP_TABLE1:.*]] = call i32* @saveSetjmp( +; CHECK: %[[VAR0:.*]] = load i32, ptr @global_var, align 4 +; CHECK: %[[SETJMP_TABLE1:.*]] = call ptr @saveSetjmp( ; CHECK-NEXT: %[[SETJMP_TABLE_SIZE1:.*]] = call i32 @getTempRet0() ; CHECK: if.then.split: -; CHECK: %[[VAR1:.*]] = phi i32 [ %[[VAR2:.*]], %if.end3 ], [ %[[VAR0]], %if.then ] -; CHECK: %[[SETJMP_TABLE_SIZE2:.*]] = phi i32 [ %[[SETJMP_TABLE_SIZE1]], %if.then ], [ %[[SETJMP_TABLE_SIZE3:.*]], %if.end3 ] -; CHECK: %[[SETJMP_TABLE2:.*]] = phi i32* [ %[[SETJMP_TABLE1]], %if.then ], [ %[[SETJMP_TABLE3:.*]], %if.end3 ] -; CHECK: store i32 %[[VAR1]], i32* @global_var, align 4 +; CHECK: %[[VAR1:.*]] = phi i32 [ %[[VAR2:.*]], %if.end2 ], [ %[[VAR0]], %if.then ] +; CHECK: %[[SETJMP_TABLE_SIZE2:.*]] = phi i32 [ %[[SETJMP_TABLE_SIZE1]], %if.then ], [ %[[SETJMP_TABLE_SIZE3:.*]], %if.end2 ] +; CHECK: %[[SETJMP_TABLE2:.*]] = phi ptr [ %[[SETJMP_TABLE1]], %if.then ], [ %[[SETJMP_TABLE3:.*]], %if.end2 ] +; CHECK: store i32 %[[VAR1]], ptr @global_var, align 4 if.end: ; preds = %if.then, %entry - %arraydecay1 = getelementptr inbounds [1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* %buf, i32 0, i32 0 - call void @longjmp(%struct.__jmp_buf_tag* %arraydecay1, i32 5) #1 + call void @longjmp(ptr %buf, i32 5) #1 unreachable ; CHECK: if.end: ; CHECK: %[[VAR2]] = phi i32 [ %[[VAR1]], %if.then.split ], [ undef, %entry.split ] ; CHECK: %[[SETJMP_TABLE_SIZE3]] = phi i32 [ %[[SETJMP_TABLE_SIZE2]], %if.then.split ], [ %[[SETJMP_TABLE_SIZE0]], %entry.split ] -; CHECK: %[[SETJMP_TABLE3]] = phi i32* [ %[[SETJMP_TABLE2]], %if.then.split ], [ %[[SETJMP_TABLE0]], %entry.split ] +; CHECK: %[[SETJMP_TABLE3]] = phi ptr [ %[[SETJMP_TABLE2]], %if.then.split ], [ %malloccall, %entry.split ] } ; Test a case when a function only calls other functions that are neither setjmp nor longjmp @@ -200,8 +186,7 @@ define void @inline_asm() { ; CHECK-LABEL: @inline_asm entry: %env = alloca [1 x %struct.__jmp_buf_tag], align 16 - %arraydecay = getelementptr inbounds [1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* %env, i32 0, i32 0 - %call = call i32 @setjmp(%struct.__jmp_buf_tag* %arraydecay) #4 + %call = call i32 @setjmp(ptr %env) #4 ; Inline assembly should not generate __invoke wrappers. ; Doing so would fail as inline assembly cannot be passed as a function pointer. ; CHECK: call void asm sideeffect "", ""() @@ -211,16 +196,15 @@ entry: } ; Test that the allocsize attribute is being transformed properly -declare i8 *@allocator(i32, %struct.__jmp_buf_tag*) #3 -define i8 *@allocsize() { +declare ptr @allocator(i32, ptr) #3 +define ptr @allocsize() { ; CHECK-LABEL: @allocsize entry: %buf = alloca [1 x %struct.__jmp_buf_tag], align 16 - %arraydecay = getelementptr inbounds [1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* %buf, i32 0, i32 0 - %call = call i32 @setjmp(%struct.__jmp_buf_tag* %arraydecay) #0 -; CHECK: call cc{{.*}} i8* @"__invoke_i8*_i32_%struct.__jmp_buf_tag*"([[ARGS:.*]]) #[[ALLOCSIZE_ATTR:[0-9]+]] - %alloc = call i8* @allocator(i32 20, %struct.__jmp_buf_tag* %arraydecay) #3 - ret i8 *%alloc + %call = call i32 @setjmp(ptr %buf) #0 +; CHECK: call cc{{.*}} ptr @__invoke_ptr_i32_ptr([[ARGS:.*]]) #[[ALLOCSIZE_ATTR:[0-9]+]] + %alloc = call ptr @allocator(i32 20, ptr %buf) #3 + ret ptr %alloc } ; Test a case when a function only calls longjmp and not setjmp @@ -229,7 +213,7 @@ define void @longjmp_only() { ; CHECK-LABEL: @longjmp_only entry: ; CHECK: call void @emscripten_longjmp - call void @longjmp(%struct.__jmp_buf_tag* getelementptr inbounds ([1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* @buffer, i32 0, i32 0), i32 1) #1 + call void @longjmp(ptr @buffer, i32 1) #1 unreachable } @@ -247,7 +231,7 @@ for.cond: ; preds = %for.inc, %entry br label %for.inc for.inc: ; preds = %for.cond - %call5 = call i32 @setjmp(%struct.__jmp_buf_tag* undef) #0 + %call5 = call i32 @setjmp(ptr undef) #0 br label %for.cond ; CHECK: for.inc.split: @@ -257,30 +241,28 @@ for.inc: ; preds = %for.cond ; Tests cases where longjmp function pointer is used in other ways than direct ; calls. longjmps should be replaced with ; (void(*)(jmp_buf*, int))emscripten_longjmp. -declare void @take_longjmp(void (%struct.__jmp_buf_tag*, i32)* %arg_ptr) +declare void @take_longjmp(ptr %arg_ptr) define void @indirect_longjmp() { ; CHECK-LABEL: @indirect_longjmp entry: - %local_longjmp_ptr = alloca void (%struct.__jmp_buf_tag*, i32)*, align 4 + %local_longjmp_ptr = alloca ptr, align 4 %buf0 = alloca [1 x %struct.__jmp_buf_tag], align 16 %buf1 = alloca [1 x %struct.__jmp_buf_tag], align 16 ; Store longjmp in a local variable, load it, and call it - store void (%struct.__jmp_buf_tag*, i32)* @longjmp, void (%struct.__jmp_buf_tag*, i32)** %local_longjmp_ptr, align 4 - ; CHECK: store void (%struct.__jmp_buf_tag*, i32)* bitcast (void ([[PTR]], i32)* @emscripten_longjmp to void (%struct.__jmp_buf_tag*, i32)*), void (%struct.__jmp_buf_tag*, i32)** %local_longjmp_ptr, align 4 - %longjmp_from_local_ptr = load void (%struct.__jmp_buf_tag*, i32)*, void (%struct.__jmp_buf_tag*, i32)** %local_longjmp_ptr, align 4 - %arraydecay = getelementptr inbounds [1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* %buf0, i32 0, i32 0 - call void %longjmp_from_local_ptr(%struct.__jmp_buf_tag* %arraydecay, i32 0) + store ptr @longjmp, ptr %local_longjmp_ptr, align 4 + ; CHECK: store ptr @emscripten_longjmp, ptr %local_longjmp_ptr, align 4 + %longjmp_from_local_ptr = load ptr, ptr %local_longjmp_ptr, align 4 + call void %longjmp_from_local_ptr(ptr %buf0, i32 0) ; Load longjmp from a global variable and call it - %longjmp_from_global_ptr = load void (%struct.__jmp_buf_tag*, i32)*, void (%struct.__jmp_buf_tag*, i32)** @global_longjmp_ptr, align 4 - %arraydecay1 = getelementptr inbounds [1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* %buf1, i32 0, i32 0 - call void %longjmp_from_global_ptr(%struct.__jmp_buf_tag* %arraydecay1, i32 0) + %longjmp_from_global_ptr = load ptr, ptr @global_longjmp_ptr, align 4 + call void %longjmp_from_global_ptr(ptr %buf1, i32 0) ; Pass longjmp as a function argument. This is a call but longjmp is not a ; callee but an argument. - call void @take_longjmp(void (%struct.__jmp_buf_tag*, i32)* @longjmp) - ; CHECK: call void @take_longjmp(void (%struct.__jmp_buf_tag*, i32)* bitcast (void ([[PTR]], i32)* @emscripten_longjmp to void (%struct.__jmp_buf_tag*, i32)*)) + call void @take_longjmp(ptr @longjmp) + ; CHECK: call void @take_longjmp(ptr @emscripten_longjmp) ret void } @@ -293,33 +275,31 @@ define void @_setjmp__longjmp() { ; CHECK-NOT: call void @_longjmp entry: %buf = alloca [1 x %struct.__jmp_buf_tag], align 16 - %arraydecay = getelementptr inbounds [1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* %buf, i32 0, i32 0 - %call = call i32 @_setjmp(%struct.__jmp_buf_tag* %arraydecay) #0 - %arraydecay1 = getelementptr inbounds [1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* %buf, i32 0, i32 0 - call void @_longjmp(%struct.__jmp_buf_tag* %arraydecay1, i32 1) #1 + %call = call i32 @_setjmp(ptr %buf) #0 + call void @_longjmp(ptr %buf, i32 1) #1 unreachable } ; Function Attrs: nounwind declare void @foo() #2 ; Function Attrs: returns_twice -declare i32 @setjmp(%struct.__jmp_buf_tag*) #0 -declare i32 @_setjmp(%struct.__jmp_buf_tag*) #0 +declare i32 @setjmp(ptr) #0 +declare i32 @_setjmp(ptr) #0 ; Function Attrs: noreturn -declare void @longjmp(%struct.__jmp_buf_tag*, i32) #1 -declare void @_longjmp(%struct.__jmp_buf_tag*, i32) #1 +declare void @longjmp(ptr, i32) #1 +declare void @_longjmp(ptr, i32) #1 declare i32 @__gxx_personality_v0(...) -declare i8* @__cxa_begin_catch(i8*) +declare ptr @__cxa_begin_catch(ptr) declare void @__cxa_end_catch() -declare void @free(i8*) +declare void @free(ptr) ; JS glue functions and invoke wrappers declaration ; CHECK-DAG: declare i32 @getTempRet0() ; CHECK-DAG: declare void @setTempRet0(i32) -; CHECK-DAG: declare i32* @saveSetjmp(%struct.__jmp_buf_tag*, i32, i32*, i32) -; CHECK-DAG: declare i32 @testSetjmp([[PTR]], i32*, i32) +; CHECK-DAG: declare ptr @saveSetjmp(ptr, i32, ptr, i32) +; CHECK-DAG: declare i32 @testSetjmp([[PTR]], ptr, i32) ; CHECK-DAG: declare void @emscripten_longjmp([[PTR]], i32) -; CHECK-DAG: declare void @__invoke_void(void ()*) +; CHECK-DAG: declare void @__invoke_void(ptr) attributes #0 = { returns_twice } attributes #1 = { noreturn } @@ -331,7 +311,7 @@ attributes #3 = { allocsize(0) } ; CHECK-DAG: attributes #{{[0-9]+}} = { "wasm-import-module"="env" "wasm-import-name"="saveSetjmp" } ; CHECK-DAG: attributes #{{[0-9]+}} = { "wasm-import-module"="env" "wasm-import-name"="testSetjmp" } ; CHECK-DAG: attributes #{{[0-9]+}} = { noreturn "wasm-import-module"="env" "wasm-import-name"="emscripten_longjmp" } -; CHECK-DAG: attributes #{{[0-9]+}} = { "wasm-import-module"="env" "wasm-import-name"="__invoke_i8*_i32_%struct.__jmp_buf_tag*" } +; CHECK-DAG: attributes #{{[0-9]+}} = { "wasm-import-module"="env" "wasm-import-name"="__invoke_ptr_i32_ptr" } ; CHECK-DAG: attributes #[[ALLOCSIZE_ATTR]] = { allocsize(1) } !llvm.dbg.cu = !{!2} diff --git a/llvm/test/CodeGen/WebAssembly/lower-wasm-ehsjlj.ll b/llvm/test/CodeGen/WebAssembly/lower-wasm-ehsjlj.ll index 0010d326..03e19c0 100644 --- a/llvm/test/CodeGen/WebAssembly/lower-wasm-ehsjlj.ll +++ b/llvm/test/CodeGen/WebAssembly/lower-wasm-ehsjlj.ll @@ -1,5 +1,5 @@ -; RUN: opt -opaque-pointers=0 < %s -wasm-lower-em-ehsjlj -wasm-enable-eh -wasm-enable-sjlj -S | FileCheck %s -; RUN: llc -opaque-pointers=0 < %s -wasm-enable-eh -wasm-enable-sjlj -exception-model=wasm -mattr=+exception-handling -verify-machineinstrs +; RUN: opt < %s -wasm-lower-em-ehsjlj -wasm-enable-eh -wasm-enable-sjlj -S | FileCheck %s +; RUN: llc < %s -wasm-enable-eh -wasm-enable-sjlj -exception-model=wasm -mattr=+exception-handling -verify-machineinstrs target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" target triple = "wasm32-unknown-unknown" @@ -17,10 +17,10 @@ target triple = "wasm32-unknown-unknown" ; } catch (...) { ; } ; } -define void @setjmp_and_try() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) { +define void @setjmp_and_try() personality ptr @__gxx_wasm_personality_v0 { ; CHECK-LABEL: @setjmp_and_try entry: - %call = call i32 @setjmp(%struct.__jmp_buf_tag* getelementptr inbounds ([1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* @_ZL3buf, i32 0, i32 0)) #0 + %call = call i32 @setjmp(ptr @_ZL3buf) #0 %cmp = icmp ne i32 %call, 0 br i1 %cmp, label %return, label %if.end @@ -34,14 +34,14 @@ catch.dispatch: ; preds = %if.end ; CHECK-NEXT: catchswitch within none [label %catch.start] unwind label %catch.dispatch.longjmp catch.start: ; preds = %catch.dispatch - %1 = catchpad within %0 [i8* null] - %2 = call i8* @llvm.wasm.get.exception(token %1) + %1 = catchpad within %0 [ptr null] + %2 = call ptr @llvm.wasm.get.exception(token %1) %3 = call i32 @llvm.wasm.get.ehselector(token %1) - %4 = call i8* @__cxa_begin_catch(i8* %2) #2 [ "funclet"(token %1) ] + %4 = call ptr @__cxa_begin_catch(ptr %2) #2 [ "funclet"(token %1) ] call void @__cxa_end_catch() [ "funclet"(token %1) ] catchret from %1 to label %return ; CHECK: catch.start: -; CHECK: [[T0:%.*]] = catchpad within {{.*}} [i8* null] +; CHECK: [[T0:%.*]] = catchpad within {{.*}} [ptr null] ; CHECK: invoke void @__cxa_end_catch() [ "funclet"(token [[T0]]) ] ; CHECK-NEXT: to label %.noexc unwind label %catch.dispatch.longjmp @@ -65,21 +65,21 @@ return: ; preds = %catch.start, %if.en ; } catch (...) { ; } ; } -define void @setjmp_within_try() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) { +define void @setjmp_within_try() personality ptr @__gxx_wasm_personality_v0 { ; CHECK-LABEL: @setjmp_within_try entry: %jmpval = alloca i32, align 4 - %exn.slot = alloca i8*, align 4 + %exn.slot = alloca ptr, align 4 invoke void @foo() to label %invoke.cont unwind label %catch.dispatch invoke.cont: ; preds = %entry - %call = invoke i32 @setjmp(%struct.__jmp_buf_tag* getelementptr inbounds ([1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* @_ZL3buf, i32 0, i32 0)) #0 + %call = invoke i32 @setjmp(ptr @_ZL3buf) #0 to label %invoke.cont1 unwind label %catch.dispatch invoke.cont1: ; preds = %invoke.cont - store i32 %call, i32* %jmpval, align 4 - %0 = load i32, i32* %jmpval, align 4 + store i32 %call, ptr %jmpval, align 4 + %0 = load i32, ptr %jmpval, align 4 %cmp = icmp ne i32 %0, 0 br i1 %cmp, label %if.then, label %if.end @@ -96,20 +96,20 @@ catch.dispatch: ; preds = %if.end, %invoke.con ; CHECK: catch.dispatch: ; CHECK: catchswitch within none [label %catch.start] unwind label %catch.dispatch.longjmp catch.start: ; preds = %catch.dispatch - %2 = catchpad within %1 [i8* null] - %3 = call i8* @llvm.wasm.get.exception(token %2) - store i8* %3, i8** %exn.slot, align 4 + %2 = catchpad within %1 [ptr null] + %3 = call ptr @llvm.wasm.get.exception(token %2) + store ptr %3, ptr %exn.slot, align 4 %4 = call i32 @llvm.wasm.get.ehselector(token %2) br label %catch catch: ; preds = %catch.start - %exn = load i8*, i8** %exn.slot, align 4 - %5 = call i8* @__cxa_begin_catch(i8* %exn) #2 [ "funclet"(token %2) ] + %exn = load ptr, ptr %exn.slot, align 4 + %5 = call ptr @__cxa_begin_catch(ptr %exn) #2 [ "funclet"(token %2) ] call void @__cxa_end_catch() [ "funclet"(token %2) ] catchret from %2 to label %catchret.dest ; CHECK: catch: ; preds = %catch.start -; CHECK-NEXT: %exn = load i8*, i8** %exn.slot15, align 4 -; CHECK-NEXT: %5 = call i8* @__cxa_begin_catch(i8* %exn) #7 [ "funclet"(token %2) ] +; CHECK-NEXT: %exn = load ptr, ptr %exn.slot14, align 4 +; CHECK-NEXT: %5 = call ptr @__cxa_begin_catch(ptr %exn) #7 [ "funclet"(token %2) ] ; CHECK-NEXT: invoke void @__cxa_end_catch() [ "funclet"(token %2) ] ; CHECK-NEXT: to label %.noexc unwind label %catch.dispatch.longjmp @@ -140,10 +140,10 @@ invoke.cont2: ; preds = %if.end ; } catch (...) { ; } ; } -define void @setjmp_and_nested_try() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) { +define void @setjmp_and_nested_try() personality ptr @__gxx_wasm_personality_v0 { ; CHECK-LABEL: @setjmp_and_nested_try entry: - %call = call i32 @setjmp(%struct.__jmp_buf_tag* getelementptr inbounds ([1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* @_ZL3buf, i32 0, i32 0)) #0 + %call = call i32 @setjmp(ptr @_ZL3buf) #0 %cmp = icmp ne i32 %call, 0 br i1 %cmp, label %try.cont10, label %if.end @@ -159,10 +159,10 @@ catch.dispatch: ; preds = %invoke.cont %0 = catchswitch within none [label %catch.start] unwind label %catch.dispatch5 catch.start: ; preds = %catch.dispatch - %1 = catchpad within %0 [i8* null] - %2 = call i8* @llvm.wasm.get.exception(token %1) + %1 = catchpad within %0 [ptr null] + %2 = call ptr @llvm.wasm.get.exception(token %1) %3 = call i32 @llvm.wasm.get.ehselector(token %1) - %4 = call i8* @__cxa_begin_catch(i8* %2) #2 [ "funclet"(token %1) ] + %4 = call ptr @__cxa_begin_catch(ptr %2) #2 [ "funclet"(token %1) ] invoke void @foo() [ "funclet"(token %1) ] to label %invoke.cont2 unwind label %ehcleanup @@ -193,17 +193,17 @@ catch.dispatch5: ; preds = %invoke.cont4, %invo ; CHECK-NEXT: catchswitch within none [label %catch.start6] unwind label %catch.dispatch.longjmp catch.start6: ; preds = %catch.dispatch5 - %7 = catchpad within %6 [i8* null] - %8 = call i8* @llvm.wasm.get.exception(token %7) + %7 = catchpad within %6 [ptr null] + %8 = call ptr @llvm.wasm.get.exception(token %7) %9 = call i32 @llvm.wasm.get.ehselector(token %7) - %10 = call i8* @__cxa_begin_catch(i8* %8) #2 [ "funclet"(token %7) ] + %10 = call ptr @__cxa_begin_catch(ptr %8) #2 [ "funclet"(token %7) ] call void @__cxa_end_catch() [ "funclet"(token %7) ] catchret from %7 to label %try.cont10 ; CHECK: catch.start6: -; CHECK-NEXT: [[T1:%.*]] = catchpad within {{.*}} [i8* null] -; CHECK-NEXT: call i8* @llvm.wasm.get.exception(token [[T1]]) +; CHECK-NEXT: [[T1:%.*]] = catchpad within {{.*}} [ptr null] +; CHECK-NEXT: call ptr @llvm.wasm.get.exception(token [[T1]]) ; CHECK-NEXT: call i32 @llvm.wasm.get.ehselector(token [[T1]]) -; CHECK-NEXT: call i8* @__cxa_begin_catch(i8* {{.*}}) {{.*}} [ "funclet"(token [[T1]]) ] +; CHECK-NEXT: call ptr @__cxa_begin_catch(ptr {{.*}}) {{.*}} [ "funclet"(token [[T1]]) ] ; CHECK: invoke void @__cxa_end_catch() [ "funclet"(token [[T1]]) ] ; CHECK-NEXT: to label %.noexc unwind label %catch.dispatch.longjmp @@ -230,9 +230,9 @@ terminate: ; preds = %ehcleanup ; change to an invoke whose unwind destination is determined by its parent ; chain. ; CHECK-NEXT: invoke void @terminate() {{.*}} [ "funclet"(token [[T2]]) ] -; CHECK-NEXT: to label %.noexc4 unwind label %catch.dispatch5 +; CHECK-NEXT: to label %.noexc3 unwind label %catch.dispatch5 -; CHECK: .noexc4: +; CHECK: .noexc3: ; CHECK-NEXT: unreachable ; CHECK: catch.dispatch.longjmp: @@ -244,17 +244,16 @@ terminate: ; preds = %ehcleanup ; Temp t; ; setjmp(buf); ; } -define void @cleanuppad_no_parent() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) { +define void @cleanuppad_no_parent() personality ptr @__gxx_wasm_personality_v0 { ; CHECK-LABEL: @cleanuppad_no_parent entry: %buf = alloca [1 x %struct.__jmp_buf_tag], align 16 %t = alloca %struct.Temp, align 1 - %arraydecay = getelementptr inbounds [1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* %buf, i32 0, i32 0 - %call = invoke i32 @setjmp(%struct.__jmp_buf_tag* noundef %arraydecay) #0 + %call = invoke i32 @setjmp(ptr noundef %buf) #0 to label %invoke.cont unwind label %ehcleanup invoke.cont: ; preds = %entry - %call1 = call noundef %struct.Temp* @_ZN4TempD2Ev(%struct.Temp* noundef %t) #2 + %call1 = call noundef ptr @_ZN4TempD2Ev(ptr noundef %t) #2 ret void ehcleanup: ; preds = %entry @@ -265,8 +264,8 @@ ehcleanup: ; preds = %entry ; first to preserve the scoping structure. But this call's parent is %0 ; (cleanuppad), whose parent is 'none', so we should unwind directly to ; %catch.dispatch.longjmp. - %call2 = call noundef %struct.Temp* @_ZN4TempD2Ev(%struct.Temp* noundef %t) #2 [ "funclet"(token %0) ] -; CHECK: %call13 = invoke {{.*}} %struct.Temp* @_ZN4TempD2Ev(%struct.Temp* + %call2 = call noundef ptr @_ZN4TempD2Ev(ptr noundef %t) #2 [ "funclet"(token %0) ] +; CHECK: %call23 = invoke {{.*}} ptr @_ZN4TempD2Ev(ptr ; CHECK-NEXT: to label {{.*}} unwind label %catch.dispatch.longjmp cleanupret from %0 unwind to caller } @@ -274,12 +273,11 @@ ehcleanup: ; preds = %entry ; This case was adapted from @cleanuppad_no_parent by removing allocas and ; destructor calls, to generate a situation that there's only 'invoke @setjmp' ; and no other longjmpable calls. -define i32 @setjmp_only() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) { +define i32 @setjmp_only() personality ptr @__gxx_wasm_personality_v0 { ; CHECK-LABEL: @setjmp_only entry: %buf = alloca [1 x %struct.__jmp_buf_tag], align 16 - %arraydecay = getelementptr inbounds [1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* %buf, i32 0, i32 0 - %call = invoke i32 @setjmp(%struct.__jmp_buf_tag* noundef %arraydecay) #0 + %call = invoke i32 @setjmp(ptr noundef %buf) #0 to label %invoke.cont unwind label %ehcleanup invoke.cont: ; preds = %entry @@ -296,17 +294,17 @@ ehcleanup: ; preds = %entry declare void @foo() ; Function Attrs: nounwind -declare %struct.Temp* @_ZN4TempD2Ev(%struct.Temp* %this) #2 +declare ptr @_ZN4TempD2Ev(ptr %this) #2 ; Function Attrs: returns_twice -declare i32 @setjmp(%struct.__jmp_buf_tag*) #0 +declare i32 @setjmp(ptr) #0 ; Function Attrs: noreturn -declare void @longjmp(%struct.__jmp_buf_tag*, i32) #1 +declare void @longjmp(ptr, i32) #1 declare i32 @__gxx_wasm_personality_v0(...) ; Function Attrs: nounwind -declare i8* @llvm.wasm.get.exception(token) #2 +declare ptr @llvm.wasm.get.exception(token) #2 ; Function Attrs: nounwind declare i32 @llvm.wasm.get.ehselector(token) #2 -declare i8* @__cxa_begin_catch(i8*) +declare ptr @__cxa_begin_catch(ptr) declare void @__cxa_end_catch() declare void @terminate() diff --git a/llvm/test/CodeGen/WebAssembly/lower-wasm-sjlj.ll b/llvm/test/CodeGen/WebAssembly/lower-wasm-sjlj.ll index 6adf261..e303770 100644 --- a/llvm/test/CodeGen/WebAssembly/lower-wasm-sjlj.ll +++ b/llvm/test/CodeGen/WebAssembly/lower-wasm-sjlj.ll @@ -1,6 +1,6 @@ -; RUN: opt -opaque-pointers=0 < %s -wasm-lower-em-ehsjlj -wasm-enable-sjlj -S | FileCheck %s -DPTR=i32 -; RUN: opt -opaque-pointers=0 < %s -wasm-lower-em-ehsjlj -wasm-enable-sjlj -S --mattr=+atomics,+bulk-memory | FileCheck %s -DPTR=i32 -; RUN: opt -opaque-pointers=0 < %s -wasm-lower-em-ehsjlj -wasm-enable-sjlj --mtriple=wasm64-unknown-unknown -data-layout="e-m:e-p:64:64-i64:64-n32:64-S128" -S | FileCheck %s -DPTR=i64 +; RUN: opt < %s -wasm-lower-em-ehsjlj -wasm-enable-sjlj -S | FileCheck %s -DPTR=i32 +; RUN: opt < %s -wasm-lower-em-ehsjlj -wasm-enable-sjlj -S --mattr=+atomics,+bulk-memory | FileCheck %s -DPTR=i32 +; RUN: opt < %s -wasm-lower-em-ehsjlj -wasm-enable-sjlj --mtriple=wasm64-unknown-unknown -data-layout="e-m:e-p:64:64-i64:64-n32:64-S128" -S | FileCheck %s -DPTR=i64 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" target triple = "wasm32-unknown-unknown" @@ -12,32 +12,29 @@ target triple = "wasm32-unknown-unknown" ; CHECK-NOT: @__THREW__ = ; CHECK-NOT: @__threwValue = -@global_longjmp_ptr = global void (%struct.__jmp_buf_tag*, i32)* @longjmp, align 4 -; CHECK-DAG: @global_longjmp_ptr = global void (%struct.__jmp_buf_tag*, i32)* bitcast (void (i8*, i32)* @__wasm_longjmp to void (%struct.__jmp_buf_tag*, i32)*) +@global_longjmp_ptr = global ptr @longjmp, align 4 +; CHECK-DAG: @global_longjmp_ptr = global ptr @__wasm_longjmp ; Test a simple setjmp - longjmp sequence define void @setjmp_longjmp() { ; CHECK-LABEL: @setjmp_longjmp() entry: %buf = alloca [1 x %struct.__jmp_buf_tag], align 16 - %arraydecay = getelementptr inbounds [1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* %buf, i32 0, i32 0 - %call = call i32 @setjmp(%struct.__jmp_buf_tag* %arraydecay) #0 - %arraydecay1 = getelementptr inbounds [1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* %buf, i32 0, i32 0 - call void @longjmp(%struct.__jmp_buf_tag* %arraydecay1, i32 1) #1 + %call = call i32 @setjmp(ptr %buf) #0 + call void @longjmp(ptr %buf, i32 1) #1 unreachable ; CHECK: entry: -; CHECK-NEXT: %malloccall = tail call i8* @malloc([[PTR]] 40) -; CHECK-NEXT: %setjmpTable = bitcast i8* %malloccall to i32* -; CHECK-NEXT: store i32 0, i32* %setjmpTable, align 4 +; CHECK-NEXT: %malloccall = tail call ptr @malloc([[PTR]] 40) +; CHECK-NEXT: store i32 0, ptr %malloccall, align 4 ; CHECK-NEXT: %setjmpTableSize = add i32 4, 0 ; CHECK-NEXT: br label %setjmp.dispatch ; CHECK: setjmp.dispatch: -; CHECK-NEXT: %val10 = phi i32 [ %val, %if.end ], [ undef, %entry ] -; CHECK-NEXT: %buf9 = phi [1 x %struct.__jmp_buf_tag]* [ %buf8, %if.end ], [ undef, %entry ] -; CHECK-NEXT: %setjmpTableSize6 = phi i32 [ %setjmpTableSize7, %if.end ], [ %setjmpTableSize, %entry ] -; CHECK-NEXT: %setjmpTable4 = phi i32* [ %setjmpTable5, %if.end ], [ %setjmpTable, %entry ] +; CHECK-NEXT: %val8 = phi i32 [ %val, %if.end ], [ undef, %entry ] +; CHECK-NEXT: %buf7 = phi ptr [ %buf6, %if.end ], [ undef, %entry ] +; CHECK-NEXT: %setjmpTableSize4 = phi i32 [ %setjmpTableSize5, %if.end ], [ %setjmpTableSize, %entry ] +; CHECK-NEXT: %setjmpTable2 = phi ptr [ %setjmpTable3, %if.end ], [ %malloccall, %entry ] ; CHECK-NEXT: %label.phi = phi i32 [ %label, %if.end ], [ -1, %entry ] ; CHECK-NEXT: switch i32 %label.phi, label %entry.split [ ; CHECK-NEXT: i32 1, label %entry.split.split @@ -45,19 +42,16 @@ entry: ; CHECK: entry.split: ; CHECK-NEXT: %buf = alloca [1 x %struct.__jmp_buf_tag], align 16 -; CHECK-NEXT: %arraydecay = getelementptr inbounds [1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* %buf, i32 0, i32 0 -; CHECK-NEXT: %setjmpTable1 = call i32* @saveSetjmp(%struct.__jmp_buf_tag* %arraydecay, i32 1, i32* %setjmpTable4, i32 %setjmpTableSize6) -; CHECK-NEXT: %setjmpTableSize2 = call i32 @getTempRet0() +; CHECK-NEXT: %setjmpTable = call ptr @saveSetjmp(ptr %buf, i32 1, ptr %setjmpTable2, i32 %setjmpTableSize4) +; CHECK-NEXT: %setjmpTableSize1 = call i32 @getTempRet0() ; CHECK-NEXT: br label %entry.split.split ; CHECK: entry.split.split: -; CHECK-NEXT: %buf8 = phi [1 x %struct.__jmp_buf_tag]* [ %buf9, %setjmp.dispatch ], [ %buf, %entry.split ] -; CHECK-NEXT: %setjmpTableSize7 = phi i32 [ %setjmpTableSize2, %entry.split ], [ %setjmpTableSize6, %setjmp.dispatch ] -; CHECK-NEXT: %setjmpTable5 = phi i32* [ %setjmpTable1, %entry.split ], [ %setjmpTable4, %setjmp.dispatch ] -; CHECK-NEXT: %setjmp.ret = phi i32 [ 0, %entry.split ], [ %val10, %setjmp.dispatch ] -; CHECK-NEXT: %arraydecay1 = getelementptr inbounds [1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* %buf8, i32 0, i32 0 -; CHECK-NEXT: %env = bitcast %struct.__jmp_buf_tag* %arraydecay1 to i8* -; CHECK-NEXT: invoke void @__wasm_longjmp(i8* %env, i32 1) +; CHECK-NEXT: %buf6 = phi ptr [ %buf7, %setjmp.dispatch ], [ %buf, %entry.split ] +; CHECK-NEXT: %setjmpTableSize5 = phi i32 [ %setjmpTableSize1, %entry.split ], [ %setjmpTableSize4, %setjmp.dispatch ] +; CHECK-NEXT: %setjmpTable3 = phi ptr [ %setjmpTable, %entry.split ], [ %setjmpTable2, %setjmp.dispatch ] +; CHECK-NEXT: %setjmp.ret = phi i32 [ 0, %entry.split ], [ %val8, %setjmp.dispatch ] +; CHECK-NEXT: invoke void @__wasm_longjmp(ptr %buf6, i32 1) ; CHECK-NEXT: to label %.noexc unwind label %catch.dispatch.longjmp ; CHECK: .noexc: @@ -68,22 +62,19 @@ entry: ; CHECK: catch.longjmp: ; CHECK-NEXT: %1 = catchpad within %0 [] -; CHECK-NEXT: %thrown = call i8* @llvm.wasm.catch(i32 1) -; CHECK-NEXT: %longjmp.args = bitcast i8* %thrown to { i8*, i32 }* -; CHECK-NEXT: %env_gep = getelementptr { i8*, i32 }, { i8*, i32 }* %longjmp.args, i32 0, i32 0 -; CHECK-NEXT: %val_gep = getelementptr { i8*, i32 }, { i8*, i32 }* %longjmp.args, i32 0, i32 1 -; CHECK-NEXT: %env3 = load i8*, i8** %env_gep, align {{.*}} -; CHECK-NEXT: %val = load i32, i32* %val_gep, align 4 -; CHECK-NEXT: %env.p = bitcast i8* %env3 to [[PTR]]* -; CHECK-NEXT: %setjmp.id = load [[PTR]], [[PTR]]* %env.p, align {{.*}} -; CHECK-NEXT: %label = call i32 @testSetjmp([[PTR]] %setjmp.id, i32* %setjmpTable5, i32 %setjmpTableSize7) [ "funclet"(token %1) ] +; CHECK-NEXT: %thrown = call ptr @llvm.wasm.catch(i32 1) +; CHECK-NEXT: %env_gep = getelementptr { ptr, i32 }, ptr %thrown, i32 0, i32 0 +; CHECK-NEXT: %val_gep = getelementptr { ptr, i32 }, ptr %thrown, i32 0, i32 1 +; CHECK-NEXT: %env = load ptr, ptr %env_gep, align {{.*}} +; CHECK-NEXT: %val = load i32, ptr %val_gep, align 4 +; CHECK-NEXT: %setjmp.id = load [[PTR]], ptr %env, align {{.*}} +; CHECK-NEXT: %label = call i32 @testSetjmp([[PTR]] %setjmp.id, ptr %setjmpTable3, i32 %setjmpTableSize5) [ "funclet"(token %1) ] ; CHECK-NEXT: %2 = icmp eq i32 %label, 0 ; CHECK-NEXT: br i1 %2, label %if.then, label %if.end ; CHECK: if.then: -; CHECK-NEXT: %3 = bitcast i32* %setjmpTable5 to i8* -; CHECK-NEXT: tail call void @free(i8* %3) [ "funclet"(token %1) ] -; CHECK-NEXT: call void @__wasm_longjmp(i8* %env3, i32 %val) [ "funclet"(token %1) ] +; CHECK-NEXT: tail call void @free(ptr %setjmpTable3) [ "funclet"(token %1) ] +; CHECK-NEXT: call void @__wasm_longjmp(ptr %env, i32 %val) [ "funclet"(token %1) ] ; CHECK-NEXT: unreachable ; CHECK: if.end: @@ -97,8 +88,7 @@ define void @setjmp_multiple_longjmpable_calls() { ; CHECK-LABEL: @setjmp_multiple_longjmpable_calls entry: %buf = alloca [1 x %struct.__jmp_buf_tag], align 16 - %arraydecay = getelementptr inbounds [1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* %buf, i32 0, i32 0 - %call = call i32 @setjmp(%struct.__jmp_buf_tag* %arraydecay) #0 + %call = call i32 @setjmp(ptr %buf) #0 call void @foo() call void @foo() ret void @@ -114,30 +104,28 @@ entry: ; Tests cases where longjmp function pointer is used in other ways than direct ; calls. longjmps should be replaced with (void(*)(jmp_buf*, int))__wasm_longjmp. -declare void @take_longjmp(void (%struct.__jmp_buf_tag*, i32)* %arg_ptr) +declare void @take_longjmp(ptr %arg_ptr) define void @indirect_longjmp() { ; CHECK-LABEL: @indirect_longjmp entry: - %local_longjmp_ptr = alloca void (%struct.__jmp_buf_tag*, i32)*, align 4 + %local_longjmp_ptr = alloca ptr, align 4 %buf0 = alloca [1 x %struct.__jmp_buf_tag], align 16 %buf1 = alloca [1 x %struct.__jmp_buf_tag], align 16 ; Store longjmp in a local variable, load it, and call it - store void (%struct.__jmp_buf_tag*, i32)* @longjmp, void (%struct.__jmp_buf_tag*, i32)** %local_longjmp_ptr, align 4 - ; CHECK: store void (%struct.__jmp_buf_tag*, i32)* bitcast (void (i8*, i32)* @__wasm_longjmp to void (%struct.__jmp_buf_tag*, i32)*), void (%struct.__jmp_buf_tag*, i32)** %local_longjmp_ptr, align 4 - %longjmp_from_local_ptr = load void (%struct.__jmp_buf_tag*, i32)*, void (%struct.__jmp_buf_tag*, i32)** %local_longjmp_ptr, align 4 - %arraydecay = getelementptr inbounds [1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* %buf0, i32 0, i32 0 - call void %longjmp_from_local_ptr(%struct.__jmp_buf_tag* %arraydecay, i32 0) + store ptr @longjmp, ptr %local_longjmp_ptr, align 4 + ; CHECK: store ptr @__wasm_longjmp, ptr %local_longjmp_ptr, align 4 + %longjmp_from_local_ptr = load ptr, ptr %local_longjmp_ptr, align 4 + call void %longjmp_from_local_ptr(ptr %buf0, i32 0) ; Load longjmp from a global variable and call it - %longjmp_from_global_ptr = load void (%struct.__jmp_buf_tag*, i32)*, void (%struct.__jmp_buf_tag*, i32)** @global_longjmp_ptr, align 4 - %arraydecay1 = getelementptr inbounds [1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* %buf1, i32 0, i32 0 - call void %longjmp_from_global_ptr(%struct.__jmp_buf_tag* %arraydecay1, i32 0) + %longjmp_from_global_ptr = load ptr, ptr @global_longjmp_ptr, align 4 + call void %longjmp_from_global_ptr(ptr %buf1, i32 0) ; Pass longjmp as a function argument. This is a call but longjmp is not a ; callee but an argument. - call void @take_longjmp(void (%struct.__jmp_buf_tag*, i32)* @longjmp) - ; CHECK: call void @take_longjmp(void (%struct.__jmp_buf_tag*, i32)* bitcast (void (i8*, i32)* @__wasm_longjmp to void (%struct.__jmp_buf_tag*, i32)*)) + call void @take_longjmp(ptr @longjmp) + ; CHECK: call void @take_longjmp(ptr @__wasm_longjmp) ret void } @@ -146,19 +134,19 @@ declare void @foo() #2 ; The pass removes the 'nounwind' attribute, so there should be no attributes ; CHECK-NOT: declare void @foo #{{.*}} ; Function Attrs: returns_twice -declare i32 @setjmp(%struct.__jmp_buf_tag*) #0 +declare i32 @setjmp(ptr) #0 ; Function Attrs: noreturn -declare void @longjmp(%struct.__jmp_buf_tag*, i32) #1 +declare void @longjmp(ptr, i32) #1 declare i32 @__gxx_personality_v0(...) -declare i8* @__cxa_begin_catch(i8*) +declare ptr @__cxa_begin_catch(ptr) declare void @__cxa_end_catch() -declare void @free(i8*) +declare void @free(ptr) ; JS glue function declarations ; CHECK-DAG: declare i32 @getTempRet0() -; CHECK-DAG: declare i32* @saveSetjmp(%struct.__jmp_buf_tag*, i32, i32*, i32) -; CHECK-DAG: declare i32 @testSetjmp([[PTR]], i32*, i32) -; CHECK-DAG: declare void @__wasm_longjmp(i8*, i32) +; CHECK-DAG: declare ptr @saveSetjmp(ptr, i32, ptr, i32) +; CHECK-DAG: declare i32 @testSetjmp([[PTR]], ptr, i32) +; CHECK-DAG: declare void @__wasm_longjmp(ptr, i32) attributes #0 = { returns_twice } attributes #1 = { noreturn } diff --git a/llvm/test/CodeGen/WebAssembly/wasmehprepare.ll b/llvm/test/CodeGen/WebAssembly/wasmehprepare.ll index 93cb008..a418eb4 100644 --- a/llvm/test/CodeGen/WebAssembly/wasmehprepare.ll +++ b/llvm/test/CodeGen/WebAssembly/wasmehprepare.ll @@ -1,12 +1,12 @@ -; RUN: opt -opaque-pointers=0 < %s -winehprepare -demote-catchswitch-only -wasmehprepare -S | FileCheck %s -; RUN: opt -opaque-pointers=0 < %s -winehprepare -demote-catchswitch-only -wasmehprepare -S --mattr=+atomics,+bulk-memory | FileCheck %s +; RUN: opt < %s -winehprepare -demote-catchswitch-only -wasmehprepare -S | FileCheck %s +; RUN: opt < %s -winehprepare -demote-catchswitch-only -wasmehprepare -S --mattr=+atomics,+bulk-memory | FileCheck %s target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" target triple = "wasm32-unknown-unknown" -; CHECK: @__wasm_lpad_context = external thread_local global { i32, i8*, i32 } +; CHECK: @__wasm_lpad_context = external thread_local global { i32, ptr, i32 } -@_ZTIi = external constant i8* +@_ZTIi = external constant ptr %struct.Temp = type { i8 } ; A single 'catch (int)' clause. @@ -20,7 +20,7 @@ target triple = "wasm32-unknown-unknown" ; } catch (int) { ; } ; } -define void @test0() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) { +define void @test0() personality ptr @__gxx_wasm_personality_v0 { ; CHECK-LABEL: @test0() entry: invoke void @foo() @@ -30,29 +30,29 @@ catch.dispatch: ; preds = %entry %0 = catchswitch within none [label %catch.start] unwind to caller catch.start: ; preds = %catch.dispatch - %1 = catchpad within %0 [i8* bitcast (i8** @_ZTIi to i8*)] - %2 = call i8* @llvm.wasm.get.exception(token %1) + %1 = catchpad within %0 [ptr @_ZTIi] + %2 = call ptr @llvm.wasm.get.exception(token %1) %3 = call i32 @llvm.wasm.get.ehselector(token %1) - %4 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*)) + %4 = call i32 @llvm.eh.typeid.for(ptr @_ZTIi) %matches = icmp eq i32 %3, %4 br i1 %matches, label %catch, label %rethrow ; CHECK: catch.start: ; CHECK-NEXT: %[[CATCHPAD:.*]] = catchpad -; CHECK-NEXT: %[[EXN:.*]] = call i8* @llvm.wasm.catch(i32 0) +; CHECK-NEXT: %[[EXN:.*]] = call ptr @llvm.wasm.catch(i32 0) ; CHECK-NEXT: call void @llvm.wasm.landingpad.index(token %[[CATCHPAD]], i32 0) -; CHECK-NEXT: store i32 0, i32* getelementptr inbounds ({ i32, i8*, i32 }, { i32, i8*, i32 }* @__wasm_lpad_context, i32 0, i32 0) -; CHECK-NEXT: %[[LSDA:.*]] = call i8* @llvm.wasm.lsda() -; CHECK-NEXT: store i8* %[[LSDA]], i8** getelementptr inbounds ({ i32, i8*, i32 }, { i32, i8*, i32 }* @__wasm_lpad_context, i32 0, i32 1) -; CHECK-NEXT: call i32 @_Unwind_CallPersonality(i8* %[[EXN]]) {{.*}} [ "funclet"(token %[[CATCHPAD]]) ] -; CHECK-NEXT: %[[SELECTOR:.*]] = load i32, i32* getelementptr inbounds ({ i32, i8*, i32 }, { i32, i8*, i32 }* @__wasm_lpad_context, i32 0, i32 2) +; CHECK-NEXT: store i32 0, ptr @__wasm_lpad_context +; CHECK-NEXT: %[[LSDA:.*]] = call ptr @llvm.wasm.lsda() +; CHECK-NEXT: store ptr %[[LSDA]], ptr getelementptr inbounds ({ i32, ptr, i32 }, ptr @__wasm_lpad_context, i32 0, i32 1) +; CHECK-NEXT: call i32 @_Unwind_CallPersonality(ptr %[[EXN]]) {{.*}} [ "funclet"(token %[[CATCHPAD]]) ] +; CHECK-NEXT: %[[SELECTOR:.*]] = load i32, ptr getelementptr inbounds ({ i32, ptr, i32 }, ptr @__wasm_lpad_context, i32 0, i32 2) ; CHECK: icmp eq i32 %[[SELECTOR]] catch: ; preds = %catch.start - %5 = call i8* @__cxa_begin_catch(i8* %2) [ "funclet"(token %1) ] + %5 = call ptr @__cxa_begin_catch(ptr %2) [ "funclet"(token %1) ] call void @__cxa_end_catch() [ "funclet"(token %1) ] catchret from %1 to label %try.cont ; CHECK: catch: -; CHECK-NEXT: call i8* @__cxa_begin_catch(i8* %[[EXN]]) +; CHECK-NEXT: call ptr @__cxa_begin_catch(ptr %[[EXN]]) rethrow: ; preds = %catch.start call void @llvm.wasm.rethrow() [ "funclet"(token %1) ] @@ -79,7 +79,7 @@ try.cont: ; preds = %entry, %catch ; } catch (int) { ; } ; } -define void @test1() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) { +define void @test1() personality ptr @__gxx_wasm_personality_v0 { ; CHECK-LABEL: @test1() entry: invoke void @foo() @@ -89,17 +89,17 @@ catch.dispatch: ; preds = %entry %0 = catchswitch within none [label %catch.start] unwind to caller catch.start: ; preds = %catch.dispatch - %1 = catchpad within %0 [i8* null] - %2 = call i8* @llvm.wasm.get.exception(token %1) + %1 = catchpad within %0 [ptr null] + %2 = call ptr @llvm.wasm.get.exception(token %1) %3 = call i32 @llvm.wasm.get.ehselector(token %1) - %4 = call i8* @__cxa_begin_catch(i8* %2) [ "funclet"(token %1) ] + %4 = call ptr @__cxa_begin_catch(ptr %2) [ "funclet"(token %1) ] call void @__cxa_end_catch() [ "funclet"(token %1) ] catchret from %1 to label %try.cont ; CHECK: catch.start: -; CHECK-NEXT: catchpad within %0 [i8* null] +; CHECK-NEXT: catchpad within %0 [ptr null] ; CHECK-NOT: call void @llvm.wasm.landingpad.index ; CHECK-NOT: store {{.*}} @__wasm_lpad_context -; CHECK-NOT: call i8* @llvm.wasm.lsda() +; CHECK-NOT: call ptr @llvm.wasm.lsda() ; CHECK-NOT: call i32 @_Unwind_CallPersonality ; CHECK-NOT: load {{.*}} @__wasm_lpad_context @@ -111,17 +111,17 @@ catch.dispatch2: ; preds = %try.cont %5 = catchswitch within none [label %catch.start3] unwind to caller catch.start3: ; preds = %catch.dispatch2 - %6 = catchpad within %5 [i8* bitcast (i8** @_ZTIi to i8*)] - %7 = call i8* @llvm.wasm.get.exception(token %6) + %6 = catchpad within %5 [ptr @_ZTIi] + %7 = call ptr @llvm.wasm.get.exception(token %6) %8 = call i32 @llvm.wasm.get.ehselector(token %6) - %9 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*)) + %9 = call i32 @llvm.eh.typeid.for(ptr @_ZTIi) %matches = icmp eq i32 %8, %9 br i1 %matches, label %catch4, label %rethrow ; CHECK: catch.start3: ; CHECK: call void @llvm.wasm.landingpad.index(token %{{.+}}, i32 0) catch4: ; preds = %catch.start3 - %10 = call i8* @__cxa_begin_catch(i8* %7) [ "funclet"(token %6) ] + %10 = call ptr @__cxa_begin_catch(ptr %7) [ "funclet"(token %6) ] call void @__cxa_end_catch() [ "funclet"(token %6) ] catchret from %6 to label %try.cont7 @@ -162,7 +162,7 @@ try.cont7: ; preds = %try.cont, %catch4 ; bar(num); ; } ; } -define void @test2() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) { +define void @test2() personality ptr @__gxx_wasm_personality_v0 { ; CHECK-LABEL: @test2 entry: %t = alloca %struct.Temp, align 1 @@ -174,13 +174,13 @@ invoke.cont: ; preds = %entry to label %invoke.cont1 unwind label %ehcleanup invoke.cont1: ; preds = %invoke.cont - %call = call %struct.Temp* @_ZN4TempD2Ev(%struct.Temp* %t) + %call = call ptr @_ZN4TempD2Ev(ptr %t) br label %try.cont ehcleanup: ; preds = %invoke.cont, %entry %num.0 = phi i32 [ 2, %invoke.cont ], [ 1, %entry ] %0 = cleanuppad within none [] - %call2 = call %struct.Temp* @_ZN4TempD2Ev(%struct.Temp* %t) [ "funclet"(token %0) ] + %call2 = call ptr @_ZN4TempD2Ev(ptr %t) [ "funclet"(token %0) ] cleanupret from %0 unwind label %catch.dispatch ; CHECK: ehcleanup: ; CHECK-NEXT: = phi @@ -189,10 +189,10 @@ catch.dispatch: ; preds = %ehcleanup %1 = catchswitch within none [label %catch.start] unwind to caller catch.start: ; preds = %catch.dispatch - %2 = catchpad within %1 [i8* null] - %3 = call i8* @llvm.wasm.get.exception(token %2) + %2 = catchpad within %1 [ptr null] + %3 = call ptr @llvm.wasm.get.exception(token %2) %4 = call i32 @llvm.wasm.get.ehselector(token %2) - %5 = call i8* @__cxa_begin_catch(i8* %3) [ "funclet"(token %2) ] + %5 = call ptr @__cxa_begin_catch(ptr %3) [ "funclet"(token %2) ] call void @bar(i32 %num.0) [ "funclet"(token %2) ] call void @__cxa_end_catch() [ "funclet"(token %2) ] catchret from %2 to label %try.cont @@ -212,10 +212,10 @@ catch.dispatch5: ; preds = %invoke.cont3, %try. ; CHECK-NOT: = phi catch.start6: ; preds = %catch.dispatch5 - %7 = catchpad within %6 [i8* null] - %8 = call i8* @llvm.wasm.get.exception(token %7) + %7 = catchpad within %6 [ptr null] + %8 = call ptr @llvm.wasm.get.exception(token %7) %9 = call i32 @llvm.wasm.get.ehselector(token %7) - %10 = call i8* @__cxa_begin_catch(i8* %8) [ "funclet"(token %7) ] + %10 = call ptr @__cxa_begin_catch(ptr %8) [ "funclet"(token %7) ] call void @bar(i32 %num.1) [ "funclet"(token %7) ] call void @__cxa_end_catch() [ "funclet"(token %7) ] catchret from %7 to label %try.cont10 @@ -228,15 +228,15 @@ try.cont10: ; preds = %invoke.cont3, %catc ; BB's dead children are deleted. ; CHECK-LABEL: @test3 -define i32 @test3(i1 %b, i8* %p) { +define i32 @test3(i1 %b, ptr %p) { entry: br i1 %b, label %bb.true, label %bb.false ; CHECK: bb.true: -; CHECK-NEXT: call void @llvm.wasm.throw(i32 0, i8* %p) +; CHECK-NEXT: call void @llvm.wasm.throw(i32 0, ptr %p) ; CHECK-NEXT: unreachable bb.true: ; preds = %entry - call void @llvm.wasm.throw(i32 0, i8* %p) + call void @llvm.wasm.throw(i32 0, ptr %p) br label %bb.true.0 ; CHECK-NOT: bb.true.0 @@ -254,19 +254,19 @@ merge: ; preds = %bb.true.0, %bb.fals declare void @foo() declare void @bar(i32) -declare %struct.Temp* @_ZN4TempD2Ev(%struct.Temp* returned) +declare ptr @_ZN4TempD2Ev(ptr returned) declare i32 @__gxx_wasm_personality_v0(...) ; Function Attrs: nounwind -declare i8* @llvm.wasm.get.exception(token) #0 +declare ptr @llvm.wasm.get.exception(token) #0 ; Function Attrs: nounwind declare i32 @llvm.wasm.get.ehselector(token) #0 ; Function Attrs: nounwind -declare i32 @llvm.eh.typeid.for(i8*) #0 +declare i32 @llvm.eh.typeid.for(ptr) #0 ; Function Attrs: noreturn -declare void @llvm.wasm.throw(i32, i8*) #1 +declare void @llvm.wasm.throw(i32, ptr) #1 ; Function Attrs: noreturn declare void @llvm.wasm.rethrow() #1 -declare i8* @__cxa_begin_catch(i8*) +declare ptr @__cxa_begin_catch(ptr) declare void @__cxa_end_catch() declare void @_ZSt9terminatev() @@ -274,5 +274,5 @@ attributes #0 = { nounwind } attributes #1 = { noreturn } ; CHECK-DAG: declare void @llvm.wasm.landingpad.index(token, i32 immarg) -; CHECK-DAG: declare i8* @llvm.wasm.lsda() -; CHECK-DAG: declare i32 @_Unwind_CallPersonality(i8*) +; CHECK-DAG: declare ptr @llvm.wasm.lsda() +; CHECK-DAG: declare i32 @_Unwind_CallPersonality(ptr) -- 2.7.4