[clang] [llvm] [Clang][OpenMP] Non-contiguous strided update (PR #144635)

2025-06-17 Thread Amit Tiwari via cfe-commits

https://github.com/amitamd7 created 
https://github.com/llvm/llvm-project/pull/144635

This patch handles the strided update in the `#pragma omp target update 
from(data[a:b:c])` directive where 'c' represents the strided access leading to 
non-contiguous update in the `data` array when the offloaded execution returns 
the control back to host from device using the `from` clause.

Issue: Clang CodeGen where info is generated for the particular `MapType` (to, 
from, etc), it was failing to detect the strided access. Because of this, the 
`MapType` bits were incorrect when passed to runtime. This led to incorrect 
execution (contiguous) in the libomptarget runtime code.

Added a minimal testcase that verifies the working of the patch.

>From 6846880a245a199b31f5cbbc0e9781460dc185ba Mon Sep 17 00:00:00 2001
From: amtiwari 
Date: Mon, 16 Jun 2025 01:07:01 -0400
Subject: [PATCH 1/2] strided_update_offloading

---
 clang/lib/CodeGen/CGOpenMPRuntime.cpp | 35 ++-
 1 file changed, 34 insertions(+), 1 deletion(-)

diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp 
b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
index 4173355491fd4..81a2dd0fae5c9 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -7384,7 +7384,40 @@ class MappableExprsHandler {
 // dimension.
 uint64_t DimSize = 1;
 
-bool IsNonContiguous = CombinedInfo.NonContigInfo.IsNonContiguous;
+// Detects non-contiguous updates due to strided accesses.
+// Sets the 'IsNonContiguous' flag so that the 'MapType' bits are set
+// correctly when generating information to be passed to the runtime. The
+// flag is set to true if any array section has a stride not equal to 1, or
+// if the stride is not a constant expression (conservatively assumed
+// non-contiguous).
+bool IsNonContiguous = false;
+for (const auto &Component : Components) {
+  const auto *OASE =
+  dyn_cast(Component.getAssociatedExpression());
+  if (OASE) {
+const Expr *StrideExpr = OASE->getStride();
+if (StrideExpr) {
+  // Check if the stride is a constant integer expression
+  if (StrideExpr->isIntegerConstantExpr(CGF.getContext())) {
+if (auto Constant =
+StrideExpr->getIntegerConstantExpr(CGF.getContext())) {
+  int64_t StrideVal = Constant->getExtValue();
+  if (StrideVal != 1) {
+// Set flag if stride is not 1 (i.e., non-contiguous update)
+IsNonContiguous = true;
+break;
+  }
+}
+  } else {
+// If stride is not a constant, conservatively treat as
+// non-contiguous
+IsNonContiguous = true;
+break;
+  }
+}
+  }
+}
+
 bool IsPrevMemberReference = false;
 
 bool IsPartialMapped =

>From 31b83e221c03bee590182ed6c692dd8206a6e833 Mon Sep 17 00:00:00 2001
From: amtiwari 
Date: Tue, 17 Jun 2025 04:04:03 -0400
Subject: [PATCH 2/2] bug-tested

---
 offload/test/offloading/strided_update.c | 51 
 1 file changed, 51 insertions(+)
 create mode 100644 offload/test/offloading/strided_update.c

diff --git a/offload/test/offloading/strided_update.c 
b/offload/test/offloading/strided_update.c
new file mode 100644
index 0..fc47216fb5684
--- /dev/null
+++ b/offload/test/offloading/strided_update.c
@@ -0,0 +1,51 @@
+// Checks that "update from" clause in OpenMP is supported when the elements 
are updated in a non-contiguous manner.
+// RUN: %libomptarget-compile-run-and-check-generic
+#include   
+#include   
+  
+int main() {  
+  int len = 8;  
+  double data[len];  
+  #pragma omp target map(tofrom: len, 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: len, data[0:len])  
+  {  
+#pragma omp target  
+for (int i = 0; i < len; i++) {  
+  data[i] += i ;  
+}  
+  
+#pragma omp target update from(data[0:8:2])  
+  }  
+  // from results  
+  // CHECK: 0.00
+  // CHECK: 1.00
+  // CHECK: 4.00
+  // CHECK: 3.00
+  // CHECK: 8.00
+  // CHECK: 5.00
+  // CHECK: 12.00
+  // CHECK: 7.00
+  // CHECK-NOT: 2.00
+  // CHECK-NOT: 6.00
+  // CHECK-NOT: 10.00
+  // CHECK-NOT: 14.00
+
+  printf("from target array results:\n");  
+  for (int i = 0; i < len; i++)  
+printf("%f\n", data[i]);  
+  printf("\n");  
+  
+  return 0;  
+}  
+

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [Clang][OpenMP] Non-contiguous strided update (PR #144635)

2025-06-17 Thread Amit Tiwari via cfe-commits

https://github.com/amitamd7 converted_to_draft 
https://github.com/llvm/llvm-project/pull/144635
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [Clang][OpenMP] Non-contiguous strided update (PR #144635)

2025-06-23 Thread Amit Tiwari via cfe-commits


@@ -7384,7 +7384,40 @@ class MappableExprsHandler {
 // dimension.
 uint64_t DimSize = 1;
 
-bool IsNonContiguous = CombinedInfo.NonContigInfo.IsNonContiguous;
+// Detects non-contiguous updates due to strided accesses.
+// Sets the 'IsNonContiguous' flag so that the 'MapType' bits are set
+// correctly when generating information to be passed to the runtime. The
+// flag is set to true if any array section has a stride not equal to 1, or
+// if the stride is not a constant expression (conservatively assumed
+// non-contiguous).
+bool IsNonContiguous = false;
+for (const auto &Component : Components) {
+  const auto *OASE =
+  dyn_cast(Component.getAssociatedExpression());
+  if (OASE) {
+const Expr *StrideExpr = OASE->getStride();
+if (StrideExpr) {
+  // Check if the stride is a constant integer expression
+  if (StrideExpr->isIntegerConstantExpr(CGF.getContext())) {

amitamd7 wrote:

Yes, because `stride` can be a variable/complex expression that is determined 
only at runtime, so conservatively treating it as non-contiguous. 

https://github.com/llvm/llvm-project/pull/144635
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [Clang][OpenMP] Non-contiguous strided update (PR #144635)

2025-06-23 Thread Amit Tiwari via cfe-commits


@@ -7384,7 +7384,40 @@ class MappableExprsHandler {
 // dimension.
 uint64_t DimSize = 1;
 
-bool IsNonContiguous = CombinedInfo.NonContigInfo.IsNonContiguous;
+// Detects non-contiguous updates due to strided accesses.
+// Sets the 'IsNonContiguous' flag so that the 'MapType' bits are set
+// correctly when generating information to be passed to the runtime. The
+// flag is set to true if any array section has a stride not equal to 1, or
+// if the stride is not a constant expression (conservatively assumed
+// non-contiguous).
+bool IsNonContiguous = false;
+for (const auto &Component : Components) {
+  const auto *OASE =
+  dyn_cast(Component.getAssociatedExpression());
+  if (OASE) {
+const Expr *StrideExpr = OASE->getStride();
+if (StrideExpr) {
+  // Check if the stride is a constant integer expression
+  if (StrideExpr->isIntegerConstantExpr(CGF.getContext())) {

amitamd7 wrote:

Okay, got it. No, it does not implicitly check if it is an integer. 

https://github.com/llvm/llvm-project/pull/144635
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [Clang][OpenMP] Non-contiguous strided update (PR #144635)

2025-06-26 Thread Amit Tiwari via cfe-commits

https://github.com/amitamd7 updated 
https://github.com/llvm/llvm-project/pull/144635

>From 1383c0e58feff9aabbffab23dc705c497baa0f2d Mon Sep 17 00:00:00 2001
From: amtiwari 
Date: Mon, 16 Jun 2025 01:07:01 -0400
Subject: [PATCH] strided_update_offloading with lit-tests added

---
 clang/lib/CodeGen/CGOpenMPRuntime.cpp | 189 ++
 .../test/offloading/strided_multiple_update.c |  61 ++
 .../test/offloading/strided_partial_update.c  |  63 ++
 offload/test/offloading/strided_update.c  |  54 +
 4 files changed, 282 insertions(+), 85 deletions(-)
 create mode 100644 offload/test/offloading/strided_multiple_update.c
 create mode 100644 offload/test/offloading/strided_partial_update.c
 create mode 100644 offload/test/offloading/strided_update.c

diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp 
b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
index 8ccc37ef98a74..785eb5f6a869d 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -490,11 +490,11 @@ enum OpenMPLocationFlags : unsigned {
 ///  member  */
 ///kmp_int32 reserved_2;   /**<  not really used in Fortran any more;
 ///  see above */
-///#if USE_ITT_BUILD
+/// #if USE_ITT_BUILD
 ////*  but currently used for storing
 ///region-specific ITT */
 ////*  contextual information. */
-///#endif /* USE_ITT_BUILD */
+/// #endif /* USE_ITT_BUILD */
 ///kmp_int32 reserved_3;   /**< source[4] in Fortran, do not use for
 /// C++  */
 ///char const *psource;/**< String describing the source location.
@@ -714,16 +714,16 @@ static void EmitOMPAggregateInit(CodeGenFunction &CGF, 
Address DestAddr,
 
   if (DRD) {
 // Shift the address forward by one element.
-llvm::Value *SrcElementNext = CGF.Builder.CreateConstGEP1_32(
-SrcAddr.getElementType(), SrcElementPHI, /*Idx0=*/1,
-"omp.arraycpy.dest.element");
+llvm::Value *SrcElementNext =
+CGF.Builder.CreateConstGEP1_32(SrcAddr.getElementType(), SrcElementPHI,
+   /*Idx0=*/1, 
"omp.arraycpy.dest.element");
 SrcElementPHI->addIncoming(SrcElementNext, CGF.Builder.GetInsertBlock());
   }
 
   // Shift the address forward by one element.
-  llvm::Value *DestElementNext = CGF.Builder.CreateConstGEP1_32(
-  DestAddr.getElementType(), DestElementPHI, /*Idx0=*/1,
-  "omp.arraycpy.dest.element");
+  llvm::Value *DestElementNext =
+  CGF.Builder.CreateConstGEP1_32(DestAddr.getElementType(), DestElementPHI,
+ /*Idx0=*/1, "omp.arraycpy.dest.element");
   // Check whether we've reached the end.
   llvm::Value *Done =
   CGF.Builder.CreateICmpEQ(DestElementNext, DestEnd, "omp.arraycpy.done");
@@ -973,8 +973,8 @@ Address 
ReductionCodeGen::adjustPrivateAddress(CodeGenFunction &CGF, unsigned N,
 llvm::Value *PrivatePointer =
 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
 PrivateAddr.emitRawPointer(CGF), SharedAddr.getType());
-llvm::Value *Ptr = CGF.Builder.CreateGEP(
-SharedAddr.getElementType(), PrivatePointer, Adjustment);
+llvm::Value *Ptr = CGF.Builder.CreateGEP(SharedAddr.getElementType(),
+ PrivatePointer, Adjustment);
 return castToBase(CGF, OrigVD->getType(),
   SharedAddresses[N].first.getType(),
   OriginalBaseLValue.getAddress(), Ptr);
@@ -1599,12 +1599,11 @@ Address 
CGOpenMPRuntime::getAddrOfThreadPrivate(CodeGenFunction &CGF,
   CGF.Builder.CreatePointerCast(VDAddr.emitRawPointer(CGF), CGM.Int8PtrTy),
   CGM.getSize(CGM.GetTargetTypeStoreSize(VarTy)),
   getOrCreateThreadPrivateCache(VD)};
-  return Address(
-  CGF.EmitRuntimeCall(
-  OMPBuilder.getOrCreateRuntimeFunction(
-  CGM.getModule(), OMPRTL___kmpc_threadprivate_cached),
-  Args),
-  CGF.Int8Ty, VDAddr.getAlignment());
+  return Address(CGF.EmitRuntimeCall(
+ OMPBuilder.getOrCreateRuntimeFunction(
+ CGM.getModule(), OMPRTL___kmpc_threadprivate_cached),
+ Args),
+ CGF.Int8Ty, VDAddr.getAlignment());
 }
 
 void CGOpenMPRuntime::emitThreadPrivateVarInit(
@@ -1629,8 +1628,8 @@ void CGOpenMPRuntime::emitThreadPrivateVarInit(
 }
 
 llvm::Function *CGOpenMPRuntime::emitThreadPrivateVarDefinition(
-const VarDecl *VD, Address VDAddr, SourceLocation Loc,
-bool PerformInit, CodeGenFunction *CGF) {
+const VarDecl *VD, Address VDAddr, SourceLocation Loc, bool PerformInit,
+CodeGenFunction *CGF) {
   if (CGM.getLangOpts().OpenMPUseTLS &&
   CGM.getContext().getTargetInfo().isTLSSupported())
 return nullptr;
@@ -1692,7 +1691,8 @@ llvm::Function 
*CGOpenMPRuntime::emitThreadPrivateVarDefinition(
   auto NL =

[clang] [llvm] [Clang][OpenMP] Non-contiguous strided update (PR #144635)

2025-06-26 Thread Amit Tiwari via cfe-commits

amitamd7 wrote:

Please ignore the indentation changes. I'll fix them soon in the revised 
version along. 

https://github.com/llvm/llvm-project/pull/144635
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits