[flang] [llvm] [flang][openacc] Allow if clause on atomic directives (PR #135451)
Valentin Clement バレンタイン クレメン via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 11 16:22:35 PDT 2025
https://github.com/clementval created https://github.com/llvm/llvm-project/pull/135451
The new version of the OpenACC specification will allow the if clause on the atomic directives. Allow it in `ACC.td` and update the parse node and parser in flang to support it.
OpenACC dialect will need to be updated to support it as well.
>From 34e45cadb465bd554b7c63364fe193b2e83d17e0 Mon Sep 17 00:00:00 2001
From: Valentin Clement <clementval at gmail.com>
Date: Fri, 11 Apr 2025 16:20:43 -0700
Subject: [PATCH] [flang][openacc] Allow if clause on atomic directives
---
flang/include/flang/Parser/parse-tree.h | 10 +++---
flang/lib/Parser/openacc-parsers.cpp | 25 ++++++++-------
.../Semantics/OpenACC/acc-atomic-validity.f90 | 32 +++++++++++++++++++
llvm/include/llvm/Frontend/OpenACC/ACC.td | 1 +
4 files changed, 53 insertions(+), 15 deletions(-)
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index eeb438991feee..0c2a5de3b71d2 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -5244,21 +5244,23 @@ EMPTY_CLASS(AccEndAtomic);
// ACC ATOMIC READ
struct AccAtomicRead {
TUPLE_CLASS_BOILERPLATE(AccAtomicRead);
- std::tuple<Verbatim, Statement<AssignmentStmt>, std::optional<AccEndAtomic>>
+ std::tuple<Verbatim, AccClauseList, Statement<AssignmentStmt>,
+ std::optional<AccEndAtomic>>
t;
};
// ACC ATOMIC WRITE
struct AccAtomicWrite {
TUPLE_CLASS_BOILERPLATE(AccAtomicWrite);
- std::tuple<Verbatim, Statement<AssignmentStmt>, std::optional<AccEndAtomic>>
+ std::tuple<Verbatim, AccClauseList, Statement<AssignmentStmt>,
+ std::optional<AccEndAtomic>>
t;
};
// ACC ATOMIC UPDATE
struct AccAtomicUpdate {
TUPLE_CLASS_BOILERPLATE(AccAtomicUpdate);
- std::tuple<std::optional<Verbatim>, Statement<AssignmentStmt>,
+ std::tuple<std::optional<Verbatim>, AccClauseList, Statement<AssignmentStmt>,
std::optional<AccEndAtomic>>
t;
};
@@ -5268,7 +5270,7 @@ struct AccAtomicCapture {
TUPLE_CLASS_BOILERPLATE(AccAtomicCapture);
WRAPPER_CLASS(Stmt1, Statement<AssignmentStmt>);
WRAPPER_CLASS(Stmt2, Statement<AssignmentStmt>);
- std::tuple<Verbatim, Stmt1, Stmt2, AccEndAtomic> t;
+ std::tuple<Verbatim, AccClauseList, Stmt1, Stmt2, AccEndAtomic> t;
};
struct OpenACCAtomicConstruct {
diff --git a/flang/lib/Parser/openacc-parsers.cpp b/flang/lib/Parser/openacc-parsers.cpp
index fb731ee52cbba..072eba99826a1 100644
--- a/flang/lib/Parser/openacc-parsers.cpp
+++ b/flang/lib/Parser/openacc-parsers.cpp
@@ -187,22 +187,25 @@ TYPE_PARSER(construct<AccBeginCombinedDirective>(
// 2.12 Atomic constructs
TYPE_PARSER(construct<AccEndAtomic>(startAccLine >> "END ATOMIC"_tok))
-TYPE_PARSER("ATOMIC" >>
- construct<AccAtomicRead>(verbatim("READ"_tok) / endAccLine,
- statement(assignmentStmt), maybe(Parser<AccEndAtomic>{} / endAccLine)))
+TYPE_PARSER("ATOMIC" >> construct<AccAtomicRead>(verbatim("READ"_tok),
+ Parser<AccClauseList>{} / endAccLine,
+ statement(assignmentStmt),
+ maybe(Parser<AccEndAtomic>{} / endAccLine)))
-TYPE_PARSER("ATOMIC" >>
- construct<AccAtomicWrite>(verbatim("WRITE"_tok) / endAccLine,
- statement(assignmentStmt), maybe(Parser<AccEndAtomic>{} / endAccLine)))
+TYPE_PARSER("ATOMIC" >> construct<AccAtomicWrite>(verbatim("WRITE"_tok),
+ Parser<AccClauseList>{} / endAccLine,
+ statement(assignmentStmt),
+ maybe(Parser<AccEndAtomic>{} / endAccLine)))
TYPE_PARSER("ATOMIC" >>
- construct<AccAtomicUpdate>(maybe(verbatim("UPDATE"_tok)) / endAccLine,
- statement(assignmentStmt), maybe(Parser<AccEndAtomic>{} / endAccLine)))
+ construct<AccAtomicUpdate>(maybe(verbatim("UPDATE"_tok)),
+ Parser<AccClauseList>{} / endAccLine, statement(assignmentStmt),
+ maybe(Parser<AccEndAtomic>{} / endAccLine)))
TYPE_PARSER("ATOMIC" >>
- construct<AccAtomicCapture>(verbatim("CAPTURE"_tok) / endAccLine,
- statement(assignmentStmt), statement(assignmentStmt),
- Parser<AccEndAtomic>{} / endAccLine))
+ construct<AccAtomicCapture>(verbatim("CAPTURE"_tok),
+ Parser<AccClauseList>{} / endAccLine, statement(assignmentStmt),
+ statement(assignmentStmt), Parser<AccEndAtomic>{} / endAccLine))
TYPE_PARSER(
sourced(construct<OpenACCAtomicConstruct>(Parser<AccAtomicRead>{})) ||
diff --git a/flang/test/Semantics/OpenACC/acc-atomic-validity.f90 b/flang/test/Semantics/OpenACC/acc-atomic-validity.f90
index ba68031b0f18b..07fb864695737 100644
--- a/flang/test/Semantics/OpenACC/acc-atomic-validity.f90
+++ b/flang/test/Semantics/OpenACC/acc-atomic-validity.f90
@@ -10,6 +10,7 @@ program openacc_atomic_validity
integer :: i
integer, parameter :: N = 256
integer, dimension(N) :: c
+ logical :: l
!$acc parallel
@@ -23,27 +24,58 @@ program openacc_atomic_validity
!$acc atomic write
c(i) = 10
+ !$acc atomic write if(l)
+ c(i) = 10
+
!$acc atomic write
c(i) = 10
!$acc end atomic
+ !$acc atomic write if(.true.)
+ c(i) = 10
+ !$acc end atomic
+
!$acc atomic read
i = c(i)
+
+ !$acc atomic read if(.true.)
+ i = c(i)
!$acc atomic read
i = c(i)
!$acc end atomic
+ !$acc atomic read if(l)
+ i = c(i)
+ !$acc end atomic
+
+ !ERROR: FINALIZE clause is not allowed on the ATOMIC READ FINALIZE IF(L)
+ !$acc atomic read finalize if(l)
+ i = c(i)
+ !$acc end atomic
+
!$acc atomic capture
c(i) = i
i = i + 1
!$acc end atomic
+ !$acc atomic capture if(l .EQV. .false.)
+ c(i) = i
+ i = i + 1
+ !$acc end atomic
+
!$acc atomic update
!ERROR: RHS of atomic update statement must be scalar
!ERROR: LHS of atomic update statement must be scalar
c = c + 1
+ !$acc atomic update if(i == 0)
+ c(i) = c(i) + 1
+
+ !ERROR: At most one IF clause can appear on the ATOMIC UPDATE IF(I == 0) IF(.TRUE.)
+ !$acc atomic update if(i == 0) if(.true.)
+ c(i) = c(i) + 1
+
!$acc end parallel
end program openacc_atomic_validity
diff --git a/llvm/include/llvm/Frontend/OpenACC/ACC.td b/llvm/include/llvm/Frontend/OpenACC/ACC.td
index 8729d4505205b..c77988b21c1e3 100644
--- a/llvm/include/llvm/Frontend/OpenACC/ACC.td
+++ b/llvm/include/llvm/Frontend/OpenACC/ACC.td
@@ -270,6 +270,7 @@ def ACCC_Unknown : Clause<"unknown"> {
// 2.12
def ACC_Atomic : Directive<"atomic"> {
+ let allowedOnceClauses = [VersionedClause<ACCC_If, 34>];
let association = AS_Block;
let category = CA_Executable;
}
More information about the llvm-commits
mailing list