EHTerminateScope is used to implement C++ noexcept semantics. Per C++ [except.terminate], it is implemented-defined whether no, some, or all cleanups are run prior to terminatation. Therefore, the code to run cleanups on the way towards termination is unnecessary, and may be omitted. After this change, we will still run some cleanups: any cleanups in a function called from the noexcept function will continue to run, while those in the noexcept function itself will not. (Commit attempt 2: check InnermostEHScope != stable_end() before accessing it.) Differential Revision: https://reviews.llvm.org/D113620
241 lines
14 KiB
C++
241 lines
14 KiB
C++
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --function-signature --include-generated-funcs --replace-value-regex "__omp_offloading_[0-9a-z]+_[0-9a-z]+" "reduction_size[.].+[.]" "pl_cond[.].+[.|,]" --prefix-filecheck-ir-name _
|
|
// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s --check-prefix=CHECK1
|
|
// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s
|
|
// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK2
|
|
// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -fexceptions -fcxx-exceptions -debug-info-kind=line-tables-only -x c++ -emit-llvm %s -o - | FileCheck %s --check-prefix=DEBUG1
|
|
|
|
// RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s --implicit-check-not="{{__kmpc|__tgt}}"
|
|
// RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s
|
|
// RUN: %clang_cc1 -fopenmp-simd -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --implicit-check-not="{{__kmpc|__tgt}}"
|
|
// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp-simd -fexceptions -fcxx-exceptions -debug-info-kind=line-tables-only -x c++ -emit-llvm %s -o - | FileCheck %s --implicit-check-not="{{__kmpc|__tgt}}"
|
|
// expected-no-diagnostics
|
|
#ifndef HEADER
|
|
#define HEADER
|
|
|
|
void foo() { extern void mayThrow(); mayThrow(); }
|
|
|
|
int main() {
|
|
char a;
|
|
#pragma omp taskgroup
|
|
a = 2;
|
|
#pragma omp taskgroup
|
|
foo();
|
|
return a;
|
|
}
|
|
|
|
void parallel_taskgroup() {
|
|
#pragma omp parallel
|
|
#pragma omp taskgroup
|
|
foo();
|
|
}
|
|
#endif
|
|
// CHECK1-LABEL: define {{[^@]+}}@_Z3foov
|
|
// CHECK1-SAME: () #[[ATTR0:[0-9]+]] {
|
|
// CHECK1-NEXT: entry:
|
|
// CHECK1-NEXT: call void @_Z8mayThrowv()
|
|
// CHECK1-NEXT: ret void
|
|
//
|
|
//
|
|
// CHECK1-LABEL: define {{[^@]+}}@main
|
|
// CHECK1-SAME: () #[[ATTR2:[0-9]+]] personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
|
|
// CHECK1-NEXT: entry:
|
|
// CHECK1-NEXT: [[RETVAL:%.*]] = alloca i32, align 4
|
|
// CHECK1-NEXT: [[A:%.*]] = alloca i8, align 1
|
|
// CHECK1-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1:[0-9]+]])
|
|
// CHECK1-NEXT: store i32 0, i32* [[RETVAL]], align 4
|
|
// CHECK1-NEXT: call void @__kmpc_taskgroup(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]])
|
|
// CHECK1-NEXT: store i8 2, i8* [[A]], align 1
|
|
// CHECK1-NEXT: call void @__kmpc_end_taskgroup(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]])
|
|
// CHECK1-NEXT: call void @__kmpc_taskgroup(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]])
|
|
// CHECK1-NEXT: invoke void @_Z3foov()
|
|
// CHECK1-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]]
|
|
// CHECK1: invoke.cont:
|
|
// CHECK1-NEXT: call void @__kmpc_end_taskgroup(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]])
|
|
// CHECK1-NEXT: [[TMP1:%.*]] = load i8, i8* [[A]], align 1
|
|
// CHECK1-NEXT: [[CONV:%.*]] = sext i8 [[TMP1]] to i32
|
|
// CHECK1-NEXT: ret i32 [[CONV]]
|
|
// CHECK1: terminate.lpad:
|
|
// CHECK1-NEXT: [[TMP2:%.*]] = landingpad { i8*, i32 }
|
|
// CHECK1-NEXT: catch i8* null
|
|
// CHECK1-NEXT: [[TMP3:%.*]] = extractvalue { i8*, i32 } [[TMP2]], 0
|
|
// CHECK1-NEXT: call void @__clang_call_terminate(i8* [[TMP3]]) #[[ATTR8:[0-9]+]]
|
|
// CHECK1-NEXT: unreachable
|
|
//
|
|
//
|
|
// CHECK1-LABEL: define {{[^@]+}}@__clang_call_terminate
|
|
// CHECK1-SAME: (i8* [[TMP0:%.*]]) #[[ATTR5:[0-9]+]] comdat {
|
|
// CHECK1-NEXT: [[TMP2:%.*]] = call i8* @__cxa_begin_catch(i8* [[TMP0]]) #[[ATTR3:[0-9]+]]
|
|
// CHECK1-NEXT: call void @_ZSt9terminatev() #[[ATTR8]]
|
|
// CHECK1-NEXT: unreachable
|
|
//
|
|
//
|
|
// CHECK1-LABEL: define {{[^@]+}}@_Z18parallel_taskgroupv
|
|
// CHECK1-SAME: () #[[ATTR6:[0-9]+]] {
|
|
// CHECK1-NEXT: entry:
|
|
// CHECK1-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB1]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined. to void (i32*, i32*, ...)*))
|
|
// CHECK1-NEXT: ret void
|
|
//
|
|
//
|
|
// CHECK1-LABEL: define {{[^@]+}}@.omp_outlined.
|
|
// CHECK1-SAME: (i32* noalias noundef [[DOTGLOBAL_TID_:%.*]], i32* noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR7:[0-9]+]] personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
|
|
// CHECK1-NEXT: entry:
|
|
// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8
|
|
// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8
|
|
// CHECK1-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8
|
|
// CHECK1-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8
|
|
// CHECK1-NEXT: [[TMP0:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
|
|
// CHECK1-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4
|
|
// CHECK1-NEXT: call void @__kmpc_taskgroup(%struct.ident_t* @[[GLOB1]], i32 [[TMP1]])
|
|
// CHECK1-NEXT: invoke void @_Z3foov()
|
|
// CHECK1-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]]
|
|
// CHECK1: invoke.cont:
|
|
// CHECK1-NEXT: call void @__kmpc_end_taskgroup(%struct.ident_t* @[[GLOB1]], i32 [[TMP1]])
|
|
// CHECK1-NEXT: ret void
|
|
// CHECK1: terminate.lpad:
|
|
// CHECK1-NEXT: [[TMP2:%.*]] = landingpad { i8*, i32 }
|
|
// CHECK1-NEXT: catch i8* null
|
|
// CHECK1-NEXT: [[TMP3:%.*]] = extractvalue { i8*, i32 } [[TMP2]], 0
|
|
// CHECK1-NEXT: call void @__clang_call_terminate(i8* [[TMP3]]) #[[ATTR8]]
|
|
// CHECK1-NEXT: unreachable
|
|
//
|
|
//
|
|
// CHECK2-LABEL: define {{[^@]+}}@_Z3foov
|
|
// CHECK2-SAME: () #[[ATTR0:[0-9]+]] {
|
|
// CHECK2-NEXT: entry:
|
|
// CHECK2-NEXT: call void @_Z8mayThrowv()
|
|
// CHECK2-NEXT: ret void
|
|
//
|
|
//
|
|
// CHECK2-LABEL: define {{[^@]+}}@main
|
|
// CHECK2-SAME: () #[[ATTR2:[0-9]+]] personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
|
|
// CHECK2-NEXT: entry:
|
|
// CHECK2-NEXT: [[RETVAL:%.*]] = alloca i32, align 4
|
|
// CHECK2-NEXT: [[A:%.*]] = alloca i8, align 1
|
|
// CHECK2-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1:[0-9]+]])
|
|
// CHECK2-NEXT: store i32 0, i32* [[RETVAL]], align 4
|
|
// CHECK2-NEXT: call void @__kmpc_taskgroup(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]])
|
|
// CHECK2-NEXT: store i8 2, i8* [[A]], align 1
|
|
// CHECK2-NEXT: call void @__kmpc_end_taskgroup(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]])
|
|
// CHECK2-NEXT: call void @__kmpc_taskgroup(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]])
|
|
// CHECK2-NEXT: invoke void @_Z3foov()
|
|
// CHECK2-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]]
|
|
// CHECK2: invoke.cont:
|
|
// CHECK2-NEXT: call void @__kmpc_end_taskgroup(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]])
|
|
// CHECK2-NEXT: [[TMP1:%.*]] = load i8, i8* [[A]], align 1
|
|
// CHECK2-NEXT: [[CONV:%.*]] = sext i8 [[TMP1]] to i32
|
|
// CHECK2-NEXT: ret i32 [[CONV]]
|
|
// CHECK2: terminate.lpad:
|
|
// CHECK2-NEXT: [[TMP2:%.*]] = landingpad { i8*, i32 }
|
|
// CHECK2-NEXT: catch i8* null
|
|
// CHECK2-NEXT: [[TMP3:%.*]] = extractvalue { i8*, i32 } [[TMP2]], 0
|
|
// CHECK2-NEXT: call void @__clang_call_terminate(i8* [[TMP3]]) #[[ATTR8:[0-9]+]]
|
|
// CHECK2-NEXT: unreachable
|
|
//
|
|
//
|
|
// CHECK2-LABEL: define {{[^@]+}}@__clang_call_terminate
|
|
// CHECK2-SAME: (i8* [[TMP0:%.*]]) #[[ATTR5:[0-9]+]] comdat {
|
|
// CHECK2-NEXT: [[TMP2:%.*]] = call i8* @__cxa_begin_catch(i8* [[TMP0]]) #[[ATTR3:[0-9]+]]
|
|
// CHECK2-NEXT: call void @_ZSt9terminatev() #[[ATTR8]]
|
|
// CHECK2-NEXT: unreachable
|
|
//
|
|
//
|
|
// CHECK2-LABEL: define {{[^@]+}}@_Z18parallel_taskgroupv
|
|
// CHECK2-SAME: () #[[ATTR6:[0-9]+]] {
|
|
// CHECK2-NEXT: entry:
|
|
// CHECK2-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB1]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined. to void (i32*, i32*, ...)*))
|
|
// CHECK2-NEXT: ret void
|
|
//
|
|
//
|
|
// CHECK2-LABEL: define {{[^@]+}}@.omp_outlined.
|
|
// CHECK2-SAME: (i32* noalias noundef [[DOTGLOBAL_TID_:%.*]], i32* noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR7:[0-9]+]] personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
|
|
// CHECK2-NEXT: entry:
|
|
// CHECK2-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8
|
|
// CHECK2-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8
|
|
// CHECK2-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8
|
|
// CHECK2-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8
|
|
// CHECK2-NEXT: [[TMP0:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
|
|
// CHECK2-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4
|
|
// CHECK2-NEXT: call void @__kmpc_taskgroup(%struct.ident_t* @[[GLOB1]], i32 [[TMP1]])
|
|
// CHECK2-NEXT: invoke void @_Z3foov()
|
|
// CHECK2-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]]
|
|
// CHECK2: invoke.cont:
|
|
// CHECK2-NEXT: call void @__kmpc_end_taskgroup(%struct.ident_t* @[[GLOB1]], i32 [[TMP1]])
|
|
// CHECK2-NEXT: ret void
|
|
// CHECK2: terminate.lpad:
|
|
// CHECK2-NEXT: [[TMP2:%.*]] = landingpad { i8*, i32 }
|
|
// CHECK2-NEXT: catch i8* null
|
|
// CHECK2-NEXT: [[TMP3:%.*]] = extractvalue { i8*, i32 } [[TMP2]], 0
|
|
// CHECK2-NEXT: call void @__clang_call_terminate(i8* [[TMP3]]) #[[ATTR8]]
|
|
// CHECK2-NEXT: unreachable
|
|
//
|
|
//
|
|
// DEBUG1-LABEL: define {{[^@]+}}@_Z3foov
|
|
// DEBUG1-SAME: () #[[ATTR0:[0-9]+]] !dbg [[DBG6:![0-9]+]] {
|
|
// DEBUG1-NEXT: entry:
|
|
// DEBUG1-NEXT: call void @_Z8mayThrowv(), !dbg [[DBG10:![0-9]+]]
|
|
// DEBUG1-NEXT: ret void, !dbg [[DBG11:![0-9]+]]
|
|
//
|
|
//
|
|
// DEBUG1-LABEL: define {{[^@]+}}@main
|
|
// DEBUG1-SAME: () #[[ATTR2:[0-9]+]] personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) !dbg [[DBG12:![0-9]+]] {
|
|
// DEBUG1-NEXT: entry:
|
|
// DEBUG1-NEXT: [[RETVAL:%.*]] = alloca i32, align 4
|
|
// DEBUG1-NEXT: [[A:%.*]] = alloca i8, align 1
|
|
// DEBUG1-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1:[0-9]+]])
|
|
// DEBUG1-NEXT: store i32 0, i32* [[RETVAL]], align 4
|
|
// DEBUG1-NEXT: call void @__kmpc_taskgroup(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]]), !dbg [[DBG13:![0-9]+]]
|
|
// DEBUG1-NEXT: store i8 2, i8* [[A]], align 1, !dbg [[DBG14:![0-9]+]]
|
|
// DEBUG1-NEXT: call void @__kmpc_end_taskgroup(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]]), !dbg [[DBG15:![0-9]+]]
|
|
// DEBUG1-NEXT: call void @__kmpc_taskgroup(%struct.ident_t* @[[GLOB3:[0-9]+]], i32 [[TMP0]]), !dbg [[DBG16:![0-9]+]]
|
|
// DEBUG1-NEXT: invoke void @_Z3foov()
|
|
// DEBUG1-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]], !dbg [[DBG17:![0-9]+]]
|
|
// DEBUG1: invoke.cont:
|
|
// DEBUG1-NEXT: call void @__kmpc_end_taskgroup(%struct.ident_t* @[[GLOB3]], i32 [[TMP0]]), !dbg [[DBG17]]
|
|
// DEBUG1-NEXT: [[TMP1:%.*]] = load i8, i8* [[A]], align 1, !dbg [[DBG18:![0-9]+]]
|
|
// DEBUG1-NEXT: [[CONV:%.*]] = sext i8 [[TMP1]] to i32, !dbg [[DBG18]]
|
|
// DEBUG1-NEXT: ret i32 [[CONV]], !dbg [[DBG19:![0-9]+]]
|
|
// DEBUG1: terminate.lpad:
|
|
// DEBUG1-NEXT: [[TMP2:%.*]] = landingpad { i8*, i32 }
|
|
// DEBUG1-NEXT: catch i8* null, !dbg [[DBG17]]
|
|
// DEBUG1-NEXT: [[TMP3:%.*]] = extractvalue { i8*, i32 } [[TMP2]], 0, !dbg [[DBG17]]
|
|
// DEBUG1-NEXT: call void @__clang_call_terminate(i8* [[TMP3]]) #[[ATTR8:[0-9]+]], !dbg [[DBG17]]
|
|
// DEBUG1-NEXT: unreachable, !dbg [[DBG17]]
|
|
//
|
|
//
|
|
// DEBUG1-LABEL: define {{[^@]+}}@__clang_call_terminate
|
|
// DEBUG1-SAME: (i8* [[TMP0:%.*]]) #[[ATTR5:[0-9]+]] {
|
|
// DEBUG1-NEXT: [[TMP2:%.*]] = call i8* @__cxa_begin_catch(i8* [[TMP0]]) #[[ATTR3:[0-9]+]]
|
|
// DEBUG1-NEXT: call void @_ZSt9terminatev() #[[ATTR8]]
|
|
// DEBUG1-NEXT: unreachable
|
|
//
|
|
//
|
|
// DEBUG1-LABEL: define {{[^@]+}}@_Z18parallel_taskgroupv
|
|
// DEBUG1-SAME: () #[[ATTR6:[0-9]+]] !dbg [[DBG20:![0-9]+]] {
|
|
// DEBUG1-NEXT: entry:
|
|
// DEBUG1-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB7:[0-9]+]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined. to void (i32*, i32*, ...)*)), !dbg [[DBG21:![0-9]+]]
|
|
// DEBUG1-NEXT: ret void, !dbg [[DBG22:![0-9]+]]
|
|
//
|
|
//
|
|
// DEBUG1-LABEL: define {{[^@]+}}@.omp_outlined.
|
|
// DEBUG1-SAME: (i32* noalias noundef [[DOTGLOBAL_TID_:%.*]], i32* noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR7:[0-9]+]] personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) !dbg [[DBG24:![0-9]+]] {
|
|
// DEBUG1-NEXT: entry:
|
|
// DEBUG1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8
|
|
// DEBUG1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8
|
|
// DEBUG1-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8
|
|
// DEBUG1-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8
|
|
// DEBUG1-NEXT: [[TMP0:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG24:![0-9]+]]
|
|
// DEBUG1-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4, !dbg [[DBG24]]
|
|
// DEBUG1-NEXT: call void @__kmpc_taskgroup(%struct.ident_t* @[[GLOB5:[0-9]+]], i32 [[TMP1]]), !dbg [[DBG24]]
|
|
// DEBUG1-NEXT: invoke void @_Z3foov()
|
|
// DEBUG1-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]], !dbg [[DBG25:![0-9]+]]
|
|
// DEBUG1: invoke.cont:
|
|
// DEBUG1-NEXT: call void @__kmpc_end_taskgroup(%struct.ident_t* @[[GLOB5]], i32 [[TMP1]]), !dbg [[DBG25]]
|
|
// DEBUG1-NEXT: ret void, !dbg [[DBG26:![0-9]+]]
|
|
// DEBUG1: terminate.lpad:
|
|
// DEBUG1-NEXT: [[TMP2:%.*]] = landingpad { i8*, i32 }
|
|
// DEBUG1-NEXT: catch i8* null, !dbg [[DBG25]]
|
|
// DEBUG1-NEXT: [[TMP3:%.*]] = extractvalue { i8*, i32 } [[TMP2]], 0, !dbg [[DBG25]]
|
|
// DEBUG1-NEXT: call void @__clang_call_terminate(i8* [[TMP3]]) #[[ATTR8]], !dbg [[DBG25]]
|
|
// DEBUG1-NEXT: unreachable, !dbg [[DBG25]]
|
|
//
|