Skip to content

Conversation

@amitamd7
Copy link
Contributor

@amitamd7 amitamd7 commented Sep 8, 2025

1. ElementType deduction for pointer-based array sections

Problem: Pointer-based array sections were previously ignored during ElementType deduction, leading to incorrect assumptions about array item types.

This often resulted in out-of-bounds access, as seen in the assertion failure:

Assertion `idx < size()' failed.
llvm-project/llvm/include/llvm/ADT/SmallVector.h:292:
reference llvm::SmallVectorTemplateCommon<llvm::Value *>::operatorsize_type
[T = llvm::Value *]

Fix: Added a check in clang/lib/CodeGen/CGOpenMPRuntime.cpp to ensure ElementType is correctly detected for cases involving non-contiguous updates with a base pointer.
Impact: Resolves failures in OpenMP_VV (formerly sollve_vv) and other offload/clang-OpenMP tests:

All tests under:
https://github.com/OpenMP-Validation-and-Verification/OpenMP_VV/tree/master/tests/5.0/target_update

test_target_update_mapper_from_discontiguous.c
test_target_update_mapper_to_discontiguous.c
test_target_update_to_discontiguous.c
test_target_update_from_discontiguous.c

2. Zero-dimension propagation in struct member mappings

Problem: A zero-dimension entry for struct members introduced inconsistencies in complex mapping logic within OMPIRBuilder.cpp.

Placeholder zeros propagated to emitNonContiguousDescriptor(), breaking reverse indexing logic and corrupting IR:

Loops assume Dims[I] >= 1. When Dims[I] == 0:

Reverse indexing still stores pointers to uninitialized allocas or mismatched slots. Runtime interprets ArgSizes[I] (derived from Dims[I]) as dimensionality, causing size/offset calculations to collapse to zero → results in size=0 async copy and plugin interface errors.

Fix: Prepend a synthetic dimension of size 1 instead of appending a zero, preserving correctness in targetDataUpdate() for non-contiguous updates.
Impact: Added dedicated test cases that previously failed on main.

@jtb20
Copy link
Contributor

jtb20 commented Sep 8, 2025

Does this patch work for the test_target_update_mapper_{to,from}_discontiguous tests?

@amitamd7
Copy link
Contributor Author

amitamd7 commented Sep 8, 2025

Does this patch work for the test_target_update_mapper_{to,from}_discontiguous tests?

Yes Julian, for the compilation error marked in SWDEV-553534

@jtb20
Copy link
Contributor

jtb20 commented Sep 8, 2025

I had a quick look because I was looking into this briefly too -- it still crashes for me, like so:

Thread 1 "test_target_upd" received signal SIGSEGV, Segmentation fault.
0x00007ffff7aec887 in targetDataUpdate (Loc=0x55555555b5c8, Device=..., ArgNum=2, ArgsBase=0x7fffffffd880, Args=0x7fffffffd870, ArgSizes=0x7fffffffd860, ArgTypes=0x5555555582d0, ArgNames=0x55555555b5b8, ArgMappers=0x0, AsyncInfo=..., AttachInfo=0x0, FromMapper=false) at /work1/julbrown/code/mainline+amd-staging/src/llvm-project-main/offload/libomptarget/omptarget.cpp:1297
1297              NonContig[DimSize - 1].Count * NonContig[DimSize - 1].Stride;

The strange thing about the surrounding loop (in generateInfoForComponentList) is that it appears like it was written to handle this case at some point, see e.g. the comment:

        // 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.

But, that can't ever happen because of the if stmt further up:

      if (!OASE)
        continue;

So it might be worth doing some archaeology to figure out why/when this was broken.

JFYI!

@amitamd7
Copy link
Contributor Author

amitamd7 commented Sep 9, 2025

Yes indeed the if (!OASE) check is FALSE only once (when it is an single dimension array-section expression) and we would ideally want to get the ElementType to be deduced in that traversal itself for OASE case. I checked few cases where it hits off CAT, VAT while the one in test_target_update_mapper_from_discontiguous.c (and other mentioned tests in the ticket), it goes undetected.

@amitamd7 amitamd7 marked this pull request as ready for review September 10, 2025 06:41
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:codegen IR generation bugs: mangling, exceptions, etc. clang:openmp OpenMP related changes to Clang labels Sep 10, 2025
@llvmbot
Copy link
Member

llvmbot commented Sep 10, 2025

@llvm/pr-subscribers-offload
@llvm/pr-subscribers-clang

@llvm/pr-subscribers-clang-codegen

Author: Amit Tiwari (amitamd7)

Changes

This patch adds the check where pointer-based array sections are not considered while deducing ElementType of the array items.


Full diff: https://github.com/llvm/llvm-project/pull/157443.diff

1 Files Affected:

  • (modified) clang/lib/CodeGen/CGOpenMPRuntime.cpp (+6-4)
diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
index b38eb54036e60..416a8c1ad4a03 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -7930,10 +7930,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.

@amitamd7 amitamd7 changed the title [Clang][OpenMP] Handle check for pointer-based array sections [Clang][OpenMP] Handle check for non-contiguous update in pointer-based array sections Sep 10, 2025
@amitamd7 amitamd7 changed the title [Clang][OpenMP] Handle check for non-contiguous update in pointer-based array sections [Clang][OpenMP] Handle check for non-contiguous mapping in pointer-based array sections Sep 10, 2025
@efriedma-quic
Copy link
Collaborator

Missing testcase.

@amitamd7 amitamd7 force-pushed the tiwari_array_section_pointer_variable branch from 70e1552 to f627a17 Compare November 24, 2025 09:35
@github-actions
Copy link

github-actions bot commented Nov 24, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

@amitamd7 amitamd7 force-pushed the tiwari_array_section_pointer_variable branch from f627a17 to 5c7f6ee Compare November 24, 2025 10:58
@amitamd7 amitamd7 force-pushed the tiwari_array_section_pointer_variable branch 2 times, most recently from 901f2cf to eff9a58 Compare November 24, 2025 13:57
@amitamd7 amitamd7 marked this pull request as draft November 25, 2025 08:24
@amitamd7 amitamd7 force-pushed the tiwari_array_section_pointer_variable branch from eff9a58 to 3c552fd Compare November 25, 2025 13:04
@amitamd7
Copy link
Contributor Author

Missing testcase.

Done.

@amitamd7 amitamd7 marked this pull request as ready for review November 26, 2025 06:16
@amitamd7
Copy link
Contributor Author

Missing testcase.

Done.

Comment on lines 8249 to 8251
if (const auto *PtrType = Ty->getAs<PointerType>()) {
ElementType = PtrType->getPointeeType().getTypePtr();
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drop braces

Comment on lines 4 to 5
extern void *malloc(__SIZE_TYPE__);
extern void free(void *);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clang unit test does not need to use these functions, remove

Copy link
Contributor Author

@amitamd7 amitamd7 Dec 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CI/CD doesn't support the malloc declaration used in the unit-test. Specifying the declaration as a pointer to <TYPE> is the integral part of the test. The use of extern can be seen in other tests too, when the type specified mismatches with the dynamically linked malloc type. Without the malloc definition, the build CI/CD fails so:

# |   File /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/OpenMP/target_update_strided_ptr_messages_to.c Line 39: call to undeclared library function 'free' with type 'void (void *)'; **ISO C99 and later do not support implicit function declarations**
 # | error: 'expected-note' diagnostics seen but not expected: 
 # |   File /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/OpenMP/target_update_strided_ptr_messages_to.c Line 6: include the header <stdlib.h> or explicitly provide a declaration for 'malloc' 

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You do not need to use them at all, this is a codegen test, not the execution, you can simply remove them

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

Comment on lines -1224 to -1228
// 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]],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better not to remove these checks, but change accordingly

@amitamd7 amitamd7 marked this pull request as draft December 1, 2025 06:48
@amitamd7 amitamd7 force-pushed the tiwari_array_section_pointer_variable branch from 3c552fd to 4009b36 Compare December 2, 2025 13:28
@amitamd7 amitamd7 marked this pull request as ready for review December 2, 2025 13:29
@amitamd7 amitamd7 marked this pull request as draft December 2, 2025 13:50
@amitamd7 amitamd7 force-pushed the tiwari_array_section_pointer_variable branch from 4009b36 to 1879ae1 Compare December 2, 2025 17:03
@amitamd7 amitamd7 marked this pull request as ready for review December 2, 2025 18:35
@amitamd7
Copy link
Contributor Author

amitamd7 commented Dec 2, 2025

Added few more clang-unit tests that support the inlined arrays in a structure. Corresponding offload lit-tests were added previously.

Comment on lines 1224 to 1227
// CK21-DAG: [[GEPBP:%.+]] = getelementptr inbounds [2 x ptr], ptr %.offload_baseptrs, i32 0, i32 0
// CK21-DAG: [[GEPP:%.+]] = getelementptr inbounds [2 x ptr], ptr %.offload_ptrs, i32 0, i32 0
// CK21-DAG: [[GEPSZ:%.+]] = getelementptr inbounds [2 x i64], ptr %.offload_sizes, i32 0, i32 0
// CK21-DAG: call void @__tgt_target_data_update_mapper(ptr @{{.+}}, i64 -1, i32 2, ptr [[GEPBP]], ptr [[GEPP]], ptr [[GEPSZ]], ptr @.offload_maptypes, ptr null, ptr null)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not recommended to use %.offload_baseptrs-like names, replace by regexps

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang:codegen IR generation bugs: mangling, exceptions, etc. clang:openmp OpenMP related changes to Clang clang Clang issues not falling into any other category offload

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants