Skip to content

[OpenMP][LLVM] Clone omp.private op in the parent module #96024

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 9 commits into from
Jun 23, 2024

Conversation

ergawy
Copy link
Member

@ergawy ergawy commented Jun 19, 2024

Fixes a crash uncovered by test 0007_0019.f90 in the Fujitsu test suite.

Previously, in the PrivCB, we cloned the omp.private op without inserting it in the parent module of the original op. This causes issues whenever there is an op that needs to lookup the parent module (e.g. for symbol lookup). This PR fixes the issue by cloning in the parent module instead of creating an orphaned op.

Fixes a crash uncovered by test 0007_0019.f90 in the Fujitsu test suite.

Previously, in the `PrivCB`, we cloned the `omp.private` op without
inserting it in the parent module of the original op. This causes issues
whenever there is an op that needs to lookup the parent module (e.g. for
symbol lookup). This PR fixes the issue by cloning in the parent module
instead of creating an orphaned op.
@llvmbot llvmbot added mlir:llvm mlir flang Flang issues not falling into any other category mlir:openmp flang:fir-hlfir flang:openmp labels Jun 19, 2024
@llvmbot
Copy link
Member

llvmbot commented Jun 19, 2024

@llvm/pr-subscribers-mlir-openmp
@llvm/pr-subscribers-mlir-llvm

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

Author: Kareem Ergawy (ergawy)

Changes

Fixes a crash uncovered by test 0007_0019.f90 in the Fujitsu test suite.

Previously, in the PrivCB, we cloned the omp.private op without inserting it in the parent module of the original op. This causes issues whenever there is an op that needs to lookup the parent module (e.g. for symbol lookup). This PR fixes the issue by cloning in the parent module instead of creating an orphaned op.


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

3 Files Affected:

  • (removed) flang/test/Lower/OpenMP/delayed-privatization-lower-allocatable-to-llvm.f90 (-23)
  • (added) flang/test/Lower/OpenMP/delayed-privatization-lower-to-llvm.f90 (+40)
  • (modified) mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp (+5-1)
diff --git a/flang/test/Lower/OpenMP/delayed-privatization-lower-allocatable-to-llvm.f90 b/flang/test/Lower/OpenMP/delayed-privatization-lower-allocatable-to-llvm.f90
deleted file mode 100644
index ac9a6d8746cf2..0000000000000
--- a/flang/test/Lower/OpenMP/delayed-privatization-lower-allocatable-to-llvm.f90
+++ /dev/null
@@ -1,23 +0,0 @@
-! Tests the OMPIRBuilder can handle multiple privatization regions that contain
-! multiple BBs (for example, for allocatables).
-
-! RUN: %flang -S -emit-llvm -fopenmp -mmlir --openmp-enable-delayed-privatization \
-! RUN:   -o - %s 2>&1 | FileCheck %s
-
-subroutine foo(x)
-  integer, allocatable :: x, y
-!$omp parallel private(x, y)
-  x = y
-!$omp end parallel
-end
-
-! CHECK-LABEL: define void @foo_
-! CHECK:         ret void
-! CHECK-NEXT:  }
-
-! CHECK-LABEL: define internal void @foo_..omp_par
-! CHECK-DAG:     call ptr @malloc
-! CHECK-DAG:     call ptr @malloc
-! CHECK-DAG:     call void @free
-! CHECK-DAG:     call void @free
-! CHECK:       }
diff --git a/flang/test/Lower/OpenMP/delayed-privatization-lower-to-llvm.f90 b/flang/test/Lower/OpenMP/delayed-privatization-lower-to-llvm.f90
new file mode 100644
index 0000000000000..a60b843f10e28
--- /dev/null
+++ b/flang/test/Lower/OpenMP/delayed-privatization-lower-to-llvm.f90
@@ -0,0 +1,40 @@
+! Tests the OMPIRBuilder can handle multiple privatization regions that contain
+! multiple BBs (for example, for allocatables).
+
+! RUN: %flang -S -emit-llvm -fopenmp -mmlir --openmp-enable-delayed-privatization \
+! RUN:   -o - %s 2>&1 | FileCheck %s
+
+! CHECK: @[[SOURCE:.*]] = linkonce constant [{{.*}} x i8] c"{{.*}}delayed-privatization-lower-to-llvm.f90\00", comdat
+
+subroutine lower_allocatable(x)
+  integer, allocatable :: x, y
+!$omp parallel private(x, y)
+  x = y
+!$omp end parallel
+end
+
+! CHECK-LABEL: define void @lower_allocatable_
+! CHECK:         ret void
+! CHECK-NEXT:  }
+
+! CHECK-LABEL: define internal void @lower_allocatable_..omp_par
+! CHECK-DAG:     call ptr @malloc
+! CHECK-DAG:     call ptr @malloc
+! CHECK-DAG:     call void @free
+! CHECK-DAG:     call void @free
+! CHECK:       }
+
+subroutine lower_region_with_if_print
+  real(kind=8), dimension(1,1) :: u1
+  !$omp parallel firstprivate(u1) 
+    if (any(u1/=1)) print *,"if branch"
+  !$omp end parallel
+end subroutine
+
+! CHECK-LABEL: define void @lower_region_with_if_print_
+! CHECK:         ret void
+! CHECK-NEXT:  }
+
+! CHECK-LABEL: define internal void @lower_region_with_if_print_..omp_par
+! CHECK:         call i1 @_FortranAAny(ptr %{{[^[:space:]]+}}, ptr @[[SOURCE]], i32 {{.*}}, i32 {{.*}})
+! CHECK:       }
diff --git a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
index cbfc64972f38b..abfe7a2210eb4 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
@@ -1288,7 +1288,11 @@ convertOmpParallel(omp::ParallelOp opInst, llvm::IRBuilderBase &builder,
           // region. The privatizer is processed in-place (see below) before it
           // gets inlined in the parallel region and therefore processing the
           // original op is dangerous.
-          return {privVar, privatizer.clone()};
+
+          mlir::IRRewriter opCloner(&moduleTranslation.getContext());
+          opCloner.setInsertionPoint(privatizer);
+          return {privVar, llvm::cast<mlir::omp::PrivateClauseOp>(
+                               opCloner.clone(*privatizer))};
         }
       }
 

@llvmbot
Copy link
Member

llvmbot commented Jun 19, 2024

@llvm/pr-subscribers-flang-openmp

Author: Kareem Ergawy (ergawy)

Changes

Fixes a crash uncovered by test 0007_0019.f90 in the Fujitsu test suite.

Previously, in the PrivCB, we cloned the omp.private op without inserting it in the parent module of the original op. This causes issues whenever there is an op that needs to lookup the parent module (e.g. for symbol lookup). This PR fixes the issue by cloning in the parent module instead of creating an orphaned op.


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

3 Files Affected:

  • (removed) flang/test/Lower/OpenMP/delayed-privatization-lower-allocatable-to-llvm.f90 (-23)
  • (added) flang/test/Lower/OpenMP/delayed-privatization-lower-to-llvm.f90 (+40)
  • (modified) mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp (+5-1)
diff --git a/flang/test/Lower/OpenMP/delayed-privatization-lower-allocatable-to-llvm.f90 b/flang/test/Lower/OpenMP/delayed-privatization-lower-allocatable-to-llvm.f90
deleted file mode 100644
index ac9a6d8746cf2..0000000000000
--- a/flang/test/Lower/OpenMP/delayed-privatization-lower-allocatable-to-llvm.f90
+++ /dev/null
@@ -1,23 +0,0 @@
-! Tests the OMPIRBuilder can handle multiple privatization regions that contain
-! multiple BBs (for example, for allocatables).
-
-! RUN: %flang -S -emit-llvm -fopenmp -mmlir --openmp-enable-delayed-privatization \
-! RUN:   -o - %s 2>&1 | FileCheck %s
-
-subroutine foo(x)
-  integer, allocatable :: x, y
-!$omp parallel private(x, y)
-  x = y
-!$omp end parallel
-end
-
-! CHECK-LABEL: define void @foo_
-! CHECK:         ret void
-! CHECK-NEXT:  }
-
-! CHECK-LABEL: define internal void @foo_..omp_par
-! CHECK-DAG:     call ptr @malloc
-! CHECK-DAG:     call ptr @malloc
-! CHECK-DAG:     call void @free
-! CHECK-DAG:     call void @free
-! CHECK:       }
diff --git a/flang/test/Lower/OpenMP/delayed-privatization-lower-to-llvm.f90 b/flang/test/Lower/OpenMP/delayed-privatization-lower-to-llvm.f90
new file mode 100644
index 0000000000000..a60b843f10e28
--- /dev/null
+++ b/flang/test/Lower/OpenMP/delayed-privatization-lower-to-llvm.f90
@@ -0,0 +1,40 @@
+! Tests the OMPIRBuilder can handle multiple privatization regions that contain
+! multiple BBs (for example, for allocatables).
+
+! RUN: %flang -S -emit-llvm -fopenmp -mmlir --openmp-enable-delayed-privatization \
+! RUN:   -o - %s 2>&1 | FileCheck %s
+
+! CHECK: @[[SOURCE:.*]] = linkonce constant [{{.*}} x i8] c"{{.*}}delayed-privatization-lower-to-llvm.f90\00", comdat
+
+subroutine lower_allocatable(x)
+  integer, allocatable :: x, y
+!$omp parallel private(x, y)
+  x = y
+!$omp end parallel
+end
+
+! CHECK-LABEL: define void @lower_allocatable_
+! CHECK:         ret void
+! CHECK-NEXT:  }
+
+! CHECK-LABEL: define internal void @lower_allocatable_..omp_par
+! CHECK-DAG:     call ptr @malloc
+! CHECK-DAG:     call ptr @malloc
+! CHECK-DAG:     call void @free
+! CHECK-DAG:     call void @free
+! CHECK:       }
+
+subroutine lower_region_with_if_print
+  real(kind=8), dimension(1,1) :: u1
+  !$omp parallel firstprivate(u1) 
+    if (any(u1/=1)) print *,"if branch"
+  !$omp end parallel
+end subroutine
+
+! CHECK-LABEL: define void @lower_region_with_if_print_
+! CHECK:         ret void
+! CHECK-NEXT:  }
+
+! CHECK-LABEL: define internal void @lower_region_with_if_print_..omp_par
+! CHECK:         call i1 @_FortranAAny(ptr %{{[^[:space:]]+}}, ptr @[[SOURCE]], i32 {{.*}}, i32 {{.*}})
+! CHECK:       }
diff --git a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
index cbfc64972f38b..abfe7a2210eb4 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
@@ -1288,7 +1288,11 @@ convertOmpParallel(omp::ParallelOp opInst, llvm::IRBuilderBase &builder,
           // region. The privatizer is processed in-place (see below) before it
           // gets inlined in the parallel region and therefore processing the
           // original op is dangerous.
-          return {privVar, privatizer.clone()};
+
+          mlir::IRRewriter opCloner(&moduleTranslation.getContext());
+          opCloner.setInsertionPoint(privatizer);
+          return {privVar, llvm::cast<mlir::omp::PrivateClauseOp>(
+                               opCloner.clone(*privatizer))};
         }
       }
 

@ergawy
Copy link
Member Author

ergawy commented Jun 21, 2024

@Dinistro @kiranchandramohan do you have any other suggestions to do in this PR?

@Dinistro
Copy link
Contributor

@Dinistro @kiranchandramohan do you have any other suggestions to do in this PR?

I'm fine with the test, but I don't feel qualified to accept the PR, as I'm not too familiar with these parts of MLIR. Thanks for minimizing the test 🙂

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.

Thanks Kareem. LGTM.

! Tests the OMPIRBuilder can handle multiple privatization regions that contain
! multiple BBs (for example, for allocatables).

! RUN: %flang -S -emit-llvm -fopenmp -mmlir --openmp-enable-delayed-privatization \
Copy link
Contributor

Choose a reason for hiding this comment

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

LLVM IR checks are better avoided in Flang. If we really need this then this should go to the Integration directory. Alternative is to drop it since it will be tested in the Fujitsu suite (later incorporated into llvm-testsuite) and by the translation lit test.

@ergawy ergawy merged commit f372bb4 into llvm:main Jun 23, 2024
7 checks passed
AlexisPerry pushed a commit to llvm-project-tlp/llvm-project that referenced this pull request Jul 9, 2024
Fixes a crash uncovered by test 0007_0019.f90 in the Fujitsu test suite.

Previously, in the `PrivCB`, we cloned the `omp.private` op without
inserting it in the parent module of the original op. This causes issues
whenever there is an op that needs to lookup the parent module (e.g. for
symbol lookup). This PR fixes the issue by cloning in the parent module
instead of creating an orphaned op.
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.

4 participants