diff options
author | Tom Eccles <tom.eccles@arm.com> | 2025-07-04 12:15:07 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-07-04 12:15:07 +0100 |
commit | ea5ee2e74347bcd8be236e4becd9b00eeb2a286a (patch) | |
tree | 092fc04537788729d688e14a2e2500f192e97464 | |
parent | 3099b7eb5da7605995ab89695353866189e06ac3 (diff) | |
download | llvm-ea5ee2e74347bcd8be236e4becd9b00eeb2a286a.zip llvm-ea5ee2e74347bcd8be236e4becd9b00eeb2a286a.tar.gz llvm-ea5ee2e74347bcd8be236e4becd9b00eeb2a286a.tar.bz2 |
[mlir][OpenMP] Don't allow firstprivate for simd (#146734)
This is not allowed by the openmp standard.
-rw-r--r-- | mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp | 19 | ||||
-rw-r--r-- | mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp | 3 | ||||
-rw-r--r-- | mlir/test/Dialect/OpenMP/invalid.mlir | 33 |
3 files changed, 54 insertions, 1 deletions
diff --git a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp index e94d570..ffc8478 100644 --- a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp +++ b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp @@ -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(); } diff --git a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp index ed88c19..7a517fb 100644 --- a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp @@ -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, diff --git a/mlir/test/Dialect/OpenMP/invalid.mlir b/mlir/test/Dialect/OpenMP/invalid.mlir index 060b3cd..7608ad5 100644 --- a/mlir/test/Dialect/OpenMP/invalid.mlir +++ b/mlir/test/Dialect/OpenMP/invalid.mlir @@ -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 { |