diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp --- a/flang/lib/Lower/OpenACC.cpp +++ b/flang/lib/Lower/OpenACC.cpp @@ -1108,7 +1108,6 @@ // Parallel operation operands mlir::Value async; - mlir::Value numGangs; mlir::Value numWorkers; mlir::Value vectorLength; mlir::Value ifCond; @@ -1116,7 +1115,7 @@ mlir::Value waitDevnum; llvm::SmallVector waitOperands, attachEntryOperands, copyEntryOperands, copyoutEntryOperands, createEntryOperands, - dataClauseOperands; + dataClauseOperands, numGangs; llvm::SmallVector reductionOperands, privateOperands, firstprivateOperands; @@ -1147,8 +1146,9 @@ } else if (const auto *numGangsClause = std::get_if( &clause.u)) { - numGangs = fir::getBase(converter.genExprValue( - *Fortran::semantics::GetExpr(numGangsClause->v), stmtCtx)); + for (const Fortran::parser::ScalarIntExpr &expr : numGangsClause->v) + numGangs.push_back(fir::getBase(converter.genExprValue( + *Fortran::semantics::GetExpr(expr), stmtCtx))); } else if (const auto *numWorkersClause = std::get_if( &clause.u)) { @@ -1291,7 +1291,7 @@ addOperand(operands, operandSegments, async); addOperands(operands, operandSegments, waitOperands); if constexpr (!std::is_same_v) { - addOperand(operands, operandSegments, numGangs); + addOperands(operands, operandSegments, numGangs); addOperand(operands, operandSegments, numWorkers); addOperand(operands, operandSegments, vectorLength); } diff --git a/flang/lib/Semantics/check-acc-structure.cpp b/flang/lib/Semantics/check-acc-structure.cpp --- a/flang/lib/Semantics/check-acc-structure.cpp +++ b/flang/lib/Semantics/check-acc-structure.cpp @@ -331,7 +331,6 @@ CHECK_SIMPLE_CLAUSE(Link, ACCC_link) CHECK_SIMPLE_CLAUSE(NoCreate, ACCC_no_create) CHECK_SIMPLE_CLAUSE(Nohost, ACCC_nohost) -CHECK_SIMPLE_CLAUSE(NumGangs, ACCC_num_gangs) CHECK_SIMPLE_CLAUSE(NumWorkers, ACCC_num_workers) CHECK_SIMPLE_CLAUSE(Present, ACCC_present) CHECK_SIMPLE_CLAUSE(Private, ACCC_private) @@ -424,6 +423,14 @@ } } +void AccStructureChecker::Enter(const parser::AccClause::NumGangs &n) { + CheckAllowed(llvm::acc::Clause::ACCC_num_gangs); + + if (n.v.size() > 3) + context_.Say(GetContext().clauseSource, + "NUM_GANGS clause accepts a maximum of 3 arguments"_err_en_US); +} + void AccStructureChecker::Enter(const parser::AccClause::Self &x) { CheckAllowed(llvm::acc::Clause::ACCC_self); const std::optional &accSelfClause = x.v; diff --git a/flang/test/Lower/OpenACC/acc-parallel.f90 b/flang/test/Lower/OpenACC/acc-parallel.f90 --- a/flang/test/Lower/OpenACC/acc-parallel.f90 +++ b/flang/test/Lower/OpenACC/acc-parallel.f90 @@ -116,6 +116,13 @@ !CHECK: [[NUMGANGS2:%.*]] = fir.load %{{.*}} : !fir.ref !CHECK: acc.parallel num_gangs([[NUMGANGS2]] : i32) { !CHECK: acc.yield +!CHECK-NEXT: }{{$}} + + !$acc parallel num_gangs(1, 1, 1) + !$acc end parallel + +!CHECK: acc.parallel num_gangs(%{{.*}}, %{{.*}}, %{{.*}} : i32, i32, i32) { +!CHECK: acc.yield !CHECK-NEXT: }{{$}} !$acc parallel num_workers(10) diff --git a/flang/test/Semantics/OpenACC/acc-parallel.f90 b/flang/test/Semantics/OpenACC/acc-parallel.f90 --- a/flang/test/Semantics/OpenACC/acc-parallel.f90 +++ b/flang/test/Semantics/OpenACC/acc-parallel.f90 @@ -55,6 +55,10 @@ !$acc parallel num_gangs(8) !$acc end parallel + !ERROR: NUM_GANGS clause accepts a maximum of 3 arguments + !$acc parallel num_gangs(1, 1, 1, 1) + !$acc end parallel + !$acc parallel num_workers(8) !$acc end parallel diff --git a/llvm/include/llvm/Frontend/OpenACC/ACC.td b/llvm/include/llvm/Frontend/OpenACC/ACC.td --- a/llvm/include/llvm/Frontend/OpenACC/ACC.td +++ b/llvm/include/llvm/Frontend/OpenACC/ACC.td @@ -183,6 +183,7 @@ // 2.5.9 def ACCC_NumGangs : Clause<"num_gangs"> { let flangClass = "ScalarIntExpr"; + let isValueList = 1; } // 2.5.10