diff --git a/clang/docs/OpenMPSupport.rst b/clang/docs/OpenMPSupport.rst index 0fa4ba3961bdd..46c365865f8dd 100644 --- a/clang/docs/OpenMPSupport.rst +++ b/clang/docs/OpenMPSupport.rst @@ -443,7 +443,8 @@ implementation. +-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+ | Traits for default device envirable | :none:`unclaimed` | :none:`unclaimed` | | +-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+ -| Optionally omit array length expression | :good:`done` | :none:`unclaimed` | https://github.com/llvm/llvm-project/pull/148048 | +| Optionally omit array length expression | :good:`done` | :none:`unclaimed` | (Parse) https://github.com/llvm/llvm-project/pull/148048, | +| | | | (Sema) https://github.com/llvm/llvm-project/pull/152786 | +-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+ | Canonical loop sequences | :none:`unclaimed` | :part:`In Progress` | | +-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 42eb2bf3109f2..581d3ec1af760 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -465,6 +465,7 @@ OpenMP Support modifier in the ``adjust_args`` clause. - Allow array length to be omitted in array section subscript expression. - Fixed non-contiguous strided update in the ``omp target update`` directive with the ``from`` clause. +- Properly handle array section/assumed-size array privatization in C/C++. Improvements ^^^^^^^^^^^^ diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index bbf2b2ac69d66..335a7d62d3e3d 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -2780,7 +2780,7 @@ void SemaOpenMP::EndOpenMPClause() { static std::pair getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, SourceRange &ERange, bool AllowArraySection = false, - StringRef DiagType = ""); + bool AllowAssumedSizeArray = false, StringRef DiagType = ""); /// Check consistency of the reduction clauses. static void checkReductionClauses(Sema &S, DSAStackTy *Stack, @@ -5148,11 +5148,10 @@ static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, return ErrorFound; } -static std::pair getPrivateItem(Sema &S, Expr *&RefExpr, - SourceLocation &ELoc, - SourceRange &ERange, - bool AllowArraySection, - StringRef DiagType) { +static std::pair +getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, + SourceRange &ERange, bool AllowArraySection, + bool AllowAssumedSizeArray, StringRef DiagType) { if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || RefExpr->containsUnexpandedParameterPack()) return std::make_pair(nullptr, true); @@ -5162,6 +5161,20 @@ static std::pair getPrivateItem(Sema &S, Expr *&RefExpr, // OpenMP [2.9.3.3, Restrictions, p.1] // A variable that is part of another variable (as an array or // structure element) cannot appear in a private clause. + // + // OpenMP [6.0] + // 5.2.5 Array Sections, p. 166, L28-29 + // When the length is absent and the size of the dimension is not known, + // the array section is an assumed-size array. + // 2 Glossary, p. 23, L4-6 + // assumed-size array + // For C/C++, an array section for which the length is absent and the + // size of the dimensions is not known. + // 5.2.5 Array Sections, p. 168, L11 + // An assumed-size array can appear only in clauses for which it is + // explicitly allowed. + // 7.4 List Item Privatization, Restrictions, p. 222, L15 + // Assumed-size arrays must not be privatized. RefExpr = RefExpr->IgnoreParens(); enum { NoArrayExpr = -1, @@ -5177,6 +5190,17 @@ static std::pair getPrivateItem(Sema &S, Expr *&RefExpr, IsArrayExpr = ArraySubscript; } else if (auto *OASE = dyn_cast_or_null(RefExpr)) { Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); + if (S.getLangOpts().OpenMP >= 60 && !AllowAssumedSizeArray && + OASE->getColonLocFirst().isValid() && !OASE->getLength()) { + QualType BaseType = ArraySectionExpr::getBaseOriginalType(Base); + if (BaseType.isNull() || (!BaseType->isConstantArrayType() && + !BaseType->isVariableArrayType())) { + S.Diag(OASE->getColonLocFirst(), + diag::err_omp_section_length_undefined) + << (!BaseType.isNull() && BaseType->isArrayType()); + return std::make_pair(nullptr, false); + } + } while (auto *TempOASE = dyn_cast(Base)) Base = TempOASE->getBase()->IgnoreParenImpCasts(); while (auto *TempASE = dyn_cast(Base)) @@ -17320,9 +17344,10 @@ static bool isValidInteropVariable(Sema &SemaRef, Expr *InteropVarExpr, SourceLocation ELoc; SourceRange ERange; Expr *RefExpr = InteropVarExpr; - auto Res = - getPrivateItem(SemaRef, RefExpr, ELoc, ERange, - /*AllowArraySection=*/false, /*DiagType=*/"omp_interop_t"); + auto Res = getPrivateItem(SemaRef, RefExpr, ELoc, ERange, + /*AllowArraySection=*/false, + /*AllowAssumedSizeArray=*/false, + /*DiagType=*/"omp_interop_t"); if (Res.second) { // It will be analyzed later. @@ -23506,7 +23531,8 @@ SemaOpenMP::ActOnOpenMPUseDeviceAddrClause(ArrayRef VarList, SourceRange ERange; Expr *SimpleRefExpr = RefExpr; auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange, - /*AllowArraySection=*/true); + /*AllowArraySection=*/true, + /*AllowAssumedSizeArray=*/true); if (Res.second) { // It will be analyzed later. MVLI.ProcessedVarList.push_back(RefExpr); diff --git a/clang/test/OpenMP/scan_messages.cpp b/clang/test/OpenMP/scan_messages.cpp index 0de94898c6571..45516768090a8 100644 --- a/clang/test/OpenMP/scan_messages.cpp +++ b/clang/test/OpenMP/scan_messages.cpp @@ -2,9 +2,14 @@ // RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 150 %s +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=60 -ferror-limit 150 %s + +// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=60 -ferror-limit 150 %s + template -T tmain() { +T tfoobar(T ub[]) { static T argc; + T *ptr; #pragma omp for for (int i = 0; i < 10; ++i) { #pragma omp scan // expected-error {{exactly one of 'inclusive' or 'exclusive' clauses is expected}} @@ -83,12 +88,23 @@ T tmain() { label1 : { #pragma omp scan inclusive(argc) // expected-error {{orphaned 'omp scan' directives are prohibited; perhaps you forget to enclose the directive into a for, simd, for simd, parallel for, or parallel for simd region?}} }} +#pragma omp simd reduction(inscan, +: argc) + for (int i = 0; i < 10; ++i) { + #pragma omp scan inclusive(ptr[0:], argc) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} + ; + } +#pragma omp simd reduction(inscan, +: argc) + for (int i = 0; i < 10; ++i) { + #pragma omp scan exclusive(argc, ub[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is an array of unknown bound}} + ; + } return T(); } -int main() { +int foobar(int ub[]) { static int argc; + int *ptr; #pragma omp simd reduction(inscan, +: argc) for (int i = 0; i < 10; ++i) { #pragma omp scan inclusive(argc) inclusive(argc) // expected-error {{exactly one of 'inclusive' or 'exclusive' clauses is expected}} @@ -177,6 +193,16 @@ label1 : { #pragma omp scan inclusive(argc) // expected-error {{orphaned 'omp scan' directives are prohibited; perhaps you forget to enclose the directive into a for, simd, for simd, parallel for, or parallel for simd region?}} } } +#pragma omp simd reduction(inscan, +: argc) + for (int i = 0; i < 10; ++i) { + #pragma omp scan inclusive(ptr[0:], argc) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} + ; + } +#pragma omp simd reduction(inscan, +: argc) + for (int i = 0; i < 10; ++i) { + #pragma omp scan exclusive(argc, ub[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is an array of unknown bound}} + ; + } - return tmain(); // expected-note {{in instantiation of function template specialization 'tmain' requested here}} + return tfoobar(ub); // expected-note {{in instantiation of function template specialization 'tfoobar' requested here}} } diff --git a/clang/test/OpenMP/target_data_use_device_addr_codegen.cpp b/clang/test/OpenMP/target_data_use_device_addr_codegen.cpp index 19a523ee165c8..a67d3258ea071 100644 --- a/clang/test/OpenMP/target_data_use_device_addr_codegen.cpp +++ b/clang/test/OpenMP/target_data_use_device_addr_codegen.cpp @@ -1,23 +1,28 @@ -// RUN: %clang_cc1 -DCK1 -verify -Wno-vla -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s -// RUN: %clang_cc1 -DCK1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --include-generated-funcs --replace-value-regex "__omp_offloading_[0-9a-z]+_[0-9a-z]+" "reduction_size[.].+[.]" "pl_cond[.].+[.|,]" --prefix-filecheck-ir-name _ --version 5 +// RUN: %clang_cc1 -verify -Wno-vla -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s // RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify -Wno-vla %s -emit-llvm -o - | FileCheck %s -// RUN: %clang_cc1 -DCK1 -verify -Wno-vla -fopenmp-simd -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s -// RUN: %clang_cc1 -DCK1 -fopenmp-simd -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -DOMP60 -verify -Wno-vla -fopenmp -fopenmp-version=60 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck --check-prefix OMP60 %s +// RUN: %clang_cc1 -DOMP60 -fopenmp -fopenmp-version=60 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -DOMP60 -fopenmp -fopenmp-version=60 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify -Wno-vla %s -emit-llvm -o - | FileCheck --check-prefix OMP60 %s + +// RUN: %clang_cc1 -verify -Wno-vla -fopenmp-simd -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s // RUN: %clang_cc1 -fopenmp-simd -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify -Wno-vla %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY0 %s -// SIMD-ONLY0-NOT: {{__kmpc|__tgt}} + +// RUN: %clang_cc1 -DOMP60 -verify -Wno-vla -fopenmp-simd -fopenmp-version=60 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0-OMP60 %s +// RUN: %clang_cc1 -DOMP60 -fopenmp-simd -fopenmp-version=60 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -DOMP60 -fopenmp-simd -fopenmp-version=60 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify -Wno-vla %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY0-OMP60 %s // expected-no-diagnostics #ifndef HEADER #define HEADER -// CHECK-DAG: [[SIZES1:@.+]] = private unnamed_addr constant [6 x i64] [i64 4, i64 16, i64 4, i64 4, i64 0, i64 4] // 64 = 0x40 = OMP_MAP_RETURN_PARAM -// CHECK-DAG: [[MAPTYPES1:@.+]] = private unnamed_addr constant [6 x i64] [i64 67, i64 115, i64 51, i64 67, i64 67, i64 67] -// CHECK-DAG: [[SIZES2:@.+]] = private unnamed_addr constant [6 x i64] [i64 0, i64 4, i64 16, i64 4, i64 4, i64 0] // 0 = OMP_MAP_NONE // 281474976710720 = 0x1000000000040 = OMP_MAP_MEMBER_OF | OMP_MAP_RETURN_PARAM -// CHECK-DAG: [[MAPTYPES2:@.+]] = private unnamed_addr constant [6 x i64] [i64 0, i64 281474976710723, i64 281474976710739, i64 281474976710739, i64 281474976710675, i64 281474976710723] + struct S { int a = 0; int *ptr = &a; @@ -25,12 +30,20 @@ struct S { int arr[4]; S() {} void foo() { +#ifdef OMP60 +#pragma omp target data map(tofrom: a, ptr [3:4], ref, ptr[0], arr[:a], ptr[:]) use_device_addr(a, ptr [3:4], ref, ptr[0], arr[:a], ptr[:]) +#else #pragma omp target data map(tofrom: a, ptr [3:4], ref, ptr[0], arr[:a]) use_device_addr(a, ptr [3:4], ref, ptr[0], arr[:a]) +#endif // OMP60 ++a, ++*ptr, ++ref, ++arr[0]; } }; +#ifdef OMP60 +int main(int argc, char *argv[]) { +#else int main() { +#endif // OMP60 float a = 0; float *ptr = &a; float &ref = a; @@ -38,185 +51,901 @@ int main() { float vla[(int)a]; S s; s.foo(); +#ifdef OMP60 +#pragma omp target data map(tofrom: a, ptr [3:4], ref, ptr[0], arr[:(int)a], vla[0], ptr[:], argv[0][:]) use_device_addr(a, ptr [3:4], ref, ptr[0], arr[:(int)a], vla[0], ptr[:], argv[0][:]) +#else #pragma omp target data map(tofrom: a, ptr [3:4], ref, ptr[0], arr[:(int)a], vla[0]) use_device_addr(a, ptr [3:4], ref, ptr[0], arr[:(int)a], vla[0]) +#endif // OMP60 ++a, ++*ptr, ++ref, ++arr[0], ++vla[0]; return a; } -// CHECK-LABEL: @main() -// CHECK: [[A_ADDR:%.+]] = alloca float, -// CHECK: [[PTR_ADDR:%.+]] = alloca ptr, -// CHECK: [[REF_ADDR:%.+]] = alloca ptr, -// CHECK: [[ARR_ADDR:%.+]] = alloca [4 x float], -// CHECK: [[BPTRS:%.+]] = alloca [6 x ptr], -// CHECK: [[PTRS:%.+]] = alloca [6 x ptr], -// CHECK: [[MAP_PTRS:%.+]] = alloca [6 x ptr], -// CHECK: [[SIZES:%.+]] = alloca [6 x i64], -// CHECK: [[VLA_ADDR:%.+]] = alloca float, i64 %{{.+}}, -// CHECK: [[PTR:%.+]] = load ptr, ptr [[PTR_ADDR]], -// CHECK-NEXT: [[ARR_IDX:%.+]] = getelementptr inbounds nuw float, ptr [[PTR]], i64 3 -// CHECK: [[P5:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8 -// CHECK-NEXT: [[ARR_IDX1:%.+]] = getelementptr inbounds float, ptr [[P5]], i64 0 -// CHECK: [[P7:%.+]] = load ptr, ptr [[REF_ADDR]], -// CHECK-NEXT: [[REF:%.+]] = load ptr, ptr [[REF_ADDR]], -// CHECK-NEXT: [[ARR_IDX2:%.+]] = getelementptr inbounds nuw [4 x float], ptr [[ARR_ADDR]], i64 0, i64 0 -// CHECK: [[P10:%.+]] = mul nuw i64 {{.+}}, 4 -// CHECK-NEXT: [[ARR_IDX5:%.+]] = getelementptr inbounds float, ptr [[VLA_ADDR]], i64 0 -// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[SIZES]], ptr align 8 [[SIZES1]], i64 48, i1 false) -// CHECK: [[BPTR0:%.+]] = getelementptr inbounds [6 x ptr], ptr [[BPTRS]], i32 0, i32 0 -// CHECK: store ptr [[A_ADDR]], ptr [[BPTR0]], -// CHECK: [[PTR0:%.+]] = getelementptr inbounds [6 x ptr], ptr [[PTRS]], i32 0, i32 0 -// CHECK: store ptr [[A_ADDR]], ptr [[PTR0]], -// CHECK: [[BPTR1:%.+]] = getelementptr inbounds [6 x ptr], ptr [[BPTRS]], i32 0, i32 1 -// CHECK: store ptr [[PTR_ADDR]], ptr [[BPTR1]], -// CHECK: [[PTR1:%.+]] = getelementptr inbounds [6 x ptr], ptr [[PTRS]], i32 0, i32 1 -// CHECK: store ptr [[ARR_IDX]], ptr [[PTR1]], -// CHECK: [[BPTR2:%.+]] = getelementptr inbounds [6 x ptr], ptr [[BPTRS]], i32 0, i32 2 -// CHECK: store ptr [[PTR_ADDR]], ptr [[BPTR2]], -// CHECK: [[PTR2:%.+]] = getelementptr inbounds [6 x ptr], ptr [[PTRS]], i32 0, i32 2 -// CHECK: store ptr [[ARR_IDX1]], ptr [[PTR2]], -// CHECK: [[BPTR3:%.+]] = getelementptr inbounds [6 x ptr], ptr [[BPTRS]], i32 0, i32 3 -// CHECK: store ptr [[P7]], ptr [[BPTR3]], -// CHECK: [[PTR3:%.+]] = getelementptr inbounds [6 x ptr], ptr [[PTRS]], i32 0, i32 3 -// CHECK: store ptr [[REF]], ptr [[PTR3]], -// CHECK: [[BPTR4:%.+]] = getelementptr inbounds [6 x ptr], ptr [[BPTRS]], i32 0, i32 4 -// CHECK: store ptr [[ARR_ADDR]], ptr [[BPTR4]], align -// CHECK: [[PTR4:%.+]] = getelementptr inbounds [6 x ptr], ptr [[PTRS]], i32 0, i32 4 -// CHECK: store ptr [[ARR_IDX2]], ptr [[PTR4]], align 8 -// CHECK: [[SIZE_PTR:%.+]] = getelementptr inbounds [6 x i64], ptr [[SIZES]], i32 0, i32 4 -// CHECK: store i64 [[P10:%.+]], ptr [[SIZE_PTR]], align 8 -// CHECK: [[MAP_PTR:%.+]] = getelementptr inbounds [6 x ptr], ptr [[MAP_PTRS]], i64 0, i64 4 -// CHECK: store ptr null, ptr [[MAP_PTR]], align 8 -// CHECK: [[BPTR5:%.+]] = getelementptr inbounds [6 x ptr], ptr [[BPTRS]], i32 0, i32 5 -// CHECK: store ptr [[VLA_ADDR]], ptr [[BPTR5]], -// CHECK: [[PTR5:%.+]] = getelementptr inbounds [6 x ptr], ptr [[PTRS]], i32 0, i32 5 -// CHECK: store ptr [[ARR_IDX5]], ptr [[PTR5]], -// CHECK: [[BPTR:%.+]] = getelementptr inbounds [6 x ptr], ptr [[BPTRS]], i32 0, i32 0 -// CHECK: [[PTR:%.+]] = getelementptr inbounds [6 x ptr], ptr [[PTRS]], i32 0, i32 0 -// CHECK: [[SIZE:%.+]] = getelementptr inbounds [6 x i64], ptr [[SIZES]], i32 0, i32 0 -// CHECK: call void @__tgt_target_data_begin_mapper(ptr @{{.+}}, i64 -1, i32 6, ptr [[BPTR]], ptr [[PTR]], ptr [[SIZE]], ptr [[MAPTYPES1]], ptr null, ptr null) -// CHECK: [[A_REF:%.+]] = load ptr, ptr [[BPTR0]], -// CHECK: [[REF_REF:%.+]] = load ptr, ptr [[BPTR3]], -// CHECK: store ptr [[REF_REF]], ptr [[TMP_REF_ADDR:%.+]], -// CHECK: [[ARR_REF:%.+]] = load ptr, ptr [[BPTR4]], -// CHECK: [[VLA_REF:%.+]] = load ptr, ptr [[BPTR5]], -// CHECK: [[A:%.+]] = load float, ptr [[A_REF]], -// CHECK: [[INC:%.+]] = fadd float [[A]], 1.000000e+00 -// CHECK: store float [[INC]], ptr [[A_REF]], -// CHECK: [[PTR:%.+]] = load ptr, ptr [[BPTR1]], -// CHECK: [[VAL:%.+]] = load float, ptr [[PTR]], -// CHECK: [[INC:%.+]] = fadd float [[VAL]], 1.000000e+00 -// CHECK: store float [[INC]], ptr [[PTR]], -// CHECK: [[REF_ADDR:%.+]] = load ptr, ptr [[TMP_REF_ADDR]], -// CHECK: [[REF:%.+]] = load float, ptr [[REF_ADDR]], -// CHECK: [[INC:%.+]] = fadd float [[REF]], 1.000000e+00 -// CHECK: store float [[INC]], ptr [[REF_ADDR]], -// CHECK: [[ARR0_ADDR:%.+]] = getelementptr inbounds [4 x float], ptr [[ARR_REF]], i64 0, i64 0 -// CHECK: [[ARR0:%.+]] = load float, ptr [[ARR0_ADDR]], -// CHECK: [[INC:%.+]] = fadd float [[ARR0]], 1.000000e+00 -// CHECK: store float [[INC]], ptr [[ARR0_ADDR]], -// CHECK: [[VLA0_ADDR:%.+]] = getelementptr inbounds float, ptr [[VLA_REF]], i64 0 -// CHECK: [[VLA0:%.+]] = load float, ptr [[VLA0_ADDR]], -// CHECK: [[INC:%.+]] = fadd float [[VLA0]], 1.000000e+00 -// CHECK: store float [[INC]], ptr [[VLA0_ADDR]], -// CHECK: [[BPTR:%.+]] = getelementptr inbounds [6 x ptr], ptr [[BPTRS]], i32 0, i32 0 -// CHECK: [[PTR:%.+]] = getelementptr inbounds [6 x ptr], ptr [[PTRS]], i32 0, i32 0 -// CHECK: [[SIZE:%.+]] = getelementptr inbounds [6 x i64], ptr [[SIZES]], i32 0, i32 0 -// CHECK: call void @__tgt_target_data_end_mapper(ptr @{{.+}}, i64 -1, i32 6, ptr [[BPTR]], ptr [[PTR]], ptr [[SIZE]], ptr [[MAPTYPES1]], ptr null, ptr null) -// CHECK: foo -// CHECK: [[BPTRS:%.+]] = alloca [6 x ptr], -// CHECK: [[PTRS:%.+]] = alloca [6 x ptr], -// CHECK: [[MAP_PTRS:%.+]] = alloca [6 x ptr], -// CHECK: [[SIZES:%.+]] = alloca [6 x i64], -// CHECK: [[A_ADDR:%.+]] = getelementptr inbounds nuw %struct.S, ptr [[THIS:%.+]], i32 0, i32 0 -// CHECK: [[PTR_ADDR:%.+]] = getelementptr inbounds nuw %struct.S, ptr [[THIS]], i32 0, i32 1 -// CHECK: [[ARR_IDX:%.+]] = getelementptr inbounds nuw i32, ptr %{{.+}}, i64 3 -// CHECK: [[REF_REF:%.+]] = getelementptr inbounds nuw %struct.S, ptr [[THIS]], i32 0, i32 2 -// CHECK: [[REF_PTR:%.+]] = load ptr, ptr [[REF_REF]], -// CHECK-NEXT: [[P3:%.+]] = getelementptr inbounds nuw %struct.S, ptr [[THIS]], i32 0, i32 1 -// CHECK: [[ARR_IDX5:%.+]] = getelementptr inbounds i32, ptr {{.+}}, i64 0 -// CHECK: [[ARR_ADDR:%.+]] = getelementptr inbounds nuw %struct.S, ptr [[THIS]], i32 0, i32 3 -// CHECK: [[ARR_IDX6:%.+]] = getelementptr inbounds nuw [4 x i32], ptr [[ARR_ADDR]], i64 0, i64 0 -// CHECK: [[A_ADDR2:%.+]] = getelementptr inbounds nuw %struct.S, ptr [[THIS]], i32 0, i32 0 -// CHECK: [[P4:%.+]] = mul nuw i64 [[CONV:%.+]], 4 -// CHECK: [[A_ADDR3:%.+]] = getelementptr inbounds nuw %struct.S, ptr [[THIS]], i32 0, i32 0 -// CHECK: [[L5:%.+]] = load i32, ptr [[A_ADDR3]] -// CHECK: [[L6:%.+]] = sext i32 [[L5]] to i64 -// CHECK: [[LB_ADD_LEN:%lb_add_len]] = add nsw i64 -1, [[L6]] -// CHECK: [[ARR_ADDR9:%.+]] = getelementptr inbounds nuw %struct.S, ptr [[THIS]], i32 0, i32 3 -// CHECK: [[ARR_IDX10:%arrayidx.+]] = getelementptr inbounds nuw [4 x i32], ptr [[ARR_ADDR9]], i64 0, i64 %lb_add_len -// CHECK: [[ARR_END:%.+]] = getelementptr i32, ptr [[ARR_IDX10]], i32 1 -// CHECK: [[E:%.+]] = ptrtoint ptr [[ARR_END]] to i64 -// CHECK: [[B:%.+]] = ptrtoint ptr [[A_ADDR]] to i64 -// CHECK: [[DIFF:%.+]] = sub i64 [[E]], [[B]] -// CHECK: [[SZ:%.+]] = sdiv exact i64 [[DIFF]], ptrtoint (ptr getelementptr (i8, ptr null, i32 1) to i64) -// CHECK: [[BPTR0:%.+]] = getelementptr inbounds [6 x ptr], ptr [[BPTRS]], i32 0, i32 0 -// CHECK: store ptr [[THIS]], ptr [[BPTR0]], -// CHECK: [[PTR0:%.+]] = getelementptr inbounds [6 x ptr], ptr [[PTRS]], i32 0, i32 0 -// CHECK: store ptr [[A_ADDR]], ptr [[PTR0]], -// CHECK: [[SIZE0:%.+]] = getelementptr inbounds [6 x i64], ptr [[SIZES]], i32 0, i32 0 -// CHECK: store i64 [[SZ]], ptr [[SIZE0]], -// CHECK: [[BPTR1:%.+]] = getelementptr inbounds [6 x ptr], ptr [[BPTRS]], i32 0, i32 1 -// CHECK: store ptr [[THIS]], ptr [[BPTR1]] -// CHECK: [[PTR1:%.+]] = getelementptr inbounds [6 x ptr], ptr [[PTRS]], i32 0, i32 1 -// CHECK: store ptr [[A_ADDR]], ptr [[PTR1]], -// CHECK: [[BPTR2:%.+]] = getelementptr inbounds [6 x ptr], ptr [[BPTRS]], i32 0, i32 2 -// CHECK: store ptr [[PTR_ADDR]], ptr [[BPTR2]], -// CHECK: [[PTR2:%.+]] = getelementptr inbounds [6 x ptr], ptr [[PTRS]], i32 0, i32 2 -// CHECK: store ptr [[ARR_IDX]], ptr [[PTR2]], -// CHECK: [[BPTR3:%.+]] = getelementptr inbounds [6 x ptr], ptr [[BPTRS]], i32 0, i32 3 -// CHECK: store ptr [[THIS]], ptr [[BPTR3]] -// CHECK: [[PTR3:%.+]] = getelementptr inbounds [6 x ptr], ptr [[PTRS]], i32 0, i32 3 -// CHECK: store ptr [[REF_PTR]], ptr [[PTR3]], -// CHECK: [[BPTR4:%.+]] = getelementptr inbounds [6 x ptr], ptr [[BPTRS]], i32 0, i32 4 -// CHECK: store ptr [[P3]], ptr [[BPTR4]], -// CHECK: [[PTR4:%.+]] = getelementptr inbounds [6 x ptr], ptr [[PTRS]], i32 0, i32 4 -// CHECK: store ptr [[ARR_IDX5]], ptr [[PTR4]] -// CHECK: [[BPTR5:%.+]] = getelementptr inbounds [6 x ptr], ptr [[BPTRS]], i32 0, i32 5 -// CHECK: store ptr [[THIS]], ptr [[BPTR5]], align 8 -// CHECK: [[PTR5:%.+]] = getelementptr inbounds [6 x ptr], ptr [[PTRS]], i32 0, i32 5 -// CHECK: store ptr [[ARR_IDX6]], ptr [[PTR5]], align 8 -// CHECK: [[SIZE1:%.+]] = getelementptr inbounds [6 x i64], ptr [[SIZES]], i32 0, i32 5 -// CHECK: store i64 [[P4]], ptr [[SIZE1]], align 8 -// CHECK: [[BPTR:%.+]] = getelementptr inbounds [6 x ptr], ptr [[BPTRS]], i32 0, i32 0 -// CHECK: [[PTR:%.+]] = getelementptr inbounds [6 x ptr], ptr [[PTRS]], i32 0, i32 0 -// CHECK: [[SIZE:%.+]] = getelementptr inbounds [6 x i64], ptr [[SIZES]], i32 0, i32 0 -// CHECK: call void @__tgt_target_data_begin_mapper(ptr @{{.+}}, i64 -1, i32 6, ptr [[BPTR]], ptr [[PTR]], ptr [[SIZE]], ptr [[MAPTYPES2]], ptr null, ptr null) -// CHECK: [[A_ADDR:%.+]] = load ptr, ptr [[BPTR1]], -// CHECK: store ptr [[A_ADDR]], ptr [[A_REF:%.+]], -// CHECK: [[PTR_ADDR:%.+]] = load ptr, ptr [[BPTR2]], -// CHECK: store ptr [[PTR_ADDR]], ptr [[PTR_REF:%.+]], -// CHECK: [[REF_PTR:%.+]] = load ptr, ptr [[BPTR3]], -// CHECK: store ptr [[REF_PTR]], ptr [[REF_REF:%.+]], -// CHECK: [[PTR_ADDR:%.+]] = load ptr, ptr [[BPTR2]], -// CHECK: store ptr [[PTR_ADDR]], ptr [[PTR_REF2:%.+]], -// CHECK: [[ARR_ADDR:%.+]] = load ptr, ptr [[BPTR5]], -// CHECK: store ptr [[ARR_ADDR]], ptr [[ARR_REF:%.+]], -// CHECK: [[A_ADDR:%.+]] = load ptr, ptr [[A_REF]], -// CHECK: [[A:%.+]] = load i32, ptr [[A_ADDR]], -// CHECK: [[INC:%.+]] = add nsw i32 [[A]], 1 -// CHECK: store i32 [[INC]], ptr [[A_ADDR]], -// CHECK: [[PTR_PTR:%.+]] = load ptr, ptr [[PTR_REF2]], -// CHECK: [[PTR:%.+]] = load ptr, ptr [[PTR_PTR]], -// CHECK: [[VAL:%.+]] = load i32, ptr [[PTR]], -// CHECK: [[INC:%.+]] = add nsw i32 [[VAL]], 1 -// CHECK: store i32 [[INC]], ptr [[PTR]], -// CHECK: [[REF_PTR:%.+]] = load ptr, ptr [[REF_REF]], -// CHECK: [[VAL:%.+]] = load i32, ptr [[REF_PTR]], -// CHECK: [[INC:%.+]] = add nsw i32 [[VAL]], 1 -// CHECK: store i32 [[INC]], ptr [[REF_PTR]], -// CHECK: [[ARR_ADDR:%.+]] = load ptr, ptr [[ARR_REF]], -// CHECK: [[ARR0_ADDR:%.+]] = getelementptr inbounds [4 x i32], ptr [[ARR_ADDR]], i64 0, i64 0 -// CHECK: [[VAL:%.+]] = load i32, ptr [[ARR0_ADDR]], -// CHECK: [[INC:%.+]] = add nsw i32 [[VAL]], 1 -// CHECK: store i32 [[INC]], ptr [[ARR0_ADDR]], -// CHECK: [[BPTR:%.+]] = getelementptr inbounds [6 x ptr], ptr [[BPTRS]], i32 0, i32 0 -// CHECK: [[PTR:%.+]] = getelementptr inbounds [6 x ptr], ptr [[PTRS]], i32 0, i32 0 -// CHECK: [[SIZE:%.+]] = getelementptr inbounds [6 x i64], ptr [[SIZES]], i32 0, i32 0 -// CHECK: call void @__tgt_target_data_end_mapper(ptr @{{.+}}, i64 -1, i32 6, ptr [[BPTR]], ptr [[PTR]], ptr [[SIZE]], ptr [[MAPTYPES2]], ptr null, ptr null) #endif +// CHECK-LABEL: define dso_local noundef signext i32 @main( +// CHECK-SAME: ) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 +// CHECK-NEXT: [[A:%.*]] = alloca float, align 4 +// CHECK-NEXT: [[PTR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[REF:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[ARR:%.*]] = alloca [4 x float], align 4 +// CHECK-NEXT: [[SAVED_STACK:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[__VLA_EXPR0:%.*]] = alloca i64, align 8 +// CHECK-NEXT: [[S:%.*]] = alloca [[STRUCT_S:%.*]], align 8 +// CHECK-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [6 x ptr], align 8 +// CHECK-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [6 x ptr], align 8 +// CHECK-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [6 x ptr], align 8 +// CHECK-NEXT: [[DOTOFFLOAD_SIZES:%.*]] = alloca [6 x i64], align 8 +// CHECK-NEXT: [[TMP:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: store i32 0, ptr [[RETVAL]], align 4 +// CHECK-NEXT: store float 0.000000e+00, ptr [[A]], align 4 +// CHECK-NEXT: store ptr [[A]], ptr [[PTR]], align 8 +// CHECK-NEXT: store ptr [[A]], ptr [[REF]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[A]], align 4 +// CHECK-NEXT: [[CONV:%.*]] = fptosi float [[TMP0]] to i32 +// CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[CONV]] to i64 +// CHECK-NEXT: [[TMP2:%.*]] = call ptr @llvm.stacksave.p0() +// CHECK-NEXT: store ptr [[TMP2]], ptr [[SAVED_STACK]], align 8 +// CHECK-NEXT: [[VLA:%.*]] = alloca float, i64 [[TMP1]], align 4 +// CHECK-NEXT: store i64 [[TMP1]], ptr [[__VLA_EXPR0]], align 8 +// CHECK-NEXT: call void @_ZN1SC1Ev(ptr noundef nonnull align 8 dereferenceable(40) [[S]]) +// CHECK-NEXT: call void @_ZN1S3fooEv(ptr noundef nonnull align 8 dereferenceable(40) [[S]]) +// CHECK-NEXT: [[TMP3:%.*]] = load ptr, ptr [[PTR]], align 8 +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP3]], i64 3 +// CHECK-NEXT: [[TMP4:%.*]] = load ptr, ptr [[PTR]], align 8 +// CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds float, ptr [[TMP4]], i64 0 +// CHECK-NEXT: [[TMP5:%.*]] = load ptr, ptr [[REF]], align 8, !nonnull [[META3:![0-9]+]], !align [[META4:![0-9]+]] +// CHECK-NEXT: [[TMP6:%.*]] = load ptr, ptr [[REF]], align 8, !nonnull [[META3]], !align [[META4]] +// CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw [4 x float], ptr [[ARR]], i64 0, i64 0 +// CHECK-NEXT: [[TMP7:%.*]] = load float, ptr [[A]], align 4 +// CHECK-NEXT: [[CONV3:%.*]] = fptosi float [[TMP7]] to i32 +// CHECK-NEXT: [[CONV4:%.*]] = sext i32 [[CONV3]] to i64 +// CHECK-NEXT: [[TMP8:%.*]] = mul nuw i64 [[CONV4]], 4 +// CHECK-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds float, ptr [[VLA]], i64 0 +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[DOTOFFLOAD_SIZES]], ptr align 8 @.offload_sizes, i64 48, i1 false) +// CHECK-NEXT: [[TMP9:%.*]] = getelementptr inbounds [6 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK-NEXT: store ptr [[A]], ptr [[TMP9]], align 8 +// CHECK-NEXT: [[TMP10:%.*]] = getelementptr inbounds [6 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK-NEXT: store ptr [[A]], ptr [[TMP10]], align 8 +// CHECK-NEXT: [[TMP11:%.*]] = getelementptr inbounds [6 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK-NEXT: store ptr null, ptr [[TMP11]], align 8 +// CHECK-NEXT: [[TMP12:%.*]] = getelementptr inbounds [6 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 1 +// CHECK-NEXT: store ptr [[PTR]], ptr [[TMP12]], align 8 +// CHECK-NEXT: [[TMP13:%.*]] = getelementptr inbounds [6 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 1 +// CHECK-NEXT: store ptr [[ARRAYIDX]], ptr [[TMP13]], align 8 +// CHECK-NEXT: [[TMP14:%.*]] = getelementptr inbounds [6 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 1 +// CHECK-NEXT: store ptr null, ptr [[TMP14]], align 8 +// CHECK-NEXT: [[TMP15:%.*]] = getelementptr inbounds [6 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 2 +// CHECK-NEXT: store ptr [[PTR]], ptr [[TMP15]], align 8 +// CHECK-NEXT: [[TMP16:%.*]] = getelementptr inbounds [6 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 2 +// CHECK-NEXT: store ptr [[ARRAYIDX1]], ptr [[TMP16]], align 8 +// CHECK-NEXT: [[TMP17:%.*]] = getelementptr inbounds [6 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 2 +// CHECK-NEXT: store ptr null, ptr [[TMP17]], align 8 +// CHECK-NEXT: [[TMP18:%.*]] = getelementptr inbounds [6 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 3 +// CHECK-NEXT: store ptr [[TMP5]], ptr [[TMP18]], align 8 +// CHECK-NEXT: [[TMP19:%.*]] = getelementptr inbounds [6 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 3 +// CHECK-NEXT: store ptr [[TMP6]], ptr [[TMP19]], align 8 +// CHECK-NEXT: [[TMP20:%.*]] = getelementptr inbounds [6 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 3 +// CHECK-NEXT: store ptr null, ptr [[TMP20]], align 8 +// CHECK-NEXT: [[TMP21:%.*]] = getelementptr inbounds [6 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 4 +// CHECK-NEXT: store ptr [[ARR]], ptr [[TMP21]], align 8 +// CHECK-NEXT: [[TMP22:%.*]] = getelementptr inbounds [6 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 4 +// CHECK-NEXT: store ptr [[ARRAYIDX2]], ptr [[TMP22]], align 8 +// CHECK-NEXT: [[TMP23:%.*]] = getelementptr inbounds [6 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 4 +// CHECK-NEXT: store i64 [[TMP8]], ptr [[TMP23]], align 8 +// CHECK-NEXT: [[TMP24:%.*]] = getelementptr inbounds [6 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 4 +// CHECK-NEXT: store ptr null, ptr [[TMP24]], align 8 +// CHECK-NEXT: [[TMP25:%.*]] = getelementptr inbounds [6 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 5 +// CHECK-NEXT: store ptr [[VLA]], ptr [[TMP25]], align 8 +// CHECK-NEXT: [[TMP26:%.*]] = getelementptr inbounds [6 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 5 +// CHECK-NEXT: store ptr [[ARRAYIDX5]], ptr [[TMP26]], align 8 +// CHECK-NEXT: [[TMP27:%.*]] = getelementptr inbounds [6 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 5 +// CHECK-NEXT: store ptr null, ptr [[TMP27]], align 8 +// CHECK-NEXT: [[TMP28:%.*]] = getelementptr inbounds [6 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK-NEXT: [[TMP29:%.*]] = getelementptr inbounds [6 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK-NEXT: [[TMP30:%.*]] = getelementptr inbounds [6 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 +// CHECK-NEXT: call void @__tgt_target_data_begin_mapper(ptr @[[GLOB1:[0-9]+]], i64 -1, i32 6, ptr [[TMP28]], ptr [[TMP29]], ptr [[TMP30]], ptr @.offload_maptypes, ptr null, ptr null) +// CHECK-NEXT: [[TMP31:%.*]] = load ptr, ptr [[TMP9]], align 8 +// CHECK-NEXT: [[TMP32:%.*]] = load ptr, ptr [[TMP18]], align 8 +// CHECK-NEXT: store ptr [[TMP32]], ptr [[TMP]], align 8 +// CHECK-NEXT: [[TMP33:%.*]] = load ptr, ptr [[TMP21]], align 8 +// CHECK-NEXT: [[TMP34:%.*]] = load ptr, ptr [[TMP25]], align 8 +// CHECK-NEXT: [[TMP35:%.*]] = load float, ptr [[TMP31]], align 4 +// CHECK-NEXT: [[INC:%.*]] = fadd float [[TMP35]], 1.000000e+00 +// CHECK-NEXT: store float [[INC]], ptr [[TMP31]], align 4 +// CHECK-NEXT: [[TMP36:%.*]] = load ptr, ptr [[TMP12]], align 8 +// CHECK-NEXT: [[TMP37:%.*]] = load float, ptr [[TMP36]], align 4 +// CHECK-NEXT: [[INC6:%.*]] = fadd float [[TMP37]], 1.000000e+00 +// CHECK-NEXT: store float [[INC6]], ptr [[TMP36]], align 4 +// CHECK-NEXT: [[TMP38:%.*]] = load ptr, ptr [[TMP]], align 8, !nonnull [[META3]], !align [[META4]] +// CHECK-NEXT: [[TMP39:%.*]] = load float, ptr [[TMP38]], align 4 +// CHECK-NEXT: [[INC7:%.*]] = fadd float [[TMP39]], 1.000000e+00 +// CHECK-NEXT: store float [[INC7]], ptr [[TMP38]], align 4 +// CHECK-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds [4 x float], ptr [[TMP33]], i64 0, i64 0 +// CHECK-NEXT: [[TMP40:%.*]] = load float, ptr [[ARRAYIDX8]], align 4 +// CHECK-NEXT: [[INC9:%.*]] = fadd float [[TMP40]], 1.000000e+00 +// CHECK-NEXT: store float [[INC9]], ptr [[ARRAYIDX8]], align 4 +// CHECK-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds float, ptr [[TMP34]], i64 0 +// CHECK-NEXT: [[TMP41:%.*]] = load float, ptr [[ARRAYIDX10]], align 4 +// CHECK-NEXT: [[INC11:%.*]] = fadd float [[TMP41]], 1.000000e+00 +// CHECK-NEXT: store float [[INC11]], ptr [[ARRAYIDX10]], align 4 +// CHECK-NEXT: [[TMP42:%.*]] = getelementptr inbounds [6 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK-NEXT: [[TMP43:%.*]] = getelementptr inbounds [6 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK-NEXT: [[TMP44:%.*]] = getelementptr inbounds [6 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 +// CHECK-NEXT: call void @__tgt_target_data_end_mapper(ptr @[[GLOB1]], i64 -1, i32 6, ptr [[TMP42]], ptr [[TMP43]], ptr [[TMP44]], ptr @.offload_maptypes, ptr null, ptr null) +// CHECK-NEXT: [[TMP45:%.*]] = load float, ptr [[A]], align 4 +// CHECK-NEXT: [[CONV12:%.*]] = fptosi float [[TMP45]] to i32 +// CHECK-NEXT: store i32 [[CONV12]], ptr [[RETVAL]], align 4 +// CHECK-NEXT: [[TMP46:%.*]] = load ptr, ptr [[SAVED_STACK]], align 8 +// CHECK-NEXT: call void @llvm.stackrestore.p0(ptr [[TMP46]]) +// CHECK-NEXT: [[TMP47:%.*]] = load i32, ptr [[RETVAL]], align 4 +// CHECK-NEXT: ret i32 [[TMP47]] +// +// +// CHECK-LABEL: define linkonce_odr void @_ZN1SC1Ev( +// CHECK-SAME: ptr noundef nonnull align 8 dereferenceable(40) [[THIS:%.*]]) unnamed_addr #[[ATTR2:[0-9]+]] comdat { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: call void @_ZN1SC2Ev(ptr noundef nonnull align 8 dereferenceable(40) [[THIS1]]) +// CHECK-NEXT: ret void +// +// +// CHECK-LABEL: define linkonce_odr void @_ZN1S3fooEv( +// CHECK-SAME: ptr noundef nonnull align 8 dereferenceable(40) [[THIS:%.*]]) #[[ATTR2]] comdat { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [6 x ptr], align 8 +// CHECK-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [6 x ptr], align 8 +// CHECK-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [6 x ptr], align 8 +// CHECK-NEXT: [[DOTOFFLOAD_SIZES:%.*]] = alloca [6 x i64], align 8 +// CHECK-NEXT: [[TMP:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[_TMP11:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[_TMP12:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[_TMP13:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[_TMP14:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: [[A:%.*]] = getelementptr inbounds nuw [[STRUCT_S:%.*]], ptr [[THIS1]], i32 0, i32 0 +// CHECK-NEXT: [[PTR:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 1 +// CHECK-NEXT: [[PTR2:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 1 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[PTR2]], align 8 +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP0]], i64 3 +// CHECK-NEXT: [[REF:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 2 +// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[REF]], align 8, !nonnull [[META3]], !align [[META4]] +// CHECK-NEXT: [[PTR3:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 1 +// CHECK-NEXT: [[PTR4:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 1 +// CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[PTR4]], align 8 +// CHECK-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds i32, ptr [[TMP2]], i64 0 +// CHECK-NEXT: [[ARR:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 3 +// CHECK-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds nuw [4 x i32], ptr [[ARR]], i64 0, i64 0 +// CHECK-NEXT: [[A7:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 0 +// CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[A7]], align 8 +// CHECK-NEXT: [[CONV:%.*]] = sext i32 [[TMP3]] to i64 +// CHECK-NEXT: [[TMP4:%.*]] = mul nuw i64 [[CONV]], 4 +// CHECK-NEXT: [[A8:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 0 +// CHECK-NEXT: [[TMP5:%.*]] = load i32, ptr [[A8]], align 8 +// CHECK-NEXT: [[TMP6:%.*]] = sext i32 [[TMP5]] to i64 +// CHECK-NEXT: [[LB_ADD_LEN:%.*]] = add nsw i64 -1, [[TMP6]] +// CHECK-NEXT: [[ARR9:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 3 +// CHECK-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds nuw [4 x i32], ptr [[ARR9]], i64 0, i64 [[LB_ADD_LEN]] +// CHECK-NEXT: [[TMP7:%.*]] = getelementptr i32, ptr [[ARRAYIDX10]], i32 1 +// CHECK-NEXT: [[TMP8:%.*]] = ptrtoint ptr [[TMP7]] to i64 +// CHECK-NEXT: [[TMP9:%.*]] = ptrtoint ptr [[A]] to i64 +// CHECK-NEXT: [[TMP10:%.*]] = sub i64 [[TMP8]], [[TMP9]] +// CHECK-NEXT: [[TMP11:%.*]] = sdiv exact i64 [[TMP10]], ptrtoint (ptr getelementptr (i8, ptr null, i32 1) to i64) +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[DOTOFFLOAD_SIZES]], ptr align 8 @.offload_sizes.1, i64 48, i1 false) +// CHECK-NEXT: [[TMP12:%.*]] = getelementptr inbounds [6 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK-NEXT: store ptr [[THIS1]], ptr [[TMP12]], align 8 +// CHECK-NEXT: [[TMP13:%.*]] = getelementptr inbounds [6 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK-NEXT: store ptr [[A]], ptr [[TMP13]], align 8 +// CHECK-NEXT: [[TMP14:%.*]] = getelementptr inbounds [6 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 +// CHECK-NEXT: store i64 [[TMP11]], ptr [[TMP14]], align 8 +// CHECK-NEXT: [[TMP15:%.*]] = getelementptr inbounds [6 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK-NEXT: store ptr null, ptr [[TMP15]], align 8 +// CHECK-NEXT: [[TMP16:%.*]] = getelementptr inbounds [6 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 1 +// CHECK-NEXT: store ptr [[THIS1]], ptr [[TMP16]], align 8 +// CHECK-NEXT: [[TMP17:%.*]] = getelementptr inbounds [6 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 1 +// CHECK-NEXT: store ptr [[A]], ptr [[TMP17]], align 8 +// CHECK-NEXT: [[TMP18:%.*]] = getelementptr inbounds [6 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 1 +// CHECK-NEXT: store ptr null, ptr [[TMP18]], align 8 +// CHECK-NEXT: [[TMP19:%.*]] = getelementptr inbounds [6 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 2 +// CHECK-NEXT: store ptr [[PTR]], ptr [[TMP19]], align 8 +// CHECK-NEXT: [[TMP20:%.*]] = getelementptr inbounds [6 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 2 +// CHECK-NEXT: store ptr [[ARRAYIDX]], ptr [[TMP20]], align 8 +// CHECK-NEXT: [[TMP21:%.*]] = getelementptr inbounds [6 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 2 +// CHECK-NEXT: store ptr null, ptr [[TMP21]], align 8 +// CHECK-NEXT: [[TMP22:%.*]] = getelementptr inbounds [6 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 3 +// CHECK-NEXT: store ptr [[THIS1]], ptr [[TMP22]], align 8 +// CHECK-NEXT: [[TMP23:%.*]] = getelementptr inbounds [6 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 3 +// CHECK-NEXT: store ptr [[TMP1]], ptr [[TMP23]], align 8 +// CHECK-NEXT: [[TMP24:%.*]] = getelementptr inbounds [6 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 3 +// CHECK-NEXT: store ptr null, ptr [[TMP24]], align 8 +// CHECK-NEXT: [[TMP25:%.*]] = getelementptr inbounds [6 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 4 +// CHECK-NEXT: store ptr [[PTR3]], ptr [[TMP25]], align 8 +// CHECK-NEXT: [[TMP26:%.*]] = getelementptr inbounds [6 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 4 +// CHECK-NEXT: store ptr [[ARRAYIDX5]], ptr [[TMP26]], align 8 +// CHECK-NEXT: [[TMP27:%.*]] = getelementptr inbounds [6 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 4 +// CHECK-NEXT: store ptr null, ptr [[TMP27]], align 8 +// CHECK-NEXT: [[TMP28:%.*]] = getelementptr inbounds [6 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 5 +// CHECK-NEXT: store ptr [[THIS1]], ptr [[TMP28]], align 8 +// CHECK-NEXT: [[TMP29:%.*]] = getelementptr inbounds [6 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 5 +// CHECK-NEXT: store ptr [[ARRAYIDX6]], ptr [[TMP29]], align 8 +// CHECK-NEXT: [[TMP30:%.*]] = getelementptr inbounds [6 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 5 +// CHECK-NEXT: store i64 [[TMP4]], ptr [[TMP30]], align 8 +// CHECK-NEXT: [[TMP31:%.*]] = getelementptr inbounds [6 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 5 +// CHECK-NEXT: store ptr null, ptr [[TMP31]], align 8 +// CHECK-NEXT: [[TMP32:%.*]] = getelementptr inbounds [6 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK-NEXT: [[TMP33:%.*]] = getelementptr inbounds [6 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK-NEXT: [[TMP34:%.*]] = getelementptr inbounds [6 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 +// CHECK-NEXT: call void @__tgt_target_data_begin_mapper(ptr @[[GLOB1]], i64 -1, i32 6, ptr [[TMP32]], ptr [[TMP33]], ptr [[TMP34]], ptr @.offload_maptypes.2, ptr null, ptr null) +// CHECK-NEXT: [[TMP35:%.*]] = load ptr, ptr [[TMP16]], align 8 +// CHECK-NEXT: store ptr [[TMP35]], ptr [[TMP]], align 8 +// CHECK-NEXT: [[TMP36:%.*]] = load ptr, ptr [[TMP19]], align 8 +// CHECK-NEXT: store ptr [[TMP36]], ptr [[_TMP11]], align 8 +// CHECK-NEXT: [[TMP37:%.*]] = load ptr, ptr [[TMP22]], align 8 +// CHECK-NEXT: store ptr [[TMP37]], ptr [[_TMP12]], align 8 +// CHECK-NEXT: [[TMP38:%.*]] = load ptr, ptr [[TMP19]], align 8 +// CHECK-NEXT: store ptr [[TMP38]], ptr [[_TMP13]], align 8 +// CHECK-NEXT: [[TMP39:%.*]] = load ptr, ptr [[TMP28]], align 8 +// CHECK-NEXT: store ptr [[TMP39]], ptr [[_TMP14]], align 8 +// CHECK-NEXT: [[TMP40:%.*]] = load ptr, ptr [[TMP]], align 8, !nonnull [[META3]], !align [[META4]] +// CHECK-NEXT: [[TMP41:%.*]] = load i32, ptr [[TMP40]], align 4 +// CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[TMP41]], 1 +// CHECK-NEXT: store i32 [[INC]], ptr [[TMP40]], align 4 +// CHECK-NEXT: [[TMP42:%.*]] = load ptr, ptr [[_TMP13]], align 8, !nonnull [[META3]], !align [[META5:![0-9]+]] +// CHECK-NEXT: [[TMP43:%.*]] = load ptr, ptr [[TMP42]], align 8 +// CHECK-NEXT: [[TMP44:%.*]] = load i32, ptr [[TMP43]], align 4 +// CHECK-NEXT: [[INC15:%.*]] = add nsw i32 [[TMP44]], 1 +// CHECK-NEXT: store i32 [[INC15]], ptr [[TMP43]], align 4 +// CHECK-NEXT: [[TMP45:%.*]] = load ptr, ptr [[_TMP12]], align 8, !nonnull [[META3]], !align [[META4]] +// CHECK-NEXT: [[TMP46:%.*]] = load i32, ptr [[TMP45]], align 4 +// CHECK-NEXT: [[INC16:%.*]] = add nsw i32 [[TMP46]], 1 +// CHECK-NEXT: store i32 [[INC16]], ptr [[TMP45]], align 4 +// CHECK-NEXT: [[TMP47:%.*]] = load ptr, ptr [[_TMP14]], align 8, !nonnull [[META3]], !align [[META4]] +// CHECK-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds [4 x i32], ptr [[TMP47]], i64 0, i64 0 +// CHECK-NEXT: [[TMP48:%.*]] = load i32, ptr [[ARRAYIDX17]], align 4 +// CHECK-NEXT: [[INC18:%.*]] = add nsw i32 [[TMP48]], 1 +// CHECK-NEXT: store i32 [[INC18]], ptr [[ARRAYIDX17]], align 4 +// CHECK-NEXT: [[TMP49:%.*]] = getelementptr inbounds [6 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK-NEXT: [[TMP50:%.*]] = getelementptr inbounds [6 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK-NEXT: [[TMP51:%.*]] = getelementptr inbounds [6 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 +// CHECK-NEXT: call void @__tgt_target_data_end_mapper(ptr @[[GLOB1]], i64 -1, i32 6, ptr [[TMP49]], ptr [[TMP50]], ptr [[TMP51]], ptr @.offload_maptypes.2, ptr null, ptr null) +// CHECK-NEXT: ret void +// +// +// CHECK-LABEL: define linkonce_odr void @_ZN1SC2Ev( +// CHECK-SAME: ptr noundef nonnull align 8 dereferenceable(40) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] comdat { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// CHECK-NEXT: [[A:%.*]] = getelementptr inbounds nuw [[STRUCT_S:%.*]], ptr [[THIS1]], i32 0, i32 0 +// CHECK-NEXT: store i32 0, ptr [[A]], align 8 +// CHECK-NEXT: [[PTR:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 1 +// CHECK-NEXT: [[A2:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 0 +// CHECK-NEXT: store ptr [[A2]], ptr [[PTR]], align 8 +// CHECK-NEXT: [[REF:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 2 +// CHECK-NEXT: [[A3:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 0 +// CHECK-NEXT: store ptr [[A3]], ptr [[REF]], align 8 +// CHECK-NEXT: ret void +// +// +// OMP60-LABEL: define dso_local noundef signext i32 @main( +// OMP60-SAME: i32 noundef signext [[ARGC:%.*]], ptr noundef [[ARGV:%.*]]) #[[ATTR0:[0-9]+]] { +// OMP60-NEXT: [[ENTRY:.*:]] +// OMP60-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 +// OMP60-NEXT: [[ARGC_ADDR:%.*]] = alloca i32, align 4 +// OMP60-NEXT: [[ARGV_ADDR:%.*]] = alloca ptr, align 8 +// OMP60-NEXT: [[A:%.*]] = alloca float, align 4 +// OMP60-NEXT: [[PTR:%.*]] = alloca ptr, align 8 +// OMP60-NEXT: [[REF:%.*]] = alloca ptr, align 8 +// OMP60-NEXT: [[ARR:%.*]] = alloca [4 x float], align 4 +// OMP60-NEXT: [[SAVED_STACK:%.*]] = alloca ptr, align 8 +// OMP60-NEXT: [[__VLA_EXPR0:%.*]] = alloca i64, align 8 +// OMP60-NEXT: [[S:%.*]] = alloca [[STRUCT_S:%.*]], align 8 +// OMP60-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [9 x ptr], align 8 +// OMP60-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [9 x ptr], align 8 +// OMP60-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [9 x ptr], align 8 +// OMP60-NEXT: [[DOTOFFLOAD_SIZES:%.*]] = alloca [9 x i64], align 8 +// OMP60-NEXT: [[TMP:%.*]] = alloca ptr, align 8 +// OMP60-NEXT: store i32 0, ptr [[RETVAL]], align 4 +// OMP60-NEXT: store i32 [[ARGC]], ptr [[ARGC_ADDR]], align 4 +// OMP60-NEXT: store ptr [[ARGV]], ptr [[ARGV_ADDR]], align 8 +// OMP60-NEXT: store float 0.000000e+00, ptr [[A]], align 4 +// OMP60-NEXT: store ptr [[A]], ptr [[PTR]], align 8 +// OMP60-NEXT: store ptr [[A]], ptr [[REF]], align 8 +// OMP60-NEXT: [[TMP0:%.*]] = load float, ptr [[A]], align 4 +// OMP60-NEXT: [[CONV:%.*]] = fptosi float [[TMP0]] to i32 +// OMP60-NEXT: [[TMP1:%.*]] = zext i32 [[CONV]] to i64 +// OMP60-NEXT: [[TMP2:%.*]] = call ptr @llvm.stacksave.p0() +// OMP60-NEXT: store ptr [[TMP2]], ptr [[SAVED_STACK]], align 8 +// OMP60-NEXT: [[VLA:%.*]] = alloca float, i64 [[TMP1]], align 4 +// OMP60-NEXT: store i64 [[TMP1]], ptr [[__VLA_EXPR0]], align 8 +// OMP60-NEXT: call void @_ZN1SC1Ev(ptr noundef nonnull align 8 dereferenceable(40) [[S]]) +// OMP60-NEXT: call void @_ZN1S3fooEv(ptr noundef nonnull align 8 dereferenceable(40) [[S]]) +// OMP60-NEXT: [[TMP3:%.*]] = load ptr, ptr [[PTR]], align 8 +// OMP60-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw float, ptr [[TMP3]], i64 3 +// OMP60-NEXT: [[TMP4:%.*]] = load ptr, ptr [[PTR]], align 8 +// OMP60-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds float, ptr [[TMP4]], i64 0 +// OMP60-NEXT: [[TMP5:%.*]] = load ptr, ptr [[PTR]], align 8 +// OMP60-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw float, ptr [[TMP5]], i64 0 +// OMP60-NEXT: [[TMP6:%.*]] = load ptr, ptr [[REF]], align 8, !nonnull [[META3:![0-9]+]], !align [[META4:![0-9]+]] +// OMP60-NEXT: [[TMP7:%.*]] = load ptr, ptr [[REF]], align 8, !nonnull [[META3]], !align [[META4]] +// OMP60-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw [4 x float], ptr [[ARR]], i64 0, i64 0 +// OMP60-NEXT: [[TMP8:%.*]] = load float, ptr [[A]], align 4 +// OMP60-NEXT: [[CONV4:%.*]] = fptosi float [[TMP8]] to i32 +// OMP60-NEXT: [[CONV5:%.*]] = sext i32 [[CONV4]] to i64 +// OMP60-NEXT: [[TMP9:%.*]] = mul nuw i64 [[CONV5]], 4 +// OMP60-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds float, ptr [[VLA]], i64 0 +// OMP60-NEXT: [[TMP10:%.*]] = load ptr, ptr [[ARGV_ADDR]], align 8 +// OMP60-NEXT: [[TMP11:%.*]] = load ptr, ptr [[ARGV_ADDR]], align 8 +// OMP60-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds ptr, ptr [[TMP11]], i64 0 +// OMP60-NEXT: [[TMP12:%.*]] = load ptr, ptr [[ARGV_ADDR]], align 8 +// OMP60-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds ptr, ptr [[TMP12]], i64 0 +// OMP60-NEXT: [[TMP13:%.*]] = load ptr, ptr [[ARRAYIDX8]], align 8 +// OMP60-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP13]], i64 0 +// OMP60-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[DOTOFFLOAD_SIZES]], ptr align 8 @.offload_sizes, i64 72, i1 false) +// OMP60-NEXT: [[TMP14:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// OMP60-NEXT: store ptr [[A]], ptr [[TMP14]], align 8 +// OMP60-NEXT: [[TMP15:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// OMP60-NEXT: store ptr [[A]], ptr [[TMP15]], align 8 +// OMP60-NEXT: [[TMP16:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// OMP60-NEXT: store ptr null, ptr [[TMP16]], align 8 +// OMP60-NEXT: [[TMP17:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 1 +// OMP60-NEXT: store ptr [[PTR]], ptr [[TMP17]], align 8 +// OMP60-NEXT: [[TMP18:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 1 +// OMP60-NEXT: store ptr [[ARRAYIDX]], ptr [[TMP18]], align 8 +// OMP60-NEXT: [[TMP19:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 1 +// OMP60-NEXT: store ptr null, ptr [[TMP19]], align 8 +// OMP60-NEXT: [[TMP20:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 2 +// OMP60-NEXT: store ptr [[PTR]], ptr [[TMP20]], align 8 +// OMP60-NEXT: [[TMP21:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 2 +// OMP60-NEXT: store ptr [[ARRAYIDX1]], ptr [[TMP21]], align 8 +// OMP60-NEXT: [[TMP22:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 2 +// OMP60-NEXT: store ptr null, ptr [[TMP22]], align 8 +// OMP60-NEXT: [[TMP23:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 3 +// OMP60-NEXT: store ptr [[PTR]], ptr [[TMP23]], align 8 +// OMP60-NEXT: [[TMP24:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 3 +// OMP60-NEXT: store ptr [[ARRAYIDX2]], ptr [[TMP24]], align 8 +// OMP60-NEXT: [[TMP25:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 3 +// OMP60-NEXT: store ptr null, ptr [[TMP25]], align 8 +// OMP60-NEXT: [[TMP26:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 4 +// OMP60-NEXT: store ptr [[TMP6]], ptr [[TMP26]], align 8 +// OMP60-NEXT: [[TMP27:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 4 +// OMP60-NEXT: store ptr [[TMP7]], ptr [[TMP27]], align 8 +// OMP60-NEXT: [[TMP28:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 4 +// OMP60-NEXT: store ptr null, ptr [[TMP28]], align 8 +// OMP60-NEXT: [[TMP29:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 5 +// OMP60-NEXT: store ptr [[ARR]], ptr [[TMP29]], align 8 +// OMP60-NEXT: [[TMP30:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 5 +// OMP60-NEXT: store ptr [[ARRAYIDX3]], ptr [[TMP30]], align 8 +// OMP60-NEXT: [[TMP31:%.*]] = getelementptr inbounds [9 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 5 +// OMP60-NEXT: store i64 [[TMP9]], ptr [[TMP31]], align 8 +// OMP60-NEXT: [[TMP32:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 5 +// OMP60-NEXT: store ptr null, ptr [[TMP32]], align 8 +// OMP60-NEXT: [[TMP33:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 6 +// OMP60-NEXT: store ptr [[VLA]], ptr [[TMP33]], align 8 +// OMP60-NEXT: [[TMP34:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 6 +// OMP60-NEXT: store ptr [[ARRAYIDX6]], ptr [[TMP34]], align 8 +// OMP60-NEXT: [[TMP35:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 6 +// OMP60-NEXT: store ptr null, ptr [[TMP35]], align 8 +// OMP60-NEXT: [[TMP36:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 7 +// OMP60-NEXT: store ptr [[TMP10]], ptr [[TMP36]], align 8 +// OMP60-NEXT: [[TMP37:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 7 +// OMP60-NEXT: store ptr [[ARRAYIDX7]], ptr [[TMP37]], align 8 +// OMP60-NEXT: [[TMP38:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 7 +// OMP60-NEXT: store ptr null, ptr [[TMP38]], align 8 +// OMP60-NEXT: [[TMP39:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 8 +// OMP60-NEXT: store ptr [[ARRAYIDX7]], ptr [[TMP39]], align 8 +// OMP60-NEXT: [[TMP40:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 8 +// OMP60-NEXT: store ptr [[ARRAYIDX9]], ptr [[TMP40]], align 8 +// OMP60-NEXT: [[TMP41:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 8 +// OMP60-NEXT: store ptr null, ptr [[TMP41]], align 8 +// OMP60-NEXT: [[TMP42:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// OMP60-NEXT: [[TMP43:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// OMP60-NEXT: [[TMP44:%.*]] = getelementptr inbounds [9 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 +// OMP60-NEXT: call void @__tgt_target_data_begin_mapper(ptr @[[GLOB1:[0-9]+]], i64 -1, i32 9, ptr [[TMP42]], ptr [[TMP43]], ptr [[TMP44]], ptr @.offload_maptypes, ptr null, ptr null) +// OMP60-NEXT: [[TMP45:%.*]] = load ptr, ptr [[TMP14]], align 8 +// OMP60-NEXT: [[TMP46:%.*]] = load ptr, ptr [[TMP26]], align 8 +// OMP60-NEXT: store ptr [[TMP46]], ptr [[TMP]], align 8 +// OMP60-NEXT: [[TMP47:%.*]] = load ptr, ptr [[TMP29]], align 8 +// OMP60-NEXT: [[TMP48:%.*]] = load ptr, ptr [[TMP33]], align 8 +// OMP60-NEXT: [[TMP49:%.*]] = load float, ptr [[TMP45]], align 4 +// OMP60-NEXT: [[INC:%.*]] = fadd float [[TMP49]], 1.000000e+00 +// OMP60-NEXT: store float [[INC]], ptr [[TMP45]], align 4 +// OMP60-NEXT: [[TMP50:%.*]] = load ptr, ptr [[TMP17]], align 8 +// OMP60-NEXT: [[TMP51:%.*]] = load float, ptr [[TMP50]], align 4 +// OMP60-NEXT: [[INC10:%.*]] = fadd float [[TMP51]], 1.000000e+00 +// OMP60-NEXT: store float [[INC10]], ptr [[TMP50]], align 4 +// OMP60-NEXT: [[TMP52:%.*]] = load ptr, ptr [[TMP]], align 8, !nonnull [[META3]], !align [[META4]] +// OMP60-NEXT: [[TMP53:%.*]] = load float, ptr [[TMP52]], align 4 +// OMP60-NEXT: [[INC11:%.*]] = fadd float [[TMP53]], 1.000000e+00 +// OMP60-NEXT: store float [[INC11]], ptr [[TMP52]], align 4 +// OMP60-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds [4 x float], ptr [[TMP47]], i64 0, i64 0 +// OMP60-NEXT: [[TMP54:%.*]] = load float, ptr [[ARRAYIDX12]], align 4 +// OMP60-NEXT: [[INC13:%.*]] = fadd float [[TMP54]], 1.000000e+00 +// OMP60-NEXT: store float [[INC13]], ptr [[ARRAYIDX12]], align 4 +// OMP60-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds float, ptr [[TMP48]], i64 0 +// OMP60-NEXT: [[TMP55:%.*]] = load float, ptr [[ARRAYIDX14]], align 4 +// OMP60-NEXT: [[INC15:%.*]] = fadd float [[TMP55]], 1.000000e+00 +// OMP60-NEXT: store float [[INC15]], ptr [[ARRAYIDX14]], align 4 +// OMP60-NEXT: [[TMP56:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// OMP60-NEXT: [[TMP57:%.*]] = getelementptr inbounds [9 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// OMP60-NEXT: [[TMP58:%.*]] = getelementptr inbounds [9 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 +// OMP60-NEXT: call void @__tgt_target_data_end_mapper(ptr @[[GLOB1]], i64 -1, i32 9, ptr [[TMP56]], ptr [[TMP57]], ptr [[TMP58]], ptr @.offload_maptypes, ptr null, ptr null) +// OMP60-NEXT: [[TMP59:%.*]] = load float, ptr [[A]], align 4 +// OMP60-NEXT: [[CONV16:%.*]] = fptosi float [[TMP59]] to i32 +// OMP60-NEXT: store i32 [[CONV16]], ptr [[RETVAL]], align 4 +// OMP60-NEXT: [[TMP60:%.*]] = load ptr, ptr [[SAVED_STACK]], align 8 +// OMP60-NEXT: call void @llvm.stackrestore.p0(ptr [[TMP60]]) +// OMP60-NEXT: [[TMP61:%.*]] = load i32, ptr [[RETVAL]], align 4 +// OMP60-NEXT: ret i32 [[TMP61]] +// +// +// OMP60-LABEL: define linkonce_odr void @_ZN1SC1Ev( +// OMP60-SAME: ptr noundef nonnull align 8 dereferenceable(40) [[THIS:%.*]]) unnamed_addr #[[ATTR2:[0-9]+]] comdat { +// OMP60-NEXT: [[ENTRY:.*:]] +// OMP60-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// OMP60-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 +// OMP60-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// OMP60-NEXT: call void @_ZN1SC2Ev(ptr noundef nonnull align 8 dereferenceable(40) [[THIS1]]) +// OMP60-NEXT: ret void +// +// +// OMP60-LABEL: define linkonce_odr void @_ZN1S3fooEv( +// OMP60-SAME: ptr noundef nonnull align 8 dereferenceable(40) [[THIS:%.*]]) #[[ATTR2]] comdat { +// OMP60-NEXT: [[ENTRY:.*:]] +// OMP60-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// OMP60-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [7 x ptr], align 8 +// OMP60-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [7 x ptr], align 8 +// OMP60-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [7 x ptr], align 8 +// OMP60-NEXT: [[DOTOFFLOAD_SIZES:%.*]] = alloca [7 x i64], align 8 +// OMP60-NEXT: [[TMP:%.*]] = alloca ptr, align 8 +// OMP60-NEXT: [[_TMP14:%.*]] = alloca ptr, align 8 +// OMP60-NEXT: [[_TMP15:%.*]] = alloca ptr, align 8 +// OMP60-NEXT: [[_TMP16:%.*]] = alloca ptr, align 8 +// OMP60-NEXT: [[_TMP17:%.*]] = alloca ptr, align 8 +// OMP60-NEXT: [[_TMP18:%.*]] = alloca ptr, align 8 +// OMP60-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 +// OMP60-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// OMP60-NEXT: [[A:%.*]] = getelementptr inbounds nuw [[STRUCT_S:%.*]], ptr [[THIS1]], i32 0, i32 0 +// OMP60-NEXT: [[PTR:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 1 +// OMP60-NEXT: [[PTR2:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 1 +// OMP60-NEXT: [[TMP0:%.*]] = load ptr, ptr [[PTR2]], align 8 +// OMP60-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP0]], i64 3 +// OMP60-NEXT: [[REF:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 2 +// OMP60-NEXT: [[TMP1:%.*]] = load ptr, ptr [[REF]], align 8, !nonnull [[META3]], !align [[META4]] +// OMP60-NEXT: [[PTR3:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 1 +// OMP60-NEXT: [[PTR4:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 1 +// OMP60-NEXT: [[TMP2:%.*]] = load ptr, ptr [[PTR4]], align 8 +// OMP60-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds i32, ptr [[TMP2]], i64 0 +// OMP60-NEXT: [[ARR:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 3 +// OMP60-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds nuw [4 x i32], ptr [[ARR]], i64 0, i64 0 +// OMP60-NEXT: [[A7:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 0 +// OMP60-NEXT: [[TMP3:%.*]] = load i32, ptr [[A7]], align 8 +// OMP60-NEXT: [[CONV:%.*]] = sext i32 [[TMP3]] to i64 +// OMP60-NEXT: [[TMP4:%.*]] = mul nuw i64 [[CONV]], 4 +// OMP60-NEXT: [[A8:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 0 +// OMP60-NEXT: [[TMP5:%.*]] = load i32, ptr [[A8]], align 8 +// OMP60-NEXT: [[TMP6:%.*]] = sext i32 [[TMP5]] to i64 +// OMP60-NEXT: [[LB_ADD_LEN:%.*]] = add nsw i64 -1, [[TMP6]] +// OMP60-NEXT: [[ARR9:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 3 +// OMP60-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds nuw [4 x i32], ptr [[ARR9]], i64 0, i64 [[LB_ADD_LEN]] +// OMP60-NEXT: [[PTR11:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 1 +// OMP60-NEXT: [[PTR12:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 1 +// OMP60-NEXT: [[TMP7:%.*]] = load ptr, ptr [[PTR12]], align 8 +// OMP60-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds nuw i32, ptr [[TMP7]], i64 0 +// OMP60-NEXT: [[TMP8:%.*]] = getelementptr i32, ptr [[ARRAYIDX10]], i32 1 +// OMP60-NEXT: [[TMP9:%.*]] = ptrtoint ptr [[TMP8]] to i64 +// OMP60-NEXT: [[TMP10:%.*]] = ptrtoint ptr [[A]] to i64 +// OMP60-NEXT: [[TMP11:%.*]] = sub i64 [[TMP9]], [[TMP10]] +// OMP60-NEXT: [[TMP12:%.*]] = sdiv exact i64 [[TMP11]], ptrtoint (ptr getelementptr (i8, ptr null, i32 1) to i64) +// OMP60-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[DOTOFFLOAD_SIZES]], ptr align 8 @.offload_sizes.1, i64 56, i1 false) +// OMP60-NEXT: [[TMP13:%.*]] = getelementptr inbounds [7 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// OMP60-NEXT: store ptr [[THIS1]], ptr [[TMP13]], align 8 +// OMP60-NEXT: [[TMP14:%.*]] = getelementptr inbounds [7 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// OMP60-NEXT: store ptr [[A]], ptr [[TMP14]], align 8 +// OMP60-NEXT: [[TMP15:%.*]] = getelementptr inbounds [7 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 +// OMP60-NEXT: store i64 [[TMP12]], ptr [[TMP15]], align 8 +// OMP60-NEXT: [[TMP16:%.*]] = getelementptr inbounds [7 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// OMP60-NEXT: store ptr null, ptr [[TMP16]], align 8 +// OMP60-NEXT: [[TMP17:%.*]] = getelementptr inbounds [7 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 1 +// OMP60-NEXT: store ptr [[THIS1]], ptr [[TMP17]], align 8 +// OMP60-NEXT: [[TMP18:%.*]] = getelementptr inbounds [7 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 1 +// OMP60-NEXT: store ptr [[A]], ptr [[TMP18]], align 8 +// OMP60-NEXT: [[TMP19:%.*]] = getelementptr inbounds [7 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 1 +// OMP60-NEXT: store ptr null, ptr [[TMP19]], align 8 +// OMP60-NEXT: [[TMP20:%.*]] = getelementptr inbounds [7 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 2 +// OMP60-NEXT: store ptr [[PTR]], ptr [[TMP20]], align 8 +// OMP60-NEXT: [[TMP21:%.*]] = getelementptr inbounds [7 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 2 +// OMP60-NEXT: store ptr [[ARRAYIDX]], ptr [[TMP21]], align 8 +// OMP60-NEXT: [[TMP22:%.*]] = getelementptr inbounds [7 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 2 +// OMP60-NEXT: store ptr null, ptr [[TMP22]], align 8 +// OMP60-NEXT: [[TMP23:%.*]] = getelementptr inbounds [7 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 3 +// OMP60-NEXT: store ptr [[THIS1]], ptr [[TMP23]], align 8 +// OMP60-NEXT: [[TMP24:%.*]] = getelementptr inbounds [7 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 3 +// OMP60-NEXT: store ptr [[TMP1]], ptr [[TMP24]], align 8 +// OMP60-NEXT: [[TMP25:%.*]] = getelementptr inbounds [7 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 3 +// OMP60-NEXT: store ptr null, ptr [[TMP25]], align 8 +// OMP60-NEXT: [[TMP26:%.*]] = getelementptr inbounds [7 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 4 +// OMP60-NEXT: store ptr [[PTR3]], ptr [[TMP26]], align 8 +// OMP60-NEXT: [[TMP27:%.*]] = getelementptr inbounds [7 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 4 +// OMP60-NEXT: store ptr [[ARRAYIDX5]], ptr [[TMP27]], align 8 +// OMP60-NEXT: [[TMP28:%.*]] = getelementptr inbounds [7 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 4 +// OMP60-NEXT: store ptr null, ptr [[TMP28]], align 8 +// OMP60-NEXT: [[TMP29:%.*]] = getelementptr inbounds [7 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 5 +// OMP60-NEXT: store ptr [[THIS1]], ptr [[TMP29]], align 8 +// OMP60-NEXT: [[TMP30:%.*]] = getelementptr inbounds [7 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 5 +// OMP60-NEXT: store ptr [[ARRAYIDX6]], ptr [[TMP30]], align 8 +// OMP60-NEXT: [[TMP31:%.*]] = getelementptr inbounds [7 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 5 +// OMP60-NEXT: store i64 [[TMP4]], ptr [[TMP31]], align 8 +// OMP60-NEXT: [[TMP32:%.*]] = getelementptr inbounds [7 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 5 +// OMP60-NEXT: store ptr null, ptr [[TMP32]], align 8 +// OMP60-NEXT: [[TMP33:%.*]] = getelementptr inbounds [7 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 6 +// OMP60-NEXT: store ptr [[PTR11]], ptr [[TMP33]], align 8 +// OMP60-NEXT: [[TMP34:%.*]] = getelementptr inbounds [7 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 6 +// OMP60-NEXT: store ptr [[ARRAYIDX13]], ptr [[TMP34]], align 8 +// OMP60-NEXT: [[TMP35:%.*]] = getelementptr inbounds [7 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 6 +// OMP60-NEXT: store ptr null, ptr [[TMP35]], align 8 +// OMP60-NEXT: [[TMP36:%.*]] = getelementptr inbounds [7 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// OMP60-NEXT: [[TMP37:%.*]] = getelementptr inbounds [7 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// OMP60-NEXT: [[TMP38:%.*]] = getelementptr inbounds [7 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 +// OMP60-NEXT: call void @__tgt_target_data_begin_mapper(ptr @[[GLOB1]], i64 -1, i32 7, ptr [[TMP36]], ptr [[TMP37]], ptr [[TMP38]], ptr @.offload_maptypes.2, ptr null, ptr null) +// OMP60-NEXT: [[TMP39:%.*]] = load ptr, ptr [[TMP17]], align 8 +// OMP60-NEXT: store ptr [[TMP39]], ptr [[TMP]], align 8 +// OMP60-NEXT: [[TMP40:%.*]] = load ptr, ptr [[TMP20]], align 8 +// OMP60-NEXT: store ptr [[TMP40]], ptr [[_TMP14]], align 8 +// OMP60-NEXT: [[TMP41:%.*]] = load ptr, ptr [[TMP23]], align 8 +// OMP60-NEXT: store ptr [[TMP41]], ptr [[_TMP15]], align 8 +// OMP60-NEXT: [[TMP42:%.*]] = load ptr, ptr [[TMP20]], align 8 +// OMP60-NEXT: store ptr [[TMP42]], ptr [[_TMP16]], align 8 +// OMP60-NEXT: [[TMP43:%.*]] = load ptr, ptr [[TMP29]], align 8 +// OMP60-NEXT: store ptr [[TMP43]], ptr [[_TMP17]], align 8 +// OMP60-NEXT: [[TMP44:%.*]] = load ptr, ptr [[TMP20]], align 8 +// OMP60-NEXT: store ptr [[TMP44]], ptr [[_TMP18]], align 8 +// OMP60-NEXT: [[TMP45:%.*]] = load ptr, ptr [[TMP]], align 8, !nonnull [[META3]], !align [[META4]] +// OMP60-NEXT: [[TMP46:%.*]] = load i32, ptr [[TMP45]], align 4 +// OMP60-NEXT: [[INC:%.*]] = add nsw i32 [[TMP46]], 1 +// OMP60-NEXT: store i32 [[INC]], ptr [[TMP45]], align 4 +// OMP60-NEXT: [[TMP47:%.*]] = load ptr, ptr [[_TMP18]], align 8, !nonnull [[META3]], !align [[META5:![0-9]+]] +// OMP60-NEXT: [[TMP48:%.*]] = load ptr, ptr [[TMP47]], align 8 +// OMP60-NEXT: [[TMP49:%.*]] = load i32, ptr [[TMP48]], align 4 +// OMP60-NEXT: [[INC19:%.*]] = add nsw i32 [[TMP49]], 1 +// OMP60-NEXT: store i32 [[INC19]], ptr [[TMP48]], align 4 +// OMP60-NEXT: [[TMP50:%.*]] = load ptr, ptr [[_TMP15]], align 8, !nonnull [[META3]], !align [[META4]] +// OMP60-NEXT: [[TMP51:%.*]] = load i32, ptr [[TMP50]], align 4 +// OMP60-NEXT: [[INC20:%.*]] = add nsw i32 [[TMP51]], 1 +// OMP60-NEXT: store i32 [[INC20]], ptr [[TMP50]], align 4 +// OMP60-NEXT: [[TMP52:%.*]] = load ptr, ptr [[_TMP17]], align 8, !nonnull [[META3]], !align [[META4]] +// OMP60-NEXT: [[ARRAYIDX21:%.*]] = getelementptr inbounds [4 x i32], ptr [[TMP52]], i64 0, i64 0 +// OMP60-NEXT: [[TMP53:%.*]] = load i32, ptr [[ARRAYIDX21]], align 4 +// OMP60-NEXT: [[INC22:%.*]] = add nsw i32 [[TMP53]], 1 +// OMP60-NEXT: store i32 [[INC22]], ptr [[ARRAYIDX21]], align 4 +// OMP60-NEXT: [[TMP54:%.*]] = getelementptr inbounds [7 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// OMP60-NEXT: [[TMP55:%.*]] = getelementptr inbounds [7 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// OMP60-NEXT: [[TMP56:%.*]] = getelementptr inbounds [7 x i64], ptr [[DOTOFFLOAD_SIZES]], i32 0, i32 0 +// OMP60-NEXT: call void @__tgt_target_data_end_mapper(ptr @[[GLOB1]], i64 -1, i32 7, ptr [[TMP54]], ptr [[TMP55]], ptr [[TMP56]], ptr @.offload_maptypes.2, ptr null, ptr null) +// OMP60-NEXT: ret void +// +// +// OMP60-LABEL: define linkonce_odr void @_ZN1SC2Ev( +// OMP60-SAME: ptr noundef nonnull align 8 dereferenceable(40) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] comdat { +// OMP60-NEXT: [[ENTRY:.*:]] +// OMP60-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// OMP60-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 +// OMP60-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// OMP60-NEXT: [[A:%.*]] = getelementptr inbounds nuw [[STRUCT_S:%.*]], ptr [[THIS1]], i32 0, i32 0 +// OMP60-NEXT: store i32 0, ptr [[A]], align 8 +// OMP60-NEXT: [[PTR:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 1 +// OMP60-NEXT: [[A2:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 0 +// OMP60-NEXT: store ptr [[A2]], ptr [[PTR]], align 8 +// OMP60-NEXT: [[REF:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 2 +// OMP60-NEXT: [[A3:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 0 +// OMP60-NEXT: store ptr [[A3]], ptr [[REF]], align 8 +// OMP60-NEXT: ret void +// +// +// SIMD-ONLY0-LABEL: define dso_local noundef signext i32 @main( +// SIMD-ONLY0-SAME: ) #[[ATTR0:[0-9]+]] { +// SIMD-ONLY0-NEXT: [[ENTRY:.*:]] +// SIMD-ONLY0-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 +// SIMD-ONLY0-NEXT: [[A:%.*]] = alloca float, align 4 +// SIMD-ONLY0-NEXT: [[PTR:%.*]] = alloca ptr, align 8 +// SIMD-ONLY0-NEXT: [[REF:%.*]] = alloca ptr, align 8 +// SIMD-ONLY0-NEXT: [[ARR:%.*]] = alloca [4 x float], align 4 +// SIMD-ONLY0-NEXT: [[SAVED_STACK:%.*]] = alloca ptr, align 8 +// SIMD-ONLY0-NEXT: [[__VLA_EXPR0:%.*]] = alloca i64, align 8 +// SIMD-ONLY0-NEXT: [[S:%.*]] = alloca [[STRUCT_S:%.*]], align 8 +// SIMD-ONLY0-NEXT: [[TMP:%.*]] = alloca ptr, align 8 +// SIMD-ONLY0-NEXT: store i32 0, ptr [[RETVAL]], align 4 +// SIMD-ONLY0-NEXT: store float 0.000000e+00, ptr [[A]], align 4 +// SIMD-ONLY0-NEXT: store ptr [[A]], ptr [[PTR]], align 8 +// SIMD-ONLY0-NEXT: store ptr [[A]], ptr [[REF]], align 8 +// SIMD-ONLY0-NEXT: [[TMP0:%.*]] = load float, ptr [[A]], align 4 +// SIMD-ONLY0-NEXT: [[CONV:%.*]] = fptosi float [[TMP0]] to i32 +// SIMD-ONLY0-NEXT: [[TMP1:%.*]] = zext i32 [[CONV]] to i64 +// SIMD-ONLY0-NEXT: [[TMP2:%.*]] = call ptr @llvm.stacksave.p0() +// SIMD-ONLY0-NEXT: store ptr [[TMP2]], ptr [[SAVED_STACK]], align 8 +// SIMD-ONLY0-NEXT: [[VLA:%.*]] = alloca float, i64 [[TMP1]], align 4 +// SIMD-ONLY0-NEXT: store i64 [[TMP1]], ptr [[__VLA_EXPR0]], align 8 +// SIMD-ONLY0-NEXT: call void @_ZN1SC1Ev(ptr noundef nonnull align 8 dereferenceable(40) [[S]]) +// SIMD-ONLY0-NEXT: call void @_ZN1S3fooEv(ptr noundef nonnull align 8 dereferenceable(40) [[S]]) +// SIMD-ONLY0-NEXT: [[TMP3:%.*]] = load ptr, ptr [[REF]], align 8, !nonnull [[META2:![0-9]+]], !align [[META3:![0-9]+]] +// SIMD-ONLY0-NEXT: store ptr [[TMP3]], ptr [[TMP]], align 8 +// SIMD-ONLY0-NEXT: [[TMP4:%.*]] = load float, ptr [[A]], align 4 +// SIMD-ONLY0-NEXT: [[INC:%.*]] = fadd float [[TMP4]], 1.000000e+00 +// SIMD-ONLY0-NEXT: store float [[INC]], ptr [[A]], align 4 +// SIMD-ONLY0-NEXT: [[TMP5:%.*]] = load ptr, ptr [[PTR]], align 8 +// SIMD-ONLY0-NEXT: [[TMP6:%.*]] = load float, ptr [[TMP5]], align 4 +// SIMD-ONLY0-NEXT: [[INC1:%.*]] = fadd float [[TMP6]], 1.000000e+00 +// SIMD-ONLY0-NEXT: store float [[INC1]], ptr [[TMP5]], align 4 +// SIMD-ONLY0-NEXT: [[TMP7:%.*]] = load ptr, ptr [[TMP]], align 8, !nonnull [[META2]], !align [[META3]] +// SIMD-ONLY0-NEXT: [[TMP8:%.*]] = load float, ptr [[TMP7]], align 4 +// SIMD-ONLY0-NEXT: [[INC2:%.*]] = fadd float [[TMP8]], 1.000000e+00 +// SIMD-ONLY0-NEXT: store float [[INC2]], ptr [[TMP7]], align 4 +// SIMD-ONLY0-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [4 x float], ptr [[ARR]], i64 0, i64 0 +// SIMD-ONLY0-NEXT: [[TMP9:%.*]] = load float, ptr [[ARRAYIDX]], align 4 +// SIMD-ONLY0-NEXT: [[INC3:%.*]] = fadd float [[TMP9]], 1.000000e+00 +// SIMD-ONLY0-NEXT: store float [[INC3]], ptr [[ARRAYIDX]], align 4 +// SIMD-ONLY0-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds float, ptr [[VLA]], i64 0 +// SIMD-ONLY0-NEXT: [[TMP10:%.*]] = load float, ptr [[ARRAYIDX4]], align 4 +// SIMD-ONLY0-NEXT: [[INC5:%.*]] = fadd float [[TMP10]], 1.000000e+00 +// SIMD-ONLY0-NEXT: store float [[INC5]], ptr [[ARRAYIDX4]], align 4 +// SIMD-ONLY0-NEXT: [[TMP11:%.*]] = load float, ptr [[A]], align 4 +// SIMD-ONLY0-NEXT: [[CONV6:%.*]] = fptosi float [[TMP11]] to i32 +// SIMD-ONLY0-NEXT: store i32 [[CONV6]], ptr [[RETVAL]], align 4 +// SIMD-ONLY0-NEXT: [[TMP12:%.*]] = load ptr, ptr [[SAVED_STACK]], align 8 +// SIMD-ONLY0-NEXT: call void @llvm.stackrestore.p0(ptr [[TMP12]]) +// SIMD-ONLY0-NEXT: [[TMP13:%.*]] = load i32, ptr [[RETVAL]], align 4 +// SIMD-ONLY0-NEXT: ret i32 [[TMP13]] +// +// +// SIMD-ONLY0-LABEL: define linkonce_odr void @_ZN1SC1Ev( +// SIMD-ONLY0-SAME: ptr noundef nonnull align 8 dereferenceable(40) [[THIS:%.*]]) unnamed_addr #[[ATTR2:[0-9]+]] comdat { +// SIMD-ONLY0-NEXT: [[ENTRY:.*:]] +// SIMD-ONLY0-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// SIMD-ONLY0-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 +// SIMD-ONLY0-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// SIMD-ONLY0-NEXT: call void @_ZN1SC2Ev(ptr noundef nonnull align 8 dereferenceable(40) [[THIS1]]) +// SIMD-ONLY0-NEXT: ret void +// +// +// SIMD-ONLY0-LABEL: define linkonce_odr void @_ZN1S3fooEv( +// SIMD-ONLY0-SAME: ptr noundef nonnull align 8 dereferenceable(40) [[THIS:%.*]]) #[[ATTR2]] comdat { +// SIMD-ONLY0-NEXT: [[ENTRY:.*:]] +// SIMD-ONLY0-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// SIMD-ONLY0-NEXT: [[A:%.*]] = alloca ptr, align 8 +// SIMD-ONLY0-NEXT: [[PTR:%.*]] = alloca ptr, align 8 +// SIMD-ONLY0-NEXT: [[REF:%.*]] = alloca ptr, align 8 +// SIMD-ONLY0-NEXT: [[PTR5:%.*]] = alloca ptr, align 8 +// SIMD-ONLY0-NEXT: [[ARR:%.*]] = alloca ptr, align 8 +// SIMD-ONLY0-NEXT: [[TMP:%.*]] = alloca ptr, align 8 +// SIMD-ONLY0-NEXT: [[_TMP8:%.*]] = alloca ptr, align 8 +// SIMD-ONLY0-NEXT: [[_TMP9:%.*]] = alloca ptr, align 8 +// SIMD-ONLY0-NEXT: [[_TMP10:%.*]] = alloca ptr, align 8 +// SIMD-ONLY0-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 +// SIMD-ONLY0-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// SIMD-ONLY0-NEXT: [[A2:%.*]] = getelementptr inbounds nuw [[STRUCT_S:%.*]], ptr [[THIS1]], i32 0, i32 0 +// SIMD-ONLY0-NEXT: store ptr [[A2]], ptr [[A]], align 8 +// SIMD-ONLY0-NEXT: [[PTR3:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 1 +// SIMD-ONLY0-NEXT: store ptr [[PTR3]], ptr [[PTR]], align 8 +// SIMD-ONLY0-NEXT: [[REF4:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 2 +// SIMD-ONLY0-NEXT: [[TMP0:%.*]] = load ptr, ptr [[REF4]], align 8, !nonnull [[META2]], !align [[META3]] +// SIMD-ONLY0-NEXT: store ptr [[TMP0]], ptr [[REF]], align 8 +// SIMD-ONLY0-NEXT: [[PTR6:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 1 +// SIMD-ONLY0-NEXT: store ptr [[PTR6]], ptr [[PTR5]], align 8 +// SIMD-ONLY0-NEXT: [[ARR7:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 3 +// SIMD-ONLY0-NEXT: store ptr [[ARR7]], ptr [[ARR]], align 8 +// SIMD-ONLY0-NEXT: [[TMP1:%.*]] = load ptr, ptr [[A]], align 8, !nonnull [[META2]], !align [[META3]] +// SIMD-ONLY0-NEXT: store ptr [[TMP1]], ptr [[TMP]], align 8 +// SIMD-ONLY0-NEXT: [[TMP2:%.*]] = load ptr, ptr [[PTR5]], align 8, !nonnull [[META2]], !align [[META4:![0-9]+]] +// SIMD-ONLY0-NEXT: store ptr [[TMP2]], ptr [[_TMP8]], align 8 +// SIMD-ONLY0-NEXT: [[TMP3:%.*]] = load ptr, ptr [[REF]], align 8, !nonnull [[META2]], !align [[META3]] +// SIMD-ONLY0-NEXT: store ptr [[TMP3]], ptr [[_TMP9]], align 8 +// SIMD-ONLY0-NEXT: [[TMP4:%.*]] = load ptr, ptr [[ARR]], align 8, !nonnull [[META2]], !align [[META3]] +// SIMD-ONLY0-NEXT: store ptr [[TMP4]], ptr [[_TMP10]], align 8 +// SIMD-ONLY0-NEXT: [[TMP5:%.*]] = load ptr, ptr [[TMP]], align 8, !nonnull [[META2]], !align [[META3]] +// SIMD-ONLY0-NEXT: [[TMP6:%.*]] = load i32, ptr [[TMP5]], align 4 +// SIMD-ONLY0-NEXT: [[INC:%.*]] = add nsw i32 [[TMP6]], 1 +// SIMD-ONLY0-NEXT: store i32 [[INC]], ptr [[TMP5]], align 4 +// SIMD-ONLY0-NEXT: [[TMP7:%.*]] = load ptr, ptr [[_TMP8]], align 8, !nonnull [[META2]], !align [[META4]] +// SIMD-ONLY0-NEXT: [[TMP8:%.*]] = load ptr, ptr [[TMP7]], align 8 +// SIMD-ONLY0-NEXT: [[TMP9:%.*]] = load i32, ptr [[TMP8]], align 4 +// SIMD-ONLY0-NEXT: [[INC11:%.*]] = add nsw i32 [[TMP9]], 1 +// SIMD-ONLY0-NEXT: store i32 [[INC11]], ptr [[TMP8]], align 4 +// SIMD-ONLY0-NEXT: [[TMP10:%.*]] = load ptr, ptr [[_TMP9]], align 8, !nonnull [[META2]], !align [[META3]] +// SIMD-ONLY0-NEXT: [[TMP11:%.*]] = load i32, ptr [[TMP10]], align 4 +// SIMD-ONLY0-NEXT: [[INC12:%.*]] = add nsw i32 [[TMP11]], 1 +// SIMD-ONLY0-NEXT: store i32 [[INC12]], ptr [[TMP10]], align 4 +// SIMD-ONLY0-NEXT: [[TMP12:%.*]] = load ptr, ptr [[_TMP10]], align 8, !nonnull [[META2]], !align [[META3]] +// SIMD-ONLY0-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [4 x i32], ptr [[TMP12]], i64 0, i64 0 +// SIMD-ONLY0-NEXT: [[TMP13:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 +// SIMD-ONLY0-NEXT: [[INC13:%.*]] = add nsw i32 [[TMP13]], 1 +// SIMD-ONLY0-NEXT: store i32 [[INC13]], ptr [[ARRAYIDX]], align 4 +// SIMD-ONLY0-NEXT: ret void +// +// +// SIMD-ONLY0-LABEL: define linkonce_odr void @_ZN1SC2Ev( +// SIMD-ONLY0-SAME: ptr noundef nonnull align 8 dereferenceable(40) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] comdat { +// SIMD-ONLY0-NEXT: [[ENTRY:.*:]] +// SIMD-ONLY0-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// SIMD-ONLY0-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 +// SIMD-ONLY0-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// SIMD-ONLY0-NEXT: [[A:%.*]] = getelementptr inbounds nuw [[STRUCT_S:%.*]], ptr [[THIS1]], i32 0, i32 0 +// SIMD-ONLY0-NEXT: store i32 0, ptr [[A]], align 8 +// SIMD-ONLY0-NEXT: [[PTR:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 1 +// SIMD-ONLY0-NEXT: [[A2:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 0 +// SIMD-ONLY0-NEXT: store ptr [[A2]], ptr [[PTR]], align 8 +// SIMD-ONLY0-NEXT: [[REF:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 2 +// SIMD-ONLY0-NEXT: [[A3:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 0 +// SIMD-ONLY0-NEXT: store ptr [[A3]], ptr [[REF]], align 8 +// SIMD-ONLY0-NEXT: ret void +// +// +// SIMD-ONLY0-OMP60-LABEL: define dso_local noundef signext i32 @main( +// SIMD-ONLY0-OMP60-SAME: i32 noundef signext [[ARGC:%.*]], ptr noundef [[ARGV:%.*]]) #[[ATTR0:[0-9]+]] { +// SIMD-ONLY0-OMP60-NEXT: [[ENTRY:.*:]] +// SIMD-ONLY0-OMP60-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 +// SIMD-ONLY0-OMP60-NEXT: [[ARGC_ADDR:%.*]] = alloca i32, align 4 +// SIMD-ONLY0-OMP60-NEXT: [[ARGV_ADDR:%.*]] = alloca ptr, align 8 +// SIMD-ONLY0-OMP60-NEXT: [[A:%.*]] = alloca float, align 4 +// SIMD-ONLY0-OMP60-NEXT: [[PTR:%.*]] = alloca ptr, align 8 +// SIMD-ONLY0-OMP60-NEXT: [[REF:%.*]] = alloca ptr, align 8 +// SIMD-ONLY0-OMP60-NEXT: [[ARR:%.*]] = alloca [4 x float], align 4 +// SIMD-ONLY0-OMP60-NEXT: [[SAVED_STACK:%.*]] = alloca ptr, align 8 +// SIMD-ONLY0-OMP60-NEXT: [[__VLA_EXPR0:%.*]] = alloca i64, align 8 +// SIMD-ONLY0-OMP60-NEXT: [[S:%.*]] = alloca [[STRUCT_S:%.*]], align 8 +// SIMD-ONLY0-OMP60-NEXT: [[TMP:%.*]] = alloca ptr, align 8 +// SIMD-ONLY0-OMP60-NEXT: store i32 0, ptr [[RETVAL]], align 4 +// SIMD-ONLY0-OMP60-NEXT: store i32 [[ARGC]], ptr [[ARGC_ADDR]], align 4 +// SIMD-ONLY0-OMP60-NEXT: store ptr [[ARGV]], ptr [[ARGV_ADDR]], align 8 +// SIMD-ONLY0-OMP60-NEXT: store float 0.000000e+00, ptr [[A]], align 4 +// SIMD-ONLY0-OMP60-NEXT: store ptr [[A]], ptr [[PTR]], align 8 +// SIMD-ONLY0-OMP60-NEXT: store ptr [[A]], ptr [[REF]], align 8 +// SIMD-ONLY0-OMP60-NEXT: [[TMP0:%.*]] = load float, ptr [[A]], align 4 +// SIMD-ONLY0-OMP60-NEXT: [[CONV:%.*]] = fptosi float [[TMP0]] to i32 +// SIMD-ONLY0-OMP60-NEXT: [[TMP1:%.*]] = zext i32 [[CONV]] to i64 +// SIMD-ONLY0-OMP60-NEXT: [[TMP2:%.*]] = call ptr @llvm.stacksave.p0() +// SIMD-ONLY0-OMP60-NEXT: store ptr [[TMP2]], ptr [[SAVED_STACK]], align 8 +// SIMD-ONLY0-OMP60-NEXT: [[VLA:%.*]] = alloca float, i64 [[TMP1]], align 4 +// SIMD-ONLY0-OMP60-NEXT: store i64 [[TMP1]], ptr [[__VLA_EXPR0]], align 8 +// SIMD-ONLY0-OMP60-NEXT: call void @_ZN1SC1Ev(ptr noundef nonnull align 8 dereferenceable(40) [[S]]) +// SIMD-ONLY0-OMP60-NEXT: call void @_ZN1S3fooEv(ptr noundef nonnull align 8 dereferenceable(40) [[S]]) +// SIMD-ONLY0-OMP60-NEXT: [[TMP3:%.*]] = load ptr, ptr [[REF]], align 8, !nonnull [[META2:![0-9]+]], !align [[META3:![0-9]+]] +// SIMD-ONLY0-OMP60-NEXT: store ptr [[TMP3]], ptr [[TMP]], align 8 +// SIMD-ONLY0-OMP60-NEXT: [[TMP4:%.*]] = load float, ptr [[A]], align 4 +// SIMD-ONLY0-OMP60-NEXT: [[INC:%.*]] = fadd float [[TMP4]], 1.000000e+00 +// SIMD-ONLY0-OMP60-NEXT: store float [[INC]], ptr [[A]], align 4 +// SIMD-ONLY0-OMP60-NEXT: [[TMP5:%.*]] = load ptr, ptr [[PTR]], align 8 +// SIMD-ONLY0-OMP60-NEXT: [[TMP6:%.*]] = load float, ptr [[TMP5]], align 4 +// SIMD-ONLY0-OMP60-NEXT: [[INC1:%.*]] = fadd float [[TMP6]], 1.000000e+00 +// SIMD-ONLY0-OMP60-NEXT: store float [[INC1]], ptr [[TMP5]], align 4 +// SIMD-ONLY0-OMP60-NEXT: [[TMP7:%.*]] = load ptr, ptr [[TMP]], align 8, !nonnull [[META2]], !align [[META3]] +// SIMD-ONLY0-OMP60-NEXT: [[TMP8:%.*]] = load float, ptr [[TMP7]], align 4 +// SIMD-ONLY0-OMP60-NEXT: [[INC2:%.*]] = fadd float [[TMP8]], 1.000000e+00 +// SIMD-ONLY0-OMP60-NEXT: store float [[INC2]], ptr [[TMP7]], align 4 +// SIMD-ONLY0-OMP60-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [4 x float], ptr [[ARR]], i64 0, i64 0 +// SIMD-ONLY0-OMP60-NEXT: [[TMP9:%.*]] = load float, ptr [[ARRAYIDX]], align 4 +// SIMD-ONLY0-OMP60-NEXT: [[INC3:%.*]] = fadd float [[TMP9]], 1.000000e+00 +// SIMD-ONLY0-OMP60-NEXT: store float [[INC3]], ptr [[ARRAYIDX]], align 4 +// SIMD-ONLY0-OMP60-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds float, ptr [[VLA]], i64 0 +// SIMD-ONLY0-OMP60-NEXT: [[TMP10:%.*]] = load float, ptr [[ARRAYIDX4]], align 4 +// SIMD-ONLY0-OMP60-NEXT: [[INC5:%.*]] = fadd float [[TMP10]], 1.000000e+00 +// SIMD-ONLY0-OMP60-NEXT: store float [[INC5]], ptr [[ARRAYIDX4]], align 4 +// SIMD-ONLY0-OMP60-NEXT: [[TMP11:%.*]] = load float, ptr [[A]], align 4 +// SIMD-ONLY0-OMP60-NEXT: [[CONV6:%.*]] = fptosi float [[TMP11]] to i32 +// SIMD-ONLY0-OMP60-NEXT: store i32 [[CONV6]], ptr [[RETVAL]], align 4 +// SIMD-ONLY0-OMP60-NEXT: [[TMP12:%.*]] = load ptr, ptr [[SAVED_STACK]], align 8 +// SIMD-ONLY0-OMP60-NEXT: call void @llvm.stackrestore.p0(ptr [[TMP12]]) +// SIMD-ONLY0-OMP60-NEXT: [[TMP13:%.*]] = load i32, ptr [[RETVAL]], align 4 +// SIMD-ONLY0-OMP60-NEXT: ret i32 [[TMP13]] +// +// +// SIMD-ONLY0-OMP60-LABEL: define linkonce_odr void @_ZN1SC1Ev( +// SIMD-ONLY0-OMP60-SAME: ptr noundef nonnull align 8 dereferenceable(40) [[THIS:%.*]]) unnamed_addr #[[ATTR2:[0-9]+]] comdat { +// SIMD-ONLY0-OMP60-NEXT: [[ENTRY:.*:]] +// SIMD-ONLY0-OMP60-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// SIMD-ONLY0-OMP60-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 +// SIMD-ONLY0-OMP60-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// SIMD-ONLY0-OMP60-NEXT: call void @_ZN1SC2Ev(ptr noundef nonnull align 8 dereferenceable(40) [[THIS1]]) +// SIMD-ONLY0-OMP60-NEXT: ret void +// +// +// SIMD-ONLY0-OMP60-LABEL: define linkonce_odr void @_ZN1S3fooEv( +// SIMD-ONLY0-OMP60-SAME: ptr noundef nonnull align 8 dereferenceable(40) [[THIS:%.*]]) #[[ATTR2]] comdat { +// SIMD-ONLY0-OMP60-NEXT: [[ENTRY:.*:]] +// SIMD-ONLY0-OMP60-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// SIMD-ONLY0-OMP60-NEXT: [[A:%.*]] = alloca ptr, align 8 +// SIMD-ONLY0-OMP60-NEXT: [[PTR:%.*]] = alloca ptr, align 8 +// SIMD-ONLY0-OMP60-NEXT: [[REF:%.*]] = alloca ptr, align 8 +// SIMD-ONLY0-OMP60-NEXT: [[PTR5:%.*]] = alloca ptr, align 8 +// SIMD-ONLY0-OMP60-NEXT: [[ARR:%.*]] = alloca ptr, align 8 +// SIMD-ONLY0-OMP60-NEXT: [[PTR8:%.*]] = alloca ptr, align 8 +// SIMD-ONLY0-OMP60-NEXT: [[TMP:%.*]] = alloca ptr, align 8 +// SIMD-ONLY0-OMP60-NEXT: [[_TMP10:%.*]] = alloca ptr, align 8 +// SIMD-ONLY0-OMP60-NEXT: [[_TMP11:%.*]] = alloca ptr, align 8 +// SIMD-ONLY0-OMP60-NEXT: [[_TMP12:%.*]] = alloca ptr, align 8 +// SIMD-ONLY0-OMP60-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 +// SIMD-ONLY0-OMP60-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// SIMD-ONLY0-OMP60-NEXT: [[A2:%.*]] = getelementptr inbounds nuw [[STRUCT_S:%.*]], ptr [[THIS1]], i32 0, i32 0 +// SIMD-ONLY0-OMP60-NEXT: store ptr [[A2]], ptr [[A]], align 8 +// SIMD-ONLY0-OMP60-NEXT: [[PTR3:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 1 +// SIMD-ONLY0-OMP60-NEXT: store ptr [[PTR3]], ptr [[PTR]], align 8 +// SIMD-ONLY0-OMP60-NEXT: [[REF4:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 2 +// SIMD-ONLY0-OMP60-NEXT: [[TMP0:%.*]] = load ptr, ptr [[REF4]], align 8, !nonnull [[META2]], !align [[META3]] +// SIMD-ONLY0-OMP60-NEXT: store ptr [[TMP0]], ptr [[REF]], align 8 +// SIMD-ONLY0-OMP60-NEXT: [[PTR6:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 1 +// SIMD-ONLY0-OMP60-NEXT: store ptr [[PTR6]], ptr [[PTR5]], align 8 +// SIMD-ONLY0-OMP60-NEXT: [[ARR7:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 3 +// SIMD-ONLY0-OMP60-NEXT: store ptr [[ARR7]], ptr [[ARR]], align 8 +// SIMD-ONLY0-OMP60-NEXT: [[PTR9:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 1 +// SIMD-ONLY0-OMP60-NEXT: store ptr [[PTR9]], ptr [[PTR8]], align 8 +// SIMD-ONLY0-OMP60-NEXT: [[TMP1:%.*]] = load ptr, ptr [[A]], align 8, !nonnull [[META2]], !align [[META3]] +// SIMD-ONLY0-OMP60-NEXT: store ptr [[TMP1]], ptr [[TMP]], align 8 +// SIMD-ONLY0-OMP60-NEXT: [[TMP2:%.*]] = load ptr, ptr [[PTR8]], align 8, !nonnull [[META2]], !align [[META4:![0-9]+]] +// SIMD-ONLY0-OMP60-NEXT: store ptr [[TMP2]], ptr [[_TMP10]], align 8 +// SIMD-ONLY0-OMP60-NEXT: [[TMP3:%.*]] = load ptr, ptr [[REF]], align 8, !nonnull [[META2]], !align [[META3]] +// SIMD-ONLY0-OMP60-NEXT: store ptr [[TMP3]], ptr [[_TMP11]], align 8 +// SIMD-ONLY0-OMP60-NEXT: [[TMP4:%.*]] = load ptr, ptr [[ARR]], align 8, !nonnull [[META2]], !align [[META3]] +// SIMD-ONLY0-OMP60-NEXT: store ptr [[TMP4]], ptr [[_TMP12]], align 8 +// SIMD-ONLY0-OMP60-NEXT: [[TMP5:%.*]] = load ptr, ptr [[TMP]], align 8, !nonnull [[META2]], !align [[META3]] +// SIMD-ONLY0-OMP60-NEXT: [[TMP6:%.*]] = load i32, ptr [[TMP5]], align 4 +// SIMD-ONLY0-OMP60-NEXT: [[INC:%.*]] = add nsw i32 [[TMP6]], 1 +// SIMD-ONLY0-OMP60-NEXT: store i32 [[INC]], ptr [[TMP5]], align 4 +// SIMD-ONLY0-OMP60-NEXT: [[TMP7:%.*]] = load ptr, ptr [[_TMP10]], align 8, !nonnull [[META2]], !align [[META4]] +// SIMD-ONLY0-OMP60-NEXT: [[TMP8:%.*]] = load ptr, ptr [[TMP7]], align 8 +// SIMD-ONLY0-OMP60-NEXT: [[TMP9:%.*]] = load i32, ptr [[TMP8]], align 4 +// SIMD-ONLY0-OMP60-NEXT: [[INC13:%.*]] = add nsw i32 [[TMP9]], 1 +// SIMD-ONLY0-OMP60-NEXT: store i32 [[INC13]], ptr [[TMP8]], align 4 +// SIMD-ONLY0-OMP60-NEXT: [[TMP10:%.*]] = load ptr, ptr [[_TMP11]], align 8, !nonnull [[META2]], !align [[META3]] +// SIMD-ONLY0-OMP60-NEXT: [[TMP11:%.*]] = load i32, ptr [[TMP10]], align 4 +// SIMD-ONLY0-OMP60-NEXT: [[INC14:%.*]] = add nsw i32 [[TMP11]], 1 +// SIMD-ONLY0-OMP60-NEXT: store i32 [[INC14]], ptr [[TMP10]], align 4 +// SIMD-ONLY0-OMP60-NEXT: [[TMP12:%.*]] = load ptr, ptr [[_TMP12]], align 8, !nonnull [[META2]], !align [[META3]] +// SIMD-ONLY0-OMP60-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [4 x i32], ptr [[TMP12]], i64 0, i64 0 +// SIMD-ONLY0-OMP60-NEXT: [[TMP13:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 +// SIMD-ONLY0-OMP60-NEXT: [[INC15:%.*]] = add nsw i32 [[TMP13]], 1 +// SIMD-ONLY0-OMP60-NEXT: store i32 [[INC15]], ptr [[ARRAYIDX]], align 4 +// SIMD-ONLY0-OMP60-NEXT: ret void +// +// +// SIMD-ONLY0-OMP60-LABEL: define linkonce_odr void @_ZN1SC2Ev( +// SIMD-ONLY0-OMP60-SAME: ptr noundef nonnull align 8 dereferenceable(40) [[THIS:%.*]]) unnamed_addr #[[ATTR2]] comdat { +// SIMD-ONLY0-OMP60-NEXT: [[ENTRY:.*:]] +// SIMD-ONLY0-OMP60-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// SIMD-ONLY0-OMP60-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 +// SIMD-ONLY0-OMP60-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// SIMD-ONLY0-OMP60-NEXT: [[A:%.*]] = getelementptr inbounds nuw [[STRUCT_S:%.*]], ptr [[THIS1]], i32 0, i32 0 +// SIMD-ONLY0-OMP60-NEXT: store i32 0, ptr [[A]], align 8 +// SIMD-ONLY0-OMP60-NEXT: [[PTR:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 1 +// SIMD-ONLY0-OMP60-NEXT: [[A2:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 0 +// SIMD-ONLY0-OMP60-NEXT: store ptr [[A2]], ptr [[PTR]], align 8 +// SIMD-ONLY0-OMP60-NEXT: [[REF:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 2 +// SIMD-ONLY0-OMP60-NEXT: [[A3:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[THIS1]], i32 0, i32 0 +// SIMD-ONLY0-OMP60-NEXT: store ptr [[A3]], ptr [[REF]], align 8 +// SIMD-ONLY0-OMP60-NEXT: ret void +// +//. +// CHECK: [[META3]] = !{} +// CHECK: [[META4]] = !{i64 4} +// CHECK: [[META5]] = !{i64 8} +//. +// OMP60: [[META3]] = !{} +// OMP60: [[META4]] = !{i64 4} +// OMP60: [[META5]] = !{i64 8} +//. +// SIMD-ONLY0: [[META2]] = !{} +// SIMD-ONLY0: [[META3]] = !{i64 4} +// SIMD-ONLY0: [[META4]] = !{i64 8} +//. +// SIMD-ONLY0-OMP60: [[META2]] = !{} +// SIMD-ONLY0-OMP60: [[META3]] = !{i64 4} +// SIMD-ONLY0-OMP60: [[META4]] = !{i64 8} +//. diff --git a/clang/test/OpenMP/target_has_device_addr_messages.cpp b/clang/test/OpenMP/target_has_device_addr_messages.cpp index 532ace5caf0a0..bac6fc06d6a16 100644 --- a/clang/test/OpenMP/target_has_device_addr_messages.cpp +++ b/clang/test/OpenMP/target_has_device_addr_messages.cpp @@ -4,9 +4,16 @@ // RUN: %clang_cc1 -std=c++11 -verify \ // RUN: -fopenmp-simd -ferror-limit 200 %s -Wuninitialized +// RUN: %clang_cc1 -std=c++11 -verify \ +// RUN: -fopenmp -fopenmp-version=60 -ferror-limit 200 %s -Wuninitialized + +// RUN: %clang_cc1 -std=c++11 -verify \ +// RUN: -fopenmp-simd -fopenmp-version=60 -ferror-limit 200 %s -Wuninitialized + struct ST { int *a; }; + typedef int arr[10]; typedef ST STarr[10]; struct SA { @@ -133,9 +140,9 @@ typedef struct { int a; } S6; -template -T tmain(T argc) { - const T d = 5; +template +T tfoo(T argc, S ub[]) { + const T d = I; const T da[5] = { 0 }; S4 e(4); S5 g(5); @@ -200,10 +207,14 @@ T tmain(T argc) { {} #pragma omp target private(ps) has_device_addr(ps) // expected-error{{private variable cannot be in a has_device_addr clause in '#pragma omp target' directive}} expected-note{{defined as private}} {} +#pragma omp target has_device_addr(ps[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} + {} +#pragma omp target has_device_addr(ub[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is an array of unknown bound}} + {} return 0; } -int main(int argc, char **argv) { +int foo(int argc, float ub[]) { const int d = 5; const int da[5] = { 0 }; S4 e(4); @@ -269,5 +280,10 @@ int main(int argc, char **argv) { {} #pragma omp target private(ps) has_device_addr(ps) // expected-error{{private variable cannot be in a has_device_addr clause in '#pragma omp target' directive}} expected-note{{defined as private}} {} - return tmain(argc); +#pragma omp target has_device_addr(ps[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} + {} +#pragma omp target has_device_addr(ub[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is an array of unknown bound}} + {} + return tfoo(argc, ub); // expected-note {{in instantiation of function template specialization 'tfoo' requested here}} + } diff --git a/clang/test/OpenMP/task_in_reduction_message.cpp b/clang/test/OpenMP/task_in_reduction_message.cpp index dceefef90c2f2..7979f70aa9699 100644 --- a/clang/test/OpenMP/task_in_reduction_message.cpp +++ b/clang/test/OpenMP/task_in_reduction_message.cpp @@ -1,16 +1,17 @@ -// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 150 -o - %s -// RUN: %clang_cc1 -verify -fopenmp -std=c++98 -ferror-limit 150 -o - %s -// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ferror-limit 150 -o - %s -// RUN: %clang_cc1 -verify=expected,omp52 -fopenmp -fopenmp-version=52 -ferror-limit 150 -o - %s -// RUN: %clang_cc1 -verify=expected,omp52 -fopenmp -fopenmp-version=52 -std=c++98 -ferror-limit 150 -o - %s -// RUN: %clang_cc1 -verify=expected,omp52 -fopenmp -fopenmp-version=52 -std=c++11 -ferror-limit 150 -o - %s +// RUN: %clang_cc1 -verify=expected,omp-lt60 -fopenmp -std=c++98 -ferror-limit 150 -o - %s +// RUN: %clang_cc1 -verify=expected,omp-lt60 -fopenmp -std=c++11 -ferror-limit 150 -o - %s +// RUN: %clang_cc1 -verify=expected,omp52,omp-lt60 -fopenmp -fopenmp-version=52 -ferror-limit 150 -o - %s +// RUN: %clang_cc1 -verify=expected,omp52,omp-lt60 -fopenmp -fopenmp-version=52 -std=c++98 -ferror-limit 150 -o - %s +// RUN: %clang_cc1 -verify=expected,omp52,omp-lt60 -fopenmp -fopenmp-version=52 -std=c++11 -ferror-limit 150 -o - %s +// RUN: %clang_cc1 -verify=expected,omp-ge60 -fopenmp -fopenmp-version=60 -ferror-limit 150 -o - %s -// RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 150 -o - %s -// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++98 -ferror-limit 150 -o - %s -// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++11 -ferror-limit 150 -o - %s -// RUN: %clang_cc1 -verify=expected,omp52 -fopenmp-simd -fopenmp-version=52 -ferror-limit 150 -o - %s -// RUN: %clang_cc1 -verify=expected,omp52 -fopenmp-simd -fopenmp-version=52 -std=c++98 -ferror-limit 150 -o - %s -// RUN: %clang_cc1 -verify=expected,omp52 -fopenmp-simd -fopenmp-version=52 -std=c++11 -ferror-limit 150 -o - %s +// RUN: %clang_cc1 -verify=expected,omp-lt60 -fopenmp-simd -ferror-limit 150 -o - %s +// RUN: %clang_cc1 -verify=expected,omp-lt60 -fopenmp-simd -std=c++98 -ferror-limit 150 -o - %s +// RUN: %clang_cc1 -verify=expected,omp-lt60 -fopenmp-simd -std=c++11 -ferror-limit 150 -o - %s +// RUN: %clang_cc1 -verify=expected,omp52,omp-lt60 -fopenmp-simd -fopenmp-version=52 -ferror-limit 150 -o - %s +// RUN: %clang_cc1 -verify=expected,omp52,omp-lt60 -fopenmp-simd -fopenmp-version=52 -std=c++98 -ferror-limit 150 -o - %s +// RUN: %clang_cc1 -verify=expected,omp52,omp-lt60 -fopenmp-simd -fopenmp-version=52 -std=c++11 -ferror-limit 150 -o - %s +// RUN: %clang_cc1 -verify=expected,omp-ge60 -fopenmp-simd -fopenmp-version=60 -std=c++11 -ferror-limit 150 -o - %s // SIMD-ONLY0-NOT: {{__kmpc|__tgt}} typedef void **omp_allocator_handle_t; @@ -39,7 +40,7 @@ void foobar(int &ref) { void foobar1(int &ref) { #pragma omp taskgroup task_reduction(+:ref) -#pragma omp task in_reduction(-:ref) // omp52-warning {{minus(-) operator for reductions is deprecated; use + or user defined reduction instead}} +#pragma omp task in_reduction(-:ref) // omp52-warning {{minus(-) operator for reductions is deprecated; use + or user defined reduction instead}} omp-ge60-error {{incorrect reduction identifier, expected one of '+', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int}} foo(); } @@ -123,8 +124,8 @@ class S6 { // expected-note 3 {{candidate function (the implicit copy assignment S3 h, k; #pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} -template // expected-note {{declared here}} -T tmain(T argc) { +template // expected-note {{declared here}} +T tfoobar5(T argc, S ub[]) { const T d = T(); // expected-note 4 {{'d' defined here}} const T da[5] = {T()}; // expected-note 2 {{'da' defined here}} T qa[5] = {T()}; @@ -134,6 +135,7 @@ T tmain(T argc) { const T &r = da[(int)i]; // expected-note 2 {{'r' defined here}} T &q = qa[(int)i]; T fl; + T *ptr; #pragma omp taskgroup task_reduction(+:argc) #pragma omp task in_reduction // expected-error {{expected '(' after 'in_reduction'}} foo(); @@ -163,7 +165,7 @@ T tmain(T argc) { foo(); #pragma omp task in_reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name, array element or array section}} foo(); -#pragma omp task in_reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}} +#pragma omp task in_reduction(foo : argc) //omp-lt60-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} omp-lt60-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}} omp-ge60-error {{incorrect reduction identifier, expected one of '+', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}} omp-ge60-error {{incorrect reduction identifier, expected one of '+', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} foo(); #pragma omp taskgroup task_reduction(&&:argc) #pragma omp task in_reduction(&& : argc) @@ -210,11 +212,15 @@ T tmain(T argc) { #pragma omp task in_reduction(+ : fl) foo(); #pragma omp parallel -#pragma omp for reduction(- : fl) // omp52-warning 3 {{minus(-) operator for reductions is deprecated; use + or user defined reduction instead}} +#pragma omp for reduction(- : fl) // omp52-warning 3 {{minus(-) operator for reductions is deprecated; use + or user defined reduction instead}} omp-ge60-error {{incorrect reduction identifier, expected one of '+', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}} omp-ge60-error {{incorrect reduction identifier, expected one of '+', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} for (int i = 0; i < 10; ++i) #pragma omp taskgroup task_reduction(+:fl) #pragma omp task in_reduction(+ : fl) foo(); +#pragma omp task in_reduction(min:ub[:]) // expected-error 2 {{section length is unspecified and cannot be inferred because subscripted value is an array of unknown bound}} + foo(); +#pragma omp task in_reduction(min:ptr[:]) // expected-error 2 {{section length is unspecified and cannot be inferred because subscripted value is not an array}} + foo(); return T(); } @@ -227,7 +233,7 @@ namespace B { using A::x; } -int main(int argc, char **argv) { +int foobar5(int argc, float ub[]) { const int d = 5; // expected-note 2 {{'d' defined here}} const int da[5] = {0}; // expected-note {{'da' defined here}} int qa[5] = {0}; @@ -239,6 +245,7 @@ int main(int argc, char **argv) { const int &r = da[i]; // expected-note {{'r' defined here}} int &q = qa[i]; float fl; + float *ptr; #pragma omp task in_reduction // expected-error {{expected '(' after 'in_reduction'}} foo(); #pragma omp task in_reduction + // expected-error {{expected '(' after 'in_reduction'}} expected-warning {{extra tokens at the end of '#pragma omp task' are ignored}} @@ -253,7 +260,7 @@ int main(int argc, char **argv) { foo(); #pragma omp task in_reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} foo(); -#pragma omp task in_reduction(foo : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}} +#pragma omp task in_reduction(foo : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} omp-lt60-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}} omp-ge60-error {{incorrect reduction identifier, expected one of '+', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}} foo(); #pragma omp taskgroup task_reduction(|:argc) { @@ -262,10 +269,10 @@ int main(int argc, char **argv) { #pragma omp task in_reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{in_reduction variable must have the same reduction operation as in a task_reduction clause}} foo(); } -#pragma omp task in_reduction(| : argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}} +#pragma omp task in_reduction(| : argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: ub), allocate(ub) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}} foo(); } -#pragma omp task in_reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name, array element or array section}} +#pragma omp task in_reduction(|| : argc > 0 ? ub[1] : ub[2]) // expected-error {{expected variable name, array element or array section}} foo(); #pragma omp task in_reduction(~ : argc) // expected-error {{expected unqualified-id}} foo(); @@ -325,6 +332,10 @@ int main(int argc, char **argv) { #pragma omp taskgroup task_reduction(+:m) #pragma omp task in_reduction(+ : m) // OK m++; +#pragma omp task in_reduction(min:ub[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is an array of unknown bound}} + foo(); +#pragma omp task in_reduction(min:ptr[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} + foo(); - return tmain(argc) + tmain(fl); // expected-note {{in instantiation of function template specialization 'tmain' requested here}} expected-note {{in instantiation of function template specialization 'tmain' requested here}} + return tfoobar5(argc, ub) + tfoobar5(fl, ub); // expected-note {{in instantiation of function template specialization 'tfoobar5' requested here}} expected-note {{in instantiation of function template specialization 'tfoobar5' requested here}} } diff --git a/clang/test/OpenMP/taskgroup_task_reduction_messages.cpp b/clang/test/OpenMP/taskgroup_task_reduction_messages.cpp index e038b5edf2066..08b4bf2bbe721 100644 --- a/clang/test/OpenMP/taskgroup_task_reduction_messages.cpp +++ b/clang/test/OpenMP/taskgroup_task_reduction_messages.cpp @@ -92,8 +92,8 @@ class S6 { // expected-note 3 {{candidate function (the implicit copy assignment S3 h, k; #pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} -template // expected-note {{declared here}} -T tmain(T argc) { +template // expected-note {{declared here}} +T tfoobar2(T argc, S ub[]) { const T d = T(); // expected-note 4 {{'d' defined here}} const T da[5] = {T()}; // expected-note 2 {{'da' defined here}} T qa[5] = {T()}; @@ -103,6 +103,7 @@ T tmain(T argc) { const T &r = da[(int)i]; // expected-note 2 {{'r' defined here}} T &q = qa[(int)i]; T fl; + T *ptr; #pragma omp taskgroup task_reduction // expected-error {{expected '(' after 'task_reduction'}} foo(); #pragma omp taskgroup task_reduction + // expected-error {{expected '(' after 'task_reduction'}} expected-warning {{extra tokens at the end of '#pragma omp taskgroup' are ignored}} @@ -125,7 +126,7 @@ T tmain(T argc) { foo(); #pragma omp taskgroup task_reduction(foo : argc) //omp51-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} omp51-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}} omp52-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} omp52-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}} omp60-error {{incorrect reduction identifier, expected one of '+', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} omp60-error {{incorrect reduction identifier, expected one of '+', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}} foo(); -#pragma omp taskgroup task_reduction(&& : argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}} +#pragma omp taskgroup task_reduction(&& : argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: ub), allocate(ub) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}} foo(); #pragma omp taskgroup task_reduction(^ : T) // expected-error {{'T' does not refer to a value}} foo(); @@ -172,6 +173,10 @@ T tmain(T argc) { for (int i = 0; i < 10; ++i) #pragma omp taskgroup task_reduction(+ : fl) foo(); +#pragma omp taskgroup task_reduction(+:ub[1:]) // expected-error 2 {{section length is unspecified and cannot be inferred because subscripted value is an array of unknown bound}} + foo(); +#pragma omp taskgroup task_reduction(+:ptr[:]) // expected-error 2 {{section length is unspecified and cannot be inferred because subscripted value is not an array}} + foo(); return T(); } @@ -184,7 +189,7 @@ namespace B { using A::x; } -int main(int argc, char **argv) { +int foobar2(int argc, float ub[]) { const int d = 5; // expected-note 2 {{'d' defined here}} const int da[5] = {0}; // expected-note {{'da' defined here}} int qa[5] = {0}; @@ -196,6 +201,7 @@ int main(int argc, char **argv) { const int &r = da[i]; // expected-note {{'r' defined here}} int &q = qa[i]; float fl; + float *ptr; #pragma omp taskgroup task_reduction // expected-error {{expected '(' after 'task_reduction'}} foo(); #pragma omp taskgroup task_reduction + // expected-error {{expected '(' after 'task_reduction'}} expected-warning {{extra tokens at the end of '#pragma omp taskgroup' are ignored}} @@ -214,7 +220,7 @@ int main(int argc, char **argv) { foo(); #pragma omp taskgroup task_reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} foo(); -#pragma omp taskgroup task_reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name, array element or array section}} +#pragma omp taskgroup task_reduction(|| : argc > 0 ? ub[1] : ub[2]) // expected-error {{expected variable name, array element or array section}} foo(); #pragma omp taskgroup task_reduction(~ : argc) // expected-error {{expected unqualified-id}} foo(); @@ -270,6 +276,10 @@ int main(int argc, char **argv) { static int m; #pragma omp taskgroup task_reduction(+ : m) // OK m++; +#pragma omp taskgroup task_reduction(+:ub[1:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is an array of unknown bound}} + foo(); +#pragma omp taskgroup task_reduction(+:ptr[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} + foo(); - return tmain(argc) + tmain(fl); // expected-note {{in instantiation of function template specialization 'tmain' requested here}} expected-note {{in instantiation of function template specialization 'tmain' requested here}} + return tfoobar2(argc, ub) + tfoobar2(fl, ub); // expected-note {{in instantiation of function template specialization 'tfoobar2' requested here}} expected-note {{in instantiation of function template specialization 'tfoobar2' requested here}} } diff --git a/clang/test/OpenMP/teams_reduction_messages.cpp b/clang/test/OpenMP/teams_reduction_messages.cpp index c980dfa61ef2a..b22659cb609d1 100644 --- a/clang/test/OpenMP/teams_reduction_messages.cpp +++ b/clang/test/OpenMP/teams_reduction_messages.cpp @@ -107,8 +107,8 @@ class S6 { // expected-note 3 {{candidate function (the implicit copy assignment S3 h, k; #pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} -template // expected-note {{declared here}} -T tmain(T argc) { +template // expected-note {{declared here}} +T tfoobar2(T argc, S ub) { const T d = T(); // expected-note 4 {{'d' defined here}} const T da[5] = {T()}; // expected-note 2 {{'da' defined here}} T qa[5] = {T()}; @@ -118,6 +118,7 @@ T tmain(T argc) { const T &r = da[(int)i]; // expected-note 2 {{'r' defined here}} T &q = qa[(int)i]; // expected-note 2 {{'q' defined here}} T fl; + T *ptr; #pragma omp target #pragma omp teams reduction // expected-error {{expected '(' after 'reduction'}} foo(); @@ -152,7 +153,7 @@ T tmain(T argc) { #pragma omp teams reduction(foo : argc) //omp45-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} omp45-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}} omp51-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} omp51-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}} omp52-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} omp52-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}} omp60-error {{incorrect reduction identifier, expected one of '+', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} omp60-error {{incorrect reduction identifier, expected one of '+', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}} foo(); #pragma omp target -#pragma omp teams reduction(&& : argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}} +#pragma omp teams reduction(&& : argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: ub), allocate(ub) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}} foo(); #pragma omp target #pragma omp teams reduction(^ : T) // expected-error {{'T' does not refer to a value}} @@ -224,6 +225,12 @@ T tmain(T argc) { #pragma omp target #pragma omp teams reduction(+ : fl) foo(); +#pragma omp target +#pragma omp teams reduction(+ : ptr[0:]) // expected-error 2 {{section length is unspecified and cannot be inferred because subscripted value is not an array}} + foo(); +#pragma omp target +#pragma omp teams reduction(* : ub[:]) // expected-error 2 {{section length is unspecified and cannot be inferred because subscripted value is an array of unknown bound}} + foo(); return T(); } @@ -236,7 +243,7 @@ namespace B { using A::x; } -int main(int argc, char **argv) { +int foobar2(int argc, float ub[]) { const int d = 5; // expected-note 2 {{'d' defined here}} const int da[5] = {0}; // expected-note {{'da' defined here}} int qa[5] = {0}; @@ -248,6 +255,7 @@ int main(int argc, char **argv) { const int &r = da[i]; // expected-note {{'r' defined here}} int &q = qa[i]; // expected-note {{'q' defined here}} float fl; + float *ptr; #pragma omp target #pragma omp teams reduction // expected-error {{expected '(' after 'reduction'}} foo(); @@ -276,7 +284,7 @@ int main(int argc, char **argv) { #pragma omp teams reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} foo(); #pragma omp target -#pragma omp teams reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name, array element or array section}} +#pragma omp teams reduction(|| : argc > 0 ? ub[1] : ub[2]) // expected-error {{expected variable name, array element or array section}} foo(); #pragma omp target #pragma omp teams reduction(~ : argc) // expected-error {{expected unqualified-id}} @@ -364,6 +372,12 @@ int main(int argc, char **argv) { #pragma omp target #pragma omp teams reduction(task, + : m) // omp45-error 2 {{expected expression}} omp45-warning {{missing ':' after reduction identifier - ignoring}} omp51-error {{'reduction' clause with 'task' modifier allowed only on non-simd parallel or worksharing constructs}} omp52-error {{'reduction' clause with 'task' modifier allowed only on non-simd parallel or worksharing constructs}} omp60-error {{'reduction' clause with 'task' modifier allowed only on non-simd parallel or worksharing constructs}} foo(); +#pragma omp target +#pragma omp teams reduction(+ : ptr[0:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} + foo(); +#pragma omp target +#pragma omp teams reduction(* : ub[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is an array of unknown bound}} + foo(); - return tmain(argc) + tmain(fl); // expected-note {{in instantiation of function template specialization 'tmain' requested here}} expected-note {{in instantiation of function template specialization 'tmain' requested here}} + return tfoobar2(argc, ub) + tfoobar2(fl, ub); // expected-note {{in instantiation of function template specialization 'tfoobar2' requested here}} expected-note {{in instantiation of function template specialization 'tfoobar2' requested here}} }