diff --git a/flang/include/flang/Semantics/symbol.h b/flang/include/flang/Semantics/symbol.h --- a/flang/include/flang/Semantics/symbol.h +++ b/flang/include/flang/Semantics/symbol.h @@ -511,7 +511,7 @@ // OpenMP data-copying attribute OmpCopyIn, OmpCopyPrivate, // OpenMP miscellaneous flags - OmpCommonBlock, OmpReduction, OmpAligned, OmpAllocate, + OmpCommonBlock, OmpReduction, OmpAligned, OmpNontemporal, OmpAllocate, OmpDeclarativeAllocateDirective, OmpExecutableAllocateDirective, OmpDeclareSimd, OmpDeclareTarget, OmpThreadprivate, OmpDeclareReduction, OmpFlushed, OmpCriticalLock, OmpIfSpecified, OmpNone, OmpPreDetermined); diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -203,6 +203,8 @@ parenthesized(Parser{}))) || "MERGEABLE" >> construct(construct()) || "NOGROUP" >> construct(construct()) || + "NONTEMPORAL" >> construct(construct( + parenthesized(nonemptyList(name)))) || "NOTINBRANCH" >> construct(construct()) || "NOWAIT" >> construct(construct()) || diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp --- a/flang/lib/Semantics/resolve-directives.cpp +++ b/flang/lib/Semantics/resolve-directives.cpp @@ -407,6 +407,13 @@ ResolveOmpNameList(alignedNameList, Symbol::Flag::OmpAligned); return false; } + + bool Pre(const parser::OmpClause::Nontemporal &x) { + const auto &nontemporalNameList{x.v}; + ResolveOmpNameList(nontemporalNameList, Symbol::Flag::OmpNontemporal); + return false; + } + void Post(const parser::Name &); // Keep track of labels in the statements that causes jumps to target labels diff --git a/flang/test/Parser/omp-nontemporal-unparse.f90 b/flang/test/Parser/omp-nontemporal-unparse.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Parser/omp-nontemporal-unparse.f90 @@ -0,0 +1,19 @@ +! RUN: %flang_fc1 -fdebug-unparse-no-sema -fopenmp %s | FileCheck %s + +program omp_simd + integer i + integer, allocatable :: a(:) + + allocate(a(10)) + + !NONTEMPORAL + !$omp simd nontemporal(a) + do i = 1, 10 + a(i) = i + end do + !$omp end simd +end program omp_simd +!CHECK-LABEL: PROGRAM omp_simd + +!NONTEMPORAL +!CHECK: !$OMP SIMD NONTEMPORAL(a) diff --git a/flang/test/Semantics/omp-nontemporal.f90 b/flang/test/Semantics/omp-nontemporal.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Semantics/omp-nontemporal.f90 @@ -0,0 +1,95 @@ +! RUN: %python %S/test_errors.py %s %flang -fopenmp +! REQUIRES: shell +! Check OpenMP clause validity for NONTEMPORAL clause + +program omp_simd + integer i + integer, allocatable :: a(:) + + allocate(a(10)) + + !$omp simd nontemporal(a) + do i = 1, 10 + a(i) = i + end do + !$omp end simd + + !$omp parallel do simd nontemporal(a) + do i = 1, 10 + a(i) = i + end do + !$omp end parallel do simd + + !$omp parallel do simd nontemporal(a) + do i = 1, 10 + a(i) = i + end do + !$omp end parallel do simd + + !ERROR: NONTEMPORAL clause is not allowed on the DO SIMD directive + !$omp do simd nontemporal(a) + do i = 1, 10 + a(i) = i + end do + !$omp end do simd + + !$omp taskloop simd nontemporal(a) + do i = 1, 10 + a(i) = i + end do + !$omp end taskloop simd + + !$omp teams + !$omp distribute parallel do simd nontemporal(a) + do i = 1, 10 + a(i) = i + end do + !$omp end distribute parallel do simd + !$omp end teams + + !$omp teams + !$omp distribute simd nontemporal(a) + do i = 1, 10 + a(i) = i + end do + !$omp end distribute simd + !$omp end teams + + !$omp target parallel do simd nontemporal(a) + do i = 1, 10 + a(i) = i + end do + !$omp end target parallel do simd + + !$omp target simd nontemporal(a) + do i = 1, 10 + a(i) = i + end do + !$omp end target simd + + !$omp teams distribute simd nontemporal(a) + do i = 1, 10 + a(i) = i + end do + !$omp end teams distribute simd + + !$omp teams distribute parallel do simd nontemporal(a) + do i = 1, 10 + a(i) = i + end do + !$omp end teams distribute parallel do simd + + !$omp target teams distribute parallel do simd nontemporal(a) + do i = 1, 10 + a(i) = i + end do + !$omp end target teams distribute parallel do simd + + !$omp target teams distribute simd nontemporal(a) + do i = 1, 10 + a(i) = i + end do + !$omp end target teams distribute simd + + +end program omp_simd diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td --- a/llvm/include/llvm/Frontend/OpenMP/OMP.td +++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td @@ -261,6 +261,8 @@ } def OMPC_NonTemporal : Clause<"nontemporal"> { let clangClass = "OMPNontemporalClause"; + let flangClass = "Name"; + let isValueList = true; } def OMP_ORDER_concurrent : ClauseVal<"default",2,0> { let isDefault = 1; }