Skip to content

[flang][OpenMP] Delayed privatization for variables with equivalence association #100531

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

Merged
merged 3 commits into from
Aug 1, 2024

Conversation

ergawy
Copy link
Member

@ergawy ergawy commented Jul 25, 2024

Handles variables that are storage associated via equivalence. The problem is that these variables are declared as fir.ptrs while their privatized storage is declared as fir.ref which was triggering a validation error in the OpenMP dialect.

@llvmbot
Copy link
Member

llvmbot commented Jul 25, 2024

@llvm/pr-subscribers-flang-fir-hlfir
@llvm/pr-subscribers-mlir
@llvm/pr-subscribers-flang-openmp

@llvm/pr-subscribers-mlir-openmp

Author: Kareem Ergawy (ergawy)

Changes

… association

Handles variables that are storage associated via equivalence. The problem is that these variables are declared as fir.ptrs while their privatized storage is declared as fir.ref which was triggering a validation error in the OpenMP dialect. So far, I just disabled a small part of the validation logic until we find a way to properly check of compatible types without leaking the FIR dialect specifics in the OpenMP dialect validation logic.


Full diff: https://github.com/llvm/llvm-project/pull/100531.diff

5 Files Affected:

  • (modified) flang/lib/Lower/OpenMP/DataSharingProcessor.cpp (+4-2)
  • (added) flang/test/Lower/OpenMP/DelayedPrivatization/equivalence.f90 (+36)
  • (modified) mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp (+5-1)
  • (modified) mlir/test/Dialect/OpenMP/invalid.mlir (+8-7)
  • (modified) mlir/test/Target/LLVMIR/openmp-private.mlir (+35)
diff --git a/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp b/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp
index 7e76a81e0df92..443979c27c26d 100644
--- a/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp
+++ b/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp
@@ -523,6 +523,7 @@ void DataSharingProcessor::doPrivatize(const semantics::Symbol *sym,
     fir::ExtendedValue symExV = converter.getSymbolExtendedValue(*sym);
 
     symTable->pushScope();
+    mlir::Type yieldedType;
 
     // Populate the `alloc` region.
     {
@@ -542,9 +543,10 @@ void DataSharingProcessor::doPrivatize(const semantics::Symbol *sym,
       symTable->addSymbol(*sym, localExV);
       symTable->pushScope();
       cloneSymbol(sym);
-      firOpBuilder.create<mlir::omp::YieldOp>(
+      auto yieldOp = firOpBuilder.create<mlir::omp::YieldOp>(
           hsb.getAddr().getLoc(),
           symTable->shallowLookupSymbol(*sym).getAddr());
+      yieldedType = yieldOp.getOperand(0).getType();
       symTable->popScope();
     }
 
@@ -554,7 +556,7 @@ void DataSharingProcessor::doPrivatize(const semantics::Symbol *sym,
       // First block argument corresponding to the original/host value while
       // second block argument corresponding to the privatized value.
       mlir::Block *copyEntryBlock = firOpBuilder.createBlock(
-          &copyRegion, /*insertPt=*/{}, {symType, symType}, {symLoc, symLoc});
+          &copyRegion, /*insertPt=*/{}, {symType, yieldedType}, {symLoc, symLoc});
       firOpBuilder.setInsertionPointToEnd(copyEntryBlock);
 
       auto addSymbol = [&](unsigned argIdx, bool force = false) {
diff --git a/flang/test/Lower/OpenMP/DelayedPrivatization/equivalence.f90 b/flang/test/Lower/OpenMP/DelayedPrivatization/equivalence.f90
new file mode 100644
index 0000000000000..23a3b3f96e3e5
--- /dev/null
+++ b/flang/test/Lower/OpenMP/DelayedPrivatization/equivalence.f90
@@ -0,0 +1,36 @@
+! Test delayed privatization for variables that are storage associated via `EQUIVALENCE`.
+
+! RUN: %flang_fc1 -emit-hlfir -fopenmp -mmlir --openmp-enable-delayed-privatization \
+! RUN:   -o - %s 2>&1 | FileCheck %s
+! RUN: bbc -emit-hlfir -fopenmp --openmp-enable-delayed-privatization -o - %s 2>&1 \
+! RUN:   | FileCheck %s
+
+subroutine private_common
+  real x, y
+  equivalence (x,y)
+  !$omp parallel firstprivate(x)
+    x = 3.14
+  !$omp end parallel
+end subroutine
+
+! CHECK:  omp.private {type = firstprivate} @[[X_PRIVATIZER:.*]] : ![[X_TYPE:fir.ptr<f32>]] alloc {
+! CHECK:  ^bb0(%{{.*}}: ![[X_TYPE]]):
+! CHECK:    %[[PRIV_ALLOC:.*]] = fir.alloca f32 {bindc_name = "x", {{.*}}}
+! CHECK:    %[[PRIV_DECL:.*]]:2 = hlfir.declare %[[PRIV_ALLOC]] {{{.*}}} : (![[PRIV_TYPE:fir.ref<f32>]]) -> ({{.*}})
+! CHECK:    omp.yield(%[[PRIV_DECL]]#0 : ![[PRIV_TYPE]])
+! CHECK:  } copy {
+! CHECK:  ^bb0(%[[ORIG_PTR:.*]]: ![[X_TYPE]], %[[PRIV_REF:.*]]: ![[PRIV_TYPE]]):
+! CHECK:    %[[ORIG_VAL:.*]] = fir.load %[[ORIG_PTR]] : !fir.ptr<f32>
+! CHECK:    hlfir.assign %[[ORIG_VAL]] to %[[PRIV_REF]] temporary_lhs : f32, ![[PRIV_TYPE]]
+! CHECK:    omp.yield(%[[PRIV_REF]] : ![[PRIV_TYPE]])
+! CHECK:  }
+
+! CHECK:  func.func @_QPprivate_common() {
+! CHECK:    omp.parallel private(@[[X_PRIVATIZER]] %{{.*}}#0 -> %[[PRIV_ARG:.*]] : ![[X_TYPE]]) {
+! CHECK:      %[[REG_DECL:.*]]:2 = hlfir.declare %[[PRIV_ARG]] {{{.*}}} : (![[X_TYPE]]) -> ({{.*}})
+! CHECK:      %[[CST:.*]] = arith.constant {{.*}}
+! CHECK:      hlfir.assign %[[CST]] to %[[REG_DECL]]#0 : {{.*}}
+! CHECK:      omp.terminator
+! CHECK:    }
+! CHECK:    return
+! CHECK:  }
diff --git a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
index f5ec5a476ad8f..ffcd3b11a12f3 100644
--- a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
+++ b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
@@ -2505,7 +2505,11 @@ LogicalResult PrivateClauseOp::verify() {
              << "Did not expect any values to be yielded.";
     }
 
-    if (yieldedTypes.size() == 1 && yieldedTypes.front() == symType)
+    // TODO How can we check that 2 types are compatible without leaking
+    // dialect-specific (e.g. FIR) information? The problem is that in some
+    // cases, we would get the input type of the symbol as, e.g. `fir.ptr<i32>`
+    // while the allocated private memory is of type `fir.ref<i32>`.
+    if (yieldedTypes.size() == 1 /*&& yieldedTypes.front() == symType*/)
       return success();
 
     auto error = mlir::emitError(yieldOp.getLoc())
diff --git a/mlir/test/Dialect/OpenMP/invalid.mlir b/mlir/test/Dialect/OpenMP/invalid.mlir
index 9977dd57e3023..d511c063c8d9c 100644
--- a/mlir/test/Dialect/OpenMP/invalid.mlir
+++ b/mlir/test/Dialect/OpenMP/invalid.mlir
@@ -2207,13 +2207,14 @@ func.func @omp_distribute_unconstrained_order() -> () {
   }
   return
 }
-// -----
-omp.private {type = private} @x.privatizer : i32 alloc {
-^bb0(%arg0: i32):
-  %0 = arith.constant 0.0 : f32
-  // expected-error @below {{Invalid yielded value. Expected type: 'i32', got: 'f32'}}
-  omp.yield(%0 : f32)
-}
+
+// Disabled for now. See relevant TODO in PrivateClauseOp::verify().
+//omp.private {type = private} @x.privatizer : i32 alloc {
+//^bb0(%arg0: i32):
+//  %0 = arith.constant 0.0 : f32
+//  // _expected-error_ @below {{Invalid yielded value. Expected type: 'i32', got: 'f32'}}
+//  omp.yield(%0 : f32)
+//}
 
 // -----
 
diff --git a/mlir/test/Target/LLVMIR/openmp-private.mlir b/mlir/test/Target/LLVMIR/openmp-private.mlir
index 5924377581db6..6bc73fc6f102b 100644
--- a/mlir/test/Target/LLVMIR/openmp-private.mlir
+++ b/mlir/test/Target/LLVMIR/openmp-private.mlir
@@ -234,3 +234,38 @@ omp.declare_reduction @reducer.part : !llvm.ptr init {
 ^bb0(%arg0: !llvm.ptr):
   omp.yield
 }
+
+// -----
+
+llvm.func @_QPequivalence() {
+  %0 = llvm.mlir.constant(1 : i64) : i64
+  %1 = llvm.alloca %0 x !llvm.array<4 x i8> : (i64) -> !llvm.ptr
+  %2 = llvm.mlir.constant(0 : index) : i64
+  %3 = llvm.getelementptr %1[0, %2] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.array<4 x i8>
+  omp.parallel private(@_QFequivalenceEx_firstprivate_ptr_f32 %3 -> %arg0 : !llvm.ptr) {
+    %4 = llvm.mlir.constant(3.140000e+00 : f32) : f32
+    llvm.store %4, %arg0 : f32, !llvm.ptr
+    omp.terminator
+  }
+  llvm.return
+}
+
+omp.private {type = firstprivate} @_QFequivalenceEx_firstprivate_ptr_f32 : !llvm.ptr alloc {
+^bb0(%arg0: !llvm.ptr):
+  %0 = llvm.mlir.constant(1 : i64) : i64
+  %1 = llvm.alloca %0 x f32 {bindc_name = "x", pinned} : (i64) -> !llvm.ptr
+  omp.yield(%1 : !llvm.ptr)
+} copy {
+^bb0(%arg0: !llvm.ptr, %arg1: !llvm.ptr):
+  %0 = llvm.load %arg0 : !llvm.ptr -> f32
+  llvm.store %0, %arg1 : f32, !llvm.ptr
+  omp.yield(%arg1 : !llvm.ptr)
+}
+
+// CHECK: define internal void @_QPequivalence..omp_par
+// CHECK:   %[[PRIV_ALLOC:.*]] = alloca float, i64 1, align 4
+// CHECK:   %[[HOST_VAL:.*]] = load float, ptr %{{.*}}, align 4
+// Test that we initialzie the firstprivate variable.
+// CHECK:   store float %[[HOST_VAL]], ptr %[[PRIV_ALLOC]], align 4
+// Test that we inlined the body of the parallel region.
+// CHECK:   store float 0x{{.*}}, ptr %[[PRIV_ALLOC]], align 4

@llvmbot
Copy link
Member

llvmbot commented Jul 25, 2024

@llvm/pr-subscribers-mlir-llvm

Author: Kareem Ergawy (ergawy)

Changes

… association

Handles variables that are storage associated via equivalence. The problem is that these variables are declared as fir.ptrs while their privatized storage is declared as fir.ref which was triggering a validation error in the OpenMP dialect. So far, I just disabled a small part of the validation logic until we find a way to properly check of compatible types without leaking the FIR dialect specifics in the OpenMP dialect validation logic.


Full diff: https://github.com/llvm/llvm-project/pull/100531.diff

5 Files Affected:

  • (modified) flang/lib/Lower/OpenMP/DataSharingProcessor.cpp (+4-2)
  • (added) flang/test/Lower/OpenMP/DelayedPrivatization/equivalence.f90 (+36)
  • (modified) mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp (+5-1)
  • (modified) mlir/test/Dialect/OpenMP/invalid.mlir (+8-7)
  • (modified) mlir/test/Target/LLVMIR/openmp-private.mlir (+35)
diff --git a/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp b/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp
index 7e76a81e0df92..443979c27c26d 100644
--- a/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp
+++ b/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp
@@ -523,6 +523,7 @@ void DataSharingProcessor::doPrivatize(const semantics::Symbol *sym,
     fir::ExtendedValue symExV = converter.getSymbolExtendedValue(*sym);
 
     symTable->pushScope();
+    mlir::Type yieldedType;
 
     // Populate the `alloc` region.
     {
@@ -542,9 +543,10 @@ void DataSharingProcessor::doPrivatize(const semantics::Symbol *sym,
       symTable->addSymbol(*sym, localExV);
       symTable->pushScope();
       cloneSymbol(sym);
-      firOpBuilder.create<mlir::omp::YieldOp>(
+      auto yieldOp = firOpBuilder.create<mlir::omp::YieldOp>(
           hsb.getAddr().getLoc(),
           symTable->shallowLookupSymbol(*sym).getAddr());
+      yieldedType = yieldOp.getOperand(0).getType();
       symTable->popScope();
     }
 
@@ -554,7 +556,7 @@ void DataSharingProcessor::doPrivatize(const semantics::Symbol *sym,
       // First block argument corresponding to the original/host value while
       // second block argument corresponding to the privatized value.
       mlir::Block *copyEntryBlock = firOpBuilder.createBlock(
-          &copyRegion, /*insertPt=*/{}, {symType, symType}, {symLoc, symLoc});
+          &copyRegion, /*insertPt=*/{}, {symType, yieldedType}, {symLoc, symLoc});
       firOpBuilder.setInsertionPointToEnd(copyEntryBlock);
 
       auto addSymbol = [&](unsigned argIdx, bool force = false) {
diff --git a/flang/test/Lower/OpenMP/DelayedPrivatization/equivalence.f90 b/flang/test/Lower/OpenMP/DelayedPrivatization/equivalence.f90
new file mode 100644
index 0000000000000..23a3b3f96e3e5
--- /dev/null
+++ b/flang/test/Lower/OpenMP/DelayedPrivatization/equivalence.f90
@@ -0,0 +1,36 @@
+! Test delayed privatization for variables that are storage associated via `EQUIVALENCE`.
+
+! RUN: %flang_fc1 -emit-hlfir -fopenmp -mmlir --openmp-enable-delayed-privatization \
+! RUN:   -o - %s 2>&1 | FileCheck %s
+! RUN: bbc -emit-hlfir -fopenmp --openmp-enable-delayed-privatization -o - %s 2>&1 \
+! RUN:   | FileCheck %s
+
+subroutine private_common
+  real x, y
+  equivalence (x,y)
+  !$omp parallel firstprivate(x)
+    x = 3.14
+  !$omp end parallel
+end subroutine
+
+! CHECK:  omp.private {type = firstprivate} @[[X_PRIVATIZER:.*]] : ![[X_TYPE:fir.ptr<f32>]] alloc {
+! CHECK:  ^bb0(%{{.*}}: ![[X_TYPE]]):
+! CHECK:    %[[PRIV_ALLOC:.*]] = fir.alloca f32 {bindc_name = "x", {{.*}}}
+! CHECK:    %[[PRIV_DECL:.*]]:2 = hlfir.declare %[[PRIV_ALLOC]] {{{.*}}} : (![[PRIV_TYPE:fir.ref<f32>]]) -> ({{.*}})
+! CHECK:    omp.yield(%[[PRIV_DECL]]#0 : ![[PRIV_TYPE]])
+! CHECK:  } copy {
+! CHECK:  ^bb0(%[[ORIG_PTR:.*]]: ![[X_TYPE]], %[[PRIV_REF:.*]]: ![[PRIV_TYPE]]):
+! CHECK:    %[[ORIG_VAL:.*]] = fir.load %[[ORIG_PTR]] : !fir.ptr<f32>
+! CHECK:    hlfir.assign %[[ORIG_VAL]] to %[[PRIV_REF]] temporary_lhs : f32, ![[PRIV_TYPE]]
+! CHECK:    omp.yield(%[[PRIV_REF]] : ![[PRIV_TYPE]])
+! CHECK:  }
+
+! CHECK:  func.func @_QPprivate_common() {
+! CHECK:    omp.parallel private(@[[X_PRIVATIZER]] %{{.*}}#0 -> %[[PRIV_ARG:.*]] : ![[X_TYPE]]) {
+! CHECK:      %[[REG_DECL:.*]]:2 = hlfir.declare %[[PRIV_ARG]] {{{.*}}} : (![[X_TYPE]]) -> ({{.*}})
+! CHECK:      %[[CST:.*]] = arith.constant {{.*}}
+! CHECK:      hlfir.assign %[[CST]] to %[[REG_DECL]]#0 : {{.*}}
+! CHECK:      omp.terminator
+! CHECK:    }
+! CHECK:    return
+! CHECK:  }
diff --git a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
index f5ec5a476ad8f..ffcd3b11a12f3 100644
--- a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
+++ b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
@@ -2505,7 +2505,11 @@ LogicalResult PrivateClauseOp::verify() {
              << "Did not expect any values to be yielded.";
     }
 
-    if (yieldedTypes.size() == 1 && yieldedTypes.front() == symType)
+    // TODO How can we check that 2 types are compatible without leaking
+    // dialect-specific (e.g. FIR) information? The problem is that in some
+    // cases, we would get the input type of the symbol as, e.g. `fir.ptr<i32>`
+    // while the allocated private memory is of type `fir.ref<i32>`.
+    if (yieldedTypes.size() == 1 /*&& yieldedTypes.front() == symType*/)
       return success();
 
     auto error = mlir::emitError(yieldOp.getLoc())
diff --git a/mlir/test/Dialect/OpenMP/invalid.mlir b/mlir/test/Dialect/OpenMP/invalid.mlir
index 9977dd57e3023..d511c063c8d9c 100644
--- a/mlir/test/Dialect/OpenMP/invalid.mlir
+++ b/mlir/test/Dialect/OpenMP/invalid.mlir
@@ -2207,13 +2207,14 @@ func.func @omp_distribute_unconstrained_order() -> () {
   }
   return
 }
-// -----
-omp.private {type = private} @x.privatizer : i32 alloc {
-^bb0(%arg0: i32):
-  %0 = arith.constant 0.0 : f32
-  // expected-error @below {{Invalid yielded value. Expected type: 'i32', got: 'f32'}}
-  omp.yield(%0 : f32)
-}
+
+// Disabled for now. See relevant TODO in PrivateClauseOp::verify().
+//omp.private {type = private} @x.privatizer : i32 alloc {
+//^bb0(%arg0: i32):
+//  %0 = arith.constant 0.0 : f32
+//  // _expected-error_ @below {{Invalid yielded value. Expected type: 'i32', got: 'f32'}}
+//  omp.yield(%0 : f32)
+//}
 
 // -----
 
diff --git a/mlir/test/Target/LLVMIR/openmp-private.mlir b/mlir/test/Target/LLVMIR/openmp-private.mlir
index 5924377581db6..6bc73fc6f102b 100644
--- a/mlir/test/Target/LLVMIR/openmp-private.mlir
+++ b/mlir/test/Target/LLVMIR/openmp-private.mlir
@@ -234,3 +234,38 @@ omp.declare_reduction @reducer.part : !llvm.ptr init {
 ^bb0(%arg0: !llvm.ptr):
   omp.yield
 }
+
+// -----
+
+llvm.func @_QPequivalence() {
+  %0 = llvm.mlir.constant(1 : i64) : i64
+  %1 = llvm.alloca %0 x !llvm.array<4 x i8> : (i64) -> !llvm.ptr
+  %2 = llvm.mlir.constant(0 : index) : i64
+  %3 = llvm.getelementptr %1[0, %2] : (!llvm.ptr, i64) -> !llvm.ptr, !llvm.array<4 x i8>
+  omp.parallel private(@_QFequivalenceEx_firstprivate_ptr_f32 %3 -> %arg0 : !llvm.ptr) {
+    %4 = llvm.mlir.constant(3.140000e+00 : f32) : f32
+    llvm.store %4, %arg0 : f32, !llvm.ptr
+    omp.terminator
+  }
+  llvm.return
+}
+
+omp.private {type = firstprivate} @_QFequivalenceEx_firstprivate_ptr_f32 : !llvm.ptr alloc {
+^bb0(%arg0: !llvm.ptr):
+  %0 = llvm.mlir.constant(1 : i64) : i64
+  %1 = llvm.alloca %0 x f32 {bindc_name = "x", pinned} : (i64) -> !llvm.ptr
+  omp.yield(%1 : !llvm.ptr)
+} copy {
+^bb0(%arg0: !llvm.ptr, %arg1: !llvm.ptr):
+  %0 = llvm.load %arg0 : !llvm.ptr -> f32
+  llvm.store %0, %arg1 : f32, !llvm.ptr
+  omp.yield(%arg1 : !llvm.ptr)
+}
+
+// CHECK: define internal void @_QPequivalence..omp_par
+// CHECK:   %[[PRIV_ALLOC:.*]] = alloca float, i64 1, align 4
+// CHECK:   %[[HOST_VAL:.*]] = load float, ptr %{{.*}}, align 4
+// Test that we initialzie the firstprivate variable.
+// CHECK:   store float %[[HOST_VAL]], ptr %[[PRIV_ALLOC]], align 4
+// Test that we inlined the body of the parallel region.
+// CHECK:   store float 0x{{.*}}, ptr %[[PRIV_ALLOC]], align 4

@ergawy ergawy changed the title [flang][OpenMP] Delayed privatization for variable with equivalence [flang][OpenMP] Delayed privatization for variable with equivalence association Jul 25, 2024
Copy link

github-actions bot commented Jul 25, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

@ergawy ergawy changed the title [flang][OpenMP] Delayed privatization for variable with equivalence association [flang][OpenMP] Delayed privatization for variables with equivalence association Jul 25, 2024
@ergawy ergawy force-pushed the delayed_privatization_equivalence branch from 5252b29 to a8a797f Compare July 25, 2024 09:05
Copy link
Contributor

@tblah tblah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, but please wait for another approval because I am still getting up to speed with delayed privatisation.

@ergawy ergawy force-pushed the delayed_privatization_equivalence branch from a8a797f to 48ea3cc Compare July 30, 2024 05:11
@ergawy
Copy link
Member Author

ergawy commented Jul 31, 2024

@kiranchandramohan @Dinistro Thanks for the review, do you have any further comments/suggestions on this PR?

@Dinistro
Copy link
Contributor

@kiranchandramohan @Dinistro Thanks for the review, do you have any further comments/suggestions on this PR?

I'm fine with the implemented solution and do not have the expertise to properly review the flang parts. If this looks good to others, it's good for me 🙂

@ergawy ergawy force-pushed the delayed_privatization_equivalence branch from 48ea3cc to 17265b4 Compare July 31, 2024 09:53
Copy link
Member

@skatrak skatrak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you Kareem, this LGTM. However, I'm not very familiar with equivalence handling in flang, so perhaps it's still good waiting for a look by another reviewer.

@ergawy ergawy requested a review from luporl August 1, 2024 03:19
@ergawy ergawy force-pushed the delayed_privatization_equivalence branch from 282aa1d to 73855c0 Compare August 1, 2024 04:46
Copy link
Contributor

@kiranchandramohan kiranchandramohan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LG.

ergawy added 3 commits August 1, 2024 04:28
… association

Handles variables that are storage associated via `equivalence`. The
problem is that these variables are declared as `fir.ptr`s while their
privatized storage is declared as `fir.ref` which was triggering a
validation error in the OpenMP dialect.
@ergawy ergawy force-pushed the delayed_privatization_equivalence branch from 73855c0 to 174abf6 Compare August 1, 2024 09:31
@ergawy ergawy merged commit bbadbf7 into llvm:main Aug 1, 2024
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants