Index: flang/lib/Lower/OpenMP.cpp =================================================================== --- flang/lib/Lower/OpenMP.cpp +++ flang/lib/Lower/OpenMP.cpp @@ -1054,7 +1054,7 @@ fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); mlir::Location currentLocation = converter.getCurrentLocation(); llvm::SmallVector lowerBound, upperBound, step, linearVars, - linearStepVars, reductionVars; + linearStepVars, reductionVars, alignedVars, alignmentVars; mlir::Value scheduleChunkClauseOperand, ifClauseOperand; mlir::Attribute scheduleClauseOperand, noWaitClauseOperand, orderedClauseOperand, orderClauseOperand; @@ -1213,8 +1213,9 @@ if (llvm::omp::OMPD_simd == ompDirective) { TypeRange resultType; auto SimdLoopOp = firOpBuilder.create( - currentLocation, resultType, lowerBound, upperBound, step, - ifClauseOperand, simdlenClauseOperand, safelenClauseOperand, + currentLocation, resultType, lowerBound, upperBound, step, alignedVars, + alignmentVars, ifClauseOperand, simdlenClauseOperand, + safelenClauseOperand, /*inclusive=*/firOpBuilder.getUnitAttr()); createBodyOfOp(SimdLoopOp, converter, currentLocation, eval, &loopOpClauseList, iv); Index: mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td =================================================================== --- mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td +++ mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td @@ -385,6 +385,11 @@ Collapsed loops are represented by the simd-loop having a list of indices, bounds and steps where the size of the list is equal to the collapse value. + The `alignment_val` operand additionally specifies alignment of each + corresponding aligned operand. Note that `$aligned_vars` and + `alignment_val` variadic lists should contain the same number of + elements. + When an if clause is present and evaluates to false, the preferred number of iterations to be executed concurrently is one, regardless of whether a simdlen clause is speciļ¬ed. @@ -408,6 +413,8 @@ let arguments = (ins Variadic:$lowerBound, Variadic:$upperBound, Variadic:$step, + Variadic:$aligned_vars, + Variadic:$alignment_val, Optional:$if_expr, ConfinedAttr, [IntPositive]>:$simdlen, ConfinedAttr, [IntPositive]>:$safelen, @@ -416,7 +423,10 @@ let regions = (region AnyRegion:$region); let assemblyFormat = [{ - oilist(`if` `(` $if_expr `)` + oilist(`if` `(` $if_expr `)` | + `aligned` `(` + custom($aligned_vars, type($aligned_vars), + $alignment_val) `)` |`simdlen` `(` $simdlen `)` |`safelen` `(` $safelen `)` ) `for` custom($region, $lowerBound, $upperBound, $step, Index: mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp =================================================================== --- mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp +++ mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp @@ -130,17 +130,15 @@ } //===----------------------------------------------------------------------===// -// Parser and printer for Linear Clause +// Parser and printer for Linear or Aligned Clauses comma list //===----------------------------------------------------------------------===// -/// linear ::= `linear` `(` linear-list `)` -/// linear-list := linear-val | linear-val linear-list -/// linear-val := ssa-id-and-type `=` ssa-id-and-type -static ParseResult -parseLinearClause(OpAsmParser &parser, - SmallVectorImpl &vars, - SmallVectorImpl &types, - SmallVectorImpl &stepVars) { +/// comma-list := comma-val | comma-val comma-list +/// comma-val := ssa-id-and-type `=` ssa-id-and-type +static ParseResult parseCommaSeparatedListClause( + OpAsmParser &parser, SmallVectorImpl &items, + SmallVectorImpl &types, + SmallVectorImpl &itemsVars) { return parser.parseCommaSeparatedList([&]() { OpAsmParser::UnresolvedOperand var; Type type; @@ -149,25 +147,64 @@ parser.parseOperand(stepVar) || parser.parseColonType(type)) return failure(); - vars.push_back(var); + items.push_back(var); types.push_back(type); - stepVars.push_back(stepVar); + itemsVars.push_back(stepVar); return success(); }); } -/// Print Linear Clause +static void printCommaSeparatedListClause(OpAsmPrinter &p, Operation *op, + ValueRange items, TypeRange types, + ValueRange itemsVars) { + size_t itemsSize = items.size(); + for (unsigned i = 0; i < itemsSize; ++i) { + std::string separator = i == itemsSize - 1 ? "" : ", "; + p << items[i]; + if (itemsVars.size() > i) + p << " = " << itemsVars[i]; + p << " : " << items[i].getType() << separator; + } +} + +//===----------------------------------------------------------------------===// +// Parser and printer for Aligned Clause +//===----------------------------------------------------------------------===// +/// linear ::= `aligned` `(` comma-list `)` +static ParseResult parseAlignedClause( + OpAsmParser &parser, + SmallVectorImpl &alignedItems, + SmallVectorImpl &types, + SmallVectorImpl &alignmentValues) { + return parseCommaSeparatedListClause(parser, alignedItems, types, + alignmentValues); +} + +static void printAlignedClause(OpAsmPrinter &p, Operation *op, + ValueRange alignedVars, + TypeRange alignedVarTypes, + ValueRange alignmentValues) { + printCommaSeparatedListClause(p, op, alignedVars, alignedVarTypes, + alignmentValues); +} + +//===----------------------------------------------------------------------===// +// Parser and printer for Linear Clause +//===----------------------------------------------------------------------===// +/// linear ::= `linear` `(` comma-list `)` +static ParseResult +parseLinearClause(OpAsmParser &parser, + SmallVectorImpl &vars, + SmallVectorImpl &types, + SmallVectorImpl &stepVars) { + return parseCommaSeparatedListClause(parser, vars, types, stepVars); +} + static void printLinearClause(OpAsmPrinter &p, Operation *op, ValueRange linearVars, TypeRange linearVarTypes, ValueRange linearStepVars) { - size_t linearVarsSize = linearVars.size(); - for (unsigned i = 0; i < linearVarsSize; ++i) { - std::string separator = i == linearVarsSize - 1 ? "" : ", "; - p << linearVars[i]; - if (linearStepVars.size() > i) - p << " = " << linearStepVars[i]; - p << " : " << linearVars[i].getType() << separator; - } + printCommaSeparatedListClause(p, op, linearVars, linearVarTypes, + linearStepVars); } //===----------------------------------------------------------------------===// Index: mlir/test/Dialect/OpenMP/invalid.mlir =================================================================== --- mlir/test/Dialect/OpenMP/invalid.mlir +++ mlir/test/Dialect/OpenMP/invalid.mlir @@ -197,12 +197,22 @@ "omp.simdloop" (%lb, %ub, %step) ({ ^bb0(%iv: index): omp.yield - }) {operand_segment_sizes = array} : + }) {operand_segment_sizes = array} : (index, index, i32) -> () return } +// ----- +func.func @omp_simdloop_pretty_aligned(%lb : index, %ub : index, %step : index, %data_var : memref, %alignment_var : i32) -> () { + // expected-error @below {{expected '='}} + omp.simdloop aligned(%data_var : memref) + for (%iv) : index = (%lb) to (%ub) step (%step) { + omp.yield + } + return +} + // ----- func.func @omp_simdloop_pretty_simdlen(%lb : index, %ub : index, %step : index) -> () { Index: mlir/test/Dialect/OpenMP/ops.mlir =================================================================== --- mlir/test/Dialect/OpenMP/ops.mlir +++ mlir/test/Dialect/OpenMP/ops.mlir @@ -333,7 +333,7 @@ "omp.simdloop" (%lb, %ub, %step) ({ ^bb0(%iv: index): omp.yield - }) {operand_segment_sizes = array} : + }) {operand_segment_sizes = array} : (index, index, index) -> () return @@ -348,6 +348,18 @@ return } +// CHECK-LABEL: omp_simdloop_pretty_aligned +func.func @omp_simdloop_pretty_aligned(%lb : index, %ub : index, %step : index, %data_var : memref, %alignment_var : i32) -> () { + + // CHECK: omp.simdloop aligned(%{{.*}} = %{{.*}} : memref) + // CHECK-SAME: for (%{{.*}}) : index = (%{{.*}}) to (%{{.*}}) step (%{{.*}}) + omp.simdloop aligned(%data_var = %alignment_var : memref) + for (%iv) : index = (%lb) to (%ub) step (%step) { + omp.yield + } + return +} + // CHECK-LABEL: omp_simdloop_pretty_if func.func @omp_simdloop_pretty_if(%lb : index, %ub : index, %step : index, %if_cond : i1) -> () { // CHECK: omp.simdloop if(%{{.*}}) for (%{{.*}}) : index = (%{{.*}}) to (%{{.*}}) step (%{{.*}}) Index: mlir/test/Target/LLVMIR/openmp-llvm.mlir =================================================================== --- mlir/test/Target/LLVMIR/openmp-llvm.mlir +++ mlir/test/Target/LLVMIR/openmp-llvm.mlir @@ -697,7 +697,7 @@ %4 = llvm.getelementptr %arg0[%iv] : (!llvm.ptr, i64) -> !llvm.ptr llvm.store %3, %4 : !llvm.ptr omp.yield - }) {operand_segment_sizes = array} : + }) {operand_segment_sizes = array} : (i64, i64, i64) -> () llvm.return