llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-codegen Author: David Pagan (ddpagan) <details> <summary>Changes</summary> Added codegen for scope directive, enabled allocate and firstprivate clauses, and added scope directive LIT test. Testing - LIT tests (including new scope test). - OpenMP scope example test from 5.2 OpenMP API examples document. - Three executable scope tests from OpenMP_VV/sollve_vv suite. --- Patch is 160.18 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/109197.diff 6 Files Affected: - (modified) clang/lib/CodeGen/CGStmt.cpp (+1-1) - (modified) clang/lib/CodeGen/CGStmtOpenMP.cpp (+26) - (modified) clang/lib/CodeGen/CodeGenFunction.h (+1) - (removed) clang/test/OpenMP/error_unsupport_feature.c (-8) - (added) clang/test/OpenMP/scope_codegen.cpp (+2267) - (modified) llvm/include/llvm/Frontend/OpenMP/OMP.td (+2) ``````````diff diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index b138c87a853495..27cf3de531d8a4 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -420,7 +420,7 @@ void CodeGenFunction::EmitStmt(const Stmt *S, ArrayRef<const Attr *> Attrs) { CGM.ErrorUnsupported(S, "OpenMP dispatch directive"); break; case Stmt::OMPScopeDirectiveClass: - CGM.ErrorUnsupported(S, "scope with FE outlining"); + EmitOMPScopeDirective(cast<OMPScopeDirective>(*S)); break; case Stmt::OMPMaskedDirectiveClass: EmitOMPMaskedDirective(cast<OMPMaskedDirective>(*S)); diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp index 8afe2abf2cc494..b11df8334766a8 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -4223,6 +4223,32 @@ void CodeGenFunction::EmitSections(const OMPExecutableDirective &S) { } } +void CodeGenFunction::EmitOMPScopeDirective(const OMPScopeDirective &S) { + { + // Emit code for 'scope' region + auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { + Action.Enter(CGF); + OMPPrivateScope PrivateScope(CGF); + (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope); + CGF.EmitOMPPrivateClause(S, PrivateScope); + CGF.EmitOMPReductionClauseInit(S, PrivateScope); + (void)PrivateScope.Privatize(); + CGF.EmitStmt(S.getInnermostCapturedStmt()->getCapturedStmt()); + CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_parallel); + }; + auto LPCRegion = + CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S); + OMPLexicalScope Scope(*this, S, OMPD_unknown); + CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_scope, CodeGen); + } + // Emit an implicit barrier at the end. + if (!S.getSingleClause<OMPNowaitClause>()) { + CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getBeginLoc(), OMPD_scope); + } + // Check for outer lastprivate conditional update. + checkForLastprivateConditionalUpdate(*this, S); +} + void CodeGenFunction::EmitOMPSectionsDirective(const OMPSectionsDirective &S) { if (CGM.getLangOpts().OpenMPIRBuilder) { llvm::OpenMPIRBuilder &OMPBuilder = CGM.getOpenMPRuntime().getOMPBuilder(); diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 6802dc7f0c1598..2df17e83bae2ee 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -3823,6 +3823,7 @@ class CodeGenFunction : public CodeGenTypeCache { void EmitOMPInterchangeDirective(const OMPInterchangeDirective &S); void EmitOMPForDirective(const OMPForDirective &S); void EmitOMPForSimdDirective(const OMPForSimdDirective &S); + void EmitOMPScopeDirective(const OMPScopeDirective &S); void EmitOMPSectionsDirective(const OMPSectionsDirective &S); void EmitOMPSectionDirective(const OMPSectionDirective &S); void EmitOMPSingleDirective(const OMPSingleDirective &S); diff --git a/clang/test/OpenMP/error_unsupport_feature.c b/clang/test/OpenMP/error_unsupport_feature.c deleted file mode 100644 index eb381b3bea1e1a..00000000000000 --- a/clang/test/OpenMP/error_unsupport_feature.c +++ /dev/null @@ -1,8 +0,0 @@ -// RUN: %clang_cc1 -emit-llvm-only -verify -fopenmp %s - -int main () { - int r = 0; -#pragma omp scope reduction(+:r) // expected-error {{cannot compile this scope with FE outlining yet}} - r++; - return r; -} diff --git a/clang/test/OpenMP/scope_codegen.cpp b/clang/test/OpenMP/scope_codegen.cpp new file mode 100644 index 00000000000000..ef69b8302fa2de --- /dev/null +++ b/clang/test/OpenMP/scope_codegen.cpp @@ -0,0 +1,2267 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --function-signature --include-generated-funcs --replace-value-regex "__omp_offloading_[0-9a-z]+_[0-9a-z]+" "reduction_size[.].+[.]" "pl_cond[.].+[.|,]" --prefix-filecheck-ir-name _ +// RUN: %clang_cc1 -verify -Wno-vla -fopenmp -fopenmp-version=52 -fnoopenmp-use-tls -x c++ -std=c++11 -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s --check-prefix=CHECK1 + +// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -fnoopenmp-use-tls -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -fnoopenmp-use-tls -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify -Wno-vla %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK1 + +// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -fnoopenmp-use-tls -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -fnoopenmp-use-tls -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify -Wno-vla %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK4 + +// RUN: %clang_cc1 -verify -Wno-vla -triple x86_64-apple-darwin10 -std=c++11 -fopenmp -fopenmp-version=52 -fnoopenmp-use-tls -fexceptions -fcxx-exceptions -debug-info-kind=line-tables-only -x c++ -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK5 +// RUN: %clang_cc1 -verify -Wno-vla -fopenmp -fopenmp-version=52 -fnoopenmp-use-tls -x c++ -std=c++11 -DARRAY -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK6 + +// RUN: %clang_cc1 -verify -Wno-vla -fopenmp-simd -fopenmp-version=52 -fnoopenmp-use-tls -x c++ -std=c++11 -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s --implicit-check-not="{{__kmpc|__tgt}}" +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -fnoopenmp-use-tls -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -fnoopenmp-use-tls -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --implicit-check-not="{{__kmpc|__tgt}}" +// RUN: %clang_cc1 -verify -Wno-vla -triple x86_64-apple-darwin10 -std=c++11 -fopenmp-simd -fopenmp-version=52 -fnoopenmp-use-tls -fexceptions -fcxx-exceptions -debug-info-kind=line-tables-only -x c++ -emit-llvm %s -o - | FileCheck %s --implicit-check-not="{{__kmpc|__tgt}}" +// RUN: %clang_cc1 -verify -Wno-vla -fopenmp-simd -fopenmp-version=52 -fnoopenmp-use-tls -x c++ -std=c++11 -DARRAY -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s --implicit-check-not="{{__kmpc|__tgt}}" +// expected-no-diagnostics + +typedef void **omp_allocator_handle_t; +extern const omp_allocator_handle_t omp_null_allocator; +extern const omp_allocator_handle_t omp_default_mem_alloc; +extern const omp_allocator_handle_t omp_large_cap_mem_alloc; +extern const omp_allocator_handle_t omp_const_mem_alloc; +extern const omp_allocator_handle_t omp_high_bw_mem_alloc; +extern const omp_allocator_handle_t omp_low_lat_mem_alloc; +extern const omp_allocator_handle_t omp_cgroup_mem_alloc; +extern const omp_allocator_handle_t omp_pteam_mem_alloc; +extern const omp_allocator_handle_t omp_thread_mem_alloc; + +#ifndef ARRAY +#ifndef HEADER +#define HEADER + +class TestClass { +public: + int a; + TestClass() : a(0) {} + TestClass(const TestClass &C) : a(C.a) {} + TestClass &operator=(const TestClass &) { return *this;} + ~TestClass(){}; +}; + + +TestClass tc; +TestClass tc2[2]; + +void foo() { extern void mayThrow(); mayThrow(); } + +struct SS { + int e; + int a; + int b : 4; + int &c; + SS(int &d) : a(0), b(0), c(d) { +#pragma omp scope private(a, this->b, (this)->c) allocate(omp_default_mem_alloc:b) nowait + [&]() { + ++this->a, --b, (this)->c /= 1; +#pragma omp parallel num_threads(b) +#pragma omp scope firstprivate(a, this->b, (this)->c) reduction(+:e) + ++(this)->a, e+=1, this->c /= 1; + }(); + } +}; + +template<typename T> +struct SST { + T a; + SST() : a(T()) { +#pragma omp target teams +#pragma omp parallel firstprivate(a) +#pragma omp scope private(this->a) + [&]() { + [&]() { + int c; + ++this->a; +#pragma omp parallel firstprivate(a) +#pragma omp scope private((this)->a) allocate(omp_cgroup_mem_alloc:a) + ++(this)->a; + }(); + }(); + } +}; + +int main() { + char a; + char a2[2]; + TestClass &c = tc; + SST<double> sst; + SS ss(c.a); + +#pragma omp scope nowait + a = 2; +#pragma omp scope + a = 2; +#pragma omp scope firstprivate(a,c, tc) private(a2, tc2) + foo(); + return a; +} + + +void parallel_single() { +#pragma omp parallel +#pragma omp scope + foo(); +} +#endif +#else +struct St { + int a, b; + St() : a(0), b(0) {} + St &operator=(const St &) { return *this; }; + ~St() {} +}; + +void array_func(int n, int a[n], St s[2]) { + int b,c; +#pragma omp scope nowait firstprivate(b) allocate(omp_high_bw_mem_alloc:c) private(a,s) reduction(*:c) + ; +} + +int main() { + int n; + int a[10]; + St s[2]; + + array_func(n, a, s); + return 0; +} +#endif +// CHECK1-LABEL: define {{[^@]+}}@__cxx_global_var_init +// CHECK1-SAME: () #[[ATTR0:[0-9]+]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: call void @_ZN9TestClassC1Ev(ptr noundef nonnull align 4 dereferenceable(4) @tc) +// CHECK1-NEXT: [[TMP0:%.*]] = call i32 @__cxa_atexit(ptr @_ZN9TestClassD1Ev, ptr @tc, ptr @__dso_handle) #[[ATTR3:[0-9]+]] +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@_ZN9TestClassC1Ev +// CHECK1-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR1:[0-9]+]] comdat align 2 { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 +// CHECK1-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// CHECK1-NEXT: call void @_ZN9TestClassC2Ev(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]]) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@_ZN9TestClassD1Ev +// CHECK1-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR2:[0-9]+]] comdat align 2 { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 +// CHECK1-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// CHECK1-NEXT: call void @_ZN9TestClassD2Ev(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]]) #[[ATTR3]] +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@_ZN9TestClassC2Ev +// CHECK1-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 +// CHECK1-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// CHECK1-NEXT: [[A:%.*]] = getelementptr inbounds nuw [[CLASS_TESTCLASS:%.*]], ptr [[THIS1]], i32 0, i32 0 +// CHECK1-NEXT: store i32 0, ptr [[A]], align 4 +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@_ZN9TestClassD2Ev +// CHECK1-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] comdat align 2 { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 +// CHECK1-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@__cxx_global_var_init.1 +// CHECK1-SAME: () #[[ATTR0]] personality ptr @__gxx_personality_v0 { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[EXN_SLOT:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[EHSELECTOR_SLOT:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: br label [[ARRAYCTOR_LOOP:%.*]] +// CHECK1: arrayctor.loop: +// CHECK1-NEXT: [[ARRAYCTOR_CUR:%.*]] = phi ptr [ @tc2, [[ENTRY:%.*]] ], [ [[ARRAYCTOR_NEXT:%.*]], [[INVOKE_CONT:%.*]] ] +// CHECK1-NEXT: invoke void @_ZN9TestClassC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYCTOR_CUR]]) +// CHECK1-NEXT: to label [[INVOKE_CONT]] unwind label [[LPAD:%.*]] +// CHECK1: invoke.cont: +// CHECK1-NEXT: [[ARRAYCTOR_NEXT]] = getelementptr inbounds [[CLASS_TESTCLASS:%.*]], ptr [[ARRAYCTOR_CUR]], i64 1 +// CHECK1-NEXT: [[ARRAYCTOR_DONE:%.*]] = icmp eq ptr [[ARRAYCTOR_NEXT]], getelementptr inbounds ([[CLASS_TESTCLASS]], ptr @tc2, i64 2) +// CHECK1-NEXT: br i1 [[ARRAYCTOR_DONE]], label [[ARRAYCTOR_CONT:%.*]], label [[ARRAYCTOR_LOOP]] +// CHECK1: arrayctor.cont: +// CHECK1-NEXT: [[TMP0:%.*]] = call i32 @__cxa_atexit(ptr @__cxx_global_array_dtor, ptr null, ptr @__dso_handle) #[[ATTR3]] +// CHECK1-NEXT: ret void +// CHECK1: lpad: +// CHECK1-NEXT: [[TMP1:%.*]] = landingpad { ptr, i32 } +// CHECK1-NEXT: cleanup +// CHECK1-NEXT: [[TMP2:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 0 +// CHECK1-NEXT: store ptr [[TMP2]], ptr [[EXN_SLOT]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP1]], 1 +// CHECK1-NEXT: store i32 [[TMP3]], ptr [[EHSELECTOR_SLOT]], align 4 +// CHECK1-NEXT: [[ARRAYDESTROY_ISEMPTY:%.*]] = icmp eq ptr @tc2, [[ARRAYCTOR_CUR]] +// CHECK1-NEXT: br i1 [[ARRAYDESTROY_ISEMPTY]], label [[ARRAYDESTROY_DONE1:%.*]], label [[ARRAYDESTROY_BODY:%.*]] +// CHECK1: arraydestroy.body: +// CHECK1-NEXT: [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi ptr [ [[ARRAYCTOR_CUR]], [[LPAD]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ] +// CHECK1-NEXT: [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[CLASS_TESTCLASS]], ptr [[ARRAYDESTROY_ELEMENTPAST]], i64 -1 +// CHECK1-NEXT: call void @_ZN9TestClassD1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR3]] +// CHECK1-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT]], @tc2 +// CHECK1-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE1]], label [[ARRAYDESTROY_BODY]] +// CHECK1: arraydestroy.done1: +// CHECK1-NEXT: br label [[EH_RESUME:%.*]] +// CHECK1: eh.resume: +// CHECK1-NEXT: [[EXN:%.*]] = load ptr, ptr [[EXN_SLOT]], align 8 +// CHECK1-NEXT: [[SEL:%.*]] = load i32, ptr [[EHSELECTOR_SLOT]], align 4 +// CHECK1-NEXT: [[LPAD_VAL:%.*]] = insertvalue { ptr, i32 } poison, ptr [[EXN]], 0 +// CHECK1-NEXT: [[LPAD_VAL2:%.*]] = insertvalue { ptr, i32 } [[LPAD_VAL]], i32 [[SEL]], 1 +// CHECK1-NEXT: resume { ptr, i32 } [[LPAD_VAL2]] +// +// +// CHECK1-LABEL: define {{[^@]+}}@__cxx_global_array_dtor +// CHECK1-SAME: (ptr noundef [[TMP0:%.*]]) #[[ATTR0]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: store ptr [[TMP0]], ptr [[DOTADDR]], align 8 +// CHECK1-NEXT: br label [[ARRAYDESTROY_BODY:%.*]] +// CHECK1: arraydestroy.body: +// CHECK1-NEXT: [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi ptr [ getelementptr inbounds ([[CLASS_TESTCLASS:%.*]], ptr @tc2, i64 2), [[ENTRY:%.*]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ] +// CHECK1-NEXT: [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[CLASS_TESTCLASS]], ptr [[ARRAYDESTROY_ELEMENTPAST]], i64 -1 +// CHECK1-NEXT: call void @_ZN9TestClassD1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR3]] +// CHECK1-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT]], @tc2 +// CHECK1-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE1:%.*]], label [[ARRAYDESTROY_BODY]] +// CHECK1: arraydestroy.done1: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@_Z3foov +// CHECK1-SAME: () #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: call void @_Z8mayThrowv() +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@main +// CHECK1-SAME: () #[[ATTR5:[0-9]+]] personality ptr @__gxx_personality_v0 { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[A:%.*]] = alloca i8, align 1 +// CHECK1-NEXT: [[A2:%.*]] = alloca [2 x i8], align 1 +// CHECK1-NEXT: [[C:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[SST:%.*]] = alloca [[STRUCT_SST:%.*]], align 8 +// CHECK1-NEXT: [[SS:%.*]] = alloca [[STRUCT_SS:%.*]], align 8 +// CHECK1-NEXT: [[A1:%.*]] = alloca i8, align 1 +// CHECK1-NEXT: [[C2:%.*]] = alloca [[CLASS_TESTCLASS:%.*]], align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[TC:%.*]] = alloca [[CLASS_TESTCLASS]], align 4 +// CHECK1-NEXT: [[A24:%.*]] = alloca [2 x i8], align 1 +// CHECK1-NEXT: [[TC2:%.*]] = alloca [2 x %class.TestClass], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB2:[0-9]+]]) +// CHECK1-NEXT: store i32 0, ptr [[RETVAL]], align 4 +// CHECK1-NEXT: store ptr @tc, ptr [[C]], align 8 +// CHECK1-NEXT: call void @_ZN3SSTIdEC1Ev(ptr noundef nonnull align 8 dereferenceable(8) [[SST]]) +// CHECK1-NEXT: call void @_ZN2SSC1ERi(ptr noundef nonnull align 8 dereferenceable(24) [[SS]], ptr noundef nonnull align 4 dereferenceable(4) @tc) +// CHECK1-NEXT: store i8 2, ptr [[A]], align 1 +// CHECK1-NEXT: store i8 2, ptr [[A]], align 1 +// CHECK1-NEXT: call void @__kmpc_barrier(ptr @[[GLOB1:[0-9]+]], i32 [[TMP0]]) +// CHECK1-NEXT: [[TMP1:%.*]] = load i8, ptr [[A]], align 1 +// CHECK1-NEXT: store i8 [[TMP1]], ptr [[A1]], align 1 +// CHECK1-NEXT: invoke void @_ZN9TestClassC1ERKS_(ptr noundef nonnull align 4 dereferenceable(4) [[C2]], ptr noundef nonnull align 4 dereferenceable(4) @tc) +// CHECK1-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]] +// CHECK1: invoke.cont: +// CHECK1-NEXT: store ptr [[C2]], ptr [[TMP]], align 8 +// CHECK1-NEXT: invoke void @_ZN9TestClassC1ERKS_(ptr noundef nonnull align 4 dereferenceable(4) [[TC]], ptr noundef nonnull align 4 dereferenceable(4) @tc) +// CHECK1-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[TERMINATE_LPAD]] +// CHECK1: invoke.cont3: +// CHECK1-NEXT: [[ARRAY_BEGIN:%.*]] = getelementptr inbounds [2 x %class.TestClass], ptr [[TC2]], i32 0, i32 0 +// CHECK1-NEXT: [[ARRAYCTOR_END:%.*]] = getelementptr inbounds [[CLASS_TESTCLASS]], ptr [[ARRAY_BEGIN]], i64 2 +// CHECK1-NEXT: br label [[ARRAYCTOR_LOOP:%.*]] +// CHECK1: arrayctor.loop: +// CHECK1-NEXT: [[ARRAYCTOR_CUR:%.*]] = phi ptr [ [[ARRAY_BEGIN]], [[INVOKE_CONT3]] ], [ [[ARRAYCTOR_NEXT:%.*]], [[INVOKE_CONT5:%.*]] ] +// CHECK1-NEXT: invoke void @_ZN9TestClassC1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYCTOR_CUR]]) +// CHECK1-NEXT: to label [[INVOKE_CONT5]] unwind label [[TERMINATE_LPAD]] +// CHECK1: invoke.cont5: +// CHECK1-NEXT: [[ARRAYCTOR_NEXT]] = getelementptr inbounds [[CLASS_TESTCLASS]], ptr [[ARRAYCTOR_CUR]], i64 1 +// CHECK1-NEXT: [[ARRAYCTOR_DONE:%.*]] = icmp eq ptr [[ARRAYCTOR_NEXT]], [[ARRAYCTOR_END]] +// CHECK1-NEXT: br i1 [[ARRAYCTOR_DONE]], label [[ARRAYCTOR_CONT:%.*]], label [[ARRAYCTOR_LOOP]] +// CHECK1: arrayctor.cont: +// CHECK1-NEXT: invoke void @_Z3foov() +// CHECK1-NEXT: to label [[INVOKE_CONT6:%.*]] unwind label [[TERMINATE_LPAD]] +// CHECK1: invoke.cont6: +// CHECK1-NEXT: [[ARRAY_BEGIN7:%.*]] = getelementptr inbounds [2 x %class.TestClass], ptr [[TC2]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[CLASS_TESTCLASS]], ptr [[ARRAY_BEGIN7]], i64 2 +// CHECK1-NEXT: br label [[ARRAYDESTROY_BODY:%.*]] +// CHECK1: arraydestroy.body: +// CHECK1-NEXT: [[ARRAYDESTROY_ELEMENTPAST:%.*]] = phi ptr [ [[TMP2]], [[INVOKE_CONT6]] ], [ [[ARRAYDESTROY_ELEMENT:%.*]], [[ARRAYDESTROY_BODY]] ] +// CHECK1-NEXT: [[ARRAYDESTROY_ELEMENT]] = getelementptr inbounds [[CLASS_TESTCLASS]], ptr [[ARRAYDESTROY_ELEMENTPAST]], i64 -1 +// CHECK1-NEXT: call void @_ZN9TestClassD1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[ARRAYDESTROY_ELEMENT]]) #[[ATTR3]] +// CHECK1-NEXT: [[ARRAYDESTROY_DONE:%.*]] = icmp eq ptr [[ARRAYDESTROY_ELEMENT]], [[ARRAY_BEGIN7]] +// CHECK1-NEXT: br i1 [[ARRAYDESTROY_DONE]], label [[ARRAYDESTROY_DONE8:%.*]], label [[ARRAYDESTROY_BODY]] +// CHECK1: arraydestroy.done8: +// CHECK1-NEXT: call void @_ZN9TestClassD1Ev(ptr noundef nonnull align 4 dereferenceable(4) [[TC]]) #[[ATTR3]] +/... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/109197 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits