]> granicus.if.org Git - clang/commitdiff
[OPENMP] Fix PR34927: Emit initializer for reduction array with declare
authorAlexey Bataev <a.bataev@hotmail.com>
Thu, 12 Oct 2017 20:03:39 +0000 (20:03 +0000)
committerAlexey Bataev <a.bataev@hotmail.com>
Thu, 12 Oct 2017 20:03:39 +0000 (20:03 +0000)
reduction.

If the reduction is an array or an array section and reduction operation
is declare reduction without initializer, it may lead to crash.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@315611 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGOpenMPRuntime.cpp
test/OpenMP/declare_reduction_codegen.cpp

index 3ca92531b9c3198134bd4f9d4101b7be4bfc56fc..f98ff85565faa5301ab8d40a871a227c516ee86e 100644 (file)
@@ -786,7 +786,8 @@ static void emitInitWithReductionInitializer(CodeGenFunction &CGF,
 /// \param Init Initial expression of array.
 /// \param SrcAddr Address of the original array.
 static void EmitOMPAggregateInit(CodeGenFunction &CGF, Address DestAddr,
-                                 QualType Type, const Expr *Init,
+                                 QualType Type, bool EmitDeclareReductionInit,
+                                 const Expr *Init,
                                  const OMPDeclareReductionDecl *DRD,
                                  Address SrcAddr = Address::invalid()) {
   // Perform element-by-element initialization.
@@ -840,7 +841,7 @@ static void EmitOMPAggregateInit(CodeGenFunction &CGF, Address DestAddr,
   // Emit copy.
   {
     CodeGenFunction::RunCleanupsScope InitScope(CGF);
-    if (DRD && (DRD->getInitializer() || !Init)) {
+    if (EmitDeclareReductionInit) {
       emitInitWithReductionInitializer(CGF, DRD, Init, DestElementCurrent,
                                        SrcElementCurrent, ElementTy);
     } else
@@ -887,8 +888,12 @@ void ReductionCodeGen::emitAggregateInitialization(
   // captured region.
   auto *PrivateVD =
       cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());
+  bool EmitDeclareReductionInit =
+      DRD && (DRD->getInitializer() || !PrivateVD->hasInit());
   EmitOMPAggregateInit(CGF, PrivateAddr, PrivateVD->getType(),
-                       DRD ? ClausesData[N].ReductionOp : PrivateVD->getInit(),
+                       EmitDeclareReductionInit,
+                       EmitDeclareReductionInit ? ClausesData[N].ReductionOp
+                                                : PrivateVD->getInit(),
                        DRD, SharedLVal.getAddress());
 }
 
index daa1fe8aaf5cbdf62e37918ac216340a8cb712a0..ae6e047d94836f954492cf424f63f6b183418037 100644 (file)
@@ -9,6 +9,26 @@
 // CHECK: [[SSS_INT:.+]] = type { i32 }
 // CHECK-LOAD: [[SSS_INT:.+]] = type { i32 }
 
+// CHECK: add
+void add(short &out, short &in) {}
+
+#pragma omp declare reduction(my_add : short : add(omp_out, omp_in))
+
+// CHECK: define internal void @.
+// CHECK: call void @{{.+}}add{{.+}}(
+// CHECK: ret void
+
+// CHECK: foo_reduction_array
+void foo_reduction_array() {
+  short y[1];
+  // CHECK: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(
+#pragma omp parallel for reduction(my_add : y)
+  for (int i = 0; i < 1; i++) {
+  }
+}
+
+// CHECK: define internal void @
+
 #pragma omp declare reduction(+ : int, char : omp_out *= omp_in)
 // CHECK: define internal {{.*}}void @{{[^(]+}}(i32* noalias, i32* noalias)
 // CHECK: [[MUL:%.+]] = mul nsw i32