[Mlir-commits] [flang] [mlir] [OpenMP][LLVM] Clone `omp.private` op in the parent module (PR #96024)

Kareem Ergawy llvmlistbot at llvm.org
Tue Jun 18 22:19:44 PDT 2024


https://github.com/ergawy created https://github.com/llvm/llvm-project/pull/96024

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.

>From 254a34472fc4bc69577e542ae05f5417c99845ee Mon Sep 17 00:00:00 2001
From: ergawy <kareem.ergawy at amd.com>
Date: Wed, 19 Jun 2024 00:15:42 -0500
Subject: [PATCH] [OpenMP][LLVM] Clone `omp.private` op in the parent module

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.
---
 ...rivatization-lower-allocatable-to-llvm.f90 | 23 -----------
 .../delayed-privatization-lower-to-llvm.f90   | 40 +++++++++++++++++++
 .../OpenMP/OpenMPToLLVMIRTranslation.cpp      |  6 ++-
 3 files changed, 45 insertions(+), 24 deletions(-)
 delete mode 100644 flang/test/Lower/OpenMP/delayed-privatization-lower-allocatable-to-llvm.f90
 create mode 100644 flang/test/Lower/OpenMP/delayed-privatization-lower-to-llvm.f90

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))};
         }
       }
 



More information about the Mlir-commits mailing list