From 6fa660017ff80dc5ba467239c53c43ed561e99d4 Mon Sep 17 00:00:00 2001 From: Mats Petersson Date: Wed, 20 Nov 2024 18:09:23 +0000 Subject: [PATCH 1/6] [flang][OpenMP]Add parsing and semantics support for ATOMIC COMPARE This adds a minimalistic implementation of parsing and semantics for the ATOMIC COMPARE feature from OpenMP 5.1. There is no lowering, just a TODO for that part. Some of the Semantics is also just a comment explaining that more is needed. --- flang/include/flang/Parser/dump-parse-tree.h | 1 + flang/include/flang/Parser/parse-tree.h | 13 +++- flang/lib/Lower/OpenMP/OpenMP.cpp | 4 + flang/lib/Parser/openmp-parsers.cpp | 7 ++ flang/lib/Parser/unparse.cpp | 10 +++ flang/lib/Semantics/check-omp-structure.cpp | 28 +++++++ flang/lib/Semantics/check-omp-structure.h | 1 + flang/test/Parser/OpenMP/atomic-compare.f90 | 16 ++++ flang/test/Parser/OpenMP/atomic-unparse.f90 | 39 ++++++++++ .../test/Semantics/OpenMP/atomic-compare.f90 | 76 +++++++++++++++++++ flang/test/Semantics/OpenMP/atomic.f90 | 2 + 11 files changed, 195 insertions(+), 2 deletions(-) create mode 100644 flang/test/Parser/OpenMP/atomic-compare.f90 create mode 100644 flang/test/Semantics/OpenMP/atomic-compare.f90 diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h index 63fddc424182b..a31dd82e266b7 100644 --- a/flang/include/flang/Parser/dump-parse-tree.h +++ b/flang/include/flang/Parser/dump-parse-tree.h @@ -484,6 +484,7 @@ class ParseTreeDumper { NODE(parser, OmpAtomicCapture) NODE(OmpAtomicCapture, Stmt1) NODE(OmpAtomicCapture, Stmt2) + NODE(parser, OmpAtomicCompare) NODE(parser, OmpAtomicRead) NODE(parser, OmpAtomicUpdate) NODE(parser, OmpAtomicWrite) diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h index 22b7f9acd1af5..a8a23d1a16938 100644 --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -4126,6 +4126,15 @@ struct OmpAtomicCapture { t; }; +// ATOMCI COMPARE (OpenMP 5.1, Spec: 15.8.4) +struct OmpAtomicCompare { + TUPLE_CLASS_BOILERPLATE(OmpAtomicCompare); + CharBlock source; + std::tuple, std::optional> + t; +}; + // ATOMIC struct OmpAtomic { TUPLE_CLASS_BOILERPLATE(OmpAtomic); @@ -4138,11 +4147,11 @@ struct OmpAtomic { // 2.17.7 atomic -> // ATOMIC [atomic-clause-list] atomic-construct [atomic-clause-list] | // ATOMIC [atomic-clause-list] -// atomic-construct -> READ | WRITE | UPDATE | CAPTURE +// atomic-construct -> READ | WRITE | UPDATE | CAPTURE | COMPARE struct OpenMPAtomicConstruct { UNION_CLASS_BOILERPLATE(OpenMPAtomicConstruct); std::variant + OmpAtomicCompare, OmpAtomic> u; }; diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp index a2779213a1a15..80a17e97ee67f 100644 --- a/flang/lib/Lower/OpenMP/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP/OpenMP.cpp @@ -2896,6 +2896,10 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable, parser::OmpAtomicClauseList>( converter, atomicCapture, loc); }, + [&](const parser::OmpAtomicCompare &atomicCompare) { + mlir::Location loc = converter.genLocation(atomicCompare.source); + TODO(loc, "OpenMP atomic compare"); + }, }, atomicConstruct.u); } diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp index 630acf9a6b256..6d19d13f181e1 100644 --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -912,6 +912,12 @@ TYPE_PARSER("ATOMIC" >> Parser{} / endOmpLine, statement(assignmentStmt), statement(assignmentStmt), Parser{} / endOmpLine))) +TYPE_PARSER("ATOMIC" >> + sourced(construct( + Parser{} / maybe(","_tok), verbatim("COMPARE"_tok), + Parser{} / endOmpLine, statement(assignmentStmt), + maybe(Parser{} / endOmpLine)))) + // OMP ATOMIC [MEMORY-ORDER-CLAUSE-LIST] UPDATE [MEMORY-ORDER-CLAUSE-LIST] TYPE_PARSER("ATOMIC" >> sourced(construct( @@ -934,6 +940,7 @@ TYPE_PARSER("ATOMIC" >> // Atomic Construct TYPE_PARSER(construct(Parser{}) || construct(Parser{}) || + construct(Parser{}) || construct(Parser{}) || construct(Parser{}) || construct(Parser{})) diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp index 4d6aaceb69c18..c1ffb44385f04 100644 --- a/flang/lib/Parser/unparse.cpp +++ b/flang/lib/Parser/unparse.cpp @@ -2520,6 +2520,16 @@ class UnparseVisitor { Word("!$OMP END ATOMIC\n"); EndOpenMP(); } + void Unparse(const OmpAtomicCompare &x) { + BeginOpenMP(); + Word("!$OMP ATOMIC"); + Walk(std::get<0>(x.t)); + Word(" COMPARE"); + Walk(std::get<2>(x.t)); + Put("\n"); + EndOpenMP(); + Walk(std::get>(x.t)); + } void Unparse(const OmpAtomicRead &x) { BeginOpenMP(); Word("!$OMP ATOMIC"); diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp index 9cac652216fcf..90e8e99043ff5 100644 --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -2408,6 +2408,24 @@ void OmpStructureChecker::CheckAtomicUpdateStmt( ErrIfAllocatableVariable(var); } +void OmpStructureChecker::CheckAtomicCompareConstruct( + const parser::OmpAtomicCompare &atomicCompareConstruct) { + + CheckAtomicWriteStmt(std::get>( + atomicCompareConstruct.t) + .statement); + + unsigned version{context_.langOptions().OpenMPVersion}; + if (version < 51) { + context_.Say(atomicCompareConstruct.source, + "%s construct not allowed in %s, %s"_err_en_US, + atomicCompareConstruct.source, ThisVersion(version), TryVersion(51)); + } + + // TODO: More work needed here. Some of the Update restrictions need to + // be added, but Update isn't the same either. +} + // TODO: Allow cond-update-stmt once compare clause is supported. void OmpStructureChecker::CheckAtomicCaptureConstruct( const parser::OmpAtomicCapture &atomicCaptureConstruct) { @@ -2553,6 +2571,16 @@ void OmpStructureChecker::Enter(const parser::OpenMPAtomicConstruct &x) { &std::get<0>(atomicCapture.t), &std::get<2>(atomicCapture.t)); CheckAtomicCaptureConstruct(atomicCapture); }, + [&](const parser::OmpAtomicCompare &atomicCompare) { + const auto &dir{std::get(atomicCompare.t)}; + PushContextAndClauseSets( + dir.source, llvm::omp::Directive::OMPD_atomic); + CheckAtomicMemoryOrderClause( + &std::get<0>(atomicCompare.t), &std::get<2>(atomicCompare.t)); + CheckHintClause( + &std::get<0>(atomicCompare.t), &std::get<2>(atomicCompare.t)); + CheckAtomicCompareConstruct(atomicCompare); + }, }, x.u); } diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h index df21ebac0f6d7..6b4fb51c2d99c 100644 --- a/flang/lib/Semantics/check-omp-structure.h +++ b/flang/lib/Semantics/check-omp-structure.h @@ -213,6 +213,7 @@ class OmpStructureChecker void CheckAtomicCaptureStmt(const parser::AssignmentStmt &); void CheckAtomicWriteStmt(const parser::AssignmentStmt &); void CheckAtomicCaptureConstruct(const parser::OmpAtomicCapture &); + void CheckAtomicCompareConstruct(const parser::OmpAtomicCompare &); void CheckAtomicConstructStructure(const parser::OpenMPAtomicConstruct &); void CheckDistLinear(const parser::OpenMPLoopConstruct &x); void CheckSIMDNest(const parser::OpenMPConstruct &x); diff --git a/flang/test/Parser/OpenMP/atomic-compare.f90 b/flang/test/Parser/OpenMP/atomic-compare.f90 new file mode 100644 index 0000000000000..5cd02698ff482 --- /dev/null +++ b/flang/test/Parser/OpenMP/atomic-compare.f90 @@ -0,0 +1,16 @@ +! RUN: not %flang_fc1 -fopenmp-version=51 -fopenmp %s 2>&1 | FileCheck %s +! OpenMP version for documentation purposes only - it isn't used until Sema. +! This is testing for Parser errors that bail out before Sema. +program main + implicit none + integer :: i, j = 10 + logical :: r + + !CHECK: error: expected OpenMP construct + !$omp atomic compare write + r = i .eq. j + 1 + + !CHECK: error: expected end of line + !$omp atomic compare num_threads(4) + r = i .eq. j +end program main diff --git a/flang/test/Parser/OpenMP/atomic-unparse.f90 b/flang/test/Parser/OpenMP/atomic-unparse.f90 index f9d8ec5d5c681..a7b4d673bc3c6 100644 --- a/flang/test/Parser/OpenMP/atomic-unparse.f90 +++ b/flang/test/Parser/OpenMP/atomic-unparse.f90 @@ -3,6 +3,7 @@ program main implicit none integer :: i, j = 10 + logical :: k !READ !$omp atomic read i = j @@ -121,6 +122,30 @@ program main i = j !$omp end atomic +!COMPARE +!$omp atomic compare + r = i .eq. j +!$omp atomic seq_cst compare + r = i .eq. j +!$omp atomic compare seq_cst + r = i .eq. j +!$omp atomic release compare + r = i .eq. j +!$omp atomic compare release + r = i .eq. j +!$omp atomic acq_rel compare + r = i .eq. j +!$omp atomic compare acq_rel + r = i .eq. j +!$omp atomic acquire compare + r = i .eq. j +!$omp atomic compare acquire + r = i .eq. j +!$omp atomic relaxed compare + r = i .eq. j +!$omp atomic compare relaxed + r = i .eq. j + !ATOMIC !$omp atomic i = j @@ -205,6 +230,20 @@ end program main !CHECK: !$OMP ATOMIC CAPTURE RELAXED !CHECK: !$OMP END ATOMIC +!COMPARE + +!CHECK: !$OMP ATOMIC COMPARE +!CHECK: !$OMP ATOMIC SEQ_CST COMPARE +!CHECK: !$OMP ATOMIC COMPARE SEQ_CST +!CHECK: !$OMP ATOMIC RELEASE COMPARE +!CHECK: !$OMP ATOMIC COMPARE RELEASE +!CHECK: !$OMP ATOMIC ACQ_REL COMPARE +!CHECK: !$OMP ATOMIC COMPARE ACQ_REL +!CHECK: !$OMP ATOMIC ACQUIRE COMPARE +!CHECK: !$OMP ATOMIC COMPARE ACQUIRE +!CHECK: !$OMP ATOMIC RELAXED COMPARE +!CHECK: !$OMP ATOMIC COMPARE RELAXED + !ATOMIC !CHECK: !$OMP ATOMIC !CHECK: !$OMP ATOMIC SEQ_CST diff --git a/flang/test/Semantics/OpenMP/atomic-compare.f90 b/flang/test/Semantics/OpenMP/atomic-compare.f90 new file mode 100644 index 0000000000000..624624a8ecc4a --- /dev/null +++ b/flang/test/Semantics/OpenMP/atomic-compare.f90 @@ -0,0 +1,76 @@ +! RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=51 + use omp_lib + implicit none + ! Check atomic compare. This combines elements from multiple other "atomic*.f90", as + ! to avoid having several files with just a few lines in them. atomic compare needs + ! higher openmp version than the others, so need a separate file. + + + real a, b + logical r + a = 1.0 + b = 2.0 + !$omp parallel num_threads(4) + ! First a few things that should compile without error. + !$omp atomic seq_cst, compare + r = b .ne. a + + !$omp atomic seq_cst compare + r = a .ge. b + !$omp end atomic + + !$omp atomic compare acquire hint(OMP_LOCK_HINT_CONTENDED) + r = a .lt. b + + !$omp atomic release hint(OMP_LOCK_HINT_UNCONTENDED) compare + r = a .gt. b + + !$omp atomic compare seq_cst + r = b .ne. a + + !$omp atomic hint(1) acq_rel compare + r = b .eq. a + !$omp end atomic + + ! Check for error conidtions: + !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: At most one SEQ_CST clause can appear on the COMPARE directive + !$omp atomic seq_cst seq_cst compare + r = a .le. b + !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: At most one SEQ_CST clause can appear on the COMPARE directive + !$omp atomic compare seq_cst seq_cst + r = b .gt. a + !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: At most one SEQ_CST clause can appear on the COMPARE directive + !$omp atomic seq_cst compare seq_cst + r = b .ge. b + + !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: At most one ACQUIRE clause can appear on the COMPARE directive + !$omp atomic acquire acquire compare + r = a .le. b + !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: At most one ACQUIRE clause can appear on the COMPARE directive + !$omp atomic compare acquire acquire + r = b .gt. a + !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: At most one ACQUIRE clause can appear on the COMPARE directive + !$omp atomic acquire compare acquire + r = b .ge. b + + !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: At most one RELAXED clause can appear on the COMPARE directive + !$omp atomic relaxed relaxed compare + r = a .le. b + !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: At most one RELAXED clause can appear on the COMPARE directive + !$omp atomic compare relaxed relaxed + r = b .gt. a + !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: At most one RELAXED clause can appear on the COMPARE directive + !$omp atomic relaxed compare relaxed + r = b .ge. b + + !$omp end parallel +end diff --git a/flang/test/Semantics/OpenMP/atomic.f90 b/flang/test/Semantics/OpenMP/atomic.f90 index 44f06b7460bf1..0e100871ea9b4 100644 --- a/flang/test/Semantics/OpenMP/atomic.f90 +++ b/flang/test/Semantics/OpenMP/atomic.f90 @@ -35,6 +35,7 @@ a = a + 1 !ERROR: expected 'UPDATE' !ERROR: expected 'WRITE' + !ERROR: expected 'COMPARE' !ERROR: expected 'CAPTURE' !ERROR: expected 'READ' !$omp atomic num_threads(4) @@ -49,6 +50,7 @@ !ERROR: expected 'UPDATE' !ERROR: expected 'WRITE' + !ERROR: expected 'COMPARE' !ERROR: expected 'CAPTURE' !ERROR: expected 'READ' !$omp atomic num_threads write From 549e2e01dfdea843cdf6b650e08ac4f4bc3f3b06 Mon Sep 17 00:00:00 2001 From: Mats Petersson Date: Wed, 27 Nov 2024 19:47:11 +0000 Subject: [PATCH 2/6] Update based on review comments, consisting of: * Accept only if statements, rather than an assignment statement. * Modify tests to match the if-statment required. * Add test to check for the TODO in lowering. --- flang/include/flang/Parser/dump-parse-tree.h | 1 + flang/include/flang/Parser/parse-tree.h | 9 +++- flang/lib/Parser/openmp-parsers.cpp | 8 +++- flang/lib/Parser/unparse.cpp | 2 +- flang/lib/Semantics/check-omp-structure.cpp | 5 +-- .../test/Lower/OpenMP/Todo/atomic-compare.f90 | 11 +++++ flang/test/Parser/OpenMP/atomic-unparse.f90 | 43 +++++++++++++------ .../test/Semantics/OpenMP/atomic-compare.f90 | 36 ++++++++-------- 8 files changed, 79 insertions(+), 36 deletions(-) create mode 100644 flang/test/Lower/OpenMP/Todo/atomic-compare.f90 diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h index a31dd82e266b7..150a07d1142f6 100644 --- a/flang/include/flang/Parser/dump-parse-tree.h +++ b/flang/include/flang/Parser/dump-parse-tree.h @@ -485,6 +485,7 @@ class ParseTreeDumper { NODE(OmpAtomicCapture, Stmt1) NODE(OmpAtomicCapture, Stmt2) NODE(parser, OmpAtomicCompare) + NODE(parser, OmpAtomicCompareIfStmt) NODE(parser, OmpAtomicRead) NODE(parser, OmpAtomicUpdate) NODE(parser, OmpAtomicWrite) diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h index a8a23d1a16938..b8ae734596128 100644 --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -4126,12 +4126,17 @@ struct OmpAtomicCapture { t; }; -// ATOMCI COMPARE (OpenMP 5.1, Spec: 15.8.4) +struct OmpAtomicCompareIfStmt { + UNION_CLASS_BOILERPLATE(OmpAtomicCompareIfStmt); + std::variant, common::Indirection> u; +}; + +// ATOMIC COMPARE (OpenMP 5.1, OPenMP 5.2 spec: 15.8.4) struct OmpAtomicCompare { TUPLE_CLASS_BOILERPLATE(OmpAtomicCompare); CharBlock source; std::tuple, std::optional> + OmpAtomicCompareIfStmt, std::optional> t; }; diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp index 6d19d13f181e1..1e01c2a5634de 100644 --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -10,6 +10,7 @@ // See OpenMP-4.5-grammar.txt for documentation. #include "basic-parsers.h" +#include "debug-parser.h" #include "expr-parsers.h" #include "misc-parsers.h" #include "stmt-parser.h" @@ -912,10 +913,15 @@ TYPE_PARSER("ATOMIC" >> Parser{} / endOmpLine, statement(assignmentStmt), statement(assignmentStmt), Parser{} / endOmpLine))) +TYPE_PARSER(construct(indirect(Parser{})) || + construct(indirect(Parser{}))) + +// OMP ATOMIC [MEMORY-ORDER-CLAUSE-LIST] COMPARE [MEMORY-ORDER-CLAUSE-LIST] TYPE_PARSER("ATOMIC" >> sourced(construct( Parser{} / maybe(","_tok), verbatim("COMPARE"_tok), - Parser{} / endOmpLine, statement(assignmentStmt), + Parser{} / endOmpLine, + Parser{}, maybe(Parser{} / endOmpLine)))) // OMP ATOMIC [MEMORY-ORDER-CLAUSE-LIST] UPDATE [MEMORY-ORDER-CLAUSE-LIST] diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp index c1ffb44385f04..1e97262d66981 100644 --- a/flang/lib/Parser/unparse.cpp +++ b/flang/lib/Parser/unparse.cpp @@ -2528,7 +2528,7 @@ class UnparseVisitor { Walk(std::get<2>(x.t)); Put("\n"); EndOpenMP(); - Walk(std::get>(x.t)); + Walk(std::get(x.t)); } void Unparse(const OmpAtomicRead &x) { BeginOpenMP(); diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp index 90e8e99043ff5..0cf9493695607 100644 --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -2411,9 +2411,8 @@ void OmpStructureChecker::CheckAtomicUpdateStmt( void OmpStructureChecker::CheckAtomicCompareConstruct( const parser::OmpAtomicCompare &atomicCompareConstruct) { - CheckAtomicWriteStmt(std::get>( - atomicCompareConstruct.t) - .statement); + // TODO: Check that the if-stmt is `if (var == expr) var = new` + // [with or without then/end-do] unsigned version{context_.langOptions().OpenMPVersion}; if (version < 51) { diff --git a/flang/test/Lower/OpenMP/Todo/atomic-compare.f90 b/flang/test/Lower/OpenMP/Todo/atomic-compare.f90 new file mode 100644 index 0000000000000..88ec6fe910b9e --- /dev/null +++ b/flang/test/Lower/OpenMP/Todo/atomic-compare.f90 @@ -0,0 +1,11 @@ +! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -fopenmp-version=51 -o - %s 2>&1 | FileCheck %s + +! CHECK: not yet implemented: OpenMP atomic compare +program p + integer :: x + logical :: r + !$omp atomic compare + if (x .eq. 0) then + x = 2 + end if +end program p diff --git a/flang/test/Parser/OpenMP/atomic-unparse.f90 b/flang/test/Parser/OpenMP/atomic-unparse.f90 index a7b4d673bc3c6..64fa79fb1d1a2 100644 --- a/flang/test/Parser/OpenMP/atomic-unparse.f90 +++ b/flang/test/Parser/OpenMP/atomic-unparse.f90 @@ -3,7 +3,7 @@ program main implicit none integer :: i, j = 10 - logical :: k + integer :: k !READ !$omp atomic read i = j @@ -124,27 +124,46 @@ program main !COMPARE !$omp atomic compare - r = i .eq. j + if (k == i) k = j !$omp atomic seq_cst compare - r = i .eq. j + if (k == j) then + k = i + end if !$omp atomic compare seq_cst - r = i .eq. j + if (k .eq. j) then + k = i + end if !$omp atomic release compare - r = i .eq. j + if (i .eq. j) k = i !$omp atomic compare release - r = i .eq. j + if (i .eq. j) then + i = k + end if !$omp atomic acq_rel compare - r = i .eq. j + if (k .eq. j) then + j = i + end if !$omp atomic compare acq_rel - r = i .eq. j + if (i .eq. j) then + i = k + end if !$omp atomic acquire compare - r = i .eq. j + if (i .eq. j + 1) then + i = j + end if + !$omp atomic compare acquire - r = i .eq. j + if (i .eq. j) then + i = k + end if !$omp atomic relaxed compare - r = i .eq. j + if (i .eq. j) then + i = k + end if !$omp atomic compare relaxed - r = i .eq. j + if (i .eq. k) then + i = j + end if !ATOMIC !$omp atomic diff --git a/flang/test/Semantics/OpenMP/atomic-compare.f90 b/flang/test/Semantics/OpenMP/atomic-compare.f90 index 624624a8ecc4a..0867950b08053 100644 --- a/flang/test/Semantics/OpenMP/atomic-compare.f90 +++ b/flang/test/Semantics/OpenMP/atomic-compare.f90 @@ -6,71 +6,73 @@ ! higher openmp version than the others, so need a separate file. - real a, b - logical r + real a, b, c a = 1.0 b = 2.0 + c = 3.0 !$omp parallel num_threads(4) ! First a few things that should compile without error. !$omp atomic seq_cst, compare - r = b .ne. a + if (b .eq. a) then + b = c + end if !$omp atomic seq_cst compare - r = a .ge. b + if (a .eq. b) a = c !$omp end atomic !$omp atomic compare acquire hint(OMP_LOCK_HINT_CONTENDED) - r = a .lt. b + if (b .eq. a) b = c !$omp atomic release hint(OMP_LOCK_HINT_UNCONTENDED) compare - r = a .gt. b + if (b .eq. a) b = c !$omp atomic compare seq_cst - r = b .ne. a + if (b .eq. c) b = a !$omp atomic hint(1) acq_rel compare - r = b .eq. a + if (b .eq. a) b = c !$omp end atomic ! Check for error conidtions: !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct !ERROR: At most one SEQ_CST clause can appear on the COMPARE directive !$omp atomic seq_cst seq_cst compare - r = a .le. b + if (b .eq. c) b = a !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct !ERROR: At most one SEQ_CST clause can appear on the COMPARE directive !$omp atomic compare seq_cst seq_cst - r = b .gt. a + if (b .eq. c) b = a !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct !ERROR: At most one SEQ_CST clause can appear on the COMPARE directive !$omp atomic seq_cst compare seq_cst - r = b .ge. b + if (b .eq. c) b = a !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct !ERROR: At most one ACQUIRE clause can appear on the COMPARE directive !$omp atomic acquire acquire compare - r = a .le. b + if (b .eq. c) b = a !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct !ERROR: At most one ACQUIRE clause can appear on the COMPARE directive !$omp atomic compare acquire acquire - r = b .gt. a + if (b .eq. c) b = a !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct !ERROR: At most one ACQUIRE clause can appear on the COMPARE directive !$omp atomic acquire compare acquire - r = b .ge. b + if (b .eq. c) b = a !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct !ERROR: At most one RELAXED clause can appear on the COMPARE directive !$omp atomic relaxed relaxed compare - r = a .le. b + if (b .eq. c) b = a !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct !ERROR: At most one RELAXED clause can appear on the COMPARE directive !$omp atomic compare relaxed relaxed - r = b .gt. a + if (b .eq. c) b = a !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct !ERROR: At most one RELAXED clause can appear on the COMPARE directive !$omp atomic relaxed compare relaxed - r = b .ge. b + if (b .eq. c) b = a !$omp end parallel end From c55179169cca25968d7e4f4395b152a9a3ffca74 Mon Sep 17 00:00:00 2001 From: Mats Petersson Date: Thu, 28 Nov 2024 11:54:08 +0000 Subject: [PATCH 3/6] Use opnemp_flags to get directory location of omp_lib --- flang/test/Semantics/OpenMP/atomic-compare.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flang/test/Semantics/OpenMP/atomic-compare.f90 b/flang/test/Semantics/OpenMP/atomic-compare.f90 index 0867950b08053..29ce60fa6ec1c 100644 --- a/flang/test/Semantics/OpenMP/atomic-compare.f90 +++ b/flang/test/Semantics/OpenMP/atomic-compare.f90 @@ -1,4 +1,4 @@ -! RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=51 +! RUN: %python %S/../test_errors.py %s %flang -fopenmp-version=51 %openmp_flags use omp_lib implicit none ! Check atomic compare. This combines elements from multiple other "atomic*.f90", as From 0b7c4dbabc8f6ce480510a05d1dc1c38dc9b8b7e Mon Sep 17 00:00:00 2001 From: Mats Petersson Date: Thu, 28 Nov 2024 14:59:46 +0000 Subject: [PATCH 4/6] Change order of flags --- flang/test/Semantics/OpenMP/atomic-compare.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flang/test/Semantics/OpenMP/atomic-compare.f90 b/flang/test/Semantics/OpenMP/atomic-compare.f90 index 29ce60fa6ec1c..bab3cb5923250 100644 --- a/flang/test/Semantics/OpenMP/atomic-compare.f90 +++ b/flang/test/Semantics/OpenMP/atomic-compare.f90 @@ -1,4 +1,4 @@ -! RUN: %python %S/../test_errors.py %s %flang -fopenmp-version=51 %openmp_flags +! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags -fopenmp-version=51 use omp_lib implicit none ! Check atomic compare. This combines elements from multiple other "atomic*.f90", as From c2c2ecf9ccaf00002eddf3f36e27675b2c6b63c1 Mon Sep 17 00:00:00 2001 From: Mats Petersson Date: Thu, 28 Nov 2024 15:48:10 +0000 Subject: [PATCH 5/6] Add requires openmp_runtime to test --- flang/test/Semantics/OpenMP/atomic-compare.f90 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/flang/test/Semantics/OpenMP/atomic-compare.f90 b/flang/test/Semantics/OpenMP/atomic-compare.f90 index bab3cb5923250..85644ad909107 100644 --- a/flang/test/Semantics/OpenMP/atomic-compare.f90 +++ b/flang/test/Semantics/OpenMP/atomic-compare.f90 @@ -1,3 +1,4 @@ +! REQUIRES: openmp_runtime ! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags -fopenmp-version=51 use omp_lib implicit none @@ -34,7 +35,7 @@ if (b .eq. a) b = c !$omp end atomic - ! Check for error conidtions: + ! Check for error conditions: !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct !ERROR: At most one SEQ_CST clause can appear on the COMPARE directive !$omp atomic seq_cst seq_cst compare From 62e7d536814099d12dbee0501a9f5ff69ec25905 Mon Sep 17 00:00:00 2001 From: Mats Petersson Date: Fri, 29 Nov 2024 12:26:21 +0000 Subject: [PATCH 6/6] Remove unused include --- flang/lib/Parser/openmp-parsers.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp index 1e01c2a5634de..5295cbcff09bc 100644 --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -10,7 +10,6 @@ // See OpenMP-4.5-grammar.txt for documentation. #include "basic-parsers.h" -#include "debug-parser.h" #include "expr-parsers.h" #include "misc-parsers.h" #include "stmt-parser.h"