[clang] 1696b8a - [OPENMP]Fix PR48740: OpenMP declare reduction in C does not require an initializer

Alexey Bataev via cfe-commits cfe-commits at lists.llvm.org
Tue Mar 30 05:38:58 PDT 2021


Author: Alexey Bataev
Date: 2021-03-30T05:38:20-07:00
New Revision: 1696b8ae96b2d8bcbf90894bd344a8a090f43c84

URL: https://github.com/llvm/llvm-project/commit/1696b8ae96b2d8bcbf90894bd344a8a090f43c84
DIFF: https://github.com/llvm/llvm-project/commit/1696b8ae96b2d8bcbf90894bd344a8a090f43c84.diff

LOG: [OPENMP]Fix PR48740: OpenMP declare reduction in C does not require an initializer

If no initializer-clause is specified, the private variables will be
initialized following the rules for initialization of objects with static
storage duration.

Need to adjust the implementation to the current version of the
standard.

Differential Revision: https://reviews.llvm.org/D99539

Added: 
    

Modified: 
    clang/lib/CodeGen/CGOpenMPRuntime.cpp
    clang/lib/Sema/SemaOpenMP.cpp
    clang/test/OpenMP/declare_reduction_ast_print.c
    clang/test/OpenMP/declare_reduction_codegen.c
    clang/test/OpenMP/declare_reduction_messages.c

Removed: 
    


################################################################################
diff  --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
index 95859e6e94a7..4ec216a42188 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -655,9 +655,13 @@ static void emitInitWithReductionInitializer(CodeGenFunction &CGF,
       InitRVal =
           RValue::getComplex(CGF.EmitLoadOfComplex(LV, DRD->getLocation()));
       break;
-    case TEK_Aggregate:
-      InitRVal = RValue::getAggregate(LV.getAddress(CGF));
-      break;
+    case TEK_Aggregate: {
+      OpaqueValueExpr OVE(DRD->getLocation(), Ty, VK_LValue);
+      CodeGenFunction::OpaqueValueMapping OpaqueMap(CGF, &OVE, LV);
+      CGF.EmitAnyExprToMem(&OVE, Private, Ty.getQualifiers(),
+                           /*IsInitializer=*/false);
+      return;
+    }
     }
     OpaqueValueExpr OVE(DRD->getLocation(), Ty, VK_RValue);
     CodeGenFunction::OpaqueValueMapping OpaqueMap(CGF, &OVE, InitRVal);

diff  --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 54c824c4a759..fcb95e3a8442 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -16567,8 +16567,7 @@ static bool actOnOMPReductionKindClause(
     }
     if (RHSVD->isInvalidDecl())
       continue;
-    if (!RHSVD->hasInit() &&
-        (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) {
+    if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) {
       S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
           << Type << ReductionIdRange;
       bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==

diff  --git a/clang/test/OpenMP/declare_reduction_ast_print.c b/clang/test/OpenMP/declare_reduction_ast_print.c
index 37b722e5f8ca..a421886dd3fe 100644
--- a/clang/test/OpenMP/declare_reduction_ast_print.c
+++ b/clang/test/OpenMP/declare_reduction_ast_print.c
@@ -47,13 +47,18 @@ int main() {
                               : omp_out = omp_out > omp_in ? omp_in : omp_out) \
     initializer(omp_priv = 2147483647)
 
+#pragma omp declare reduction(mymin        \
+                              : struct SSS \
+                              : omp_out = omp_out.field > omp_in.field ? omp_in : omp_out)
+
 int foo(int argc, char **argv) {
   int x;
-#pragma omp parallel for reduction(mymin : x)
+  struct SSS ss;
+#pragma omp parallel for reduction(mymin : x, ss)
   for (int i = 0; i < 1000; i++)
     ;
   return 0;
 }
 
-// CHECK: #pragma omp parallel for reduction(mymin: x)
+// CHECK: #pragma omp parallel for reduction(mymin: x,ss)
 #endif

diff  --git a/clang/test/OpenMP/declare_reduction_codegen.c b/clang/test/OpenMP/declare_reduction_codegen.c
index f5695ffaac34..c5b5d1dfa5a4 100644
--- a/clang/test/OpenMP/declare_reduction_codegen.c
+++ b/clang/test/OpenMP/declare_reduction_codegen.c
@@ -17,6 +17,9 @@
 // CHECK: [[SSS_INT:.+]] = type { i32 }
 // CHECK-LOAD: [[SSS_INT:.+]] = type { i32 }
 
+// CHECK-DAG: [[SSS_INIT:@.+]] = private constant %struct.SSS zeroinitializer
+// CHECK-DAG: [[INT_INIT:@.+]] = private constant i32 0
+
 #pragma omp declare reduction(+ : int, char : omp_out *= omp_in)
 // CHECK: define internal {{.*}}void @{{[^(]+}}(i32* noalias %0, i32* noalias %1)
 // CHECK: [[MUL:%.+]] = mul nsw i32
@@ -163,4 +166,27 @@ int main() {
 // OMP45-LOAD-NEXT: store i8 [[TRUNC]], i8*
 // OMP45-LOAD-NEXT: ret void
 // OMP45-LOAD-NEXT: }
+
+// CHECK-LABEL: bar
+struct SSS ss;
+int in;
+void bar() {
+  // CHECK: [[SS_PRIV:%.+]] = alloca %struct.SSS,
+  // CHECK: [[IN_PRIV:%.+]] = alloca i32,
+  // CHECK: [[BC:%.+]] = bitcast %struct.SSS* [[SS_PRIV]] to i8*
+  // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[BC]], i8* align 4 bitcast (%struct.SSS* [[SSS_INIT]] to i8*), i64 4, i1 false)
+  // CHECK: [[IN_VAL:%.+]] = load i32, i32* [[INT_INIT]],
+  // CHECK: store i32 [[IN_VAL]], i32* [[IN_PRIV]],
+  // CHECK: call void @__kmpc_for_static_init_4(
+#pragma omp declare reduction(+            \
+                              : struct SSS \
+                              : omp_out = omp_in)
+#pragma omp declare reduction(+     \
+                              : int \
+                              : omp_out = omp_in)
+#pragma omp for reduction(+ \
+                          : ss, in)
+  for (int i = 0; i < 10; ++i)
+    ;
+}
 #endif

diff  --git a/clang/test/OpenMP/declare_reduction_messages.c b/clang/test/OpenMP/declare_reduction_messages.c
index 69b73f4c72b5..411a1c0f1820 100644
--- a/clang/test/OpenMP/declare_reduction_messages.c
+++ b/clang/test/OpenMP/declare_reduction_messages.c
@@ -49,9 +49,9 @@ struct S {
 #pragma omp declare reduction(|: struct S: omp_out.s += omp_in.s) initializer(omp_priv = { 0 })
 
 int fun(int arg) {
-  struct S s;// expected-note {{'s' defined here}}
+  struct S s;
   s.s = 0;
-#pragma omp parallel for reduction(+ : s) // expected-error {{list item of type 'struct S' is not valid for specified reduction operation: unable to provide default initialization value}}
+#pragma omp parallel for reduction(+ : s)
   for (arg = 0; arg < 10; ++arg)
     s.s += arg;
 #pragma omp declare reduction(red : int : omp_out++)


        


More information about the cfe-commits mailing list