-
Notifications
You must be signed in to change notification settings - Fork 15.5k
[Clang][OpenMP] Handle check for non-contiguous mapping in pointer-based array sections #157443
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
[Clang][OpenMP] Handle check for non-contiguous mapping in pointer-based array sections #157443
Conversation
|
Does this patch work for the test_target_update_mapper_{to,from}_discontiguous tests? |
Yes Julian, for the compilation error marked in SWDEV-553534 |
|
I had a quick look because I was looking into this briefly too -- it still crashes for me, like so: The strange thing about the surrounding loop (in But, that can't ever happen because of the if stmt further up: So it might be worth doing some archaeology to figure out why/when this was broken. JFYI! |
|
Yes indeed the |
|
@llvm/pr-subscribers-offload @llvm/pr-subscribers-clang-codegen Author: Amit Tiwari (amitamd7) ChangesThis patch adds the check where pointer-based array sections are not considered while deducing Full diff: https://github.com/llvm/llvm-project/pull/157443.diff 1 Files Affected:
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.
|
|
Missing testcase. |
70e1552 to
f627a17
Compare
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
f627a17 to
5c7f6ee
Compare
901f2cf to
eff9a58
Compare
eff9a58 to
3c552fd
Compare
Done. |
Done. |
| if (const auto *PtrType = Ty->getAs<PointerType>()) { | ||
| ElementType = PtrType->getPointeeType().getTypePtr(); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Drop braces
| extern void *malloc(__SIZE_TYPE__); | ||
| extern void free(void *); |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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'
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
| // 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]], |
There was a problem hiding this comment.
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
3c552fd to
4009b36
Compare
4009b36 to
1879ae1
Compare
|
Added few more clang-unit tests that support the inlined arrays in a structure. Corresponding offload lit-tests were added previously. |
| // 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) |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
1. ElementType deduction for pointer-based array sections
Problem: Pointer-based array sections were previously ignored during
ElementTypededuction, leading to incorrect assumptions about array item types.This often resulted in out-of-bounds access, as seen in the assertion failure:
Fix: Added a check in clang/lib/CodeGen/CGOpenMPRuntime.cpp to ensure
ElementTypeis 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. WhenDims[I] == 0:Reverse indexing still stores pointers to uninitialized allocas or mismatched slots. Runtime interprets
ArgSizes[I](derived fromDims[I])as dimensionality, causing size/offset calculations to collapse to zero → results insize=0async 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.