https://github.com/amitamd7 updated https://github.com/llvm/llvm-project/pull/170287
>From f394b935494d2f9614ff821f6e5fc0fb7fdd2361 Mon Sep 17 00:00:00 2001 From: amtiwari <[email protected]> Date: Mon, 8 Sep 2025 08:23:21 -0400 Subject: [PATCH 1/5] handle_array_pointer_var_check --- clang/lib/CodeGen/CGOpenMPRuntime.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp index a8255ac74cfcf..d9e3f5ed61e83 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -8239,10 +8239,12 @@ class MappableExprsHandler { ElementType = CAT->getElementType().getTypePtr(); else if (VAT) ElementType = VAT->getElementType().getTypePtr(); - else - assert(&Component == &*Components.begin() && - "Only expect pointer (non CAT or VAT) when this is the " - "first Component"); + else if (&Component == &*Components.begin()) { + // Handle pointer-based array sections like data[a:b:c] + if (const auto *PtrType = Ty->getAs<PointerType>()) { + ElementType = PtrType->getPointeeType().getTypePtr(); + } + } // If ElementType is null, then it means the base is a pointer // (neither CAT nor VAT) and we'll attempt to get ElementType again // for next iteration. >From 4762b1159d370b8722d7733fb9cdfcab950e5658 Mon Sep 17 00:00:00 2001 From: amtiwari <[email protected]> Date: Fri, 21 Nov 2025 06:47:59 -0500 Subject: [PATCH 2/5] plugin_interface_issue_fix --- clang/lib/CodeGen/CGOpenMPRuntime.cpp | 30 +++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp index d9e3f5ed61e83..a0b373478b19b 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -8240,14 +8240,25 @@ class MappableExprsHandler { else if (VAT) ElementType = VAT->getElementType().getTypePtr(); else if (&Component == &*Components.begin()) { - // Handle pointer-based array sections like data[a:b:c] + // If the base is a raw pointer (e.g. T *data with data[a:b:c]), + // there was no earlier CAT/VAT/array handling to establish + // ElementType. Capture the pointee type now so that subsequent + // components (offset/length/stride) have a concrete element type to + // work with. This makes pointer-backed sections behave consistently + // with CAT/VAT/array bases. if (const auto *PtrType = Ty->getAs<PointerType>()) { ElementType = PtrType->getPointeeType().getTypePtr(); } + } else { + // Any component after the first should never have a raw pointer type; + // by this point. ElementType must already be known (set above or in + // prior array / CAT / VAT handling). + assert(!Ty->isPointerType() && + "Non-first components should not be raw pointers"); } - // If ElementType is null, then it means the base is a pointer - // (neither CAT nor VAT) and we'll attempt to get ElementType again - // for next iteration. + + // At this stage, if ElementType was a base pointer and we are in the + // first iteration, it has been computed. if (ElementType) { // For the case that having pointer as base, we need to remove one // level of indirection. @@ -8957,8 +8968,15 @@ class MappableExprsHandler { // If there is an entry in PartialStruct it means we have a struct with // individual members mapped. Emit an extra combined entry. if (PartialStruct.Base.isValid()) { - UnionCurInfo.NonContigInfo.Dims.push_back(0); - // Emit a combined entry: + // Prepend a synthetic dimension of length 1 to represent the + // aggregated struct object. Using 1 (not 0, as 0 produced an + // incorrect non-contiguous descriptor (DimSize==1), causing the + // non-contiguous motion clause path to be skipped.) is important: + // * It preserves the correct rank so targetDataUpdate() computes + // DimSize == 2 for cases like strided array sections originating + // from user-defined mappers (e.g. test with s.data[0:8:2]). + UnionCurInfo.NonContigInfo.Dims.insert( + UnionCurInfo.NonContigInfo.Dims.begin(), 1); emitCombinedEntry(CombinedInfo, UnionCurInfo.Types, PartialStruct, /*IsMapThis*/ !VD, OMPBuilder, VD); } >From b651261614a57e22c4cc240e90fbdd34c9d54adf Mon Sep 17 00:00:00 2001 From: amtiwari <[email protected]> Date: Mon, 24 Nov 2025 05:55:21 -0500 Subject: [PATCH 3/5] testing_extern --- clang/lib/CodeGen/CGOpenMPRuntime.cpp | 2 +- clang/test/OpenMP/target_update_codegen.cpp | 9 +- clang/test/OpenMP/target_update_codegen.ll | 26 ++++ .../target_update_strided_ptr_messages_from.c | 44 ++++++ .../target_update_strided_ptr_messages_to.c | 41 ++++++ ...pdate_strided_ptr_multiple_messages_from.c | 64 +++++++++ ..._update_strided_ptr_multiple_messages_to.c | 64 +++++++++ ...update_strided_ptr_partial_messages_from.c | 41 ++++++ ...t_update_strided_ptr_partial_messages_to.c | 40 ++++++ .../strided_ptr_multiple_update_from.c | 114 +++++++++++++++ .../strided_ptr_multiple_update_to.c | 130 +++++++++++++++++ .../strided_ptr_partial_update_from.c | 68 +++++++++ .../strided_ptr_partial_update_to.c | 81 +++++++++++ offload/test/offloading/target_update_from.c | 73 ++++++++++ .../target_update_strided_struct_from.c | 86 +++++++++++ ...rget_update_strided_struct_multiple_from.c | 130 +++++++++++++++++ ...target_update_strided_struct_multiple_to.c | 136 ++++++++++++++++++ ...arget_update_strided_struct_partial_from.c | 86 +++++++++++ .../target_update_strided_struct_partial_to.c | 85 +++++++++++ .../target_update_strided_struct_to.c | 98 +++++++++++++ offload/test/offloading/target_update_to.c | 81 +++++++++++ 21 files changed, 1492 insertions(+), 7 deletions(-) create mode 100644 clang/test/OpenMP/target_update_codegen.ll create mode 100644 clang/test/OpenMP/target_update_strided_ptr_messages_from.c create mode 100644 clang/test/OpenMP/target_update_strided_ptr_messages_to.c create mode 100644 clang/test/OpenMP/target_update_strided_ptr_multiple_messages_from.c create mode 100644 clang/test/OpenMP/target_update_strided_ptr_multiple_messages_to.c create mode 100644 clang/test/OpenMP/target_update_strided_ptr_partial_messages_from.c create mode 100644 clang/test/OpenMP/target_update_strided_ptr_partial_messages_to.c create mode 100644 offload/test/offloading/strided_ptr_multiple_update_from.c create mode 100644 offload/test/offloading/strided_ptr_multiple_update_to.c create mode 100644 offload/test/offloading/strided_ptr_partial_update_from.c create mode 100644 offload/test/offloading/strided_ptr_partial_update_to.c create mode 100644 offload/test/offloading/target_update_from.c create mode 100644 offload/test/offloading/target_update_strided_struct_from.c create mode 100644 offload/test/offloading/target_update_strided_struct_multiple_from.c create mode 100644 offload/test/offloading/target_update_strided_struct_multiple_to.c create mode 100644 offload/test/offloading/target_update_strided_struct_partial_from.c create mode 100644 offload/test/offloading/target_update_strided_struct_partial_to.c create mode 100644 offload/test/offloading/target_update_strided_struct_to.c create mode 100644 offload/test/offloading/target_update_to.c diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp index a0b373478b19b..ae17d749dc979 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -8258,7 +8258,7 @@ class MappableExprsHandler { } // At this stage, if ElementType was a base pointer and we are in the - // first iteration, it has been computed. + // first iteration, it has been computed. if (ElementType) { // For the case that having pointer as base, we need to remove one // level of indirection. diff --git a/clang/test/OpenMP/target_update_codegen.cpp b/clang/test/OpenMP/target_update_codegen.cpp index c8211f475c7fc..c7ff467ad056a 100644 --- a/clang/test/OpenMP/target_update_codegen.cpp +++ b/clang/test/OpenMP/target_update_codegen.cpp @@ -1177,7 +1177,7 @@ void foo(int arg) { // CK21: [[STRUCT_ST:%.+]] = type { [10 x [10 x [10 x ptr]]] } // CK21: [[STRUCT_DESCRIPTOR:%.+]] = type { i64, i64, i64 } -// CK21: [[SIZE:@.+]] = private unnamed_addr constant [2 x i64] zeroinitializer +// CK21: [[SIZE:@.+]] = private unnamed_addr constant [2 x i64] [i64 0, i64 4] // CK21: [[MTYPE:@.+]] = {{.+}}constant [2 x i64] [i64 0, i64 299067162755073] struct ST { @@ -1221,11 +1221,8 @@ struct ST { // CK21: store i64 1, ptr [[COUNT_4]], // CK21: [[STRIDE_4:%.+]] = getelementptr inbounds nuw [[STRUCT_DESCRIPTOR]], ptr [[DIM_4]], {{.+}} 0, {{.+}} 2 // CK21: store i64 {{4|8}}, ptr [[STRIDE_4]], - // CK21-DAG: call void @__tgt_target_data_update_mapper(ptr @{{.+}}, i64 -1, i32 2, ptr [[GEPBP:%.+]], ptr [[GEPP:%.+]], ptr [[GEPSZ:%.+]], ptr [[MTYPE]]{{.+}}) - // CK21-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP]] - // CK21-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] - // CK21-DAG: [[PTRS:%.+]] = getelementptr inbounds [2 x ptr], ptr %.offload_ptrs, i32 0, i32 0 - // CK21-DAG: store ptr [[DIMS]], ptr [[PTRS]], + // CK21: call void @__tgt_target_data_update_mapper(ptr @1, i64 -1, i32 2, ptr %{{[0-9]+}}, ptr %{{[0-9]+}}, ptr %{{[0-9]+}}, ptr @.offload_maptypes, ptr null, ptr null) + // CK21: ret void #pragma omp target update to(dptr[0:2][1:3][0:4]) } }; diff --git a/clang/test/OpenMP/target_update_codegen.ll b/clang/test/OpenMP/target_update_codegen.ll new file mode 100644 index 0000000000000..ae34f51835c9d --- /dev/null +++ b/clang/test/OpenMP/target_update_codegen.ll @@ -0,0 +1,26 @@ +; ModuleID = '/tmp/target_update_codegen-91f92b.bc' +source_filename = "target_update_codegen.cpp" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + [email protected] = private constant [19160 x i8] c"\10\FF\10\AD\01\00\00\00\D8J\00\00\00\00\00\00 \00\00\00\00\00\00\00(\00\00\00\00\00\00\00\02\00\01\00\00\00\00\00H\00\00\00\00\00\00\00\02\00\00\00\00\00\00\00\90\00\00\00\00\00\00\00BJ\00\00\00\00\00\00i\00\00\00\00\00\00\00\87\00\00\00\00\00\00\00n\00\00\00\00\00\00\00u\00\00\00\00\00\00\00\00arch\00triple\00amdgcn-amd-amdhsa\00gfx90a\00\00\00; ModuleID = 'target_update_codegen.cpp'\0Asource_filename = \22target_update_codegen.cpp\22\0Atarget datalayout = \22e-m:e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128:128:48-p9:192:256:256:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8:9\22\0Atarget triple = \22amdgcn-amd-amdhsa\22\0A\0A@__omp_rtl_debug_kind = weak_odr hidden addrspace(1) constant i32 0\0A@__omp_rtl_assume_teams_oversubscription = weak_odr hidden addrspace(1) constant i32 0\0A@__omp_rtl_assume_threads_oversubscription = weak_odr hidden addrspace(1) constant i32 0\0A@__omp_rtl_assume_no_thread_state = weak_odr hidden addrspace(1) constant i32 0\0A@__omp_rtl_assume_no_nested_parallelism = weak_odr hidden addrspace(1) constant i32 0\0A\0A!llvm.dbg.cu = !{!0}\0A!llvm.module.flags = !{!213, !214, !215, !216, !217, !218, !219, !220}\0A!llvm.ident = !{!221, !222}\0A!opencl.ocl.version = !{!223}\0A\0A!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: \22clang version 22.0.0git (https://github.com/llvm/llvm-project.git e38e0feaf7bb13e6147eca002cd616499253c595)\22, isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, imports: !2, splitDebugInlining: false, nameTableKind: None)\0A!1 = !DIFile(filename: \22target_update_codegen.cpp\22, directory: \22/work/amtiwari/llvm-project/clang/test/OpenMP\22, checksumkind: CSK_MD5, checksum: \227308366b6b2010802bc22bb2e9c0e7c4\22)\0A!2 = !{!3, !11, !15, !22, !26, !34, !39, !41, !49, !53, !57, !67, !69, !73, !77, !81, !86, !90, !94, !98, !102, !110, !114, !118, !120, !124, !128, !133, !139, !143, !147, !149, !157, !161, !169, !171, !175, !179, !183, !187, !192, !197, !202, !203, !204, !205, !207, !208, !209, !210, !211, !212}\0A!3 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !4, entity: !5, file: !10, line: 52)\0A!4 = !DINamespace(name: \22std\22, scope: null)\0A!5 = !DISubprogram(name: \22abs\22, scope: !6, file: !6, line: 848, type: !7, flags: DIFlagPrototyped, spFlags: 0)\0A!6 = !DIFile(filename: \22/usr/include/stdlib.h\22, directory: \22\22, checksumkind: CSK_MD5, checksum: \2202258fad21adf111bb9df9825e61954a\22)\0A!7 = !DISubroutineType(types: !8)\0A!8 = !{!9, !9}\0A!9 = !DIBasicType(name: \22int\22, size: 32, encoding: DW_ATE_signed)\0A!10 = !DIFile(filename: \22/usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/std_abs.h\22, directory: \22\22)\0A!11 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !4, entity: !12, file: !14, line: 127)\0A!12 = !DIDerivedType(tag: DW_TAG_typedef, name: \22div_t\22, file: !6, line: 63, baseType: !13)\0A!13 = !DICompositeType(tag: DW_TAG_structure_type, file: !6, line: 59, size: 64, flags: DIFlagFwdDecl, identifier: \22_ZTS5div_t\22)\0A!14 = !DIFile(filename: \22/usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/cstdlib\22, directory: \22\22)\0A!15 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !4, entity: !16, file: !14, line: 128)\0A!16 = !DIDerivedType(tag: DW_TAG_typedef, name: \22ldiv_t\22, file: !6, line: 71, baseType: !17)\0A!17 = distinct !DICompositeType(tag: DW_TAG_structure_type, file: !6, line: 67, size: 128, flags: DIFlagTypePassByValue, elements: !18, identifier: \22_ZTS6ldiv_t\22)\0A!18 = !{!19, !21}\0A!19 = !DIDerivedType(tag: DW_TAG_member, name: \22quot\22, scope: !17, file: !6, line: 69, baseType: !20, size: 64)\0A!20 = !DIBasicType(name: \22long\22, size: 64, encoding: DW_ATE_signed)\0A!21 = !DIDerivedType(tag: DW_TAG_member, name: \22rem\22, scope: !17, file: !6, line: 70, baseType: !20, size: 64, offset: 64)\0A!22 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !4, entity: !23, file: !14, line: 130)\0A!23 = !DISubprogram(name: \22abort\22, scope: !6, file: !6, line: 598, type: !24, flags: DIFlagPrototyped | DIFlagNoReturn, spFlags: 0)\0A!24 = !DISubroutineType(types: !25)\0A!25 = !{null}\0A!26 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !4, entity: !27, file: !14, line: 132)\0A!27 = !DISubprogram(name: \22aligned_alloc\22, scope: !6, file: !6, line: 592, type: !28, flags: DIFlagPrototyped, spFlags: 0)\0A!28 = !DISubroutineType(types: !29)\0A!29 = !{!30, !31, !31}\0A!30 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64, dwarfAddressSpace: 1)\0A!31 = !DIDerivedType(tag: DW_TAG_typedef, name: \22size_t\22, file: !32, line: 18, baseType: !33)\0A!32 = !DIFile(filename: \22lib/clang/22/include/__stddef_size_t.h\22, directory: \22/work/amtiwari/llvm-project\22, checksumkind: CSK_MD5, checksum: \222c44e821a2b1951cde2eb0fb2e656867\22)\0A!33 = !DIBasicType(name: \22unsigned long\22, size: 64, encoding: DW_ATE_unsigned)\0A!34 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !4, entity: !35, file: !14, line: 134)\0A!35 = !DISubprogram(name: \22atexit\22, scope: !6, file: !6, line: 602, type: !36, flags: DIFlagPrototyped, spFlags: 0)\0A!36 = !DISubroutineType(types: !37)\0A!37 = !{!9, !38}\0A!38 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !24, size: 64, dwarfAddressSpace: 1)\0A!39 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !4, entity: !40, file: !14, line: 137)\0A!40 = !DISubprogram(name: \22at_quick_exit\22, scope: !6, file: !6, line: 607, type: !36, flags: DIFlagPrototyped, spFlags: 0)\0A!41 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !4, entity: !42, file: !14, line: 140)\0A!42 = !DISubprogram(name: \22atof\22, scope: !6, file: !6, line: 102, type: !43, flags: DIFlagPrototyped, spFlags: 0)\0A!43 = !DISubroutineType(types: !44)\0A!44 = !{!45, !46}\0A!45 = !DIBasicType(name: \22double\22, size: 64, encoding: DW_ATE_float)\0A!46 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !47, size: 64, dwarfAddressSpace: 1)\0A!47 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !48)\0A!48 = !DIBasicType(name: \22char\22, size: 8, encoding: DW_ATE_signed_char)\0A!49 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !4, entity: !50, file: !14, line: 141)\0A!50 = !DISubprogram(name: \22atoi\22, scope: !6, file: !6, line: 105, type: !51, flags: DIFlagPrototyped, spFlags: 0)\0A!51 = !DISubroutineType(types: !52)\0A!52 = !{!9, !46}\0A!53 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !4, entity: !54, file: !14, line: 142)\0A!54 = !DISubprogram(name: \22atol\22, scope: !6, file: !6, line: 108, type: !55, flags: DIFlagPrototyped, spFlags: 0)\0A!55 = !DISubroutineType(types: !56)\0A!56 = !{!20, !46}\0A!57 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !4, entity: !58, file: !14, line: 143)\0A!58 = !DISubprogram(name: \22bsearch\22, scope: !6, file: !6, line: 828, type: !59, flags: DIFlagPrototyped, spFlags: 0)\0A!59 = !DISubroutineType(types: !60)\0A!60 = !{!30, !61, !61, !31, !31, !63}\0A!61 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !62, size: 64, dwarfAddressSpace: 1)\0A!62 = !DIDerivedType(tag: DW_TAG_const_type, baseType: null)\0A!63 = !DIDerivedType(tag: DW_TAG_typedef, name: \22__compar_fn_t\22, file: !6, line: 816, baseType: !64)\0A!64 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !65, size: 64, dwarfAddressSpace: 1)\0A!65 = !DISubroutineType(types: !66)\0A!66 = !{!9, !61, !61}\0A!67 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !4, entity: !68, file: !14, line: 144)\0A!68 = !DISubprogram(name: \22calloc\22, scope: !6, file: !6, line: 543, type: !28, flags: DIFlagPrototyped, spFlags: 0)\0A!69 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !4, entity: !70, file: !14, line: 145)\0A!70 = !DISubprogram(name: \22div\22, scope: !6, file: !6, line: 860, type: !71, flags: DIFlagPrototyped, spFlags: 0)\0A!71 = !DISubroutineType(types: !72)\0A!72 = !{!12, !9, !9}\0A!73 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !4, entity: !74, file: !14, line: 146)\0A!74 = !DISubprogram(name: \22exit\22, scope: !6, file: !6, line: 624, type: !75, flags: DIFlagPrototyped | DIFlagNoReturn, spFlags: 0)\0A!75 = !DISubroutineType(types: !76)\0A!76 = !{null, !9}\0A!77 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !4, entity: !78, file: !14, line: 147)\0A!78 = !DISubprogram(name: \22free\22, scope: !6, file: !6, line: 555, type: !79, flags: DIFlagPrototyped, spFlags: 0)\0A!79 = !DISubroutineType(types: !80)\0A!80 = !{null, !30}\0A!81 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !4, entity: !82, file: !14, line: 148)\0A!82 = !DISubprogram(name: \22getenv\22, scope: !6, file: !6, line: 641, type: !83, flags: DIFlagPrototyped, spFlags: 0)\0A!83 = !DISubroutineType(types: !84)\0A!84 = !{!85, !46}\0A!85 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !48, size: 64, dwarfAddressSpace: 1)\0A!86 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !4, entity: !87, file: !14, line: 149)\0A!87 = !DISubprogram(name: \22labs\22, scope: !6, file: !6, line: 849, type: !88, flags: DIFlagPrototyped, spFlags: 0)\0A!88 = !DISubroutineType(types: !89)\0A!89 = !{!20, !20}\0A!90 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !4, entity: !91, file: !14, line: 150)\0A!91 = !DISubprogram(name: \22ldiv\22, scope: !6, file: !6, line: 862, type: !92, flags: DIFlagPrototyped, spFlags: 0)\0A!92 = !DISubroutineType(types: !93)\0A!93 = !{!16, !20, !20}\0A!94 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !4, entity: !95, file: !14, line: 151)\0A!95 = !DISubprogram(name: \22malloc\22, scope: !6, file: !6, line: 540, type: !96, flags: DIFlagPrototyped, spFlags: 0)\0A!96 = !DISubroutineType(types: !97)\0A!97 = !{!30, !31}\0A!98 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !4, entity: !99, file: !14, line: 153)\0A!99 = !DISubprogram(name: \22mblen\22, scope: !6, file: !6, line: 930, type: !100, flags: DIFlagPrototyped, spFlags: 0)\0A!100 = !DISubroutineType(types: !101)\0A!101 = !{!9, !46, !31}\0A!102 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !4, entity: !103, file: !14, line: 154)\0A!103 = !DISubprogram(name: \22mbstowcs\22, scope: !6, file: !6, line: 941, type: !104, flags: DIFlagPrototyped, spFlags: 0)\0A!104 = !DISubroutineType(types: !105)\0A!105 = !{!31, !106, !109, !31}\0A!106 = !DIDerivedType(tag: DW_TAG_restrict_type, baseType: !107)\0A!107 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !108, size: 64, dwarfAddressSpace: 1)\0A!108 = !DIBasicType(name: \22wchar_t\22, size: 32, encoding: DW_ATE_signed)\0A!109 = !DIDerivedType(tag: DW_TAG_restrict_type, baseType: !46)\0A!110 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !4, entity: !111, file: !14, line: 155)\0A!111 = !DISubprogram(name: \22mbtowc\22, scope: !6, file: !6, line: 933, type: !112, flags: DIFlagPrototyped, spFlags: 0)\0A!112 = !DISubroutineType(types: !113)\0A!113 = !{!9, !106, !109, !31}\0A!114 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !4, entity: !115, file: !14, line: 157)\0A!115 = !DISubprogram(name: \22qsort\22, scope: !6, file: !6, line: 838, type: !116, flags: DIFlagPrototyped, spFlags: 0)\0A!116 = !DISubroutineType(types: !117)\0A!117 = !{null, !30, !31, !31, !63}\0A!118 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !4, entity: !119, file: !14, line: 160)\0A!119 = !DISubprogram(name: \22quick_exit\22, scope: !6, file: !6, line: 630, type: !75, flags: DIFlagPrototyped | DIFlagNoReturn, spFlags: 0)\0A!120 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !4, entity: !121, file: !14, line: 163)\0A!121 = !DISubprogram(name: \22rand\22, scope: !6, file: !6, line: 454, type: !122, flags: DIFlagPrototyped, spFlags: 0)\0A!122 = !DISubroutineType(types: !123)\0A!123 = !{!9}\0A!124 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !4, entity: !125, file: !14, line: 164)\0A!125 = !DISubprogram(name: \22realloc\22, scope: !6, file: !6, line: 551, type: !126, flags: DIFlagPrototyped, spFlags: 0)\0A!126 = !DISubroutineType(types: !127)\0A!127 = !{!30, !30, !31}\0A!128 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !4, entity: !129, file: !14, line: 165)\0A!129 = !DISubprogram(name: \22srand\22, scope: !6, file: !6, line: 456, type: !130, flags: DIFlagPrototyped, spFlags: 0)\0A!130 = !DISubroutineType(types: !131)\0A!131 = !{null, !132}\0A!132 = !DIBasicType(name: \22unsigned int\22, size: 32, encoding: DW_ATE_unsigned)\0A!133 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !4, entity: !134, file: !14, line: 166)\0A!134 = !DISubprogram(name: \22strtod\22, scope: !6, file: !6, line: 118, type: !135, flags: DIFlagPrototyped, spFlags: 0)\0A!135 = !DISubroutineType(types: !136)\0A!136 = !{!45, !109, !137}\0A!137 = !DIDerivedType(tag: DW_TAG_restrict_type, baseType: !138)\0A!138 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !85, size: 64, dwarfAddressSpace: 1)\0A!139 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !4, entity: !140, file: !14, line: 167)\0A!140 = !DISubprogram(name: \22strtol\22, scope: !6, file: !6, line: 177, type: !141, flags: DIFlagPrototyped, spFlags: 0)\0A!141 = !DISubroutineType(types: !142)\0A!142 = !{!20, !109, !137, !9}\0A!143 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !4, entity: !144, file: !14, line: 168)\0A!144 = !DISubprogram(name: \22strtoul\22, scope: !6, file: !6, line: 181, type: !145, flags: DIFlagPrototyped, spFlags: 0)\0A!145 = !DISubroutineType(types: !146)\0A!146 = !{!33, !109, !137, !9}\0A!147 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !4, entity: !148, file: !14, line: 169)\0A!148 = !DISubprogram(name: \22system\22, scope: !6, file: !6, line: 791, type: !51, flags: DIFlagPrototyped, spFlags: 0)\0A!149 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !4, entity: !150, file: !14, line: 171)\0A!150 = !DISubprogram(name: \22wcstombs\22, scope: !6, file: !6, line: 945, type: !151, flags: DIFlagPrototyped, spFlags: 0)\0A!151 = !DISubroutineType(types: !152)\0A!152 = !{!31, !153, !154, !31}\0A!153 = !DIDerivedType(tag: DW_TAG_restrict_type, baseType: !85)\0A!154 = !DIDerivedType(tag: DW_TAG_restrict_type, baseType: !155)\0A!155 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !156, size: 64, dwarfAddressSpace: 1)\0A!156 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !108)\0A!157 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !4, entity: !158, file: !14, line: 172)\0A!158 = !DISubprogram(name: \22wctomb\22, scope: !6, file: !6, line: 937, type: !159, flags: DIFlagPrototyped, spFlags: 0)\0A!159 = !DISubroutineType(types: !160)\0A!160 = !{!9, !85, !108}\0A!161 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !162, entity: !163, file: !14, line: 200)\0A!162 = !DINamespace(name: \22__gnu_cxx\22, scope: null)\0A!163 = !DIDerivedType(tag: DW_TAG_typedef, name: \22lldiv_t\22, file: !6, line: 81, baseType: !164)\0A!164 = distinct !DICompositeType(tag: DW_TAG_structure_type, file: !6, line: 77, size: 128, flags: DIFlagTypePassByValue, elements: !165, identifier: \22_ZTS7lldiv_t\22)\0A!165 = !{!166, !168}\0A!166 = !DIDerivedType(tag: DW_TAG_member, name: \22quot\22, scope: !164, file: !6, line: 79, baseType: !167, size: 64)\0A!167 = !DIBasicType(name: \22long long\22, size: 64, encoding: DW_ATE_signed)\0A!168 = !DIDerivedType(tag: DW_TAG_member, name: \22rem\22, scope: !164, file: !6, line: 80, baseType: !167, size: 64, offset: 64)\0A!169 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !162, entity: !170, file: !14, line: 206)\0A!170 = !DISubprogram(name: \22_Exit\22, scope: !6, file: !6, line: 636, type: !75, flags: DIFlagPrototyped | DIFlagNoReturn, spFlags: 0)\0A!171 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !162, entity: !172, file: !14, line: 210)\0A!172 = !DISubprogram(name: \22llabs\22, scope: !6, file: !6, line: 852, type: !173, flags: DIFlagPrototyped, spFlags: 0)\0A!173 = !DISubroutineType(types: !174)\0A!174 = !{!167, !167}\0A!175 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !162, entity: !176, file: !14, line: 216)\0A!176 = !DISubprogram(name: \22lldiv\22, scope: !6, file: !6, line: 866, type: !177, flags: DIFlagPrototyped, spFlags: 0)\0A!177 = !DISubroutineType(types: !178)\0A!178 = !{!163, !167, !167}\0A!179 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !162, entity: !180, file: !14, line: 227)\0A!180 = !DISubprogram(name: \22atoll\22, scope: !6, file: !6, line: 113, type: !181, flags: DIFlagPrototyped, spFlags: 0)\0A!181 = !DISubroutineType(types: !182)\0A!182 = !{!167, !46}\0A!183 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !162, entity: !184, file: !14, line: 228)\0A!184 = !DISubprogram(name: \22strtoll\22, scope: !6, file: !6, line: 201, type: !185, flags: DIFlagPrototyped, spFlags: 0)\0A!185 = !DISubroutineType(types: !186)\0A!186 = !{!167, !109, !137, !9}\0A!187 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !162, entity: !188, file: !14, line: 229)\0A!188 = !DISubprogram(name: \22strtoull\22, scope: !6, file: !6, line: 206, type: !189, flags: DIFlagPrototyped, spFlags: 0)\0A!189 = !DISubroutineType(types: !190)\0A!190 = !{!191, !109, !137, !9}\0A!191 = !DIBasicType(name: \22unsigned long long\22, size: 64, encoding: DW_ATE_unsigned)\0A!192 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !162, entity: !193, file: !14, line: 231)\0A!193 = !DISubprogram(name: \22strtof\22, scope: !6, file: !6, line: 124, type: !194, flags: DIFlagPrototyped, spFlags: 0)\0A!194 = !DISubroutineType(types: !195)\0A!195 = !{!196, !109, !137}\0A!196 = !DIBasicType(name: \22float\22, size: 32, encoding: DW_ATE_float)\0A!197 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !162, entity: !198, file: !14, line: 232)\0A!198 = !DISubprogram(name: \22strtold\22, scope: !6, file: !6, line: 127, type: !199, flags: DIFlagPrototyped, spFlags: 0)\0A!199 = !DISubroutineType(types: !200)\0A!200 = !{!201, !109, !137}\0A!201 = !DIBasicType(name: \22long double\22, size: 128, encoding: DW_ATE_float)\0A!202 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !4, entity: !163, file: !14, line: 240)\0A!203 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !4, entity: !170, file: !14, line: 242)\0A!204 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !4, entity: !172, file: !14, line: 244)\0A!205 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !4, entity: !206, file: !14, line: 245)\0A!206 = !DISubprogram(name: \22div\22, linkageName: \22_ZN9__gnu_cxx3divExx\22, scope: !162, file: !14, line: 213, type: !177, flags: DIFlagPrototyped, spFlags: 0)\0A!207 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !4, entity: !176, file: !14, line: 246)\0A!208 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !4, entity: !180, file: !14, line: 248)\0A!209 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !4, entity: !193, file: !14, line: 249)\0A!210 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !4, entity: !184, file: !14, line: 250)\0A!211 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !4, entity: !188, file: !14, line: 251)\0A!212 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !4, entity: !198, file: !14, line: 252)\0A!213 = !{i32 1, !\22amdhsa_code_object_version\22, i32 600}\0A!214 = !{i32 7, !\22Dwarf Version\22, i32 5}\0A!215 = !{i32 2, !\22Debug Info Version\22, i32 3}\0A!216 = !{i32 1, !\22wchar_size\22, i32 4}\0A!217 = !{i32 7, !\22openmp\22, i32 51}\0A!218 = !{i32 7, !\22openmp-device\22, i32 51}\0A!219 = !{i32 8, !\22PIC Level\22, i32 2}\0A!220 = !{i32 7, !\22frame-pointer\22, i32 2}\0A!221 = !{!\22clang version 22.0.0git (https://github.com/llvm/llvm-project.git e38e0feaf7bb13e6147eca002cd616499253c595)\22}\0A!222 = !{!\22AMD clang version 18.0.0git (https://github.com/RadeonOpenCompute/llvm-project roc-6.3.1 24491 1e0fda770a2079fbd71e4b70974d74f62fd3af10)\22}\0A!223 = !{i32 2, i32 0}\0A\00\00\00\00\00\00", section ".llvm.offloading", align 8, !exclude !0 [email protected] = appending global [1 x ptr] [ptr @llvm.embedded.object], section "llvm.metadata" + +!llvm.dbg.cu = !{!1} +!llvm.module.flags = !{!3, !4, !5, !6, !7, !8, !9, !10} +!llvm.ident = !{!11} +!llvm.embedded.objects = !{!12} + +!0 = !{} +!1 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !2, producer: "clang version 22.0.0git (https://github.com/llvm/llvm-project.git e38e0feaf7bb13e6147eca002cd616499253c595)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) +!2 = !DIFile(filename: "target_update_codegen.cpp", directory: "/work/amtiwari/llvm-project/clang/test/OpenMP", checksumkind: CSK_MD5, checksum: "7308366b6b2010802bc22bb2e9c0e7c4") +!3 = !{i32 7, !"Dwarf Version", i32 5} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{i32 7, !"openmp", i32 51} +!7 = !{i32 8, !"PIC Level", i32 2} +!8 = !{i32 7, !"PIE Level", i32 2} +!9 = !{i32 7, !"uwtable", i32 2} +!10 = !{i32 7, !"frame-pointer", i32 2} +!11 = !{!"clang version 22.0.0git (https://github.com/llvm/llvm-project.git e38e0feaf7bb13e6147eca002cd616499253c595)"} +!12 = !{ptr @llvm.embedded.object, !".llvm.offloading"} diff --git a/clang/test/OpenMP/target_update_strided_ptr_messages_from.c b/clang/test/OpenMP/target_update_strided_ptr_messages_from.c new file mode 100644 index 0000000000000..cd158ff10e4de --- /dev/null +++ b/clang/test/OpenMP/target_update_strided_ptr_messages_from.c @@ -0,0 +1,44 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 %s -Wuninitialized + +extern void *malloc(__SIZE_TYPE__); +extern void free(void *); + +int main(int argc, char **argv) { + int len = 16; + double *data = (double *)malloc(len * sizeof(double)); + + // Valid strided array sections with FROM + #pragma omp target update from(data[0:8:2]) // OK - even indices + {} + + #pragma omp target update from(data[1:4:3]) // OK - odd start with stride + {} + + #pragma omp target update from(data[2:3:5]) // OK - large stride + {} + + // Missing stride (default = 1) + #pragma omp target update from(data[0:8]) // OK - default stride + {} + + #pragma omp target update from(data[4:len-4]) // OK - computed length + {} + + // Invalid stride expressions + #pragma omp target update from(data[0:8:0]) // expected-error {{section stride is evaluated to a non-positive value 0}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} + + #pragma omp target update from(data[0:4:-1]) // expected-error {{section stride is evaluated to a non-positive value -1}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} + + #pragma omp target update from(data[1:5:-2]) // expected-error {{section stride is evaluated to a non-positive value -2}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} + + // Syntax errors + #pragma omp target update from(data[0:4 2]) // expected-error {{expected ']'}} expected-note {{to match this '['}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} + {} + + #pragma omp target update from(data[0:4:2:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} + {} + + free(data); + return 0; +} \ No newline at end of file diff --git a/clang/test/OpenMP/target_update_strided_ptr_messages_to.c b/clang/test/OpenMP/target_update_strided_ptr_messages_to.c new file mode 100644 index 0000000000000..6459c79149326 --- /dev/null +++ b/clang/test/OpenMP/target_update_strided_ptr_messages_to.c @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 %s -Wuninitialized + +int main(int argc, char **argv) { + int len = 16; + double *data = (double *)malloc(len * sizeof(double)); + + // Valid strided array sections with TO + #pragma omp target update to(data[0:8:2]) // OK - even indices + {} + + #pragma omp target update to(data[1:4:3]) // OK - odd start with stride + {} + + #pragma omp target update to(data[2:3:5]) // OK - large stride + {} + + // Missing stride (default = 1) + #pragma omp target update to(data[0:8]) // OK - default stride + {} + + #pragma omp target update to(data[4:len-4]) // OK - computed length + {} + + // Invalid stride expressions + #pragma omp target update to(data[0:8:0]) // expected-error {{section stride is evaluated to a non-positive value 0}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} + + #pragma omp target update to(data[0:4:-1]) // expected-error {{section stride is evaluated to a non-positive value -1}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} + + #pragma omp target update to(data[1:5:-2]) // expected-error {{section stride is evaluated to a non-positive value -2}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} + + // Syntax errors + #pragma omp target update to(data[0:4 2]) // expected-error {{expected ']'}} expected-note {{to match this '['}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} + {} + + #pragma omp target update to(data[0:4:2:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} + {} + + free(data); + return 0; +} \ No newline at end of file diff --git a/clang/test/OpenMP/target_update_strided_ptr_multiple_messages_from.c b/clang/test/OpenMP/target_update_strided_ptr_multiple_messages_from.c new file mode 100644 index 0000000000000..2462ae1c840c3 --- /dev/null +++ b/clang/test/OpenMP/target_update_strided_ptr_multiple_messages_from.c @@ -0,0 +1,64 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 %s -Wuninitialized + +extern void *malloc(__SIZE_TYPE__); +extern void free(void *); + +double *data; +double *data1; +double *data2; + +int main(int argc, char **argv) { + int len = 12; + + // Allocate memory for explicit pointers + data = (double *)malloc(len * sizeof(double)); + data1 = (double *)malloc(len * sizeof(double)); + data2 = (double *)malloc(len * sizeof(double)); + + // Valid multiple strided array sections + #pragma omp target update from(data1[0:6:2], data2[0:4:3]) // OK - different strides + {} + + #pragma omp target update from(data1[1:2:3], data2[2:3:2]) // OK - with offsets + {} + + // Mixed strided and regular sections + #pragma omp target update from(data1[0:len], data2[0:4:2]) // OK - mixed + {} + + #pragma omp target update from(data1[1:3:2], data2[0:len]) // OK - reversed mix + {} + + // Using the single data pointer with strides + #pragma omp target update from(data[0:4:2]) // OK - single pointer + {} + + // Invalid stride in one of multiple sections + #pragma omp target update from(data1[0:3:4], data2[0:2:0]) // expected-error {{section stride is evaluated to a non-positive value 0}} + + #pragma omp target update from(data1[0:3:-1], data2[0:2:2]) // expected-error {{section stride is evaluated to a non-positive value -1}} + + #pragma omp target update from(data[0:4:0], data1[0:2:1]) // expected-error {{section stride is evaluated to a non-positive value 0}} + + // Complex expressions in multiple arrays + int stride1 = 2, stride2 = 3; + #pragma omp target update from(data1[1:4:stride1+1], data2[0:3:stride2-1]) // OK - expressions + {} + + // Mix all three pointers + #pragma omp target update from(data[0:2:3], data1[1:3:2], data2[2:2:4]) // OK - three arrays + {} + + // Syntax errors in multiple arrays + #pragma omp target update from(data1[0:4:2], data2[0:3 4]) // expected-error {{expected ']'}} expected-note {{to match this '['}} + + #pragma omp target update from(data1[0:4:2:3], data2[0:3:2]) // expected-error {{expected ']'}} expected-note {{to match this '['}} + + #pragma omp target update from(data[0:4:2], data1[0:3:2:1], data2[0:2:3]) // expected-error {{expected ']'}} expected-note {{to match this '['}} + + free(data); + free(data1); + free(data2); + return 0; +} \ No newline at end of file diff --git a/clang/test/OpenMP/target_update_strided_ptr_multiple_messages_to.c b/clang/test/OpenMP/target_update_strided_ptr_multiple_messages_to.c new file mode 100644 index 0000000000000..d8cebefb02606 --- /dev/null +++ b/clang/test/OpenMP/target_update_strided_ptr_multiple_messages_to.c @@ -0,0 +1,64 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 %s -Wuninitialized + +extern void *malloc(__SIZE_TYPE__); +extern void free(void *); + +double *data; +double *data1; +double *data2; + +int main(int argc, char **argv) { + int len = 12; + + // Allocate memory for explicit pointers + data = (double *)malloc(len * sizeof(double)); + data1 = (double *)malloc(len * sizeof(double)); + data2 = (double *)malloc(len * sizeof(double)); + + // Valid multiple strided array sections + #pragma omp target update to(data1[0:6:2], data2[0:4:3]) // OK - different strides + {} + + #pragma omp target update to(data1[1:2:3], data2[2:3:2]) // OK - with offsets + {} + + // Mixed strided and regular sections + #pragma omp target update to(data1[0:len], data2[0:4:2]) // OK - mixed + {} + + #pragma omp target update to(data1[1:3:2], data2[0:len]) // OK - reversed mix + {} + + // Using the single data pointer with strides + #pragma omp target update to(data[0:4:2]) // OK - single pointer + {} + + // Invalid stride in one of multiple sections + #pragma omp target update to(data1[0:3:4], data2[0:2:0]) // expected-error {{section stride is evaluated to a non-positive value 0}} + + #pragma omp target update to(data1[0:3:-1], data2[0:2:2]) // expected-error {{section stride is evaluated to a non-positive value -1}} + + #pragma omp target update to(data[0:4:0], data1[0:2:1]) // expected-error {{section stride is evaluated to a non-positive value 0}} + + // Complex expressions in multiple arrays + int stride1 = 2, stride2 = 3; + #pragma omp target update to(data1[1:4:stride1+1], data2[0:3:stride2-1]) // OK - expressions + {} + + // Mix all three pointers + #pragma omp target update to(data[0:2:3], data1[1:3:2], data2[2:2:4]) // OK - three arrays + {} + + // Syntax errors in multiple arrays + #pragma omp target update to(data1[0:4:2], data2[0:3 4]) // expected-error {{expected ']'}} expected-note {{to match this '['}} + + #pragma omp target update to(data1[0:4:2:3], data2[0:3:2]) // expected-error {{expected ']'}} expected-note {{to match this '['}} + + #pragma omp target update to(data[0:4:2], data1[0:3:2:1], data2[0:2:3]) // expected-error {{expected ']'}} expected-note {{to match this '['}} + + free(data); + free(data1); + free(data2); + return 0; +} \ No newline at end of file diff --git a/clang/test/OpenMP/target_update_strided_ptr_partial_messages_from.c b/clang/test/OpenMP/target_update_strided_ptr_partial_messages_from.c new file mode 100644 index 0000000000000..2f36dfa84cd1b --- /dev/null +++ b/clang/test/OpenMP/target_update_strided_ptr_partial_messages_from.c @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 %s -Wuninitialized + +extern void *malloc(__SIZE_TYPE__); +extern void free(void *); + +int main(int argc, char **argv) { + int len = 11; + double *data = (double *)malloc(len * sizeof(double)); + + // Valid partial strided sections with FROM + #pragma omp target update from(data[0:2:3]) // OK - partial coverage + {} + + #pragma omp target update from(data[1:3:4]) // OK - offset with partial stride + {} + + #pragma omp target update from(data[2:2:5]) // OK - large partial stride + {} + + // Stride larger than remaining elements + #pragma omp target update from(data[0:2:10]) // OK - stride > array size + {} + + #pragma omp target update from(data[0:3:len]) // OK - stride = len + {} + + // Complex expressions + int offset = 1; + int stride = 2; + + // Runtime-dependent invalid strides + #pragma omp target update from(data[0:4:offset-1]) // OK if offset > 1 + {} + + // Compile-time invalid strides + #pragma omp target update from(data[1:2:-3]) // expected-error {{section stride is evaluated to a non-positive value -3}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} + + free(data); + return 0; +} \ No newline at end of file diff --git a/clang/test/OpenMP/target_update_strided_ptr_partial_messages_to.c b/clang/test/OpenMP/target_update_strided_ptr_partial_messages_to.c new file mode 100644 index 0000000000000..ce4b315bec1ae --- /dev/null +++ b/clang/test/OpenMP/target_update_strided_ptr_partial_messages_to.c @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 %s -Wuninitialized + +extern void *malloc(__SIZE_TYPE__); +extern void free(void *); + +int main(int argc, char **argv) { + int len = 11; + double *data = (double *)malloc(len * sizeof(double)); + + // Valid partial strided sections with TO + #pragma omp target update to(data[0:2:3]) // OK - partial coverage + {} + + #pragma omp target update to(data[1:3:4]) // OK - offset with partial stride + {} + + #pragma omp target update to(data[2:2:5]) // OK - large partial stride + {} + + // Stride larger than remaining elements + #pragma omp target update to(data[0:2:10]) // OK - stride > array size + {} + + #pragma omp target update to(data[0:3:len]) // OK - stride = len + {} + + int offset = 1; + int stride = 2; + + // Runtime-dependent invalid strides + #pragma omp target update to(data[0:4:offset-1]) // OK if offset > 1 + {} + + // Compile-time invalid strides + #pragma omp target update to(data[1:2:-3]) // expected-error {{section stride is evaluated to a non-positive value -3}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} + + free(data); + return 0; +} \ No newline at end of file diff --git a/offload/test/offloading/strided_ptr_multiple_update_from.c b/offload/test/offloading/strided_ptr_multiple_update_from.c new file mode 100644 index 0000000000000..afb2f1fc8dd53 --- /dev/null +++ b/offload/test/offloading/strided_ptr_multiple_update_from.c @@ -0,0 +1,114 @@ +// This test checks that #pragma omp target update from(data1[0:6:2], +// data2[0:4:3]) correctly updates strided sections covering full arrays +// from the device to the host using dynamically allocated memory. + +// RUN: %libomptarget-compile-run-and-check-generic +#include <omp.h> +#include <stdio.h> +#include <stdlib.h> + +int main() { + int len = 12; + double *data1 = (double *)calloc(len, sizeof(double)); + double *data2 = (double *)calloc(len, sizeof(double)); + +// Initial values +#pragma omp target map(tofrom : data1[0 : len], data2[0 : len]) + { + for (int i = 0; i < len; i++) { + data1[i] = i; + data2[i] = i * 10; + } + } + + printf("original host array values:\n"); + printf("data1:\n"); + for (int i = 0; i < len; i++) + printf("%.1f\n", data1[i]); + printf("data2:\n"); + for (int i = 0; i < len; i++) + printf("%.1f\n", data2[i]); + +#pragma omp target data map(to : data1[0 : len], data2[0 : len]) + { +#pragma omp target + { + for (int i = 0; i < len; i++) + data1[i] += i; + for (int i = 0; i < len; i++) + data2[i] += 100; + } + +// data1[0:6:2] covers all even indices: 0,2,4,6,8,10 (6 elements) +// data2[0:4:3] covers every 3rd: 0,3,6,9 (4 elements) +#pragma omp target update from(data1[0 : 6 : 2], data2[0 : 4 : 3]) + } + + printf("device array values after update from:\n"); + printf("data1:\n"); + for (int i = 0; i < len; i++) + printf("%.1f\n", data1[i]); + printf("data2:\n"); + for (int i = 0; i < len; i++) + printf("%.1f\n", data2[i]); + + // CHECK: original host array values: + // CHECK-NEXT: data1: + // CHECK-NEXT: 0.0 + // CHECK-NEXT: 1.0 + // CHECK-NEXT: 2.0 + // CHECK-NEXT: 3.0 + // CHECK-NEXT: 4.0 + // CHECK-NEXT: 5.0 + // CHECK-NEXT: 6.0 + // CHECK-NEXT: 7.0 + // CHECK-NEXT: 8.0 + // CHECK-NEXT: 9.0 + // CHECK-NEXT: 10.0 + // CHECK-NEXT: 11.0 + // CHECK-NEXT: data2: + // CHECK-NEXT: 0.0 + // CHECK-NEXT: 10.0 + // CHECK-NEXT: 20.0 + // CHECK-NEXT: 30.0 + // CHECK-NEXT: 40.0 + // CHECK-NEXT: 50.0 + // CHECK-NEXT: 60.0 + // CHECK-NEXT: 70.0 + // CHECK-NEXT: 80.0 + // CHECK-NEXT: 90.0 + // CHECK-NEXT: 100.0 + // CHECK-NEXT: 110.0 + + // CHECK: device array values after update from: + // CHECK-NEXT: data1: + // CHECK-NEXT: 0.0 + // CHECK-NEXT: 1.0 + // CHECK-NEXT: 4.0 + // CHECK-NEXT: 3.0 + // CHECK-NEXT: 8.0 + // CHECK-NEXT: 5.0 + // CHECK-NEXT: 12.0 + // CHECK-NEXT: 7.0 + // CHECK-NEXT: 16.0 + // CHECK-NEXT: 9.0 + // CHECK-NEXT: 20.0 + // CHECK-NEXT: 11.0 + // CHECK-NEXT: data2: + // CHECK-NEXT: 100.0 + // CHECK-NEXT: 10.0 + // CHECK-NEXT: 20.0 + // CHECK-NEXT: 130.0 + // CHECK-NEXT: 40.0 + // CHECK-NEXT: 50.0 + // CHECK-NEXT: 160.0 + // CHECK-NEXT: 70.0 + // CHECK-NEXT: 80.0 + // CHECK-NEXT: 190.0 + // CHECK-NEXT: 100.0 + // CHECK-NEXT: 110.0 + + free(data1); + free(data2); + return 0; +} \ No newline at end of file diff --git a/offload/test/offloading/strided_ptr_multiple_update_to.c b/offload/test/offloading/strided_ptr_multiple_update_to.c new file mode 100644 index 0000000000000..2005117c83754 --- /dev/null +++ b/offload/test/offloading/strided_ptr_multiple_update_to.c @@ -0,0 +1,130 @@ +// This test checks that #pragma omp target update to(data1[0:6:2], +// data2[0:4:3]) correctly updates strided sections covering full arrays +// from the host to the device using dynamically allocated memory. + +// RUN: %libomptarget-compile-run-and-check-generic +#include <omp.h> +#include <stdio.h> +#include <stdlib.h> + +int main() { + int len = 12; + double *data1 = (double *)calloc(len, sizeof(double)); + double *data2 = (double *)calloc(len, sizeof(double)); + + // Initialize host arrays + for (int i = 0; i < len; i++) { + data1[i] = i; + data2[i] = i * 10; + } + + printf("original host array values:\n"); + printf("data1:\n"); + for (int i = 0; i < len; i++) + printf("%.1f\n", data1[i]); + printf("data2:\n"); + for (int i = 0; i < len; i++) + printf("%.1f\n", data2[i]); + +#pragma omp target data map(tofrom : data1[0 : len], data2[0 : len]) + { +// Initialize device arrays to 20 +#pragma omp target + { + for (int i = 0; i < len; i++) { + data1[i] = 20.0; + data2[i] = 20.0; + } + } + + // data1: even indices + for (int i = 0; i < 6; i++) { + data1[i * 2] = 10.0; + } + // data2: every 3rd index + for (int i = 0; i < 4; i++) { + data2[i * 3] = 10.0; + } + +// data1[0:6:2] updates all even indices: 0,2,4,6,8,10 (6 elements) +// data2[0:4:3] updates every 3rd: 0,3,6,9 (4 elements) +#pragma omp target update to(data1[0 : 6 : 2], data2[0 : 4 : 3]) + +// Verify on device by adding 5 +#pragma omp target + { + for (int i = 0; i < len; i++) { + data1[i] += 5.0; + data2[i] += 5.0; + } + } + } + + printf("device array values after update to:\n"); + printf("data1:\n"); + for (int i = 0; i < len; i++) + printf("%.1f\n", data1[i]); + printf("data2:\n"); + for (int i = 0; i < len; i++) + printf("%.1f\n", data2[i]); + + // CHECK: original host array values: + // CHECK-NEXT: data1: + // CHECK-NEXT: 0.0 + // CHECK-NEXT: 1.0 + // CHECK-NEXT: 2.0 + // CHECK-NEXT: 3.0 + // CHECK-NEXT: 4.0 + // CHECK-NEXT: 5.0 + // CHECK-NEXT: 6.0 + // CHECK-NEXT: 7.0 + // CHECK-NEXT: 8.0 + // CHECK-NEXT: 9.0 + // CHECK-NEXT: 10.0 + // CHECK-NEXT: 11.0 + // CHECK-NEXT: data2: + // CHECK-NEXT: 0.0 + // CHECK-NEXT: 10.0 + // CHECK-NEXT: 20.0 + // CHECK-NEXT: 30.0 + // CHECK-NEXT: 40.0 + // CHECK-NEXT: 50.0 + // CHECK-NEXT: 60.0 + // CHECK-NEXT: 70.0 + // CHECK-NEXT: 80.0 + // CHECK-NEXT: 90.0 + // CHECK-NEXT: 100.0 + // CHECK-NEXT: 110.0 + + // CHECK: device array values after update to: + // CHECK-NEXT: data1: + // CHECK-NEXT: 15.0 + // CHECK-NEXT: 25.0 + // CHECK-NEXT: 15.0 + // CHECK-NEXT: 25.0 + // CHECK-NEXT: 15.0 + // CHECK-NEXT: 25.0 + // CHECK-NEXT: 15.0 + // CHECK-NEXT: 25.0 + // CHECK-NEXT: 15.0 + // CHECK-NEXT: 25.0 + // CHECK-NEXT: 15.0 + // CHECK-NEXT: 25.0 + // CHECK-NEXT: data2: + // CHECK-NEXT: 15.0 + // CHECK-NEXT: 25.0 + // CHECK-NEXT: 25.0 + // CHECK-NEXT: 15.0 + // CHECK-NEXT: 25.0 + // CHECK-NEXT: 25.0 + // CHECK-NEXT: 15.0 + // CHECK-NEXT: 25.0 + // CHECK-NEXT: 25.0 + // CHECK-NEXT: 15.0 + // CHECK-NEXT: 25.0 + // CHECK-NEXT: 25.0 + + free(data1); + free(data2); + return 0; +} \ No newline at end of file diff --git a/offload/test/offloading/strided_ptr_partial_update_from.c b/offload/test/offloading/strided_ptr_partial_update_from.c new file mode 100644 index 0000000000000..e2f4398b2fbd7 --- /dev/null +++ b/offload/test/offloading/strided_ptr_partial_update_from.c @@ -0,0 +1,68 @@ +// This test checks that #pragma omp target update from(data[0:2:3]) correctly +// updates every third element (stride 3) from the device to the host, partially +// across the array using dynamically allocated memory. + +// RUN: %libomptarget-compile-run-and-check-generic +#include <omp.h> +#include <stdio.h> +#include <stdlib.h> + +int main() { + int len = 11; + double *data = (double *)calloc(len, sizeof(double)); + +#pragma omp target map(tofrom : data[0 : len]) + { + for (int i = 0; i < len; i++) + data[i] = i; + } + + // Initial values + printf("original host array values:\n"); + for (int i = 0; i < len; i++) + printf("%f\n", data[i]); + printf("\n"); + +#pragma omp target data map(to : data[0 : len]) + { +#pragma omp target + for (int i = 0; i < len; i++) + data[i] += i; + +#pragma omp target update from(data[0 : 2 : 3]) // indices 0,3 only + } + + printf("device array values after update from:\n"); + for (int i = 0; i < len; i++) + printf("%f\n", data[i]); + printf("\n"); + + // CHECK: original host array values: + // CHECK-NEXT: 0.000000 + // CHECK-NEXT: 1.000000 + // CHECK-NEXT: 2.000000 + // CHECK-NEXT: 3.000000 + // CHECK-NEXT: 4.000000 + // CHECK-NEXT: 5.000000 + // CHECK-NEXT: 6.000000 + // CHECK-NEXT: 7.000000 + // CHECK-NEXT: 8.000000 + // CHECK-NEXT: 9.000000 + // CHECK-NEXT: 10.000000 + + // CHECK: device array values after update from: + // CHECK-NEXT: 0.000000 + // CHECK-NEXT: 1.000000 + // CHECK-NEXT: 2.000000 + // CHECK-NEXT: 6.000000 + // CHECK-NEXT: 4.000000 + // CHECK-NEXT: 5.000000 + // CHECK-NEXT: 6.000000 + // CHECK-NEXT: 7.000000 + // CHECK-NEXT: 8.000000 + // CHECK-NEXT: 9.000000 + // CHECK-NEXT: 10.000000 + + free(data); + return 0; +} \ No newline at end of file diff --git a/offload/test/offloading/strided_ptr_partial_update_to.c b/offload/test/offloading/strided_ptr_partial_update_to.c new file mode 100644 index 0000000000000..28bd27fd04366 --- /dev/null +++ b/offload/test/offloading/strided_ptr_partial_update_to.c @@ -0,0 +1,81 @@ +// This test checks that #pragma omp target update to(data[0:2:3]) correctly +// updates every third element (stride 3) from the host to the device, partially +// across the array using dynamically allocated memory. + +// RUN: %libomptarget-compile-run-and-check-generic +#include <omp.h> +#include <stdio.h> +#include <stdlib.h> + +int main() { + int len = 11; + double *data = (double *)calloc(len, sizeof(double)); + + // Initialize on host + for (int i = 0; i < len; i++) + data[i] = i; + + // Initial values + printf("original host array values:\n"); + for (int i = 0; i < len; i++) + printf("%f\n", data[i]); + printf("\n"); + +#pragma omp target data map(tofrom : data[0 : len]) + { +// Initialize device array to 20 +#pragma omp target + { + for (int i = 0; i < len; i++) + data[i] = 20.0; + } + + // Modify host data for elements that will be updated + data[0] = 10.0; + data[3] = 10.0; + +// This creates Host→Device transfer for indices 0,3 only +#pragma omp target update to(data[0 : 2 : 3]) + +// Verify on device by adding 5 to all elements +#pragma omp target + { + for (int i = 0; i < len; i++) + data[i] += 5.0; + } + } + + printf("device array values after update to:\n"); + for (int i = 0; i < len; i++) + printf("%f\n", data[i]); + printf("\n"); + + // CHECK: original host array values: + // CHECK-NEXT: 0.000000 + // CHECK-NEXT: 1.000000 + // CHECK-NEXT: 2.000000 + // CHECK-NEXT: 3.000000 + // CHECK-NEXT: 4.000000 + // CHECK-NEXT: 5.000000 + // CHECK-NEXT: 6.000000 + // CHECK-NEXT: 7.000000 + // CHECK-NEXT: 8.000000 + // CHECK-NEXT: 9.000000 + // CHECK-NEXT: 10.000000 + + // CHECK: device array values after update to: + // CHECK-NEXT: 15.000000 + // CHECK-NEXT: 25.000000 + // CHECK-NEXT: 25.000000 + // CHECK-NEXT: 15.000000 + // CHECK-NEXT: 25.000000 + // CHECK-NEXT: 25.000000 + // CHECK-NEXT: 25.000000 + // CHECK-NEXT: 25.000000 + // CHECK-NEXT: 25.000000 + // CHECK-NEXT: 25.000000 + // CHECK-NEXT: 25.000000 + + free(data); + return 0; +} \ No newline at end of file diff --git a/offload/test/offloading/target_update_from.c b/offload/test/offloading/target_update_from.c new file mode 100644 index 0000000000000..089b498ada0db --- /dev/null +++ b/offload/test/offloading/target_update_from.c @@ -0,0 +1,73 @@ +// RUN: %libomptarget-compile-run-and-check-generic +// This test checks that "update from" clause in OpenMP supports strided +// sections. #pragma omp target update from(result[0:N/2:2]) updates every other +// element from device +#include <omp.h> +#include <stdio.h> +#include <stdlib.h> + +#define N 32 + +int main() { + double *result = (double *)calloc(N, sizeof(double)); + + printf("initial host array values:\n"); + for (int i = 0; i < N; i++) + printf("%f\n", result[i]); + printf("\n"); + +#pragma omp target data map(to : result[0 : N]) + { +#pragma omp target map(alloc : result[0 : N]) + for (int i = 0; i < N; i++) + result[i] += i; + + // Update strided elements from device: even indices 0,2,4,...,30 +#pragma omp target update from(result[0 : 16 : 2]) + } + + printf("after target update from (even indices up to 30 updated):\n"); + for (int i = 0; i < N; i++) + printf("%f\n", result[i]); + printf("\n"); + + // Expected: even indices i, odd indices 0 + // CHECK: 0.000000 + // CHECK: 0.000000 + // CHECK: 2.000000 + // CHECK: 0.000000 + // CHECK: 4.000000 + // CHECK: 0.000000 + // CHECK: 6.000000 + // CHECK: 0.000000 + // CHECK: 8.000000 + // CHECK: 0.000000 + // CHECK: 10.000000 + // CHECK: 0.000000 + // CHECK: 12.000000 + // CHECK: 0.000000 + // CHECK: 14.000000 + // CHECK: 0.000000 + // CHECK: 16.000000 + // CHECK: 0.000000 + // CHECK: 18.000000 + // CHECK: 0.000000 + // CHECK: 20.000000 + // CHECK: 0.000000 + // CHECK: 22.000000 + // CHECK: 0.000000 + // CHECK: 24.000000 + // CHECK: 0.000000 + // CHECK: 26.000000 + // CHECK: 0.000000 + // CHECK: 28.000000 + // CHECK: 0.000000 + // CHECK: 30.000000 + // CHECK: 0.000000 + // CHECK-NOT: 1.000000 + // CHECK-NOT: 3.000000 + // CHECK-NOT: 31.000000 + + free(result); + return 0; +} \ No newline at end of file diff --git a/offload/test/offloading/target_update_strided_struct_from.c b/offload/test/offloading/target_update_strided_struct_from.c new file mode 100644 index 0000000000000..1c5759b1864c5 --- /dev/null +++ b/offload/test/offloading/target_update_strided_struct_from.c @@ -0,0 +1,86 @@ +// RUN: %libomptarget-compile-run-and-check-generic +// This test checks that "update from" with user-defined mapper supports strided +// sections using fixed-size arrays in structs. + +#include <omp.h> +#include <stdio.h> +#include <stdlib.h> + +#define N 16 + +typedef struct { + double data[N]; + size_t len; +} T; + +#pragma omp declare mapper(custom : T v) map(to : v, v.len, v.data[0 : v.len]) + +int main() { + T s; + s.len = N; + + for (int i = 0; i < N; i++) { + s.data[i] = i; + } + + printf("original host array values:\n"); + for (int i = 0; i < N; i++) + printf("%f\n", s.data[i]); + printf("\n"); + +#pragma omp target data map(mapper(custom), tofrom : s) + { +// Execute on device with explicit mapper +#pragma omp target map(mapper(custom), tofrom : s) + { + for (int i = 0; i < s.len; i++) { + s.data[i] += i; + } + } + +// Update strided elements from device: indices 0,2,4,6,8,10,12,14 +#pragma omp target update from(s.data[0 : 8 : 2]) + } + + printf("from target array results:\n"); + for (int i = 0; i < N; i++) + printf("%f\n", s.data[i]); + + // CHECK: original host array values: + // CHECK-NEXT: 0.000000 + // CHECK-NEXT: 1.000000 + // CHECK-NEXT: 2.000000 + // CHECK-NEXT: 3.000000 + // CHECK-NEXT: 4.000000 + // CHECK-NEXT: 5.000000 + // CHECK-NEXT: 6.000000 + // CHECK-NEXT: 7.000000 + // CHECK-NEXT: 8.000000 + // CHECK-NEXT: 9.000000 + // CHECK-NEXT: 10.000000 + // CHECK-NEXT: 11.000000 + // CHECK-NEXT: 12.000000 + // CHECK-NEXT: 13.000000 + // CHECK-NEXT: 14.000000 + // CHECK-NEXT: 15.000000 + + // CHECK: from target array results: + // CHECK-NEXT: 0.000000 + // CHECK-NEXT: 1.000000 + // CHECK-NEXT: 4.000000 + // CHECK-NEXT: 3.000000 + // CHECK-NEXT: 8.000000 + // CHECK-NEXT: 5.000000 + // CHECK-NEXT: 12.000000 + // CHECK-NEXT: 7.000000 + // CHECK-NEXT: 16.000000 + // CHECK-NEXT: 9.000000 + // CHECK-NEXT: 20.000000 + // CHECK-NEXT: 11.000000 + // CHECK-NEXT: 24.000000 + // CHECK-NEXT: 13.000000 + // CHECK-NEXT: 28.000000 + // CHECK-NEXT: 15.000000 + + return 0; +} \ No newline at end of file diff --git a/offload/test/offloading/target_update_strided_struct_multiple_from.c b/offload/test/offloading/target_update_strided_struct_multiple_from.c new file mode 100644 index 0000000000000..95faf104826d5 --- /dev/null +++ b/offload/test/offloading/target_update_strided_struct_multiple_from.c @@ -0,0 +1,130 @@ +// RUN: %libomptarget-compile-run-and-check-generic +// This test checks that #pragma omp target update from(s1.data[0:6:2], +// s2.data[0:4:3]) correctly updates strided sections covering the full arrays +// from device to host. + +#include <omp.h> +#include <stdio.h> +#include <stdlib.h> + +#define LEN 12 + +typedef struct { + double data[LEN]; + int len; +} T; + +int main() { + T s1, s2; + s1.len = LEN; + s2.len = LEN; + + // Initialize struct arrays on host with simple sequential values + for (int i = 0; i < LEN; i++) { + s1.data[i] = i; + s2.data[i] = i; + } + + printf("original host struct array values:\n"); + printf("s1.data:\n"); + for (int i = 0; i < LEN; i++) + printf("%.1f\n", s1.data[i]); + printf("s2.data:\n"); + for (int i = 0; i < LEN; i++) + printf("%.1f\n", s2.data[i]); + +#pragma omp target data map(tofrom : s1, s2) + { +// Initialize all device values to 20 +#pragma omp target map(tofrom : s1, s2) + { + for (int i = 0; i < s1.len; i++) { + s1.data[i] = 20.0; + s2.data[i] = 20.0; + } + } + +// Modify specific strided elements on device to 10 +#pragma omp target map(tofrom : s1, s2) + { + // s1: modify even indices (0,2,4,6,8,10) + for (int i = 0; i < 6; i++) { + s1.data[i * 2] = 10.0; + } + // s2: modify every 3rd index (0,3,6,9) + for (int i = 0; i < 4; i++) { + s2.data[i * 3] = 10.0; + } + } + +// s1.data[0:6:2] updates only even indices: 0,2,4,6,8,10 +// s2.data[0:4:3] updates only every 3rd: 0,3,6,9 +#pragma omp target update from(s1.data[0 : 6 : 2], s2.data[0 : 4 : 3]) + } + + printf("host struct array values after update from:\n"); + printf("s1.data:\n"); + for (int i = 0; i < LEN; i++) + printf("%.1f\n", s1.data[i]); + printf("s2.data:\n"); + for (int i = 0; i < LEN; i++) + printf("%.1f\n", s2.data[i]); + + // CHECK: original host struct array values: + // CHECK-NEXT: s1.data: + // CHECK-NEXT: 0.0 + // CHECK-NEXT: 1.0 + // CHECK-NEXT: 2.0 + // CHECK-NEXT: 3.0 + // CHECK-NEXT: 4.0 + // CHECK-NEXT: 5.0 + // CHECK-NEXT: 6.0 + // CHECK-NEXT: 7.0 + // CHECK-NEXT: 8.0 + // CHECK-NEXT: 9.0 + // CHECK-NEXT: 10.0 + // CHECK-NEXT: 11.0 + // CHECK-NEXT: s2.data: + // CHECK-NEXT: 0.0 + // CHECK-NEXT: 1.0 + // CHECK-NEXT: 2.0 + // CHECK-NEXT: 3.0 + // CHECK-NEXT: 4.0 + // CHECK-NEXT: 5.0 + // CHECK-NEXT: 6.0 + // CHECK-NEXT: 7.0 + // CHECK-NEXT: 8.0 + // CHECK-NEXT: 9.0 + // CHECK-NEXT: 10.0 + // CHECK-NEXT: 11.0 + + // CHECK: host struct array values after update from: + // CHECK-NEXT: s1.data: + // CHECK-NEXT: 10.0 + // CHECK-NEXT: 20.0 + // CHECK-NEXT: 10.0 + // CHECK-NEXT: 20.0 + // CHECK-NEXT: 10.0 + // CHECK-NEXT: 20.0 + // CHECK-NEXT: 10.0 + // CHECK-NEXT: 20.0 + // CHECK-NEXT: 10.0 + // CHECK-NEXT: 20.0 + // CHECK-NEXT: 10.0 + // CHECK-NEXT: 20.0 + // CHECK-NEXT: s2.data: + // CHECK-NEXT: 10.0 + // CHECK-NEXT: 20.0 + // CHECK-NEXT: 20.0 + // CHECK-NEXT: 10.0 + // CHECK-NEXT: 20.0 + // CHECK-NEXT: 20.0 + // CHECK-NEXT: 10.0 + // CHECK-NEXT: 20.0 + // CHECK-NEXT: 20.0 + // CHECK-NEXT: 10.0 + // CHECK-NEXT: 20.0 + // CHECK-NEXT: 20.0 + + return 0; +} \ No newline at end of file diff --git a/offload/test/offloading/target_update_strided_struct_multiple_to.c b/offload/test/offloading/target_update_strided_struct_multiple_to.c new file mode 100644 index 0000000000000..1c3646aefabec --- /dev/null +++ b/offload/test/offloading/target_update_strided_struct_multiple_to.c @@ -0,0 +1,136 @@ +// RUN: %libomptarget-compile-run-and-check-generic +// This test checks that #pragma omp target update to(s1.data[0:6:2], +// s2.data[0:4:3]) correctly updates strided sections covering the full arrays +// from host to device. + +#include <omp.h> +#include <stdio.h> +#include <stdlib.h> + +#define LEN 12 + +typedef struct { + double data[LEN]; + int len; +} T; + +int main() { + T s1, s2; + s1.len = LEN; + s2.len = LEN; + + // Initialize struct arrays on host with simple sequential values + for (int i = 0; i < LEN; i++) { + s1.data[i] = i; + s2.data[i] = i; + } + + printf("original host struct array values:\n"); + printf("s1.data:\n"); + for (int i = 0; i < LEN; i++) + printf("%.1f\n", s1.data[i]); + printf("s2.data:\n"); + for (int i = 0; i < LEN; i++) + printf("%.1f\n", s2.data[i]); + printf("\n"); + +#pragma omp target data map(tofrom : s1, s2) + { +// Initialize device struct arrays to 20 +#pragma omp target map(tofrom : s1, s2) + { + for (int i = 0; i < s1.len; i++) { + s1.data[i] = 20.0; + s2.data[i] = 20.0; + } + } + + // s1: even indices (0,2,4,6,8,10) + for (int i = 0; i < 6; i++) { + s1.data[i * 2] = 10.0; + } + // s2: every 3rd index (0,3,6,9) + for (int i = 0; i < 4; i++) { + s2.data[i * 3] = 10.0; + } + +// s1.data[0:6:2] updates all even indices: 0,2,4,6,8,10 (6 elements, stride 2) +// s2.data[0:4:3] updates every 3rd: 0,3,6,9 (4 elements, stride 3) +#pragma omp target update to(s1.data[0 : 6 : 2], s2.data[0 : 4 : 3]) + +// Verify update on device by adding 5 +#pragma omp target map(tofrom : s1, s2) + { + for (int i = 0; i < s1.len; i++) { + s1.data[i] += 5.0; + s2.data[i] += 5.0; + } + } + } + + printf("device struct array values after update to:\n"); + printf("s1.data:\n"); + for (int i = 0; i < LEN; i++) + printf("%.1f\n", s1.data[i]); + printf("s2.data:\n"); + for (int i = 0; i < LEN; i++) + printf("%.1f\n", s2.data[i]); + + // CHECK: original host struct array values: + // CHECK-NEXT: s1.data: + // CHECK-NEXT: 0.0 + // CHECK-NEXT: 1.0 + // CHECK-NEXT: 2.0 + // CHECK-NEXT: 3.0 + // CHECK-NEXT: 4.0 + // CHECK-NEXT: 5.0 + // CHECK-NEXT: 6.0 + // CHECK-NEXT: 7.0 + // CHECK-NEXT: 8.0 + // CHECK-NEXT: 9.0 + // CHECK-NEXT: 10.0 + // CHECK-NEXT: 11.0 + // CHECK-NEXT: s2.data: + // CHECK-NEXT: 0.0 + // CHECK-NEXT: 1.0 + // CHECK-NEXT: 2.0 + // CHECK-NEXT: 3.0 + // CHECK-NEXT: 4.0 + // CHECK-NEXT: 5.0 + // CHECK-NEXT: 6.0 + // CHECK-NEXT: 7.0 + // CHECK-NEXT: 8.0 + // CHECK-NEXT: 9.0 + // CHECK-NEXT: 10.0 + // CHECK-NEXT: 11.0 + + // CHECK: device struct array values after update to: + // CHECK-NEXT: s1.data: + // CHECK-NEXT: 15.0 + // CHECK-NEXT: 25.0 + // CHECK-NEXT: 15.0 + // CHECK-NEXT: 25.0 + // CHECK-NEXT: 15.0 + // CHECK-NEXT: 25.0 + // CHECK-NEXT: 15.0 + // CHECK-NEXT: 25.0 + // CHECK-NEXT: 15.0 + // CHECK-NEXT: 25.0 + // CHECK-NEXT: 15.0 + // CHECK-NEXT: 25.0 + // CHECK-NEXT: s2.data: + // CHECK-NEXT: 15.0 + // CHECK-NEXT: 25.0 + // CHECK-NEXT: 25.0 + // CHECK-NEXT: 15.0 + // CHECK-NEXT: 25.0 + // CHECK-NEXT: 25.0 + // CHECK-NEXT: 15.0 + // CHECK-NEXT: 25.0 + // CHECK-NEXT: 25.0 + // CHECK-NEXT: 15.0 + // CHECK-NEXT: 25.0 + // CHECK-NEXT: 25.0 + + return 0; +} \ No newline at end of file diff --git a/offload/test/offloading/target_update_strided_struct_partial_from.c b/offload/test/offloading/target_update_strided_struct_partial_from.c new file mode 100644 index 0000000000000..d40fc85adc4f7 --- /dev/null +++ b/offload/test/offloading/target_update_strided_struct_partial_from.c @@ -0,0 +1,86 @@ +// RUN: %libomptarget-compile-run-and-check-generic +// This test checks that #pragma omp target update from(s.data[0:2:3]) correctly +// updates every third element (stride 3) from the device to the host +// using a struct with fixed-size array member. + +#include <omp.h> +#include <stdio.h> +#include <stdlib.h> + +#define LEN 11 + +typedef struct { + double data[LEN]; + size_t len; +} T; + +#pragma omp declare mapper(custom : T v) map(to : v, v.len, v.data[0 : v.len]) + +int main() { + T s; + s.len = LEN; + + // Initialize struct data on host + for (int i = 0; i < LEN; i++) { + s.data[i] = i; + } + + printf("original host array values:\n"); + for (int i = 0; i < LEN; i++) + printf("%.1f\n", s.data[i]); + printf("\n"); + +#pragma omp target data map(mapper(custom), tofrom : s) + { +// Execute on device with mapper +#pragma omp target map(mapper(custom), tofrom : s) + { + for (int i = 0; i < s.len; i++) { + s.data[i] = 20.0; // Set all to 20 on device + } + } + +// Modify specific elements on device (only first 2 stride positions) +#pragma omp target map(mapper(custom), tofrom : s) + { + s.data[0] = 10.0; + s.data[3] = 10.0; + } + +// indices 0,3 only +#pragma omp target update from(s.data[0 : 2 : 3]) + } + + printf("device array values after update from:\n"); + for (int i = 0; i < LEN; i++) + printf("%.1f\n", s.data[i]); + printf("\n"); + + // CHECK: original host array values: + // CHECK-NEXT: 0.0 + // CHECK-NEXT: 1.0 + // CHECK-NEXT: 2.0 + // CHECK-NEXT: 3.0 + // CHECK-NEXT: 4.0 + // CHECK-NEXT: 5.0 + // CHECK-NEXT: 6.0 + // CHECK-NEXT: 7.0 + // CHECK-NEXT: 8.0 + // CHECK-NEXT: 9.0 + // CHECK-NEXT: 10.0 + + // CHECK: device array values after update from: + // CHECK-NEXT: 10.0 + // CHECK-NEXT: 1.0 + // CHECK-NEXT: 2.0 + // CHECK-NEXT: 10.0 + // CHECK-NEXT: 4.0 + // CHECK-NEXT: 5.0 + // CHECK-NEXT: 6.0 + // CHECK-NEXT: 7.0 + // CHECK-NEXT: 8.0 + // CHECK-NEXT: 9.0 + // CHECK-NEXT: 10.0 + + return 0; +} \ No newline at end of file diff --git a/offload/test/offloading/target_update_strided_struct_partial_to.c b/offload/test/offloading/target_update_strided_struct_partial_to.c new file mode 100644 index 0000000000000..d0c8adc6b5ea0 --- /dev/null +++ b/offload/test/offloading/target_update_strided_struct_partial_to.c @@ -0,0 +1,85 @@ +// RUN: %libomptarget-compile-run-and-check-generic +// This test checks that #pragma omp target update to(s.data[0:2:3]) correctly +// updates every third element (stride 3) from the host to the device +// for struct member arrays. + +#include <omp.h> +#include <stdio.h> +#include <stdlib.h> + +#define LEN 11 + +typedef struct { + double data[LEN]; + int len; +} T; + +int main() { + T s; + s.len = LEN; + + // Initialize struct array on host with simple sequential values + for (int i = 0; i < LEN; i++) + s.data[i] = i; + + printf("original host struct array values:\n"); + for (int i = 0; i < LEN; i++) + printf("%.1f\n", s.data[i]); + printf("\n"); + +#pragma omp target data map(tofrom : s) + { +// Initialize all elements on device to 20 +#pragma omp target map(tofrom : s) + { + for (int i = 0; i < s.len; i++) + s.data[i] = 20.0; + } + + // Modify host struct data for elements that will be updated (set to 10) + s.data[0] = 10.0; + s.data[3] = 10.0; + +// indices 0,3 only +#pragma omp target update to(s.data[0 : 2 : 3]) + +// Verify on device by adding 5 to all elements +#pragma omp target map(tofrom : s) + { + for (int i = 0; i < s.len; i++) + s.data[i] += 5.0; + } + } + + printf("device struct array values after update to:\n"); + for (int i = 0; i < LEN; i++) + printf("%.1f\n", s.data[i]); + + // CHECK: original host struct array values: + // CHECK-NEXT: 0.0 + // CHECK-NEXT: 1.0 + // CHECK-NEXT: 2.0 + // CHECK-NEXT: 3.0 + // CHECK-NEXT: 4.0 + // CHECK-NEXT: 5.0 + // CHECK-NEXT: 6.0 + // CHECK-NEXT: 7.0 + // CHECK-NEXT: 8.0 + // CHECK-NEXT: 9.0 + // CHECK-NEXT: 10.0 + + // CHECK: device struct array values after update to: + // CHECK-NEXT: 15.0 + // CHECK-NEXT: 25.0 + // CHECK-NEXT: 25.0 + // CHECK-NEXT: 15.0 + // CHECK-NEXT: 25.0 + // CHECK-NEXT: 25.0 + // CHECK-NEXT: 25.0 + // CHECK-NEXT: 25.0 + // CHECK-NEXT: 25.0 + // CHECK-NEXT: 25.0 + // CHECK-NEXT: 25.0 + + return 0; +} \ No newline at end of file diff --git a/offload/test/offloading/target_update_strided_struct_to.c b/offload/test/offloading/target_update_strided_struct_to.c new file mode 100644 index 0000000000000..b3fe32bbaa345 --- /dev/null +++ b/offload/test/offloading/target_update_strided_struct_to.c @@ -0,0 +1,98 @@ +// RUN: %libomptarget-compile-run-and-check-generic +// This test checks that "update to" with struct member arrays supports strided +// sections using fixed-size arrays in structs. + +#include <omp.h> +#include <stdio.h> +#include <stdlib.h> + +#define N 16 + +typedef struct { + double data[N]; + int len; +} T; + +int main() { + T s; + s.len = N; + + // Initialize struct array on host with simple sequential values + for (int i = 0; i < N; i++) { + s.data[i] = i; + } + + printf("original host struct array values:\n"); + for (int i = 0; i < N; i++) + printf("%.1f\n", s.data[i]); + printf("\n"); + +#pragma omp target data map(tofrom : s) + { +// Initialize device struct array to 20 +#pragma omp target map(tofrom : s) + { + for (int i = 0; i < s.len; i++) { + s.data[i] = 20.0; + } + } + + // Modify host struct data for strided elements (set to 10) + for (int i = 0; i < 8; i++) { + s.data[i * 2] = 10.0; // Set even indices to 10 + } + +// indices 0,2,4,6,8,10,12,14 +#pragma omp target update to(s.data[0 : 8 : 2]) + +// Execute on device - add 5 to verify update worked +#pragma omp target map(tofrom : s) + { + for (int i = 0; i < s.len; i++) { + s.data[i] += 5.0; + } + } + } + + printf("after target update to struct:\n"); + for (int i = 0; i < N; i++) + printf("%.1f\n", s.data[i]); + + // CHECK: original host struct array values: + // CHECK-NEXT: 0.0 + // CHECK-NEXT: 1.0 + // CHECK-NEXT: 2.0 + // CHECK-NEXT: 3.0 + // CHECK-NEXT: 4.0 + // CHECK-NEXT: 5.0 + // CHECK-NEXT: 6.0 + // CHECK-NEXT: 7.0 + // CHECK-NEXT: 8.0 + // CHECK-NEXT: 9.0 + // CHECK-NEXT: 10.0 + // CHECK-NEXT: 11.0 + // CHECK-NEXT: 12.0 + // CHECK-NEXT: 13.0 + // CHECK-NEXT: 14.0 + // CHECK-NEXT: 15.0 + + // CHECK: after target update to struct: + // CHECK-NEXT: 15.0 + // CHECK-NEXT: 25.0 + // CHECK-NEXT: 15.0 + // CHECK-NEXT: 25.0 + // CHECK-NEXT: 15.0 + // CHECK-NEXT: 25.0 + // CHECK-NEXT: 15.0 + // CHECK-NEXT: 25.0 + // CHECK-NEXT: 15.0 + // CHECK-NEXT: 25.0 + // CHECK-NEXT: 15.0 + // CHECK-NEXT: 25.0 + // CHECK-NEXT: 15.0 + // CHECK-NEXT: 25.0 + // CHECK-NEXT: 15.0 + // CHECK-NEXT: 25.0 + + return 0; +} \ No newline at end of file diff --git a/offload/test/offloading/target_update_to.c b/offload/test/offloading/target_update_to.c new file mode 100644 index 0000000000000..ecfc3bb69dbf4 --- /dev/null +++ b/offload/test/offloading/target_update_to.c @@ -0,0 +1,81 @@ +// RUN: %libomptarget-compile-run-and-check-generic +// This test checks that "update to" clause in OpenMP supports strided sections. +// #pragma omp target update to(result[0:8:2]) updates every other element +// (stride 2) + +#include <omp.h> +#include <stdio.h> +#include <stdlib.h> + +#define N 16 + +int main() { + double *result = (double *)calloc(N, sizeof(double)); + + // Initialize on host + for (int i = 0; i < N; i++) { + result[i] = i; + } + + // Initial values + printf("original host array values:\n"); + for (int i = 0; i < N; i++) + printf("%f\n", result[i]); + printf("\n"); + +#pragma omp target data map(tofrom : result[0 : N]) + { +// Update strided elements to device: indices 0,2,4,6 +#pragma omp target update to(result[0 : 8 : 2]) + +#pragma omp target + { + for (int i = 0; i < N; i++) { + result[i] += i; + } + } + } + + printf("from target array results:\n"); + for (int i = 0; i < N; i++) + printf("%f\n", result[i]); + + // CHECK: original host array values: + // CHECK-NEXT: 0.000000 + // CHECK-NEXT: 1.000000 + // CHECK-NEXT: 2.000000 + // CHECK-NEXT: 3.000000 + // CHECK-NEXT: 4.000000 + // CHECK-NEXT: 5.000000 + // CHECK-NEXT: 6.000000 + // CHECK-NEXT: 7.000000 + // CHECK-NEXT: 8.000000 + // CHECK-NEXT: 9.000000 + // CHECK-NEXT: 10.000000 + // CHECK-NEXT: 11.000000 + // CHECK-NEXT: 12.000000 + // CHECK-NEXT: 13.000000 + // CHECK-NEXT: 14.000000 + // CHECK-NEXT: 15.000000 + + // CHECK: from target array results: + // CHECK-NEXT: 0.000000 + // CHECK-NEXT: 2.000000 + // CHECK-NEXT: 4.000000 + // CHECK-NEXT: 6.000000 + // CHECK-NEXT: 8.000000 + // CHECK-NEXT: 10.000000 + // CHECK-NEXT: 12.000000 + // CHECK-NEXT: 14.000000 + // CHECK-NEXT: 16.000000 + // CHECK-NEXT: 18.000000 + // CHECK-NEXT: 20.000000 + // CHECK-NEXT: 22.000000 + // CHECK-NEXT: 24.000000 + // CHECK-NEXT: 26.000000 + // CHECK-NEXT: 28.000000 + // CHECK-NEXT: 30.000000 + + free(result); + return 0; +} \ No newline at end of file >From dd6dd25b079ddf5189540c255fc7ec25f5bb047a Mon Sep 17 00:00:00 2001 From: amtiwari <[email protected]> Date: Fri, 5 Dec 2025 04:25:05 -0500 Subject: [PATCH 4/5] test_w/o_extern --- .../test/OpenMP/target_update_strided_ptr_messages_from.c | 4 ---- clang/test/OpenMP/target_update_strided_ptr_messages_to.c | 1 - .../target_update_strided_ptr_multiple_messages_from.c | 8 -------- .../target_update_strided_ptr_multiple_messages_to.c | 8 -------- .../target_update_strided_ptr_partial_messages_from.c | 4 ---- .../target_update_strided_ptr_partial_messages_to.c | 4 ---- 6 files changed, 29 deletions(-) diff --git a/clang/test/OpenMP/target_update_strided_ptr_messages_from.c b/clang/test/OpenMP/target_update_strided_ptr_messages_from.c index cd158ff10e4de..65757083dd50d 100644 --- a/clang/test/OpenMP/target_update_strided_ptr_messages_from.c +++ b/clang/test/OpenMP/target_update_strided_ptr_messages_from.c @@ -1,12 +1,8 @@ // RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s -Wuninitialized // RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 %s -Wuninitialized -extern void *malloc(__SIZE_TYPE__); -extern void free(void *); - int main(int argc, char **argv) { int len = 16; - double *data = (double *)malloc(len * sizeof(double)); // Valid strided array sections with FROM #pragma omp target update from(data[0:8:2]) // OK - even indices diff --git a/clang/test/OpenMP/target_update_strided_ptr_messages_to.c b/clang/test/OpenMP/target_update_strided_ptr_messages_to.c index 6459c79149326..e074fa6cbbfc7 100644 --- a/clang/test/OpenMP/target_update_strided_ptr_messages_to.c +++ b/clang/test/OpenMP/target_update_strided_ptr_messages_to.c @@ -3,7 +3,6 @@ int main(int argc, char **argv) { int len = 16; - double *data = (double *)malloc(len * sizeof(double)); // Valid strided array sections with TO #pragma omp target update to(data[0:8:2]) // OK - even indices diff --git a/clang/test/OpenMP/target_update_strided_ptr_multiple_messages_from.c b/clang/test/OpenMP/target_update_strided_ptr_multiple_messages_from.c index 2462ae1c840c3..3aa8777676a66 100644 --- a/clang/test/OpenMP/target_update_strided_ptr_multiple_messages_from.c +++ b/clang/test/OpenMP/target_update_strided_ptr_multiple_messages_from.c @@ -1,9 +1,6 @@ // RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s -Wuninitialized // RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 %s -Wuninitialized -extern void *malloc(__SIZE_TYPE__); -extern void free(void *); - double *data; double *data1; double *data2; @@ -11,11 +8,6 @@ double *data2; int main(int argc, char **argv) { int len = 12; - // Allocate memory for explicit pointers - data = (double *)malloc(len * sizeof(double)); - data1 = (double *)malloc(len * sizeof(double)); - data2 = (double *)malloc(len * sizeof(double)); - // Valid multiple strided array sections #pragma omp target update from(data1[0:6:2], data2[0:4:3]) // OK - different strides {} diff --git a/clang/test/OpenMP/target_update_strided_ptr_multiple_messages_to.c b/clang/test/OpenMP/target_update_strided_ptr_multiple_messages_to.c index d8cebefb02606..ce26ad2d827e0 100644 --- a/clang/test/OpenMP/target_update_strided_ptr_multiple_messages_to.c +++ b/clang/test/OpenMP/target_update_strided_ptr_multiple_messages_to.c @@ -1,9 +1,6 @@ // RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s -Wuninitialized // RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 %s -Wuninitialized -extern void *malloc(__SIZE_TYPE__); -extern void free(void *); - double *data; double *data1; double *data2; @@ -11,11 +8,6 @@ double *data2; int main(int argc, char **argv) { int len = 12; - // Allocate memory for explicit pointers - data = (double *)malloc(len * sizeof(double)); - data1 = (double *)malloc(len * sizeof(double)); - data2 = (double *)malloc(len * sizeof(double)); - // Valid multiple strided array sections #pragma omp target update to(data1[0:6:2], data2[0:4:3]) // OK - different strides {} diff --git a/clang/test/OpenMP/target_update_strided_ptr_partial_messages_from.c b/clang/test/OpenMP/target_update_strided_ptr_partial_messages_from.c index 2f36dfa84cd1b..3d8f26cdecc0b 100644 --- a/clang/test/OpenMP/target_update_strided_ptr_partial_messages_from.c +++ b/clang/test/OpenMP/target_update_strided_ptr_partial_messages_from.c @@ -1,12 +1,8 @@ // RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s -Wuninitialized // RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 %s -Wuninitialized -extern void *malloc(__SIZE_TYPE__); -extern void free(void *); - int main(int argc, char **argv) { int len = 11; - double *data = (double *)malloc(len * sizeof(double)); // Valid partial strided sections with FROM #pragma omp target update from(data[0:2:3]) // OK - partial coverage diff --git a/clang/test/OpenMP/target_update_strided_ptr_partial_messages_to.c b/clang/test/OpenMP/target_update_strided_ptr_partial_messages_to.c index ce4b315bec1ae..8df0b46dfb272 100644 --- a/clang/test/OpenMP/target_update_strided_ptr_partial_messages_to.c +++ b/clang/test/OpenMP/target_update_strided_ptr_partial_messages_to.c @@ -1,12 +1,8 @@ // RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s -Wuninitialized // RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 %s -Wuninitialized -extern void *malloc(__SIZE_TYPE__); -extern void free(void *); - int main(int argc, char **argv) { int len = 11; - double *data = (double *)malloc(len * sizeof(double)); // Valid partial strided sections with TO #pragma omp target update to(data[0:2:3]) // OK - partial coverage >From ca4eee50deaa2befd42723273a7ab7c620ba44de Mon Sep 17 00:00:00 2001 From: amtiwari <[email protected]> Date: Fri, 5 Dec 2025 04:42:29 -0500 Subject: [PATCH 5/5] test_again --- clang/test/OpenMP/target_update_strided_ptr_messages_from.c | 1 - clang/test/OpenMP/target_update_strided_ptr_messages_to.c | 1 - .../target_update_strided_ptr_multiple_messages_from.c | 5 +---- .../OpenMP/target_update_strided_ptr_multiple_messages_to.c | 3 --- .../OpenMP/target_update_strided_ptr_partial_messages_from.c | 1 - .../OpenMP/target_update_strided_ptr_partial_messages_to.c | 1 - 6 files changed, 1 insertion(+), 11 deletions(-) diff --git a/clang/test/OpenMP/target_update_strided_ptr_messages_from.c b/clang/test/OpenMP/target_update_strided_ptr_messages_from.c index 65757083dd50d..a99b2815b1f33 100644 --- a/clang/test/OpenMP/target_update_strided_ptr_messages_from.c +++ b/clang/test/OpenMP/target_update_strided_ptr_messages_from.c @@ -35,6 +35,5 @@ int main(int argc, char **argv) { #pragma omp target update from(data[0:4:2:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} {} - free(data); return 0; } \ No newline at end of file diff --git a/clang/test/OpenMP/target_update_strided_ptr_messages_to.c b/clang/test/OpenMP/target_update_strided_ptr_messages_to.c index e074fa6cbbfc7..914172fef4f98 100644 --- a/clang/test/OpenMP/target_update_strided_ptr_messages_to.c +++ b/clang/test/OpenMP/target_update_strided_ptr_messages_to.c @@ -35,6 +35,5 @@ int main(int argc, char **argv) { #pragma omp target update to(data[0:4:2:1]) // expected-error {{expected ']'}} expected-note {{to match this '['}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} {} - free(data); return 0; } \ No newline at end of file diff --git a/clang/test/OpenMP/target_update_strided_ptr_multiple_messages_from.c b/clang/test/OpenMP/target_update_strided_ptr_multiple_messages_from.c index 3aa8777676a66..7e956fdf5aec4 100644 --- a/clang/test/OpenMP/target_update_strided_ptr_multiple_messages_from.c +++ b/clang/test/OpenMP/target_update_strided_ptr_multiple_messages_from.c @@ -48,9 +48,6 @@ int main(int argc, char **argv) { #pragma omp target update from(data1[0:4:2:3], data2[0:3:2]) // expected-error {{expected ']'}} expected-note {{to match this '['}} #pragma omp target update from(data[0:4:2], data1[0:3:2:1], data2[0:2:3]) // expected-error {{expected ']'}} expected-note {{to match this '['}} - - free(data); - free(data1); - free(data2); + return 0; } \ No newline at end of file diff --git a/clang/test/OpenMP/target_update_strided_ptr_multiple_messages_to.c b/clang/test/OpenMP/target_update_strided_ptr_multiple_messages_to.c index ce26ad2d827e0..9daafef664da4 100644 --- a/clang/test/OpenMP/target_update_strided_ptr_multiple_messages_to.c +++ b/clang/test/OpenMP/target_update_strided_ptr_multiple_messages_to.c @@ -49,8 +49,5 @@ int main(int argc, char **argv) { #pragma omp target update to(data[0:4:2], data1[0:3:2:1], data2[0:2:3]) // expected-error {{expected ']'}} expected-note {{to match this '['}} - free(data); - free(data1); - free(data2); return 0; } \ No newline at end of file diff --git a/clang/test/OpenMP/target_update_strided_ptr_partial_messages_from.c b/clang/test/OpenMP/target_update_strided_ptr_partial_messages_from.c index 3d8f26cdecc0b..861872b8ba564 100644 --- a/clang/test/OpenMP/target_update_strided_ptr_partial_messages_from.c +++ b/clang/test/OpenMP/target_update_strided_ptr_partial_messages_from.c @@ -32,6 +32,5 @@ int main(int argc, char **argv) { // Compile-time invalid strides #pragma omp target update from(data[1:2:-3]) // expected-error {{section stride is evaluated to a non-positive value -3}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} - free(data); return 0; } \ No newline at end of file diff --git a/clang/test/OpenMP/target_update_strided_ptr_partial_messages_to.c b/clang/test/OpenMP/target_update_strided_ptr_partial_messages_to.c index 8df0b46dfb272..d0f72a0b944aa 100644 --- a/clang/test/OpenMP/target_update_strided_ptr_partial_messages_to.c +++ b/clang/test/OpenMP/target_update_strided_ptr_partial_messages_to.c @@ -31,6 +31,5 @@ int main(int argc, char **argv) { // Compile-time invalid strides #pragma omp target update to(data[1:2:-3]) // expected-error {{section stride is evaluated to a non-positive value -3}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} - free(data); return 0; } \ No newline at end of file _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
