Skip to content

Commit f372bb4

Browse files
authored
[OpenMP][LLVM] Clone omp.private op in the parent module (#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.
1 parent f7fc72e commit f372bb4

File tree

2 files changed

+64
-1
lines changed

2 files changed

+64
-1
lines changed

mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1304,7 +1304,26 @@ convertOmpParallel(omp::ParallelOp opInst, llvm::IRBuilderBase &builder,
13041304
// region. The privatizer is processed in-place (see below) before it
13051305
// gets inlined in the parallel region and therefore processing the
13061306
// original op is dangerous.
1307-
return {privVar, privatizer.clone()};
1307+
1308+
MLIRContext &context = moduleTranslation.getContext();
1309+
mlir::IRRewriter opCloner(&context);
1310+
opCloner.setInsertionPoint(privatizer);
1311+
auto clone = llvm::cast<mlir::omp::PrivateClauseOp>(
1312+
opCloner.clone(*privatizer));
1313+
1314+
// Unique the clone name to avoid clashes in the symbol table.
1315+
unsigned counter = 0;
1316+
SmallString<256> cloneName = SymbolTable::generateSymbolName<256>(
1317+
privatizer.getSymName(),
1318+
[&](llvm::StringRef candidate) {
1319+
return SymbolTable::lookupNearestSymbolFrom(
1320+
opInst, StringAttr::get(&context, candidate)) !=
1321+
nullptr;
1322+
},
1323+
counter);
1324+
1325+
clone.setSymName(cloneName);
1326+
return {privVar, clone};
13081327
}
13091328
}
13101329

mlir/test/Target/LLVMIR/openmp-private.mlir

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,3 +140,47 @@ omp.private {type = private} @multi_block.privatizer : !llvm.ptr alloc {
140140
llvm.store %1, %arg2 : f32, !llvm.ptr
141141
omp.yield(%arg2 : !llvm.ptr)
142142
}
143+
144+
// Tests fix for Fujitsu test suite test: 0007_0019.f90: the
145+
// `llvm.mlir.addressof` op needs access to the parent module when lowering
146+
// from the LLVM dialect to LLVM IR. If such op is used inside an `omp.private`
147+
// op instance that was not created/cloned inside the module, we would get a
148+
// seg fault due to trying to access a null pointer.
149+
150+
// CHECK-LABEL: define internal void @lower_region_with_addressof..omp_par
151+
// CHECK: omp.par.region:
152+
// CHECK: br label %[[PAR_REG_BEG:.*]]
153+
// CHECK: [[PAR_REG_BEG]]:
154+
// CHECK: %[[PRIVATIZER_GEP:.*]] = getelementptr double, ptr @_QQfoo, i64 111
155+
// CHECK: call void @bar(ptr %[[PRIVATIZER_GEP]])
156+
// CHECK: call void @bar(ptr getelementptr (double, ptr @_QQfoo, i64 222))
157+
llvm.func @lower_region_with_addressof() {
158+
%0 = llvm.mlir.constant(1 : i64) : i64
159+
%1 = llvm.alloca %0 x f64 {bindc_name = "u1"} : (i64) -> !llvm.ptr
160+
omp.parallel private(@_QFlower_region_with_addressof_privatizer %1 -> %arg0 : !llvm.ptr) {
161+
%c0 = llvm.mlir.constant(111 : i64) : i64
162+
%2 = llvm.getelementptr %arg0[%c0] : (!llvm.ptr, i64) -> !llvm.ptr, f64
163+
llvm.call @bar(%2) : (!llvm.ptr) -> ()
164+
165+
%c1 = llvm.mlir.constant(222 : i64) : i64
166+
%3 = llvm.mlir.addressof @_QQfoo: !llvm.ptr
167+
%4 = llvm.getelementptr %3[%c1] : (!llvm.ptr, i64) -> !llvm.ptr, f64
168+
llvm.call @bar(%4) : (!llvm.ptr) -> ()
169+
omp.terminator
170+
}
171+
172+
llvm.return
173+
}
174+
175+
omp.private {type = private} @_QFlower_region_with_addressof_privatizer : !llvm.ptr alloc {
176+
^bb0(%arg0: !llvm.ptr):
177+
%0 = llvm.mlir.addressof @_QQfoo: !llvm.ptr
178+
omp.yield(%0 : !llvm.ptr)
179+
}
180+
181+
llvm.mlir.global linkonce constant @_QQfoo() {addr_space = 0 : i32} : !llvm.array<3 x i8> {
182+
%0 = llvm.mlir.constant("foo") : !llvm.array<3 x i8>
183+
llvm.return %0 : !llvm.array<3 x i8>
184+
}
185+
186+
llvm.func @bar(!llvm.ptr)

0 commit comments

Comments
 (0)