[PATCH] D90101: [Clang][OpenMP][WIP] Avoid unnecessary privatization of mapper array when there is no user defined mapper

2020-10-26 Thread Shilei Tian via Phabricator via cfe-commits
tianshilei1992 updated this revision to Diff 300738.
tianshilei1992 added a comment.

Fixed two test cases


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D90101/new/

https://reviews.llvm.org/D90101

Files:
  clang/lib/CodeGen/CGOpenMPRuntime.cpp
  clang/lib/CodeGen/CGStmtOpenMP.cpp
  clang/test/OpenMP/target_codegen.cpp
  clang/test/OpenMP/target_enter_data_depend_codegen.cpp
  clang/test/OpenMP/target_exit_data_depend_codegen.cpp
  clang/test/OpenMP/target_parallel_depend_codegen.cpp
  clang/test/OpenMP/target_parallel_for_codegen.cpp
  clang/test/OpenMP/target_parallel_for_depend_codegen.cpp
  clang/test/OpenMP/target_parallel_for_simd_depend_codegen.cpp
  clang/test/OpenMP/target_simd_depend_codegen.cpp
  clang/test/OpenMP/target_teams_codegen.cpp
  clang/test/OpenMP/target_teams_depend_codegen.cpp
  clang/test/OpenMP/target_teams_distribute_codegen.cpp
  clang/test/OpenMP/target_teams_distribute_depend_codegen.cpp
  clang/test/OpenMP/target_teams_distribute_parallel_for_depend_codegen.cpp
  clang/test/OpenMP/target_teams_distribute_parallel_for_simd_depend_codegen.cpp
  clang/test/OpenMP/target_teams_distribute_simd_codegen.cpp
  clang/test/OpenMP/target_teams_distribute_simd_depend_codegen.cpp
  clang/test/OpenMP/target_update_depend_codegen.cpp

Index: clang/test/OpenMP/target_update_depend_codegen.cpp
===
--- clang/test/OpenMP/target_update_depend_codegen.cpp
+++ clang/test/OpenMP/target_update_depend_codegen.cpp
@@ -64,7 +64,7 @@
   // CK1: store i32 [[DEVICE]], i32* [[CAP_DEVICE]],
   // CK1: [[DEV1:%.+]] = load i32, i32* %{{.+}}
   // CK1: [[DEV2:%.+]] = sext i32 [[DEV1]] to i64
-  // CK1: [[RES:%.+]] = call i8* @__kmpc_omp_target_task_alloc(%struct.ident_t* {{.+}}, i32 {{.+}}, i32 1, i[[sz]] {{72|40}}, i[[sz]] 4, i32 (i32, i8*)* bitcast (i32 (i32, %struct.kmp_task_t_with_privates*)* [[TASK_ENTRY0:@.+]] to i32 (i32, i8*)*), i64 [[DEV2]])
+  // CK1: [[RES:%.+]] = call i8* @__kmpc_omp_target_task_alloc(%struct.ident_t* {{.+}}, i32 {{.+}}, i32 1, i[[sz]] {{64|36}}, i[[sz]] 4, i32 (i32, i8*)* bitcast (i32 (i32, %struct.kmp_task_t_with_privates*)* [[TASK_ENTRY0:@.+]] to i32 (i32, i8*)*), i64 [[DEV2]])
   // CK1: [[BC:%.+]] = bitcast i8* [[RES]] to %struct.kmp_task_t_with_privates*
   // CK1: [[TASK_T:%.+]] = getelementptr inbounds %struct.kmp_task_t_with_privates, %struct.kmp_task_t_with_privates* [[BC]], i32 0, i32 0
   // CK1: [[SHAREDS:%.+]] = getelementptr inbounds %struct.kmp_task_t, %struct.kmp_task_t* [[TASK_T]], i32 0, i32 0
@@ -130,7 +130,7 @@
   // CK1: [[IF_BOOL:%.+]] = trunc i8 [[IF]] to i1
   // CK1: [[IF:%.+]] = zext i1 [[IF_BOOL]] to i8
   // CK1: store i8 [[IF]], i8* [[IF_DEVICE]],
-  // CK1: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%struct.ident_t* {{.+}}, i32 {{.+}}, i32 1, i[[sz]] {{72|40}}, i[[sz]] 1, i32 (i32, i8*)* bitcast (i32 (i32, %struct.kmp_task_t_with_privates{{.+}}*)* [[TASK_ENTRY2:@.+]] to i32 (i32, i8*)*))
+  // CK1: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%struct.ident_t* {{.+}}, i32 {{.+}}, i32 1, i[[sz]] {{64|36}}, i[[sz]] 1, i32 (i32, i8*)* bitcast (i32 (i32, %struct.kmp_task_t_with_privates{{.+}}*)* [[TASK_ENTRY2:@.+]] to i32 (i32, i8*)*))
   // CK1: [[RES_BC:%.+]] = bitcast i8* [[RES]] to %struct.kmp_task_t_with_privates{{.+}}*
   // CK1: [[TASK_T:%.+]] = getelementptr inbounds %struct.kmp_task_t_with_privates{{.+}}, %struct.kmp_task_t_with_privates{{.+}}* [[RES_BC]], i32 0, i32 0
   // CK1: [[SHAREDS:%.+]] = getelementptr inbounds %struct.kmp_task_t, %struct.kmp_task_t* [[TASK_T]], i32 0, i32 0
@@ -213,7 +213,7 @@
   // CK1: [[GEPBP0:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[BP]], i32 0, i32 0
   // CK1: [[GEPP0:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[P]], i32 0, i32 0
   // CK1: [[GEPS0:%.+]] = getelementptr inbounds [1 x i64], [1 x i64]* [[S]], i32 0, i32 0
-  // CK1: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%struct.ident_t* {{.+}}, i32 {{.+}}, i32 1, i[[sz]] {{72|40}}, i[[sz]] 1, i32 (i32, i8*)* bitcast (i32 (i32, %struct.kmp_task_t_with_privates{{.+}}*)* [[TASK_ENTRY3:@.+]] to i32 (i32, i8*)*))
+  // CK1: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%struct.ident_t* {{.+}}, i32 {{.+}}, i32 1, i[[sz]] {{64|36}}, i[[sz]] 1, i32 (i32, i8*)* bitcast (i32 (i32, %struct.kmp_task_t_with_privates{{.+}}*)* [[TASK_ENTRY3:@.+]] to i32 (i32, i8*)*))
   // CK1: [[RES_BC:%.+]] = bitcast i8* [[RES]] to %struct.kmp_task_t_with_privates{{.+}}*
   // CK1: [[TASK_T:%.+]] = getelementptr inbounds %struct.kmp_task_t_with_privates{{.+}}, %struct.kmp_task_t_with_privates{{.+}}* [[RES_BC]], i32 0, i32 0
   // CK1: [[PRIVS:%.+]] = getelementptr inbounds %struct.kmp_task_t_with_privates{{.+}}, %struct.kmp_task_t_with_privates{{.+}}* [[RES_BC]], i32 0, i32 1
@@ -298,7 +298,7 @@
   // CK1: store double* %{{.+}}, double** [[P1_BC]],
   // CK1: [[GEPBP0:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP]], i32 0, i32 0
   // 

[PATCH] D90101: [Clang][OpenMP][WIP] Avoid unnecessary privatization of mapper array when there is no user defined mapper

2020-10-25 Thread Johannes Doerfert via Phabricator via cfe-commits
jdoerfert accepted this revision.
jdoerfert added a comment.
This revision is now accepted and ready to land.

4 tests seem to fail still, otherwise this LGTM.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D90101/new/

https://reviews.llvm.org/D90101

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


[PATCH] D90101: [Clang][OpenMP][WIP] Avoid unnecessary privatization of mapper array when there is no user defined mapper

2020-10-24 Thread Shilei Tian via Phabricator via cfe-commits
tianshilei1992 updated this revision to Diff 300517.
tianshilei1992 added a comment.

Fixed some test cases


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D90101/new/

https://reviews.llvm.org/D90101

Files:
  clang/lib/CodeGen/CGOpenMPRuntime.cpp
  clang/lib/CodeGen/CGStmtOpenMP.cpp
  clang/test/OpenMP/target_codegen.cpp
  clang/test/OpenMP/target_enter_data_depend_codegen.cpp
  clang/test/OpenMP/target_exit_data_depend_codegen.cpp
  clang/test/OpenMP/target_parallel_depend_codegen.cpp
  clang/test/OpenMP/target_parallel_for_codegen.cpp
  clang/test/OpenMP/target_parallel_for_depend_codegen.cpp
  clang/test/OpenMP/target_parallel_for_simd_depend_codegen.cpp
  clang/test/OpenMP/target_simd_depend_codegen.cpp
  clang/test/OpenMP/target_teams_codegen.cpp
  clang/test/OpenMP/target_teams_depend_codegen.cpp
  clang/test/OpenMP/target_teams_distribute_codegen.cpp
  clang/test/OpenMP/target_teams_distribute_depend_codegen.cpp
  clang/test/OpenMP/target_teams_distribute_parallel_for_depend_codegen.cpp
  clang/test/OpenMP/target_teams_distribute_parallel_for_simd_depend_codegen.cpp
  clang/test/OpenMP/target_teams_distribute_simd_codegen.cpp
  clang/test/OpenMP/target_teams_distribute_simd_depend_codegen.cpp
  clang/test/OpenMP/target_update_depend_codegen.cpp

Index: clang/test/OpenMP/target_update_depend_codegen.cpp
===
--- clang/test/OpenMP/target_update_depend_codegen.cpp
+++ clang/test/OpenMP/target_update_depend_codegen.cpp
@@ -64,7 +64,7 @@
   // CK1: store i32 [[DEVICE]], i32* [[CAP_DEVICE]],
   // CK1: [[DEV1:%.+]] = load i32, i32* %{{.+}}
   // CK1: [[DEV2:%.+]] = sext i32 [[DEV1]] to i64
-  // CK1: [[RES:%.+]] = call i8* @__kmpc_omp_target_task_alloc(%struct.ident_t* {{.+}}, i32 {{.+}}, i32 1, i[[sz]] {{72|40}}, i[[sz]] 4, i32 (i32, i8*)* bitcast (i32 (i32, %struct.kmp_task_t_with_privates*)* [[TASK_ENTRY0:@.+]] to i32 (i32, i8*)*), i64 [[DEV2]])
+  // CK1: [[RES:%.+]] = call i8* @__kmpc_omp_target_task_alloc(%struct.ident_t* {{.+}}, i32 {{.+}}, i32 1, i[[sz]] {{64|36}}, i[[sz]] 4, i32 (i32, i8*)* bitcast (i32 (i32, %struct.kmp_task_t_with_privates*)* [[TASK_ENTRY0:@.+]] to i32 (i32, i8*)*), i64 [[DEV2]])
   // CK1: [[BC:%.+]] = bitcast i8* [[RES]] to %struct.kmp_task_t_with_privates*
   // CK1: [[TASK_T:%.+]] = getelementptr inbounds %struct.kmp_task_t_with_privates, %struct.kmp_task_t_with_privates* [[BC]], i32 0, i32 0
   // CK1: [[SHAREDS:%.+]] = getelementptr inbounds %struct.kmp_task_t, %struct.kmp_task_t* [[TASK_T]], i32 0, i32 0
@@ -130,7 +130,7 @@
   // CK1: [[IF_BOOL:%.+]] = trunc i8 [[IF]] to i1
   // CK1: [[IF:%.+]] = zext i1 [[IF_BOOL]] to i8
   // CK1: store i8 [[IF]], i8* [[IF_DEVICE]],
-  // CK1: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%struct.ident_t* {{.+}}, i32 {{.+}}, i32 1, i[[sz]] {{72|40}}, i[[sz]] 1, i32 (i32, i8*)* bitcast (i32 (i32, %struct.kmp_task_t_with_privates{{.+}}*)* [[TASK_ENTRY2:@.+]] to i32 (i32, i8*)*))
+  // CK1: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%struct.ident_t* {{.+}}, i32 {{.+}}, i32 1, i[[sz]] {{64|36}}, i[[sz]] 1, i32 (i32, i8*)* bitcast (i32 (i32, %struct.kmp_task_t_with_privates{{.+}}*)* [[TASK_ENTRY2:@.+]] to i32 (i32, i8*)*))
   // CK1: [[RES_BC:%.+]] = bitcast i8* [[RES]] to %struct.kmp_task_t_with_privates{{.+}}*
   // CK1: [[TASK_T:%.+]] = getelementptr inbounds %struct.kmp_task_t_with_privates{{.+}}, %struct.kmp_task_t_with_privates{{.+}}* [[RES_BC]], i32 0, i32 0
   // CK1: [[SHAREDS:%.+]] = getelementptr inbounds %struct.kmp_task_t, %struct.kmp_task_t* [[TASK_T]], i32 0, i32 0
@@ -213,7 +213,7 @@
   // CK1: [[GEPBP0:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[BP]], i32 0, i32 0
   // CK1: [[GEPP0:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[P]], i32 0, i32 0
   // CK1: [[GEPS0:%.+]] = getelementptr inbounds [1 x i64], [1 x i64]* [[S]], i32 0, i32 0
-  // CK1: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%struct.ident_t* {{.+}}, i32 {{.+}}, i32 1, i[[sz]] {{72|40}}, i[[sz]] 1, i32 (i32, i8*)* bitcast (i32 (i32, %struct.kmp_task_t_with_privates{{.+}}*)* [[TASK_ENTRY3:@.+]] to i32 (i32, i8*)*))
+  // CK1: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%struct.ident_t* {{.+}}, i32 {{.+}}, i32 1, i[[sz]] {{64|36}}, i[[sz]] 1, i32 (i32, i8*)* bitcast (i32 (i32, %struct.kmp_task_t_with_privates{{.+}}*)* [[TASK_ENTRY3:@.+]] to i32 (i32, i8*)*))
   // CK1: [[RES_BC:%.+]] = bitcast i8* [[RES]] to %struct.kmp_task_t_with_privates{{.+}}*
   // CK1: [[TASK_T:%.+]] = getelementptr inbounds %struct.kmp_task_t_with_privates{{.+}}, %struct.kmp_task_t_with_privates{{.+}}* [[RES_BC]], i32 0, i32 0
   // CK1: [[PRIVS:%.+]] = getelementptr inbounds %struct.kmp_task_t_with_privates{{.+}}, %struct.kmp_task_t_with_privates{{.+}}* [[RES_BC]], i32 0, i32 1
@@ -298,7 +298,7 @@
   // CK1: store double* %{{.+}}, double** [[P1_BC]],
   // CK1: [[GEPBP0:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP]], i32 0, i32 0
   // 

[PATCH] D90101: [Clang][OpenMP][WIP] Avoid unnecessary privatization of mapper array when there is no user defined mapper

2020-10-24 Thread Shilei Tian via Phabricator via cfe-commits
tianshilei1992 updated this revision to Diff 300509.
tianshilei1992 added a comment.

Fixed an issue that caused compiler crash


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D90101/new/

https://reviews.llvm.org/D90101

Files:
  clang/lib/CodeGen/CGOpenMPRuntime.cpp
  clang/lib/CodeGen/CGStmtOpenMP.cpp

Index: clang/lib/CodeGen/CGStmtOpenMP.cpp
===
--- clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -4210,16 +4210,21 @@
 /*IndexTypeQuals=*/0);
 SVD = createImplicitFirstprivateForType(getContext(), Data, SizesType, CD,
 S.getBeginLoc());
-MVD = createImplicitFirstprivateForType(
-getContext(), Data, BaseAndPointerAndMapperType, CD, S.getBeginLoc());
 TargetScope.addPrivate(
 BPVD, []() { return InputInfo.BasePointersArray; });
 TargetScope.addPrivate(PVD,
[]() { return InputInfo.PointersArray; });
 TargetScope.addPrivate(SVD,
[]() { return InputInfo.SizesArray; });
-TargetScope.addPrivate(MVD,
-   []() { return InputInfo.MappersArray; });
+// If there is no user-defined mapper, the mapper array will be nullptr. In
+// this case, we don't need to privatize it.
+if (!dyn_cast_or_null(
+InputInfo.MappersArray.getPointer())) {
+  MVD = createImplicitFirstprivateForType(
+  getContext(), Data, BaseAndPointerAndMapperType, CD, S.getBeginLoc());
+  TargetScope.addPrivate(MVD,
+ []() { return InputInfo.MappersArray; });
+}
   }
   (void)TargetScope.Privatize();
   // Build list of dependences.
@@ -4269,8 +4274,10 @@
   CGF.GetAddrOfLocalVar(PVD), /*Index=*/0);
   InputInfo.SizesArray = CGF.Builder.CreateConstArrayGEP(
   CGF.GetAddrOfLocalVar(SVD), /*Index=*/0);
-  InputInfo.MappersArray = CGF.Builder.CreateConstArrayGEP(
-  CGF.GetAddrOfLocalVar(MVD), /*Index=*/0);
+  // If MVD is nullptr, the mapper array is not privatized
+  if (MVD)
+InputInfo.MappersArray = CGF.Builder.CreateConstArrayGEP(
+CGF.GetAddrOfLocalVar(MVD), /*Index=*/0);
 }
 
 Action.Enter(CGF);
Index: clang/lib/CodeGen/CGOpenMPRuntime.cpp
===
--- clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -8870,10 +8870,8 @@
 /// Additional arguments for emitOffloadingArraysArgument function.
 struct ArgumentsOptions {
   bool ForEndCall = false;
-  bool IsTask = false;
   ArgumentsOptions() = default;
-  ArgumentsOptions(bool ForEndCall, bool IsTask)
-  : ForEndCall(ForEndCall), IsTask(IsTask) {}
+  ArgumentsOptions(bool ForEndCall) : ForEndCall(ForEndCall) {}
 };
 } // namespace
 
@@ -8909,9 +8907,9 @@
 : Info.MapTypesArray,
 /*Idx0=*/0,
 /*Idx1=*/0);
-// Always emit the mapper array address in case of a target task for
-// privatization.
-if (!Options.IsTask && !Info.HasMapper)
+// If there is no user-defined mapper, set the mapper array to nullptr to
+// avoid an unnecessary data privatization
+if (!Info.HasMapper)
   MappersArrayArg = llvm::ConstantPointerNull::get(CGM.VoidPtrPtrTy);
 else
   MappersArrayArg =
@@ -9664,11 +9662,9 @@
 TargetDataInfo Info;
 // Fill up the arrays and create the arguments.
 emitOffloadingArrays(CGF, CombinedInfo, Info);
-bool HasDependClauses = D.hasClausesOfKind();
-emitOffloadingArraysArgument(CGF, Info.BasePointersArray,
- Info.PointersArray, Info.SizesArray,
- Info.MapTypesArray, Info.MappersArray, Info,
- {/*ForEndTask=*/false, HasDependClauses});
+emitOffloadingArraysArgument(
+CGF, Info.BasePointersArray, Info.PointersArray, Info.SizesArray,
+Info.MapTypesArray, Info.MappersArray, Info, {/*ForEndTask=*/false});
 InputInfo.NumberOfTargetItems = Info.NumberOfPtrs;
 InputInfo.BasePointersArray =
 Address(Info.BasePointersArray, CGM.getPointerAlign());
@@ -10319,8 +10315,7 @@
 llvm::Value *MappersArrayArg = nullptr;
 emitOffloadingArraysArgument(CGF, BasePointersArrayArg, PointersArrayArg,
  SizesArrayArg, MapTypesArrayArg,
- MappersArrayArg, Info,
- {/*ForEndCall=*/true, /*IsTask=*/false});
+ MappersArrayArg, Info, {/*ForEndCall=*/true});
 
 // Emit device ID if any.
 llvm::Value *DeviceID = nullptr;
@@ -10519,10 +10514,9 @@
 // Fill up the arrays and create the arguments.
 emitOffloadingArrays(CGF, CombinedInfo, Info);
 bool HasDependClauses = D.hasClausesOfKind();
-

[PATCH] D90101: [Clang][OpenMP][WIP] Avoid unnecessary privatization of mapper array when there is no user defined mapper

2020-10-24 Thread Shilei Tian via Phabricator via cfe-commits
tianshilei1992 created this revision.
Herald added subscribers: cfe-commits, guansong, yaxunl.
Herald added a project: clang.
tianshilei1992 requested review of this revision.
Herald added a reviewer: jdoerfert.
Herald added a subscriber: sstefan1.

In current implementation, if it requires an outer task, the mapper array will 
be privatized no matter whether it has mapper. In fact, when there is no 
mapper, the mapper array only contains number of nullptr. In the libomptarget, 
the use of mapper array is `if (mappers_array && mappers_array[i])`, which 
means we can directly set mapper array to nullptr if there is no mapper. This 
can avoid unnecessary data copy.

In this patch, the data privatization will not be emitted if the mapper array 
is nullptr. When it comes to the emit of task body, the nullptr will be used 
directly.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D90101

Files:
  clang/lib/CodeGen/CGOpenMPRuntime.cpp
  clang/lib/CodeGen/CGStmtOpenMP.cpp

Index: clang/lib/CodeGen/CGStmtOpenMP.cpp
===
--- clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -4210,16 +4210,21 @@
 /*IndexTypeQuals=*/0);
 SVD = createImplicitFirstprivateForType(getContext(), Data, SizesType, CD,
 S.getBeginLoc());
-MVD = createImplicitFirstprivateForType(
-getContext(), Data, BaseAndPointerAndMapperType, CD, S.getBeginLoc());
 TargetScope.addPrivate(
 BPVD, []() { return InputInfo.BasePointersArray; });
 TargetScope.addPrivate(PVD,
[]() { return InputInfo.PointersArray; });
 TargetScope.addPrivate(SVD,
[]() { return InputInfo.SizesArray; });
-TargetScope.addPrivate(MVD,
-   []() { return InputInfo.MappersArray; });
+// If there is no user-defined mapper, the mapper array will be nullptr. In
+// this case, we don't need to privatize it.
+if (!dyn_cast_or_null(
+InputInfo.MappersArray.getPointer())) {
+  MVD = createImplicitFirstprivateForType(
+  getContext(), Data, BaseAndPointerAndMapperType, CD, S.getBeginLoc());
+  TargetScope.addPrivate(MVD,
+ []() { return InputInfo.MappersArray; });
+}
   }
   (void)TargetScope.Privatize();
   // Build list of dependences.
@@ -4269,8 +4274,10 @@
   CGF.GetAddrOfLocalVar(PVD), /*Index=*/0);
   InputInfo.SizesArray = CGF.Builder.CreateConstArrayGEP(
   CGF.GetAddrOfLocalVar(SVD), /*Index=*/0);
-  InputInfo.MappersArray = CGF.Builder.CreateConstArrayGEP(
-  CGF.GetAddrOfLocalVar(MVD), /*Index=*/0);
+  // If MVD is nullptr, the mapper array is not privatized
+  if (!MVD)
+InputInfo.MappersArray = CGF.Builder.CreateConstArrayGEP(
+CGF.GetAddrOfLocalVar(MVD), /*Index=*/0);
 }
 
 Action.Enter(CGF);
Index: clang/lib/CodeGen/CGOpenMPRuntime.cpp
===
--- clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -8870,10 +8870,8 @@
 /// Additional arguments for emitOffloadingArraysArgument function.
 struct ArgumentsOptions {
   bool ForEndCall = false;
-  bool IsTask = false;
   ArgumentsOptions() = default;
-  ArgumentsOptions(bool ForEndCall, bool IsTask)
-  : ForEndCall(ForEndCall), IsTask(IsTask) {}
+  ArgumentsOptions(bool ForEndCall) : ForEndCall(ForEndCall) {}
 };
 } // namespace
 
@@ -8909,9 +8907,9 @@
 : Info.MapTypesArray,
 /*Idx0=*/0,
 /*Idx1=*/0);
-// Always emit the mapper array address in case of a target task for
-// privatization.
-if (!Options.IsTask && !Info.HasMapper)
+// If there is no user-defined mapper, set the mapper array to nullptr to
+// avoid an unnecessary data privatization
+if (!Info.HasMapper)
   MappersArrayArg = llvm::ConstantPointerNull::get(CGM.VoidPtrPtrTy);
 else
   MappersArrayArg =
@@ -9664,11 +9662,9 @@
 TargetDataInfo Info;
 // Fill up the arrays and create the arguments.
 emitOffloadingArrays(CGF, CombinedInfo, Info);
-bool HasDependClauses = D.hasClausesOfKind();
-emitOffloadingArraysArgument(CGF, Info.BasePointersArray,
- Info.PointersArray, Info.SizesArray,
- Info.MapTypesArray, Info.MappersArray, Info,
- {/*ForEndTask=*/false, HasDependClauses});
+emitOffloadingArraysArgument(
+CGF, Info.BasePointersArray, Info.PointersArray, Info.SizesArray,
+Info.MapTypesArray, Info.MappersArray, Info, {/*ForEndTask=*/false});
 InputInfo.NumberOfTargetItems = Info.NumberOfPtrs;
 InputInfo.BasePointersArray =
 Address(Info.BasePointersArray, CGM.getPointerAlign());
@@ -10319,8 +10315,7 @@