diff --git a/clang/lib/CodeGen/CGCleanup.cpp b/clang/lib/CodeGen/CGCleanup.cpp index b146141465f5d4..b9364fcd22314f 100644 --- a/clang/lib/CodeGen/CGCleanup.cpp +++ b/clang/lib/CodeGen/CGCleanup.cpp @@ -180,14 +180,6 @@ void *EHScopeStack::pushCleanup(CleanupKind Kind, size_t Size) { bool IsNormalCleanup = Kind & NormalCleanup; bool IsEHCleanup = Kind & EHCleanup; bool IsLifetimeMarker = Kind & LifetimeMarker; - - // Per C++ [except.terminate], it is implementation-defined whether none, - // some, or all cleanups are called before std::terminate. Thus, when - // terminate is the current EH scope, we may skip adding any EH cleanup - // scopes. - if (find(InnermostEHScope)->getKind() == EHScope::Terminate) - IsEHCleanup = false; - EHCleanupScope *Scope = new (Buffer) EHCleanupScope(IsNormalCleanup, IsEHCleanup, diff --git a/clang/test/CodeGenCXX/noexcept.cpp b/clang/test/CodeGenCXX/noexcept.cpp index 43053da53308b7..fe3ae98cf9bbed 100644 --- a/clang/test/CodeGenCXX/noexcept.cpp +++ b/clang/test/CodeGenCXX/noexcept.cpp @@ -16,23 +16,32 @@ namespace test0 { foo(); } } - // CHECK-LABEL: define{{.*}} void @_ZN5test04testEv() +// CHECK: [[EXN:%.*]] = alloca i8* // This goes to the terminate lpad. // CHECK: invoke void @_ZN5test01AC1Ev( -// CHECK-NEXT: unwind label %[[TERMINATE_LPAD:.*]] -// This also goes to the terminate lpad (no cleanups!). +// This goes to the cleanup-and-then-terminate lpad. // CHECK: invoke void @_ZN5test03fooEv() -// CHECK-NEXT: unwind label %[[TERMINATE_LPAD]] // Destructors don't throw by default in C++11. // CHECK: call void @_ZN5test01AD1Ev( // Cleanup lpad. -// CHECK: [[TERMINATE_LPAD]]: -// CHECK-NEXT: [[T0:%.*]] = landingpad +// CHECK: [[T0:%.*]] = landingpad +// CHECK-NEXT: catch i8* null +// CHECK-NEXT: [[T1:%.*]] = extractvalue { i8*, i32 } [[T0]], 0 +// CHECK-NEXT: store i8* [[T1]], i8** [[EXN]] +// (Calling this destructor is not technically required.) +// CHECK: call void @_ZN5test01AD1Ev( +// CHECK-NEXT: br label +// The terminate landing pad jumps in here for some reason. +// CHECK: [[T0:%.*]] = landingpad // CHECK-NEXT: catch i8* null // CHECK-NEXT: [[T1:%.*]] = extractvalue { i8*, i32 } [[T0]], 0 // CHECK-NEXT: call void @__clang_call_terminate(i8* [[T1]]) // CHECK-NEXT: unreachable +// The terminate handler chained to by the cleanup lpad. +// CHECK: [[T0:%.*]] = load i8*, i8** [[EXN]] +// CHECK-NEXT: call void @__clang_call_terminate(i8* [[T0]]) +// CHECK-NEXT: unreachable // CHECK-LABEL: define linkonce_odr hidden void @__clang_call_terminate( // CHECK: call i8* @__cxa_begin_catch( diff --git a/clang/test/OpenMP/distribute_parallel_for_num_threads_codegen.cpp b/clang/test/OpenMP/distribute_parallel_for_num_threads_codegen.cpp index 65643d3afa5bf6..b1a573ef88561e 100644 --- a/clang/test/OpenMP/distribute_parallel_for_num_threads_codegen.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_num_threads_codegen.cpp @@ -1051,6 +1051,8 @@ int main() { // CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_S:%.*]], align 8 +// CHECK1-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// CHECK1-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // 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: store i32 0, i32* [[DOTOMP_COMB_LB]], align 4 @@ -1084,7 +1086,7 @@ int main() { // CHECK1-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]] // CHECK1: invoke.cont: // CHECK1-NEXT: [[CALL:%.*]] = invoke signext i8 @_ZN1ScvcEv(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]]) -// CHECK1-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[TERMINATE_LPAD]] +// CHECK1-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD:%.*]] // CHECK1: invoke.cont2: // CHECK1-NEXT: [[TMP7:%.*]] = sext i8 [[CALL]] to i32 // CHECK1-NEXT: call void @__kmpc_push_num_threads(%struct.ident_t* @[[GLOB3]], i32 [[TMP1]], i32 [[TMP7]]) @@ -1101,16 +1103,29 @@ int main() { // CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] // CHECK1-NEXT: store i32 [[ADD]], i32* [[DOTOMP_IV]], align 4 // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]] +// CHECK1: lpad: +// CHECK1-NEXT: [[TMP14:%.*]] = landingpad { i8*, i32 } +// CHECK1-NEXT: catch i8* null +// CHECK1-NEXT: [[TMP15:%.*]] = extractvalue { i8*, i32 } [[TMP14]], 0 +// CHECK1-NEXT: store i8* [[TMP15]], i8** [[EXN_SLOT]], align 8 +// CHECK1-NEXT: [[TMP16:%.*]] = extractvalue { i8*, i32 } [[TMP14]], 1 +// CHECK1-NEXT: store i32 [[TMP16]], i32* [[EHSELECTOR_SLOT]], align 4 +// CHECK1-NEXT: call void @_ZN1SD1Ev(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]]) #[[ATTR6]] +// CHECK1-NEXT: br label [[TERMINATE_HANDLER:%.*]] // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: // CHECK1-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB1]], i32 [[TMP1]]) // CHECK1-NEXT: ret void // CHECK1: terminate.lpad: -// CHECK1-NEXT: [[TMP14:%.*]] = landingpad { i8*, i32 } +// CHECK1-NEXT: [[TMP17:%.*]] = landingpad { i8*, i32 } // CHECK1-NEXT: catch i8* null -// CHECK1-NEXT: [[TMP15:%.*]] = extractvalue { i8*, i32 } [[TMP14]], 0 -// CHECK1-NEXT: call void @__clang_call_terminate(i8* [[TMP15]]) #[[ATTR10]] +// CHECK1-NEXT: [[TMP18:%.*]] = extractvalue { i8*, i32 } [[TMP17]], 0 +// CHECK1-NEXT: call void @__clang_call_terminate(i8* [[TMP18]]) #[[ATTR10]] +// CHECK1-NEXT: unreachable +// CHECK1: terminate.handler: +// CHECK1-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8 +// CHECK1-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR10]] // CHECK1-NEXT: unreachable // // @@ -2158,6 +2173,8 @@ int main() { // CHECK2-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 // CHECK2-NEXT: [[I:%.*]] = alloca i32, align 4 // CHECK2-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_S:%.*]], align 8 +// CHECK2-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// CHECK2-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // 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: store i32 0, i32* [[DOTOMP_COMB_LB]], align 4 @@ -2191,7 +2208,7 @@ int main() { // CHECK2-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]] // CHECK2: invoke.cont: // CHECK2-NEXT: [[CALL:%.*]] = invoke signext i8 @_ZN1ScvcEv(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]]) -// CHECK2-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[TERMINATE_LPAD]] +// CHECK2-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD:%.*]] // CHECK2: invoke.cont2: // CHECK2-NEXT: [[TMP7:%.*]] = sext i8 [[CALL]] to i32 // CHECK2-NEXT: call void @__kmpc_push_num_threads(%struct.ident_t* @[[GLOB3]], i32 [[TMP1]], i32 [[TMP7]]) @@ -2208,16 +2225,29 @@ int main() { // CHECK2-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] // CHECK2-NEXT: store i32 [[ADD]], i32* [[DOTOMP_IV]], align 4 // CHECK2-NEXT: br label [[OMP_INNER_FOR_COND]] +// CHECK2: lpad: +// CHECK2-NEXT: [[TMP14:%.*]] = landingpad { i8*, i32 } +// CHECK2-NEXT: catch i8* null +// CHECK2-NEXT: [[TMP15:%.*]] = extractvalue { i8*, i32 } [[TMP14]], 0 +// CHECK2-NEXT: store i8* [[TMP15]], i8** [[EXN_SLOT]], align 8 +// CHECK2-NEXT: [[TMP16:%.*]] = extractvalue { i8*, i32 } [[TMP14]], 1 +// CHECK2-NEXT: store i32 [[TMP16]], i32* [[EHSELECTOR_SLOT]], align 4 +// CHECK2-NEXT: call void @_ZN1SD1Ev(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]]) #[[ATTR6]] +// CHECK2-NEXT: br label [[TERMINATE_HANDLER:%.*]] // CHECK2: omp.inner.for.end: // CHECK2-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK2: omp.loop.exit: // CHECK2-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB1]], i32 [[TMP1]]) // CHECK2-NEXT: ret void // CHECK2: terminate.lpad: -// CHECK2-NEXT: [[TMP14:%.*]] = landingpad { i8*, i32 } +// CHECK2-NEXT: [[TMP17:%.*]] = landingpad { i8*, i32 } // CHECK2-NEXT: catch i8* null -// CHECK2-NEXT: [[TMP15:%.*]] = extractvalue { i8*, i32 } [[TMP14]], 0 -// CHECK2-NEXT: call void @__clang_call_terminate(i8* [[TMP15]]) #[[ATTR10]] +// CHECK2-NEXT: [[TMP18:%.*]] = extractvalue { i8*, i32 } [[TMP17]], 0 +// CHECK2-NEXT: call void @__clang_call_terminate(i8* [[TMP18]]) #[[ATTR10]] +// CHECK2-NEXT: unreachable +// CHECK2: terminate.handler: +// CHECK2-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8 +// CHECK2-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR10]] // CHECK2-NEXT: unreachable // // @@ -3256,6 +3286,8 @@ int main() { // CHECK5-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 // CHECK5-NEXT: [[I:%.*]] = alloca i32, align 4 // CHECK5-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_S:%.*]], align 8 +// CHECK5-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// CHECK5-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // CHECK5-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK5-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 // CHECK5-NEXT: store i32 0, i32* [[DOTOMP_COMB_LB]], align 4 @@ -3289,7 +3321,7 @@ int main() { // CHECK5-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]] // CHECK5: invoke.cont: // CHECK5-NEXT: [[CALL:%.*]] = invoke signext i8 @_ZN1ScvcEv(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]]) -// CHECK5-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[TERMINATE_LPAD]] +// CHECK5-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD:%.*]] // CHECK5: invoke.cont2: // CHECK5-NEXT: [[TMP7:%.*]] = sext i8 [[CALL]] to i32 // CHECK5-NEXT: call void @__kmpc_push_num_threads(%struct.ident_t* @[[GLOB3]], i32 [[TMP1]], i32 [[TMP7]]) @@ -3306,16 +3338,29 @@ int main() { // CHECK5-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] // CHECK5-NEXT: store i32 [[ADD]], i32* [[DOTOMP_IV]], align 4 // CHECK5-NEXT: br label [[OMP_INNER_FOR_COND]] +// CHECK5: lpad: +// CHECK5-NEXT: [[TMP14:%.*]] = landingpad { i8*, i32 } +// CHECK5-NEXT: catch i8* null +// CHECK5-NEXT: [[TMP15:%.*]] = extractvalue { i8*, i32 } [[TMP14]], 0 +// CHECK5-NEXT: store i8* [[TMP15]], i8** [[EXN_SLOT]], align 8 +// CHECK5-NEXT: [[TMP16:%.*]] = extractvalue { i8*, i32 } [[TMP14]], 1 +// CHECK5-NEXT: store i32 [[TMP16]], i32* [[EHSELECTOR_SLOT]], align 4 +// CHECK5-NEXT: call void @_ZN1SD1Ev(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]]) #[[ATTR6]] +// CHECK5-NEXT: br label [[TERMINATE_HANDLER:%.*]] // CHECK5: omp.inner.for.end: // CHECK5-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK5: omp.loop.exit: // CHECK5-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB1]], i32 [[TMP1]]) // CHECK5-NEXT: ret void // CHECK5: terminate.lpad: -// CHECK5-NEXT: [[TMP14:%.*]] = landingpad { i8*, i32 } +// CHECK5-NEXT: [[TMP17:%.*]] = landingpad { i8*, i32 } // CHECK5-NEXT: catch i8* null -// CHECK5-NEXT: [[TMP15:%.*]] = extractvalue { i8*, i32 } [[TMP14]], 0 -// CHECK5-NEXT: call void @__clang_call_terminate(i8* [[TMP15]]) #[[ATTR10]] +// CHECK5-NEXT: [[TMP18:%.*]] = extractvalue { i8*, i32 } [[TMP17]], 0 +// CHECK5-NEXT: call void @__clang_call_terminate(i8* [[TMP18]]) #[[ATTR10]] +// CHECK5-NEXT: unreachable +// CHECK5: terminate.handler: +// CHECK5-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8 +// CHECK5-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR10]] // CHECK5-NEXT: unreachable // // @@ -4363,6 +4408,8 @@ int main() { // CHECK6-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 // CHECK6-NEXT: [[I:%.*]] = alloca i32, align 4 // CHECK6-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_S:%.*]], align 8 +// CHECK6-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// CHECK6-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // CHECK6-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK6-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 // CHECK6-NEXT: store i32 0, i32* [[DOTOMP_COMB_LB]], align 4 @@ -4396,7 +4443,7 @@ int main() { // CHECK6-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]] // CHECK6: invoke.cont: // CHECK6-NEXT: [[CALL:%.*]] = invoke signext i8 @_ZN1ScvcEv(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]]) -// CHECK6-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[TERMINATE_LPAD]] +// CHECK6-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD:%.*]] // CHECK6: invoke.cont2: // CHECK6-NEXT: [[TMP7:%.*]] = sext i8 [[CALL]] to i32 // CHECK6-NEXT: call void @__kmpc_push_num_threads(%struct.ident_t* @[[GLOB3]], i32 [[TMP1]], i32 [[TMP7]]) @@ -4413,16 +4460,29 @@ int main() { // CHECK6-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] // CHECK6-NEXT: store i32 [[ADD]], i32* [[DOTOMP_IV]], align 4 // CHECK6-NEXT: br label [[OMP_INNER_FOR_COND]] +// CHECK6: lpad: +// CHECK6-NEXT: [[TMP14:%.*]] = landingpad { i8*, i32 } +// CHECK6-NEXT: catch i8* null +// CHECK6-NEXT: [[TMP15:%.*]] = extractvalue { i8*, i32 } [[TMP14]], 0 +// CHECK6-NEXT: store i8* [[TMP15]], i8** [[EXN_SLOT]], align 8 +// CHECK6-NEXT: [[TMP16:%.*]] = extractvalue { i8*, i32 } [[TMP14]], 1 +// CHECK6-NEXT: store i32 [[TMP16]], i32* [[EHSELECTOR_SLOT]], align 4 +// CHECK6-NEXT: call void @_ZN1SD1Ev(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]]) #[[ATTR6]] +// CHECK6-NEXT: br label [[TERMINATE_HANDLER:%.*]] // CHECK6: omp.inner.for.end: // CHECK6-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK6: omp.loop.exit: // CHECK6-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB1]], i32 [[TMP1]]) // CHECK6-NEXT: ret void // CHECK6: terminate.lpad: -// CHECK6-NEXT: [[TMP14:%.*]] = landingpad { i8*, i32 } +// CHECK6-NEXT: [[TMP17:%.*]] = landingpad { i8*, i32 } // CHECK6-NEXT: catch i8* null -// CHECK6-NEXT: [[TMP15:%.*]] = extractvalue { i8*, i32 } [[TMP14]], 0 -// CHECK6-NEXT: call void @__clang_call_terminate(i8* [[TMP15]]) #[[ATTR10]] +// CHECK6-NEXT: [[TMP18:%.*]] = extractvalue { i8*, i32 } [[TMP17]], 0 +// CHECK6-NEXT: call void @__clang_call_terminate(i8* [[TMP18]]) #[[ATTR10]] +// CHECK6-NEXT: unreachable +// CHECK6: terminate.handler: +// CHECK6-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8 +// CHECK6-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR10]] // CHECK6-NEXT: unreachable // // @@ -5479,6 +5539,8 @@ int main() { // CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 // CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 // CHECK9-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_S:%.*]], align 8 +// CHECK9-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// CHECK9-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // CHECK9-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 // CHECK9-NEXT: store i32 0, i32* [[DOTOMP_COMB_LB]], align 4 @@ -5512,7 +5574,7 @@ int main() { // CHECK9-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]] // CHECK9: invoke.cont: // CHECK9-NEXT: [[CALL:%.*]] = invoke i8 @_ZN1ScvcEv(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]]) -// CHECK9-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[TERMINATE_LPAD]] +// CHECK9-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD:%.*]] // CHECK9: invoke.cont2: // CHECK9-NEXT: [[TMP7:%.*]] = sext i8 [[CALL]] to i32 // CHECK9-NEXT: call void @__kmpc_push_num_threads(%struct.ident_t* @[[GLOB3]], i32 [[TMP1]], i32 [[TMP7]]) @@ -5529,16 +5591,29 @@ int main() { // CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] // CHECK9-NEXT: store i32 [[ADD]], i32* [[DOTOMP_IV]], align 4 // CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]] +// CHECK9: lpad: +// CHECK9-NEXT: [[TMP14:%.*]] = landingpad { i8*, i32 } +// CHECK9-NEXT: catch i8* null +// CHECK9-NEXT: [[TMP15:%.*]] = extractvalue { i8*, i32 } [[TMP14]], 0 +// CHECK9-NEXT: store i8* [[TMP15]], i8** [[EXN_SLOT]], align 8 +// CHECK9-NEXT: [[TMP16:%.*]] = extractvalue { i8*, i32 } [[TMP14]], 1 +// CHECK9-NEXT: store i32 [[TMP16]], i32* [[EHSELECTOR_SLOT]], align 4 +// CHECK9-NEXT: call void @_ZN1SD1Ev(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]]) #[[ATTR6]] +// CHECK9-NEXT: br label [[TERMINATE_HANDLER:%.*]] // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: // CHECK9-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB1]], i32 [[TMP1]]) // CHECK9-NEXT: ret void // CHECK9: terminate.lpad: -// CHECK9-NEXT: [[TMP14:%.*]] = landingpad { i8*, i32 } +// CHECK9-NEXT: [[TMP17:%.*]] = landingpad { i8*, i32 } // CHECK9-NEXT: catch i8* null -// CHECK9-NEXT: [[TMP15:%.*]] = extractvalue { i8*, i32 } [[TMP14]], 0 -// CHECK9-NEXT: call void @__clang_call_terminate(i8* [[TMP15]]) #[[ATTR10]] +// CHECK9-NEXT: [[TMP18:%.*]] = extractvalue { i8*, i32 } [[TMP17]], 0 +// CHECK9-NEXT: call void @__clang_call_terminate(i8* [[TMP18]]) #[[ATTR10]] +// CHECK9-NEXT: unreachable +// CHECK9: terminate.handler: +// CHECK9-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8 +// CHECK9-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR10]] // CHECK9-NEXT: unreachable // // @@ -6586,6 +6661,8 @@ int main() { // CHECK10-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 // CHECK10-NEXT: [[I:%.*]] = alloca i32, align 4 // CHECK10-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_S:%.*]], align 8 +// CHECK10-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// CHECK10-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // CHECK10-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK10-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 // CHECK10-NEXT: store i32 0, i32* [[DOTOMP_COMB_LB]], align 4 @@ -6619,7 +6696,7 @@ int main() { // CHECK10-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]] // CHECK10: invoke.cont: // CHECK10-NEXT: [[CALL:%.*]] = invoke i8 @_ZN1ScvcEv(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]]) -// CHECK10-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[TERMINATE_LPAD]] +// CHECK10-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD:%.*]] // CHECK10: invoke.cont2: // CHECK10-NEXT: [[TMP7:%.*]] = sext i8 [[CALL]] to i32 // CHECK10-NEXT: call void @__kmpc_push_num_threads(%struct.ident_t* @[[GLOB3]], i32 [[TMP1]], i32 [[TMP7]]) @@ -6636,16 +6713,29 @@ int main() { // CHECK10-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] // CHECK10-NEXT: store i32 [[ADD]], i32* [[DOTOMP_IV]], align 4 // CHECK10-NEXT: br label [[OMP_INNER_FOR_COND]] +// CHECK10: lpad: +// CHECK10-NEXT: [[TMP14:%.*]] = landingpad { i8*, i32 } +// CHECK10-NEXT: catch i8* null +// CHECK10-NEXT: [[TMP15:%.*]] = extractvalue { i8*, i32 } [[TMP14]], 0 +// CHECK10-NEXT: store i8* [[TMP15]], i8** [[EXN_SLOT]], align 8 +// CHECK10-NEXT: [[TMP16:%.*]] = extractvalue { i8*, i32 } [[TMP14]], 1 +// CHECK10-NEXT: store i32 [[TMP16]], i32* [[EHSELECTOR_SLOT]], align 4 +// CHECK10-NEXT: call void @_ZN1SD1Ev(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]]) #[[ATTR6]] +// CHECK10-NEXT: br label [[TERMINATE_HANDLER:%.*]] // CHECK10: omp.inner.for.end: // CHECK10-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK10: omp.loop.exit: // CHECK10-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB1]], i32 [[TMP1]]) // CHECK10-NEXT: ret void // CHECK10: terminate.lpad: -// CHECK10-NEXT: [[TMP14:%.*]] = landingpad { i8*, i32 } +// CHECK10-NEXT: [[TMP17:%.*]] = landingpad { i8*, i32 } // CHECK10-NEXT: catch i8* null -// CHECK10-NEXT: [[TMP15:%.*]] = extractvalue { i8*, i32 } [[TMP14]], 0 -// CHECK10-NEXT: call void @__clang_call_terminate(i8* [[TMP15]]) #[[ATTR10]] +// CHECK10-NEXT: [[TMP18:%.*]] = extractvalue { i8*, i32 } [[TMP17]], 0 +// CHECK10-NEXT: call void @__clang_call_terminate(i8* [[TMP18]]) #[[ATTR10]] +// CHECK10-NEXT: unreachable +// CHECK10: terminate.handler: +// CHECK10-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8 +// CHECK10-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR10]] // CHECK10-NEXT: unreachable // // @@ -7684,6 +7774,8 @@ int main() { // CHECK13-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 // CHECK13-NEXT: [[I:%.*]] = alloca i32, align 4 // CHECK13-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_S:%.*]], align 8 +// CHECK13-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// CHECK13-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // CHECK13-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK13-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 // CHECK13-NEXT: store i32 0, i32* [[DOTOMP_COMB_LB]], align 4 @@ -7717,7 +7809,7 @@ int main() { // CHECK13-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]] // CHECK13: invoke.cont: // CHECK13-NEXT: [[CALL:%.*]] = invoke i8 @_ZN1ScvcEv(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]]) -// CHECK13-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[TERMINATE_LPAD]] +// CHECK13-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD:%.*]] // CHECK13: invoke.cont2: // CHECK13-NEXT: [[TMP7:%.*]] = sext i8 [[CALL]] to i32 // CHECK13-NEXT: call void @__kmpc_push_num_threads(%struct.ident_t* @[[GLOB3]], i32 [[TMP1]], i32 [[TMP7]]) @@ -7734,16 +7826,29 @@ int main() { // CHECK13-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] // CHECK13-NEXT: store i32 [[ADD]], i32* [[DOTOMP_IV]], align 4 // CHECK13-NEXT: br label [[OMP_INNER_FOR_COND]] +// CHECK13: lpad: +// CHECK13-NEXT: [[TMP14:%.*]] = landingpad { i8*, i32 } +// CHECK13-NEXT: catch i8* null +// CHECK13-NEXT: [[TMP15:%.*]] = extractvalue { i8*, i32 } [[TMP14]], 0 +// CHECK13-NEXT: store i8* [[TMP15]], i8** [[EXN_SLOT]], align 8 +// CHECK13-NEXT: [[TMP16:%.*]] = extractvalue { i8*, i32 } [[TMP14]], 1 +// CHECK13-NEXT: store i32 [[TMP16]], i32* [[EHSELECTOR_SLOT]], align 4 +// CHECK13-NEXT: call void @_ZN1SD1Ev(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]]) #[[ATTR6]] +// CHECK13-NEXT: br label [[TERMINATE_HANDLER:%.*]] // CHECK13: omp.inner.for.end: // CHECK13-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK13: omp.loop.exit: // CHECK13-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB1]], i32 [[TMP1]]) // CHECK13-NEXT: ret void // CHECK13: terminate.lpad: -// CHECK13-NEXT: [[TMP14:%.*]] = landingpad { i8*, i32 } +// CHECK13-NEXT: [[TMP17:%.*]] = landingpad { i8*, i32 } // CHECK13-NEXT: catch i8* null -// CHECK13-NEXT: [[TMP15:%.*]] = extractvalue { i8*, i32 } [[TMP14]], 0 -// CHECK13-NEXT: call void @__clang_call_terminate(i8* [[TMP15]]) #[[ATTR10]] +// CHECK13-NEXT: [[TMP18:%.*]] = extractvalue { i8*, i32 } [[TMP17]], 0 +// CHECK13-NEXT: call void @__clang_call_terminate(i8* [[TMP18]]) #[[ATTR10]] +// CHECK13-NEXT: unreachable +// CHECK13: terminate.handler: +// CHECK13-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8 +// CHECK13-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR10]] // CHECK13-NEXT: unreachable // // @@ -8791,6 +8896,8 @@ int main() { // CHECK14-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 // CHECK14-NEXT: [[I:%.*]] = alloca i32, align 4 // CHECK14-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_S:%.*]], align 8 +// CHECK14-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// CHECK14-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // CHECK14-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK14-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 // CHECK14-NEXT: store i32 0, i32* [[DOTOMP_COMB_LB]], align 4 @@ -8824,7 +8931,7 @@ int main() { // CHECK14-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]] // CHECK14: invoke.cont: // CHECK14-NEXT: [[CALL:%.*]] = invoke i8 @_ZN1ScvcEv(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]]) -// CHECK14-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[TERMINATE_LPAD]] +// CHECK14-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD:%.*]] // CHECK14: invoke.cont2: // CHECK14-NEXT: [[TMP7:%.*]] = sext i8 [[CALL]] to i32 // CHECK14-NEXT: call void @__kmpc_push_num_threads(%struct.ident_t* @[[GLOB3]], i32 [[TMP1]], i32 [[TMP7]]) @@ -8841,16 +8948,29 @@ int main() { // CHECK14-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] // CHECK14-NEXT: store i32 [[ADD]], i32* [[DOTOMP_IV]], align 4 // CHECK14-NEXT: br label [[OMP_INNER_FOR_COND]] +// CHECK14: lpad: +// CHECK14-NEXT: [[TMP14:%.*]] = landingpad { i8*, i32 } +// CHECK14-NEXT: catch i8* null +// CHECK14-NEXT: [[TMP15:%.*]] = extractvalue { i8*, i32 } [[TMP14]], 0 +// CHECK14-NEXT: store i8* [[TMP15]], i8** [[EXN_SLOT]], align 8 +// CHECK14-NEXT: [[TMP16:%.*]] = extractvalue { i8*, i32 } [[TMP14]], 1 +// CHECK14-NEXT: store i32 [[TMP16]], i32* [[EHSELECTOR_SLOT]], align 4 +// CHECK14-NEXT: call void @_ZN1SD1Ev(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]]) #[[ATTR6]] +// CHECK14-NEXT: br label [[TERMINATE_HANDLER:%.*]] // CHECK14: omp.inner.for.end: // CHECK14-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK14: omp.loop.exit: // CHECK14-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB1]], i32 [[TMP1]]) // CHECK14-NEXT: ret void // CHECK14: terminate.lpad: -// CHECK14-NEXT: [[TMP14:%.*]] = landingpad { i8*, i32 } +// CHECK14-NEXT: [[TMP17:%.*]] = landingpad { i8*, i32 } // CHECK14-NEXT: catch i8* null -// CHECK14-NEXT: [[TMP15:%.*]] = extractvalue { i8*, i32 } [[TMP14]], 0 -// CHECK14-NEXT: call void @__clang_call_terminate(i8* [[TMP15]]) #[[ATTR10]] +// CHECK14-NEXT: [[TMP18:%.*]] = extractvalue { i8*, i32 } [[TMP17]], 0 +// CHECK14-NEXT: call void @__clang_call_terminate(i8* [[TMP18]]) #[[ATTR10]] +// CHECK14-NEXT: unreachable +// CHECK14: terminate.handler: +// CHECK14-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8 +// CHECK14-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR10]] // CHECK14-NEXT: unreachable // // @@ -8948,3 +9068,4 @@ int main() { // CHECK14-NEXT: call void @__tgt_register_requires(i64 1) // CHECK14-NEXT: ret void // +// \ No newline at end of file diff --git a/clang/test/OpenMP/distribute_parallel_for_simd_num_threads_codegen.cpp b/clang/test/OpenMP/distribute_parallel_for_simd_num_threads_codegen.cpp index 142749a1369886..749010caccaaea 100644 --- a/clang/test/OpenMP/distribute_parallel_for_simd_num_threads_codegen.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_simd_num_threads_codegen.cpp @@ -1121,6 +1121,8 @@ int main() { // CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_S:%.*]], align 8 +// CHECK1-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// CHECK1-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // 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: store i32 0, i32* [[DOTOMP_COMB_LB]], align 4 @@ -1154,7 +1156,7 @@ int main() { // CHECK1-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]], !llvm.access.group !42 // CHECK1: invoke.cont: // CHECK1-NEXT: [[CALL:%.*]] = invoke signext i8 @_ZN1ScvcEv(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]]) -// CHECK1-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[TERMINATE_LPAD]], !llvm.access.group !42 +// CHECK1-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD:%.*]], !llvm.access.group !42 // CHECK1: invoke.cont2: // CHECK1-NEXT: [[TMP7:%.*]] = sext i8 [[CALL]] to i32 // CHECK1-NEXT: call void @__kmpc_push_num_threads(%struct.ident_t* @[[GLOB3]], i32 [[TMP1]], i32 [[TMP7]]), !llvm.access.group !42 @@ -1171,23 +1173,36 @@ int main() { // CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] // CHECK1-NEXT: store i32 [[ADD]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !42 // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP43:![0-9]+]] +// CHECK1: lpad: +// CHECK1-NEXT: [[TMP14:%.*]] = landingpad { i8*, i32 } +// CHECK1-NEXT: catch i8* null +// CHECK1-NEXT: [[TMP15:%.*]] = extractvalue { i8*, i32 } [[TMP14]], 0 +// CHECK1-NEXT: store i8* [[TMP15]], i8** [[EXN_SLOT]], align 8, !llvm.access.group !42 +// CHECK1-NEXT: [[TMP16:%.*]] = extractvalue { i8*, i32 } [[TMP14]], 1 +// CHECK1-NEXT: store i32 [[TMP16]], i32* [[EHSELECTOR_SLOT]], align 4, !llvm.access.group !42 +// CHECK1-NEXT: call void @_ZN1SD1Ev(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]]) #[[ATTR6]], !llvm.access.group !42 +// CHECK1-NEXT: br label [[TERMINATE_HANDLER:%.*]] // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: // CHECK1-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB1]], i32 [[TMP1]]) -// CHECK1-NEXT: [[TMP14:%.*]] = load i32, i32* [[DOTOMP_IS_LAST]], align 4 -// CHECK1-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 -// CHECK1-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1-NEXT: [[TMP17:%.*]] = load i32, i32* [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP18:%.*]] = icmp ne i32 [[TMP17]], 0 +// CHECK1-NEXT: br i1 [[TMP18]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] // CHECK1: .omp.final.then: // CHECK1-NEXT: store i32 100, i32* [[I]], align 4 // CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] // CHECK1: .omp.final.done: // CHECK1-NEXT: ret void // CHECK1: terminate.lpad: -// CHECK1-NEXT: [[TMP16:%.*]] = landingpad { i8*, i32 } +// CHECK1-NEXT: [[TMP19:%.*]] = landingpad { i8*, i32 } // CHECK1-NEXT: catch i8* null -// CHECK1-NEXT: [[TMP17:%.*]] = extractvalue { i8*, i32 } [[TMP16]], 0 -// CHECK1-NEXT: call void @__clang_call_terminate(i8* [[TMP17]]) #[[ATTR10]], !llvm.access.group !42 +// CHECK1-NEXT: [[TMP20:%.*]] = extractvalue { i8*, i32 } [[TMP19]], 0 +// CHECK1-NEXT: call void @__clang_call_terminate(i8* [[TMP20]]) #[[ATTR10]], !llvm.access.group !42 +// CHECK1-NEXT: unreachable +// CHECK1: terminate.handler: +// CHECK1-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8, !llvm.access.group !42 +// CHECK1-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR10]], !llvm.access.group !42 // CHECK1-NEXT: unreachable // // @@ -2312,6 +2327,8 @@ int main() { // CHECK2-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 // CHECK2-NEXT: [[I:%.*]] = alloca i32, align 4 // CHECK2-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_S:%.*]], align 8 +// CHECK2-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// CHECK2-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // 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: store i32 0, i32* [[DOTOMP_COMB_LB]], align 4 @@ -2345,7 +2362,7 @@ int main() { // CHECK2-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]], !llvm.access.group !42 // CHECK2: invoke.cont: // CHECK2-NEXT: [[CALL:%.*]] = invoke signext i8 @_ZN1ScvcEv(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]]) -// CHECK2-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[TERMINATE_LPAD]], !llvm.access.group !42 +// CHECK2-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD:%.*]], !llvm.access.group !42 // CHECK2: invoke.cont2: // CHECK2-NEXT: [[TMP7:%.*]] = sext i8 [[CALL]] to i32 // CHECK2-NEXT: call void @__kmpc_push_num_threads(%struct.ident_t* @[[GLOB3]], i32 [[TMP1]], i32 [[TMP7]]), !llvm.access.group !42 @@ -2362,23 +2379,36 @@ int main() { // CHECK2-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] // CHECK2-NEXT: store i32 [[ADD]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !42 // CHECK2-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP43:![0-9]+]] +// CHECK2: lpad: +// CHECK2-NEXT: [[TMP14:%.*]] = landingpad { i8*, i32 } +// CHECK2-NEXT: catch i8* null +// CHECK2-NEXT: [[TMP15:%.*]] = extractvalue { i8*, i32 } [[TMP14]], 0 +// CHECK2-NEXT: store i8* [[TMP15]], i8** [[EXN_SLOT]], align 8, !llvm.access.group !42 +// CHECK2-NEXT: [[TMP16:%.*]] = extractvalue { i8*, i32 } [[TMP14]], 1 +// CHECK2-NEXT: store i32 [[TMP16]], i32* [[EHSELECTOR_SLOT]], align 4, !llvm.access.group !42 +// CHECK2-NEXT: call void @_ZN1SD1Ev(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]]) #[[ATTR6]], !llvm.access.group !42 +// CHECK2-NEXT: br label [[TERMINATE_HANDLER:%.*]] // CHECK2: omp.inner.for.end: // CHECK2-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK2: omp.loop.exit: // CHECK2-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB1]], i32 [[TMP1]]) -// CHECK2-NEXT: [[TMP14:%.*]] = load i32, i32* [[DOTOMP_IS_LAST]], align 4 -// CHECK2-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 -// CHECK2-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK2-NEXT: [[TMP17:%.*]] = load i32, i32* [[DOTOMP_IS_LAST]], align 4 +// CHECK2-NEXT: [[TMP18:%.*]] = icmp ne i32 [[TMP17]], 0 +// CHECK2-NEXT: br i1 [[TMP18]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] // CHECK2: .omp.final.then: // CHECK2-NEXT: store i32 100, i32* [[I]], align 4 // CHECK2-NEXT: br label [[DOTOMP_FINAL_DONE]] // CHECK2: .omp.final.done: // CHECK2-NEXT: ret void // CHECK2: terminate.lpad: -// CHECK2-NEXT: [[TMP16:%.*]] = landingpad { i8*, i32 } +// CHECK2-NEXT: [[TMP19:%.*]] = landingpad { i8*, i32 } // CHECK2-NEXT: catch i8* null -// CHECK2-NEXT: [[TMP17:%.*]] = extractvalue { i8*, i32 } [[TMP16]], 0 -// CHECK2-NEXT: call void @__clang_call_terminate(i8* [[TMP17]]) #[[ATTR10]], !llvm.access.group !42 +// CHECK2-NEXT: [[TMP20:%.*]] = extractvalue { i8*, i32 } [[TMP19]], 0 +// CHECK2-NEXT: call void @__clang_call_terminate(i8* [[TMP20]]) #[[ATTR10]], !llvm.access.group !42 +// CHECK2-NEXT: unreachable +// CHECK2: terminate.handler: +// CHECK2-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8, !llvm.access.group !42 +// CHECK2-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR10]], !llvm.access.group !42 // CHECK2-NEXT: unreachable // // @@ -4172,6 +4202,8 @@ int main() { // CHECK5-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 // CHECK5-NEXT: [[I:%.*]] = alloca i32, align 4 // CHECK5-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_S:%.*]], align 8 +// CHECK5-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// CHECK5-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // CHECK5-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK5-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 // CHECK5-NEXT: store i32 0, i32* [[DOTOMP_COMB_LB]], align 4 @@ -4205,7 +4237,7 @@ int main() { // CHECK5-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]], !llvm.access.group !42 // CHECK5: invoke.cont: // CHECK5-NEXT: [[CALL:%.*]] = invoke signext i8 @_ZN1ScvcEv(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]]) -// CHECK5-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[TERMINATE_LPAD]], !llvm.access.group !42 +// CHECK5-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD:%.*]], !llvm.access.group !42 // CHECK5: invoke.cont2: // CHECK5-NEXT: [[TMP7:%.*]] = sext i8 [[CALL]] to i32 // CHECK5-NEXT: call void @__kmpc_push_num_threads(%struct.ident_t* @[[GLOB3]], i32 [[TMP1]], i32 [[TMP7]]), !llvm.access.group !42 @@ -4222,23 +4254,36 @@ int main() { // CHECK5-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] // CHECK5-NEXT: store i32 [[ADD]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !42 // CHECK5-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP43:![0-9]+]] +// CHECK5: lpad: +// CHECK5-NEXT: [[TMP14:%.*]] = landingpad { i8*, i32 } +// CHECK5-NEXT: catch i8* null +// CHECK5-NEXT: [[TMP15:%.*]] = extractvalue { i8*, i32 } [[TMP14]], 0 +// CHECK5-NEXT: store i8* [[TMP15]], i8** [[EXN_SLOT]], align 8, !llvm.access.group !42 +// CHECK5-NEXT: [[TMP16:%.*]] = extractvalue { i8*, i32 } [[TMP14]], 1 +// CHECK5-NEXT: store i32 [[TMP16]], i32* [[EHSELECTOR_SLOT]], align 4, !llvm.access.group !42 +// CHECK5-NEXT: call void @_ZN1SD1Ev(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]]) #[[ATTR6]], !llvm.access.group !42 +// CHECK5-NEXT: br label [[TERMINATE_HANDLER:%.*]] // CHECK5: omp.inner.for.end: // CHECK5-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK5: omp.loop.exit: // CHECK5-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB1]], i32 [[TMP1]]) -// CHECK5-NEXT: [[TMP14:%.*]] = load i32, i32* [[DOTOMP_IS_LAST]], align 4 -// CHECK5-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 -// CHECK5-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK5-NEXT: [[TMP17:%.*]] = load i32, i32* [[DOTOMP_IS_LAST]], align 4 +// CHECK5-NEXT: [[TMP18:%.*]] = icmp ne i32 [[TMP17]], 0 +// CHECK5-NEXT: br i1 [[TMP18]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] // CHECK5: .omp.final.then: // CHECK5-NEXT: store i32 100, i32* [[I]], align 4 // CHECK5-NEXT: br label [[DOTOMP_FINAL_DONE]] // CHECK5: .omp.final.done: // CHECK5-NEXT: ret void // CHECK5: terminate.lpad: -// CHECK5-NEXT: [[TMP16:%.*]] = landingpad { i8*, i32 } +// CHECK5-NEXT: [[TMP19:%.*]] = landingpad { i8*, i32 } // CHECK5-NEXT: catch i8* null -// CHECK5-NEXT: [[TMP17:%.*]] = extractvalue { i8*, i32 } [[TMP16]], 0 -// CHECK5-NEXT: call void @__clang_call_terminate(i8* [[TMP17]]) #[[ATTR10]], !llvm.access.group !42 +// CHECK5-NEXT: [[TMP20:%.*]] = extractvalue { i8*, i32 } [[TMP19]], 0 +// CHECK5-NEXT: call void @__clang_call_terminate(i8* [[TMP20]]) #[[ATTR10]], !llvm.access.group !42 +// CHECK5-NEXT: unreachable +// CHECK5: terminate.handler: +// CHECK5-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8, !llvm.access.group !42 +// CHECK5-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR10]], !llvm.access.group !42 // CHECK5-NEXT: unreachable // // @@ -5363,6 +5408,8 @@ int main() { // CHECK6-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 // CHECK6-NEXT: [[I:%.*]] = alloca i32, align 4 // CHECK6-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_S:%.*]], align 8 +// CHECK6-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// CHECK6-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // CHECK6-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK6-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 // CHECK6-NEXT: store i32 0, i32* [[DOTOMP_COMB_LB]], align 4 @@ -5396,7 +5443,7 @@ int main() { // CHECK6-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]], !llvm.access.group !42 // CHECK6: invoke.cont: // CHECK6-NEXT: [[CALL:%.*]] = invoke signext i8 @_ZN1ScvcEv(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]]) -// CHECK6-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[TERMINATE_LPAD]], !llvm.access.group !42 +// CHECK6-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD:%.*]], !llvm.access.group !42 // CHECK6: invoke.cont2: // CHECK6-NEXT: [[TMP7:%.*]] = sext i8 [[CALL]] to i32 // CHECK6-NEXT: call void @__kmpc_push_num_threads(%struct.ident_t* @[[GLOB3]], i32 [[TMP1]], i32 [[TMP7]]), !llvm.access.group !42 @@ -5413,23 +5460,36 @@ int main() { // CHECK6-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] // CHECK6-NEXT: store i32 [[ADD]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !42 // CHECK6-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP43:![0-9]+]] +// CHECK6: lpad: +// CHECK6-NEXT: [[TMP14:%.*]] = landingpad { i8*, i32 } +// CHECK6-NEXT: catch i8* null +// CHECK6-NEXT: [[TMP15:%.*]] = extractvalue { i8*, i32 } [[TMP14]], 0 +// CHECK6-NEXT: store i8* [[TMP15]], i8** [[EXN_SLOT]], align 8, !llvm.access.group !42 +// CHECK6-NEXT: [[TMP16:%.*]] = extractvalue { i8*, i32 } [[TMP14]], 1 +// CHECK6-NEXT: store i32 [[TMP16]], i32* [[EHSELECTOR_SLOT]], align 4, !llvm.access.group !42 +// CHECK6-NEXT: call void @_ZN1SD1Ev(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]]) #[[ATTR6]], !llvm.access.group !42 +// CHECK6-NEXT: br label [[TERMINATE_HANDLER:%.*]] // CHECK6: omp.inner.for.end: // CHECK6-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK6: omp.loop.exit: // CHECK6-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB1]], i32 [[TMP1]]) -// CHECK6-NEXT: [[TMP14:%.*]] = load i32, i32* [[DOTOMP_IS_LAST]], align 4 -// CHECK6-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 -// CHECK6-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK6-NEXT: [[TMP17:%.*]] = load i32, i32* [[DOTOMP_IS_LAST]], align 4 +// CHECK6-NEXT: [[TMP18:%.*]] = icmp ne i32 [[TMP17]], 0 +// CHECK6-NEXT: br i1 [[TMP18]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] // CHECK6: .omp.final.then: // CHECK6-NEXT: store i32 100, i32* [[I]], align 4 // CHECK6-NEXT: br label [[DOTOMP_FINAL_DONE]] // CHECK6: .omp.final.done: // CHECK6-NEXT: ret void // CHECK6: terminate.lpad: -// CHECK6-NEXT: [[TMP16:%.*]] = landingpad { i8*, i32 } +// CHECK6-NEXT: [[TMP19:%.*]] = landingpad { i8*, i32 } // CHECK6-NEXT: catch i8* null -// CHECK6-NEXT: [[TMP17:%.*]] = extractvalue { i8*, i32 } [[TMP16]], 0 -// CHECK6-NEXT: call void @__clang_call_terminate(i8* [[TMP17]]) #[[ATTR10]], !llvm.access.group !42 +// CHECK6-NEXT: [[TMP20:%.*]] = extractvalue { i8*, i32 } [[TMP19]], 0 +// CHECK6-NEXT: call void @__clang_call_terminate(i8* [[TMP20]]) #[[ATTR10]], !llvm.access.group !42 +// CHECK6-NEXT: unreachable +// CHECK6: terminate.handler: +// CHECK6-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8, !llvm.access.group !42 +// CHECK6-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR10]], !llvm.access.group !42 // CHECK6-NEXT: unreachable // // @@ -7241,6 +7301,8 @@ int main() { // CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 // CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 // CHECK9-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_S:%.*]], align 8 +// CHECK9-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// CHECK9-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // CHECK9-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK9-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 // CHECK9-NEXT: store i32 0, i32* [[DOTOMP_COMB_LB]], align 4 @@ -7274,7 +7336,7 @@ int main() { // CHECK9-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]], !llvm.access.group !46 // CHECK9: invoke.cont: // CHECK9-NEXT: [[CALL:%.*]] = invoke i8 @_ZN1ScvcEv(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]]) -// CHECK9-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[TERMINATE_LPAD]], !llvm.access.group !46 +// CHECK9-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD:%.*]], !llvm.access.group !46 // CHECK9: invoke.cont2: // CHECK9-NEXT: [[TMP7:%.*]] = sext i8 [[CALL]] to i32 // CHECK9-NEXT: call void @__kmpc_push_num_threads(%struct.ident_t* @[[GLOB3]], i32 [[TMP1]], i32 [[TMP7]]), !llvm.access.group !46 @@ -7291,23 +7353,36 @@ int main() { // CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] // CHECK9-NEXT: store i32 [[ADD]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !46 // CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP47:![0-9]+]] +// CHECK9: lpad: +// CHECK9-NEXT: [[TMP14:%.*]] = landingpad { i8*, i32 } +// CHECK9-NEXT: catch i8* null +// CHECK9-NEXT: [[TMP15:%.*]] = extractvalue { i8*, i32 } [[TMP14]], 0 +// CHECK9-NEXT: store i8* [[TMP15]], i8** [[EXN_SLOT]], align 8, !llvm.access.group !46 +// CHECK9-NEXT: [[TMP16:%.*]] = extractvalue { i8*, i32 } [[TMP14]], 1 +// CHECK9-NEXT: store i32 [[TMP16]], i32* [[EHSELECTOR_SLOT]], align 4, !llvm.access.group !46 +// CHECK9-NEXT: call void @_ZN1SD1Ev(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]]) #[[ATTR6]], !llvm.access.group !46 +// CHECK9-NEXT: br label [[TERMINATE_HANDLER:%.*]] // CHECK9: omp.inner.for.end: // CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK9: omp.loop.exit: // CHECK9-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB1]], i32 [[TMP1]]) -// CHECK9-NEXT: [[TMP14:%.*]] = load i32, i32* [[DOTOMP_IS_LAST]], align 4 -// CHECK9-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 -// CHECK9-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9-NEXT: [[TMP17:%.*]] = load i32, i32* [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP18:%.*]] = icmp ne i32 [[TMP17]], 0 +// CHECK9-NEXT: br i1 [[TMP18]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] // CHECK9: .omp.final.then: // CHECK9-NEXT: store i32 100, i32* [[I]], align 4 // CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] // CHECK9: .omp.final.done: // CHECK9-NEXT: ret void // CHECK9: terminate.lpad: -// CHECK9-NEXT: [[TMP16:%.*]] = landingpad { i8*, i32 } +// CHECK9-NEXT: [[TMP19:%.*]] = landingpad { i8*, i32 } // CHECK9-NEXT: catch i8* null -// CHECK9-NEXT: [[TMP17:%.*]] = extractvalue { i8*, i32 } [[TMP16]], 0 -// CHECK9-NEXT: call void @__clang_call_terminate(i8* [[TMP17]]) #[[ATTR10]], !llvm.access.group !46 +// CHECK9-NEXT: [[TMP20:%.*]] = extractvalue { i8*, i32 } [[TMP19]], 0 +// CHECK9-NEXT: call void @__clang_call_terminate(i8* [[TMP20]]) #[[ATTR10]], !llvm.access.group !46 +// CHECK9-NEXT: unreachable +// CHECK9: terminate.handler: +// CHECK9-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8, !llvm.access.group !46 +// CHECK9-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR10]], !llvm.access.group !46 // CHECK9-NEXT: unreachable // // @@ -8432,6 +8507,8 @@ int main() { // CHECK10-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 // CHECK10-NEXT: [[I:%.*]] = alloca i32, align 4 // CHECK10-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_S:%.*]], align 8 +// CHECK10-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// CHECK10-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // CHECK10-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK10-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 // CHECK10-NEXT: store i32 0, i32* [[DOTOMP_COMB_LB]], align 4 @@ -8465,7 +8542,7 @@ int main() { // CHECK10-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]], !llvm.access.group !46 // CHECK10: invoke.cont: // CHECK10-NEXT: [[CALL:%.*]] = invoke i8 @_ZN1ScvcEv(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]]) -// CHECK10-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[TERMINATE_LPAD]], !llvm.access.group !46 +// CHECK10-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD:%.*]], !llvm.access.group !46 // CHECK10: invoke.cont2: // CHECK10-NEXT: [[TMP7:%.*]] = sext i8 [[CALL]] to i32 // CHECK10-NEXT: call void @__kmpc_push_num_threads(%struct.ident_t* @[[GLOB3]], i32 [[TMP1]], i32 [[TMP7]]), !llvm.access.group !46 @@ -8482,23 +8559,36 @@ int main() { // CHECK10-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] // CHECK10-NEXT: store i32 [[ADD]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !46 // CHECK10-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP47:![0-9]+]] +// CHECK10: lpad: +// CHECK10-NEXT: [[TMP14:%.*]] = landingpad { i8*, i32 } +// CHECK10-NEXT: catch i8* null +// CHECK10-NEXT: [[TMP15:%.*]] = extractvalue { i8*, i32 } [[TMP14]], 0 +// CHECK10-NEXT: store i8* [[TMP15]], i8** [[EXN_SLOT]], align 8, !llvm.access.group !46 +// CHECK10-NEXT: [[TMP16:%.*]] = extractvalue { i8*, i32 } [[TMP14]], 1 +// CHECK10-NEXT: store i32 [[TMP16]], i32* [[EHSELECTOR_SLOT]], align 4, !llvm.access.group !46 +// CHECK10-NEXT: call void @_ZN1SD1Ev(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]]) #[[ATTR6]], !llvm.access.group !46 +// CHECK10-NEXT: br label [[TERMINATE_HANDLER:%.*]] // CHECK10: omp.inner.for.end: // CHECK10-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK10: omp.loop.exit: // CHECK10-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB1]], i32 [[TMP1]]) -// CHECK10-NEXT: [[TMP14:%.*]] = load i32, i32* [[DOTOMP_IS_LAST]], align 4 -// CHECK10-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 -// CHECK10-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK10-NEXT: [[TMP17:%.*]] = load i32, i32* [[DOTOMP_IS_LAST]], align 4 +// CHECK10-NEXT: [[TMP18:%.*]] = icmp ne i32 [[TMP17]], 0 +// CHECK10-NEXT: br i1 [[TMP18]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] // CHECK10: .omp.final.then: // CHECK10-NEXT: store i32 100, i32* [[I]], align 4 // CHECK10-NEXT: br label [[DOTOMP_FINAL_DONE]] // CHECK10: .omp.final.done: // CHECK10-NEXT: ret void // CHECK10: terminate.lpad: -// CHECK10-NEXT: [[TMP16:%.*]] = landingpad { i8*, i32 } +// CHECK10-NEXT: [[TMP19:%.*]] = landingpad { i8*, i32 } // CHECK10-NEXT: catch i8* null -// CHECK10-NEXT: [[TMP17:%.*]] = extractvalue { i8*, i32 } [[TMP16]], 0 -// CHECK10-NEXT: call void @__clang_call_terminate(i8* [[TMP17]]) #[[ATTR10]], !llvm.access.group !46 +// CHECK10-NEXT: [[TMP20:%.*]] = extractvalue { i8*, i32 } [[TMP19]], 0 +// CHECK10-NEXT: call void @__clang_call_terminate(i8* [[TMP20]]) #[[ATTR10]], !llvm.access.group !46 +// CHECK10-NEXT: unreachable +// CHECK10: terminate.handler: +// CHECK10-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8, !llvm.access.group !46 +// CHECK10-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR10]], !llvm.access.group !46 // CHECK10-NEXT: unreachable // // @@ -10292,6 +10382,8 @@ int main() { // CHECK13-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 // CHECK13-NEXT: [[I:%.*]] = alloca i32, align 4 // CHECK13-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_S:%.*]], align 8 +// CHECK13-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// CHECK13-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // CHECK13-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK13-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 // CHECK13-NEXT: store i32 0, i32* [[DOTOMP_COMB_LB]], align 4 @@ -10325,7 +10417,7 @@ int main() { // CHECK13-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]], !llvm.access.group !46 // CHECK13: invoke.cont: // CHECK13-NEXT: [[CALL:%.*]] = invoke i8 @_ZN1ScvcEv(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]]) -// CHECK13-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[TERMINATE_LPAD]], !llvm.access.group !46 +// CHECK13-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD:%.*]], !llvm.access.group !46 // CHECK13: invoke.cont2: // CHECK13-NEXT: [[TMP7:%.*]] = sext i8 [[CALL]] to i32 // CHECK13-NEXT: call void @__kmpc_push_num_threads(%struct.ident_t* @[[GLOB3]], i32 [[TMP1]], i32 [[TMP7]]), !llvm.access.group !46 @@ -10342,23 +10434,36 @@ int main() { // CHECK13-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] // CHECK13-NEXT: store i32 [[ADD]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !46 // CHECK13-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP47:![0-9]+]] +// CHECK13: lpad: +// CHECK13-NEXT: [[TMP14:%.*]] = landingpad { i8*, i32 } +// CHECK13-NEXT: catch i8* null +// CHECK13-NEXT: [[TMP15:%.*]] = extractvalue { i8*, i32 } [[TMP14]], 0 +// CHECK13-NEXT: store i8* [[TMP15]], i8** [[EXN_SLOT]], align 8, !llvm.access.group !46 +// CHECK13-NEXT: [[TMP16:%.*]] = extractvalue { i8*, i32 } [[TMP14]], 1 +// CHECK13-NEXT: store i32 [[TMP16]], i32* [[EHSELECTOR_SLOT]], align 4, !llvm.access.group !46 +// CHECK13-NEXT: call void @_ZN1SD1Ev(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]]) #[[ATTR6]], !llvm.access.group !46 +// CHECK13-NEXT: br label [[TERMINATE_HANDLER:%.*]] // CHECK13: omp.inner.for.end: // CHECK13-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK13: omp.loop.exit: // CHECK13-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB1]], i32 [[TMP1]]) -// CHECK13-NEXT: [[TMP14:%.*]] = load i32, i32* [[DOTOMP_IS_LAST]], align 4 -// CHECK13-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 -// CHECK13-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK13-NEXT: [[TMP17:%.*]] = load i32, i32* [[DOTOMP_IS_LAST]], align 4 +// CHECK13-NEXT: [[TMP18:%.*]] = icmp ne i32 [[TMP17]], 0 +// CHECK13-NEXT: br i1 [[TMP18]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] // CHECK13: .omp.final.then: // CHECK13-NEXT: store i32 100, i32* [[I]], align 4 // CHECK13-NEXT: br label [[DOTOMP_FINAL_DONE]] // CHECK13: .omp.final.done: // CHECK13-NEXT: ret void // CHECK13: terminate.lpad: -// CHECK13-NEXT: [[TMP16:%.*]] = landingpad { i8*, i32 } +// CHECK13-NEXT: [[TMP19:%.*]] = landingpad { i8*, i32 } // CHECK13-NEXT: catch i8* null -// CHECK13-NEXT: [[TMP17:%.*]] = extractvalue { i8*, i32 } [[TMP16]], 0 -// CHECK13-NEXT: call void @__clang_call_terminate(i8* [[TMP17]]) #[[ATTR10]], !llvm.access.group !46 +// CHECK13-NEXT: [[TMP20:%.*]] = extractvalue { i8*, i32 } [[TMP19]], 0 +// CHECK13-NEXT: call void @__clang_call_terminate(i8* [[TMP20]]) #[[ATTR10]], !llvm.access.group !46 +// CHECK13-NEXT: unreachable +// CHECK13: terminate.handler: +// CHECK13-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8, !llvm.access.group !46 +// CHECK13-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR10]], !llvm.access.group !46 // CHECK13-NEXT: unreachable // // @@ -11483,6 +11588,8 @@ int main() { // CHECK14-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 // CHECK14-NEXT: [[I:%.*]] = alloca i32, align 4 // CHECK14-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_S:%.*]], align 8 +// CHECK14-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// CHECK14-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // CHECK14-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK14-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 // CHECK14-NEXT: store i32 0, i32* [[DOTOMP_COMB_LB]], align 4 @@ -11516,7 +11623,7 @@ int main() { // CHECK14-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]], !llvm.access.group !46 // CHECK14: invoke.cont: // CHECK14-NEXT: [[CALL:%.*]] = invoke i8 @_ZN1ScvcEv(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]]) -// CHECK14-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[TERMINATE_LPAD]], !llvm.access.group !46 +// CHECK14-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD:%.*]], !llvm.access.group !46 // CHECK14: invoke.cont2: // CHECK14-NEXT: [[TMP7:%.*]] = sext i8 [[CALL]] to i32 // CHECK14-NEXT: call void @__kmpc_push_num_threads(%struct.ident_t* @[[GLOB3]], i32 [[TMP1]], i32 [[TMP7]]), !llvm.access.group !46 @@ -11533,23 +11640,36 @@ int main() { // CHECK14-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] // CHECK14-NEXT: store i32 [[ADD]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !46 // CHECK14-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP47:![0-9]+]] +// CHECK14: lpad: +// CHECK14-NEXT: [[TMP14:%.*]] = landingpad { i8*, i32 } +// CHECK14-NEXT: catch i8* null +// CHECK14-NEXT: [[TMP15:%.*]] = extractvalue { i8*, i32 } [[TMP14]], 0 +// CHECK14-NEXT: store i8* [[TMP15]], i8** [[EXN_SLOT]], align 8, !llvm.access.group !46 +// CHECK14-NEXT: [[TMP16:%.*]] = extractvalue { i8*, i32 } [[TMP14]], 1 +// CHECK14-NEXT: store i32 [[TMP16]], i32* [[EHSELECTOR_SLOT]], align 4, !llvm.access.group !46 +// CHECK14-NEXT: call void @_ZN1SD1Ev(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]]) #[[ATTR6]], !llvm.access.group !46 +// CHECK14-NEXT: br label [[TERMINATE_HANDLER:%.*]] // CHECK14: omp.inner.for.end: // CHECK14-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK14: omp.loop.exit: // CHECK14-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB1]], i32 [[TMP1]]) -// CHECK14-NEXT: [[TMP14:%.*]] = load i32, i32* [[DOTOMP_IS_LAST]], align 4 -// CHECK14-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 -// CHECK14-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK14-NEXT: [[TMP17:%.*]] = load i32, i32* [[DOTOMP_IS_LAST]], align 4 +// CHECK14-NEXT: [[TMP18:%.*]] = icmp ne i32 [[TMP17]], 0 +// CHECK14-NEXT: br i1 [[TMP18]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] // CHECK14: .omp.final.then: // CHECK14-NEXT: store i32 100, i32* [[I]], align 4 // CHECK14-NEXT: br label [[DOTOMP_FINAL_DONE]] // CHECK14: .omp.final.done: // CHECK14-NEXT: ret void // CHECK14: terminate.lpad: -// CHECK14-NEXT: [[TMP16:%.*]] = landingpad { i8*, i32 } +// CHECK14-NEXT: [[TMP19:%.*]] = landingpad { i8*, i32 } // CHECK14-NEXT: catch i8* null -// CHECK14-NEXT: [[TMP17:%.*]] = extractvalue { i8*, i32 } [[TMP16]], 0 -// CHECK14-NEXT: call void @__clang_call_terminate(i8* [[TMP17]]) #[[ATTR10]], !llvm.access.group !46 +// CHECK14-NEXT: [[TMP20:%.*]] = extractvalue { i8*, i32 } [[TMP19]], 0 +// CHECK14-NEXT: call void @__clang_call_terminate(i8* [[TMP20]]) #[[ATTR10]], !llvm.access.group !46 +// CHECK14-NEXT: unreachable +// CHECK14: terminate.handler: +// CHECK14-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8, !llvm.access.group !46 +// CHECK14-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR10]], !llvm.access.group !46 // CHECK14-NEXT: unreachable // // diff --git a/clang/test/OpenMP/openmp_win_codegen.cpp b/clang/test/OpenMP/openmp_win_codegen.cpp index 77e83d90fa8806..4ccb85e93f1125 100644 --- a/clang/test/OpenMP/openmp_win_codegen.cpp +++ b/clang/test/OpenMP/openmp_win_codegen.cpp @@ -73,7 +73,7 @@ int main() { // CHECK1-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4 // CHECK1-NEXT: call void @__kmpc_critical(%struct.ident_t* @[[GLOB1]], i32 [[TMP3]], [8 x i32]* @.gomp_critical_user_.var) [ "funclet"(token [[TMP1]]) ] // CHECK1-NEXT: invoke void @"?bar@@YAXXZ"() [ "funclet"(token [[TMP1]]) ] -// CHECK1-NEXT: to label [[INVOKE_CONT1:%.*]] unwind label [[TERMINATE2:%.*]] +// CHECK1-NEXT: to label [[INVOKE_CONT1:%.*]] unwind label [[EHCLEANUP:%.*]] // CHECK1: invoke.cont1: // CHECK1-NEXT: call void @__kmpc_end_critical(%struct.ident_t* @[[GLOB1]], i32 [[TMP3]], [8 x i32]* @.gomp_critical_user_.var) [ "funclet"(token [[TMP1]]) ] // CHECK1-NEXT: catchret from [[TMP1]] to label [[CATCHRET_DEST:%.*]] @@ -83,13 +83,17 @@ int main() { // CHECK1-NEXT: ret void // CHECK1: invoke.cont: // CHECK1-NEXT: br label [[TRY_CONT]] +// CHECK1: ehcleanup: +// CHECK1-NEXT: [[TMP4:%.*]] = cleanuppad within [[TMP1]] [] +// CHECK1-NEXT: call void @__kmpc_end_critical(%struct.ident_t* @[[GLOB1]], i32 [[TMP3]], [8 x i32]* @.gomp_critical_user_.var) [ "funclet"(token [[TMP4]]) ] +// CHECK1-NEXT: cleanupret from [[TMP4]] unwind label [[TERMINATE2:%.*]] // CHECK1: terminate: -// CHECK1-NEXT: [[TMP4:%.*]] = cleanuppad within none [] -// CHECK1-NEXT: call void @"?terminate@@YAXXZ"() #[[ATTR7:[0-9]+]] [ "funclet"(token [[TMP4]]) ] +// CHECK1-NEXT: [[TMP5:%.*]] = cleanuppad within none [] +// CHECK1-NEXT: call void @"?terminate@@YAXXZ"() #[[ATTR7:[0-9]+]] [ "funclet"(token [[TMP5]]) ] // CHECK1-NEXT: unreachable // CHECK1: terminate2: -// CHECK1-NEXT: [[TMP5:%.*]] = cleanuppad within [[TMP1]] [] -// CHECK1-NEXT: call void @"?terminate@@YAXXZ"() #[[ATTR7]] [ "funclet"(token [[TMP5]]) ] +// CHECK1-NEXT: [[TMP6:%.*]] = cleanuppad within [[TMP1]] [] +// CHECK1-NEXT: call void @"?terminate@@YAXXZ"() #[[ATTR7]] [ "funclet"(token [[TMP6]]) ] // CHECK1-NEXT: unreachable // // @@ -151,3 +155,4 @@ int main() { // CHECK1-NEXT: store i32 [[TMP12]], i32* [[TMP8]], align 4 // CHECK1-NEXT: ret void // +// \ No newline at end of file diff --git a/clang/test/OpenMP/ordered_doacross_codegen.cpp b/clang/test/OpenMP/ordered_doacross_codegen.cpp index 223da438e9634d..1893ed07d13c49 100644 --- a/clang/test/OpenMP/ordered_doacross_codegen.cpp +++ b/clang/test/OpenMP/ordered_doacross_codegen.cpp @@ -88,6 +88,9 @@ int main() { #pragma omp ordered depend(sink : i - 2) d[i] = a[i - 2]; } + // CHECK: landingpad + // CHECK-NORMAL: call void @__kmpc_doacross_fini([[IDENT]], i32 [[GTID]]) + // CHECK: br label % // CHECK: call void @__kmpc_for_static_fini( // CHECK-NORMAL: call void @__kmpc_doacross_fini([[IDENT]], i32 [[GTID]]) @@ -147,6 +150,10 @@ int main1() { #pragma omp ordered depend(sink : i - 2) d[i] = a[i - 2]; } + // CHECK: landingpad + // CHECK-NORMAL: call void @__kmpc_doacross_fini([[IDENT]], i32 [[GTID]]) + // CHECK: br label % + // CHECK: call void @__kmpc_for_static_fini( // CHECK-NORMAL: call void @__kmpc_doacross_fini([[IDENT]], i32 [[GTID]]) // CHECK: ret i32 0 @@ -260,6 +267,10 @@ struct TestStruct { baz(a[i][j], b[i][j]); } } + // CHECK: landingpad + // CHECK-NORMAL: call void @__kmpc_doacross_fini([[IDENT]], i32 [[GTID]]) + // CHECK: br label % + // CHECK: call void @__kmpc_for_static_fini( // CHECK-NORMAL: call void @__kmpc_doacross_fini([[IDENT]], i32 [[GTID]]) // CHECK: ret diff --git a/clang/test/OpenMP/parallel_master_codegen.cpp b/clang/test/OpenMP/parallel_master_codegen.cpp index 14ce5f9c2a68d6..212fc8a6cc07e9 100644 --- a/clang/test/OpenMP/parallel_master_codegen.cpp +++ b/clang/test/OpenMP/parallel_master_codegen.cpp @@ -305,6 +305,8 @@ void parallel_master_allocate() { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 +// CHECK1-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// CHECK1-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // 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 @@ -314,17 +316,24 @@ void parallel_master_allocate() { // CHECK1-NEXT: br i1 [[TMP3]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_END:%.*]] // CHECK1: omp_if.then: // CHECK1-NEXT: invoke void @_Z3foov() -// CHECK1-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]] +// CHECK1-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] // CHECK1: invoke.cont: // CHECK1-NEXT: call void @__kmpc_end_master(%struct.ident_t* @[[GLOB1]], i32 [[TMP1]]) // CHECK1-NEXT: br label [[OMP_IF_END]] -// CHECK1: omp_if.end: -// CHECK1-NEXT: ret void -// CHECK1: terminate.lpad: +// CHECK1: lpad: // CHECK1-NEXT: [[TMP4:%.*]] = landingpad { i8*, i32 } // CHECK1-NEXT: catch i8* null // CHECK1-NEXT: [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 0 -// CHECK1-NEXT: call void @__clang_call_terminate(i8* [[TMP5]]) #[[ATTR6:[0-9]+]] +// CHECK1-NEXT: store i8* [[TMP5]], i8** [[EXN_SLOT]], align 8 +// CHECK1-NEXT: [[TMP6:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 1 +// CHECK1-NEXT: store i32 [[TMP6]], i32* [[EHSELECTOR_SLOT]], align 4 +// CHECK1-NEXT: call void @__kmpc_end_master(%struct.ident_t* @[[GLOB1]], i32 [[TMP1]]) +// CHECK1-NEXT: br label [[TERMINATE_HANDLER:%.*]] +// CHECK1: omp_if.end: +// CHECK1-NEXT: ret void +// CHECK1: terminate.handler: +// CHECK1-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8 +// CHECK1-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR6:[0-9]+]] // CHECK1-NEXT: unreachable // // @@ -354,6 +363,8 @@ void parallel_master_allocate() { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK2-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 +// CHECK2-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// CHECK2-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // 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 @@ -363,17 +374,24 @@ void parallel_master_allocate() { // CHECK2-NEXT: br i1 [[TMP3]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_END:%.*]] // CHECK2: omp_if.then: // CHECK2-NEXT: invoke void @_Z3foov() -// CHECK2-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]] +// CHECK2-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] // CHECK2: invoke.cont: // CHECK2-NEXT: call void @__kmpc_end_master(%struct.ident_t* @[[GLOB1]], i32 [[TMP1]]) // CHECK2-NEXT: br label [[OMP_IF_END]] -// CHECK2: omp_if.end: -// CHECK2-NEXT: ret void -// CHECK2: terminate.lpad: +// CHECK2: lpad: // CHECK2-NEXT: [[TMP4:%.*]] = landingpad { i8*, i32 } // CHECK2-NEXT: catch i8* null // CHECK2-NEXT: [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 0 -// CHECK2-NEXT: call void @__clang_call_terminate(i8* [[TMP5]]) #[[ATTR6:[0-9]+]] +// CHECK2-NEXT: store i8* [[TMP5]], i8** [[EXN_SLOT]], align 8 +// CHECK2-NEXT: [[TMP6:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 1 +// CHECK2-NEXT: store i32 [[TMP6]], i32* [[EHSELECTOR_SLOT]], align 4 +// CHECK2-NEXT: call void @__kmpc_end_master(%struct.ident_t* @[[GLOB1]], i32 [[TMP1]]) +// CHECK2-NEXT: br label [[TERMINATE_HANDLER:%.*]] +// CHECK2: omp_if.end: +// CHECK2-NEXT: ret void +// CHECK2: terminate.handler: +// CHECK2-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8 +// CHECK2-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR6:[0-9]+]] // CHECK2-NEXT: unreachable // // diff --git a/clang/test/OpenMP/single_codegen.cpp b/clang/test/OpenMP/single_codegen.cpp index 21a1c3dc15b10e..ae8df718d91e46 100644 --- a/clang/test/OpenMP/single_codegen.cpp +++ b/clang/test/OpenMP/single_codegen.cpp @@ -88,6 +88,15 @@ int main() { } + + + + + + + + + void parallel_single() { #pragma omp parallel #pragma omp single @@ -108,6 +117,21 @@ void array_func(int n, int a[n], St s[2]) { } #endif + +// Private a +// Private b +// Private c + + + + + + + +// Private a +// Private b +// Private c + // CHECK1-LABEL: define {{[^@]+}}@.__kmpc_global_ctor_. // CHECK1-SAME: (i8* [[TMP0:%.*]]) #[[ATTR0:[0-9]+]] { // CHECK1-NEXT: entry: @@ -337,6 +361,8 @@ void array_func(int n, int a[n], St s[2]) { // CHECK1-NEXT: [[SST:%.*]] = alloca [[STRUCT_SST:%.*]], align 8 // CHECK1-NEXT: [[SS:%.*]] = alloca [[STRUCT_SS:%.*]], align 8 // CHECK1-NEXT: [[DOTOMP_COPYPRIVATE_DID_IT:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// CHECK1-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[DOTOMP_COPYPRIVATE_CPR_LIST:%.*]] = alloca [5 x i8*], align 8 // CHECK1-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1]]) // CHECK1-NEXT: store i32 0, i32* [[RETVAL]], align 4 @@ -366,40 +392,47 @@ void array_func(int n, int a[n], St s[2]) { // CHECK1-NEXT: br i1 [[TMP6]], label [[OMP_IF_THEN3:%.*]], label [[OMP_IF_END4:%.*]] // CHECK1: omp_if.then3: // CHECK1-NEXT: invoke void @_Z3foov() -// CHECK1-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]] +// CHECK1-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] // CHECK1: invoke.cont: // CHECK1-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]]) // CHECK1-NEXT: store i32 1, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4 // CHECK1-NEXT: br label [[OMP_IF_END4]] +// CHECK1: lpad: +// CHECK1-NEXT: [[TMP7:%.*]] = landingpad { i8*, i32 } +// CHECK1-NEXT: catch i8* null +// CHECK1-NEXT: [[TMP8:%.*]] = extractvalue { i8*, i32 } [[TMP7]], 0 +// CHECK1-NEXT: store i8* [[TMP8]], i8** [[EXN_SLOT]], align 8 +// CHECK1-NEXT: [[TMP9:%.*]] = extractvalue { i8*, i32 } [[TMP7]], 1 +// CHECK1-NEXT: store i32 [[TMP9]], i32* [[EHSELECTOR_SLOT]], align 4 +// CHECK1-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]]) +// CHECK1-NEXT: br label [[TERMINATE_HANDLER:%.*]] // CHECK1: omp_if.end4: -// CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 0 -// CHECK1-NEXT: store i8* [[A]], i8** [[TMP7]], align 8 -// CHECK1-NEXT: [[TMP8:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 1 -// CHECK1-NEXT: store i8* bitcast (%class.TestClass* @tc to i8*), i8** [[TMP8]], align 8 -// CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 2 -// CHECK1-NEXT: [[TMP10:%.*]] = call i8* @__kmpc_threadprivate_cached(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]], i8* bitcast (%class.TestClass* @tc to i8*), i64 4, i8*** @tc.cache.) -// CHECK1-NEXT: [[TMP11:%.*]] = bitcast i8* [[TMP10]] to %class.TestClass* -// CHECK1-NEXT: [[TMP12:%.*]] = bitcast %class.TestClass* [[TMP11]] to i8* -// CHECK1-NEXT: store i8* [[TMP12]], i8** [[TMP9]], align 8 -// CHECK1-NEXT: [[TMP13:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 3 -// CHECK1-NEXT: [[TMP14:%.*]] = bitcast [2 x i8]* [[A2]] to i8* -// CHECK1-NEXT: store i8* [[TMP14]], i8** [[TMP13]], align 8 -// CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 4 -// CHECK1-NEXT: [[TMP16:%.*]] = call i8* @__kmpc_threadprivate_cached(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]], i8* bitcast ([2 x %class.TestClass]* @tc2 to i8*), i64 8, i8*** @tc2.cache.) -// CHECK1-NEXT: [[TMP17:%.*]] = bitcast i8* [[TMP16]] to [2 x %class.TestClass]* -// CHECK1-NEXT: [[TMP18:%.*]] = bitcast [2 x %class.TestClass]* [[TMP17]] to i8* -// CHECK1-NEXT: store i8* [[TMP18]], i8** [[TMP15]], align 8 -// CHECK1-NEXT: [[TMP19:%.*]] = bitcast [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]] to i8* -// CHECK1-NEXT: [[TMP20:%.*]] = load i32, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4 -// CHECK1-NEXT: call void @__kmpc_copyprivate(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]], i64 40, i8* [[TMP19]], void (i8*, i8*)* @.omp.copyprivate.copy_func, i32 [[TMP20]]) -// CHECK1-NEXT: [[TMP21:%.*]] = load i8, i8* [[A]], align 1 -// CHECK1-NEXT: [[CONV:%.*]] = sext i8 [[TMP21]] to i32 +// CHECK1-NEXT: [[TMP10:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 0 +// CHECK1-NEXT: store i8* [[A]], i8** [[TMP10]], align 8 +// CHECK1-NEXT: [[TMP11:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 1 +// CHECK1-NEXT: store i8* bitcast (%class.TestClass* @tc to i8*), i8** [[TMP11]], align 8 +// CHECK1-NEXT: [[TMP12:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 2 +// CHECK1-NEXT: [[TMP13:%.*]] = call i8* @__kmpc_threadprivate_cached(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]], i8* bitcast (%class.TestClass* @tc to i8*), i64 4, i8*** @tc.cache.) +// CHECK1-NEXT: [[TMP14:%.*]] = bitcast i8* [[TMP13]] to %class.TestClass* +// CHECK1-NEXT: [[TMP15:%.*]] = bitcast %class.TestClass* [[TMP14]] to i8* +// CHECK1-NEXT: store i8* [[TMP15]], i8** [[TMP12]], align 8 +// CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 3 +// CHECK1-NEXT: [[TMP17:%.*]] = bitcast [2 x i8]* [[A2]] to i8* +// CHECK1-NEXT: store i8* [[TMP17]], i8** [[TMP16]], align 8 +// CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 4 +// CHECK1-NEXT: [[TMP19:%.*]] = call i8* @__kmpc_threadprivate_cached(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]], i8* bitcast ([2 x %class.TestClass]* @tc2 to i8*), i64 8, i8*** @tc2.cache.) +// CHECK1-NEXT: [[TMP20:%.*]] = bitcast i8* [[TMP19]] to [2 x %class.TestClass]* +// CHECK1-NEXT: [[TMP21:%.*]] = bitcast [2 x %class.TestClass]* [[TMP20]] to i8* +// CHECK1-NEXT: store i8* [[TMP21]], i8** [[TMP18]], align 8 +// CHECK1-NEXT: [[TMP22:%.*]] = bitcast [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]] to i8* +// CHECK1-NEXT: [[TMP23:%.*]] = load i32, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4 +// CHECK1-NEXT: call void @__kmpc_copyprivate(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]], i64 40, i8* [[TMP22]], void (i8*, i8*)* @.omp.copyprivate.copy_func, i32 [[TMP23]]) +// CHECK1-NEXT: [[TMP24:%.*]] = load i8, i8* [[A]], align 1 +// CHECK1-NEXT: [[CONV:%.*]] = sext i8 [[TMP24]] to i32 // CHECK1-NEXT: ret i32 [[CONV]] -// CHECK1: terminate.lpad: -// CHECK1-NEXT: [[TMP22:%.*]] = landingpad { i8*, i32 } -// CHECK1-NEXT: catch i8* null -// CHECK1-NEXT: [[TMP23:%.*]] = extractvalue { i8*, i32 } [[TMP22]], 0 -// CHECK1-NEXT: call void @__clang_call_terminate(i8* [[TMP23]]) #[[ATTR13:[0-9]+]] +// CHECK1: terminate.handler: +// CHECK1-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8 +// CHECK1-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR13:[0-9]+]] // CHECK1-NEXT: unreachable // // @@ -533,6 +566,8 @@ void array_func(int n, int a[n], St s[2]) { // CHECK1-NEXT: [[_TMP1:%.*]] = alloca double*, align 8 // CHECK1-NEXT: [[DOTOMP_COPYPRIVATE_DID_IT:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[REF_TMP:%.*]] = alloca [[CLASS_ANON:%.*]], align 8 +// CHECK1-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// CHECK1-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[DOTOMP_COPYPRIVATE_CPR_LIST:%.*]] = alloca [1 x i8*], 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 @@ -556,25 +591,32 @@ void array_func(int n, int a[n], St s[2]) { // CHECK1-NEXT: [[TMP8:%.*]] = load double*, double** [[_TMP1]], align 8 // CHECK1-NEXT: store double* [[TMP8]], double** [[TMP7]], align 8 // CHECK1-NEXT: invoke void @_ZZN3SSTIdEC1EvENKUlvE_clEv(%class.anon* nonnull align 8 dereferenceable(16) [[REF_TMP]]) -// CHECK1-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]] +// CHECK1-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] // CHECK1: invoke.cont: // CHECK1-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB1]], i32 [[TMP3]]) // CHECK1-NEXT: store i32 1, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4 // CHECK1-NEXT: br label [[OMP_IF_END]] +// CHECK1: lpad: +// CHECK1-NEXT: [[TMP9:%.*]] = landingpad { i8*, i32 } +// CHECK1-NEXT: catch i8* null +// CHECK1-NEXT: [[TMP10:%.*]] = extractvalue { i8*, i32 } [[TMP9]], 0 +// CHECK1-NEXT: store i8* [[TMP10]], i8** [[EXN_SLOT]], align 8 +// CHECK1-NEXT: [[TMP11:%.*]] = extractvalue { i8*, i32 } [[TMP9]], 1 +// CHECK1-NEXT: store i32 [[TMP11]], i32* [[EHSELECTOR_SLOT]], align 4 +// CHECK1-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB1]], i32 [[TMP3]]) +// CHECK1-NEXT: br label [[TERMINATE_HANDLER:%.*]] // CHECK1: omp_if.end: -// CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 0 -// CHECK1-NEXT: [[TMP10:%.*]] = load double*, double** [[_TMP1]], align 8 -// CHECK1-NEXT: [[TMP11:%.*]] = bitcast double* [[TMP10]] to i8* -// CHECK1-NEXT: store i8* [[TMP11]], i8** [[TMP9]], align 8 -// CHECK1-NEXT: [[TMP12:%.*]] = bitcast [1 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]] to i8* -// CHECK1-NEXT: [[TMP13:%.*]] = load i32, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4 -// CHECK1-NEXT: call void @__kmpc_copyprivate(%struct.ident_t* @[[GLOB1]], i32 [[TMP3]], i64 8, i8* [[TMP12]], void (i8*, i8*)* @.omp.copyprivate.copy_func.5, i32 [[TMP13]]) +// CHECK1-NEXT: [[TMP12:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 0 +// CHECK1-NEXT: [[TMP13:%.*]] = load double*, double** [[_TMP1]], align 8 +// CHECK1-NEXT: [[TMP14:%.*]] = bitcast double* [[TMP13]] to i8* +// CHECK1-NEXT: store i8* [[TMP14]], i8** [[TMP12]], align 8 +// CHECK1-NEXT: [[TMP15:%.*]] = bitcast [1 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]] to i8* +// CHECK1-NEXT: [[TMP16:%.*]] = load i32, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4 +// CHECK1-NEXT: call void @__kmpc_copyprivate(%struct.ident_t* @[[GLOB1]], i32 [[TMP3]], i64 8, i8* [[TMP15]], void (i8*, i8*)* @.omp.copyprivate.copy_func.5, i32 [[TMP16]]) // CHECK1-NEXT: ret void -// CHECK1: terminate.lpad: -// CHECK1-NEXT: [[TMP14:%.*]] = landingpad { i8*, i32 } -// CHECK1-NEXT: catch i8* null -// CHECK1-NEXT: [[TMP15:%.*]] = extractvalue { i8*, i32 } [[TMP14]], 0 -// CHECK1-NEXT: call void @__clang_call_terminate(i8* [[TMP15]]) #[[ATTR13]] +// CHECK1: terminate.handler: +// CHECK1-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8 +// CHECK1-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR13]] // CHECK1-NEXT: unreachable // // @@ -778,6 +820,8 @@ void array_func(int n, int a[n], St s[2]) { // CHECK1-NEXT: [[_TMP5:%.*]] = alloca i32*, align 8 // CHECK1-NEXT: [[DOTOMP_COPYPRIVATE_DID_IT:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[REF_TMP:%.*]] = alloca [[CLASS_ANON_1:%.*]], align 8 +// CHECK1-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// CHECK1-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[DOTOMP_COPYPRIVATE_CPR_LIST:%.*]] = alloca [3 x i8*], 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 @@ -813,32 +857,39 @@ void array_func(int n, int a[n], St s[2]) { // CHECK1-NEXT: [[TMP12:%.*]] = load i32*, i32** [[_TMP5]], align 8 // CHECK1-NEXT: store i32* [[TMP12]], i32** [[TMP11]], align 8 // CHECK1-NEXT: invoke void @_ZZN2SSC1ERiENKUlvE_clEv(%class.anon.1* nonnull align 8 dereferenceable(32) [[REF_TMP]]) -// CHECK1-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]] +// CHECK1-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] // CHECK1: invoke.cont: // CHECK1-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB1]], i32 [[TMP4]]) // CHECK1-NEXT: store i32 1, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4 // CHECK1-NEXT: br label [[OMP_IF_END]] +// CHECK1: lpad: +// CHECK1-NEXT: [[TMP13:%.*]] = landingpad { i8*, i32 } +// CHECK1-NEXT: catch i8* null +// CHECK1-NEXT: [[TMP14:%.*]] = extractvalue { i8*, i32 } [[TMP13]], 0 +// CHECK1-NEXT: store i8* [[TMP14]], i8** [[EXN_SLOT]], align 8 +// CHECK1-NEXT: [[TMP15:%.*]] = extractvalue { i8*, i32 } [[TMP13]], 1 +// CHECK1-NEXT: store i32 [[TMP15]], i32* [[EHSELECTOR_SLOT]], align 4 +// CHECK1-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB1]], i32 [[TMP4]]) +// CHECK1-NEXT: br label [[TERMINATE_HANDLER:%.*]] // CHECK1: omp_if.end: -// CHECK1-NEXT: [[TMP13:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 0 -// CHECK1-NEXT: [[TMP14:%.*]] = load i32*, i32** [[_TMP4]], align 8 -// CHECK1-NEXT: [[TMP15:%.*]] = bitcast i32* [[TMP14]] to i8* -// CHECK1-NEXT: store i8* [[TMP15]], i8** [[TMP13]], align 8 -// CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 1 -// CHECK1-NEXT: [[TMP17:%.*]] = bitcast i32* [[CONV1]] to i8* -// CHECK1-NEXT: store i8* [[TMP17]], i8** [[TMP16]], align 8 -// CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 2 -// CHECK1-NEXT: [[TMP19:%.*]] = load i32*, i32** [[_TMP5]], align 8 -// CHECK1-NEXT: [[TMP20:%.*]] = bitcast i32* [[TMP19]] to i8* -// CHECK1-NEXT: store i8* [[TMP20]], i8** [[TMP18]], align 8 -// CHECK1-NEXT: [[TMP21:%.*]] = bitcast [3 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]] to i8* -// CHECK1-NEXT: [[TMP22:%.*]] = load i32, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4 -// CHECK1-NEXT: call void @__kmpc_copyprivate(%struct.ident_t* @[[GLOB1]], i32 [[TMP4]], i64 24, i8* [[TMP21]], void (i8*, i8*)* @.omp.copyprivate.copy_func.9, i32 [[TMP22]]) +// CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 0 +// CHECK1-NEXT: [[TMP17:%.*]] = load i32*, i32** [[_TMP4]], align 8 +// CHECK1-NEXT: [[TMP18:%.*]] = bitcast i32* [[TMP17]] to i8* +// CHECK1-NEXT: store i8* [[TMP18]], i8** [[TMP16]], align 8 +// CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 1 +// CHECK1-NEXT: [[TMP20:%.*]] = bitcast i32* [[CONV1]] to i8* +// CHECK1-NEXT: store i8* [[TMP20]], i8** [[TMP19]], align 8 +// CHECK1-NEXT: [[TMP21:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 2 +// CHECK1-NEXT: [[TMP22:%.*]] = load i32*, i32** [[_TMP5]], align 8 +// CHECK1-NEXT: [[TMP23:%.*]] = bitcast i32* [[TMP22]] to i8* +// CHECK1-NEXT: store i8* [[TMP23]], i8** [[TMP21]], align 8 +// CHECK1-NEXT: [[TMP24:%.*]] = bitcast [3 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]] to i8* +// CHECK1-NEXT: [[TMP25:%.*]] = load i32, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4 +// CHECK1-NEXT: call void @__kmpc_copyprivate(%struct.ident_t* @[[GLOB1]], i32 [[TMP4]], i64 24, i8* [[TMP24]], void (i8*, i8*)* @.omp.copyprivate.copy_func.9, i32 [[TMP25]]) // CHECK1-NEXT: ret void -// CHECK1: terminate.lpad: -// CHECK1-NEXT: [[TMP23:%.*]] = landingpad { i8*, i32 } -// CHECK1-NEXT: catch i8* null -// CHECK1-NEXT: [[TMP24:%.*]] = extractvalue { i8*, i32 } [[TMP23]], 0 -// CHECK1-NEXT: call void @__clang_call_terminate(i8* [[TMP24]]) #[[ATTR13]] +// CHECK1: terminate.handler: +// CHECK1-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8 +// CHECK1-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR13]] // CHECK1-NEXT: unreachable // // @@ -1048,6 +1099,8 @@ void array_func(int n, int a[n], St s[2]) { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 +// CHECK1-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// CHECK1-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // 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 @@ -1057,18 +1110,25 @@ void array_func(int n, int a[n], St s[2]) { // CHECK1-NEXT: br i1 [[TMP3]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_END:%.*]] // CHECK1: omp_if.then: // CHECK1-NEXT: invoke void @_Z3foov() -// CHECK1-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]] +// CHECK1-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] // CHECK1: invoke.cont: // CHECK1-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB1]], i32 [[TMP1]]) // CHECK1-NEXT: br label [[OMP_IF_END]] -// CHECK1: omp_if.end: -// CHECK1-NEXT: call void @__kmpc_barrier(%struct.ident_t* @[[GLOB2]], i32 [[TMP1]]) -// CHECK1-NEXT: ret void -// CHECK1: terminate.lpad: +// CHECK1: lpad: // CHECK1-NEXT: [[TMP4:%.*]] = landingpad { i8*, i32 } // CHECK1-NEXT: catch i8* null // CHECK1-NEXT: [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 0 -// CHECK1-NEXT: call void @__clang_call_terminate(i8* [[TMP5]]) #[[ATTR13]] +// CHECK1-NEXT: store i8* [[TMP5]], i8** [[EXN_SLOT]], align 8 +// CHECK1-NEXT: [[TMP6:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 1 +// CHECK1-NEXT: store i32 [[TMP6]], i32* [[EHSELECTOR_SLOT]], align 4 +// CHECK1-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB1]], i32 [[TMP1]]) +// CHECK1-NEXT: br label [[TERMINATE_HANDLER:%.*]] +// CHECK1: omp_if.end: +// CHECK1-NEXT: call void @__kmpc_barrier(%struct.ident_t* @[[GLOB2]], i32 [[TMP1]]) +// CHECK1-NEXT: ret void +// CHECK1: terminate.handler: +// CHECK1-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8 +// CHECK1-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR13]] // CHECK1-NEXT: unreachable // // @@ -1291,6 +1351,8 @@ void array_func(int n, int a[n], St s[2]) { // CHECK2-NEXT: [[SST:%.*]] = alloca [[STRUCT_SST:%.*]], align 8 // CHECK2-NEXT: [[SS:%.*]] = alloca [[STRUCT_SS:%.*]], align 8 // CHECK2-NEXT: [[DOTOMP_COPYPRIVATE_DID_IT:%.*]] = alloca i32, align 4 +// CHECK2-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// CHECK2-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // CHECK2-NEXT: [[DOTOMP_COPYPRIVATE_CPR_LIST:%.*]] = alloca [5 x i8*], align 8 // CHECK2-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1]]) // CHECK2-NEXT: store i32 0, i32* [[RETVAL]], align 4 @@ -1320,40 +1382,47 @@ void array_func(int n, int a[n], St s[2]) { // CHECK2-NEXT: br i1 [[TMP6]], label [[OMP_IF_THEN3:%.*]], label [[OMP_IF_END4:%.*]] // CHECK2: omp_if.then3: // CHECK2-NEXT: invoke void @_Z3foov() -// CHECK2-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]] +// CHECK2-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] // CHECK2: invoke.cont: // CHECK2-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]]) // CHECK2-NEXT: store i32 1, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4 // CHECK2-NEXT: br label [[OMP_IF_END4]] +// CHECK2: lpad: +// CHECK2-NEXT: [[TMP7:%.*]] = landingpad { i8*, i32 } +// CHECK2-NEXT: catch i8* null +// CHECK2-NEXT: [[TMP8:%.*]] = extractvalue { i8*, i32 } [[TMP7]], 0 +// CHECK2-NEXT: store i8* [[TMP8]], i8** [[EXN_SLOT]], align 8 +// CHECK2-NEXT: [[TMP9:%.*]] = extractvalue { i8*, i32 } [[TMP7]], 1 +// CHECK2-NEXT: store i32 [[TMP9]], i32* [[EHSELECTOR_SLOT]], align 4 +// CHECK2-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]]) +// CHECK2-NEXT: br label [[TERMINATE_HANDLER:%.*]] // CHECK2: omp_if.end4: -// CHECK2-NEXT: [[TMP7:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 0 -// CHECK2-NEXT: store i8* [[A]], i8** [[TMP7]], align 8 -// CHECK2-NEXT: [[TMP8:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 1 -// CHECK2-NEXT: store i8* bitcast (%class.TestClass* @tc to i8*), i8** [[TMP8]], align 8 -// CHECK2-NEXT: [[TMP9:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 2 -// CHECK2-NEXT: [[TMP10:%.*]] = call i8* @__kmpc_threadprivate_cached(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]], i8* bitcast (%class.TestClass* @tc to i8*), i64 4, i8*** @tc.cache.) -// CHECK2-NEXT: [[TMP11:%.*]] = bitcast i8* [[TMP10]] to %class.TestClass* -// CHECK2-NEXT: [[TMP12:%.*]] = bitcast %class.TestClass* [[TMP11]] to i8* -// CHECK2-NEXT: store i8* [[TMP12]], i8** [[TMP9]], align 8 -// CHECK2-NEXT: [[TMP13:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 3 -// CHECK2-NEXT: [[TMP14:%.*]] = bitcast [2 x i8]* [[A2]] to i8* -// CHECK2-NEXT: store i8* [[TMP14]], i8** [[TMP13]], align 8 -// CHECK2-NEXT: [[TMP15:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 4 -// CHECK2-NEXT: [[TMP16:%.*]] = call i8* @__kmpc_threadprivate_cached(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]], i8* bitcast ([2 x %class.TestClass]* @tc2 to i8*), i64 8, i8*** @tc2.cache.) -// CHECK2-NEXT: [[TMP17:%.*]] = bitcast i8* [[TMP16]] to [2 x %class.TestClass]* -// CHECK2-NEXT: [[TMP18:%.*]] = bitcast [2 x %class.TestClass]* [[TMP17]] to i8* -// CHECK2-NEXT: store i8* [[TMP18]], i8** [[TMP15]], align 8 -// CHECK2-NEXT: [[TMP19:%.*]] = bitcast [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]] to i8* -// CHECK2-NEXT: [[TMP20:%.*]] = load i32, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4 -// CHECK2-NEXT: call void @__kmpc_copyprivate(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]], i64 40, i8* [[TMP19]], void (i8*, i8*)* @.omp.copyprivate.copy_func, i32 [[TMP20]]) -// CHECK2-NEXT: [[TMP21:%.*]] = load i8, i8* [[A]], align 1 -// CHECK2-NEXT: [[CONV:%.*]] = sext i8 [[TMP21]] to i32 +// CHECK2-NEXT: [[TMP10:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 0 +// CHECK2-NEXT: store i8* [[A]], i8** [[TMP10]], align 8 +// CHECK2-NEXT: [[TMP11:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 1 +// CHECK2-NEXT: store i8* bitcast (%class.TestClass* @tc to i8*), i8** [[TMP11]], align 8 +// CHECK2-NEXT: [[TMP12:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 2 +// CHECK2-NEXT: [[TMP13:%.*]] = call i8* @__kmpc_threadprivate_cached(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]], i8* bitcast (%class.TestClass* @tc to i8*), i64 4, i8*** @tc.cache.) +// CHECK2-NEXT: [[TMP14:%.*]] = bitcast i8* [[TMP13]] to %class.TestClass* +// CHECK2-NEXT: [[TMP15:%.*]] = bitcast %class.TestClass* [[TMP14]] to i8* +// CHECK2-NEXT: store i8* [[TMP15]], i8** [[TMP12]], align 8 +// CHECK2-NEXT: [[TMP16:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 3 +// CHECK2-NEXT: [[TMP17:%.*]] = bitcast [2 x i8]* [[A2]] to i8* +// CHECK2-NEXT: store i8* [[TMP17]], i8** [[TMP16]], align 8 +// CHECK2-NEXT: [[TMP18:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 4 +// CHECK2-NEXT: [[TMP19:%.*]] = call i8* @__kmpc_threadprivate_cached(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]], i8* bitcast ([2 x %class.TestClass]* @tc2 to i8*), i64 8, i8*** @tc2.cache.) +// CHECK2-NEXT: [[TMP20:%.*]] = bitcast i8* [[TMP19]] to [2 x %class.TestClass]* +// CHECK2-NEXT: [[TMP21:%.*]] = bitcast [2 x %class.TestClass]* [[TMP20]] to i8* +// CHECK2-NEXT: store i8* [[TMP21]], i8** [[TMP18]], align 8 +// CHECK2-NEXT: [[TMP22:%.*]] = bitcast [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]] to i8* +// CHECK2-NEXT: [[TMP23:%.*]] = load i32, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4 +// CHECK2-NEXT: call void @__kmpc_copyprivate(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]], i64 40, i8* [[TMP22]], void (i8*, i8*)* @.omp.copyprivate.copy_func, i32 [[TMP23]]) +// CHECK2-NEXT: [[TMP24:%.*]] = load i8, i8* [[A]], align 1 +// CHECK2-NEXT: [[CONV:%.*]] = sext i8 [[TMP24]] to i32 // CHECK2-NEXT: ret i32 [[CONV]] -// CHECK2: terminate.lpad: -// CHECK2-NEXT: [[TMP22:%.*]] = landingpad { i8*, i32 } -// CHECK2-NEXT: catch i8* null -// CHECK2-NEXT: [[TMP23:%.*]] = extractvalue { i8*, i32 } [[TMP22]], 0 -// CHECK2-NEXT: call void @__clang_call_terminate(i8* [[TMP23]]) #[[ATTR13:[0-9]+]] +// CHECK2: terminate.handler: +// CHECK2-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8 +// CHECK2-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR13:[0-9]+]] // CHECK2-NEXT: unreachable // // @@ -1467,6 +1536,8 @@ void array_func(int n, int a[n], St s[2]) { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK2-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 +// CHECK2-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// CHECK2-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // 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 @@ -1476,18 +1547,25 @@ void array_func(int n, int a[n], St s[2]) { // CHECK2-NEXT: br i1 [[TMP3]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_END:%.*]] // CHECK2: omp_if.then: // CHECK2-NEXT: invoke void @_Z3foov() -// CHECK2-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]] +// CHECK2-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] // CHECK2: invoke.cont: // CHECK2-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB1]], i32 [[TMP1]]) // CHECK2-NEXT: br label [[OMP_IF_END]] -// CHECK2: omp_if.end: -// CHECK2-NEXT: call void @__kmpc_barrier(%struct.ident_t* @[[GLOB2]], i32 [[TMP1]]) -// CHECK2-NEXT: ret void -// CHECK2: terminate.lpad: +// CHECK2: lpad: // CHECK2-NEXT: [[TMP4:%.*]] = landingpad { i8*, i32 } // CHECK2-NEXT: catch i8* null // CHECK2-NEXT: [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 0 -// CHECK2-NEXT: call void @__clang_call_terminate(i8* [[TMP5]]) #[[ATTR13]] +// CHECK2-NEXT: store i8* [[TMP5]], i8** [[EXN_SLOT]], align 8 +// CHECK2-NEXT: [[TMP6:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 1 +// CHECK2-NEXT: store i32 [[TMP6]], i32* [[EHSELECTOR_SLOT]], align 4 +// CHECK2-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB1]], i32 [[TMP1]]) +// CHECK2-NEXT: br label [[TERMINATE_HANDLER:%.*]] +// CHECK2: omp_if.end: +// CHECK2-NEXT: call void @__kmpc_barrier(%struct.ident_t* @[[GLOB2]], i32 [[TMP1]]) +// CHECK2-NEXT: ret void +// CHECK2: terminate.handler: +// CHECK2-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8 +// CHECK2-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR13]] // CHECK2-NEXT: unreachable // // @@ -1579,6 +1657,8 @@ void array_func(int n, int a[n], St s[2]) { // CHECK2-NEXT: [[_TMP5:%.*]] = alloca i32*, align 8 // CHECK2-NEXT: [[DOTOMP_COPYPRIVATE_DID_IT:%.*]] = alloca i32, align 4 // CHECK2-NEXT: [[REF_TMP:%.*]] = alloca [[CLASS_ANON:%.*]], align 8 +// CHECK2-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// CHECK2-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // CHECK2-NEXT: [[DOTOMP_COPYPRIVATE_CPR_LIST:%.*]] = alloca [3 x i8*], 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 @@ -1614,32 +1694,39 @@ void array_func(int n, int a[n], St s[2]) { // CHECK2-NEXT: [[TMP12:%.*]] = load i32*, i32** [[_TMP5]], align 8 // CHECK2-NEXT: store i32* [[TMP12]], i32** [[TMP11]], align 8 // CHECK2-NEXT: invoke void @_ZZN2SSC1ERiENKUlvE_clEv(%class.anon* nonnull align 8 dereferenceable(32) [[REF_TMP]]) -// CHECK2-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]] +// CHECK2-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] // CHECK2: invoke.cont: // CHECK2-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB1]], i32 [[TMP4]]) // CHECK2-NEXT: store i32 1, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4 // CHECK2-NEXT: br label [[OMP_IF_END]] +// CHECK2: lpad: +// CHECK2-NEXT: [[TMP13:%.*]] = landingpad { i8*, i32 } +// CHECK2-NEXT: catch i8* null +// CHECK2-NEXT: [[TMP14:%.*]] = extractvalue { i8*, i32 } [[TMP13]], 0 +// CHECK2-NEXT: store i8* [[TMP14]], i8** [[EXN_SLOT]], align 8 +// CHECK2-NEXT: [[TMP15:%.*]] = extractvalue { i8*, i32 } [[TMP13]], 1 +// CHECK2-NEXT: store i32 [[TMP15]], i32* [[EHSELECTOR_SLOT]], align 4 +// CHECK2-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB1]], i32 [[TMP4]]) +// CHECK2-NEXT: br label [[TERMINATE_HANDLER:%.*]] // CHECK2: omp_if.end: -// CHECK2-NEXT: [[TMP13:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 0 -// CHECK2-NEXT: [[TMP14:%.*]] = load i32*, i32** [[_TMP4]], align 8 -// CHECK2-NEXT: [[TMP15:%.*]] = bitcast i32* [[TMP14]] to i8* -// CHECK2-NEXT: store i8* [[TMP15]], i8** [[TMP13]], align 8 -// CHECK2-NEXT: [[TMP16:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 1 -// CHECK2-NEXT: [[TMP17:%.*]] = bitcast i32* [[CONV1]] to i8* -// CHECK2-NEXT: store i8* [[TMP17]], i8** [[TMP16]], align 8 -// CHECK2-NEXT: [[TMP18:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 2 -// CHECK2-NEXT: [[TMP19:%.*]] = load i32*, i32** [[_TMP5]], align 8 -// CHECK2-NEXT: [[TMP20:%.*]] = bitcast i32* [[TMP19]] to i8* -// CHECK2-NEXT: store i8* [[TMP20]], i8** [[TMP18]], align 8 -// CHECK2-NEXT: [[TMP21:%.*]] = bitcast [3 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]] to i8* -// CHECK2-NEXT: [[TMP22:%.*]] = load i32, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4 -// CHECK2-NEXT: call void @__kmpc_copyprivate(%struct.ident_t* @[[GLOB1]], i32 [[TMP4]], i64 24, i8* [[TMP21]], void (i8*, i8*)* @.omp.copyprivate.copy_func.6, i32 [[TMP22]]) +// CHECK2-NEXT: [[TMP16:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 0 +// CHECK2-NEXT: [[TMP17:%.*]] = load i32*, i32** [[_TMP4]], align 8 +// CHECK2-NEXT: [[TMP18:%.*]] = bitcast i32* [[TMP17]] to i8* +// CHECK2-NEXT: store i8* [[TMP18]], i8** [[TMP16]], align 8 +// CHECK2-NEXT: [[TMP19:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 1 +// CHECK2-NEXT: [[TMP20:%.*]] = bitcast i32* [[CONV1]] to i8* +// CHECK2-NEXT: store i8* [[TMP20]], i8** [[TMP19]], align 8 +// CHECK2-NEXT: [[TMP21:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 2 +// CHECK2-NEXT: [[TMP22:%.*]] = load i32*, i32** [[_TMP5]], align 8 +// CHECK2-NEXT: [[TMP23:%.*]] = bitcast i32* [[TMP22]] to i8* +// CHECK2-NEXT: store i8* [[TMP23]], i8** [[TMP21]], align 8 +// CHECK2-NEXT: [[TMP24:%.*]] = bitcast [3 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]] to i8* +// CHECK2-NEXT: [[TMP25:%.*]] = load i32, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4 +// CHECK2-NEXT: call void @__kmpc_copyprivate(%struct.ident_t* @[[GLOB1]], i32 [[TMP4]], i64 24, i8* [[TMP24]], void (i8*, i8*)* @.omp.copyprivate.copy_func.6, i32 [[TMP25]]) // CHECK2-NEXT: ret void -// CHECK2: terminate.lpad: -// CHECK2-NEXT: [[TMP23:%.*]] = landingpad { i8*, i32 } -// CHECK2-NEXT: catch i8* null -// CHECK2-NEXT: [[TMP24:%.*]] = extractvalue { i8*, i32 } [[TMP23]], 0 -// CHECK2-NEXT: call void @__clang_call_terminate(i8* [[TMP24]]) #[[ATTR13]] +// CHECK2: terminate.handler: +// CHECK2-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8 +// CHECK2-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR13]] // CHECK2-NEXT: unreachable // // @@ -1869,6 +1956,8 @@ void array_func(int n, int a[n], St s[2]) { // CHECK2-NEXT: [[_TMP1:%.*]] = alloca double*, align 8 // CHECK2-NEXT: [[DOTOMP_COPYPRIVATE_DID_IT:%.*]] = alloca i32, align 4 // CHECK2-NEXT: [[REF_TMP:%.*]] = alloca [[CLASS_ANON_0:%.*]], align 8 +// CHECK2-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// CHECK2-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // CHECK2-NEXT: [[DOTOMP_COPYPRIVATE_CPR_LIST:%.*]] = alloca [1 x i8*], 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 @@ -1892,25 +1981,32 @@ void array_func(int n, int a[n], St s[2]) { // CHECK2-NEXT: [[TMP8:%.*]] = load double*, double** [[_TMP1]], align 8 // CHECK2-NEXT: store double* [[TMP8]], double** [[TMP7]], align 8 // CHECK2-NEXT: invoke void @_ZZN3SSTIdEC1EvENKUlvE_clEv(%class.anon.0* nonnull align 8 dereferenceable(16) [[REF_TMP]]) -// CHECK2-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]] +// CHECK2-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] // CHECK2: invoke.cont: // CHECK2-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB1]], i32 [[TMP3]]) // CHECK2-NEXT: store i32 1, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4 // CHECK2-NEXT: br label [[OMP_IF_END]] +// CHECK2: lpad: +// CHECK2-NEXT: [[TMP9:%.*]] = landingpad { i8*, i32 } +// CHECK2-NEXT: catch i8* null +// CHECK2-NEXT: [[TMP10:%.*]] = extractvalue { i8*, i32 } [[TMP9]], 0 +// CHECK2-NEXT: store i8* [[TMP10]], i8** [[EXN_SLOT]], align 8 +// CHECK2-NEXT: [[TMP11:%.*]] = extractvalue { i8*, i32 } [[TMP9]], 1 +// CHECK2-NEXT: store i32 [[TMP11]], i32* [[EHSELECTOR_SLOT]], align 4 +// CHECK2-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB1]], i32 [[TMP3]]) +// CHECK2-NEXT: br label [[TERMINATE_HANDLER:%.*]] // CHECK2: omp_if.end: -// CHECK2-NEXT: [[TMP9:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 0 -// CHECK2-NEXT: [[TMP10:%.*]] = load double*, double** [[_TMP1]], align 8 -// CHECK2-NEXT: [[TMP11:%.*]] = bitcast double* [[TMP10]] to i8* -// CHECK2-NEXT: store i8* [[TMP11]], i8** [[TMP9]], align 8 -// CHECK2-NEXT: [[TMP12:%.*]] = bitcast [1 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]] to i8* -// CHECK2-NEXT: [[TMP13:%.*]] = load i32, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4 -// CHECK2-NEXT: call void @__kmpc_copyprivate(%struct.ident_t* @[[GLOB1]], i32 [[TMP3]], i64 8, i8* [[TMP12]], void (i8*, i8*)* @.omp.copyprivate.copy_func.10, i32 [[TMP13]]) +// CHECK2-NEXT: [[TMP12:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 0 +// CHECK2-NEXT: [[TMP13:%.*]] = load double*, double** [[_TMP1]], align 8 +// CHECK2-NEXT: [[TMP14:%.*]] = bitcast double* [[TMP13]] to i8* +// CHECK2-NEXT: store i8* [[TMP14]], i8** [[TMP12]], align 8 +// CHECK2-NEXT: [[TMP15:%.*]] = bitcast [1 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]] to i8* +// CHECK2-NEXT: [[TMP16:%.*]] = load i32, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4 +// CHECK2-NEXT: call void @__kmpc_copyprivate(%struct.ident_t* @[[GLOB1]], i32 [[TMP3]], i64 8, i8* [[TMP15]], void (i8*, i8*)* @.omp.copyprivate.copy_func.10, i32 [[TMP16]]) // CHECK2-NEXT: ret void -// CHECK2: terminate.lpad: -// CHECK2-NEXT: [[TMP14:%.*]] = landingpad { i8*, i32 } -// CHECK2-NEXT: catch i8* null -// CHECK2-NEXT: [[TMP15:%.*]] = extractvalue { i8*, i32 } [[TMP14]], 0 -// CHECK2-NEXT: call void @__clang_call_terminate(i8* [[TMP15]]) #[[ATTR13]] +// CHECK2: terminate.handler: +// CHECK2-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8 +// CHECK2-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR13]] // CHECK2-NEXT: unreachable // // @@ -2285,6 +2381,8 @@ void array_func(int n, int a[n], St s[2]) { // CHECK3-NEXT: [[SST:%.*]] = alloca [[STRUCT_SST:%.*]], align 8 // CHECK3-NEXT: [[SS:%.*]] = alloca [[STRUCT_SS:%.*]], align 8 // CHECK3-NEXT: [[DOTOMP_COPYPRIVATE_DID_IT:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// CHECK3-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // CHECK3-NEXT: [[DOTOMP_COPYPRIVATE_CPR_LIST:%.*]] = alloca [5 x i8*], align 8 // CHECK3-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1]]) // CHECK3-NEXT: store i32 0, i32* [[RETVAL]], align 4 @@ -2314,40 +2412,47 @@ void array_func(int n, int a[n], St s[2]) { // CHECK3-NEXT: br i1 [[TMP6]], label [[OMP_IF_THEN3:%.*]], label [[OMP_IF_END4:%.*]] // CHECK3: omp_if.then3: // CHECK3-NEXT: invoke void @_Z3foov() -// CHECK3-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]] +// CHECK3-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] // CHECK3: invoke.cont: // CHECK3-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]]) // CHECK3-NEXT: store i32 1, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4 // CHECK3-NEXT: br label [[OMP_IF_END4]] +// CHECK3: lpad: +// CHECK3-NEXT: [[TMP7:%.*]] = landingpad { i8*, i32 } +// CHECK3-NEXT: catch i8* null +// CHECK3-NEXT: [[TMP8:%.*]] = extractvalue { i8*, i32 } [[TMP7]], 0 +// CHECK3-NEXT: store i8* [[TMP8]], i8** [[EXN_SLOT]], align 8 +// CHECK3-NEXT: [[TMP9:%.*]] = extractvalue { i8*, i32 } [[TMP7]], 1 +// CHECK3-NEXT: store i32 [[TMP9]], i32* [[EHSELECTOR_SLOT]], align 4 +// CHECK3-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]]) +// CHECK3-NEXT: br label [[TERMINATE_HANDLER:%.*]] // CHECK3: omp_if.end4: -// CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 0 -// CHECK3-NEXT: store i8* [[A]], i8** [[TMP7]], align 8 -// CHECK3-NEXT: [[TMP8:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 1 -// CHECK3-NEXT: store i8* bitcast (%class.TestClass* @tc to i8*), i8** [[TMP8]], align 8 -// CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 2 -// CHECK3-NEXT: [[TMP10:%.*]] = call i8* @__kmpc_threadprivate_cached(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]], i8* bitcast (%class.TestClass* @tc to i8*), i64 4, i8*** @tc.cache.) -// CHECK3-NEXT: [[TMP11:%.*]] = bitcast i8* [[TMP10]] to %class.TestClass* -// CHECK3-NEXT: [[TMP12:%.*]] = bitcast %class.TestClass* [[TMP11]] to i8* -// CHECK3-NEXT: store i8* [[TMP12]], i8** [[TMP9]], align 8 -// CHECK3-NEXT: [[TMP13:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 3 -// CHECK3-NEXT: [[TMP14:%.*]] = bitcast [2 x i8]* [[A2]] to i8* -// CHECK3-NEXT: store i8* [[TMP14]], i8** [[TMP13]], align 8 -// CHECK3-NEXT: [[TMP15:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 4 -// CHECK3-NEXT: [[TMP16:%.*]] = call i8* @__kmpc_threadprivate_cached(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]], i8* bitcast ([2 x %class.TestClass]* @tc2 to i8*), i64 8, i8*** @tc2.cache.) -// CHECK3-NEXT: [[TMP17:%.*]] = bitcast i8* [[TMP16]] to [2 x %class.TestClass]* -// CHECK3-NEXT: [[TMP18:%.*]] = bitcast [2 x %class.TestClass]* [[TMP17]] to i8* -// CHECK3-NEXT: store i8* [[TMP18]], i8** [[TMP15]], align 8 -// CHECK3-NEXT: [[TMP19:%.*]] = bitcast [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]] to i8* -// CHECK3-NEXT: [[TMP20:%.*]] = load i32, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4 -// CHECK3-NEXT: call void @__kmpc_copyprivate(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]], i64 40, i8* [[TMP19]], void (i8*, i8*)* @.omp.copyprivate.copy_func, i32 [[TMP20]]) -// CHECK3-NEXT: [[TMP21:%.*]] = load i8, i8* [[A]], align 1 -// CHECK3-NEXT: [[CONV:%.*]] = sext i8 [[TMP21]] to i32 +// CHECK3-NEXT: [[TMP10:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 0 +// CHECK3-NEXT: store i8* [[A]], i8** [[TMP10]], align 8 +// CHECK3-NEXT: [[TMP11:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 1 +// CHECK3-NEXT: store i8* bitcast (%class.TestClass* @tc to i8*), i8** [[TMP11]], align 8 +// CHECK3-NEXT: [[TMP12:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 2 +// CHECK3-NEXT: [[TMP13:%.*]] = call i8* @__kmpc_threadprivate_cached(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]], i8* bitcast (%class.TestClass* @tc to i8*), i64 4, i8*** @tc.cache.) +// CHECK3-NEXT: [[TMP14:%.*]] = bitcast i8* [[TMP13]] to %class.TestClass* +// CHECK3-NEXT: [[TMP15:%.*]] = bitcast %class.TestClass* [[TMP14]] to i8* +// CHECK3-NEXT: store i8* [[TMP15]], i8** [[TMP12]], align 8 +// CHECK3-NEXT: [[TMP16:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 3 +// CHECK3-NEXT: [[TMP17:%.*]] = bitcast [2 x i8]* [[A2]] to i8* +// CHECK3-NEXT: store i8* [[TMP17]], i8** [[TMP16]], align 8 +// CHECK3-NEXT: [[TMP18:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 4 +// CHECK3-NEXT: [[TMP19:%.*]] = call i8* @__kmpc_threadprivate_cached(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]], i8* bitcast ([2 x %class.TestClass]* @tc2 to i8*), i64 8, i8*** @tc2.cache.) +// CHECK3-NEXT: [[TMP20:%.*]] = bitcast i8* [[TMP19]] to [2 x %class.TestClass]* +// CHECK3-NEXT: [[TMP21:%.*]] = bitcast [2 x %class.TestClass]* [[TMP20]] to i8* +// CHECK3-NEXT: store i8* [[TMP21]], i8** [[TMP18]], align 8 +// CHECK3-NEXT: [[TMP22:%.*]] = bitcast [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]] to i8* +// CHECK3-NEXT: [[TMP23:%.*]] = load i32, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4 +// CHECK3-NEXT: call void @__kmpc_copyprivate(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]], i64 40, i8* [[TMP22]], void (i8*, i8*)* @.omp.copyprivate.copy_func, i32 [[TMP23]]) +// CHECK3-NEXT: [[TMP24:%.*]] = load i8, i8* [[A]], align 1 +// CHECK3-NEXT: [[CONV:%.*]] = sext i8 [[TMP24]] to i32 // CHECK3-NEXT: ret i32 [[CONV]] -// CHECK3: terminate.lpad: -// CHECK3-NEXT: [[TMP22:%.*]] = landingpad { i8*, i32 } -// CHECK3-NEXT: catch i8* null -// CHECK3-NEXT: [[TMP23:%.*]] = extractvalue { i8*, i32 } [[TMP22]], 0 -// CHECK3-NEXT: call void @__clang_call_terminate(i8* [[TMP23]]) #[[ATTR13:[0-9]+]] +// CHECK3: terminate.handler: +// CHECK3-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8 +// CHECK3-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR13:[0-9]+]] // CHECK3-NEXT: unreachable // // @@ -2481,6 +2586,8 @@ void array_func(int n, int a[n], St s[2]) { // CHECK3-NEXT: [[_TMP1:%.*]] = alloca double*, align 8 // CHECK3-NEXT: [[DOTOMP_COPYPRIVATE_DID_IT:%.*]] = alloca i32, align 4 // CHECK3-NEXT: [[REF_TMP:%.*]] = alloca [[CLASS_ANON:%.*]], align 8 +// CHECK3-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// CHECK3-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // CHECK3-NEXT: [[DOTOMP_COPYPRIVATE_CPR_LIST:%.*]] = alloca [1 x i8*], align 8 // CHECK3-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK3-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 @@ -2504,25 +2611,32 @@ void array_func(int n, int a[n], St s[2]) { // CHECK3-NEXT: [[TMP8:%.*]] = load double*, double** [[_TMP1]], align 8 // CHECK3-NEXT: store double* [[TMP8]], double** [[TMP7]], align 8 // CHECK3-NEXT: invoke void @_ZZN3SSTIdEC1EvENKUlvE_clEv(%class.anon* nonnull align 8 dereferenceable(16) [[REF_TMP]]) -// CHECK3-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]] +// CHECK3-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] // CHECK3: invoke.cont: // CHECK3-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB1]], i32 [[TMP3]]) // CHECK3-NEXT: store i32 1, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4 // CHECK3-NEXT: br label [[OMP_IF_END]] +// CHECK3: lpad: +// CHECK3-NEXT: [[TMP9:%.*]] = landingpad { i8*, i32 } +// CHECK3-NEXT: catch i8* null +// CHECK3-NEXT: [[TMP10:%.*]] = extractvalue { i8*, i32 } [[TMP9]], 0 +// CHECK3-NEXT: store i8* [[TMP10]], i8** [[EXN_SLOT]], align 8 +// CHECK3-NEXT: [[TMP11:%.*]] = extractvalue { i8*, i32 } [[TMP9]], 1 +// CHECK3-NEXT: store i32 [[TMP11]], i32* [[EHSELECTOR_SLOT]], align 4 +// CHECK3-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB1]], i32 [[TMP3]]) +// CHECK3-NEXT: br label [[TERMINATE_HANDLER:%.*]] // CHECK3: omp_if.end: -// CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 0 -// CHECK3-NEXT: [[TMP10:%.*]] = load double*, double** [[_TMP1]], align 8 -// CHECK3-NEXT: [[TMP11:%.*]] = bitcast double* [[TMP10]] to i8* -// CHECK3-NEXT: store i8* [[TMP11]], i8** [[TMP9]], align 8 -// CHECK3-NEXT: [[TMP12:%.*]] = bitcast [1 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]] to i8* -// CHECK3-NEXT: [[TMP13:%.*]] = load i32, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4 -// CHECK3-NEXT: call void @__kmpc_copyprivate(%struct.ident_t* @[[GLOB1]], i32 [[TMP3]], i64 8, i8* [[TMP12]], void (i8*, i8*)* @.omp.copyprivate.copy_func.5, i32 [[TMP13]]) +// CHECK3-NEXT: [[TMP12:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 0 +// CHECK3-NEXT: [[TMP13:%.*]] = load double*, double** [[_TMP1]], align 8 +// CHECK3-NEXT: [[TMP14:%.*]] = bitcast double* [[TMP13]] to i8* +// CHECK3-NEXT: store i8* [[TMP14]], i8** [[TMP12]], align 8 +// CHECK3-NEXT: [[TMP15:%.*]] = bitcast [1 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]] to i8* +// CHECK3-NEXT: [[TMP16:%.*]] = load i32, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4 +// CHECK3-NEXT: call void @__kmpc_copyprivate(%struct.ident_t* @[[GLOB1]], i32 [[TMP3]], i64 8, i8* [[TMP15]], void (i8*, i8*)* @.omp.copyprivate.copy_func.5, i32 [[TMP16]]) // CHECK3-NEXT: ret void -// CHECK3: terminate.lpad: -// CHECK3-NEXT: [[TMP14:%.*]] = landingpad { i8*, i32 } -// CHECK3-NEXT: catch i8* null -// CHECK3-NEXT: [[TMP15:%.*]] = extractvalue { i8*, i32 } [[TMP14]], 0 -// CHECK3-NEXT: call void @__clang_call_terminate(i8* [[TMP15]]) #[[ATTR13]] +// CHECK3: terminate.handler: +// CHECK3-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8 +// CHECK3-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR13]] // CHECK3-NEXT: unreachable // // @@ -2726,6 +2840,8 @@ void array_func(int n, int a[n], St s[2]) { // CHECK3-NEXT: [[_TMP5:%.*]] = alloca i32*, align 8 // CHECK3-NEXT: [[DOTOMP_COPYPRIVATE_DID_IT:%.*]] = alloca i32, align 4 // CHECK3-NEXT: [[REF_TMP:%.*]] = alloca [[CLASS_ANON_1:%.*]], align 8 +// CHECK3-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// CHECK3-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // CHECK3-NEXT: [[DOTOMP_COPYPRIVATE_CPR_LIST:%.*]] = alloca [3 x i8*], align 8 // CHECK3-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK3-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 @@ -2761,32 +2877,39 @@ void array_func(int n, int a[n], St s[2]) { // CHECK3-NEXT: [[TMP12:%.*]] = load i32*, i32** [[_TMP5]], align 8 // CHECK3-NEXT: store i32* [[TMP12]], i32** [[TMP11]], align 8 // CHECK3-NEXT: invoke void @_ZZN2SSC1ERiENKUlvE_clEv(%class.anon.1* nonnull align 8 dereferenceable(32) [[REF_TMP]]) -// CHECK3-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]] +// CHECK3-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] // CHECK3: invoke.cont: // CHECK3-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB1]], i32 [[TMP4]]) // CHECK3-NEXT: store i32 1, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4 // CHECK3-NEXT: br label [[OMP_IF_END]] +// CHECK3: lpad: +// CHECK3-NEXT: [[TMP13:%.*]] = landingpad { i8*, i32 } +// CHECK3-NEXT: catch i8* null +// CHECK3-NEXT: [[TMP14:%.*]] = extractvalue { i8*, i32 } [[TMP13]], 0 +// CHECK3-NEXT: store i8* [[TMP14]], i8** [[EXN_SLOT]], align 8 +// CHECK3-NEXT: [[TMP15:%.*]] = extractvalue { i8*, i32 } [[TMP13]], 1 +// CHECK3-NEXT: store i32 [[TMP15]], i32* [[EHSELECTOR_SLOT]], align 4 +// CHECK3-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB1]], i32 [[TMP4]]) +// CHECK3-NEXT: br label [[TERMINATE_HANDLER:%.*]] // CHECK3: omp_if.end: -// CHECK3-NEXT: [[TMP13:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 0 -// CHECK3-NEXT: [[TMP14:%.*]] = load i32*, i32** [[_TMP4]], align 8 -// CHECK3-NEXT: [[TMP15:%.*]] = bitcast i32* [[TMP14]] to i8* -// CHECK3-NEXT: store i8* [[TMP15]], i8** [[TMP13]], align 8 -// CHECK3-NEXT: [[TMP16:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 1 -// CHECK3-NEXT: [[TMP17:%.*]] = bitcast i32* [[CONV1]] to i8* -// CHECK3-NEXT: store i8* [[TMP17]], i8** [[TMP16]], align 8 -// CHECK3-NEXT: [[TMP18:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 2 -// CHECK3-NEXT: [[TMP19:%.*]] = load i32*, i32** [[_TMP5]], align 8 -// CHECK3-NEXT: [[TMP20:%.*]] = bitcast i32* [[TMP19]] to i8* -// CHECK3-NEXT: store i8* [[TMP20]], i8** [[TMP18]], align 8 -// CHECK3-NEXT: [[TMP21:%.*]] = bitcast [3 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]] to i8* -// CHECK3-NEXT: [[TMP22:%.*]] = load i32, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4 -// CHECK3-NEXT: call void @__kmpc_copyprivate(%struct.ident_t* @[[GLOB1]], i32 [[TMP4]], i64 24, i8* [[TMP21]], void (i8*, i8*)* @.omp.copyprivate.copy_func.9, i32 [[TMP22]]) +// CHECK3-NEXT: [[TMP16:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 0 +// CHECK3-NEXT: [[TMP17:%.*]] = load i32*, i32** [[_TMP4]], align 8 +// CHECK3-NEXT: [[TMP18:%.*]] = bitcast i32* [[TMP17]] to i8* +// CHECK3-NEXT: store i8* [[TMP18]], i8** [[TMP16]], align 8 +// CHECK3-NEXT: [[TMP19:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 1 +// CHECK3-NEXT: [[TMP20:%.*]] = bitcast i32* [[CONV1]] to i8* +// CHECK3-NEXT: store i8* [[TMP20]], i8** [[TMP19]], align 8 +// CHECK3-NEXT: [[TMP21:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 2 +// CHECK3-NEXT: [[TMP22:%.*]] = load i32*, i32** [[_TMP5]], align 8 +// CHECK3-NEXT: [[TMP23:%.*]] = bitcast i32* [[TMP22]] to i8* +// CHECK3-NEXT: store i8* [[TMP23]], i8** [[TMP21]], align 8 +// CHECK3-NEXT: [[TMP24:%.*]] = bitcast [3 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]] to i8* +// CHECK3-NEXT: [[TMP25:%.*]] = load i32, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4 +// CHECK3-NEXT: call void @__kmpc_copyprivate(%struct.ident_t* @[[GLOB1]], i32 [[TMP4]], i64 24, i8* [[TMP24]], void (i8*, i8*)* @.omp.copyprivate.copy_func.9, i32 [[TMP25]]) // CHECK3-NEXT: ret void -// CHECK3: terminate.lpad: -// CHECK3-NEXT: [[TMP23:%.*]] = landingpad { i8*, i32 } -// CHECK3-NEXT: catch i8* null -// CHECK3-NEXT: [[TMP24:%.*]] = extractvalue { i8*, i32 } [[TMP23]], 0 -// CHECK3-NEXT: call void @__clang_call_terminate(i8* [[TMP24]]) #[[ATTR13]] +// CHECK3: terminate.handler: +// CHECK3-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8 +// CHECK3-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR13]] // CHECK3-NEXT: unreachable // // @@ -2996,6 +3119,8 @@ void array_func(int n, int a[n], St s[2]) { // CHECK3-NEXT: entry: // CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 +// CHECK3-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// CHECK3-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // CHECK3-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK3-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 // CHECK3-NEXT: [[TMP0:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8 @@ -3005,18 +3130,25 @@ void array_func(int n, int a[n], St s[2]) { // CHECK3-NEXT: br i1 [[TMP3]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_END:%.*]] // CHECK3: omp_if.then: // CHECK3-NEXT: invoke void @_Z3foov() -// CHECK3-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]] +// CHECK3-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] // CHECK3: invoke.cont: // CHECK3-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB1]], i32 [[TMP1]]) // CHECK3-NEXT: br label [[OMP_IF_END]] -// CHECK3: omp_if.end: -// CHECK3-NEXT: call void @__kmpc_barrier(%struct.ident_t* @[[GLOB2]], i32 [[TMP1]]) -// CHECK3-NEXT: ret void -// CHECK3: terminate.lpad: +// CHECK3: lpad: // CHECK3-NEXT: [[TMP4:%.*]] = landingpad { i8*, i32 } // CHECK3-NEXT: catch i8* null // CHECK3-NEXT: [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 0 -// CHECK3-NEXT: call void @__clang_call_terminate(i8* [[TMP5]]) #[[ATTR13]] +// CHECK3-NEXT: store i8* [[TMP5]], i8** [[EXN_SLOT]], align 8 +// CHECK3-NEXT: [[TMP6:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 1 +// CHECK3-NEXT: store i32 [[TMP6]], i32* [[EHSELECTOR_SLOT]], align 4 +// CHECK3-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB1]], i32 [[TMP1]]) +// CHECK3-NEXT: br label [[TERMINATE_HANDLER:%.*]] +// CHECK3: omp_if.end: +// CHECK3-NEXT: call void @__kmpc_barrier(%struct.ident_t* @[[GLOB2]], i32 [[TMP1]]) +// CHECK3-NEXT: ret void +// CHECK3: terminate.handler: +// CHECK3-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8 +// CHECK3-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR13]] // CHECK3-NEXT: unreachable // // @@ -3227,6 +3359,8 @@ void array_func(int n, int a[n], St s[2]) { // CHECK4-NEXT: [[SST:%.*]] = alloca [[STRUCT_SST:%.*]], align 8 // CHECK4-NEXT: [[SS:%.*]] = alloca [[STRUCT_SS:%.*]], align 8 // CHECK4-NEXT: [[DOTOMP_COPYPRIVATE_DID_IT:%.*]] = alloca i32, align 4 +// CHECK4-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// CHECK4-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // CHECK4-NEXT: [[DOTOMP_COPYPRIVATE_CPR_LIST:%.*]] = alloca [5 x i8*], align 8 // CHECK4-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1]]) // CHECK4-NEXT: store i32 0, i32* [[RETVAL]], align 4 @@ -3256,40 +3390,47 @@ void array_func(int n, int a[n], St s[2]) { // CHECK4-NEXT: br i1 [[TMP6]], label [[OMP_IF_THEN3:%.*]], label [[OMP_IF_END4:%.*]] // CHECK4: omp_if.then3: // CHECK4-NEXT: invoke void @_Z3foov() -// CHECK4-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]] +// CHECK4-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] // CHECK4: invoke.cont: // CHECK4-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]]) // CHECK4-NEXT: store i32 1, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4 // CHECK4-NEXT: br label [[OMP_IF_END4]] +// CHECK4: lpad: +// CHECK4-NEXT: [[TMP7:%.*]] = landingpad { i8*, i32 } +// CHECK4-NEXT: catch i8* null +// CHECK4-NEXT: [[TMP8:%.*]] = extractvalue { i8*, i32 } [[TMP7]], 0 +// CHECK4-NEXT: store i8* [[TMP8]], i8** [[EXN_SLOT]], align 8 +// CHECK4-NEXT: [[TMP9:%.*]] = extractvalue { i8*, i32 } [[TMP7]], 1 +// CHECK4-NEXT: store i32 [[TMP9]], i32* [[EHSELECTOR_SLOT]], align 4 +// CHECK4-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]]) +// CHECK4-NEXT: br label [[TERMINATE_HANDLER:%.*]] // CHECK4: omp_if.end4: -// CHECK4-NEXT: [[TMP7:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 0 -// CHECK4-NEXT: store i8* [[A]], i8** [[TMP7]], align 8 -// CHECK4-NEXT: [[TMP8:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 1 -// CHECK4-NEXT: store i8* bitcast (%class.TestClass* @tc to i8*), i8** [[TMP8]], align 8 -// CHECK4-NEXT: [[TMP9:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 2 -// CHECK4-NEXT: [[TMP10:%.*]] = call i8* @__kmpc_threadprivate_cached(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]], i8* bitcast (%class.TestClass* @tc to i8*), i64 4, i8*** @tc.cache.) -// CHECK4-NEXT: [[TMP11:%.*]] = bitcast i8* [[TMP10]] to %class.TestClass* -// CHECK4-NEXT: [[TMP12:%.*]] = bitcast %class.TestClass* [[TMP11]] to i8* -// CHECK4-NEXT: store i8* [[TMP12]], i8** [[TMP9]], align 8 -// CHECK4-NEXT: [[TMP13:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 3 -// CHECK4-NEXT: [[TMP14:%.*]] = bitcast [2 x i8]* [[A2]] to i8* -// CHECK4-NEXT: store i8* [[TMP14]], i8** [[TMP13]], align 8 -// CHECK4-NEXT: [[TMP15:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 4 -// CHECK4-NEXT: [[TMP16:%.*]] = call i8* @__kmpc_threadprivate_cached(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]], i8* bitcast ([2 x %class.TestClass]* @tc2 to i8*), i64 8, i8*** @tc2.cache.) -// CHECK4-NEXT: [[TMP17:%.*]] = bitcast i8* [[TMP16]] to [2 x %class.TestClass]* -// CHECK4-NEXT: [[TMP18:%.*]] = bitcast [2 x %class.TestClass]* [[TMP17]] to i8* -// CHECK4-NEXT: store i8* [[TMP18]], i8** [[TMP15]], align 8 -// CHECK4-NEXT: [[TMP19:%.*]] = bitcast [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]] to i8* -// CHECK4-NEXT: [[TMP20:%.*]] = load i32, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4 -// CHECK4-NEXT: call void @__kmpc_copyprivate(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]], i64 40, i8* [[TMP19]], void (i8*, i8*)* @.omp.copyprivate.copy_func, i32 [[TMP20]]) -// CHECK4-NEXT: [[TMP21:%.*]] = load i8, i8* [[A]], align 1 -// CHECK4-NEXT: [[CONV:%.*]] = sext i8 [[TMP21]] to i32 +// CHECK4-NEXT: [[TMP10:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 0 +// CHECK4-NEXT: store i8* [[A]], i8** [[TMP10]], align 8 +// CHECK4-NEXT: [[TMP11:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 1 +// CHECK4-NEXT: store i8* bitcast (%class.TestClass* @tc to i8*), i8** [[TMP11]], align 8 +// CHECK4-NEXT: [[TMP12:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 2 +// CHECK4-NEXT: [[TMP13:%.*]] = call i8* @__kmpc_threadprivate_cached(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]], i8* bitcast (%class.TestClass* @tc to i8*), i64 4, i8*** @tc.cache.) +// CHECK4-NEXT: [[TMP14:%.*]] = bitcast i8* [[TMP13]] to %class.TestClass* +// CHECK4-NEXT: [[TMP15:%.*]] = bitcast %class.TestClass* [[TMP14]] to i8* +// CHECK4-NEXT: store i8* [[TMP15]], i8** [[TMP12]], align 8 +// CHECK4-NEXT: [[TMP16:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 3 +// CHECK4-NEXT: [[TMP17:%.*]] = bitcast [2 x i8]* [[A2]] to i8* +// CHECK4-NEXT: store i8* [[TMP17]], i8** [[TMP16]], align 8 +// CHECK4-NEXT: [[TMP18:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 4 +// CHECK4-NEXT: [[TMP19:%.*]] = call i8* @__kmpc_threadprivate_cached(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]], i8* bitcast ([2 x %class.TestClass]* @tc2 to i8*), i64 8, i8*** @tc2.cache.) +// CHECK4-NEXT: [[TMP20:%.*]] = bitcast i8* [[TMP19]] to [2 x %class.TestClass]* +// CHECK4-NEXT: [[TMP21:%.*]] = bitcast [2 x %class.TestClass]* [[TMP20]] to i8* +// CHECK4-NEXT: store i8* [[TMP21]], i8** [[TMP18]], align 8 +// CHECK4-NEXT: [[TMP22:%.*]] = bitcast [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]] to i8* +// CHECK4-NEXT: [[TMP23:%.*]] = load i32, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4 +// CHECK4-NEXT: call void @__kmpc_copyprivate(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]], i64 40, i8* [[TMP22]], void (i8*, i8*)* @.omp.copyprivate.copy_func, i32 [[TMP23]]) +// CHECK4-NEXT: [[TMP24:%.*]] = load i8, i8* [[A]], align 1 +// CHECK4-NEXT: [[CONV:%.*]] = sext i8 [[TMP24]] to i32 // CHECK4-NEXT: ret i32 [[CONV]] -// CHECK4: terminate.lpad: -// CHECK4-NEXT: [[TMP22:%.*]] = landingpad { i8*, i32 } -// CHECK4-NEXT: catch i8* null -// CHECK4-NEXT: [[TMP23:%.*]] = extractvalue { i8*, i32 } [[TMP22]], 0 -// CHECK4-NEXT: call void @__clang_call_terminate(i8* [[TMP23]]) #[[ATTR13:[0-9]+]] +// CHECK4: terminate.handler: +// CHECK4-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8 +// CHECK4-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR13:[0-9]+]] // CHECK4-NEXT: unreachable // // @@ -3403,6 +3544,8 @@ void array_func(int n, int a[n], St s[2]) { // CHECK4-NEXT: entry: // CHECK4-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK4-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 +// CHECK4-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// CHECK4-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // CHECK4-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK4-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 // CHECK4-NEXT: [[TMP0:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8 @@ -3412,18 +3555,25 @@ void array_func(int n, int a[n], St s[2]) { // CHECK4-NEXT: br i1 [[TMP3]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_END:%.*]] // CHECK4: omp_if.then: // CHECK4-NEXT: invoke void @_Z3foov() -// CHECK4-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]] +// CHECK4-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] // CHECK4: invoke.cont: // CHECK4-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB1]], i32 [[TMP1]]) // CHECK4-NEXT: br label [[OMP_IF_END]] -// CHECK4: omp_if.end: -// CHECK4-NEXT: call void @__kmpc_barrier(%struct.ident_t* @[[GLOB2]], i32 [[TMP1]]) -// CHECK4-NEXT: ret void -// CHECK4: terminate.lpad: +// CHECK4: lpad: // CHECK4-NEXT: [[TMP4:%.*]] = landingpad { i8*, i32 } // CHECK4-NEXT: catch i8* null // CHECK4-NEXT: [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 0 -// CHECK4-NEXT: call void @__clang_call_terminate(i8* [[TMP5]]) #[[ATTR13]] +// CHECK4-NEXT: store i8* [[TMP5]], i8** [[EXN_SLOT]], align 8 +// CHECK4-NEXT: [[TMP6:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 1 +// CHECK4-NEXT: store i32 [[TMP6]], i32* [[EHSELECTOR_SLOT]], align 4 +// CHECK4-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB1]], i32 [[TMP1]]) +// CHECK4-NEXT: br label [[TERMINATE_HANDLER:%.*]] +// CHECK4: omp_if.end: +// CHECK4-NEXT: call void @__kmpc_barrier(%struct.ident_t* @[[GLOB2]], i32 [[TMP1]]) +// CHECK4-NEXT: ret void +// CHECK4: terminate.handler: +// CHECK4-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8 +// CHECK4-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR13]] // CHECK4-NEXT: unreachable // // @@ -3515,6 +3665,8 @@ void array_func(int n, int a[n], St s[2]) { // CHECK4-NEXT: [[_TMP5:%.*]] = alloca i32*, align 8 // CHECK4-NEXT: [[DOTOMP_COPYPRIVATE_DID_IT:%.*]] = alloca i32, align 4 // CHECK4-NEXT: [[REF_TMP:%.*]] = alloca [[CLASS_ANON:%.*]], align 8 +// CHECK4-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// CHECK4-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // CHECK4-NEXT: [[DOTOMP_COPYPRIVATE_CPR_LIST:%.*]] = alloca [3 x i8*], align 8 // CHECK4-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK4-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 @@ -3550,32 +3702,39 @@ void array_func(int n, int a[n], St s[2]) { // CHECK4-NEXT: [[TMP12:%.*]] = load i32*, i32** [[_TMP5]], align 8 // CHECK4-NEXT: store i32* [[TMP12]], i32** [[TMP11]], align 8 // CHECK4-NEXT: invoke void @_ZZN2SSC1ERiENKUlvE_clEv(%class.anon* nonnull align 8 dereferenceable(32) [[REF_TMP]]) -// CHECK4-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]] +// CHECK4-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] // CHECK4: invoke.cont: // CHECK4-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB1]], i32 [[TMP4]]) // CHECK4-NEXT: store i32 1, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4 // CHECK4-NEXT: br label [[OMP_IF_END]] +// CHECK4: lpad: +// CHECK4-NEXT: [[TMP13:%.*]] = landingpad { i8*, i32 } +// CHECK4-NEXT: catch i8* null +// CHECK4-NEXT: [[TMP14:%.*]] = extractvalue { i8*, i32 } [[TMP13]], 0 +// CHECK4-NEXT: store i8* [[TMP14]], i8** [[EXN_SLOT]], align 8 +// CHECK4-NEXT: [[TMP15:%.*]] = extractvalue { i8*, i32 } [[TMP13]], 1 +// CHECK4-NEXT: store i32 [[TMP15]], i32* [[EHSELECTOR_SLOT]], align 4 +// CHECK4-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB1]], i32 [[TMP4]]) +// CHECK4-NEXT: br label [[TERMINATE_HANDLER:%.*]] // CHECK4: omp_if.end: -// CHECK4-NEXT: [[TMP13:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 0 -// CHECK4-NEXT: [[TMP14:%.*]] = load i32*, i32** [[_TMP4]], align 8 -// CHECK4-NEXT: [[TMP15:%.*]] = bitcast i32* [[TMP14]] to i8* -// CHECK4-NEXT: store i8* [[TMP15]], i8** [[TMP13]], align 8 -// CHECK4-NEXT: [[TMP16:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 1 -// CHECK4-NEXT: [[TMP17:%.*]] = bitcast i32* [[CONV1]] to i8* -// CHECK4-NEXT: store i8* [[TMP17]], i8** [[TMP16]], align 8 -// CHECK4-NEXT: [[TMP18:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 2 -// CHECK4-NEXT: [[TMP19:%.*]] = load i32*, i32** [[_TMP5]], align 8 -// CHECK4-NEXT: [[TMP20:%.*]] = bitcast i32* [[TMP19]] to i8* -// CHECK4-NEXT: store i8* [[TMP20]], i8** [[TMP18]], align 8 -// CHECK4-NEXT: [[TMP21:%.*]] = bitcast [3 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]] to i8* -// CHECK4-NEXT: [[TMP22:%.*]] = load i32, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4 -// CHECK4-NEXT: call void @__kmpc_copyprivate(%struct.ident_t* @[[GLOB1]], i32 [[TMP4]], i64 24, i8* [[TMP21]], void (i8*, i8*)* @.omp.copyprivate.copy_func.5, i32 [[TMP22]]) +// CHECK4-NEXT: [[TMP16:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 0 +// CHECK4-NEXT: [[TMP17:%.*]] = load i32*, i32** [[_TMP4]], align 8 +// CHECK4-NEXT: [[TMP18:%.*]] = bitcast i32* [[TMP17]] to i8* +// CHECK4-NEXT: store i8* [[TMP18]], i8** [[TMP16]], align 8 +// CHECK4-NEXT: [[TMP19:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 1 +// CHECK4-NEXT: [[TMP20:%.*]] = bitcast i32* [[CONV1]] to i8* +// CHECK4-NEXT: store i8* [[TMP20]], i8** [[TMP19]], align 8 +// CHECK4-NEXT: [[TMP21:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 2 +// CHECK4-NEXT: [[TMP22:%.*]] = load i32*, i32** [[_TMP5]], align 8 +// CHECK4-NEXT: [[TMP23:%.*]] = bitcast i32* [[TMP22]] to i8* +// CHECK4-NEXT: store i8* [[TMP23]], i8** [[TMP21]], align 8 +// CHECK4-NEXT: [[TMP24:%.*]] = bitcast [3 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]] to i8* +// CHECK4-NEXT: [[TMP25:%.*]] = load i32, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4 +// CHECK4-NEXT: call void @__kmpc_copyprivate(%struct.ident_t* @[[GLOB1]], i32 [[TMP4]], i64 24, i8* [[TMP24]], void (i8*, i8*)* @.omp.copyprivate.copy_func.5, i32 [[TMP25]]) // CHECK4-NEXT: ret void -// CHECK4: terminate.lpad: -// CHECK4-NEXT: [[TMP23:%.*]] = landingpad { i8*, i32 } -// CHECK4-NEXT: catch i8* null -// CHECK4-NEXT: [[TMP24:%.*]] = extractvalue { i8*, i32 } [[TMP23]], 0 -// CHECK4-NEXT: call void @__clang_call_terminate(i8* [[TMP24]]) #[[ATTR13]] +// CHECK4: terminate.handler: +// CHECK4-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8 +// CHECK4-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR13]] // CHECK4-NEXT: unreachable // // @@ -3805,6 +3964,8 @@ void array_func(int n, int a[n], St s[2]) { // CHECK4-NEXT: [[_TMP1:%.*]] = alloca double*, align 8 // CHECK4-NEXT: [[DOTOMP_COPYPRIVATE_DID_IT:%.*]] = alloca i32, align 4 // CHECK4-NEXT: [[REF_TMP:%.*]] = alloca [[CLASS_ANON_0:%.*]], align 8 +// CHECK4-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// CHECK4-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // CHECK4-NEXT: [[DOTOMP_COPYPRIVATE_CPR_LIST:%.*]] = alloca [1 x i8*], align 8 // CHECK4-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK4-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 @@ -3828,25 +3989,32 @@ void array_func(int n, int a[n], St s[2]) { // CHECK4-NEXT: [[TMP8:%.*]] = load double*, double** [[_TMP1]], align 8 // CHECK4-NEXT: store double* [[TMP8]], double** [[TMP7]], align 8 // CHECK4-NEXT: invoke void @_ZZN3SSTIdEC1EvENKUlvE_clEv(%class.anon.0* nonnull align 8 dereferenceable(16) [[REF_TMP]]) -// CHECK4-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]] +// CHECK4-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] // CHECK4: invoke.cont: // CHECK4-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB1]], i32 [[TMP3]]) // CHECK4-NEXT: store i32 1, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4 // CHECK4-NEXT: br label [[OMP_IF_END]] +// CHECK4: lpad: +// CHECK4-NEXT: [[TMP9:%.*]] = landingpad { i8*, i32 } +// CHECK4-NEXT: catch i8* null +// CHECK4-NEXT: [[TMP10:%.*]] = extractvalue { i8*, i32 } [[TMP9]], 0 +// CHECK4-NEXT: store i8* [[TMP10]], i8** [[EXN_SLOT]], align 8 +// CHECK4-NEXT: [[TMP11:%.*]] = extractvalue { i8*, i32 } [[TMP9]], 1 +// CHECK4-NEXT: store i32 [[TMP11]], i32* [[EHSELECTOR_SLOT]], align 4 +// CHECK4-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB1]], i32 [[TMP3]]) +// CHECK4-NEXT: br label [[TERMINATE_HANDLER:%.*]] // CHECK4: omp_if.end: -// CHECK4-NEXT: [[TMP9:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 0 -// CHECK4-NEXT: [[TMP10:%.*]] = load double*, double** [[_TMP1]], align 8 -// CHECK4-NEXT: [[TMP11:%.*]] = bitcast double* [[TMP10]] to i8* -// CHECK4-NEXT: store i8* [[TMP11]], i8** [[TMP9]], align 8 -// CHECK4-NEXT: [[TMP12:%.*]] = bitcast [1 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]] to i8* -// CHECK4-NEXT: [[TMP13:%.*]] = load i32, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4 -// CHECK4-NEXT: call void @__kmpc_copyprivate(%struct.ident_t* @[[GLOB1]], i32 [[TMP3]], i64 8, i8* [[TMP12]], void (i8*, i8*)* @.omp.copyprivate.copy_func.9, i32 [[TMP13]]) +// CHECK4-NEXT: [[TMP12:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 0 +// CHECK4-NEXT: [[TMP13:%.*]] = load double*, double** [[_TMP1]], align 8 +// CHECK4-NEXT: [[TMP14:%.*]] = bitcast double* [[TMP13]] to i8* +// CHECK4-NEXT: store i8* [[TMP14]], i8** [[TMP12]], align 8 +// CHECK4-NEXT: [[TMP15:%.*]] = bitcast [1 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]] to i8* +// CHECK4-NEXT: [[TMP16:%.*]] = load i32, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4 +// CHECK4-NEXT: call void @__kmpc_copyprivate(%struct.ident_t* @[[GLOB1]], i32 [[TMP3]], i64 8, i8* [[TMP15]], void (i8*, i8*)* @.omp.copyprivate.copy_func.9, i32 [[TMP16]]) // CHECK4-NEXT: ret void -// CHECK4: terminate.lpad: -// CHECK4-NEXT: [[TMP14:%.*]] = landingpad { i8*, i32 } -// CHECK4-NEXT: catch i8* null -// CHECK4-NEXT: [[TMP15:%.*]] = extractvalue { i8*, i32 } [[TMP14]], 0 -// CHECK4-NEXT: call void @__clang_call_terminate(i8* [[TMP15]]) #[[ATTR13]] +// CHECK4: terminate.handler: +// CHECK4-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8 +// CHECK4-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR13]] // CHECK4-NEXT: unreachable // // @@ -4119,98 +4287,98 @@ void array_func(int n, int a[n], St s[2]) { // CHECK5-LABEL: define {{[^@]+}}@__cxx_global_var_init // CHECK5-SAME: () #[[ATTR0]] section "__TEXT,__StaticInit,regular,pure_instructions" !dbg [[DBG32:![0-9]+]] { // CHECK5-NEXT: entry: -// CHECK5-NEXT: call void @_ZN9TestClassC1Ev(%class.TestClass* nonnull align 4 dereferenceable(4) @tc), !dbg [[DBG33:![0-9]+]] -// CHECK5-NEXT: [[TMP0:%.*]] = call i32 @__cxa_atexit(void (i8*)* bitcast (void (%class.TestClass*)* @_ZN9TestClassD1Ev to void (i8*)*), i8* bitcast (%class.TestClass* @tc to i8*), i8* @__dso_handle) #[[ATTR3]], !dbg [[DBG35:![0-9]+]] -// CHECK5-NEXT: ret void, !dbg [[DBG33]] +// CHECK5-NEXT: call void @_ZN9TestClassC1Ev(%class.TestClass* nonnull align 4 dereferenceable(4) @tc), !dbg [[DBG34:![0-9]+]] +// CHECK5-NEXT: [[TMP0:%.*]] = call i32 @__cxa_atexit(void (i8*)* bitcast (void (%class.TestClass*)* @_ZN9TestClassD1Ev to void (i8*)*), i8* bitcast (%class.TestClass* @tc to i8*), i8* @__dso_handle) #[[ATTR3]], !dbg [[DBG36:![0-9]+]] +// CHECK5-NEXT: ret void, !dbg [[DBG34]] // // // CHECK5-LABEL: define {{[^@]+}}@__cxx_global_var_init.4 -// CHECK5-SAME: () #[[ATTR0]] section "__TEXT,__StaticInit,regular,pure_instructions" personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) !dbg [[DBG36:![0-9]+]] { +// CHECK5-SAME: () #[[ATTR0]] section "__TEXT,__StaticInit,regular,pure_instructions" personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) !dbg [[DBG37:![0-9]+]] { // CHECK5-NEXT: entry: // CHECK5-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 // CHECK5-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 -// CHECK5-NEXT: br label [[ARRAYCTOR_LOOP:%.*]], !dbg [[DBG37:![0-9]+]] +// CHECK5-NEXT: br label [[ARRAYCTOR_LOOP:%.*]], !dbg [[DBG38:![0-9]+]] // CHECK5: arrayctor.loop: -// CHECK5-NEXT: [[ARRAYCTOR_CUR:%.*]] = phi %class.TestClass* [ getelementptr inbounds ([2 x %class.TestClass], [2 x %class.TestClass]* @tc2, i32 0, i32 0), [[ENTRY:%.*]] ], [ [[ARRAYCTOR_NEXT:%.*]], [[INVOKE_CONT:%.*]] ], !dbg [[DBG37]] +// CHECK5-NEXT: [[ARRAYCTOR_CUR:%.*]] = phi %class.TestClass* [ getelementptr inbounds ([2 x %class.TestClass], [2 x %class.TestClass]* @tc2, i32 0, i32 0), [[ENTRY:%.*]] ], [ [[ARRAYCTOR_NEXT:%.*]], [[INVOKE_CONT:%.*]] ], !dbg [[DBG38]] // CHECK5-NEXT: invoke void @_ZN9TestClassC1Ev(%class.TestClass* nonnull align 4 dereferenceable(4) [[ARRAYCTOR_CUR]]) -// CHECK5-NEXT: to label [[INVOKE_CONT]] unwind label [[LPAD:%.*]], !dbg [[DBG37]] +// CHECK5-NEXT: to label [[INVOKE_CONT]] unwind label [[LPAD:%.*]], !dbg [[DBG38]] // CHECK5: invoke.cont: -// CHECK5-NEXT: [[ARRAYCTOR_NEXT]] = getelementptr inbounds [[CLASS_TESTCLASS:%.*]], %class.TestClass* [[ARRAYCTOR_CUR]], i64 1, !dbg [[DBG37]] -// CHECK5-NEXT: [[ARRAYCTOR_DONE:%.*]] = icmp eq %class.TestClass* [[ARRAYCTOR_NEXT]], getelementptr inbounds ([2 x %class.TestClass], [2 x %class.TestClass]* @tc2, i64 1, i64 0), !dbg [[DBG37]] -// CHECK5-NEXT: br i1 [[ARRAYCTOR_DONE]], label [[ARRAYCTOR_CONT:%.*]], label [[ARRAYCTOR_LOOP]], !dbg [[DBG37]] +// CHECK5-NEXT: [[ARRAYCTOR_NEXT]] = getelementptr inbounds [[CLASS_TESTCLASS:%.*]], %class.TestClass* [[ARRAYCTOR_CUR]], i64 1, !dbg [[DBG38]] +// CHECK5-NEXT: [[ARRAYCTOR_DONE:%.*]] = icmp eq %class.TestClass* [[ARRAYCTOR_NEXT]], getelementptr inbounds ([2 x %class.TestClass], [2 x %class.TestClass]* @tc2, i64 1, i64 0), !dbg [[DBG38]] +// CHECK5-NEXT: br i1 [[ARRAYCTOR_DONE]], label [[ARRAYCTOR_CONT:%.*]], label [[ARRAYCTOR_LOOP]], !dbg [[DBG38]] // CHECK5: arrayctor.cont: -// CHECK5-NEXT: [[TMP0:%.*]] = call i32 @__cxa_atexit(void (i8*)* @__cxx_global_array_dtor, i8* null, i8* @__dso_handle) #[[ATTR3]], !dbg [[DBG39:![0-9]+]] -// CHECK5-NEXT: ret void, !dbg [[DBG39]] +// CHECK5-NEXT: [[TMP0:%.*]] = call i32 @__cxa_atexit(void (i8*)* @__cxx_global_array_dtor, i8* null, i8* @__dso_handle) #[[ATTR3]], !dbg [[DBG40:![0-9]+]] +// CHECK5-NEXT: ret void, !dbg [[DBG40]] // CHECK5: lpad: // CHECK5-NEXT: [[TMP1:%.*]] = landingpad { i8*, i32 } -// CHECK5-NEXT: cleanup, !dbg [[DBG40:![0-9]+]] -// CHECK5-NEXT: [[TMP2:%.*]] = extractvalue { i8*, i32 } [[TMP1]], 0, !dbg [[DBG40]] -// CHECK5-NEXT: store i8* [[TMP2]], i8** [[EXN_SLOT]], align 8, !dbg [[DBG40]] -// CHECK5-NEXT: [[TMP3:%.*]] = extractvalue { i8*, i32 } [[TMP1]], 1, !dbg [[DBG40]] -// CHECK5-NEXT: store i32 [[TMP3]], i32* [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG40]] -// CHECK5-NEXT: [[ARRAYDESTROY_ISEMPTY:%.*]] = icmp eq %class.TestClass* getelementptr inbounds ([2 x %class.TestClass], [2 x %class.TestClass]* @tc2, i32 0, i32 0), [[ARRAYCTOR_CUR]], !dbg [[DBG37]] -// CHECK5-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY]], label [[ARRAYDESTROY_DONE1:%.*]], label [[ARRAYDESTROY_BODY:%.*]], !dbg [[DBG37]] +// CHECK5-NEXT: cleanup, !dbg [[DBG41:![0-9]+]] +// CHECK5-NEXT: [[TMP2:%.*]] = extractvalue { i8*, i32 } [[TMP1]], 0, !dbg [[DBG41]] +// CHECK5-NEXT: store i8* [[TMP2]], i8** [[EXN_SLOT]], align 8, !dbg [[DBG41]] +// CHECK5-NEXT: [[TMP3:%.*]] = extractvalue { i8*, i32 } [[TMP1]], 1, !dbg [[DBG41]] +// CHECK5-NEXT: store i32 [[TMP3]], i32* [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG41]] +// CHECK5-NEXT: [[ARRAYDESTROY_ISEMPTY:%.*]] = icmp eq %class.TestClass* getelementptr inbounds ([2 x %class.TestClass], [2 x %class.TestClass]* @tc2, i32 0, i32 0), [[ARRAYCTOR_CUR]], !dbg [[DBG38]] +// CHECK5-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY]], label [[ARRAYDESTROY_DONE1:%.*]], label [[ARRAYDESTROY_BODY:%.*]], !dbg [[DBG38]] // CHECK5: arraydestroy.body: -// CHECK5-NEXT: [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi %class.TestClass* [ [[ARRAYCTOR_CUR]], [[LPAD]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ], !dbg [[DBG37]] -// CHECK5-NEXT: [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[CLASS_TESTCLASS]], %class.TestClass* [[ARRAYDESTROY_ELEMENTPAST]], i64 -1, !dbg [[DBG37]] -// CHECK5-NEXT: call void @_ZN9TestClassD1Ev(%class.TestClass* nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR3]], !dbg [[DBG37]] -// CHECK5-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq %class.TestClass* [[ARRAYDESTROY_ELEMENT]], getelementptr inbounds ([2 x %class.TestClass], [2 x %class.TestClass]* @tc2, i32 0, i32 0), !dbg [[DBG37]] -// CHECK5-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE1]], label [[ARRAYDESTROY_BODY]], !dbg [[DBG37]] +// CHECK5-NEXT: [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi %class.TestClass* [ [[ARRAYCTOR_CUR]], [[LPAD]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ], !dbg [[DBG38]] +// CHECK5-NEXT: [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[CLASS_TESTCLASS]], %class.TestClass* [[ARRAYDESTROY_ELEMENTPAST]], i64 -1, !dbg [[DBG38]] +// CHECK5-NEXT: call void @_ZN9TestClassD1Ev(%class.TestClass* nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR3]], !dbg [[DBG38]] +// CHECK5-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq %class.TestClass* [[ARRAYDESTROY_ELEMENT]], getelementptr inbounds ([2 x %class.TestClass], [2 x %class.TestClass]* @tc2, i32 0, i32 0), !dbg [[DBG38]] +// CHECK5-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE1]], label [[ARRAYDESTROY_BODY]], !dbg [[DBG38]] // CHECK5: arraydestroy.done1: -// CHECK5-NEXT: br label [[EH_RESUME:%.*]], !dbg [[DBG37]] +// CHECK5-NEXT: br label [[EH_RESUME:%.*]], !dbg [[DBG38]] // CHECK5: eh.resume: -// CHECK5-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8, !dbg [[DBG37]] -// CHECK5-NEXT: [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG37]] -// CHECK5-NEXT: [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN]], 0, !dbg [[DBG37]] -// CHECK5-NEXT: [[LPAD_VAL2:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL]], 1, !dbg [[DBG37]] -// CHECK5-NEXT: resume { i8*, i32 } [[LPAD_VAL2]], !dbg [[DBG37]] +// CHECK5-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8, !dbg [[DBG38]] +// CHECK5-NEXT: [[SEL:%.*]] = load i32, i32* [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG38]] +// CHECK5-NEXT: [[LPAD_VAL:%.*]] = insertvalue { i8*, i32 } undef, i8* [[EXN]], 0, !dbg [[DBG38]] +// CHECK5-NEXT: [[LPAD_VAL2:%.*]] = insertvalue { i8*, i32 } [[LPAD_VAL]], i32 [[SEL]], 1, !dbg [[DBG38]] +// CHECK5-NEXT: resume { i8*, i32 } [[LPAD_VAL2]], !dbg [[DBG38]] // // // CHECK5-LABEL: define {{[^@]+}}@__cxx_global_array_dtor -// CHECK5-SAME: (i8* [[TMP0:%.*]]) #[[ATTR0]] section "__TEXT,__StaticInit,regular,pure_instructions" !dbg [[DBG41:![0-9]+]] { +// CHECK5-SAME: (i8* [[TMP0:%.*]]) #[[ATTR0]] section "__TEXT,__StaticInit,regular,pure_instructions" !dbg [[DBG42:![0-9]+]] { // CHECK5-NEXT: entry: // CHECK5-NEXT: [[DOTADDR:%.*]] = alloca i8*, align 8 // CHECK5-NEXT: store i8* [[TMP0]], i8** [[DOTADDR]], align 8 -// CHECK5-NEXT: br label [[ARRAYDESTROY_BODY:%.*]], !dbg [[DBG42:![0-9]+]] +// CHECK5-NEXT: br label [[ARRAYDESTROY_BODY:%.*]], !dbg [[DBG43:![0-9]+]] // CHECK5: arraydestroy.body: -// CHECK5-NEXT: [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi %class.TestClass* [ getelementptr inbounds ([2 x %class.TestClass], [2 x %class.TestClass]* @tc2, i64 1, i64 0), [[ENTRY:%.*]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ], !dbg [[DBG42]] -// CHECK5-NEXT: [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[CLASS_TESTCLASS:%.*]], %class.TestClass* [[ARRAYDESTROY_ELEMENTPAST]], i64 -1, !dbg [[DBG42]] -// CHECK5-NEXT: call void @_ZN9TestClassD1Ev(%class.TestClass* nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR3]], !dbg [[DBG42]] -// CHECK5-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq %class.TestClass* [[ARRAYDESTROY_ELEMENT]], getelementptr inbounds ([2 x %class.TestClass], [2 x %class.TestClass]* @tc2, i32 0, i32 0), !dbg [[DBG42]] -// CHECK5-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE1:%.*]], label [[ARRAYDESTROY_BODY]], !dbg [[DBG42]] +// CHECK5-NEXT: [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi %class.TestClass* [ getelementptr inbounds ([2 x %class.TestClass], [2 x %class.TestClass]* @tc2, i64 1, i64 0), [[ENTRY:%.*]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ], !dbg [[DBG43]] +// CHECK5-NEXT: [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[CLASS_TESTCLASS:%.*]], %class.TestClass* [[ARRAYDESTROY_ELEMENTPAST]], i64 -1, !dbg [[DBG43]] +// CHECK5-NEXT: call void @_ZN9TestClassD1Ev(%class.TestClass* nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR3]], !dbg [[DBG43]] +// CHECK5-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq %class.TestClass* [[ARRAYDESTROY_ELEMENT]], getelementptr inbounds ([2 x %class.TestClass], [2 x %class.TestClass]* @tc2, i32 0, i32 0), !dbg [[DBG43]] +// CHECK5-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE1:%.*]], label [[ARRAYDESTROY_BODY]], !dbg [[DBG43]] // CHECK5: arraydestroy.done1: -// CHECK5-NEXT: ret void, !dbg [[DBG42]] +// CHECK5-NEXT: ret void, !dbg [[DBG43]] // // // CHECK5-LABEL: define {{[^@]+}}@_ZN9TestClassC2Ev -// CHECK5-SAME: (%class.TestClass* nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] align 2 !dbg [[DBG43:![0-9]+]] { +// CHECK5-SAME: (%class.TestClass* nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] align 2 !dbg [[DBG44:![0-9]+]] { // CHECK5-NEXT: entry: // CHECK5-NEXT: [[THIS_ADDR:%.*]] = alloca %class.TestClass*, align 8 // CHECK5-NEXT: store %class.TestClass* [[THIS]], %class.TestClass** [[THIS_ADDR]], align 8 // CHECK5-NEXT: [[THIS1:%.*]] = load %class.TestClass*, %class.TestClass** [[THIS_ADDR]], align 8 -// CHECK5-NEXT: [[A:%.*]] = getelementptr inbounds [[CLASS_TESTCLASS:%.*]], %class.TestClass* [[THIS1]], i32 0, i32 0, !dbg [[DBG44:![0-9]+]] -// CHECK5-NEXT: store i32 0, i32* [[A]], align 4, !dbg [[DBG44]] -// CHECK5-NEXT: ret void, !dbg [[DBG45:![0-9]+]] +// CHECK5-NEXT: [[A:%.*]] = getelementptr inbounds [[CLASS_TESTCLASS:%.*]], %class.TestClass* [[THIS1]], i32 0, i32 0, !dbg [[DBG45:![0-9]+]] +// CHECK5-NEXT: store i32 0, i32* [[A]], align 4, !dbg [[DBG45]] +// CHECK5-NEXT: ret void, !dbg [[DBG46:![0-9]+]] // // // CHECK5-LABEL: define {{[^@]+}}@_ZN9TestClassD2Ev -// CHECK5-SAME: (%class.TestClass* nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] align 2 !dbg [[DBG46:![0-9]+]] { +// CHECK5-SAME: (%class.TestClass* nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] align 2 !dbg [[DBG47:![0-9]+]] { // CHECK5-NEXT: entry: // CHECK5-NEXT: [[THIS_ADDR:%.*]] = alloca %class.TestClass*, align 8 // CHECK5-NEXT: store %class.TestClass* [[THIS]], %class.TestClass** [[THIS_ADDR]], align 8 // CHECK5-NEXT: [[THIS1:%.*]] = load %class.TestClass*, %class.TestClass** [[THIS_ADDR]], align 8 -// CHECK5-NEXT: ret void, !dbg [[DBG47:![0-9]+]] +// CHECK5-NEXT: ret void, !dbg [[DBG48:![0-9]+]] // // // CHECK5-LABEL: define {{[^@]+}}@_Z3foov -// CHECK5-SAME: () #[[ATTR4:[0-9]+]] !dbg [[DBG48:![0-9]+]] { +// CHECK5-SAME: () #[[ATTR4:[0-9]+]] !dbg [[DBG49:![0-9]+]] { // CHECK5-NEXT: entry: -// CHECK5-NEXT: call void @_Z8mayThrowv(), !dbg [[DBG49:![0-9]+]] -// CHECK5-NEXT: ret void, !dbg [[DBG50:![0-9]+]] +// CHECK5-NEXT: call void @_Z8mayThrowv(), !dbg [[DBG50:![0-9]+]] +// CHECK5-NEXT: ret void, !dbg [[DBG51:![0-9]+]] // // // CHECK5-LABEL: define {{[^@]+}}@main -// CHECK5-SAME: () #[[ATTR6:[0-9]+]] personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) !dbg [[DBG51:![0-9]+]] { +// CHECK5-SAME: () #[[ATTR6:[0-9]+]] personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) !dbg [[DBG52:![0-9]+]] { // CHECK5-NEXT: entry: // CHECK5-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 // CHECK5-NEXT: [[A:%.*]] = alloca i8, align 1 @@ -4219,93 +4387,102 @@ void array_func(int n, int a[n], St s[2]) { // CHECK5-NEXT: [[SST:%.*]] = alloca [[STRUCT_SST:%.*]], align 8 // CHECK5-NEXT: [[SS:%.*]] = alloca [[STRUCT_SS:%.*]], align 8 // CHECK5-NEXT: [[DOTOMP_COPYPRIVATE_DID_IT:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// CHECK5-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // CHECK5-NEXT: [[DOTOMP_COPYPRIVATE_CPR_LIST:%.*]] = alloca [5 x i8*], align 8 // CHECK5-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB5:[0-9]+]]) // CHECK5-NEXT: store i32 0, i32* [[RETVAL]], align 4 -// CHECK5-NEXT: store %class.TestClass* @tc, %class.TestClass** [[C]], align 8, !dbg [[DBG52:![0-9]+]] -// CHECK5-NEXT: call void @_ZN3SSTIdEC1Ev(%struct.SST* nonnull align 8 dereferenceable(8) [[SST]]), !dbg [[DBG53:![0-9]+]] -// CHECK5-NEXT: call void @_ZN2SSC1ERi(%struct.SS* nonnull align 8 dereferenceable(16) [[SS]], i32* nonnull align 4 dereferenceable(4) getelementptr inbounds ([[CLASS_TESTCLASS:%.*]], %class.TestClass* @tc, i32 0, i32 0)), !dbg [[DBG54:![0-9]+]] -// CHECK5-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_single(%struct.ident_t* @[[GLOB5]], i32 [[TMP0]]), !dbg [[DBG55:![0-9]+]] -// CHECK5-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0, !dbg [[DBG55]] -// CHECK5-NEXT: br i1 [[TMP2]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_END:%.*]], !dbg [[DBG55]] +// CHECK5-NEXT: store %class.TestClass* @tc, %class.TestClass** [[C]], align 8, !dbg [[DBG53:![0-9]+]] +// CHECK5-NEXT: call void @_ZN3SSTIdEC1Ev(%struct.SST* nonnull align 8 dereferenceable(8) [[SST]]), !dbg [[DBG54:![0-9]+]] +// CHECK5-NEXT: call void @_ZN2SSC1ERi(%struct.SS* nonnull align 8 dereferenceable(16) [[SS]], i32* nonnull align 4 dereferenceable(4) getelementptr inbounds ([[CLASS_TESTCLASS:%.*]], %class.TestClass* @tc, i32 0, i32 0)), !dbg [[DBG55:![0-9]+]] +// CHECK5-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_single(%struct.ident_t* @[[GLOB5]], i32 [[TMP0]]), !dbg [[DBG56:![0-9]+]] +// CHECK5-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0, !dbg [[DBG56]] +// CHECK5-NEXT: br i1 [[TMP2]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_END:%.*]], !dbg [[DBG56]] // CHECK5: omp_if.then: -// CHECK5-NEXT: store i8 2, i8* [[A]], align 1, !dbg [[DBG56:![0-9]+]] -// CHECK5-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB5]], i32 [[TMP0]]), !dbg [[DBG57:![0-9]+]] -// CHECK5-NEXT: br label [[OMP_IF_END]], !dbg [[DBG57]] +// CHECK5-NEXT: store i8 2, i8* [[A]], align 1, !dbg [[DBG57:![0-9]+]] +// CHECK5-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB5]], i32 [[TMP0]]), !dbg [[DBG58:![0-9]+]] +// CHECK5-NEXT: br label [[OMP_IF_END]], !dbg [[DBG58]] // CHECK5: omp_if.end: -// CHECK5-NEXT: [[TMP3:%.*]] = call i32 @__kmpc_single(%struct.ident_t* @[[GLOB7:[0-9]+]], i32 [[TMP0]]), !dbg [[DBG58:![0-9]+]] -// CHECK5-NEXT: [[TMP4:%.*]] = icmp ne i32 [[TMP3]], 0, !dbg [[DBG58]] -// CHECK5-NEXT: br i1 [[TMP4]], label [[OMP_IF_THEN1:%.*]], label [[OMP_IF_END2:%.*]], !dbg [[DBG58]] +// CHECK5-NEXT: [[TMP3:%.*]] = call i32 @__kmpc_single(%struct.ident_t* @[[GLOB7:[0-9]+]], i32 [[TMP0]]), !dbg [[DBG59:![0-9]+]] +// CHECK5-NEXT: [[TMP4:%.*]] = icmp ne i32 [[TMP3]], 0, !dbg [[DBG59]] +// CHECK5-NEXT: br i1 [[TMP4]], label [[OMP_IF_THEN1:%.*]], label [[OMP_IF_END2:%.*]], !dbg [[DBG59]] // CHECK5: omp_if.then1: -// CHECK5-NEXT: store i8 2, i8* [[A]], align 1, !dbg [[DBG59:![0-9]+]] -// CHECK5-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB7]], i32 [[TMP0]]), !dbg [[DBG60:![0-9]+]] -// CHECK5-NEXT: br label [[OMP_IF_END2]], !dbg [[DBG60]] +// CHECK5-NEXT: store i8 2, i8* [[A]], align 1, !dbg [[DBG60:![0-9]+]] +// CHECK5-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB7]], i32 [[TMP0]]), !dbg [[DBG61:![0-9]+]] +// CHECK5-NEXT: br label [[OMP_IF_END2]], !dbg [[DBG61]] // CHECK5: omp_if.end2: -// CHECK5-NEXT: call void @__kmpc_barrier(%struct.ident_t* @[[GLOB8:[0-9]+]], i32 [[TMP0]]), !dbg [[DBG61:![0-9]+]] -// CHECK5-NEXT: store i32 0, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4, !dbg [[DBG62:![0-9]+]] -// CHECK5-NEXT: [[TMP5:%.*]] = call i32 @__kmpc_single(%struct.ident_t* @[[GLOB10:[0-9]+]], i32 [[TMP0]]), !dbg [[DBG62]] -// CHECK5-NEXT: [[TMP6:%.*]] = icmp ne i32 [[TMP5]], 0, !dbg [[DBG62]] -// CHECK5-NEXT: br i1 [[TMP6]], label [[OMP_IF_THEN3:%.*]], label [[OMP_IF_END4:%.*]], !dbg [[DBG62]] +// CHECK5-NEXT: call void @__kmpc_barrier(%struct.ident_t* @[[GLOB8:[0-9]+]], i32 [[TMP0]]), !dbg [[DBG62:![0-9]+]] +// CHECK5-NEXT: store i32 0, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4, !dbg [[DBG63:![0-9]+]] +// CHECK5-NEXT: [[TMP5:%.*]] = call i32 @__kmpc_single(%struct.ident_t* @[[GLOB10:[0-9]+]], i32 [[TMP0]]), !dbg [[DBG63]] +// CHECK5-NEXT: [[TMP6:%.*]] = icmp ne i32 [[TMP5]], 0, !dbg [[DBG63]] +// CHECK5-NEXT: br i1 [[TMP6]], label [[OMP_IF_THEN3:%.*]], label [[OMP_IF_END4:%.*]], !dbg [[DBG63]] // CHECK5: omp_if.then3: // CHECK5-NEXT: invoke void @_Z3foov() -// CHECK5-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]], !dbg [[DBG63:![0-9]+]] +// CHECK5-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]], !dbg [[DBG64:![0-9]+]] // CHECK5: invoke.cont: -// CHECK5-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB10]], i32 [[TMP0]]), !dbg [[DBG63]] -// CHECK5-NEXT: store i32 1, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4, !dbg [[DBG63]] -// CHECK5-NEXT: br label [[OMP_IF_END4]], !dbg [[DBG63]] +// CHECK5-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB10]], i32 [[TMP0]]), !dbg [[DBG64]] +// CHECK5-NEXT: store i32 1, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4, !dbg [[DBG64]] +// CHECK5-NEXT: br label [[OMP_IF_END4]], !dbg [[DBG64]] +// CHECK5: lpad: +// CHECK5-NEXT: [[TMP7:%.*]] = landingpad { i8*, i32 } +// CHECK5-NEXT: catch i8* null, !dbg [[DBG65:![0-9]+]] +// CHECK5-NEXT: [[TMP8:%.*]] = extractvalue { i8*, i32 } [[TMP7]], 0, !dbg [[DBG65]] +// CHECK5-NEXT: store i8* [[TMP8]], i8** [[EXN_SLOT]], align 8, !dbg [[DBG65]] +// CHECK5-NEXT: [[TMP9:%.*]] = extractvalue { i8*, i32 } [[TMP7]], 1, !dbg [[DBG65]] +// CHECK5-NEXT: store i32 [[TMP9]], i32* [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG65]] +// CHECK5-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB10]], i32 [[TMP0]]), !dbg [[DBG64]] +// CHECK5-NEXT: br label [[TERMINATE_HANDLER:%.*]], !dbg [[DBG64]] // CHECK5: omp_if.end4: -// CHECK5-NEXT: [[TMP7:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 0, !dbg [[DBG63]] -// CHECK5-NEXT: store i8* [[A]], i8** [[TMP7]], align 8, !dbg [[DBG63]] -// CHECK5-NEXT: [[TMP8:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 1, !dbg [[DBG63]] -// CHECK5-NEXT: store i8* bitcast (%class.TestClass* @tc to i8*), i8** [[TMP8]], align 8, !dbg [[DBG63]] -// CHECK5-NEXT: [[TMP9:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 2, !dbg [[DBG63]] -// CHECK5-NEXT: [[TMP10:%.*]] = call i8* @__kmpc_threadprivate_cached(%struct.ident_t* @[[GLOB12:[0-9]+]], i32 [[TMP0]], i8* bitcast (%class.TestClass* @tc to i8*), i64 4, i8*** @tc.cache.), !dbg [[DBG64:![0-9]+]] -// CHECK5-NEXT: [[TMP11:%.*]] = bitcast i8* [[TMP10]] to %class.TestClass*, !dbg [[DBG64]] -// CHECK5-NEXT: [[TMP12:%.*]] = bitcast %class.TestClass* [[TMP11]] to i8*, !dbg [[DBG63]] -// CHECK5-NEXT: store i8* [[TMP12]], i8** [[TMP9]], align 8, !dbg [[DBG63]] -// CHECK5-NEXT: [[TMP13:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 3, !dbg [[DBG63]] -// CHECK5-NEXT: [[TMP14:%.*]] = bitcast [2 x i8]* [[A2]] to i8*, !dbg [[DBG63]] -// CHECK5-NEXT: store i8* [[TMP14]], i8** [[TMP13]], align 8, !dbg [[DBG63]] -// CHECK5-NEXT: [[TMP15:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 4, !dbg [[DBG63]] -// CHECK5-NEXT: [[TMP16:%.*]] = call i8* @__kmpc_threadprivate_cached(%struct.ident_t* @[[GLOB14:[0-9]+]], i32 [[TMP0]], i8* bitcast ([2 x %class.TestClass]* @tc2 to i8*), i64 8, i8*** @tc2.cache.), !dbg [[DBG65:![0-9]+]] -// CHECK5-NEXT: [[TMP17:%.*]] = bitcast i8* [[TMP16]] to [2 x %class.TestClass]*, !dbg [[DBG65]] -// CHECK5-NEXT: [[TMP18:%.*]] = bitcast [2 x %class.TestClass]* [[TMP17]] to i8*, !dbg [[DBG63]] -// CHECK5-NEXT: store i8* [[TMP18]], i8** [[TMP15]], align 8, !dbg [[DBG63]] -// CHECK5-NEXT: [[TMP19:%.*]] = bitcast [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]] to i8*, !dbg [[DBG63]] -// CHECK5-NEXT: [[TMP20:%.*]] = load i32, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4, !dbg [[DBG63]] -// CHECK5-NEXT: call void @__kmpc_copyprivate(%struct.ident_t* @[[GLOB10]], i32 [[TMP0]], i64 40, i8* [[TMP19]], void (i8*, i8*)* @.omp.copyprivate.copy_func, i32 [[TMP20]]), !dbg [[DBG63]] -// CHECK5-NEXT: [[TMP21:%.*]] = load i8, i8* [[A]], align 1, !dbg [[DBG66:![0-9]+]] -// CHECK5-NEXT: [[CONV:%.*]] = sext i8 [[TMP21]] to i32, !dbg [[DBG66]] -// CHECK5-NEXT: ret i32 [[CONV]], !dbg [[DBG67:![0-9]+]] -// CHECK5: terminate.lpad: -// CHECK5-NEXT: [[TMP22:%.*]] = landingpad { i8*, i32 } -// CHECK5-NEXT: catch i8* null, !dbg [[DBG63]] -// CHECK5-NEXT: [[TMP23:%.*]] = extractvalue { i8*, i32 } [[TMP22]], 0, !dbg [[DBG63]] -// CHECK5-NEXT: call void @__clang_call_terminate(i8* [[TMP23]]) #[[ATTR13:[0-9]+]], !dbg [[DBG63]] -// CHECK5-NEXT: unreachable, !dbg [[DBG63]] +// CHECK5-NEXT: [[TMP10:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 0, !dbg [[DBG64]] +// CHECK5-NEXT: store i8* [[A]], i8** [[TMP10]], align 8, !dbg [[DBG64]] +// CHECK5-NEXT: [[TMP11:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 1, !dbg [[DBG64]] +// CHECK5-NEXT: store i8* bitcast (%class.TestClass* @tc to i8*), i8** [[TMP11]], align 8, !dbg [[DBG64]] +// CHECK5-NEXT: [[TMP12:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 2, !dbg [[DBG64]] +// CHECK5-NEXT: [[TMP13:%.*]] = call i8* @__kmpc_threadprivate_cached(%struct.ident_t* @[[GLOB12:[0-9]+]], i32 [[TMP0]], i8* bitcast (%class.TestClass* @tc to i8*), i64 4, i8*** @tc.cache.), !dbg [[DBG66:![0-9]+]] +// CHECK5-NEXT: [[TMP14:%.*]] = bitcast i8* [[TMP13]] to %class.TestClass*, !dbg [[DBG66]] +// CHECK5-NEXT: [[TMP15:%.*]] = bitcast %class.TestClass* [[TMP14]] to i8*, !dbg [[DBG64]] +// CHECK5-NEXT: store i8* [[TMP15]], i8** [[TMP12]], align 8, !dbg [[DBG64]] +// CHECK5-NEXT: [[TMP16:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 3, !dbg [[DBG64]] +// CHECK5-NEXT: [[TMP17:%.*]] = bitcast [2 x i8]* [[A2]] to i8*, !dbg [[DBG64]] +// CHECK5-NEXT: store i8* [[TMP17]], i8** [[TMP16]], align 8, !dbg [[DBG64]] +// CHECK5-NEXT: [[TMP18:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 4, !dbg [[DBG64]] +// CHECK5-NEXT: [[TMP19:%.*]] = call i8* @__kmpc_threadprivate_cached(%struct.ident_t* @[[GLOB14:[0-9]+]], i32 [[TMP0]], i8* bitcast ([2 x %class.TestClass]* @tc2 to i8*), i64 8, i8*** @tc2.cache.), !dbg [[DBG67:![0-9]+]] +// CHECK5-NEXT: [[TMP20:%.*]] = bitcast i8* [[TMP19]] to [2 x %class.TestClass]*, !dbg [[DBG67]] +// CHECK5-NEXT: [[TMP21:%.*]] = bitcast [2 x %class.TestClass]* [[TMP20]] to i8*, !dbg [[DBG64]] +// CHECK5-NEXT: store i8* [[TMP21]], i8** [[TMP18]], align 8, !dbg [[DBG64]] +// CHECK5-NEXT: [[TMP22:%.*]] = bitcast [5 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]] to i8*, !dbg [[DBG64]] +// CHECK5-NEXT: [[TMP23:%.*]] = load i32, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4, !dbg [[DBG64]] +// CHECK5-NEXT: call void @__kmpc_copyprivate(%struct.ident_t* @[[GLOB10]], i32 [[TMP0]], i64 40, i8* [[TMP22]], void (i8*, i8*)* @.omp.copyprivate.copy_func, i32 [[TMP23]]), !dbg [[DBG64]] +// CHECK5-NEXT: [[TMP24:%.*]] = load i8, i8* [[A]], align 1, !dbg [[DBG68:![0-9]+]] +// CHECK5-NEXT: [[CONV:%.*]] = sext i8 [[TMP24]] to i32, !dbg [[DBG68]] +// CHECK5-NEXT: ret i32 [[CONV]], !dbg [[DBG69:![0-9]+]] +// CHECK5: terminate.handler: +// CHECK5-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8, !dbg [[DBG64]] +// CHECK5-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR13:[0-9]+]], !dbg [[DBG64]] +// CHECK5-NEXT: unreachable, !dbg [[DBG64]] // // // CHECK5-LABEL: define {{[^@]+}}@_ZN3SSTIdEC1Ev -// CHECK5-SAME: (%struct.SST* nonnull align 8 dereferenceable(8) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] align 2 !dbg [[DBG68:![0-9]+]] { +// CHECK5-SAME: (%struct.SST* nonnull align 8 dereferenceable(8) [[THIS:%.*]]) unnamed_addr #[[ATTR1]] align 2 !dbg [[DBG70:![0-9]+]] { // CHECK5-NEXT: entry: // CHECK5-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.SST*, align 8 // CHECK5-NEXT: store %struct.SST* [[THIS]], %struct.SST** [[THIS_ADDR]], align 8 // CHECK5-NEXT: [[THIS1:%.*]] = load %struct.SST*, %struct.SST** [[THIS_ADDR]], align 8 -// CHECK5-NEXT: call void @_ZN3SSTIdEC2Ev(%struct.SST* nonnull align 8 dereferenceable(8) [[THIS1]]), !dbg [[DBG69:![0-9]+]] -// CHECK5-NEXT: ret void, !dbg [[DBG70:![0-9]+]] +// CHECK5-NEXT: call void @_ZN3SSTIdEC2Ev(%struct.SST* nonnull align 8 dereferenceable(8) [[THIS1]]), !dbg [[DBG71:![0-9]+]] +// CHECK5-NEXT: ret void, !dbg [[DBG72:![0-9]+]] // // // CHECK5-LABEL: define {{[^@]+}}@_ZN2SSC1ERi -// CHECK5-SAME: (%struct.SS* nonnull align 8 dereferenceable(16) [[THIS:%.*]], i32* nonnull align 4 dereferenceable(4) [[D:%.*]]) unnamed_addr #[[ATTR1]] align 2 !dbg [[DBG71:![0-9]+]] { +// CHECK5-SAME: (%struct.SS* nonnull align 8 dereferenceable(16) [[THIS:%.*]], i32* nonnull align 4 dereferenceable(4) [[D:%.*]]) unnamed_addr #[[ATTR1]] align 2 !dbg [[DBG73:![0-9]+]] { // CHECK5-NEXT: entry: // CHECK5-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.SS*, align 8 // CHECK5-NEXT: [[D_ADDR:%.*]] = alloca i32*, align 8 // CHECK5-NEXT: store %struct.SS* [[THIS]], %struct.SS** [[THIS_ADDR]], align 8 // CHECK5-NEXT: store i32* [[D]], i32** [[D_ADDR]], align 8 // CHECK5-NEXT: [[THIS1:%.*]] = load %struct.SS*, %struct.SS** [[THIS_ADDR]], align 8 -// CHECK5-NEXT: [[TMP0:%.*]] = load i32*, i32** [[D_ADDR]], align 8, !dbg [[DBG72:![0-9]+]] -// CHECK5-NEXT: call void @_ZN2SSC2ERi(%struct.SS* nonnull align 8 dereferenceable(16) [[THIS1]], i32* nonnull align 4 dereferenceable(4) [[TMP0]]), !dbg [[DBG72]] -// CHECK5-NEXT: ret void, !dbg [[DBG73:![0-9]+]] +// CHECK5-NEXT: [[TMP0:%.*]] = load i32*, i32** [[D_ADDR]], align 8, !dbg [[DBG74:![0-9]+]] +// CHECK5-NEXT: call void @_ZN2SSC2ERi(%struct.SS* nonnull align 8 dereferenceable(16) [[THIS1]], i32* nonnull align 4 dereferenceable(4) [[TMP0]]), !dbg [[DBG74]] +// CHECK5-NEXT: ret void, !dbg [[DBG75:![0-9]+]] // // // CHECK5-LABEL: define {{[^@]+}}@__clang_call_terminate @@ -4316,96 +4493,96 @@ void array_func(int n, int a[n], St s[2]) { // // // CHECK5-LABEL: define {{[^@]+}}@.omp.copyprivate.copy_func -// CHECK5-SAME: (i8* [[TMP0:%.*]], i8* [[TMP1:%.*]]) #[[ATTR9:[0-9]+]] !dbg [[DBG74:![0-9]+]] { +// CHECK5-SAME: (i8* [[TMP0:%.*]], i8* [[TMP1:%.*]]) #[[ATTR9:[0-9]+]] !dbg [[DBG76:![0-9]+]] { // CHECK5-NEXT: entry: // CHECK5-NEXT: [[DOTADDR:%.*]] = alloca i8*, align 8 // CHECK5-NEXT: [[DOTADDR1:%.*]] = alloca i8*, align 8 // CHECK5-NEXT: store i8* [[TMP0]], i8** [[DOTADDR]], align 8 // CHECK5-NEXT: store i8* [[TMP1]], i8** [[DOTADDR1]], align 8 -// CHECK5-NEXT: [[TMP2:%.*]] = load i8*, i8** [[DOTADDR]], align 8, !dbg [[DBG75:![0-9]+]] -// CHECK5-NEXT: [[TMP3:%.*]] = bitcast i8* [[TMP2]] to [5 x i8*]*, !dbg [[DBG75]] -// CHECK5-NEXT: [[TMP4:%.*]] = load i8*, i8** [[DOTADDR1]], align 8, !dbg [[DBG75]] -// CHECK5-NEXT: [[TMP5:%.*]] = bitcast i8* [[TMP4]] to [5 x i8*]*, !dbg [[DBG75]] -// CHECK5-NEXT: [[TMP6:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[TMP3]], i64 0, i64 0, !dbg [[DBG75]] -// CHECK5-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8, !dbg [[DBG75]] -// CHECK5-NEXT: [[TMP8:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[TMP5]], i64 0, i64 0, !dbg [[DBG75]] -// CHECK5-NEXT: [[TMP9:%.*]] = load i8*, i8** [[TMP8]], align 8, !dbg [[DBG75]] -// CHECK5-NEXT: [[TMP10:%.*]] = load i8, i8* [[TMP9]], align 1, !dbg [[DBG76:![0-9]+]] -// CHECK5-NEXT: store i8 [[TMP10]], i8* [[TMP7]], align 1, !dbg [[DBG76]] -// CHECK5-NEXT: [[TMP11:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[TMP3]], i64 0, i64 1, !dbg [[DBG75]] -// CHECK5-NEXT: [[TMP12:%.*]] = load i8*, i8** [[TMP11]], align 8, !dbg [[DBG75]] -// CHECK5-NEXT: [[TMP13:%.*]] = bitcast i8* [[TMP12]] to %class.TestClass*, !dbg [[DBG75]] -// CHECK5-NEXT: [[TMP14:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[TMP5]], i64 0, i64 1, !dbg [[DBG75]] -// CHECK5-NEXT: [[TMP15:%.*]] = load i8*, i8** [[TMP14]], align 8, !dbg [[DBG75]] -// CHECK5-NEXT: [[TMP16:%.*]] = bitcast i8* [[TMP15]] to %class.TestClass*, !dbg [[DBG75]] -// CHECK5-NEXT: [[CALL:%.*]] = call nonnull align 4 dereferenceable(4) %class.TestClass* @_ZN9TestClassaSERKS_(%class.TestClass* nonnull align 4 dereferenceable(4) [[TMP13]], %class.TestClass* nonnull align 4 dereferenceable(4) [[TMP16]]), !dbg [[DBG77:![0-9]+]] -// CHECK5-NEXT: [[TMP17:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[TMP3]], i64 0, i64 2, !dbg [[DBG75]] -// CHECK5-NEXT: [[TMP18:%.*]] = load i8*, i8** [[TMP17]], align 8, !dbg [[DBG75]] -// CHECK5-NEXT: [[TMP19:%.*]] = bitcast i8* [[TMP18]] to %class.TestClass*, !dbg [[DBG75]] -// CHECK5-NEXT: [[TMP20:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[TMP5]], i64 0, i64 2, !dbg [[DBG75]] -// CHECK5-NEXT: [[TMP21:%.*]] = load i8*, i8** [[TMP20]], align 8, !dbg [[DBG75]] -// CHECK5-NEXT: [[TMP22:%.*]] = bitcast i8* [[TMP21]] to %class.TestClass*, !dbg [[DBG75]] -// CHECK5-NEXT: [[CALL2:%.*]] = call nonnull align 4 dereferenceable(4) %class.TestClass* @_ZN9TestClassaSERKS_(%class.TestClass* nonnull align 4 dereferenceable(4) [[TMP19]], %class.TestClass* nonnull align 4 dereferenceable(4) [[TMP22]]), !dbg [[DBG78:![0-9]+]] -// CHECK5-NEXT: [[TMP23:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[TMP3]], i64 0, i64 3, !dbg [[DBG75]] -// CHECK5-NEXT: [[TMP24:%.*]] = load i8*, i8** [[TMP23]], align 8, !dbg [[DBG75]] -// CHECK5-NEXT: [[TMP25:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[TMP5]], i64 0, i64 3, !dbg [[DBG75]] -// CHECK5-NEXT: [[TMP26:%.*]] = load i8*, i8** [[TMP25]], align 8, !dbg [[DBG75]] -// CHECK5-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 [[TMP24]], i8* align 1 [[TMP26]], i64 2, i1 false), !dbg [[DBG75]] -// CHECK5-NEXT: [[TMP27:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[TMP3]], i64 0, i64 4, !dbg [[DBG75]] -// CHECK5-NEXT: [[TMP28:%.*]] = load i8*, i8** [[TMP27]], align 8, !dbg [[DBG75]] -// CHECK5-NEXT: [[TMP29:%.*]] = bitcast i8* [[TMP28]] to %class.TestClass*, !dbg [[DBG75]] -// CHECK5-NEXT: [[TMP30:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[TMP5]], i64 0, i64 4, !dbg [[DBG75]] -// CHECK5-NEXT: [[TMP31:%.*]] = load i8*, i8** [[TMP30]], align 8, !dbg [[DBG75]] -// CHECK5-NEXT: [[TMP32:%.*]] = bitcast i8* [[TMP31]] to %class.TestClass*, !dbg [[DBG75]] -// CHECK5-NEXT: [[TMP33:%.*]] = getelementptr [[CLASS_TESTCLASS:%.*]], %class.TestClass* [[TMP29]], i64 2, !dbg [[DBG75]] -// CHECK5-NEXT: [[OMP_ARRAYCPY_ISEMPTY:%.*]] = icmp eq %class.TestClass* [[TMP29]], [[TMP33]], !dbg [[DBG75]] -// CHECK5-NEXT: br i1 [[OMP_ARRAYCPY_ISEMPTY]], label [[OMP_ARRAYCPY_DONE4:%.*]], label [[OMP_ARRAYCPY_BODY:%.*]], !dbg [[DBG75]] +// CHECK5-NEXT: [[TMP2:%.*]] = load i8*, i8** [[DOTADDR]], align 8, !dbg [[DBG77:![0-9]+]] +// CHECK5-NEXT: [[TMP3:%.*]] = bitcast i8* [[TMP2]] to [5 x i8*]*, !dbg [[DBG77]] +// CHECK5-NEXT: [[TMP4:%.*]] = load i8*, i8** [[DOTADDR1]], align 8, !dbg [[DBG77]] +// CHECK5-NEXT: [[TMP5:%.*]] = bitcast i8* [[TMP4]] to [5 x i8*]*, !dbg [[DBG77]] +// CHECK5-NEXT: [[TMP6:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[TMP3]], i64 0, i64 0, !dbg [[DBG77]] +// CHECK5-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8, !dbg [[DBG77]] +// CHECK5-NEXT: [[TMP8:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[TMP5]], i64 0, i64 0, !dbg [[DBG77]] +// CHECK5-NEXT: [[TMP9:%.*]] = load i8*, i8** [[TMP8]], align 8, !dbg [[DBG77]] +// CHECK5-NEXT: [[TMP10:%.*]] = load i8, i8* [[TMP9]], align 1, !dbg [[DBG78:![0-9]+]] +// CHECK5-NEXT: store i8 [[TMP10]], i8* [[TMP7]], align 1, !dbg [[DBG78]] +// CHECK5-NEXT: [[TMP11:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[TMP3]], i64 0, i64 1, !dbg [[DBG77]] +// CHECK5-NEXT: [[TMP12:%.*]] = load i8*, i8** [[TMP11]], align 8, !dbg [[DBG77]] +// CHECK5-NEXT: [[TMP13:%.*]] = bitcast i8* [[TMP12]] to %class.TestClass*, !dbg [[DBG77]] +// CHECK5-NEXT: [[TMP14:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[TMP5]], i64 0, i64 1, !dbg [[DBG77]] +// CHECK5-NEXT: [[TMP15:%.*]] = load i8*, i8** [[TMP14]], align 8, !dbg [[DBG77]] +// CHECK5-NEXT: [[TMP16:%.*]] = bitcast i8* [[TMP15]] to %class.TestClass*, !dbg [[DBG77]] +// CHECK5-NEXT: [[CALL:%.*]] = call nonnull align 4 dereferenceable(4) %class.TestClass* @_ZN9TestClassaSERKS_(%class.TestClass* nonnull align 4 dereferenceable(4) [[TMP13]], %class.TestClass* nonnull align 4 dereferenceable(4) [[TMP16]]), !dbg [[DBG79:![0-9]+]] +// CHECK5-NEXT: [[TMP17:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[TMP3]], i64 0, i64 2, !dbg [[DBG77]] +// CHECK5-NEXT: [[TMP18:%.*]] = load i8*, i8** [[TMP17]], align 8, !dbg [[DBG77]] +// CHECK5-NEXT: [[TMP19:%.*]] = bitcast i8* [[TMP18]] to %class.TestClass*, !dbg [[DBG77]] +// CHECK5-NEXT: [[TMP20:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[TMP5]], i64 0, i64 2, !dbg [[DBG77]] +// CHECK5-NEXT: [[TMP21:%.*]] = load i8*, i8** [[TMP20]], align 8, !dbg [[DBG77]] +// CHECK5-NEXT: [[TMP22:%.*]] = bitcast i8* [[TMP21]] to %class.TestClass*, !dbg [[DBG77]] +// CHECK5-NEXT: [[CALL2:%.*]] = call nonnull align 4 dereferenceable(4) %class.TestClass* @_ZN9TestClassaSERKS_(%class.TestClass* nonnull align 4 dereferenceable(4) [[TMP19]], %class.TestClass* nonnull align 4 dereferenceable(4) [[TMP22]]), !dbg [[DBG80:![0-9]+]] +// CHECK5-NEXT: [[TMP23:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[TMP3]], i64 0, i64 3, !dbg [[DBG77]] +// CHECK5-NEXT: [[TMP24:%.*]] = load i8*, i8** [[TMP23]], align 8, !dbg [[DBG77]] +// CHECK5-NEXT: [[TMP25:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[TMP5]], i64 0, i64 3, !dbg [[DBG77]] +// CHECK5-NEXT: [[TMP26:%.*]] = load i8*, i8** [[TMP25]], align 8, !dbg [[DBG77]] +// CHECK5-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 [[TMP24]], i8* align 1 [[TMP26]], i64 2, i1 false), !dbg [[DBG77]] +// CHECK5-NEXT: [[TMP27:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[TMP3]], i64 0, i64 4, !dbg [[DBG77]] +// CHECK5-NEXT: [[TMP28:%.*]] = load i8*, i8** [[TMP27]], align 8, !dbg [[DBG77]] +// CHECK5-NEXT: [[TMP29:%.*]] = bitcast i8* [[TMP28]] to %class.TestClass*, !dbg [[DBG77]] +// CHECK5-NEXT: [[TMP30:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[TMP5]], i64 0, i64 4, !dbg [[DBG77]] +// CHECK5-NEXT: [[TMP31:%.*]] = load i8*, i8** [[TMP30]], align 8, !dbg [[DBG77]] +// CHECK5-NEXT: [[TMP32:%.*]] = bitcast i8* [[TMP31]] to %class.TestClass*, !dbg [[DBG77]] +// CHECK5-NEXT: [[TMP33:%.*]] = getelementptr [[CLASS_TESTCLASS:%.*]], %class.TestClass* [[TMP29]], i64 2, !dbg [[DBG77]] +// CHECK5-NEXT: [[OMP_ARRAYCPY_ISEMPTY:%.*]] = icmp eq %class.TestClass* [[TMP29]], [[TMP33]], !dbg [[DBG77]] +// CHECK5-NEXT: br i1 [[OMP_ARRAYCPY_ISEMPTY]], label [[OMP_ARRAYCPY_DONE4:%.*]], label [[OMP_ARRAYCPY_BODY:%.*]], !dbg [[DBG77]] // CHECK5: omp.arraycpy.body: -// CHECK5-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST:%.*]] = phi %class.TestClass* [ [[TMP32]], [[ENTRY:%.*]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT:%.*]], [[OMP_ARRAYCPY_BODY]] ], !dbg [[DBG75]] -// CHECK5-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST:%.*]] = phi %class.TestClass* [ [[TMP29]], [[ENTRY]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT:%.*]], [[OMP_ARRAYCPY_BODY]] ], !dbg [[DBG75]] -// CHECK5-NEXT: [[CALL3:%.*]] = call nonnull align 4 dereferenceable(4) %class.TestClass* @_ZN9TestClassaSERKS_(%class.TestClass* nonnull align 4 dereferenceable(4) [[OMP_ARRAYCPY_DESTELEMENTPAST]], %class.TestClass* nonnull align 4 dereferenceable(4) [[OMP_ARRAYCPY_SRCELEMENTPAST]]), !dbg [[DBG79:![0-9]+]] -// CHECK5-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT]] = getelementptr [[CLASS_TESTCLASS]], %class.TestClass* [[OMP_ARRAYCPY_DESTELEMENTPAST]], i32 1, !dbg [[DBG75]] -// CHECK5-NEXT: [[OMP_ARRAYCPY_SRC_ELEMENT]] = getelementptr [[CLASS_TESTCLASS]], %class.TestClass* [[OMP_ARRAYCPY_SRCELEMENTPAST]], i32 1, !dbg [[DBG75]] -// CHECK5-NEXT: [[OMP_ARRAYCPY_DONE:%.*]] = icmp eq %class.TestClass* [[OMP_ARRAYCPY_DEST_ELEMENT]], [[TMP33]], !dbg [[DBG75]] -// CHECK5-NEXT: br i1 [[OMP_ARRAYCPY_DONE]], label [[OMP_ARRAYCPY_DONE4]], label [[OMP_ARRAYCPY_BODY]], !dbg [[DBG75]] +// CHECK5-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST:%.*]] = phi %class.TestClass* [ [[TMP32]], [[ENTRY:%.*]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT:%.*]], [[OMP_ARRAYCPY_BODY]] ], !dbg [[DBG77]] +// CHECK5-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST:%.*]] = phi %class.TestClass* [ [[TMP29]], [[ENTRY]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT:%.*]], [[OMP_ARRAYCPY_BODY]] ], !dbg [[DBG77]] +// CHECK5-NEXT: [[CALL3:%.*]] = call nonnull align 4 dereferenceable(4) %class.TestClass* @_ZN9TestClassaSERKS_(%class.TestClass* nonnull align 4 dereferenceable(4) [[OMP_ARRAYCPY_DESTELEMENTPAST]], %class.TestClass* nonnull align 4 dereferenceable(4) [[OMP_ARRAYCPY_SRCELEMENTPAST]]), !dbg [[DBG81:![0-9]+]] +// CHECK5-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT]] = getelementptr [[CLASS_TESTCLASS]], %class.TestClass* [[OMP_ARRAYCPY_DESTELEMENTPAST]], i32 1, !dbg [[DBG77]] +// CHECK5-NEXT: [[OMP_ARRAYCPY_SRC_ELEMENT]] = getelementptr [[CLASS_TESTCLASS]], %class.TestClass* [[OMP_ARRAYCPY_SRCELEMENTPAST]], i32 1, !dbg [[DBG77]] +// CHECK5-NEXT: [[OMP_ARRAYCPY_DONE:%.*]] = icmp eq %class.TestClass* [[OMP_ARRAYCPY_DEST_ELEMENT]], [[TMP33]], !dbg [[DBG77]] +// CHECK5-NEXT: br i1 [[OMP_ARRAYCPY_DONE]], label [[OMP_ARRAYCPY_DONE4]], label [[OMP_ARRAYCPY_BODY]], !dbg [[DBG77]] // CHECK5: omp.arraycpy.done4: -// CHECK5-NEXT: ret void, !dbg [[DBG79]] +// CHECK5-NEXT: ret void, !dbg [[DBG81]] // // // CHECK5-LABEL: define {{[^@]+}}@_ZN9TestClassaSERKS_ -// CHECK5-SAME: (%class.TestClass* nonnull align 4 dereferenceable(4) [[THIS:%.*]], %class.TestClass* nonnull align 4 dereferenceable(4) [[TMP0:%.*]]) #[[ATTR10:[0-9]+]] align 2 !dbg [[DBG80:![0-9]+]] { +// CHECK5-SAME: (%class.TestClass* nonnull align 4 dereferenceable(4) [[THIS:%.*]], %class.TestClass* nonnull align 4 dereferenceable(4) [[TMP0:%.*]]) #[[ATTR10:[0-9]+]] align 2 !dbg [[DBG82:![0-9]+]] { // CHECK5-NEXT: entry: // CHECK5-NEXT: [[THIS_ADDR:%.*]] = alloca %class.TestClass*, align 8 // CHECK5-NEXT: [[DOTADDR:%.*]] = alloca %class.TestClass*, align 8 // CHECK5-NEXT: store %class.TestClass* [[THIS]], %class.TestClass** [[THIS_ADDR]], align 8 // CHECK5-NEXT: store %class.TestClass* [[TMP0]], %class.TestClass** [[DOTADDR]], align 8 // CHECK5-NEXT: [[THIS1:%.*]] = load %class.TestClass*, %class.TestClass** [[THIS_ADDR]], align 8 -// CHECK5-NEXT: ret %class.TestClass* [[THIS1]], !dbg [[DBG81:![0-9]+]] +// CHECK5-NEXT: ret %class.TestClass* [[THIS1]], !dbg [[DBG83:![0-9]+]] // // // CHECK5-LABEL: define {{[^@]+}}@_ZN3SSTIdEC2Ev -// CHECK5-SAME: (%struct.SST* nonnull align 8 dereferenceable(8) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] align 2 !dbg [[DBG82:![0-9]+]] { +// CHECK5-SAME: (%struct.SST* nonnull align 8 dereferenceable(8) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] align 2 !dbg [[DBG84:![0-9]+]] { // CHECK5-NEXT: entry: // CHECK5-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.SST*, align 8 // CHECK5-NEXT: [[A2:%.*]] = alloca double*, align 8 // CHECK5-NEXT: [[A_CASTED:%.*]] = alloca i64, align 8 // CHECK5-NEXT: store %struct.SST* [[THIS]], %struct.SST** [[THIS_ADDR]], align 8 // CHECK5-NEXT: [[THIS1:%.*]] = load %struct.SST*, %struct.SST** [[THIS_ADDR]], align 8 -// CHECK5-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_SST:%.*]], %struct.SST* [[THIS1]], i32 0, i32 0, !dbg [[DBG83:![0-9]+]] -// CHECK5-NEXT: store double 0.000000e+00, double* [[A]], align 8, !dbg [[DBG83]] -// CHECK5-NEXT: [[A3:%.*]] = getelementptr inbounds [[STRUCT_SST]], %struct.SST* [[THIS1]], i32 0, i32 0, !dbg [[DBG84:![0-9]+]] -// CHECK5-NEXT: store double* [[A3]], double** [[A2]], align 8, !dbg [[DBG84]] -// CHECK5-NEXT: [[TMP0:%.*]] = load double*, double** [[A2]], align 8, !dbg [[DBG85:![0-9]+]] -// CHECK5-NEXT: [[TMP1:%.*]] = load double, double* [[TMP0]], align 8, !dbg [[DBG86:![0-9]+]] -// CHECK5-NEXT: [[CONV:%.*]] = bitcast i64* [[A_CASTED]] to double*, !dbg [[DBG86]] -// CHECK5-NEXT: store double [[TMP1]], double* [[CONV]], align 8, !dbg [[DBG86]] -// CHECK5-NEXT: [[TMP2:%.*]] = load i64, i64* [[A_CASTED]], align 8, !dbg [[DBG86]] -// CHECK5-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB18:[0-9]+]], i32 2, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %struct.SST*, i64)* @.omp_outlined. to void (i32*, i32*, ...)*), %struct.SST* [[THIS1]], i64 [[TMP2]]), !dbg [[DBG86]] -// CHECK5-NEXT: ret void, !dbg [[DBG87:![0-9]+]] +// CHECK5-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_SST:%.*]], %struct.SST* [[THIS1]], i32 0, i32 0, !dbg [[DBG85:![0-9]+]] +// CHECK5-NEXT: store double 0.000000e+00, double* [[A]], align 8, !dbg [[DBG85]] +// CHECK5-NEXT: [[A3:%.*]] = getelementptr inbounds [[STRUCT_SST]], %struct.SST* [[THIS1]], i32 0, i32 0, !dbg [[DBG86:![0-9]+]] +// CHECK5-NEXT: store double* [[A3]], double** [[A2]], align 8, !dbg [[DBG86]] +// CHECK5-NEXT: [[TMP0:%.*]] = load double*, double** [[A2]], align 8, !dbg [[DBG87:![0-9]+]] +// CHECK5-NEXT: [[TMP1:%.*]] = load double, double* [[TMP0]], align 8, !dbg [[DBG88:![0-9]+]] +// CHECK5-NEXT: [[CONV:%.*]] = bitcast i64* [[A_CASTED]] to double*, !dbg [[DBG88]] +// CHECK5-NEXT: store double [[TMP1]], double* [[CONV]], align 8, !dbg [[DBG88]] +// CHECK5-NEXT: [[TMP2:%.*]] = load i64, i64* [[A_CASTED]], align 8, !dbg [[DBG88]] +// CHECK5-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB18:[0-9]+]], i32 2, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %struct.SST*, i64)* @.omp_outlined. to void (i32*, i32*, ...)*), %struct.SST* [[THIS1]], i64 [[TMP2]]), !dbg [[DBG88]] +// CHECK5-NEXT: ret void, !dbg [[DBG89:![0-9]+]] // // // CHECK5-LABEL: define {{[^@]+}}@.omp_outlined. -// CHECK5-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], %struct.SST* [[THIS:%.*]], i64 [[A:%.*]]) #[[ATTR12:[0-9]+]] personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) !dbg [[DBG88:![0-9]+]] { +// CHECK5-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], %struct.SST* [[THIS:%.*]], i64 [[A:%.*]]) #[[ATTR12:[0-9]+]] personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) !dbg [[DBG90:![0-9]+]] { // CHECK5-NEXT: entry: // CHECK5-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK5-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 @@ -4415,53 +4592,62 @@ void array_func(int n, int a[n], St s[2]) { // CHECK5-NEXT: [[_TMP1:%.*]] = alloca double*, align 8 // CHECK5-NEXT: [[DOTOMP_COPYPRIVATE_DID_IT:%.*]] = alloca i32, align 4 // CHECK5-NEXT: [[REF_TMP:%.*]] = alloca [[CLASS_ANON:%.*]], align 8 +// CHECK5-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// CHECK5-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // CHECK5-NEXT: [[DOTOMP_COPYPRIVATE_CPR_LIST:%.*]] = alloca [1 x i8*], align 8 // CHECK5-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK5-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 // CHECK5-NEXT: store %struct.SST* [[THIS]], %struct.SST** [[THIS_ADDR]], align 8 // CHECK5-NEXT: store i64 [[A]], i64* [[A_ADDR]], align 8 -// CHECK5-NEXT: [[TMP0:%.*]] = load %struct.SST*, %struct.SST** [[THIS_ADDR]], align 8, !dbg [[DBG89:![0-9]+]] -// CHECK5-NEXT: [[CONV:%.*]] = bitcast i64* [[A_ADDR]] to double*, !dbg [[DBG89]] -// CHECK5-NEXT: store double* [[CONV]], double** [[TMP]], align 8, !dbg [[DBG89]] -// CHECK5-NEXT: [[TMP1:%.*]] = load double*, double** [[TMP]], align 8, !dbg [[DBG90:![0-9]+]] -// CHECK5-NEXT: store double* [[TMP1]], double** [[_TMP1]], align 8, !dbg [[DBG91:![0-9]+]] -// CHECK5-NEXT: store i32 0, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4, !dbg [[DBG91]] -// CHECK5-NEXT: [[TMP2:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG91]] -// CHECK5-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4, !dbg [[DBG91]] -// CHECK5-NEXT: [[TMP4:%.*]] = call i32 @__kmpc_single(%struct.ident_t* @[[GLOB16:[0-9]+]], i32 [[TMP3]]), !dbg [[DBG91]] -// CHECK5-NEXT: [[TMP5:%.*]] = icmp ne i32 [[TMP4]], 0, !dbg [[DBG91]] -// CHECK5-NEXT: br i1 [[TMP5]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_END:%.*]], !dbg [[DBG91]] +// CHECK5-NEXT: [[TMP0:%.*]] = load %struct.SST*, %struct.SST** [[THIS_ADDR]], align 8, !dbg [[DBG91:![0-9]+]] +// CHECK5-NEXT: [[CONV:%.*]] = bitcast i64* [[A_ADDR]] to double*, !dbg [[DBG91]] +// CHECK5-NEXT: store double* [[CONV]], double** [[TMP]], align 8, !dbg [[DBG91]] +// CHECK5-NEXT: [[TMP1:%.*]] = load double*, double** [[TMP]], align 8, !dbg [[DBG92:![0-9]+]] +// CHECK5-NEXT: store double* [[TMP1]], double** [[_TMP1]], align 8, !dbg [[DBG93:![0-9]+]] +// CHECK5-NEXT: store i32 0, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4, !dbg [[DBG93]] +// CHECK5-NEXT: [[TMP2:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG93]] +// CHECK5-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4, !dbg [[DBG93]] +// CHECK5-NEXT: [[TMP4:%.*]] = call i32 @__kmpc_single(%struct.ident_t* @[[GLOB16:[0-9]+]], i32 [[TMP3]]), !dbg [[DBG93]] +// CHECK5-NEXT: [[TMP5:%.*]] = icmp ne i32 [[TMP4]], 0, !dbg [[DBG93]] +// CHECK5-NEXT: br i1 [[TMP5]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_END:%.*]], !dbg [[DBG93]] // CHECK5: omp_if.then: -// CHECK5-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[CLASS_ANON]], %class.anon* [[REF_TMP]], i32 0, i32 0, !dbg [[DBG92:![0-9]+]] -// CHECK5-NEXT: store %struct.SST* [[TMP0]], %struct.SST** [[TMP6]], align 8, !dbg [[DBG92]] -// CHECK5-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[CLASS_ANON]], %class.anon* [[REF_TMP]], i32 0, i32 1, !dbg [[DBG92]] -// CHECK5-NEXT: [[TMP8:%.*]] = load double*, double** [[_TMP1]], align 8, !dbg [[DBG93:![0-9]+]] -// CHECK5-NEXT: store double* [[TMP8]], double** [[TMP7]], align 8, !dbg [[DBG92]] +// CHECK5-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[CLASS_ANON]], %class.anon* [[REF_TMP]], i32 0, i32 0, !dbg [[DBG94:![0-9]+]] +// CHECK5-NEXT: store %struct.SST* [[TMP0]], %struct.SST** [[TMP6]], align 8, !dbg [[DBG94]] +// CHECK5-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[CLASS_ANON]], %class.anon* [[REF_TMP]], i32 0, i32 1, !dbg [[DBG94]] +// CHECK5-NEXT: [[TMP8:%.*]] = load double*, double** [[_TMP1]], align 8, !dbg [[DBG95:![0-9]+]] +// CHECK5-NEXT: store double* [[TMP8]], double** [[TMP7]], align 8, !dbg [[DBG94]] // CHECK5-NEXT: invoke void @_ZZN3SSTIdEC1EvENKUlvE_clEv(%class.anon* nonnull align 8 dereferenceable(16) [[REF_TMP]]) -// CHECK5-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]], !dbg [[DBG92]] +// CHECK5-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]], !dbg [[DBG94]] // CHECK5: invoke.cont: -// CHECK5-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB16]], i32 [[TMP3]]), !dbg [[DBG92]] -// CHECK5-NEXT: store i32 1, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4, !dbg [[DBG92]] -// CHECK5-NEXT: br label [[OMP_IF_END]], !dbg [[DBG92]] +// CHECK5-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB16]], i32 [[TMP3]]), !dbg [[DBG94]] +// CHECK5-NEXT: store i32 1, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4, !dbg [[DBG94]] +// CHECK5-NEXT: br label [[OMP_IF_END]], !dbg [[DBG94]] +// CHECK5: lpad: +// CHECK5-NEXT: [[TMP9:%.*]] = landingpad { i8*, i32 } +// CHECK5-NEXT: catch i8* null, !dbg [[DBG96:![0-9]+]] +// CHECK5-NEXT: [[TMP10:%.*]] = extractvalue { i8*, i32 } [[TMP9]], 0, !dbg [[DBG96]] +// CHECK5-NEXT: store i8* [[TMP10]], i8** [[EXN_SLOT]], align 8, !dbg [[DBG96]] +// CHECK5-NEXT: [[TMP11:%.*]] = extractvalue { i8*, i32 } [[TMP9]], 1, !dbg [[DBG96]] +// CHECK5-NEXT: store i32 [[TMP11]], i32* [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG96]] +// CHECK5-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB16]], i32 [[TMP3]]), !dbg [[DBG94]] +// CHECK5-NEXT: br label [[TERMINATE_HANDLER:%.*]], !dbg [[DBG94]] // CHECK5: omp_if.end: -// CHECK5-NEXT: [[TMP9:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 0, !dbg [[DBG92]] -// CHECK5-NEXT: [[TMP10:%.*]] = load double*, double** [[_TMP1]], align 8, !dbg [[DBG94:![0-9]+]] -// CHECK5-NEXT: [[TMP11:%.*]] = bitcast double* [[TMP10]] to i8*, !dbg [[DBG92]] -// CHECK5-NEXT: store i8* [[TMP11]], i8** [[TMP9]], align 8, !dbg [[DBG92]] -// CHECK5-NEXT: [[TMP12:%.*]] = bitcast [1 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]] to i8*, !dbg [[DBG92]] -// CHECK5-NEXT: [[TMP13:%.*]] = load i32, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4, !dbg [[DBG92]] -// CHECK5-NEXT: call void @__kmpc_copyprivate(%struct.ident_t* @[[GLOB16]], i32 [[TMP3]], i64 8, i8* [[TMP12]], void (i8*, i8*)* @.omp.copyprivate.copy_func.5, i32 [[TMP13]]), !dbg [[DBG92]] -// CHECK5-NEXT: ret void, !dbg [[DBG95:![0-9]+]] -// CHECK5: terminate.lpad: -// CHECK5-NEXT: [[TMP14:%.*]] = landingpad { i8*, i32 } -// CHECK5-NEXT: catch i8* null, !dbg [[DBG92]] -// CHECK5-NEXT: [[TMP15:%.*]] = extractvalue { i8*, i32 } [[TMP14]], 0, !dbg [[DBG92]] -// CHECK5-NEXT: call void @__clang_call_terminate(i8* [[TMP15]]) #[[ATTR13]], !dbg [[DBG92]] -// CHECK5-NEXT: unreachable, !dbg [[DBG92]] +// CHECK5-NEXT: [[TMP12:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 0, !dbg [[DBG94]] +// CHECK5-NEXT: [[TMP13:%.*]] = load double*, double** [[_TMP1]], align 8, !dbg [[DBG97:![0-9]+]] +// CHECK5-NEXT: [[TMP14:%.*]] = bitcast double* [[TMP13]] to i8*, !dbg [[DBG94]] +// CHECK5-NEXT: store i8* [[TMP14]], i8** [[TMP12]], align 8, !dbg [[DBG94]] +// CHECK5-NEXT: [[TMP15:%.*]] = bitcast [1 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]] to i8*, !dbg [[DBG94]] +// CHECK5-NEXT: [[TMP16:%.*]] = load i32, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4, !dbg [[DBG94]] +// CHECK5-NEXT: call void @__kmpc_copyprivate(%struct.ident_t* @[[GLOB16]], i32 [[TMP3]], i64 8, i8* [[TMP15]], void (i8*, i8*)* @.omp.copyprivate.copy_func.5, i32 [[TMP16]]), !dbg [[DBG94]] +// CHECK5-NEXT: ret void, !dbg [[DBG98:![0-9]+]] +// CHECK5: terminate.handler: +// CHECK5-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8, !dbg [[DBG94]] +// CHECK5-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR13]], !dbg [[DBG94]] +// CHECK5-NEXT: unreachable, !dbg [[DBG94]] // // // CHECK5-LABEL: define {{[^@]+}}@_ZZN3SSTIdEC1EvENKUlvE_clEv -// CHECK5-SAME: (%class.anon* nonnull align 8 dereferenceable(16) [[THIS:%.*]]) #[[ATTR4]] align 2 !dbg [[DBG96:![0-9]+]] { +// CHECK5-SAME: (%class.anon* nonnull align 8 dereferenceable(16) [[THIS:%.*]]) #[[ATTR4]] align 2 !dbg [[DBG99:![0-9]+]] { // CHECK5-NEXT: entry: // CHECK5-NEXT: [[THIS_ADDR:%.*]] = alloca %class.anon*, align 8 // CHECK5-NEXT: [[REF_TMP:%.*]] = alloca [[CLASS_ANON_0:%.*]], align 8 @@ -4469,40 +4655,40 @@ void array_func(int n, int a[n], St s[2]) { // CHECK5-NEXT: [[THIS1:%.*]] = load %class.anon*, %class.anon** [[THIS_ADDR]], align 8 // CHECK5-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_ANON:%.*]], %class.anon* [[THIS1]], i32 0, i32 0 // CHECK5-NEXT: [[TMP1:%.*]] = load %struct.SST*, %struct.SST** [[TMP0]], align 8 -// CHECK5-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[CLASS_ANON_0]], %class.anon.0* [[REF_TMP]], i32 0, i32 0, !dbg [[DBG97:![0-9]+]] -// CHECK5-NEXT: store %struct.SST* [[TMP1]], %struct.SST** [[TMP2]], align 8, !dbg [[DBG97]] -// CHECK5-NEXT: [[TMP3:%.*]] = getelementptr inbounds [[CLASS_ANON_0]], %class.anon.0* [[REF_TMP]], i32 0, i32 1, !dbg [[DBG97]] -// CHECK5-NEXT: [[TMP4:%.*]] = getelementptr inbounds [[CLASS_ANON]], %class.anon* [[THIS1]], i32 0, i32 1, !dbg [[DBG98:![0-9]+]] -// CHECK5-NEXT: [[TMP5:%.*]] = load double*, double** [[TMP4]], align 8, !dbg [[DBG98]] -// CHECK5-NEXT: store double* [[TMP5]], double** [[TMP3]], align 8, !dbg [[DBG97]] -// CHECK5-NEXT: call void @_ZZZN3SSTIdEC1EvENKUlvE_clEvENKUlvE_clEv(%class.anon.0* nonnull align 8 dereferenceable(16) [[REF_TMP]]), !dbg [[DBG97]] -// CHECK5-NEXT: ret void, !dbg [[DBG99:![0-9]+]] +// CHECK5-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[CLASS_ANON_0]], %class.anon.0* [[REF_TMP]], i32 0, i32 0, !dbg [[DBG100:![0-9]+]] +// CHECK5-NEXT: store %struct.SST* [[TMP1]], %struct.SST** [[TMP2]], align 8, !dbg [[DBG100]] +// CHECK5-NEXT: [[TMP3:%.*]] = getelementptr inbounds [[CLASS_ANON_0]], %class.anon.0* [[REF_TMP]], i32 0, i32 1, !dbg [[DBG100]] +// CHECK5-NEXT: [[TMP4:%.*]] = getelementptr inbounds [[CLASS_ANON]], %class.anon* [[THIS1]], i32 0, i32 1, !dbg [[DBG101:![0-9]+]] +// CHECK5-NEXT: [[TMP5:%.*]] = load double*, double** [[TMP4]], align 8, !dbg [[DBG101]] +// CHECK5-NEXT: store double* [[TMP5]], double** [[TMP3]], align 8, !dbg [[DBG100]] +// CHECK5-NEXT: call void @_ZZZN3SSTIdEC1EvENKUlvE_clEvENKUlvE_clEv(%class.anon.0* nonnull align 8 dereferenceable(16) [[REF_TMP]]), !dbg [[DBG100]] +// CHECK5-NEXT: ret void, !dbg [[DBG102:![0-9]+]] // // // CHECK5-LABEL: define {{[^@]+}}@.omp.copyprivate.copy_func.5 -// CHECK5-SAME: (i8* [[TMP0:%.*]], i8* [[TMP1:%.*]]) #[[ATTR9]] !dbg [[DBG100:![0-9]+]] { +// CHECK5-SAME: (i8* [[TMP0:%.*]], i8* [[TMP1:%.*]]) #[[ATTR9]] !dbg [[DBG103:![0-9]+]] { // CHECK5-NEXT: entry: // CHECK5-NEXT: [[DOTADDR:%.*]] = alloca i8*, align 8 // CHECK5-NEXT: [[DOTADDR1:%.*]] = alloca i8*, align 8 // CHECK5-NEXT: store i8* [[TMP0]], i8** [[DOTADDR]], align 8 // CHECK5-NEXT: store i8* [[TMP1]], i8** [[DOTADDR1]], align 8 -// CHECK5-NEXT: [[TMP2:%.*]] = load i8*, i8** [[DOTADDR]], align 8, !dbg [[DBG101:![0-9]+]] -// CHECK5-NEXT: [[TMP3:%.*]] = bitcast i8* [[TMP2]] to [1 x i8*]*, !dbg [[DBG101]] -// CHECK5-NEXT: [[TMP4:%.*]] = load i8*, i8** [[DOTADDR1]], align 8, !dbg [[DBG101]] -// CHECK5-NEXT: [[TMP5:%.*]] = bitcast i8* [[TMP4]] to [1 x i8*]*, !dbg [[DBG101]] -// CHECK5-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP3]], i64 0, i64 0, !dbg [[DBG101]] -// CHECK5-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8, !dbg [[DBG101]] -// CHECK5-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to double*, !dbg [[DBG101]] -// CHECK5-NEXT: [[TMP9:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP5]], i64 0, i64 0, !dbg [[DBG101]] -// CHECK5-NEXT: [[TMP10:%.*]] = load i8*, i8** [[TMP9]], align 8, !dbg [[DBG101]] -// CHECK5-NEXT: [[TMP11:%.*]] = bitcast i8* [[TMP10]] to double*, !dbg [[DBG101]] -// CHECK5-NEXT: [[TMP12:%.*]] = load double, double* [[TMP11]], align 8, !dbg [[DBG102:![0-9]+]] -// CHECK5-NEXT: store double [[TMP12]], double* [[TMP8]], align 8, !dbg [[DBG102]] -// CHECK5-NEXT: ret void, !dbg [[DBG102]] +// CHECK5-NEXT: [[TMP2:%.*]] = load i8*, i8** [[DOTADDR]], align 8, !dbg [[DBG104:![0-9]+]] +// CHECK5-NEXT: [[TMP3:%.*]] = bitcast i8* [[TMP2]] to [1 x i8*]*, !dbg [[DBG104]] +// CHECK5-NEXT: [[TMP4:%.*]] = load i8*, i8** [[DOTADDR1]], align 8, !dbg [[DBG104]] +// CHECK5-NEXT: [[TMP5:%.*]] = bitcast i8* [[TMP4]] to [1 x i8*]*, !dbg [[DBG104]] +// CHECK5-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP3]], i64 0, i64 0, !dbg [[DBG104]] +// CHECK5-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8, !dbg [[DBG104]] +// CHECK5-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to double*, !dbg [[DBG104]] +// CHECK5-NEXT: [[TMP9:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP5]], i64 0, i64 0, !dbg [[DBG104]] +// CHECK5-NEXT: [[TMP10:%.*]] = load i8*, i8** [[TMP9]], align 8, !dbg [[DBG104]] +// CHECK5-NEXT: [[TMP11:%.*]] = bitcast i8* [[TMP10]] to double*, !dbg [[DBG104]] +// CHECK5-NEXT: [[TMP12:%.*]] = load double, double* [[TMP11]], align 8, !dbg [[DBG105:![0-9]+]] +// CHECK5-NEXT: store double [[TMP12]], double* [[TMP8]], align 8, !dbg [[DBG105]] +// CHECK5-NEXT: ret void, !dbg [[DBG105]] // // // CHECK5-LABEL: define {{[^@]+}}@_ZZZN3SSTIdEC1EvENKUlvE_clEvENKUlvE_clEv -// CHECK5-SAME: (%class.anon.0* nonnull align 8 dereferenceable(16) [[THIS:%.*]]) #[[ATTR10]] align 2 !dbg [[DBG105:![0-9]+]] { +// CHECK5-SAME: (%class.anon.0* nonnull align 8 dereferenceable(16) [[THIS:%.*]]) #[[ATTR10]] align 2 !dbg [[DBG108:![0-9]+]] { // CHECK5-NEXT: entry: // CHECK5-NEXT: [[THIS_ADDR:%.*]] = alloca %class.anon.0*, align 8 // CHECK5-NEXT: [[A_CASTED:%.*]] = alloca i64, align 8 @@ -4510,23 +4696,23 @@ void array_func(int n, int a[n], St s[2]) { // CHECK5-NEXT: [[THIS1:%.*]] = load %class.anon.0*, %class.anon.0** [[THIS_ADDR]], align 8 // CHECK5-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_ANON_0:%.*]], %class.anon.0* [[THIS1]], i32 0, i32 0 // CHECK5-NEXT: [[TMP1:%.*]] = load %struct.SST*, %struct.SST** [[TMP0]], align 8 -// CHECK5-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[CLASS_ANON_0]], %class.anon.0* [[THIS1]], i32 0, i32 1, !dbg [[DBG106:![0-9]+]] -// CHECK5-NEXT: [[TMP3:%.*]] = load double*, double** [[TMP2]], align 8, !dbg [[DBG106]] -// CHECK5-NEXT: [[TMP4:%.*]] = load double, double* [[TMP3]], align 8, !dbg [[DBG107:![0-9]+]] -// CHECK5-NEXT: [[INC:%.*]] = fadd double [[TMP4]], 1.000000e+00, !dbg [[DBG107]] -// CHECK5-NEXT: store double [[INC]], double* [[TMP3]], align 8, !dbg [[DBG107]] -// CHECK5-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[CLASS_ANON_0]], %class.anon.0* [[THIS1]], i32 0, i32 1, !dbg [[DBG108:![0-9]+]] -// CHECK5-NEXT: [[TMP6:%.*]] = load double*, double** [[TMP5]], align 8, !dbg [[DBG108]] -// CHECK5-NEXT: [[TMP7:%.*]] = load double, double* [[TMP6]], align 8, !dbg [[DBG109:![0-9]+]] -// CHECK5-NEXT: [[CONV:%.*]] = bitcast i64* [[A_CASTED]] to double*, !dbg [[DBG109]] -// CHECK5-NEXT: store double [[TMP7]], double* [[CONV]], align 8, !dbg [[DBG109]] -// CHECK5-NEXT: [[TMP8:%.*]] = load i64, i64* [[A_CASTED]], align 8, !dbg [[DBG109]] -// CHECK5-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB22:[0-9]+]], i32 2, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %struct.SST*, i64)* @.omp_outlined..6 to void (i32*, i32*, ...)*), %struct.SST* [[TMP1]], i64 [[TMP8]]), !dbg [[DBG109]] -// CHECK5-NEXT: ret void, !dbg [[DBG110:![0-9]+]] +// CHECK5-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[CLASS_ANON_0]], %class.anon.0* [[THIS1]], i32 0, i32 1, !dbg [[DBG109:![0-9]+]] +// CHECK5-NEXT: [[TMP3:%.*]] = load double*, double** [[TMP2]], align 8, !dbg [[DBG109]] +// CHECK5-NEXT: [[TMP4:%.*]] = load double, double* [[TMP3]], align 8, !dbg [[DBG110:![0-9]+]] +// CHECK5-NEXT: [[INC:%.*]] = fadd double [[TMP4]], 1.000000e+00, !dbg [[DBG110]] +// CHECK5-NEXT: store double [[INC]], double* [[TMP3]], align 8, !dbg [[DBG110]] +// CHECK5-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[CLASS_ANON_0]], %class.anon.0* [[THIS1]], i32 0, i32 1, !dbg [[DBG111:![0-9]+]] +// CHECK5-NEXT: [[TMP6:%.*]] = load double*, double** [[TMP5]], align 8, !dbg [[DBG111]] +// CHECK5-NEXT: [[TMP7:%.*]] = load double, double* [[TMP6]], align 8, !dbg [[DBG112:![0-9]+]] +// CHECK5-NEXT: [[CONV:%.*]] = bitcast i64* [[A_CASTED]] to double*, !dbg [[DBG112]] +// CHECK5-NEXT: store double [[TMP7]], double* [[CONV]], align 8, !dbg [[DBG112]] +// CHECK5-NEXT: [[TMP8:%.*]] = load i64, i64* [[A_CASTED]], align 8, !dbg [[DBG112]] +// CHECK5-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB22:[0-9]+]], i32 2, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %struct.SST*, i64)* @.omp_outlined..6 to void (i32*, i32*, ...)*), %struct.SST* [[TMP1]], i64 [[TMP8]]), !dbg [[DBG112]] +// CHECK5-NEXT: ret void, !dbg [[DBG113:![0-9]+]] // // // CHECK5-LABEL: define {{[^@]+}}@.omp_outlined..6 -// CHECK5-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], %struct.SST* [[THIS:%.*]], i64 [[A:%.*]]) #[[ATTR12]] !dbg [[DBG111:![0-9]+]] { +// CHECK5-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], %struct.SST* [[THIS:%.*]], i64 [[A:%.*]]) #[[ATTR12]] !dbg [[DBG114:![0-9]+]] { // CHECK5-NEXT: entry: // CHECK5-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK5-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 @@ -4540,60 +4726,60 @@ void array_func(int n, int a[n], St s[2]) { // CHECK5-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 // CHECK5-NEXT: store %struct.SST* [[THIS]], %struct.SST** [[THIS_ADDR]], align 8 // CHECK5-NEXT: store i64 [[A]], i64* [[A_ADDR]], align 8 -// CHECK5-NEXT: [[TMP0:%.*]] = load %struct.SST*, %struct.SST** [[THIS_ADDR]], align 8, !dbg [[DBG112:![0-9]+]] -// CHECK5-NEXT: [[CONV:%.*]] = bitcast i64* [[A_ADDR]] to double*, !dbg [[DBG112]] -// CHECK5-NEXT: store double* [[CONV]], double** [[TMP]], align 8, !dbg [[DBG112]] -// CHECK5-NEXT: [[TMP1:%.*]] = load double*, double** [[TMP]], align 8, !dbg [[DBG113:![0-9]+]] -// CHECK5-NEXT: store double* [[TMP1]], double** [[_TMP1]], align 8, !dbg [[DBG114:![0-9]+]] -// CHECK5-NEXT: store i32 0, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4, !dbg [[DBG114]] -// CHECK5-NEXT: [[TMP2:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG114]] -// CHECK5-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4, !dbg [[DBG114]] -// CHECK5-NEXT: [[TMP4:%.*]] = call i32 @__kmpc_single(%struct.ident_t* @[[GLOB20:[0-9]+]], i32 [[TMP3]]), !dbg [[DBG114]] -// CHECK5-NEXT: [[TMP5:%.*]] = icmp ne i32 [[TMP4]], 0, !dbg [[DBG114]] -// CHECK5-NEXT: br i1 [[TMP5]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_END:%.*]], !dbg [[DBG114]] +// CHECK5-NEXT: [[TMP0:%.*]] = load %struct.SST*, %struct.SST** [[THIS_ADDR]], align 8, !dbg [[DBG115:![0-9]+]] +// CHECK5-NEXT: [[CONV:%.*]] = bitcast i64* [[A_ADDR]] to double*, !dbg [[DBG115]] +// CHECK5-NEXT: store double* [[CONV]], double** [[TMP]], align 8, !dbg [[DBG115]] +// CHECK5-NEXT: [[TMP1:%.*]] = load double*, double** [[TMP]], align 8, !dbg [[DBG116:![0-9]+]] +// CHECK5-NEXT: store double* [[TMP1]], double** [[_TMP1]], align 8, !dbg [[DBG117:![0-9]+]] +// CHECK5-NEXT: store i32 0, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4, !dbg [[DBG117]] +// CHECK5-NEXT: [[TMP2:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG117]] +// CHECK5-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4, !dbg [[DBG117]] +// CHECK5-NEXT: [[TMP4:%.*]] = call i32 @__kmpc_single(%struct.ident_t* @[[GLOB20:[0-9]+]], i32 [[TMP3]]), !dbg [[DBG117]] +// CHECK5-NEXT: [[TMP5:%.*]] = icmp ne i32 [[TMP4]], 0, !dbg [[DBG117]] +// CHECK5-NEXT: br i1 [[TMP5]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_END:%.*]], !dbg [[DBG117]] // CHECK5: omp_if.then: -// CHECK5-NEXT: [[TMP6:%.*]] = load double*, double** [[_TMP1]], align 8, !dbg [[DBG113]] -// CHECK5-NEXT: [[TMP7:%.*]] = load double, double* [[TMP6]], align 8, !dbg [[DBG115:![0-9]+]] -// CHECK5-NEXT: [[INC:%.*]] = fadd double [[TMP7]], 1.000000e+00, !dbg [[DBG115]] -// CHECK5-NEXT: store double [[INC]], double* [[TMP6]], align 8, !dbg [[DBG115]] -// CHECK5-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB20]], i32 [[TMP3]]), !dbg [[DBG115]] -// CHECK5-NEXT: store i32 1, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4, !dbg [[DBG115]] -// CHECK5-NEXT: br label [[OMP_IF_END]], !dbg [[DBG115]] +// CHECK5-NEXT: [[TMP6:%.*]] = load double*, double** [[_TMP1]], align 8, !dbg [[DBG116]] +// CHECK5-NEXT: [[TMP7:%.*]] = load double, double* [[TMP6]], align 8, !dbg [[DBG118:![0-9]+]] +// CHECK5-NEXT: [[INC:%.*]] = fadd double [[TMP7]], 1.000000e+00, !dbg [[DBG118]] +// CHECK5-NEXT: store double [[INC]], double* [[TMP6]], align 8, !dbg [[DBG118]] +// CHECK5-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB20]], i32 [[TMP3]]), !dbg [[DBG118]] +// CHECK5-NEXT: store i32 1, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4, !dbg [[DBG118]] +// CHECK5-NEXT: br label [[OMP_IF_END]], !dbg [[DBG118]] // CHECK5: omp_if.end: -// CHECK5-NEXT: [[TMP8:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 0, !dbg [[DBG115]] -// CHECK5-NEXT: [[TMP9:%.*]] = load double*, double** [[_TMP1]], align 8, !dbg [[DBG116:![0-9]+]] -// CHECK5-NEXT: [[TMP10:%.*]] = bitcast double* [[TMP9]] to i8*, !dbg [[DBG115]] -// CHECK5-NEXT: store i8* [[TMP10]], i8** [[TMP8]], align 8, !dbg [[DBG115]] -// CHECK5-NEXT: [[TMP11:%.*]] = bitcast [1 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]] to i8*, !dbg [[DBG115]] -// CHECK5-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4, !dbg [[DBG115]] -// CHECK5-NEXT: call void @__kmpc_copyprivate(%struct.ident_t* @[[GLOB20]], i32 [[TMP3]], i64 8, i8* [[TMP11]], void (i8*, i8*)* @.omp.copyprivate.copy_func.7, i32 [[TMP12]]), !dbg [[DBG115]] -// CHECK5-NEXT: ret void, !dbg [[DBG117:![0-9]+]] +// CHECK5-NEXT: [[TMP8:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 0, !dbg [[DBG118]] +// CHECK5-NEXT: [[TMP9:%.*]] = load double*, double** [[_TMP1]], align 8, !dbg [[DBG119:![0-9]+]] +// CHECK5-NEXT: [[TMP10:%.*]] = bitcast double* [[TMP9]] to i8*, !dbg [[DBG118]] +// CHECK5-NEXT: store i8* [[TMP10]], i8** [[TMP8]], align 8, !dbg [[DBG118]] +// CHECK5-NEXT: [[TMP11:%.*]] = bitcast [1 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]] to i8*, !dbg [[DBG118]] +// CHECK5-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4, !dbg [[DBG118]] +// CHECK5-NEXT: call void @__kmpc_copyprivate(%struct.ident_t* @[[GLOB20]], i32 [[TMP3]], i64 8, i8* [[TMP11]], void (i8*, i8*)* @.omp.copyprivate.copy_func.7, i32 [[TMP12]]), !dbg [[DBG118]] +// CHECK5-NEXT: ret void, !dbg [[DBG120:![0-9]+]] // // // CHECK5-LABEL: define {{[^@]+}}@.omp.copyprivate.copy_func.7 -// CHECK5-SAME: (i8* [[TMP0:%.*]], i8* [[TMP1:%.*]]) #[[ATTR9]] !dbg [[DBG118:![0-9]+]] { +// CHECK5-SAME: (i8* [[TMP0:%.*]], i8* [[TMP1:%.*]]) #[[ATTR9]] !dbg [[DBG121:![0-9]+]] { // CHECK5-NEXT: entry: // CHECK5-NEXT: [[DOTADDR:%.*]] = alloca i8*, align 8 // CHECK5-NEXT: [[DOTADDR1:%.*]] = alloca i8*, align 8 // CHECK5-NEXT: store i8* [[TMP0]], i8** [[DOTADDR]], align 8 // CHECK5-NEXT: store i8* [[TMP1]], i8** [[DOTADDR1]], align 8 -// CHECK5-NEXT: [[TMP2:%.*]] = load i8*, i8** [[DOTADDR]], align 8, !dbg [[DBG119:![0-9]+]] -// CHECK5-NEXT: [[TMP3:%.*]] = bitcast i8* [[TMP2]] to [1 x i8*]*, !dbg [[DBG119]] -// CHECK5-NEXT: [[TMP4:%.*]] = load i8*, i8** [[DOTADDR1]], align 8, !dbg [[DBG119]] -// CHECK5-NEXT: [[TMP5:%.*]] = bitcast i8* [[TMP4]] to [1 x i8*]*, !dbg [[DBG119]] -// CHECK5-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP3]], i64 0, i64 0, !dbg [[DBG119]] -// CHECK5-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8, !dbg [[DBG119]] -// CHECK5-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to double*, !dbg [[DBG119]] -// CHECK5-NEXT: [[TMP9:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP5]], i64 0, i64 0, !dbg [[DBG119]] -// CHECK5-NEXT: [[TMP10:%.*]] = load i8*, i8** [[TMP9]], align 8, !dbg [[DBG119]] -// CHECK5-NEXT: [[TMP11:%.*]] = bitcast i8* [[TMP10]] to double*, !dbg [[DBG119]] -// CHECK5-NEXT: [[TMP12:%.*]] = load double, double* [[TMP11]], align 8, !dbg [[DBG120:![0-9]+]] -// CHECK5-NEXT: store double [[TMP12]], double* [[TMP8]], align 8, !dbg [[DBG120]] -// CHECK5-NEXT: ret void, !dbg [[DBG120]] +// CHECK5-NEXT: [[TMP2:%.*]] = load i8*, i8** [[DOTADDR]], align 8, !dbg [[DBG122:![0-9]+]] +// CHECK5-NEXT: [[TMP3:%.*]] = bitcast i8* [[TMP2]] to [1 x i8*]*, !dbg [[DBG122]] +// CHECK5-NEXT: [[TMP4:%.*]] = load i8*, i8** [[DOTADDR1]], align 8, !dbg [[DBG122]] +// CHECK5-NEXT: [[TMP5:%.*]] = bitcast i8* [[TMP4]] to [1 x i8*]*, !dbg [[DBG122]] +// CHECK5-NEXT: [[TMP6:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP3]], i64 0, i64 0, !dbg [[DBG122]] +// CHECK5-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8, !dbg [[DBG122]] +// CHECK5-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to double*, !dbg [[DBG122]] +// CHECK5-NEXT: [[TMP9:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP5]], i64 0, i64 0, !dbg [[DBG122]] +// CHECK5-NEXT: [[TMP10:%.*]] = load i8*, i8** [[TMP9]], align 8, !dbg [[DBG122]] +// CHECK5-NEXT: [[TMP11:%.*]] = bitcast i8* [[TMP10]] to double*, !dbg [[DBG122]] +// CHECK5-NEXT: [[TMP12:%.*]] = load double, double* [[TMP11]], align 8, !dbg [[DBG123:![0-9]+]] +// CHECK5-NEXT: store double [[TMP12]], double* [[TMP8]], align 8, !dbg [[DBG123]] +// CHECK5-NEXT: ret void, !dbg [[DBG123]] // // // CHECK5-LABEL: define {{[^@]+}}@_ZN2SSC2ERi -// CHECK5-SAME: (%struct.SS* nonnull align 8 dereferenceable(16) [[THIS:%.*]], i32* nonnull align 4 dereferenceable(4) [[D:%.*]]) unnamed_addr #[[ATTR2]] align 2 !dbg [[DBG121:![0-9]+]] { +// CHECK5-SAME: (%struct.SS* nonnull align 8 dereferenceable(16) [[THIS:%.*]], i32* nonnull align 4 dereferenceable(4) [[D:%.*]]) unnamed_addr #[[ATTR2]] align 2 !dbg [[DBG124:![0-9]+]] { // CHECK5-NEXT: entry: // CHECK5-NEXT: [[THIS_ADDR:%.*]] = alloca %struct.SS*, align 8 // CHECK5-NEXT: [[D_ADDR:%.*]] = alloca i32*, align 8 @@ -4606,47 +4792,47 @@ void array_func(int n, int a[n], St s[2]) { // CHECK5-NEXT: store %struct.SS* [[THIS]], %struct.SS** [[THIS_ADDR]], align 8 // CHECK5-NEXT: store i32* [[D]], i32** [[D_ADDR]], align 8 // CHECK5-NEXT: [[THIS1:%.*]] = load %struct.SS*, %struct.SS** [[THIS_ADDR]], align 8 -// CHECK5-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_SS:%.*]], %struct.SS* [[THIS1]], i32 0, i32 0, !dbg [[DBG122:![0-9]+]] -// CHECK5-NEXT: store i32 0, i32* [[A]], align 8, !dbg [[DBG122]] -// CHECK5-NEXT: [[B:%.*]] = getelementptr inbounds [[STRUCT_SS]], %struct.SS* [[THIS1]], i32 0, i32 1, !dbg [[DBG123:![0-9]+]] -// CHECK5-NEXT: [[BF_LOAD:%.*]] = load i8, i8* [[B]], align 4, !dbg [[DBG123]] -// CHECK5-NEXT: [[BF_CLEAR:%.*]] = and i8 [[BF_LOAD]], -16, !dbg [[DBG123]] -// CHECK5-NEXT: [[BF_SET:%.*]] = or i8 [[BF_CLEAR]], 0, !dbg [[DBG123]] -// CHECK5-NEXT: store i8 [[BF_SET]], i8* [[B]], align 4, !dbg [[DBG123]] -// CHECK5-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_SS]], %struct.SS* [[THIS1]], i32 0, i32 2, !dbg [[DBG124:![0-9]+]] -// CHECK5-NEXT: [[TMP0:%.*]] = load i32*, i32** [[D_ADDR]], align 8, !dbg [[DBG125:![0-9]+]] -// CHECK5-NEXT: store i32* [[TMP0]], i32** [[C]], align 8, !dbg [[DBG124]] -// CHECK5-NEXT: [[A3:%.*]] = getelementptr inbounds [[STRUCT_SS]], %struct.SS* [[THIS1]], i32 0, i32 0, !dbg [[DBG126:![0-9]+]] -// CHECK5-NEXT: store i32* [[A3]], i32** [[A2]], align 8, !dbg [[DBG126]] -// CHECK5-NEXT: [[B5:%.*]] = getelementptr inbounds [[STRUCT_SS]], %struct.SS* [[THIS1]], i32 0, i32 1, !dbg [[DBG127:![0-9]+]] -// CHECK5-NEXT: [[BF_LOAD6:%.*]] = load i8, i8* [[B5]], align 4, !dbg [[DBG127]] -// CHECK5-NEXT: [[BF_SHL:%.*]] = shl i8 [[BF_LOAD6]], 4, !dbg [[DBG127]] -// CHECK5-NEXT: [[BF_ASHR:%.*]] = ashr i8 [[BF_SHL]], 4, !dbg [[DBG127]] -// CHECK5-NEXT: [[BF_CAST:%.*]] = sext i8 [[BF_ASHR]] to i32, !dbg [[DBG127]] -// CHECK5-NEXT: store i32 [[BF_CAST]], i32* [[B4]], align 4, !dbg [[DBG127]] -// CHECK5-NEXT: [[C8:%.*]] = getelementptr inbounds [[STRUCT_SS]], %struct.SS* [[THIS1]], i32 0, i32 2, !dbg [[DBG128:![0-9]+]] -// CHECK5-NEXT: [[TMP1:%.*]] = load i32*, i32** [[C8]], align 8, !dbg [[DBG128]] -// CHECK5-NEXT: store i32* [[TMP1]], i32** [[C7]], align 8, !dbg [[DBG128]] -// CHECK5-NEXT: [[TMP2:%.*]] = load i32*, i32** [[A2]], align 8, !dbg [[DBG129:![0-9]+]] -// CHECK5-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4, !dbg [[DBG130:![0-9]+]] -// CHECK5-NEXT: [[CONV:%.*]] = bitcast i64* [[A_CASTED]] to i32*, !dbg [[DBG130]] -// CHECK5-NEXT: store i32 [[TMP3]], i32* [[CONV]], align 4, !dbg [[DBG130]] -// CHECK5-NEXT: [[TMP4:%.*]] = load i64, i64* [[A_CASTED]], align 8, !dbg [[DBG130]] -// CHECK5-NEXT: [[TMP5:%.*]] = load i32, i32* [[B4]], align 4, !dbg [[DBG130]] -// CHECK5-NEXT: [[CONV9:%.*]] = bitcast i64* [[B_CASTED]] to i32*, !dbg [[DBG130]] -// CHECK5-NEXT: store i32 [[TMP5]], i32* [[CONV9]], align 4, !dbg [[DBG130]] -// CHECK5-NEXT: [[TMP6:%.*]] = load i64, i64* [[B_CASTED]], align 8, !dbg [[DBG130]] -// CHECK5-NEXT: [[TMP7:%.*]] = load i32*, i32** [[C7]], align 8, !dbg [[DBG131:![0-9]+]] -// CHECK5-NEXT: [[TMP8:%.*]] = load i32, i32* [[TMP7]], align 4, !dbg [[DBG130]] -// CHECK5-NEXT: [[CONV10:%.*]] = bitcast i64* [[C_CASTED]] to i32*, !dbg [[DBG130]] -// CHECK5-NEXT: store i32 [[TMP8]], i32* [[CONV10]], align 4, !dbg [[DBG130]] -// CHECK5-NEXT: [[TMP9:%.*]] = load i64, i64* [[C_CASTED]], align 8, !dbg [[DBG130]] -// CHECK5-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB26:[0-9]+]], i32 4, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %struct.SS*, i64, i64, i64)* @.omp_outlined..8 to void (i32*, i32*, ...)*), %struct.SS* [[THIS1]], i64 [[TMP4]], i64 [[TMP6]], i64 [[TMP9]]), !dbg [[DBG130]] -// CHECK5-NEXT: ret void, !dbg [[DBG132:![0-9]+]] +// CHECK5-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_SS:%.*]], %struct.SS* [[THIS1]], i32 0, i32 0, !dbg [[DBG125:![0-9]+]] +// CHECK5-NEXT: store i32 0, i32* [[A]], align 8, !dbg [[DBG125]] +// CHECK5-NEXT: [[B:%.*]] = getelementptr inbounds [[STRUCT_SS]], %struct.SS* [[THIS1]], i32 0, i32 1, !dbg [[DBG126:![0-9]+]] +// CHECK5-NEXT: [[BF_LOAD:%.*]] = load i8, i8* [[B]], align 4, !dbg [[DBG126]] +// CHECK5-NEXT: [[BF_CLEAR:%.*]] = and i8 [[BF_LOAD]], -16, !dbg [[DBG126]] +// CHECK5-NEXT: [[BF_SET:%.*]] = or i8 [[BF_CLEAR]], 0, !dbg [[DBG126]] +// CHECK5-NEXT: store i8 [[BF_SET]], i8* [[B]], align 4, !dbg [[DBG126]] +// CHECK5-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_SS]], %struct.SS* [[THIS1]], i32 0, i32 2, !dbg [[DBG127:![0-9]+]] +// CHECK5-NEXT: [[TMP0:%.*]] = load i32*, i32** [[D_ADDR]], align 8, !dbg [[DBG128:![0-9]+]] +// CHECK5-NEXT: store i32* [[TMP0]], i32** [[C]], align 8, !dbg [[DBG127]] +// CHECK5-NEXT: [[A3:%.*]] = getelementptr inbounds [[STRUCT_SS]], %struct.SS* [[THIS1]], i32 0, i32 0, !dbg [[DBG129:![0-9]+]] +// CHECK5-NEXT: store i32* [[A3]], i32** [[A2]], align 8, !dbg [[DBG129]] +// CHECK5-NEXT: [[B5:%.*]] = getelementptr inbounds [[STRUCT_SS]], %struct.SS* [[THIS1]], i32 0, i32 1, !dbg [[DBG130:![0-9]+]] +// CHECK5-NEXT: [[BF_LOAD6:%.*]] = load i8, i8* [[B5]], align 4, !dbg [[DBG130]] +// CHECK5-NEXT: [[BF_SHL:%.*]] = shl i8 [[BF_LOAD6]], 4, !dbg [[DBG130]] +// CHECK5-NEXT: [[BF_ASHR:%.*]] = ashr i8 [[BF_SHL]], 4, !dbg [[DBG130]] +// CHECK5-NEXT: [[BF_CAST:%.*]] = sext i8 [[BF_ASHR]] to i32, !dbg [[DBG130]] +// CHECK5-NEXT: store i32 [[BF_CAST]], i32* [[B4]], align 4, !dbg [[DBG130]] +// CHECK5-NEXT: [[C8:%.*]] = getelementptr inbounds [[STRUCT_SS]], %struct.SS* [[THIS1]], i32 0, i32 2, !dbg [[DBG131:![0-9]+]] +// CHECK5-NEXT: [[TMP1:%.*]] = load i32*, i32** [[C8]], align 8, !dbg [[DBG131]] +// CHECK5-NEXT: store i32* [[TMP1]], i32** [[C7]], align 8, !dbg [[DBG131]] +// CHECK5-NEXT: [[TMP2:%.*]] = load i32*, i32** [[A2]], align 8, !dbg [[DBG132:![0-9]+]] +// CHECK5-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4, !dbg [[DBG133:![0-9]+]] +// CHECK5-NEXT: [[CONV:%.*]] = bitcast i64* [[A_CASTED]] to i32*, !dbg [[DBG133]] +// CHECK5-NEXT: store i32 [[TMP3]], i32* [[CONV]], align 4, !dbg [[DBG133]] +// CHECK5-NEXT: [[TMP4:%.*]] = load i64, i64* [[A_CASTED]], align 8, !dbg [[DBG133]] +// CHECK5-NEXT: [[TMP5:%.*]] = load i32, i32* [[B4]], align 4, !dbg [[DBG133]] +// CHECK5-NEXT: [[CONV9:%.*]] = bitcast i64* [[B_CASTED]] to i32*, !dbg [[DBG133]] +// CHECK5-NEXT: store i32 [[TMP5]], i32* [[CONV9]], align 4, !dbg [[DBG133]] +// CHECK5-NEXT: [[TMP6:%.*]] = load i64, i64* [[B_CASTED]], align 8, !dbg [[DBG133]] +// CHECK5-NEXT: [[TMP7:%.*]] = load i32*, i32** [[C7]], align 8, !dbg [[DBG134:![0-9]+]] +// CHECK5-NEXT: [[TMP8:%.*]] = load i32, i32* [[TMP7]], align 4, !dbg [[DBG133]] +// CHECK5-NEXT: [[CONV10:%.*]] = bitcast i64* [[C_CASTED]] to i32*, !dbg [[DBG133]] +// CHECK5-NEXT: store i32 [[TMP8]], i32* [[CONV10]], align 4, !dbg [[DBG133]] +// CHECK5-NEXT: [[TMP9:%.*]] = load i64, i64* [[C_CASTED]], align 8, !dbg [[DBG133]] +// CHECK5-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB26:[0-9]+]], i32 4, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %struct.SS*, i64, i64, i64)* @.omp_outlined..8 to void (i32*, i32*, ...)*), %struct.SS* [[THIS1]], i64 [[TMP4]], i64 [[TMP6]], i64 [[TMP9]]), !dbg [[DBG133]] +// CHECK5-NEXT: ret void, !dbg [[DBG135:![0-9]+]] // // // CHECK5-LABEL: define {{[^@]+}}@.omp_outlined..8 -// CHECK5-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], %struct.SS* [[THIS:%.*]], i64 [[A:%.*]], i64 [[B:%.*]], i64 [[C:%.*]]) #[[ATTR12]] personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) !dbg [[DBG133:![0-9]+]] { +// CHECK5-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], %struct.SS* [[THIS:%.*]], i64 [[A:%.*]], i64 [[B:%.*]], i64 [[C:%.*]]) #[[ATTR12]] personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) !dbg [[DBG136:![0-9]+]] { // CHECK5-NEXT: entry: // CHECK5-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK5-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 @@ -4660,6 +4846,8 @@ void array_func(int n, int a[n], St s[2]) { // CHECK5-NEXT: [[_TMP5:%.*]] = alloca i32*, align 8 // CHECK5-NEXT: [[DOTOMP_COPYPRIVATE_DID_IT:%.*]] = alloca i32, align 4 // CHECK5-NEXT: [[REF_TMP:%.*]] = alloca [[CLASS_ANON_1:%.*]], align 8 +// CHECK5-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// CHECK5-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // CHECK5-NEXT: [[DOTOMP_COPYPRIVATE_CPR_LIST:%.*]] = alloca [3 x i8*], align 8 // CHECK5-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK5-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 @@ -4667,65 +4855,72 @@ void array_func(int n, int a[n], St s[2]) { // CHECK5-NEXT: store i64 [[A]], i64* [[A_ADDR]], align 8 // CHECK5-NEXT: store i64 [[B]], i64* [[B_ADDR]], align 8 // CHECK5-NEXT: store i64 [[C]], i64* [[C_ADDR]], align 8 -// CHECK5-NEXT: [[TMP0:%.*]] = load %struct.SS*, %struct.SS** [[THIS_ADDR]], align 8, !dbg [[DBG134:![0-9]+]] -// CHECK5-NEXT: [[CONV:%.*]] = bitcast i64* [[A_ADDR]] to i32*, !dbg [[DBG134]] -// CHECK5-NEXT: [[CONV1:%.*]] = bitcast i64* [[B_ADDR]] to i32*, !dbg [[DBG134]] -// CHECK5-NEXT: [[CONV2:%.*]] = bitcast i64* [[C_ADDR]] to i32*, !dbg [[DBG134]] -// CHECK5-NEXT: store i32* [[CONV]], i32** [[TMP]], align 8, !dbg [[DBG134]] -// CHECK5-NEXT: store i32* [[CONV2]], i32** [[_TMP3]], align 8, !dbg [[DBG134]] -// CHECK5-NEXT: [[TMP1:%.*]] = load i32*, i32** [[TMP]], align 8, !dbg [[DBG135:![0-9]+]] -// CHECK5-NEXT: store i32* [[TMP1]], i32** [[_TMP4]], align 8, !dbg [[DBG136:![0-9]+]] -// CHECK5-NEXT: [[TMP2:%.*]] = load i32*, i32** [[_TMP3]], align 8, !dbg [[DBG137:![0-9]+]] -// CHECK5-NEXT: store i32* [[TMP2]], i32** [[_TMP5]], align 8, !dbg [[DBG136]] -// CHECK5-NEXT: store i32 0, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4, !dbg [[DBG136]] -// CHECK5-NEXT: [[TMP3:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG136]] -// CHECK5-NEXT: [[TMP4:%.*]] = load i32, i32* [[TMP3]], align 4, !dbg [[DBG136]] -// CHECK5-NEXT: [[TMP5:%.*]] = call i32 @__kmpc_single(%struct.ident_t* @[[GLOB24:[0-9]+]], i32 [[TMP4]]), !dbg [[DBG136]] -// CHECK5-NEXT: [[TMP6:%.*]] = icmp ne i32 [[TMP5]], 0, !dbg [[DBG136]] -// CHECK5-NEXT: br i1 [[TMP6]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_END:%.*]], !dbg [[DBG136]] +// CHECK5-NEXT: [[TMP0:%.*]] = load %struct.SS*, %struct.SS** [[THIS_ADDR]], align 8, !dbg [[DBG137:![0-9]+]] +// CHECK5-NEXT: [[CONV:%.*]] = bitcast i64* [[A_ADDR]] to i32*, !dbg [[DBG137]] +// CHECK5-NEXT: [[CONV1:%.*]] = bitcast i64* [[B_ADDR]] to i32*, !dbg [[DBG137]] +// CHECK5-NEXT: [[CONV2:%.*]] = bitcast i64* [[C_ADDR]] to i32*, !dbg [[DBG137]] +// CHECK5-NEXT: store i32* [[CONV]], i32** [[TMP]], align 8, !dbg [[DBG137]] +// CHECK5-NEXT: store i32* [[CONV2]], i32** [[_TMP3]], align 8, !dbg [[DBG137]] +// CHECK5-NEXT: [[TMP1:%.*]] = load i32*, i32** [[TMP]], align 8, !dbg [[DBG138:![0-9]+]] +// CHECK5-NEXT: store i32* [[TMP1]], i32** [[_TMP4]], align 8, !dbg [[DBG139:![0-9]+]] +// CHECK5-NEXT: [[TMP2:%.*]] = load i32*, i32** [[_TMP3]], align 8, !dbg [[DBG140:![0-9]+]] +// CHECK5-NEXT: store i32* [[TMP2]], i32** [[_TMP5]], align 8, !dbg [[DBG139]] +// CHECK5-NEXT: store i32 0, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4, !dbg [[DBG139]] +// CHECK5-NEXT: [[TMP3:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG139]] +// CHECK5-NEXT: [[TMP4:%.*]] = load i32, i32* [[TMP3]], align 4, !dbg [[DBG139]] +// CHECK5-NEXT: [[TMP5:%.*]] = call i32 @__kmpc_single(%struct.ident_t* @[[GLOB24:[0-9]+]], i32 [[TMP4]]), !dbg [[DBG139]] +// CHECK5-NEXT: [[TMP6:%.*]] = icmp ne i32 [[TMP5]], 0, !dbg [[DBG139]] +// CHECK5-NEXT: br i1 [[TMP6]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_END:%.*]], !dbg [[DBG139]] // CHECK5: omp_if.then: -// CHECK5-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[CLASS_ANON_1]], %class.anon.1* [[REF_TMP]], i32 0, i32 0, !dbg [[DBG138:![0-9]+]] -// CHECK5-NEXT: store %struct.SS* [[TMP0]], %struct.SS** [[TMP7]], align 8, !dbg [[DBG138]] -// CHECK5-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[CLASS_ANON_1]], %class.anon.1* [[REF_TMP]], i32 0, i32 1, !dbg [[DBG138]] -// CHECK5-NEXT: [[TMP9:%.*]] = load i32*, i32** [[_TMP4]], align 8, !dbg [[DBG139:![0-9]+]] -// CHECK5-NEXT: store i32* [[TMP9]], i32** [[TMP8]], align 8, !dbg [[DBG138]] -// CHECK5-NEXT: [[TMP10:%.*]] = getelementptr inbounds [[CLASS_ANON_1]], %class.anon.1* [[REF_TMP]], i32 0, i32 2, !dbg [[DBG138]] -// CHECK5-NEXT: store i32* [[CONV1]], i32** [[TMP10]], align 8, !dbg [[DBG138]] -// CHECK5-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[CLASS_ANON_1]], %class.anon.1* [[REF_TMP]], i32 0, i32 3, !dbg [[DBG138]] -// CHECK5-NEXT: [[TMP12:%.*]] = load i32*, i32** [[_TMP5]], align 8, !dbg [[DBG139]] -// CHECK5-NEXT: store i32* [[TMP12]], i32** [[TMP11]], align 8, !dbg [[DBG138]] +// CHECK5-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[CLASS_ANON_1]], %class.anon.1* [[REF_TMP]], i32 0, i32 0, !dbg [[DBG141:![0-9]+]] +// CHECK5-NEXT: store %struct.SS* [[TMP0]], %struct.SS** [[TMP7]], align 8, !dbg [[DBG141]] +// CHECK5-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[CLASS_ANON_1]], %class.anon.1* [[REF_TMP]], i32 0, i32 1, !dbg [[DBG141]] +// CHECK5-NEXT: [[TMP9:%.*]] = load i32*, i32** [[_TMP4]], align 8, !dbg [[DBG142:![0-9]+]] +// CHECK5-NEXT: store i32* [[TMP9]], i32** [[TMP8]], align 8, !dbg [[DBG141]] +// CHECK5-NEXT: [[TMP10:%.*]] = getelementptr inbounds [[CLASS_ANON_1]], %class.anon.1* [[REF_TMP]], i32 0, i32 2, !dbg [[DBG141]] +// CHECK5-NEXT: store i32* [[CONV1]], i32** [[TMP10]], align 8, !dbg [[DBG141]] +// CHECK5-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[CLASS_ANON_1]], %class.anon.1* [[REF_TMP]], i32 0, i32 3, !dbg [[DBG141]] +// CHECK5-NEXT: [[TMP12:%.*]] = load i32*, i32** [[_TMP5]], align 8, !dbg [[DBG142]] +// CHECK5-NEXT: store i32* [[TMP12]], i32** [[TMP11]], align 8, !dbg [[DBG141]] // CHECK5-NEXT: invoke void @_ZZN2SSC1ERiENKUlvE_clEv(%class.anon.1* nonnull align 8 dereferenceable(32) [[REF_TMP]]) -// CHECK5-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]], !dbg [[DBG138]] +// CHECK5-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]], !dbg [[DBG141]] // CHECK5: invoke.cont: -// CHECK5-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB24]], i32 [[TMP4]]), !dbg [[DBG138]] -// CHECK5-NEXT: store i32 1, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4, !dbg [[DBG138]] -// CHECK5-NEXT: br label [[OMP_IF_END]], !dbg [[DBG138]] +// CHECK5-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB24]], i32 [[TMP4]]), !dbg [[DBG141]] +// CHECK5-NEXT: store i32 1, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4, !dbg [[DBG141]] +// CHECK5-NEXT: br label [[OMP_IF_END]], !dbg [[DBG141]] +// CHECK5: lpad: +// CHECK5-NEXT: [[TMP13:%.*]] = landingpad { i8*, i32 } +// CHECK5-NEXT: catch i8* null, !dbg [[DBG143:![0-9]+]] +// CHECK5-NEXT: [[TMP14:%.*]] = extractvalue { i8*, i32 } [[TMP13]], 0, !dbg [[DBG143]] +// CHECK5-NEXT: store i8* [[TMP14]], i8** [[EXN_SLOT]], align 8, !dbg [[DBG143]] +// CHECK5-NEXT: [[TMP15:%.*]] = extractvalue { i8*, i32 } [[TMP13]], 1, !dbg [[DBG143]] +// CHECK5-NEXT: store i32 [[TMP15]], i32* [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG143]] +// CHECK5-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB24]], i32 [[TMP4]]), !dbg [[DBG141]] +// CHECK5-NEXT: br label [[TERMINATE_HANDLER:%.*]], !dbg [[DBG141]] // CHECK5: omp_if.end: -// CHECK5-NEXT: [[TMP13:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 0, !dbg [[DBG138]] -// CHECK5-NEXT: [[TMP14:%.*]] = load i32*, i32** [[_TMP4]], align 8, !dbg [[DBG140:![0-9]+]] -// CHECK5-NEXT: [[TMP15:%.*]] = bitcast i32* [[TMP14]] to i8*, !dbg [[DBG138]] -// CHECK5-NEXT: store i8* [[TMP15]], i8** [[TMP13]], align 8, !dbg [[DBG138]] -// CHECK5-NEXT: [[TMP16:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 1, !dbg [[DBG138]] -// CHECK5-NEXT: [[TMP17:%.*]] = bitcast i32* [[CONV1]] to i8*, !dbg [[DBG138]] -// CHECK5-NEXT: store i8* [[TMP17]], i8** [[TMP16]], align 8, !dbg [[DBG138]] -// CHECK5-NEXT: [[TMP18:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 2, !dbg [[DBG138]] -// CHECK5-NEXT: [[TMP19:%.*]] = load i32*, i32** [[_TMP5]], align 8, !dbg [[DBG141:![0-9]+]] -// CHECK5-NEXT: [[TMP20:%.*]] = bitcast i32* [[TMP19]] to i8*, !dbg [[DBG138]] -// CHECK5-NEXT: store i8* [[TMP20]], i8** [[TMP18]], align 8, !dbg [[DBG138]] -// CHECK5-NEXT: [[TMP21:%.*]] = bitcast [3 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]] to i8*, !dbg [[DBG138]] -// CHECK5-NEXT: [[TMP22:%.*]] = load i32, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4, !dbg [[DBG138]] -// CHECK5-NEXT: call void @__kmpc_copyprivate(%struct.ident_t* @[[GLOB24]], i32 [[TMP4]], i64 24, i8* [[TMP21]], void (i8*, i8*)* @.omp.copyprivate.copy_func.9, i32 [[TMP22]]), !dbg [[DBG138]] -// CHECK5-NEXT: ret void, !dbg [[DBG142:![0-9]+]] -// CHECK5: terminate.lpad: -// CHECK5-NEXT: [[TMP23:%.*]] = landingpad { i8*, i32 } -// CHECK5-NEXT: catch i8* null, !dbg [[DBG138]] -// CHECK5-NEXT: [[TMP24:%.*]] = extractvalue { i8*, i32 } [[TMP23]], 0, !dbg [[DBG138]] -// CHECK5-NEXT: call void @__clang_call_terminate(i8* [[TMP24]]) #[[ATTR13]], !dbg [[DBG138]] -// CHECK5-NEXT: unreachable, !dbg [[DBG138]] +// CHECK5-NEXT: [[TMP16:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 0, !dbg [[DBG141]] +// CHECK5-NEXT: [[TMP17:%.*]] = load i32*, i32** [[_TMP4]], align 8, !dbg [[DBG144:![0-9]+]] +// CHECK5-NEXT: [[TMP18:%.*]] = bitcast i32* [[TMP17]] to i8*, !dbg [[DBG141]] +// CHECK5-NEXT: store i8* [[TMP18]], i8** [[TMP16]], align 8, !dbg [[DBG141]] +// CHECK5-NEXT: [[TMP19:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 1, !dbg [[DBG141]] +// CHECK5-NEXT: [[TMP20:%.*]] = bitcast i32* [[CONV1]] to i8*, !dbg [[DBG141]] +// CHECK5-NEXT: store i8* [[TMP20]], i8** [[TMP19]], align 8, !dbg [[DBG141]] +// CHECK5-NEXT: [[TMP21:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 2, !dbg [[DBG141]] +// CHECK5-NEXT: [[TMP22:%.*]] = load i32*, i32** [[_TMP5]], align 8, !dbg [[DBG145:![0-9]+]] +// CHECK5-NEXT: [[TMP23:%.*]] = bitcast i32* [[TMP22]] to i8*, !dbg [[DBG141]] +// CHECK5-NEXT: store i8* [[TMP23]], i8** [[TMP21]], align 8, !dbg [[DBG141]] +// CHECK5-NEXT: [[TMP24:%.*]] = bitcast [3 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]] to i8*, !dbg [[DBG141]] +// CHECK5-NEXT: [[TMP25:%.*]] = load i32, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4, !dbg [[DBG141]] +// CHECK5-NEXT: call void @__kmpc_copyprivate(%struct.ident_t* @[[GLOB24]], i32 [[TMP4]], i64 24, i8* [[TMP24]], void (i8*, i8*)* @.omp.copyprivate.copy_func.9, i32 [[TMP25]]), !dbg [[DBG141]] +// CHECK5-NEXT: ret void, !dbg [[DBG146:![0-9]+]] +// CHECK5: terminate.handler: +// CHECK5-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8, !dbg [[DBG141]] +// CHECK5-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR13]], !dbg [[DBG141]] +// CHECK5-NEXT: unreachable, !dbg [[DBG141]] // // // CHECK5-LABEL: define {{[^@]+}}@_ZZN2SSC1ERiENKUlvE_clEv -// CHECK5-SAME: (%class.anon.1* nonnull align 8 dereferenceable(32) [[THIS:%.*]]) #[[ATTR10]] align 2 !dbg [[DBG143:![0-9]+]] { +// CHECK5-SAME: (%class.anon.1* nonnull align 8 dereferenceable(32) [[THIS:%.*]]) #[[ATTR10]] align 2 !dbg [[DBG147:![0-9]+]] { // CHECK5-NEXT: entry: // CHECK5-NEXT: [[THIS_ADDR:%.*]] = alloca %class.anon.1*, align 8 // CHECK5-NEXT: [[A_CASTED:%.*]] = alloca i64, align 8 @@ -4735,83 +4930,83 @@ void array_func(int n, int a[n], St s[2]) { // CHECK5-NEXT: [[THIS1:%.*]] = load %class.anon.1*, %class.anon.1** [[THIS_ADDR]], align 8 // CHECK5-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_ANON_1:%.*]], %class.anon.1* [[THIS1]], i32 0, i32 0 // CHECK5-NEXT: [[TMP1:%.*]] = load %struct.SS*, %struct.SS** [[TMP0]], align 8 -// CHECK5-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[CLASS_ANON_1]], %class.anon.1* [[THIS1]], i32 0, i32 1, !dbg [[DBG144:![0-9]+]] -// CHECK5-NEXT: [[TMP3:%.*]] = load i32*, i32** [[TMP2]], align 8, !dbg [[DBG144]] -// CHECK5-NEXT: [[TMP4:%.*]] = load i32, i32* [[TMP3]], align 4, !dbg [[DBG145:![0-9]+]] -// CHECK5-NEXT: [[INC:%.*]] = add nsw i32 [[TMP4]], 1, !dbg [[DBG145]] -// CHECK5-NEXT: store i32 [[INC]], i32* [[TMP3]], align 4, !dbg [[DBG145]] -// CHECK5-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[CLASS_ANON_1]], %class.anon.1* [[THIS1]], i32 0, i32 2, !dbg [[DBG146:![0-9]+]] -// CHECK5-NEXT: [[TMP6:%.*]] = load i32*, i32** [[TMP5]], align 8, !dbg [[DBG146]] -// CHECK5-NEXT: [[TMP7:%.*]] = load i32, i32* [[TMP6]], align 4, !dbg [[DBG147:![0-9]+]] -// CHECK5-NEXT: [[DEC:%.*]] = add nsw i32 [[TMP7]], -1, !dbg [[DBG147]] -// CHECK5-NEXT: store i32 [[DEC]], i32* [[TMP6]], align 4, !dbg [[DBG147]] -// CHECK5-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[CLASS_ANON_1]], %class.anon.1* [[THIS1]], i32 0, i32 3, !dbg [[DBG148:![0-9]+]] -// CHECK5-NEXT: [[TMP9:%.*]] = load i32*, i32** [[TMP8]], align 8, !dbg [[DBG148]] -// CHECK5-NEXT: [[TMP10:%.*]] = load i32, i32* [[TMP9]], align 4, !dbg [[DBG149:![0-9]+]] -// CHECK5-NEXT: [[DIV:%.*]] = sdiv i32 [[TMP10]], 1, !dbg [[DBG149]] -// CHECK5-NEXT: store i32 [[DIV]], i32* [[TMP9]], align 4, !dbg [[DBG149]] -// CHECK5-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[CLASS_ANON_1]], %class.anon.1* [[THIS1]], i32 0, i32 1, !dbg [[DBG150:![0-9]+]] -// CHECK5-NEXT: [[TMP12:%.*]] = load i32*, i32** [[TMP11]], align 8, !dbg [[DBG150]] -// CHECK5-NEXT: [[TMP13:%.*]] = load i32, i32* [[TMP12]], align 4, !dbg [[DBG151:![0-9]+]] -// CHECK5-NEXT: [[CONV:%.*]] = bitcast i64* [[A_CASTED]] to i32*, !dbg [[DBG151]] -// CHECK5-NEXT: store i32 [[TMP13]], i32* [[CONV]], align 4, !dbg [[DBG151]] -// CHECK5-NEXT: [[TMP14:%.*]] = load i64, i64* [[A_CASTED]], align 8, !dbg [[DBG151]] -// CHECK5-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[CLASS_ANON_1]], %class.anon.1* [[THIS1]], i32 0, i32 2, !dbg [[DBG152:![0-9]+]] -// CHECK5-NEXT: [[TMP16:%.*]] = load i32*, i32** [[TMP15]], align 8, !dbg [[DBG152]] -// CHECK5-NEXT: [[TMP17:%.*]] = load i32, i32* [[TMP16]], align 4, !dbg [[DBG151]] -// CHECK5-NEXT: [[CONV2:%.*]] = bitcast i64* [[B_CASTED]] to i32*, !dbg [[DBG151]] -// CHECK5-NEXT: store i32 [[TMP17]], i32* [[CONV2]], align 4, !dbg [[DBG151]] -// CHECK5-NEXT: [[TMP18:%.*]] = load i64, i64* [[B_CASTED]], align 8, !dbg [[DBG151]] -// CHECK5-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[CLASS_ANON_1]], %class.anon.1* [[THIS1]], i32 0, i32 3, !dbg [[DBG153:![0-9]+]] -// CHECK5-NEXT: [[TMP20:%.*]] = load i32*, i32** [[TMP19]], align 8, !dbg [[DBG153]] -// CHECK5-NEXT: [[TMP21:%.*]] = load i32, i32* [[TMP20]], align 4, !dbg [[DBG151]] -// CHECK5-NEXT: [[CONV3:%.*]] = bitcast i64* [[C_CASTED]] to i32*, !dbg [[DBG151]] -// CHECK5-NEXT: store i32 [[TMP21]], i32* [[CONV3]], align 4, !dbg [[DBG151]] -// CHECK5-NEXT: [[TMP22:%.*]] = load i64, i64* [[C_CASTED]], align 8, !dbg [[DBG151]] -// CHECK5-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB30:[0-9]+]], i32 4, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %struct.SS*, i64, i64, i64)* @.omp_outlined..10 to void (i32*, i32*, ...)*), %struct.SS* [[TMP1]], i64 [[TMP14]], i64 [[TMP18]], i64 [[TMP22]]), !dbg [[DBG151]] -// CHECK5-NEXT: ret void, !dbg [[DBG154:![0-9]+]] +// CHECK5-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[CLASS_ANON_1]], %class.anon.1* [[THIS1]], i32 0, i32 1, !dbg [[DBG148:![0-9]+]] +// CHECK5-NEXT: [[TMP3:%.*]] = load i32*, i32** [[TMP2]], align 8, !dbg [[DBG148]] +// CHECK5-NEXT: [[TMP4:%.*]] = load i32, i32* [[TMP3]], align 4, !dbg [[DBG149:![0-9]+]] +// CHECK5-NEXT: [[INC:%.*]] = add nsw i32 [[TMP4]], 1, !dbg [[DBG149]] +// CHECK5-NEXT: store i32 [[INC]], i32* [[TMP3]], align 4, !dbg [[DBG149]] +// CHECK5-NEXT: [[TMP5:%.*]] = getelementptr inbounds [[CLASS_ANON_1]], %class.anon.1* [[THIS1]], i32 0, i32 2, !dbg [[DBG150:![0-9]+]] +// CHECK5-NEXT: [[TMP6:%.*]] = load i32*, i32** [[TMP5]], align 8, !dbg [[DBG150]] +// CHECK5-NEXT: [[TMP7:%.*]] = load i32, i32* [[TMP6]], align 4, !dbg [[DBG151:![0-9]+]] +// CHECK5-NEXT: [[DEC:%.*]] = add nsw i32 [[TMP7]], -1, !dbg [[DBG151]] +// CHECK5-NEXT: store i32 [[DEC]], i32* [[TMP6]], align 4, !dbg [[DBG151]] +// CHECK5-NEXT: [[TMP8:%.*]] = getelementptr inbounds [[CLASS_ANON_1]], %class.anon.1* [[THIS1]], i32 0, i32 3, !dbg [[DBG152:![0-9]+]] +// CHECK5-NEXT: [[TMP9:%.*]] = load i32*, i32** [[TMP8]], align 8, !dbg [[DBG152]] +// CHECK5-NEXT: [[TMP10:%.*]] = load i32, i32* [[TMP9]], align 4, !dbg [[DBG153:![0-9]+]] +// CHECK5-NEXT: [[DIV:%.*]] = sdiv i32 [[TMP10]], 1, !dbg [[DBG153]] +// CHECK5-NEXT: store i32 [[DIV]], i32* [[TMP9]], align 4, !dbg [[DBG153]] +// CHECK5-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[CLASS_ANON_1]], %class.anon.1* [[THIS1]], i32 0, i32 1, !dbg [[DBG154:![0-9]+]] +// CHECK5-NEXT: [[TMP12:%.*]] = load i32*, i32** [[TMP11]], align 8, !dbg [[DBG154]] +// CHECK5-NEXT: [[TMP13:%.*]] = load i32, i32* [[TMP12]], align 4, !dbg [[DBG155:![0-9]+]] +// CHECK5-NEXT: [[CONV:%.*]] = bitcast i64* [[A_CASTED]] to i32*, !dbg [[DBG155]] +// CHECK5-NEXT: store i32 [[TMP13]], i32* [[CONV]], align 4, !dbg [[DBG155]] +// CHECK5-NEXT: [[TMP14:%.*]] = load i64, i64* [[A_CASTED]], align 8, !dbg [[DBG155]] +// CHECK5-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[CLASS_ANON_1]], %class.anon.1* [[THIS1]], i32 0, i32 2, !dbg [[DBG156:![0-9]+]] +// CHECK5-NEXT: [[TMP16:%.*]] = load i32*, i32** [[TMP15]], align 8, !dbg [[DBG156]] +// CHECK5-NEXT: [[TMP17:%.*]] = load i32, i32* [[TMP16]], align 4, !dbg [[DBG155]] +// CHECK5-NEXT: [[CONV2:%.*]] = bitcast i64* [[B_CASTED]] to i32*, !dbg [[DBG155]] +// CHECK5-NEXT: store i32 [[TMP17]], i32* [[CONV2]], align 4, !dbg [[DBG155]] +// CHECK5-NEXT: [[TMP18:%.*]] = load i64, i64* [[B_CASTED]], align 8, !dbg [[DBG155]] +// CHECK5-NEXT: [[TMP19:%.*]] = getelementptr inbounds [[CLASS_ANON_1]], %class.anon.1* [[THIS1]], i32 0, i32 3, !dbg [[DBG157:![0-9]+]] +// CHECK5-NEXT: [[TMP20:%.*]] = load i32*, i32** [[TMP19]], align 8, !dbg [[DBG157]] +// CHECK5-NEXT: [[TMP21:%.*]] = load i32, i32* [[TMP20]], align 4, !dbg [[DBG155]] +// CHECK5-NEXT: [[CONV3:%.*]] = bitcast i64* [[C_CASTED]] to i32*, !dbg [[DBG155]] +// CHECK5-NEXT: store i32 [[TMP21]], i32* [[CONV3]], align 4, !dbg [[DBG155]] +// CHECK5-NEXT: [[TMP22:%.*]] = load i64, i64* [[C_CASTED]], align 8, !dbg [[DBG155]] +// CHECK5-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB30:[0-9]+]], i32 4, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %struct.SS*, i64, i64, i64)* @.omp_outlined..10 to void (i32*, i32*, ...)*), %struct.SS* [[TMP1]], i64 [[TMP14]], i64 [[TMP18]], i64 [[TMP22]]), !dbg [[DBG155]] +// CHECK5-NEXT: ret void, !dbg [[DBG158:![0-9]+]] // // // CHECK5-LABEL: define {{[^@]+}}@.omp.copyprivate.copy_func.9 -// CHECK5-SAME: (i8* [[TMP0:%.*]], i8* [[TMP1:%.*]]) #[[ATTR9]] !dbg [[DBG155:![0-9]+]] { +// CHECK5-SAME: (i8* [[TMP0:%.*]], i8* [[TMP1:%.*]]) #[[ATTR9]] !dbg [[DBG159:![0-9]+]] { // CHECK5-NEXT: entry: // CHECK5-NEXT: [[DOTADDR:%.*]] = alloca i8*, align 8 // CHECK5-NEXT: [[DOTADDR1:%.*]] = alloca i8*, align 8 // CHECK5-NEXT: store i8* [[TMP0]], i8** [[DOTADDR]], align 8 // CHECK5-NEXT: store i8* [[TMP1]], i8** [[DOTADDR1]], align 8 -// CHECK5-NEXT: [[TMP2:%.*]] = load i8*, i8** [[DOTADDR]], align 8, !dbg [[DBG156:![0-9]+]] -// CHECK5-NEXT: [[TMP3:%.*]] = bitcast i8* [[TMP2]] to [3 x i8*]*, !dbg [[DBG156]] -// CHECK5-NEXT: [[TMP4:%.*]] = load i8*, i8** [[DOTADDR1]], align 8, !dbg [[DBG156]] -// CHECK5-NEXT: [[TMP5:%.*]] = bitcast i8* [[TMP4]] to [3 x i8*]*, !dbg [[DBG156]] -// CHECK5-NEXT: [[TMP6:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP3]], i64 0, i64 0, !dbg [[DBG156]] -// CHECK5-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8, !dbg [[DBG156]] -// CHECK5-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to i32*, !dbg [[DBG156]] -// CHECK5-NEXT: [[TMP9:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP5]], i64 0, i64 0, !dbg [[DBG156]] -// CHECK5-NEXT: [[TMP10:%.*]] = load i8*, i8** [[TMP9]], align 8, !dbg [[DBG156]] -// CHECK5-NEXT: [[TMP11:%.*]] = bitcast i8* [[TMP10]] to i32*, !dbg [[DBG156]] -// CHECK5-NEXT: [[TMP12:%.*]] = load i32, i32* [[TMP11]], align 4, !dbg [[DBG157:![0-9]+]] -// CHECK5-NEXT: store i32 [[TMP12]], i32* [[TMP8]], align 4, !dbg [[DBG157]] -// CHECK5-NEXT: [[TMP13:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP3]], i64 0, i64 1, !dbg [[DBG156]] -// CHECK5-NEXT: [[TMP14:%.*]] = load i8*, i8** [[TMP13]], align 8, !dbg [[DBG156]] -// CHECK5-NEXT: [[TMP15:%.*]] = bitcast i8* [[TMP14]] to i32*, !dbg [[DBG156]] -// CHECK5-NEXT: [[TMP16:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP5]], i64 0, i64 1, !dbg [[DBG156]] -// CHECK5-NEXT: [[TMP17:%.*]] = load i8*, i8** [[TMP16]], align 8, !dbg [[DBG156]] -// CHECK5-NEXT: [[TMP18:%.*]] = bitcast i8* [[TMP17]] to i32*, !dbg [[DBG156]] -// CHECK5-NEXT: [[TMP19:%.*]] = load i32, i32* [[TMP18]], align 4, !dbg [[DBG158:![0-9]+]] -// CHECK5-NEXT: store i32 [[TMP19]], i32* [[TMP15]], align 4, !dbg [[DBG158]] -// CHECK5-NEXT: [[TMP20:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP3]], i64 0, i64 2, !dbg [[DBG156]] -// CHECK5-NEXT: [[TMP21:%.*]] = load i8*, i8** [[TMP20]], align 8, !dbg [[DBG156]] -// CHECK5-NEXT: [[TMP22:%.*]] = bitcast i8* [[TMP21]] to i32*, !dbg [[DBG156]] -// CHECK5-NEXT: [[TMP23:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP5]], i64 0, i64 2, !dbg [[DBG156]] -// CHECK5-NEXT: [[TMP24:%.*]] = load i8*, i8** [[TMP23]], align 8, !dbg [[DBG156]] -// CHECK5-NEXT: [[TMP25:%.*]] = bitcast i8* [[TMP24]] to i32*, !dbg [[DBG156]] -// CHECK5-NEXT: [[TMP26:%.*]] = load i32, i32* [[TMP25]], align 4, !dbg [[DBG159:![0-9]+]] -// CHECK5-NEXT: store i32 [[TMP26]], i32* [[TMP22]], align 4, !dbg [[DBG159]] -// CHECK5-NEXT: ret void, !dbg [[DBG159]] +// CHECK5-NEXT: [[TMP2:%.*]] = load i8*, i8** [[DOTADDR]], align 8, !dbg [[DBG160:![0-9]+]] +// CHECK5-NEXT: [[TMP3:%.*]] = bitcast i8* [[TMP2]] to [3 x i8*]*, !dbg [[DBG160]] +// CHECK5-NEXT: [[TMP4:%.*]] = load i8*, i8** [[DOTADDR1]], align 8, !dbg [[DBG160]] +// CHECK5-NEXT: [[TMP5:%.*]] = bitcast i8* [[TMP4]] to [3 x i8*]*, !dbg [[DBG160]] +// CHECK5-NEXT: [[TMP6:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP3]], i64 0, i64 0, !dbg [[DBG160]] +// CHECK5-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8, !dbg [[DBG160]] +// CHECK5-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to i32*, !dbg [[DBG160]] +// CHECK5-NEXT: [[TMP9:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP5]], i64 0, i64 0, !dbg [[DBG160]] +// CHECK5-NEXT: [[TMP10:%.*]] = load i8*, i8** [[TMP9]], align 8, !dbg [[DBG160]] +// CHECK5-NEXT: [[TMP11:%.*]] = bitcast i8* [[TMP10]] to i32*, !dbg [[DBG160]] +// CHECK5-NEXT: [[TMP12:%.*]] = load i32, i32* [[TMP11]], align 4, !dbg [[DBG161:![0-9]+]] +// CHECK5-NEXT: store i32 [[TMP12]], i32* [[TMP8]], align 4, !dbg [[DBG161]] +// CHECK5-NEXT: [[TMP13:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP3]], i64 0, i64 1, !dbg [[DBG160]] +// CHECK5-NEXT: [[TMP14:%.*]] = load i8*, i8** [[TMP13]], align 8, !dbg [[DBG160]] +// CHECK5-NEXT: [[TMP15:%.*]] = bitcast i8* [[TMP14]] to i32*, !dbg [[DBG160]] +// CHECK5-NEXT: [[TMP16:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP5]], i64 0, i64 1, !dbg [[DBG160]] +// CHECK5-NEXT: [[TMP17:%.*]] = load i8*, i8** [[TMP16]], align 8, !dbg [[DBG160]] +// CHECK5-NEXT: [[TMP18:%.*]] = bitcast i8* [[TMP17]] to i32*, !dbg [[DBG160]] +// CHECK5-NEXT: [[TMP19:%.*]] = load i32, i32* [[TMP18]], align 4, !dbg [[DBG162:![0-9]+]] +// CHECK5-NEXT: store i32 [[TMP19]], i32* [[TMP15]], align 4, !dbg [[DBG162]] +// CHECK5-NEXT: [[TMP20:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP3]], i64 0, i64 2, !dbg [[DBG160]] +// CHECK5-NEXT: [[TMP21:%.*]] = load i8*, i8** [[TMP20]], align 8, !dbg [[DBG160]] +// CHECK5-NEXT: [[TMP22:%.*]] = bitcast i8* [[TMP21]] to i32*, !dbg [[DBG160]] +// CHECK5-NEXT: [[TMP23:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP5]], i64 0, i64 2, !dbg [[DBG160]] +// CHECK5-NEXT: [[TMP24:%.*]] = load i8*, i8** [[TMP23]], align 8, !dbg [[DBG160]] +// CHECK5-NEXT: [[TMP25:%.*]] = bitcast i8* [[TMP24]] to i32*, !dbg [[DBG160]] +// CHECK5-NEXT: [[TMP26:%.*]] = load i32, i32* [[TMP25]], align 4, !dbg [[DBG163:![0-9]+]] +// CHECK5-NEXT: store i32 [[TMP26]], i32* [[TMP22]], align 4, !dbg [[DBG163]] +// CHECK5-NEXT: ret void, !dbg [[DBG163]] // // // CHECK5-LABEL: define {{[^@]+}}@.omp_outlined..10 -// CHECK5-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], %struct.SS* [[THIS:%.*]], i64 [[A:%.*]], i64 [[B:%.*]], i64 [[C:%.*]]) #[[ATTR12]] !dbg [[DBG160:![0-9]+]] { +// CHECK5-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], %struct.SS* [[THIS:%.*]], i64 [[A:%.*]], i64 [[B:%.*]], i64 [[C:%.*]]) #[[ATTR12]] !dbg [[DBG164:![0-9]+]] { // CHECK5-NEXT: entry: // CHECK5-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK5-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 @@ -4831,136 +5026,145 @@ void array_func(int n, int a[n], St s[2]) { // CHECK5-NEXT: store i64 [[A]], i64* [[A_ADDR]], align 8 // CHECK5-NEXT: store i64 [[B]], i64* [[B_ADDR]], align 8 // CHECK5-NEXT: store i64 [[C]], i64* [[C_ADDR]], align 8 -// CHECK5-NEXT: [[TMP0:%.*]] = load %struct.SS*, %struct.SS** [[THIS_ADDR]], align 8, !dbg [[DBG161:![0-9]+]] -// CHECK5-NEXT: [[CONV:%.*]] = bitcast i64* [[A_ADDR]] to i32*, !dbg [[DBG161]] -// CHECK5-NEXT: [[CONV1:%.*]] = bitcast i64* [[B_ADDR]] to i32*, !dbg [[DBG161]] -// CHECK5-NEXT: [[CONV2:%.*]] = bitcast i64* [[C_ADDR]] to i32*, !dbg [[DBG161]] -// CHECK5-NEXT: store i32* [[CONV]], i32** [[TMP]], align 8, !dbg [[DBG161]] -// CHECK5-NEXT: store i32* [[CONV2]], i32** [[_TMP3]], align 8, !dbg [[DBG161]] -// CHECK5-NEXT: [[TMP1:%.*]] = load i32*, i32** [[TMP]], align 8, !dbg [[DBG162:![0-9]+]] -// CHECK5-NEXT: store i32* [[TMP1]], i32** [[_TMP4]], align 8, !dbg [[DBG163:![0-9]+]] -// CHECK5-NEXT: [[TMP2:%.*]] = load i32*, i32** [[_TMP3]], align 8, !dbg [[DBG164:![0-9]+]] -// CHECK5-NEXT: store i32* [[TMP2]], i32** [[_TMP5]], align 8, !dbg [[DBG163]] -// CHECK5-NEXT: store i32 0, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4, !dbg [[DBG163]] -// CHECK5-NEXT: [[TMP3:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG163]] -// CHECK5-NEXT: [[TMP4:%.*]] = load i32, i32* [[TMP3]], align 4, !dbg [[DBG163]] -// CHECK5-NEXT: [[TMP5:%.*]] = call i32 @__kmpc_single(%struct.ident_t* @[[GLOB28:[0-9]+]], i32 [[TMP4]]), !dbg [[DBG163]] -// CHECK5-NEXT: [[TMP6:%.*]] = icmp ne i32 [[TMP5]], 0, !dbg [[DBG163]] -// CHECK5-NEXT: br i1 [[TMP6]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_END:%.*]], !dbg [[DBG163]] +// CHECK5-NEXT: [[TMP0:%.*]] = load %struct.SS*, %struct.SS** [[THIS_ADDR]], align 8, !dbg [[DBG165:![0-9]+]] +// CHECK5-NEXT: [[CONV:%.*]] = bitcast i64* [[A_ADDR]] to i32*, !dbg [[DBG165]] +// CHECK5-NEXT: [[CONV1:%.*]] = bitcast i64* [[B_ADDR]] to i32*, !dbg [[DBG165]] +// CHECK5-NEXT: [[CONV2:%.*]] = bitcast i64* [[C_ADDR]] to i32*, !dbg [[DBG165]] +// CHECK5-NEXT: store i32* [[CONV]], i32** [[TMP]], align 8, !dbg [[DBG165]] +// CHECK5-NEXT: store i32* [[CONV2]], i32** [[_TMP3]], align 8, !dbg [[DBG165]] +// CHECK5-NEXT: [[TMP1:%.*]] = load i32*, i32** [[TMP]], align 8, !dbg [[DBG166:![0-9]+]] +// CHECK5-NEXT: store i32* [[TMP1]], i32** [[_TMP4]], align 8, !dbg [[DBG167:![0-9]+]] +// CHECK5-NEXT: [[TMP2:%.*]] = load i32*, i32** [[_TMP3]], align 8, !dbg [[DBG168:![0-9]+]] +// CHECK5-NEXT: store i32* [[TMP2]], i32** [[_TMP5]], align 8, !dbg [[DBG167]] +// CHECK5-NEXT: store i32 0, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4, !dbg [[DBG167]] +// CHECK5-NEXT: [[TMP3:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG167]] +// CHECK5-NEXT: [[TMP4:%.*]] = load i32, i32* [[TMP3]], align 4, !dbg [[DBG167]] +// CHECK5-NEXT: [[TMP5:%.*]] = call i32 @__kmpc_single(%struct.ident_t* @[[GLOB28:[0-9]+]], i32 [[TMP4]]), !dbg [[DBG167]] +// CHECK5-NEXT: [[TMP6:%.*]] = icmp ne i32 [[TMP5]], 0, !dbg [[DBG167]] +// CHECK5-NEXT: br i1 [[TMP6]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_END:%.*]], !dbg [[DBG167]] // CHECK5: omp_if.then: -// CHECK5-NEXT: [[TMP7:%.*]] = load i32*, i32** [[_TMP4]], align 8, !dbg [[DBG162]] -// CHECK5-NEXT: [[TMP8:%.*]] = load i32, i32* [[TMP7]], align 4, !dbg [[DBG165:![0-9]+]] -// CHECK5-NEXT: [[INC:%.*]] = add nsw i32 [[TMP8]], 1, !dbg [[DBG165]] -// CHECK5-NEXT: store i32 [[INC]], i32* [[TMP7]], align 4, !dbg [[DBG165]] -// CHECK5-NEXT: [[TMP9:%.*]] = load i32, i32* [[CONV1]], align 4, !dbg [[DBG166:![0-9]+]] -// CHECK5-NEXT: [[DEC:%.*]] = add nsw i32 [[TMP9]], -1, !dbg [[DBG166]] -// CHECK5-NEXT: store i32 [[DEC]], i32* [[CONV1]], align 4, !dbg [[DBG166]] -// CHECK5-NEXT: [[TMP10:%.*]] = load i32*, i32** [[_TMP5]], align 8, !dbg [[DBG164]] -// CHECK5-NEXT: [[TMP11:%.*]] = load i32, i32* [[TMP10]], align 4, !dbg [[DBG167:![0-9]+]] -// CHECK5-NEXT: [[DIV:%.*]] = sdiv i32 [[TMP11]], 1, !dbg [[DBG167]] -// CHECK5-NEXT: store i32 [[DIV]], i32* [[TMP10]], align 4, !dbg [[DBG167]] -// CHECK5-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB28]], i32 [[TMP4]]), !dbg [[DBG165]] -// CHECK5-NEXT: store i32 1, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4, !dbg [[DBG165]] -// CHECK5-NEXT: br label [[OMP_IF_END]], !dbg [[DBG165]] +// CHECK5-NEXT: [[TMP7:%.*]] = load i32*, i32** [[_TMP4]], align 8, !dbg [[DBG166]] +// CHECK5-NEXT: [[TMP8:%.*]] = load i32, i32* [[TMP7]], align 4, !dbg [[DBG169:![0-9]+]] +// CHECK5-NEXT: [[INC:%.*]] = add nsw i32 [[TMP8]], 1, !dbg [[DBG169]] +// CHECK5-NEXT: store i32 [[INC]], i32* [[TMP7]], align 4, !dbg [[DBG169]] +// CHECK5-NEXT: [[TMP9:%.*]] = load i32, i32* [[CONV1]], align 4, !dbg [[DBG170:![0-9]+]] +// CHECK5-NEXT: [[DEC:%.*]] = add nsw i32 [[TMP9]], -1, !dbg [[DBG170]] +// CHECK5-NEXT: store i32 [[DEC]], i32* [[CONV1]], align 4, !dbg [[DBG170]] +// CHECK5-NEXT: [[TMP10:%.*]] = load i32*, i32** [[_TMP5]], align 8, !dbg [[DBG168]] +// CHECK5-NEXT: [[TMP11:%.*]] = load i32, i32* [[TMP10]], align 4, !dbg [[DBG171:![0-9]+]] +// CHECK5-NEXT: [[DIV:%.*]] = sdiv i32 [[TMP11]], 1, !dbg [[DBG171]] +// CHECK5-NEXT: store i32 [[DIV]], i32* [[TMP10]], align 4, !dbg [[DBG171]] +// CHECK5-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB28]], i32 [[TMP4]]), !dbg [[DBG169]] +// CHECK5-NEXT: store i32 1, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4, !dbg [[DBG169]] +// CHECK5-NEXT: br label [[OMP_IF_END]], !dbg [[DBG169]] // CHECK5: omp_if.end: -// CHECK5-NEXT: [[TMP12:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 0, !dbg [[DBG165]] -// CHECK5-NEXT: [[TMP13:%.*]] = load i32*, i32** [[_TMP4]], align 8, !dbg [[DBG168:![0-9]+]] -// CHECK5-NEXT: [[TMP14:%.*]] = bitcast i32* [[TMP13]] to i8*, !dbg [[DBG165]] -// CHECK5-NEXT: store i8* [[TMP14]], i8** [[TMP12]], align 8, !dbg [[DBG165]] -// CHECK5-NEXT: [[TMP15:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 1, !dbg [[DBG165]] -// CHECK5-NEXT: [[TMP16:%.*]] = bitcast i32* [[CONV1]] to i8*, !dbg [[DBG165]] -// CHECK5-NEXT: store i8* [[TMP16]], i8** [[TMP15]], align 8, !dbg [[DBG165]] -// CHECK5-NEXT: [[TMP17:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 2, !dbg [[DBG165]] -// CHECK5-NEXT: [[TMP18:%.*]] = load i32*, i32** [[_TMP5]], align 8, !dbg [[DBG169:![0-9]+]] -// CHECK5-NEXT: [[TMP19:%.*]] = bitcast i32* [[TMP18]] to i8*, !dbg [[DBG165]] -// CHECK5-NEXT: store i8* [[TMP19]], i8** [[TMP17]], align 8, !dbg [[DBG165]] -// CHECK5-NEXT: [[TMP20:%.*]] = bitcast [3 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]] to i8*, !dbg [[DBG165]] -// CHECK5-NEXT: [[TMP21:%.*]] = load i32, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4, !dbg [[DBG165]] -// CHECK5-NEXT: call void @__kmpc_copyprivate(%struct.ident_t* @[[GLOB28]], i32 [[TMP4]], i64 24, i8* [[TMP20]], void (i8*, i8*)* @.omp.copyprivate.copy_func.11, i32 [[TMP21]]), !dbg [[DBG165]] -// CHECK5-NEXT: ret void, !dbg [[DBG170:![0-9]+]] +// CHECK5-NEXT: [[TMP12:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 0, !dbg [[DBG169]] +// CHECK5-NEXT: [[TMP13:%.*]] = load i32*, i32** [[_TMP4]], align 8, !dbg [[DBG172:![0-9]+]] +// CHECK5-NEXT: [[TMP14:%.*]] = bitcast i32* [[TMP13]] to i8*, !dbg [[DBG169]] +// CHECK5-NEXT: store i8* [[TMP14]], i8** [[TMP12]], align 8, !dbg [[DBG169]] +// CHECK5-NEXT: [[TMP15:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 1, !dbg [[DBG169]] +// CHECK5-NEXT: [[TMP16:%.*]] = bitcast i32* [[CONV1]] to i8*, !dbg [[DBG169]] +// CHECK5-NEXT: store i8* [[TMP16]], i8** [[TMP15]], align 8, !dbg [[DBG169]] +// CHECK5-NEXT: [[TMP17:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]], i64 0, i64 2, !dbg [[DBG169]] +// CHECK5-NEXT: [[TMP18:%.*]] = load i32*, i32** [[_TMP5]], align 8, !dbg [[DBG173:![0-9]+]] +// CHECK5-NEXT: [[TMP19:%.*]] = bitcast i32* [[TMP18]] to i8*, !dbg [[DBG169]] +// CHECK5-NEXT: store i8* [[TMP19]], i8** [[TMP17]], align 8, !dbg [[DBG169]] +// CHECK5-NEXT: [[TMP20:%.*]] = bitcast [3 x i8*]* [[DOTOMP_COPYPRIVATE_CPR_LIST]] to i8*, !dbg [[DBG169]] +// CHECK5-NEXT: [[TMP21:%.*]] = load i32, i32* [[DOTOMP_COPYPRIVATE_DID_IT]], align 4, !dbg [[DBG169]] +// CHECK5-NEXT: call void @__kmpc_copyprivate(%struct.ident_t* @[[GLOB28]], i32 [[TMP4]], i64 24, i8* [[TMP20]], void (i8*, i8*)* @.omp.copyprivate.copy_func.11, i32 [[TMP21]]), !dbg [[DBG169]] +// CHECK5-NEXT: ret void, !dbg [[DBG174:![0-9]+]] // // // CHECK5-LABEL: define {{[^@]+}}@.omp.copyprivate.copy_func.11 -// CHECK5-SAME: (i8* [[TMP0:%.*]], i8* [[TMP1:%.*]]) #[[ATTR9]] !dbg [[DBG171:![0-9]+]] { +// CHECK5-SAME: (i8* [[TMP0:%.*]], i8* [[TMP1:%.*]]) #[[ATTR9]] !dbg [[DBG175:![0-9]+]] { // CHECK5-NEXT: entry: // CHECK5-NEXT: [[DOTADDR:%.*]] = alloca i8*, align 8 // CHECK5-NEXT: [[DOTADDR1:%.*]] = alloca i8*, align 8 // CHECK5-NEXT: store i8* [[TMP0]], i8** [[DOTADDR]], align 8 // CHECK5-NEXT: store i8* [[TMP1]], i8** [[DOTADDR1]], align 8 -// CHECK5-NEXT: [[TMP2:%.*]] = load i8*, i8** [[DOTADDR]], align 8, !dbg [[DBG172:![0-9]+]] -// CHECK5-NEXT: [[TMP3:%.*]] = bitcast i8* [[TMP2]] to [3 x i8*]*, !dbg [[DBG172]] -// CHECK5-NEXT: [[TMP4:%.*]] = load i8*, i8** [[DOTADDR1]], align 8, !dbg [[DBG172]] -// CHECK5-NEXT: [[TMP5:%.*]] = bitcast i8* [[TMP4]] to [3 x i8*]*, !dbg [[DBG172]] -// CHECK5-NEXT: [[TMP6:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP3]], i64 0, i64 0, !dbg [[DBG172]] -// CHECK5-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8, !dbg [[DBG172]] -// CHECK5-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to i32*, !dbg [[DBG172]] -// CHECK5-NEXT: [[TMP9:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP5]], i64 0, i64 0, !dbg [[DBG172]] -// CHECK5-NEXT: [[TMP10:%.*]] = load i8*, i8** [[TMP9]], align 8, !dbg [[DBG172]] -// CHECK5-NEXT: [[TMP11:%.*]] = bitcast i8* [[TMP10]] to i32*, !dbg [[DBG172]] -// CHECK5-NEXT: [[TMP12:%.*]] = load i32, i32* [[TMP11]], align 4, !dbg [[DBG173:![0-9]+]] -// CHECK5-NEXT: store i32 [[TMP12]], i32* [[TMP8]], align 4, !dbg [[DBG173]] -// CHECK5-NEXT: [[TMP13:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP3]], i64 0, i64 1, !dbg [[DBG172]] -// CHECK5-NEXT: [[TMP14:%.*]] = load i8*, i8** [[TMP13]], align 8, !dbg [[DBG172]] -// CHECK5-NEXT: [[TMP15:%.*]] = bitcast i8* [[TMP14]] to i32*, !dbg [[DBG172]] -// CHECK5-NEXT: [[TMP16:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP5]], i64 0, i64 1, !dbg [[DBG172]] -// CHECK5-NEXT: [[TMP17:%.*]] = load i8*, i8** [[TMP16]], align 8, !dbg [[DBG172]] -// CHECK5-NEXT: [[TMP18:%.*]] = bitcast i8* [[TMP17]] to i32*, !dbg [[DBG172]] -// CHECK5-NEXT: [[TMP19:%.*]] = load i32, i32* [[TMP18]], align 4, !dbg [[DBG174:![0-9]+]] -// CHECK5-NEXT: store i32 [[TMP19]], i32* [[TMP15]], align 4, !dbg [[DBG174]] -// CHECK5-NEXT: [[TMP20:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP3]], i64 0, i64 2, !dbg [[DBG172]] -// CHECK5-NEXT: [[TMP21:%.*]] = load i8*, i8** [[TMP20]], align 8, !dbg [[DBG172]] -// CHECK5-NEXT: [[TMP22:%.*]] = bitcast i8* [[TMP21]] to i32*, !dbg [[DBG172]] -// CHECK5-NEXT: [[TMP23:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP5]], i64 0, i64 2, !dbg [[DBG172]] -// CHECK5-NEXT: [[TMP24:%.*]] = load i8*, i8** [[TMP23]], align 8, !dbg [[DBG172]] -// CHECK5-NEXT: [[TMP25:%.*]] = bitcast i8* [[TMP24]] to i32*, !dbg [[DBG172]] -// CHECK5-NEXT: [[TMP26:%.*]] = load i32, i32* [[TMP25]], align 4, !dbg [[DBG175:![0-9]+]] -// CHECK5-NEXT: store i32 [[TMP26]], i32* [[TMP22]], align 4, !dbg [[DBG175]] -// CHECK5-NEXT: ret void, !dbg [[DBG175]] +// CHECK5-NEXT: [[TMP2:%.*]] = load i8*, i8** [[DOTADDR]], align 8, !dbg [[DBG176:![0-9]+]] +// CHECK5-NEXT: [[TMP3:%.*]] = bitcast i8* [[TMP2]] to [3 x i8*]*, !dbg [[DBG176]] +// CHECK5-NEXT: [[TMP4:%.*]] = load i8*, i8** [[DOTADDR1]], align 8, !dbg [[DBG176]] +// CHECK5-NEXT: [[TMP5:%.*]] = bitcast i8* [[TMP4]] to [3 x i8*]*, !dbg [[DBG176]] +// CHECK5-NEXT: [[TMP6:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP3]], i64 0, i64 0, !dbg [[DBG176]] +// CHECK5-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8, !dbg [[DBG176]] +// CHECK5-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to i32*, !dbg [[DBG176]] +// CHECK5-NEXT: [[TMP9:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP5]], i64 0, i64 0, !dbg [[DBG176]] +// CHECK5-NEXT: [[TMP10:%.*]] = load i8*, i8** [[TMP9]], align 8, !dbg [[DBG176]] +// CHECK5-NEXT: [[TMP11:%.*]] = bitcast i8* [[TMP10]] to i32*, !dbg [[DBG176]] +// CHECK5-NEXT: [[TMP12:%.*]] = load i32, i32* [[TMP11]], align 4, !dbg [[DBG177:![0-9]+]] +// CHECK5-NEXT: store i32 [[TMP12]], i32* [[TMP8]], align 4, !dbg [[DBG177]] +// CHECK5-NEXT: [[TMP13:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP3]], i64 0, i64 1, !dbg [[DBG176]] +// CHECK5-NEXT: [[TMP14:%.*]] = load i8*, i8** [[TMP13]], align 8, !dbg [[DBG176]] +// CHECK5-NEXT: [[TMP15:%.*]] = bitcast i8* [[TMP14]] to i32*, !dbg [[DBG176]] +// CHECK5-NEXT: [[TMP16:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP5]], i64 0, i64 1, !dbg [[DBG176]] +// CHECK5-NEXT: [[TMP17:%.*]] = load i8*, i8** [[TMP16]], align 8, !dbg [[DBG176]] +// CHECK5-NEXT: [[TMP18:%.*]] = bitcast i8* [[TMP17]] to i32*, !dbg [[DBG176]] +// CHECK5-NEXT: [[TMP19:%.*]] = load i32, i32* [[TMP18]], align 4, !dbg [[DBG178:![0-9]+]] +// CHECK5-NEXT: store i32 [[TMP19]], i32* [[TMP15]], align 4, !dbg [[DBG178]] +// CHECK5-NEXT: [[TMP20:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP3]], i64 0, i64 2, !dbg [[DBG176]] +// CHECK5-NEXT: [[TMP21:%.*]] = load i8*, i8** [[TMP20]], align 8, !dbg [[DBG176]] +// CHECK5-NEXT: [[TMP22:%.*]] = bitcast i8* [[TMP21]] to i32*, !dbg [[DBG176]] +// CHECK5-NEXT: [[TMP23:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP5]], i64 0, i64 2, !dbg [[DBG176]] +// CHECK5-NEXT: [[TMP24:%.*]] = load i8*, i8** [[TMP23]], align 8, !dbg [[DBG176]] +// CHECK5-NEXT: [[TMP25:%.*]] = bitcast i8* [[TMP24]] to i32*, !dbg [[DBG176]] +// CHECK5-NEXT: [[TMP26:%.*]] = load i32, i32* [[TMP25]], align 4, !dbg [[DBG179:![0-9]+]] +// CHECK5-NEXT: store i32 [[TMP26]], i32* [[TMP22]], align 4, !dbg [[DBG179]] +// CHECK5-NEXT: ret void, !dbg [[DBG179]] // // // CHECK5-LABEL: define {{[^@]+}}@_Z15parallel_singlev -// CHECK5-SAME: () #[[ATTR10]] !dbg [[DBG176:![0-9]+]] { +// CHECK5-SAME: () #[[ATTR10]] !dbg [[DBG180:![0-9]+]] { // CHECK5-NEXT: entry: -// CHECK5-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB35:[0-9]+]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined..12 to void (i32*, i32*, ...)*)), !dbg [[DBG177:![0-9]+]] -// CHECK5-NEXT: ret void, !dbg [[DBG178:![0-9]+]] +// CHECK5-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB35:[0-9]+]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined..12 to void (i32*, i32*, ...)*)), !dbg [[DBG181:![0-9]+]] +// CHECK5-NEXT: ret void, !dbg [[DBG182:![0-9]+]] // // // CHECK5-LABEL: define {{[^@]+}}@.omp_outlined..12 -// CHECK5-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]]) #[[ATTR12]] personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) !dbg [[DBG179:![0-9]+]] { +// CHECK5-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]]) #[[ATTR12]] personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) !dbg [[DBG183:![0-9]+]] { // CHECK5-NEXT: entry: // CHECK5-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK5-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 +// CHECK5-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// CHECK5-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // CHECK5-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK5-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 -// CHECK5-NEXT: [[TMP0:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG180:![0-9]+]] -// CHECK5-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4, !dbg [[DBG180]] -// CHECK5-NEXT: [[TMP2:%.*]] = call i32 @__kmpc_single(%struct.ident_t* @[[GLOB32:[0-9]+]], i32 [[TMP1]]), !dbg [[DBG180]] -// CHECK5-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0, !dbg [[DBG180]] -// CHECK5-NEXT: br i1 [[TMP3]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_END:%.*]], !dbg [[DBG180]] +// CHECK5-NEXT: [[TMP0:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG184:![0-9]+]] +// CHECK5-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4, !dbg [[DBG184]] +// CHECK5-NEXT: [[TMP2:%.*]] = call i32 @__kmpc_single(%struct.ident_t* @[[GLOB32:[0-9]+]], i32 [[TMP1]]), !dbg [[DBG184]] +// CHECK5-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0, !dbg [[DBG184]] +// CHECK5-NEXT: br i1 [[TMP3]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_END:%.*]], !dbg [[DBG184]] // CHECK5: omp_if.then: // CHECK5-NEXT: invoke void @_Z3foov() -// CHECK5-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]], !dbg [[DBG181:![0-9]+]] +// CHECK5-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]], !dbg [[DBG185:![0-9]+]] // CHECK5: invoke.cont: -// CHECK5-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB32]], i32 [[TMP1]]), !dbg [[DBG181]] -// CHECK5-NEXT: br label [[OMP_IF_END]], !dbg [[DBG181]] -// CHECK5: omp_if.end: -// CHECK5-NEXT: call void @__kmpc_barrier(%struct.ident_t* @[[GLOB33:[0-9]+]], i32 [[TMP1]]), !dbg [[DBG182:![0-9]+]] -// CHECK5-NEXT: ret void, !dbg [[DBG182]] -// CHECK5: terminate.lpad: +// CHECK5-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB32]], i32 [[TMP1]]), !dbg [[DBG185]] +// CHECK5-NEXT: br label [[OMP_IF_END]], !dbg [[DBG185]] +// CHECK5: lpad: // CHECK5-NEXT: [[TMP4:%.*]] = landingpad { i8*, i32 } -// CHECK5-NEXT: catch i8* null, !dbg [[DBG181]] -// CHECK5-NEXT: [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 0, !dbg [[DBG181]] -// CHECK5-NEXT: call void @__clang_call_terminate(i8* [[TMP5]]) #[[ATTR13]], !dbg [[DBG181]] -// CHECK5-NEXT: unreachable, !dbg [[DBG181]] +// CHECK5-NEXT: catch i8* null, !dbg [[DBG186:![0-9]+]] +// CHECK5-NEXT: [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 0, !dbg [[DBG186]] +// CHECK5-NEXT: store i8* [[TMP5]], i8** [[EXN_SLOT]], align 8, !dbg [[DBG186]] +// CHECK5-NEXT: [[TMP6:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 1, !dbg [[DBG186]] +// CHECK5-NEXT: store i32 [[TMP6]], i32* [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG186]] +// CHECK5-NEXT: call void @__kmpc_end_single(%struct.ident_t* @[[GLOB32]], i32 [[TMP1]]), !dbg [[DBG185]] +// CHECK5-NEXT: br label [[TERMINATE_HANDLER:%.*]], !dbg [[DBG185]] +// CHECK5: omp_if.end: +// CHECK5-NEXT: call void @__kmpc_barrier(%struct.ident_t* @[[GLOB33:[0-9]+]], i32 [[TMP1]]), !dbg [[DBG187:![0-9]+]] +// CHECK5-NEXT: ret void, !dbg [[DBG187]] +// CHECK5: terminate.handler: +// CHECK5-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8, !dbg [[DBG185]] +// CHECK5-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR13]], !dbg [[DBG185]] +// CHECK5-NEXT: unreachable, !dbg [[DBG185]] // // // CHECK5-LABEL: define {{[^@]+}}@_GLOBAL__sub_I_single_codegen.cpp -// CHECK5-SAME: () #[[ATTR0]] section "__TEXT,__StaticInit,regular,pure_instructions" !dbg [[DBG183:![0-9]+]] { +// CHECK5-SAME: () #[[ATTR0]] section "__TEXT,__StaticInit,regular,pure_instructions" !dbg [[DBG188:![0-9]+]] { // CHECK5-NEXT: entry: -// CHECK5-NEXT: call void @__cxx_global_var_init(), !dbg [[DBG184:![0-9]+]] -// CHECK5-NEXT: call void @__cxx_global_var_init.4(), !dbg [[DBG184]] -// CHECK5-NEXT: call void @.__omp_threadprivate_init_.(), !dbg [[DBG184]] -// CHECK5-NEXT: call void @.__omp_threadprivate_init_..3(), !dbg [[DBG184]] +// CHECK5-NEXT: call void @__cxx_global_var_init(), !dbg [[DBG189:![0-9]+]] +// CHECK5-NEXT: call void @__cxx_global_var_init.4(), !dbg [[DBG189]] +// CHECK5-NEXT: call void @.__omp_threadprivate_init_.(), !dbg [[DBG189]] +// CHECK5-NEXT: call void @.__omp_threadprivate_init_..3(), !dbg [[DBG189]] // CHECK5-NEXT: ret void // // diff --git a/clang/test/OpenMP/taskgroup_codegen.cpp b/clang/test/OpenMP/taskgroup_codegen.cpp index df384aecf004be..10deda2812f980 100644 --- a/clang/test/OpenMP/taskgroup_codegen.cpp +++ b/clang/test/OpenMP/taskgroup_codegen.cpp @@ -41,6 +41,8 @@ void parallel_taskgroup() { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[A:%.*]] = alloca i8, align 1 +// CHECK1-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// CHECK1-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // 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]]) @@ -48,17 +50,24 @@ void parallel_taskgroup() { // 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-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[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: 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: store i8* [[TMP3]], i8** [[EXN_SLOT]], align 8 +// CHECK1-NEXT: [[TMP4:%.*]] = extractvalue { i8*, i32 } [[TMP2]], 1 +// CHECK1-NEXT: store i32 [[TMP4]], i32* [[EHSELECTOR_SLOT]], align 4 +// CHECK1-NEXT: call void @__kmpc_end_taskgroup(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]]) +// CHECK1-NEXT: br label [[TERMINATE_HANDLER:%.*]] +// CHECK1: terminate.handler: +// CHECK1-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8 +// CHECK1-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR8:[0-9]+]] // CHECK1-NEXT: unreachable // // @@ -81,21 +90,30 @@ void parallel_taskgroup() { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 +// CHECK1-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// CHECK1-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // 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-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[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: 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: store i8* [[TMP3]], i8** [[EXN_SLOT]], align 8 +// CHECK1-NEXT: [[TMP4:%.*]] = extractvalue { i8*, i32 } [[TMP2]], 1 +// CHECK1-NEXT: store i32 [[TMP4]], i32* [[EHSELECTOR_SLOT]], align 4 +// CHECK1-NEXT: call void @__kmpc_end_taskgroup(%struct.ident_t* @[[GLOB1]], i32 [[TMP1]]) +// CHECK1-NEXT: br label [[TERMINATE_HANDLER:%.*]] +// CHECK1: terminate.handler: +// CHECK1-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8 +// CHECK1-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR8]] // CHECK1-NEXT: unreachable // // @@ -111,6 +129,8 @@ void parallel_taskgroup() { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 // CHECK2-NEXT: [[A:%.*]] = alloca i8, align 1 +// CHECK2-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// CHECK2-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // 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]]) @@ -118,17 +138,24 @@ void parallel_taskgroup() { // 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-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[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: 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: store i8* [[TMP3]], i8** [[EXN_SLOT]], align 8 +// CHECK2-NEXT: [[TMP4:%.*]] = extractvalue { i8*, i32 } [[TMP2]], 1 +// CHECK2-NEXT: store i32 [[TMP4]], i32* [[EHSELECTOR_SLOT]], align 4 +// CHECK2-NEXT: call void @__kmpc_end_taskgroup(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]]) +// CHECK2-NEXT: br label [[TERMINATE_HANDLER:%.*]] +// CHECK2: terminate.handler: +// CHECK2-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8 +// CHECK2-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR8:[0-9]+]] // CHECK2-NEXT: unreachable // // @@ -151,21 +178,30 @@ void parallel_taskgroup() { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK2-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 +// CHECK2-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// CHECK2-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // 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-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[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: 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: store i8* [[TMP3]], i8** [[EXN_SLOT]], align 8 +// CHECK2-NEXT: [[TMP4:%.*]] = extractvalue { i8*, i32 } [[TMP2]], 1 +// CHECK2-NEXT: store i32 [[TMP4]], i32* [[EHSELECTOR_SLOT]], align 4 +// CHECK2-NEXT: call void @__kmpc_end_taskgroup(%struct.ident_t* @[[GLOB1]], i32 [[TMP1]]) +// CHECK2-NEXT: br label [[TERMINATE_HANDLER:%.*]] +// CHECK2: terminate.handler: +// CHECK2-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8 +// CHECK2-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR8]] // CHECK2-NEXT: unreachable // // @@ -181,6 +217,8 @@ void parallel_taskgroup() { // DEBUG1-NEXT: entry: // DEBUG1-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 // DEBUG1-NEXT: [[A:%.*]] = alloca i8, align 1 +// DEBUG1-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// DEBUG1-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // 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]+]] @@ -188,17 +226,24 @@ void parallel_taskgroup() { // 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-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[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: 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: catch i8* null, !dbg [[DBG20:![0-9]+]] +// DEBUG1-NEXT: [[TMP3:%.*]] = extractvalue { i8*, i32 } [[TMP2]], 0, !dbg [[DBG20]] +// DEBUG1-NEXT: store i8* [[TMP3]], i8** [[EXN_SLOT]], align 8, !dbg [[DBG20]] +// DEBUG1-NEXT: [[TMP4:%.*]] = extractvalue { i8*, i32 } [[TMP2]], 1, !dbg [[DBG20]] +// DEBUG1-NEXT: store i32 [[TMP4]], i32* [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG20]] +// DEBUG1-NEXT: call void @__kmpc_end_taskgroup(%struct.ident_t* @[[GLOB3]], i32 [[TMP0]]), !dbg [[DBG17]] +// DEBUG1-NEXT: br label [[TERMINATE_HANDLER:%.*]], !dbg [[DBG17]] +// DEBUG1: terminate.handler: +// DEBUG1-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8, !dbg [[DBG17]] +// DEBUG1-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR8:[0-9]+]], !dbg [[DBG17]] // DEBUG1-NEXT: unreachable, !dbg [[DBG17]] // // @@ -210,31 +255,40 @@ void parallel_taskgroup() { // // // DEBUG1-LABEL: define {{[^@]+}}@_Z18parallel_taskgroupv -// DEBUG1-SAME: () #[[ATTR6:[0-9]+]] !dbg [[DBG20:![0-9]+]] { +// DEBUG1-SAME: () #[[ATTR6:[0-9]+]] !dbg [[DBG21:![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-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 [[DBG22:![0-9]+]] +// DEBUG1-NEXT: ret void, !dbg [[DBG23:![0-9]+]] // // // DEBUG1-LABEL: define {{[^@]+}}@.omp_outlined. -// DEBUG1-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]]) #[[ATTR7:[0-9]+]] personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) !dbg [[DBG23:![0-9]+]] { +// DEBUG1-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[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: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// DEBUG1-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // 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: [[TMP0:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG25:![0-9]+]] +// DEBUG1-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4, !dbg [[DBG25]] +// DEBUG1-NEXT: call void @__kmpc_taskgroup(%struct.ident_t* @[[GLOB5:[0-9]+]], i32 [[TMP1]]), !dbg [[DBG25]] // DEBUG1-NEXT: invoke void @_Z3foov() -// DEBUG1-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]], !dbg [[DBG25:![0-9]+]] +// DEBUG1-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]], !dbg [[DBG26:![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: call void @__kmpc_end_taskgroup(%struct.ident_t* @[[GLOB5]], i32 [[TMP1]]), !dbg [[DBG26]] +// DEBUG1-NEXT: ret void, !dbg [[DBG27:![0-9]+]] +// DEBUG1: 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]] +// DEBUG1-NEXT: catch i8* null, !dbg [[DBG28:![0-9]+]] +// DEBUG1-NEXT: [[TMP3:%.*]] = extractvalue { i8*, i32 } [[TMP2]], 0, !dbg [[DBG28]] +// DEBUG1-NEXT: store i8* [[TMP3]], i8** [[EXN_SLOT]], align 8, !dbg [[DBG28]] +// DEBUG1-NEXT: [[TMP4:%.*]] = extractvalue { i8*, i32 } [[TMP2]], 1, !dbg [[DBG28]] +// DEBUG1-NEXT: store i32 [[TMP4]], i32* [[EHSELECTOR_SLOT]], align 4, !dbg [[DBG28]] +// DEBUG1-NEXT: call void @__kmpc_end_taskgroup(%struct.ident_t* @[[GLOB5]], i32 [[TMP1]]), !dbg [[DBG26]] +// DEBUG1-NEXT: br label [[TERMINATE_HANDLER:%.*]], !dbg [[DBG26]] +// DEBUG1: terminate.handler: +// DEBUG1-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8, !dbg [[DBG26]] +// DEBUG1-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR8]], !dbg [[DBG26]] +// DEBUG1-NEXT: unreachable, !dbg [[DBG26]] // diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_num_threads_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_num_threads_codegen.cpp index 171264558f6089..0e06a7cfa11634 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_num_threads_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_num_threads_codegen.cpp @@ -1044,9 +1044,11 @@ int main() { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 // CHECK1-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_S:%.*]], align 8 +// CHECK1-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// CHECK1-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 // CHECK1-NEXT: invoke void @_ZN1SC1El(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]], i64 23) -// CHECK1-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]] +// CHECK1-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] // CHECK1: invoke.cont: // CHECK1-NEXT: [[CALL:%.*]] = call signext i8 @_ZN1ScvcEv(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]]) // CHECK1-NEXT: call void @_ZN1SD1Ev(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]]) #[[ATTR6]] @@ -1057,11 +1059,17 @@ int main() { // CHECK1-NEXT: [[TMP1:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED]], align 8 // CHECK1-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%struct.ident_t* @[[GLOB3]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i64)* @.omp_outlined..10 to void (i32*, i32*, ...)*), i64 [[TMP1]]) // CHECK1-NEXT: ret void -// CHECK1: terminate.lpad: +// CHECK1: 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]]) #[[ATTR9]] +// CHECK1-NEXT: store i8* [[TMP3]], i8** [[EXN_SLOT]], align 8 +// CHECK1-NEXT: [[TMP4:%.*]] = extractvalue { i8*, i32 } [[TMP2]], 1 +// CHECK1-NEXT: store i32 [[TMP4]], i32* [[EHSELECTOR_SLOT]], align 4 +// CHECK1-NEXT: br label [[TERMINATE_HANDLER:%.*]] +// CHECK1: terminate.handler: +// CHECK1-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8 +// CHECK1-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR9]] // CHECK1-NEXT: unreachable // // @@ -2188,9 +2196,11 @@ int main() { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 // CHECK2-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_S:%.*]], align 8 +// CHECK2-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// CHECK2-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // CHECK2-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 // CHECK2-NEXT: invoke void @_ZN1SC1El(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]], i64 23) -// CHECK2-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]] +// CHECK2-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] // CHECK2: invoke.cont: // CHECK2-NEXT: [[CALL:%.*]] = call signext i8 @_ZN1ScvcEv(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]]) // CHECK2-NEXT: call void @_ZN1SD1Ev(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]]) #[[ATTR6]] @@ -2201,11 +2211,17 @@ int main() { // CHECK2-NEXT: [[TMP1:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED]], align 8 // CHECK2-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%struct.ident_t* @[[GLOB3]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i64)* @.omp_outlined..10 to void (i32*, i32*, ...)*), i64 [[TMP1]]) // CHECK2-NEXT: ret void -// CHECK2: terminate.lpad: +// CHECK2: 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]]) #[[ATTR9]] +// CHECK2-NEXT: store i8* [[TMP3]], i8** [[EXN_SLOT]], align 8 +// CHECK2-NEXT: [[TMP4:%.*]] = extractvalue { i8*, i32 } [[TMP2]], 1 +// CHECK2-NEXT: store i32 [[TMP4]], i32* [[EHSELECTOR_SLOT]], align 4 +// CHECK2-NEXT: br label [[TERMINATE_HANDLER:%.*]] +// CHECK2: terminate.handler: +// CHECK2-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8 +// CHECK2-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR9]] // CHECK2-NEXT: unreachable // // @@ -3323,9 +3339,11 @@ int main() { // CHECK5-NEXT: entry: // CHECK5-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 // CHECK5-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_S:%.*]], align 8 +// CHECK5-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// CHECK5-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // CHECK5-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 // CHECK5-NEXT: invoke void @_ZN1SC1El(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]], i64 23) -// CHECK5-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]] +// CHECK5-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] // CHECK5: invoke.cont: // CHECK5-NEXT: [[CALL:%.*]] = call signext i8 @_ZN1ScvcEv(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]]) // CHECK5-NEXT: call void @_ZN1SD1Ev(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]]) #[[ATTR6]] @@ -3336,11 +3354,17 @@ int main() { // CHECK5-NEXT: [[TMP1:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED]], align 8 // CHECK5-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%struct.ident_t* @[[GLOB3]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i64)* @.omp_outlined..10 to void (i32*, i32*, ...)*), i64 [[TMP1]]) // CHECK5-NEXT: ret void -// CHECK5: terminate.lpad: +// CHECK5: lpad: // CHECK5-NEXT: [[TMP2:%.*]] = landingpad { i8*, i32 } // CHECK5-NEXT: catch i8* null // CHECK5-NEXT: [[TMP3:%.*]] = extractvalue { i8*, i32 } [[TMP2]], 0 -// CHECK5-NEXT: call void @__clang_call_terminate(i8* [[TMP3]]) #[[ATTR9]] +// CHECK5-NEXT: store i8* [[TMP3]], i8** [[EXN_SLOT]], align 8 +// CHECK5-NEXT: [[TMP4:%.*]] = extractvalue { i8*, i32 } [[TMP2]], 1 +// CHECK5-NEXT: store i32 [[TMP4]], i32* [[EHSELECTOR_SLOT]], align 4 +// CHECK5-NEXT: br label [[TERMINATE_HANDLER:%.*]] +// CHECK5: terminate.handler: +// CHECK5-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8 +// CHECK5-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR9]] // CHECK5-NEXT: unreachable // // @@ -4467,9 +4491,11 @@ int main() { // CHECK6-NEXT: entry: // CHECK6-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 // CHECK6-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_S:%.*]], align 8 +// CHECK6-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// CHECK6-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // CHECK6-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 // CHECK6-NEXT: invoke void @_ZN1SC1El(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]], i64 23) -// CHECK6-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]] +// CHECK6-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] // CHECK6: invoke.cont: // CHECK6-NEXT: [[CALL:%.*]] = call signext i8 @_ZN1ScvcEv(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]]) // CHECK6-NEXT: call void @_ZN1SD1Ev(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]]) #[[ATTR6]] @@ -4480,11 +4506,17 @@ int main() { // CHECK6-NEXT: [[TMP1:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED]], align 8 // CHECK6-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%struct.ident_t* @[[GLOB3]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i64)* @.omp_outlined..10 to void (i32*, i32*, ...)*), i64 [[TMP1]]) // CHECK6-NEXT: ret void -// CHECK6: terminate.lpad: +// CHECK6: lpad: // CHECK6-NEXT: [[TMP2:%.*]] = landingpad { i8*, i32 } // CHECK6-NEXT: catch i8* null // CHECK6-NEXT: [[TMP3:%.*]] = extractvalue { i8*, i32 } [[TMP2]], 0 -// CHECK6-NEXT: call void @__clang_call_terminate(i8* [[TMP3]]) #[[ATTR9]] +// CHECK6-NEXT: store i8* [[TMP3]], i8** [[EXN_SLOT]], align 8 +// CHECK6-NEXT: [[TMP4:%.*]] = extractvalue { i8*, i32 } [[TMP2]], 1 +// CHECK6-NEXT: store i32 [[TMP4]], i32* [[EHSELECTOR_SLOT]], align 4 +// CHECK6-NEXT: br label [[TERMINATE_HANDLER:%.*]] +// CHECK6: terminate.handler: +// CHECK6-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8 +// CHECK6-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR9]] // CHECK6-NEXT: unreachable // // diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_simd_num_threads_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_simd_num_threads_codegen.cpp index 4274d1e3d88050..59171d40b5d94e 100644 --- a/clang/test/OpenMP/teams_distribute_parallel_for_simd_num_threads_codegen.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_simd_num_threads_codegen.cpp @@ -1116,9 +1116,11 @@ int main() { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 // CHECK1-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_S:%.*]], align 8 +// CHECK1-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// CHECK1-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 // CHECK1-NEXT: invoke void @_ZN1SC1El(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]], i64 23) -// CHECK1-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]] +// CHECK1-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] // CHECK1: invoke.cont: // CHECK1-NEXT: [[CALL:%.*]] = call signext i8 @_ZN1ScvcEv(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]]) // CHECK1-NEXT: call void @_ZN1SD1Ev(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]]) #[[ATTR6]] @@ -1129,11 +1131,17 @@ int main() { // CHECK1-NEXT: [[TMP1:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED]], align 8 // CHECK1-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%struct.ident_t* @[[GLOB3]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i64)* @.omp_outlined..10 to void (i32*, i32*, ...)*), i64 [[TMP1]]) // CHECK1-NEXT: ret void -// CHECK1: terminate.lpad: +// CHECK1: 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]]) #[[ATTR9]] +// CHECK1-NEXT: store i8* [[TMP3]], i8** [[EXN_SLOT]], align 8 +// CHECK1-NEXT: [[TMP4:%.*]] = extractvalue { i8*, i32 } [[TMP2]], 1 +// CHECK1-NEXT: store i32 [[TMP4]], i32* [[EHSELECTOR_SLOT]], align 4 +// CHECK1-NEXT: br label [[TERMINATE_HANDLER:%.*]] +// CHECK1: terminate.handler: +// CHECK1-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8 +// CHECK1-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR9]] // CHECK1-NEXT: unreachable // // @@ -2344,9 +2352,11 @@ int main() { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 // CHECK2-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_S:%.*]], align 8 +// CHECK2-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// CHECK2-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // CHECK2-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 // CHECK2-NEXT: invoke void @_ZN1SC1El(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]], i64 23) -// CHECK2-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]] +// CHECK2-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] // CHECK2: invoke.cont: // CHECK2-NEXT: [[CALL:%.*]] = call signext i8 @_ZN1ScvcEv(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]]) // CHECK2-NEXT: call void @_ZN1SD1Ev(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]]) #[[ATTR6]] @@ -2357,11 +2367,17 @@ int main() { // CHECK2-NEXT: [[TMP1:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED]], align 8 // CHECK2-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%struct.ident_t* @[[GLOB3]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i64)* @.omp_outlined..10 to void (i32*, i32*, ...)*), i64 [[TMP1]]) // CHECK2-NEXT: ret void -// CHECK2: terminate.lpad: +// CHECK2: 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]]) #[[ATTR9]] +// CHECK2-NEXT: store i8* [[TMP3]], i8** [[EXN_SLOT]], align 8 +// CHECK2-NEXT: [[TMP4:%.*]] = extractvalue { i8*, i32 } [[TMP2]], 1 +// CHECK2-NEXT: store i32 [[TMP4]], i32* [[EHSELECTOR_SLOT]], align 4 +// CHECK2-NEXT: br label [[TERMINATE_HANDLER:%.*]] +// CHECK2: terminate.handler: +// CHECK2-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8 +// CHECK2-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR9]] // CHECK2-NEXT: unreachable // // @@ -4261,9 +4277,11 @@ int main() { // CHECK5-NEXT: entry: // CHECK5-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 // CHECK5-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_S:%.*]], align 8 +// CHECK5-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// CHECK5-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // CHECK5-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 // CHECK5-NEXT: invoke void @_ZN1SC1El(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]], i64 23) -// CHECK5-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]] +// CHECK5-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] // CHECK5: invoke.cont: // CHECK5-NEXT: [[CALL:%.*]] = call signext i8 @_ZN1ScvcEv(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]]) // CHECK5-NEXT: call void @_ZN1SD1Ev(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]]) #[[ATTR6]] @@ -4274,11 +4292,17 @@ int main() { // CHECK5-NEXT: [[TMP1:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED]], align 8 // CHECK5-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%struct.ident_t* @[[GLOB3]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i64)* @.omp_outlined..10 to void (i32*, i32*, ...)*), i64 [[TMP1]]) // CHECK5-NEXT: ret void -// CHECK5: terminate.lpad: +// CHECK5: lpad: // CHECK5-NEXT: [[TMP2:%.*]] = landingpad { i8*, i32 } // CHECK5-NEXT: catch i8* null // CHECK5-NEXT: [[TMP3:%.*]] = extractvalue { i8*, i32 } [[TMP2]], 0 -// CHECK5-NEXT: call void @__clang_call_terminate(i8* [[TMP3]]) #[[ATTR9]] +// CHECK5-NEXT: store i8* [[TMP3]], i8** [[EXN_SLOT]], align 8 +// CHECK5-NEXT: [[TMP4:%.*]] = extractvalue { i8*, i32 } [[TMP2]], 1 +// CHECK5-NEXT: store i32 [[TMP4]], i32* [[EHSELECTOR_SLOT]], align 4 +// CHECK5-NEXT: br label [[TERMINATE_HANDLER:%.*]] +// CHECK5: terminate.handler: +// CHECK5-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8 +// CHECK5-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR9]] // CHECK5-NEXT: unreachable // // @@ -5489,9 +5513,11 @@ int main() { // CHECK6-NEXT: entry: // CHECK6-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 // CHECK6-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_S:%.*]], align 8 +// CHECK6-NEXT: [[EXN_SLOT:%.*]] = alloca i8*, align 8 +// CHECK6-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 // CHECK6-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 // CHECK6-NEXT: invoke void @_ZN1SC1El(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]], i64 23) -// CHECK6-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]] +// CHECK6-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] // CHECK6: invoke.cont: // CHECK6-NEXT: [[CALL:%.*]] = call signext i8 @_ZN1ScvcEv(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]]) // CHECK6-NEXT: call void @_ZN1SD1Ev(%struct.S* nonnull align 8 dereferenceable(24) [[REF_TMP]]) #[[ATTR6]] @@ -5502,11 +5528,17 @@ int main() { // CHECK6-NEXT: [[TMP1:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED]], align 8 // CHECK6-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_teams(%struct.ident_t* @[[GLOB3]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i64)* @.omp_outlined..10 to void (i32*, i32*, ...)*), i64 [[TMP1]]) // CHECK6-NEXT: ret void -// CHECK6: terminate.lpad: +// CHECK6: lpad: // CHECK6-NEXT: [[TMP2:%.*]] = landingpad { i8*, i32 } // CHECK6-NEXT: catch i8* null // CHECK6-NEXT: [[TMP3:%.*]] = extractvalue { i8*, i32 } [[TMP2]], 0 -// CHECK6-NEXT: call void @__clang_call_terminate(i8* [[TMP3]]) #[[ATTR9]] +// CHECK6-NEXT: store i8* [[TMP3]], i8** [[EXN_SLOT]], align 8 +// CHECK6-NEXT: [[TMP4:%.*]] = extractvalue { i8*, i32 } [[TMP2]], 1 +// CHECK6-NEXT: store i32 [[TMP4]], i32* [[EHSELECTOR_SLOT]], align 4 +// CHECK6-NEXT: br label [[TERMINATE_HANDLER:%.*]] +// CHECK6: terminate.handler: +// CHECK6-NEXT: [[EXN:%.*]] = load i8*, i8** [[EXN_SLOT]], align 8 +// CHECK6-NEXT: call void @__clang_call_terminate(i8* [[EXN]]) #[[ATTR9]] // CHECK6-NEXT: unreachable // //