mirror of
https://github.com/intel/llvm.git
synced 2026-01-14 03:14:06 +08:00
[mlir][OpenMP] Don't allow firstprivate for simd (#146734)
This is not allowed by the openmp standard.
This commit is contained in:
@@ -15,11 +15,13 @@
|
||||
#include "mlir/Dialect/Func/IR/FuncOps.h"
|
||||
#include "mlir/Dialect/LLVMIR/LLVMTypes.h"
|
||||
#include "mlir/Dialect/OpenACCMPCommon/Interfaces/AtomicInterfaces.h"
|
||||
#include "mlir/Dialect/OpenMP/OpenMPClauseOperands.h"
|
||||
#include "mlir/IR/Attributes.h"
|
||||
#include "mlir/IR/BuiltinAttributes.h"
|
||||
#include "mlir/IR/DialectImplementation.h"
|
||||
#include "mlir/IR/OpImplementation.h"
|
||||
#include "mlir/IR/OperationSupport.h"
|
||||
#include "mlir/IR/SymbolTable.h"
|
||||
#include "mlir/Interfaces/FoldInterfaces.h"
|
||||
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
@@ -2640,6 +2642,23 @@ LogicalResult SimdOp::verify() {
|
||||
return emitError()
|
||||
<< "'omp.composite' attribute present in non-composite wrapper";
|
||||
|
||||
// Firstprivate is not allowed for SIMD in the standard. Check that none of
|
||||
// the private decls are for firstprivate.
|
||||
std::optional<ArrayAttr> privateSyms = getPrivateSyms();
|
||||
if (privateSyms) {
|
||||
for (const Attribute &sym : *privateSyms) {
|
||||
auto symRef = cast<SymbolRefAttr>(sym);
|
||||
omp::PrivateClauseOp privatizer =
|
||||
SymbolTable::lookupNearestSymbolFrom<omp::PrivateClauseOp>(
|
||||
getOperation(), symRef);
|
||||
if (!privatizer)
|
||||
return emitError() << "Cannot find privatizer '" << symRef << "'";
|
||||
if (privatizer.getDataSharingType() ==
|
||||
DataSharingClauseType::FirstPrivate)
|
||||
return emitError() << "FIRSTPRIVATE cannot be used with SIMD";
|
||||
}
|
||||
}
|
||||
|
||||
return success();
|
||||
}
|
||||
|
||||
|
||||
@@ -2899,7 +2899,8 @@ convertOmpSimd(Operation &opInst, llvm::IRBuilderBase &builder,
|
||||
.failed())
|
||||
return failure();
|
||||
|
||||
// TODO: no call to copyFirstPrivateVars?
|
||||
// No call to copyFirstPrivateVars because FIRSTPRIVATE is not allowed for
|
||||
// SIMD.
|
||||
|
||||
assert(afterAllocas.get()->getSinglePredecessor());
|
||||
if (failed(initReductionVars(simdOp, reductionArgs, builder,
|
||||
|
||||
@@ -480,6 +480,39 @@ func.func @omp_simd_pretty_simdlen_safelen(%lb : index, %ub : index, %step : ind
|
||||
|
||||
// -----
|
||||
|
||||
func.func @omp_simd_bad_privatizer(%lb : index, %ub : index, %step : index) {
|
||||
%0 = llvm.mlir.constant(1 : i64) : i64
|
||||
%1 = llvm.alloca %0 x i32 : (i64) -> !llvm.ptr
|
||||
// expected-error @below {{Cannot find privatizer '@not_defined'}}
|
||||
omp.simd private(@not_defined %1 -> %arg0 : !llvm.ptr) {
|
||||
omp.loop_nest (%arg2) : index = (%lb) to (%ub) inclusive step (%step) {
|
||||
omp.yield
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -----
|
||||
|
||||
omp.private {type = firstprivate} @_QFEp_firstprivate_i32 : i32 copy {
|
||||
^bb0(%arg0: !llvm.ptr, %arg1: !llvm.ptr):
|
||||
%0 = llvm.load %arg0 : !llvm.ptr -> i32
|
||||
llvm.store %0, %arg1 : i32, !llvm.ptr
|
||||
omp.yield(%arg1 : !llvm.ptr)
|
||||
}
|
||||
func.func @omp_simd_firstprivate(%lb : index, %ub : index, %step : index) {
|
||||
%0 = llvm.mlir.constant(1 : i64) : i64
|
||||
%1 = llvm.alloca %0 x i32 : (i64) -> !llvm.ptr
|
||||
// expected-error @below {{FIRSTPRIVATE cannot be used with SIMD}}
|
||||
omp.simd private(@_QFEp_firstprivate_i32 %1 -> %arg0 : !llvm.ptr) {
|
||||
omp.loop_nest (%arg2) : index = (%lb) to (%ub) inclusive step (%step) {
|
||||
omp.yield
|
||||
}
|
||||
}
|
||||
llvm.return
|
||||
}
|
||||
|
||||
// -----
|
||||
|
||||
// expected-error @below {{op expects alloc region to yield a value of the reduction type}}
|
||||
omp.declare_reduction @add_f32 : f32
|
||||
alloc {
|
||||
|
||||
Reference in New Issue
Block a user