[Mlir-commits] [flang] [mlir] [OpenMP][mlir] Add DynGroupPrivateClause in omp dialect (PR #153562)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Mon Oct 27 05:36:00 PDT 2025
https://github.com/skc7 updated https://github.com/llvm/llvm-project/pull/153562
>From 4e5e4958925ef16eec2c1b2e247dfc6020c24bf7 Mon Sep 17 00:00:00 2001
From: skc7 <Krishna.Sankisa at amd.com>
Date: Thu, 14 Aug 2025 09:46:31 +0530
Subject: [PATCH 1/2] [OpenMP][mlir] Add DynGroupPrivateClause in omp dialect
---
.../mlir/Dialect/OpenMP/OpenMPClauses.td | 43 +++++
.../mlir/Dialect/OpenMP/OpenMPEnums.td | 21 ++
mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td | 5 +-
mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp | 180 +++++++++++++++++-
.../OpenMP/OpenMPToLLVMIRTranslation.cpp | 6 +
mlir/test/Dialect/OpenMP/invalid.mlir | 40 +++-
mlir/test/Dialect/OpenMP/ops.mlir | 33 +++-
7 files changed, 319 insertions(+), 9 deletions(-)
diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td
index 8e43c4284d078..f1e807c125a4a 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td
@@ -1532,4 +1532,47 @@ class OpenMP_UseDevicePtrClauseSkip<
def OpenMP_UseDevicePtrClause : OpenMP_UseDevicePtrClauseSkip<>;
+//===----------------------------------------------------------------------===//
+// V6.1 `dyn_groupprivate` clause
+//===----------------------------------------------------------------------===//
+
+class OpenMP_DynGroupprivateClauseSkip<
+ bit traits = false, bit arguments = false, bit assemblyFormat = false,
+ bit description = false, bit extraClassDeclaration = false
+ > : OpenMP_Clause<traits, arguments, assemblyFormat, description,
+ extraClassDeclaration> {
+
+ let arguments = (ins
+ OptionalAttr<DynGroupprivateModifierAttr>:$modifier_first,
+ OptionalAttr<DynGroupprivateModifierAttr>:$modifier_second,
+ Optional<AnyInteger>:$dyn_groupprivate_size
+ );
+
+ let description = [{
+ The `dyn_groupprivate` clause allows you to dynamically allocate group-private
+ memory in OpenMP parallel regions, specifically for `target` and `teams` directives.
+ This clause enables runtime-sized private memory allocation and applicable to
+ target and teams ops.
+
+ Syntax:
+ ```
+ dyn_groupprivate(modifier_first ,modifier_second : dyn_groupprivate_size)
+ ```
+
+ Example:
+ ```
+ omp.target dyn_groupprivate(strict, cgroup : %dyn_groupprivate_size : i32)
+ ```
+ }];
+
+ let optAssemblyFormat = [{
+ `dyn_groupprivate` `(`
+ custom<DynGroupprivateClause>($modifier_first, $modifier_second,
+ $dyn_groupprivate_size, type($dyn_groupprivate_size))
+ `)`
+ }];
+}
+
+def OpenMP_DynGroupprivateClause : OpenMP_DynGroupprivateClauseSkip<>;
+
#endif // OPENMP_CLAUSES
diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPEnums.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPEnums.td
index d9882cbcb5977..7e1b6eaaed977 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPEnums.td
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPEnums.td
@@ -327,4 +327,25 @@ def VariableCaptureKindAttr : OpenMP_EnumAttr<VariableCaptureKind,
let assemblyFormat = "`(` $value `)`";
}
+//===----------------------------------------------------------------------===//
+// dyn_groupprivate enum.
+//===----------------------------------------------------------------------===//
+
+def DynGroupprivateCGroup : I32EnumAttrCase<"cgroup", 0>;
+def DynGroupprivateStrict : I32EnumAttrCase<"strict", 1>;
+def DynGroupprivateFallback : I32EnumAttrCase<"fallback", 2>;
+
+def DynGroupprivateModifier : OpenMP_I32EnumAttr<
+ "DynGroupprivateModifier",
+ "dyn_groupprivate modifier", [
+ DynGroupprivateCGroup,
+ DynGroupprivateStrict,
+ DynGroupprivateFallback
+ ]>;
+
+def DynGroupprivateModifierAttr : OpenMP_EnumAttr<DynGroupprivateModifier,
+ "dyn_groupprivate_modifier"> {
+ let assemblyFormat = "`(` $value `)`";
+}
+
#endif // OPENMP_ENUMS
diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
index 377f1febf6b8f..8b9c826dfe70e 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
@@ -241,7 +241,8 @@ def TeamsOp : OpenMP_Op<"teams", traits = [
AttrSizedOperandSegments, RecursiveMemoryEffects, OutlineableOpenMPOpInterface
], clauses = [
OpenMP_AllocateClause, OpenMP_IfClause, OpenMP_NumTeamsClause,
- OpenMP_PrivateClause, OpenMP_ReductionClause, OpenMP_ThreadLimitClause
+ OpenMP_PrivateClause, OpenMP_ReductionClause, OpenMP_ThreadLimitClause,
+ OpenMP_DynGroupprivateClause
], singleRegion = true> {
let summary = "teams construct";
let description = [{
@@ -1456,7 +1457,7 @@ def TargetOp : OpenMP_Op<"target", traits = [
OpenMP_DeviceClause, OpenMP_HasDeviceAddrClause, OpenMP_HostEvalClause,
OpenMP_IfClause, OpenMP_InReductionClause, OpenMP_IsDevicePtrClause,
OpenMP_MapClauseSkip<assemblyFormat = true>, OpenMP_NowaitClause,
- OpenMP_PrivateClause, OpenMP_ThreadLimitClause
+ OpenMP_PrivateClause, OpenMP_ThreadLimitClause, OpenMP_DynGroupprivateClause
], singleRegion = true> {
let summary = "target construct";
let description = [{
diff --git a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
index 1b069c62a8be9..c0f2c1ca41e23 100644
--- a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
+++ b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
@@ -797,6 +797,167 @@ static void printNumTasksClause(OpAsmPrinter &p, Operation *op,
p, op, numTasksMod, numTasks, numTasksType, &stringifyClauseNumTasksType);
}
+//===----------------------------------------------------------------------===//
+// Parser, printer and verify for dyn_groupprivate Clause
+//===----------------------------------------------------------------------===//
+
+static LogicalResult verifyDynGroupprivateClause(
+ Operation *op, DynGroupprivateModifierAttr modifierFirst,
+ DynGroupprivateModifierAttr modifierSecond, Value dynGroupprivateSize) {
+
+ // Helper to get modifier name as string
+ auto getModifierName = [](DynGroupprivateModifier mod) -> StringRef {
+ switch (mod) {
+ case DynGroupprivateModifier::strict:
+ return "strict";
+ case DynGroupprivateModifier::cgroup:
+ return "cgroup";
+ case DynGroupprivateModifier::fallback:
+ return "fallback";
+ }
+ return "unknown";
+ };
+
+ // Check for duplicate modifiers
+ if (modifierFirst && modifierSecond &&
+ modifierFirst.getValue() == modifierSecond.getValue()) {
+ return op->emitOpError("duplicate dyn_groupprivate modifier '")
+ << getModifierName(modifierFirst.getValue()) << "'";
+ }
+
+ // Check for incompatible modifier combinations
+ if (modifierFirst && modifierSecond) {
+ auto m1 = modifierFirst.getValue();
+ auto m2 = modifierSecond.getValue();
+
+ // strict and fallback are incompatible
+ if ((m1 == DynGroupprivateModifier::strict &&
+ m2 == DynGroupprivateModifier::fallback) ||
+ (m1 == DynGroupprivateModifier::fallback &&
+ m2 == DynGroupprivateModifier::strict)) {
+ return op->emitOpError("incompatible dyn_groupprivate modifiers: '")
+ << getModifierName(m1) << "' and '" << getModifierName(m2)
+ << "' cannot be used together";
+ }
+ }
+
+ // Verify the size
+ if (dynGroupprivateSize) {
+ Type size_type = dynGroupprivateSize.getType();
+ // Check if the size type is an integer type
+ if (!size_type.isIntOrIndex()) {
+ return op->emitOpError(
+ "dyn_groupprivate size must be an integer type, got ")
+ << size_type;
+ }
+ }
+
+ return success();
+}
+
+static ParseResult parseDynGroupprivateClause(
+ OpAsmParser &parser, DynGroupprivateModifierAttr &modifierFirst,
+ DynGroupprivateModifierAttr &modifierSecond,
+ std::optional<OpAsmParser::UnresolvedOperand> &dynGroupprivateSize,
+ Type &size_type) {
+
+ bool hasModifiers = false;
+
+ // Parse first modifier if present
+ if (succeeded(parser.parseOptionalKeyword("strict"))) {
+ modifierFirst = DynGroupprivateModifierAttr::get(
+ parser.getContext(), DynGroupprivateModifier::strict);
+ hasModifiers = true;
+ } else if (succeeded(parser.parseOptionalKeyword("cgroup"))) {
+ modifierFirst = DynGroupprivateModifierAttr::get(
+ parser.getContext(), DynGroupprivateModifier::cgroup);
+ hasModifiers = true;
+ } else if (succeeded(parser.parseOptionalKeyword("fallback"))) {
+ modifierFirst = DynGroupprivateModifierAttr::get(
+ parser.getContext(), DynGroupprivateModifier::fallback);
+ hasModifiers = true;
+ }
+
+ // If first modifier found, check for comma and second modifier
+ if (hasModifiers && succeeded(parser.parseOptionalComma())) {
+ if (succeeded(parser.parseOptionalKeyword("strict"))) {
+ modifierSecond = DynGroupprivateModifierAttr::get(
+ parser.getContext(), DynGroupprivateModifier::strict);
+ } else if (succeeded(parser.parseOptionalKeyword("cgroup"))) {
+ modifierSecond = DynGroupprivateModifierAttr::get(
+ parser.getContext(), DynGroupprivateModifier::cgroup);
+ } else if (succeeded(parser.parseOptionalKeyword("fallback"))) {
+ modifierSecond = DynGroupprivateModifierAttr::get(
+ parser.getContext(), DynGroupprivateModifier::fallback);
+ } else {
+ return parser.emitError(parser.getCurrentLocation(),
+ "expected modifier after comma");
+ }
+ }
+
+ // Parse colon and size if modifiers were present, or just try to parse
+ // operand
+ if (hasModifiers) {
+ // Modifiers present, expect colon
+ if (failed(parser.parseColon())) {
+ return parser.emitError(parser.getCurrentLocation(),
+ "expected ':' after modifiers");
+ }
+
+ // Parse operand and type
+ OpAsmParser::UnresolvedOperand operand;
+ if (succeeded(parser.parseOperand(operand))) {
+ dynGroupprivateSize = operand;
+ if (failed(parser.parseColon()) || failed(parser.parseType(size_type))) {
+ return parser.emitError(parser.getCurrentLocation(),
+ "expected ':' and type after size operand");
+ }
+ }
+ } else {
+ // No modifiers, try to parse operand directly
+ OpAsmParser::UnresolvedOperand operand;
+ if (succeeded(parser.parseOperand(operand))) {
+ dynGroupprivateSize = operand;
+ if (failed(parser.parseColon()) || failed(parser.parseType(size_type))) {
+ return parser.emitError(parser.getCurrentLocation(),
+ "expected ':' and type after size operand");
+ }
+ } else {
+ return parser.emitError(parser.getCurrentLocation(),
+ "expected dyn_groupprivate_size operand");
+ }
+ }
+
+ return success();
+}
+
+static void
+printDynGroupprivateClause(OpAsmPrinter &printer, Operation *op,
+ DynGroupprivateModifierAttr modifierFirst,
+ DynGroupprivateModifierAttr modifierSecond,
+ Value dynGroupprivateSize, Type size_type) {
+
+ bool needsComma = false;
+
+ if (modifierFirst) {
+ printer << modifierFirst.getValue();
+ needsComma = true;
+ }
+
+ if (modifierSecond) {
+ if (needsComma)
+ printer << ", ";
+ printer << modifierSecond.getValue();
+ needsComma = true;
+ }
+
+ if (dynGroupprivateSize) {
+ if (needsComma)
+ printer << " : ";
+ printer << dynGroupprivateSize << " : " << size_type;
+ }
+}
+
//===----------------------------------------------------------------------===//
// Parsers for operations including clauses that define entry block arguments.
//===----------------------------------------------------------------------===//
@@ -2205,6 +2366,8 @@ void TargetOp::build(OpBuilder &builder, OperationState &state,
clauses.mapVars, clauses.nowait, clauses.privateVars,
makeArrayAttr(ctx, clauses.privateSyms),
clauses.privateNeedsBarrier, clauses.threadLimit,
+ clauses.modifierFirst, clauses.modifierSecond,
+ clauses.dynGroupprivateSize,
/*private_maps=*/nullptr);
}
@@ -2219,6 +2382,12 @@ LogicalResult TargetOp::verify() {
if (failed(verifyMapClause(*this, getMapVars())))
return failure();
+ // check dyn_groupprivate clause restrictions
+ if (failed(verifyDynGroupprivateClause(*this, getModifierFirstAttr(),
+ getModifierSecondAttr(),
+ getDynGroupprivateSize())))
+ return failure();
+
return verifyPrivateVarsMapping(*this);
}
@@ -2624,8 +2793,9 @@ void TeamsOp::build(OpBuilder &builder, OperationState &state,
/*private_needs_barrier=*/nullptr, clauses.reductionMod,
clauses.reductionVars,
makeDenseBoolArrayAttr(ctx, clauses.reductionByref),
- makeArrayAttr(ctx, clauses.reductionSyms),
- clauses.threadLimit);
+ makeArrayAttr(ctx, clauses.reductionSyms), clauses.threadLimit,
+ clauses.modifierFirst, clauses.modifierSecond,
+ clauses.dynGroupprivateSize);
}
LogicalResult TeamsOp::verify() {
@@ -2656,6 +2826,12 @@ LogicalResult TeamsOp::verify() {
return emitError(
"expected equal sizes for allocate and allocator variables");
+ // check dyn_groupprivate clause restrictions
+ if (failed(verifyDynGroupprivateClause(op, getModifierFirstAttr(),
+ getModifierSecondAttr(),
+ getDynGroupprivateSize())))
+ return failure();
+
return verifyReductionVarList(*this, getReductionSyms(), getReductionVars(),
getReductionByref());
}
diff --git a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
index f28454075f1d3..a3950bf1fc578 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
@@ -378,6 +378,10 @@ static LogicalResult checkImplementationStatus(Operation &op) {
if (op.getUntied())
result = todo("untied");
};
+ auto checkDynGroupprivate = [&todo](auto op, LogicalResult &result) {
+ if (op.getDynGroupprivateSize())
+ result = todo("dyn_groupprivate");
+ };
LogicalResult result = success();
llvm::TypeSwitch<Operation &>(op)
@@ -403,6 +407,7 @@ static LogicalResult checkImplementationStatus(Operation &op) {
.Case([&](omp::TeamsOp op) {
checkAllocate(op, result);
checkPrivate(op, result);
+ checkDynGroupprivate(op, result);
})
.Case([&](omp::TaskOp op) {
checkAllocate(op, result);
@@ -445,6 +450,7 @@ static LogicalResult checkImplementationStatus(Operation &op) {
checkDevice(op, result);
checkInReduction(op, result);
checkIsDevicePtr(op, result);
+ checkDynGroupprivate(op, result);
})
.Default([](Operation &) {
// Assume all clauses for an operation can be translated unless they are
diff --git a/mlir/test/Dialect/OpenMP/invalid.mlir b/mlir/test/Dialect/OpenMP/invalid.mlir
index af24d969064ab..0d073263e9143 100644
--- a/mlir/test/Dialect/OpenMP/invalid.mlir
+++ b/mlir/test/Dialect/OpenMP/invalid.mlir
@@ -1438,7 +1438,7 @@ func.func @omp_teams_allocate(%data_var : memref<i32>) {
// expected-error @below {{expected equal sizes for allocate and allocator variables}}
"omp.teams" (%data_var) ({
omp.terminator
- }) {operandSegmentSizes = array<i32: 1,0,0,0,0,0,0,0>} : (memref<i32>) -> ()
+ }) {operandSegmentSizes = array<i32: 1,0,0,0,0,0,0,0,0>} : (memref<i32>) -> ()
omp.terminator
}
return
@@ -1451,7 +1451,7 @@ func.func @omp_teams_num_teams1(%lb : i32) {
// expected-error @below {{expected num_teams upper bound to be defined if the lower bound is defined}}
"omp.teams" (%lb) ({
omp.terminator
- }) {operandSegmentSizes = array<i32: 0,0,0,1,0,0,0,0>} : (i32) -> ()
+ }) {operandSegmentSizes = array<i32: 0,0,0,1,0,0,0,0,0>} : (i32) -> ()
omp.terminator
}
return
@@ -1472,6 +1472,26 @@ func.func @omp_teams_num_teams2(%lb : i32, %ub : i16) {
// -----
+func.func @test_teams_dyn_groupprivate_errors_1(%dyn_size: i32) {
+ // expected-error @below {{duplicate dyn_groupprivate modifier 'strict'}}
+ omp.teams dyn_groupprivate(strict, strict : %dyn_size : i32) {
+ omp.terminator
+ }
+ return
+}
+
+// -----
+
+func.func @test_teams_dyn_groupprivate_errors_2(%dyn_size: i32) {
+ // expected-error @below {{incompatible dyn_groupprivate modifiers: 'strict' and 'fallback' cannot be used together}}
+ omp.teams dyn_groupprivate(strict, fallback : %dyn_size : i32) {
+ omp.terminator
+ }
+ return
+}
+
+// -----
+
func.func @omp_sections(%data_var : memref<i32>) -> () {
// expected-error @below {{expected equal sizes for allocate and allocator variables}}
"omp.sections" (%data_var) ({
@@ -2458,12 +2478,26 @@ func.func @omp_target_depend(%data_var: memref<i32>) {
// expected-error @below {{op expected as many depend values as depend variables}}
"omp.target"(%data_var) ({
"omp.terminator"() : () -> ()
- }) {depend_kinds = [], operandSegmentSizes = array<i32: 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0>} : (memref<i32>) -> ()
+ }) {depend_kinds = [], operandSegmentSizes = array<i32: 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0>} : (memref<i32>) -> ()
"func.return"() : () -> ()
}
// -----
+func.func @test_target_dyn_groupprivate_errors(%dyn_size: i32) {
+ // expected-error @below {{duplicate dyn_groupprivate modifier 'strict'}}
+ omp.target dyn_groupprivate(strict, strict : %dyn_size : i32) {
+ omp.terminator
+ }
+ // expected-error @below {{incompatible dyn_groupprivate modifiers: 'strict' and 'fallback' cannot be used together}}
+ omp.target dyn_groupprivate(strict, fallback : %dyn_size : i32) {
+ omp.terminator
+ }
+ return
+}
+
+// -----
+
func.func @omp_distribute_schedule(%chunk_size : i32, %lb : i32, %ub : i32, %step : i32) -> () {
// expected-error @below {{op chunk size set without dist_schedule_static being present}}
"omp.distribute"(%chunk_size) <{operandSegmentSizes = array<i32: 0, 0, 1, 0>}> ({
diff --git a/mlir/test/Dialect/OpenMP/ops.mlir b/mlir/test/Dialect/OpenMP/ops.mlir
index ac29e20907b55..52fadf1416e25 100644
--- a/mlir/test/Dialect/OpenMP/ops.mlir
+++ b/mlir/test/Dialect/OpenMP/ops.mlir
@@ -823,7 +823,7 @@ func.func @omp_target(%if_cond : i1, %device : si32, %num_threads : i32, %devic
"omp.target"(%device, %if_cond, %num_threads) ({
// CHECK: omp.terminator
omp.terminator
- }) {nowait, operandSegmentSizes = array<i32: 0,0,0,1,0,0,1,0,0,0,0,1>} : ( si32, i1, i32 ) -> ()
+ }) {nowait, operandSegmentSizes = array<i32: 0,0,0,1,0,0,1,0,0,0,0,1,0>} : ( si32, i1, i32 ) -> ()
// Test with optional map clause.
// CHECK: %[[MAP_A:.*]] = omp.map.info var_ptr(%[[VAL_1:.*]] : memref<?xi32>, tensor<?xi32>) map_clauses(always, to) capture(ByRef) -> memref<?xi32> {name = ""}
@@ -1076,7 +1076,7 @@ func.func @parallel_wsloop_reduction(%lb : index, %ub : index, %step : index) {
// CHECK-LABEL: omp_teams
func.func @omp_teams(%lb : i32, %ub : i32, %if_cond : i1, %num_threads : i32,
- %data_var : memref<i32>) -> () {
+ %dyn_size : i32, %data_var : memref<i32>) -> () {
// Test nesting inside of omp.target
omp.target {
// CHECK: omp.teams
@@ -1146,6 +1146,13 @@ func.func @omp_teams(%lb : i32, %ub : i32, %if_cond : i1, %num_threads : i32,
// CHECK: omp.terminator
omp.terminator
}
+
+ // Test dyn_groupprivate
+ // CHECK: omp.teams dyn_groupprivate(cgroup, strict : %{{.+}} : i32)
+ omp.teams dyn_groupprivate(cgroup, strict : %dyn_size : i32) {
+ // CHECK: omp.terminator
+ omp.terminator
+ }
return
}
@@ -2207,6 +2214,28 @@ func.func @omp_target_depend(%arg0: memref<i32>, %arg1: memref<i32>) {
return
}
+// CHECK-LABEL: @omp_target_dyn_groupprivate
+func.func @omp_target_dyn_groupprivate(%dyn_size: i32, %large_size: i64) {
+ // CHECK: omp.target dyn_groupprivate(strict, cgroup : %{{.*}} : i32)
+ omp.target dyn_groupprivate(strict, cgroup : %dyn_size : i32) {
+ // CHECK: omp.terminator
+ omp.terminator
+ }
+ // CHECK: omp.target dyn_groupprivate(cgroup : %{{.*}} : i64)
+ omp.target dyn_groupprivate(cgroup : %large_size : i64) {
+ omp.terminator
+ }
+ // CHECK: omp.target dyn_groupprivate(fallback, cgroup : %{{.*}} : i32)
+ omp.target dyn_groupprivate(fallback, cgroup : %dyn_size : i32) {
+ omp.terminator
+ }
+ // CHECK: omp.target dyn_groupprivate(%{{.*}} : i64)
+ omp.target dyn_groupprivate(%large_size : i64) {
+ omp.terminator
+ }
+ return
+}
+
func.func @omp_threadprivate() {
%0 = arith.constant 1 : i32
%1 = arith.constant 2 : i32
>From 5dca11e7f54ea3b781a72b16012fbcee4dabfc1b Mon Sep 17 00:00:00 2001
From: skc7 <Krishna.Sankisa at amd.com>
Date: Mon, 27 Oct 2025 18:04:20 +0530
Subject: [PATCH 2/2] Update to use fallback modifiers
---
.../Optimizer/OpenMP/LowerWorkdistribute.cpp | 13 +-
.../mlir/Dialect/OpenMP/OpenMPClauses.td | 10 +-
.../mlir/Dialect/OpenMP/OpenMPEnums.td | 37 ++--
mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp | 189 +++++++-----------
mlir/test/Dialect/OpenMP/invalid.mlir | 54 +++--
mlir/test/Dialect/OpenMP/ops.mlir | 22 +-
6 files changed, 164 insertions(+), 161 deletions(-)
diff --git a/flang/lib/Optimizer/OpenMP/LowerWorkdistribute.cpp b/flang/lib/Optimizer/OpenMP/LowerWorkdistribute.cpp
index 7b61539984232..2ca75a6da78ca 100644
--- a/flang/lib/Optimizer/OpenMP/LowerWorkdistribute.cpp
+++ b/flang/lib/Optimizer/OpenMP/LowerWorkdistribute.cpp
@@ -766,7 +766,9 @@ FailureOr<omp::TargetOp> splitTargetData(omp::TargetOp targetOp,
targetOp.getInReductionSymsAttr(), targetOp.getIsDevicePtrVars(),
innerMapInfos, targetOp.getNowaitAttr(), targetOp.getPrivateVars(),
targetOp.getPrivateSymsAttr(), targetOp.getPrivateNeedsBarrierAttr(),
- targetOp.getThreadLimit(), targetOp.getPrivateMapsAttr());
+ targetOp.getThreadLimit(), targetOp.getAccessGroupAttr(),
+ targetOp.getFallbackAttr(), targetOp.getDynGroupprivateSize(),
+ targetOp.getPrivateMapsAttr());
rewriter.inlineRegionBefore(targetOp.getRegion(), newTargetOp.getRegion(),
newTargetOp.getRegion().begin());
rewriter.replaceOp(targetOp, targetDataOp);
@@ -1486,7 +1488,8 @@ genPreTargetOp(omp::TargetOp targetOp, SmallVector<Value> &preMapOperands,
targetOp.getIsDevicePtrVars(), preMapOperands, targetOp.getNowaitAttr(),
targetOp.getPrivateVars(), targetOp.getPrivateSymsAttr(),
targetOp.getPrivateNeedsBarrierAttr(), targetOp.getThreadLimit(),
- targetOp.getPrivateMapsAttr());
+ targetOp.getAccessGroupAttr(), targetOp.getFallbackAttr(),
+ targetOp.getDynGroupprivateSize(), targetOp.getPrivateMapsAttr());
auto *preTargetBlock = rewriter.createBlock(
&preTargetOp.getRegion(), preTargetOp.getRegion().begin(), {}, {});
IRMapping preMapping;
@@ -1576,7 +1579,8 @@ genIsolatedTargetOp(omp::TargetOp targetOp, SmallVector<Value> &postMapOperands,
targetOp.getIsDevicePtrVars(), postMapOperands, targetOp.getNowaitAttr(),
targetOp.getPrivateVars(), targetOp.getPrivateSymsAttr(),
targetOp.getPrivateNeedsBarrierAttr(), targetOp.getThreadLimit(),
- targetOp.getPrivateMapsAttr());
+ targetOp.getAccessGroupAttr(), targetOp.getFallbackAttr(),
+ targetOp.getDynGroupprivateSize(), targetOp.getPrivateMapsAttr());
auto *isolatedTargetBlock =
rewriter.createBlock(&isolatedTargetOp.getRegion(),
isolatedTargetOp.getRegion().begin(), {}, {});
@@ -1656,7 +1660,8 @@ static omp::TargetOp genPostTargetOp(omp::TargetOp targetOp,
targetOp.getIsDevicePtrVars(), postMapOperands, targetOp.getNowaitAttr(),
targetOp.getPrivateVars(), targetOp.getPrivateSymsAttr(),
targetOp.getPrivateNeedsBarrierAttr(), targetOp.getThreadLimit(),
- targetOp.getPrivateMapsAttr());
+ targetOp.getAccessGroupAttr(), targetOp.getFallbackAttr(),
+ targetOp.getDynGroupprivateSize(), targetOp.getPrivateMapsAttr());
// Create the block for postTargetOp
auto *postTargetBlock = rewriter.createBlock(
&postTargetOp.getRegion(), postTargetOp.getRegion().begin(), {}, {});
diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td
index f1e807c125a4a..9ad479b782428 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td
@@ -1543,8 +1543,8 @@ class OpenMP_DynGroupprivateClauseSkip<
extraClassDeclaration> {
let arguments = (ins
- OptionalAttr<DynGroupprivateModifierAttr>:$modifier_first,
- OptionalAttr<DynGroupprivateModifierAttr>:$modifier_second,
+ OptionalAttr<AccessGroupModifierAttr>:$accessGroup,
+ OptionalAttr<FallbackModifierAttr>:$fallback,
Optional<AnyInteger>:$dyn_groupprivate_size
);
@@ -1556,18 +1556,18 @@ class OpenMP_DynGroupprivateClauseSkip<
Syntax:
```
- dyn_groupprivate(modifier_first ,modifier_second : dyn_groupprivate_size)
+ dyn_groupprivate(cgroup, fallback(abort), %size)
```
Example:
```
- omp.target dyn_groupprivate(strict, cgroup : %dyn_groupprivate_size : i32)
+ omp.target dyn_groupprivate(cgroup, fallback(default_mem), %size : i32)
```
}];
let optAssemblyFormat = [{
`dyn_groupprivate` `(`
- custom<DynGroupprivateClause>($modifier_first, $modifier_second,
+ custom<DynGroupprivateClause>($accessGroup, $fallback,
$dyn_groupprivate_size, type($dyn_groupprivate_size))
`)`
}];
diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPEnums.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPEnums.td
index 7e1b6eaaed977..430f1b168c3cf 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPEnums.td
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPEnums.td
@@ -328,23 +328,36 @@ def VariableCaptureKindAttr : OpenMP_EnumAttr<VariableCaptureKind,
}
//===----------------------------------------------------------------------===//
-// dyn_groupprivate enum.
+// dyn_groupprivate enums.
//===----------------------------------------------------------------------===//
-def DynGroupprivateCGroup : I32EnumAttrCase<"cgroup", 0>;
-def DynGroupprivateStrict : I32EnumAttrCase<"strict", 1>;
-def DynGroupprivateFallback : I32EnumAttrCase<"fallback", 2>;
+def AccessGroupCGroup : I32EnumAttrCase<"cgroup", 0>;
-def DynGroupprivateModifier : OpenMP_I32EnumAttr<
- "DynGroupprivateModifier",
- "dyn_groupprivate modifier", [
- DynGroupprivateCGroup,
- DynGroupprivateStrict,
- DynGroupprivateFallback
+def AccessGroupModifier : OpenMP_I32EnumAttr<
+ "AccessGroupModifier",
+ "access group modifier", [
+ AccessGroupCGroup
]>;
-def DynGroupprivateModifierAttr : OpenMP_EnumAttr<DynGroupprivateModifier,
- "dyn_groupprivate_modifier"> {
+def AccessGroupModifierAttr : OpenMP_EnumAttr<AccessGroupModifier,
+ "access_group_modifier"> {
+ let assemblyFormat = "`(` $value `)`";
+}
+
+def FallbackAbort : I32EnumAttrCase<"abort", 0>;
+def FallbackNull : I32EnumAttrCase<"null", 1>;
+def FallbackDefaultMem : I32EnumAttrCase<"default_mem", 2>;
+
+def FallbackModifier : OpenMP_I32EnumAttr<
+ "FallbackModifier",
+ "fallback modifier", [
+ FallbackAbort,
+ FallbackNull,
+ FallbackDefaultMem
+ ]>;
+
+def FallbackModifierAttr : OpenMP_EnumAttr<FallbackModifier,
+ "fallback_modifier"> {
let assemblyFormat = "`(` $value `)`";
}
diff --git a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
index c0f2c1ca41e23..731df9d9e553d 100644
--- a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
+++ b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
@@ -802,44 +802,8 @@ static void printNumTasksClause(OpAsmPrinter &p, Operation *op,
//===----------------------------------------------------------------------===//
static LogicalResult verifyDynGroupprivateClause(
- Operation *op, DynGroupprivateModifierAttr modifierFirst,
- DynGroupprivateModifierAttr modifierSecond, Value dynGroupprivateSize) {
-
- // Helper to get modifier name as string
- auto getModifierName = [](DynGroupprivateModifier mod) -> StringRef {
- switch (mod) {
- case DynGroupprivateModifier::strict:
- return "strict";
- case DynGroupprivateModifier::cgroup:
- return "cgroup";
- case DynGroupprivateModifier::fallback:
- return "fallback";
- }
- return "unknown";
- };
-
- // Check for duplicate modifiers
- if (modifierFirst && modifierSecond &&
- modifierFirst.getValue() == modifierSecond.getValue()) {
- return op->emitOpError("duplicate dyn_groupprivate modifier '")
- << getModifierName(modifierFirst.getValue()) << "'";
- }
-
- // Check for incompatible modifier combinations
- if (modifierFirst && modifierSecond) {
- auto m1 = modifierFirst.getValue();
- auto m2 = modifierSecond.getValue();
-
- // strict and fallback are incompatible
- if ((m1 == DynGroupprivateModifier::strict &&
- m2 == DynGroupprivateModifier::fallback) ||
- (m1 == DynGroupprivateModifier::fallback &&
- m2 == DynGroupprivateModifier::strict)) {
- return op->emitOpError("incompatible dyn_groupprivate modifiers: '")
- << getModifierName(m1) << "' and '" << getModifierName(m2)
- << "' cannot be used together";
- }
- }
+ Operation *op, AccessGroupModifierAttr modifierFirst,
+ FallbackModifierAttr modifierSecond, Value dynGroupprivateSize) {
// Verify the size
if (dynGroupprivateSize) {
@@ -856,86 +820,83 @@ static LogicalResult verifyDynGroupprivateClause(
}
static ParseResult parseDynGroupprivateClause(
- OpAsmParser &parser, DynGroupprivateModifierAttr &modifierFirst,
- DynGroupprivateModifierAttr &modifierSecond,
+ OpAsmParser &parser, AccessGroupModifierAttr &accessGroupAttr,
+ FallbackModifierAttr &fallbackAttr,
std::optional<OpAsmParser::UnresolvedOperand> &dynGroupprivateSize,
- Type &size_type) {
-
- bool hasModifiers = false;
-
- // Parse first modifier if present
- if (succeeded(parser.parseOptionalKeyword("strict"))) {
- modifierFirst = DynGroupprivateModifierAttr::get(
- parser.getContext(), DynGroupprivateModifier::strict);
- hasModifiers = true;
- } else if (succeeded(parser.parseOptionalKeyword("cgroup"))) {
- modifierFirst = DynGroupprivateModifierAttr::get(
- parser.getContext(), DynGroupprivateModifier::cgroup);
- hasModifiers = true;
- } else if (succeeded(parser.parseOptionalKeyword("fallback"))) {
- modifierFirst = DynGroupprivateModifierAttr::get(
- parser.getContext(), DynGroupprivateModifier::fallback);
- hasModifiers = true;
- }
+ Type &sizeType) {
- // If first modifier found, check for comma and second modifier
- if (hasModifiers && succeeded(parser.parseOptionalComma())) {
- if (succeeded(parser.parseOptionalKeyword("strict"))) {
- modifierSecond = DynGroupprivateModifierAttr::get(
- parser.getContext(), DynGroupprivateModifier::strict);
- } else if (succeeded(parser.parseOptionalKeyword("cgroup"))) {
- modifierSecond = DynGroupprivateModifierAttr::get(
- parser.getContext(), DynGroupprivateModifier::cgroup);
- } else if (succeeded(parser.parseOptionalKeyword("fallback"))) {
- modifierSecond = DynGroupprivateModifierAttr::get(
- parser.getContext(), DynGroupprivateModifier::fallback);
- } else {
- return parser.emitError(parser.getCurrentLocation(),
- "expected modifier after comma");
- }
- }
+ bool parsedAccessGroup = false;
+ bool parsedFallback = false;
- // Parse colon and size if modifiers were present, or just try to parse
- // operand
- if (hasModifiers) {
- // Modifiers present, expect colon
- if (failed(parser.parseColon())) {
- return parser.emitError(parser.getCurrentLocation(),
- "expected ':' after modifiers");
- }
-
- // Parse operand and type
- OpAsmParser::UnresolvedOperand operand;
- if (succeeded(parser.parseOperand(operand))) {
- dynGroupprivateSize = operand;
- if (failed(parser.parseColon()) || failed(parser.parseType(size_type))) {
+ // Parse modifiers separated by commas
+ while (true) {
+ // parse AccessGroupModifier
+ if (succeeded(parser.parseOptionalKeyword("cgroup"))) {
+ if (parsedAccessGroup)
return parser.emitError(parser.getCurrentLocation(),
- "expected ':' and type after size operand");
- }
+ "duplicate access group modifier");
+ accessGroupAttr = AccessGroupModifierAttr::get(
+ parser.getContext(), AccessGroupModifier::cgroup);
+ parsedAccessGroup = true;
}
- } else {
- // No modifiers, try to parse operand directly
- OpAsmParser::UnresolvedOperand operand;
- if (succeeded(parser.parseOperand(operand))) {
- dynGroupprivateSize = operand;
- if (failed(parser.parseColon()) || failed(parser.parseType(size_type))) {
+ // parse FallbackModifier
+ else if (succeeded(parser.parseOptionalKeyword("fallback"))) {
+ if (parsedFallback)
return parser.emitError(parser.getCurrentLocation(),
- "expected ':' and type after size operand");
- }
- } else {
+ "duplicate fallback modifier");
+ if (parser.parseLParen())
+ return parser.emitError(parser.getCurrentLocation(),
+ "expected '(' after 'fallback'");
+ llvm::StringRef fbKind;
+ if (parser.parseKeyword(&fbKind))
+ return parser.emitError(
+ parser.getCurrentLocation(),
+ "expected fallback modifier (abort/null/default_mem)");
+ std::optional<FallbackModifier> fbEnum;
+ if (fbKind == "abort")
+ fbEnum = FallbackModifier::abort;
+ else if (fbKind == "null")
+ fbEnum = FallbackModifier::null;
+ else if (fbKind == "default_mem")
+ fbEnum = FallbackModifier::default_mem;
+ else
+ return parser.emitError(parser.getCurrentLocation(),
+ "invalid fallback modifier '" + fbKind + "'");
+ fallbackAttr = FallbackModifierAttr::get(parser.getContext(), *fbEnum);
+ if (parser.parseRParen())
+ return parser.emitError(parser.getCurrentLocation(),
+ "expected ')' after fallback modifier");
+ parsedFallback = true;
+ } else
+ break;
+
+ // Consume optional comma between modifiers
+ (void)parser.parseOptionalComma();
+ }
+
+ // Consume comma after modifiers, if both modifiers are present
+ (void)parser.parseOptionalComma();
+
+ OpAsmParser::UnresolvedOperand operand;
+ if (succeeded(parser.parseOperand(operand))) {
+ dynGroupprivateSize = operand;
+ if (failed(parser.parseColon()) || failed(parser.parseType(sizeType))) {
return parser.emitError(parser.getCurrentLocation(),
- "expected dyn_groupprivate_size operand");
+ "expected ':' and type after size operand");
}
+ } else {
+ return parser.emitError(parser.getCurrentLocation(),
+ "expected dyn_groupprivate_size operand");
}
return success();
}
-static void
-printDynGroupprivateClause(OpAsmPrinter &printer, Operation *op,
- DynGroupprivateModifierAttr modifierFirst,
- DynGroupprivateModifierAttr modifierSecond,
- Value dynGroupprivateSize, Type size_type) {
+static void printDynGroupprivateClause(OpAsmPrinter &printer, Operation *op,
+ AccessGroupModifierAttr modifierFirst,
+ FallbackModifierAttr modifierSecond,
+ Value dynGroupprivateSize,
+ Type sizeType) {
bool needsComma = false;
@@ -947,14 +908,16 @@ printDynGroupprivateClause(OpAsmPrinter &printer, Operation *op,
if (modifierSecond) {
if (needsComma)
printer << ", ";
+ printer << "fallback(";
printer << modifierSecond.getValue();
+ printer << ")";
needsComma = true;
}
if (dynGroupprivateSize) {
if (needsComma)
- printer << " : ";
- printer << dynGroupprivateSize << " : " << size_type;
+ printer << ", ";
+ printer << dynGroupprivateSize << " : " << sizeType;
}
}
@@ -2366,7 +2329,7 @@ void TargetOp::build(OpBuilder &builder, OperationState &state,
clauses.mapVars, clauses.nowait, clauses.privateVars,
makeArrayAttr(ctx, clauses.privateSyms),
clauses.privateNeedsBarrier, clauses.threadLimit,
- clauses.modifierFirst, clauses.modifierSecond,
+ clauses.accessGroup, clauses.fallback,
clauses.dynGroupprivateSize,
/*private_maps=*/nullptr);
}
@@ -2383,8 +2346,8 @@ LogicalResult TargetOp::verify() {
return failure();
// check dyn_groupprivate clause restrictions
- if (failed(verifyDynGroupprivateClause(*this, getModifierFirstAttr(),
- getModifierSecondAttr(),
+ if (failed(verifyDynGroupprivateClause(*this, getAccessGroupAttr(),
+ getFallbackAttr(),
getDynGroupprivateSize())))
return failure();
@@ -2794,7 +2757,7 @@ void TeamsOp::build(OpBuilder &builder, OperationState &state,
clauses.reductionVars,
makeDenseBoolArrayAttr(ctx, clauses.reductionByref),
makeArrayAttr(ctx, clauses.reductionSyms), clauses.threadLimit,
- clauses.modifierFirst, clauses.modifierSecond,
+ clauses.accessGroup, clauses.fallback,
clauses.dynGroupprivateSize);
}
@@ -2827,8 +2790,8 @@ LogicalResult TeamsOp::verify() {
"expected equal sizes for allocate and allocator variables");
// check dyn_groupprivate clause restrictions
- if (failed(verifyDynGroupprivateClause(op, getModifierFirstAttr(),
- getModifierSecondAttr(),
+ if (failed(verifyDynGroupprivateClause(op, getAccessGroupAttr(),
+ getFallbackAttr(),
getDynGroupprivateSize())))
return failure();
diff --git a/mlir/test/Dialect/OpenMP/invalid.mlir b/mlir/test/Dialect/OpenMP/invalid.mlir
index 0d073263e9143..57d22f17f94b0 100644
--- a/mlir/test/Dialect/OpenMP/invalid.mlir
+++ b/mlir/test/Dialect/OpenMP/invalid.mlir
@@ -1473,8 +1473,8 @@ func.func @omp_teams_num_teams2(%lb : i32, %ub : i16) {
// -----
func.func @test_teams_dyn_groupprivate_errors_1(%dyn_size: i32) {
- // expected-error @below {{duplicate dyn_groupprivate modifier 'strict'}}
- omp.teams dyn_groupprivate(strict, strict : %dyn_size : i32) {
+ // expected-error @below {{duplicate access group modifier}}
+ omp.teams dyn_groupprivate(cgroup, cgroup, %dyn_size : i32) {
omp.terminator
}
return
@@ -1483,8 +1483,40 @@ func.func @test_teams_dyn_groupprivate_errors_1(%dyn_size: i32) {
// -----
func.func @test_teams_dyn_groupprivate_errors_2(%dyn_size: i32) {
- // expected-error @below {{incompatible dyn_groupprivate modifiers: 'strict' and 'fallback' cannot be used together}}
- omp.teams dyn_groupprivate(strict, fallback : %dyn_size : i32) {
+ // expected-error @below {{duplicate fallback modifier}}
+ omp.teams dyn_groupprivate(fallback(null), fallback(abort), %dyn_size : i32) {
+ omp.terminator
+ }
+ return
+}
+
+// -----
+
+func.func @test_teams_dyn_groupprivate_errors_3(%dyn_size: i32) {
+ // expected-error @below {{invalid fallback modifier 'no'}}
+ omp.teams dyn_groupprivate(fallback(no), %dyn_size : i32) {
+ omp.terminator
+ }
+ return
+}
+
+// -----
+
+func.func @test_teams_dyn_groupprivate_errors_4(%dyn_size: i32) {
+ // expected-error @below {{custom op 'omp.teams' expected dyn_groupprivate_size operand}}
+ // expected-error @below {{expected SSA operand}}
+ omp.teams dyn_groupprivate(fallback(null)) {
+ omp.terminator
+ }
+ return
+}
+
+// -----
+
+func.func @test_teams_dyn_groupprivate_errors_5() {
+ // expected-error @below {{expected dyn_groupprivate_size operand}}
+ // expected-error @below {{expected SSA operand}}
+ omp.teams dyn_groupprivate() {
omp.terminator
}
return
@@ -2484,20 +2516,6 @@ func.func @omp_target_depend(%data_var: memref<i32>) {
// -----
-func.func @test_target_dyn_groupprivate_errors(%dyn_size: i32) {
- // expected-error @below {{duplicate dyn_groupprivate modifier 'strict'}}
- omp.target dyn_groupprivate(strict, strict : %dyn_size : i32) {
- omp.terminator
- }
- // expected-error @below {{incompatible dyn_groupprivate modifiers: 'strict' and 'fallback' cannot be used together}}
- omp.target dyn_groupprivate(strict, fallback : %dyn_size : i32) {
- omp.terminator
- }
- return
-}
-
-// -----
-
func.func @omp_distribute_schedule(%chunk_size : i32, %lb : i32, %ub : i32, %step : i32) -> () {
// expected-error @below {{op chunk size set without dist_schedule_static being present}}
"omp.distribute"(%chunk_size) <{operandSegmentSizes = array<i32: 0, 0, 1, 0>}> ({
diff --git a/mlir/test/Dialect/OpenMP/ops.mlir b/mlir/test/Dialect/OpenMP/ops.mlir
index 52fadf1416e25..94b679db5c0e2 100644
--- a/mlir/test/Dialect/OpenMP/ops.mlir
+++ b/mlir/test/Dialect/OpenMP/ops.mlir
@@ -1148,8 +1148,8 @@ func.func @omp_teams(%lb : i32, %ub : i32, %if_cond : i1, %num_threads : i32,
}
// Test dyn_groupprivate
- // CHECK: omp.teams dyn_groupprivate(cgroup, strict : %{{.+}} : i32)
- omp.teams dyn_groupprivate(cgroup, strict : %dyn_size : i32) {
+ // CHECK: omp.teams dyn_groupprivate(cgroup, fallback(null), %{{.+}} : i32)
+ omp.teams dyn_groupprivate(cgroup, fallback(null), %dyn_size : i32) {
// CHECK: omp.terminator
omp.terminator
}
@@ -2216,17 +2216,21 @@ func.func @omp_target_depend(%arg0: memref<i32>, %arg1: memref<i32>) {
// CHECK-LABEL: @omp_target_dyn_groupprivate
func.func @omp_target_dyn_groupprivate(%dyn_size: i32, %large_size: i64) {
- // CHECK: omp.target dyn_groupprivate(strict, cgroup : %{{.*}} : i32)
- omp.target dyn_groupprivate(strict, cgroup : %dyn_size : i32) {
- // CHECK: omp.terminator
+ // CHECK: omp.target dyn_groupprivate(%{{.*}} : i32)
+ omp.target dyn_groupprivate(%dyn_size : i32) {
+ omp.terminator
+ }
+ // CHECK: omp.target dyn_groupprivate(cgroup, %{{.*}} : i64)
+ omp.target dyn_groupprivate(cgroup, %large_size : i64) {
omp.terminator
}
- // CHECK: omp.target dyn_groupprivate(cgroup : %{{.*}} : i64)
- omp.target dyn_groupprivate(cgroup : %large_size : i64) {
+ // CHECK: omp.target dyn_groupprivate(cgroup, fallback(abort), %{{.*}} : i32)
+ omp.target dyn_groupprivate(cgroup, fallback(abort), %dyn_size : i32) {
+ // CHECK: omp.terminator
omp.terminator
}
- // CHECK: omp.target dyn_groupprivate(fallback, cgroup : %{{.*}} : i32)
- omp.target dyn_groupprivate(fallback, cgroup : %dyn_size : i32) {
+ // CHECK: omp.target dyn_groupprivate(cgroup, fallback(null), %{{.*}} : i32)
+ omp.target dyn_groupprivate(fallback(null), cgroup, %dyn_size : i32) {
omp.terminator
}
// CHECK: omp.target dyn_groupprivate(%{{.*}} : i64)
More information about the Mlir-commits
mailing list