Skip to content

Commit 3abcd5f

Browse files
authored
[flang][openmp] fix OMPFunctionFiltering pass after #87796 (#89776)
The pass assumed that all fun.func symbol usages could be safely replaced by undef, that is not true after #87796 that added a back link from internal procedure back to the parent procedure. This caused the internal procedures to be erased and then processed (segfault). Also set visibility of such internal procedures so that MLIR do not remove them before the target function is generated for the target region.
1 parent cd3e71f commit 3abcd5f

File tree

2 files changed

+45
-0
lines changed

2 files changed

+45
-0
lines changed

flang/lib/Optimizer/Transforms/OMPFunctionFiltering.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
//===----------------------------------------------------------------------===//
1313

1414
#include "flang/Optimizer/Dialect/FIRDialect.h"
15+
#include "flang/Optimizer/Dialect/FIROpsSupport.h"
1516
#include "flang/Optimizer/Transforms/Passes.h"
1617

1718
#include "mlir/Dialect/Func/IR/FuncOps.h"
@@ -66,6 +67,16 @@ class OMPFunctionFilteringPass
6667
SymbolTable::UseRange funcUses = *funcOp.getSymbolUses(op);
6768
for (SymbolTable::SymbolUse use : funcUses) {
6869
Operation *callOp = use.getUser();
70+
if (auto internalFunc = mlir::dyn_cast<func::FuncOp>(callOp)) {
71+
// Do not delete internal procedures holding the symbol of their
72+
// Fortran host procedure as attribute.
73+
internalFunc->removeAttr(fir::getHostSymbolAttrName());
74+
// Set public visibility so that the function is not deleted by MLIR
75+
// because unused. Changing it is OK here because the function will
76+
// be deleted anyway in the second filtering phase.
77+
internalFunc.setVisibility(mlir::SymbolTable::Visibility::Public);
78+
continue;
79+
}
6980
// If the callOp has users then replace them with Undef values.
7081
if (!callOp->use_empty()) {
7182
SmallVector<Value> undefResults;
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
! RUN: %flang_fc1 -fopenmp -flang-experimental-hlfir -emit-llvm %s -o - | FileCheck --check-prefixes=LLVM-HOST,LLVM-ALL %s
2+
! RUN: %flang_fc1 -fopenmp -emit-hlfir %s -o - | FileCheck --check-prefixes=MLIR-HOST,MLIR-ALL %s
3+
! RUN: %flang_fc1 -fopenmp -fopenmp-is-target-device -flang-experimental-hlfir -emit-llvm %s -o - | FileCheck --check-prefixes=LLVM-DEVICE,LLVM-ALL %s
4+
! RUN: %flang_fc1 -fopenmp -fopenmp-is-target-device -emit-hlfir %s -o - | FileCheck --check-prefixes=MLIR-DEVICE,MLIR-ALL %s
5+
! RUN: bbc -fopenmp -emit-hlfir %s -o - | FileCheck --check-prefixes=MLIR-HOST,MLIR-ALL %s
6+
! RUN: bbc -fopenmp -fopenmp-is-target-device -emit-hlfir %s -o - | FileCheck --check-prefixes=MLIR-DEVICE,MLIR-ALL %s
7+
8+
! Check that the correct LLVM IR functions are kept for the host and device
9+
! after running the whole set of translation and transformation passes from
10+
! Fortran.
11+
12+
! MLIR-HOST: func.func @{{.*}}host_parent_procedure(
13+
! MLIR-HOST: return
14+
! MLIR-DEVICE-NOT: func.func {{.*}}host_parent_procedure(
15+
16+
! LLVM-HOST: define {{.*}} @host_parent_procedure{{.*}}(
17+
! LLVM-DEVICE-NOT: {{.*}} @{{.*}}_host_parent_procedure{{.*}}(
18+
subroutine host_parent_procedure(x)
19+
integer, intent(out) :: x
20+
call target_internal_proc(x)
21+
contains
22+
! MLIR-ALL: func.func {{.*}}@_QFhost_parent_procedurePtarget_internal_proc(
23+
24+
! LLVM-HOST: define {{.*}} @_QFhost_parent_procedurePtarget_internal_proc(
25+
! LLVM-DEVICE-NOT: define {{.*}} @_QFhost_parent_procedurePtarget_internal_proc(
26+
! LLVM-ALL: define {{.*}} @__omp_offloading_{{.*}}QFhost_parent_procedurePtarget_internal_proc{{.*}}(
27+
28+
subroutine target_internal_proc(x)
29+
integer, intent(out) :: x
30+
!$omp target map(from:x)
31+
x = 10
32+
!$omp end target
33+
end subroutine
34+
end subroutine

0 commit comments

Comments
 (0)