https://github.com/akuhlens created https://github.com/llvm/llvm-project/pull/197718
Adds the flag, `-facc-allow-default-none-scalars`. When this flag is enabled, Flang reverts to the pre-3.2 behavior: scalar variables referenced inside a `default(none)` compute region without an explicit data clause do not produce an error. Instead, Flang infers implicit data attributes for those scalars via the same implicit-copy logic applied in regions without `default(none)`. - Adds tests and documentation. - Makes an explicit extensions doc for OpenACC to mirror the OpenMP extensions doc. - Moves the intentional deviations to from the standard to the extensions doc. >From 9c94a481274b3762e6d89202ab344707b8e16344 Mon Sep 17 00:00:00 2001 From: Andre Kuhlenschmidt <[email protected]> Date: Tue, 12 May 2026 11:15:40 -0700 Subject: [PATCH 1/2] [flang][OpenACC] Add -facc-allow-default-none-scalars extension flag Adds opt-in flag -facc-allow-default-none-scalars that restores pre-OpenACC-3.2 behavior: scalar variables referenced inside a default(none) compute region without an explicit data clause are allowed (with a warning at -Wacc-implicit-scalar level) instead of triggering an error. Array variables continue to require an explicit data clause regardless of this flag. This matches nvfortran's behavior and provides a migration path for legacy code that relied on pre-3.2 scalar treatment under default(none). New files: - flang/docs/OpenACC-extensions.md: documents all active and opt-in OpenACC extensions in Flang (moves content from OpenACC.md) - flang/test/Semantics/OpenACC/acc-default-none-scalars.f90: baseline test (scalars and arrays both error without the flag) - flang/test/Semantics/OpenACC/acc-default-none-scalars-ext.f90: test with the flag (scalar warns, array still errors) Fixes: https://gitlab-master.nvidia.com/nvhpc-eng/lorado/-/issues/2163 --- clang/include/clang/Driver/Options.td | 2 + clang/lib/Driver/ToolChains/Flang.cpp | 2 + flang/docs/OpenACC-extensions.md | 60 +++++++++++++++++++ flang/docs/OpenACC.md | 15 +---- .../include/flang/Support/Fortran-features.h | 6 +- flang/lib/Frontend/CompilerInvocation.cpp | 8 +++ flang/lib/Semantics/resolve-directives.cpp | 28 +++++++-- flang/lib/Support/Fortran-features.cpp | 2 + .../OpenACC/acc-default-none-scalars-ext.f90 | 16 +++++ .../OpenACC/acc-default-none-scalars.f90 | 15 +++++ 10 files changed, 136 insertions(+), 18 deletions(-) create mode 100644 flang/docs/OpenACC-extensions.md create mode 100644 flang/test/Semantics/OpenACC/acc-default-none-scalars-ext.f90 create mode 100644 flang/test/Semantics/OpenACC/acc-default-none-scalars.f90 diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 77379f1130149..bac2cddcf6e83 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -7132,6 +7132,8 @@ defm ppc_native_vec_elem_order: BoolOptionWithoutMarshalling<"f", "ppc-native-ve PosFlag<SetTrue, [], [ClangOption], "Specifies PowerPC native vector element order (default)">, NegFlag<SetFalse, [], [ClangOption], "Specifies PowerPC non-native vector element order">>; defm unsigned : OptInFC1FFlag<"unsigned", "Enables UNSIGNED type">; +defm acc_allow_default_none_scalars : OptInFC1FFlag<"acc-allow-default-none-scalars", + "Allow scalar variables in OpenACC default(none) regions without explicit data clauses (pre-OpenACC-3.2 behavior)">; def fno_automatic : Flag<["-"], "fno-automatic">, Group<f_Group>, HelpText<"Implies the SAVE attribute for non-automatic local objects in subprograms unless RECURSIVE">; diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp index 1edb83f7255eb..ed8d30f2dce14 100644 --- a/clang/lib/Driver/ToolChains/Flang.cpp +++ b/clang/lib/Driver/ToolChains/Flang.cpp @@ -128,6 +128,8 @@ void Flang::addOtherOptions(const ArgList &Args, ArgStringList &CmdArgs) const { options::OPT_fconvert_EQ, options::OPT_fpass_plugin_EQ, options::OPT_funderscoring, options::OPT_fno_underscoring, options::OPT_funsigned, options::OPT_fno_unsigned, + options::OPT_facc_allow_default_none_scalars, + options::OPT_fno_acc_allow_default_none_scalars, options::OPT_finstrument_functions}); llvm::codegenoptions::DebugInfoKind DebugInfoKind; diff --git a/flang/docs/OpenACC-extensions.md b/flang/docs/OpenACC-extensions.md new file mode 100644 index 0000000000000..c630b631fd012 --- /dev/null +++ b/flang/docs/OpenACC-extensions.md @@ -0,0 +1,60 @@ +<!--===- docs/OpenACC-extensions.md + + Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + See https://llvm.org/LICENSE.txt for license information. + SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +--> + +# OpenACC Extensions in Flang + +```{contents} +--- +local: +--- +``` + +The items below are intentional deviations from the OpenACC specification +accepted by Flang. They are also listed as deviations in +[OpenACC.md](OpenACC.md). + +## Extensions always active + +These extensions require no flag. + +* The end directive for combined constructs can omit the `loop` keyword. +* An `!$acc routine` with no parallelism clause is treated as if the `seq` + clause were present. +* `!$acc end loop` does not trigger a parsing error and is silently ignored. +* The restriction on required clauses for `!$acc data` is emitted as a + portability warning rather than an error, matching the behavior of other + compilers. +* The `if` clause accepts scalar integer expressions in addition to scalar + logical expressions. +* `!$acc routine` directives can be placed at the top level. +* `!$acc cache` directives accept scalar variables. +* The `!$acc declare` directive accepts assumed-size array arguments for + `deviceptr` and `present` clauses. + +## Extensions enabled by flag + +### `-facc-allow-default-none-scalars` — pre-OpenACC-3.2 scalar behavior under `DEFAULT(NONE)` + +OpenACC version 3.2 (section 1.16, change 733) clarified that the +`default(none)` clause applies to scalar variables. Prior to version 3.2, +`default(none)` did not impose a data-clause requirement on scalar variables. + +When this flag is enabled, Flang reverts to the pre-3.2 behavior: scalar +variables referenced inside a `default(none)` compute region without an +explicit data clause do not produce an error. Instead, Flang infers implicit +data attributes for those scalars via the same implicit-copy logic applied +in regions without `default(none)`. + +Array variables always require an explicit data clause under `default(none)` +regardless of this flag. + +When a scalar is implicitly attributed under this extension, a warning is +emitted at `-pedantic` level (or explicitly via `-Wacc-implicit-scalar`). + +**Motivation:** NVIDIA Fortran (`nvfortran`) implements the pre-3.2 behavior. +This flag provides a migration path for legacy code that relied on it. diff --git a/flang/docs/OpenACC.md b/flang/docs/OpenACC.md index 87f30ccd953b6..47ce31c0bebaa 100644 --- a/flang/docs/OpenACC.md +++ b/flang/docs/OpenACC.md @@ -15,18 +15,9 @@ local: ``` ## Intentional deviation from the specification -* The end directive for combined construct can omit the `loop` keyword. -* An `!$acc routine` with no parallelism clause is treated as if the `seq` - clause was present. -* `!$acc end loop` does not trigger a parsing error and is just ignored. -* The restriction on `!$acc data` required clauses is emitted as a portability - warning instead of an error as other compiler accepts it. -* The `if` clause accepts scalar integer expression in addition to scalar - logical expression. -* `!$acc routine` directive can be placed at the top level. -* `!$acc cache` directive accepts scalar variable. -* The `!$acc declare` directive accepts assumed size array arguments for - `deviceptr` and `present` clauses. + +See [OpenACC-extensions.md](OpenACC-extensions.md) for the full list of +intentional deviations and opt-in extensions supported by Flang. ## Remarks about incompatibilities with other implementations * Array element references in the data clauses are equivalent to array sections diff --git a/flang/include/flang/Support/Fortran-features.h b/flang/include/flang/Support/Fortran-features.h index 857de9479e4e5..9effbb4db21d3 100644 --- a/flang/include/flang/Support/Fortran-features.h +++ b/flang/include/flang/Support/Fortran-features.h @@ -55,7 +55,8 @@ ENUM_CLASS(LanguageFeature, BackslashEscapes, OldDebugLines, SavedLocalInSpecExpr, PrintNamelist, AssumedRankPassedToNonAssumedRank, IgnoreIrrelevantAttributes, Unsigned, AmbiguousStructureConstructor, ContiguousOkForSeqAssociation, ForwardRefExplicitTypeDummy, - InaccessibleDeferredOverride, CudaWarpMatchFunction, DoConcurrentOffload) + InaccessibleDeferredOverride, CudaWarpMatchFunction, DoConcurrentOffload, + AccDefaultNoneScalars) // Portability and suspicious usage warnings ENUM_CLASS(UsageWarning, Portability, PointerToUndefinable, @@ -77,7 +78,8 @@ ENUM_CLASS(UsageWarning, Portability, PointerToUndefinable, MismatchingDummyProcedure, SubscriptedEmptyArray, UnsignedLiteralTruncation, CompatibleDeclarationsFromDistinctModules, NullActualForDefaultIntentAllocatable, UseAssociationIntoSameNameSubprogram, - HostAssociatedIntentOutInSpecExpr, NonVolatilePointerToVolatile) + HostAssociatedIntentOutInSpecExpr, NonVolatilePointerToVolatile, + AccImplicitScalar) using LanguageFeatures = EnumSet<LanguageFeature, LanguageFeature_enumSize>; using UsageWarnings = EnumSet<UsageWarning, UsageWarning_enumSize>; diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp index 5455efde1a81f..7638bc7f51196 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -844,6 +844,14 @@ static bool parseFrontendArgs(FrontendOptions &opts, llvm::opt::ArgList &args, clang::driver::options::OPT_fno_unsigned, false)); + // -f{no-}acc-allow-default-none-scalars + opts.features.Enable( + Fortran::common::LanguageFeature::AccDefaultNoneScalars, + args.hasFlag( + clang::driver::options::OPT_facc_allow_default_none_scalars, + clang::driver::options::OPT_fno_acc_allow_default_none_scalars, + false)); + // -f{no-}xor-operator opts.features.Enable( Fortran::common::LanguageFeature::XOROperator, diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp index 299bb6ff876e7..14a253f301c48 100644 --- a/flang/lib/Semantics/resolve-directives.cpp +++ b/flang/lib/Semantics/resolve-directives.cpp @@ -1500,10 +1500,30 @@ void AccAttributeVisitor::Post(const parser::Name &name) { name.symbol = found; // adjust the symbol within region } else if (GetContext().defaultDSA == Symbol::Flag::AccNone) { // 2.5.14. - context_.Say(name.source, - "The DEFAULT(NONE) clause requires that '%s' must be listed in " - "a data-mapping clause"_err_en_US, - symbol->name()); + bool isScalarExtensionActive{false}; + if (context_.IsEnabled( + common::LanguageFeature::AccDefaultNoneScalars)) { + if (const auto *det{symbol->detailsIf<ObjectEntityDetails>()}) { + if (!det->IsArray()) { + // Pre-OpenACC-3.2: scalars without explicit data clauses get + // implicit attributes (firstprivate/reduction) via normal + // inference. Warn so the user knows they are using legacy + // behavior (-Wacc-implicit-scalar to suppress). + isScalarExtensionActive = true; + context_.Warn(common::UsageWarning::AccImplicitScalar, + name.source, + "'%s' has no data clause under DEFAULT(NONE); implicit " + "attribute inferred (-facc-allow-default-none-scalars " + "enables pre-OpenACC-3.2 behavior)"_warn_en_US, + symbol->name()); + } + } + } + if (!isScalarExtensionActive) { + context_.Say(name.source, + "The DEFAULT(NONE) clause requires that '%s' must be listed in a data-mapping clause"_err_en_US, + symbol->name()); + } } } } diff --git a/flang/lib/Support/Fortran-features.cpp b/flang/lib/Support/Fortran-features.cpp index fc69fc638eda1..fcd4c29d0afef 100644 --- a/flang/lib/Support/Fortran-features.cpp +++ b/flang/lib/Support/Fortran-features.cpp @@ -90,6 +90,8 @@ LanguageFeatureControl::LanguageFeatureControl() { disable_.set(LanguageFeature::OldStyleParameter); // Possibly an accidental "feature" of nvfortran. disable_.set(LanguageFeature::AssumedRankPassedToNonAssumedRank); + // Pre-OpenACC-3.2 scalar behavior under DEFAULT(NONE): disabled by default. + disable_.set(LanguageFeature::AccDefaultNoneScalars); // These warnings are enabled by default, but only because they used // to be unconditional. TODO: prune this list warnLanguage_.set(LanguageFeature::ExponentMatchingKindParam); diff --git a/flang/test/Semantics/OpenACC/acc-default-none-scalars-ext.f90 b/flang/test/Semantics/OpenACC/acc-default-none-scalars-ext.f90 new file mode 100644 index 0000000000000..f5ad7ea44cbd8 --- /dev/null +++ b/flang/test/Semantics/OpenACC/acc-default-none-scalars-ext.f90 @@ -0,0 +1,16 @@ +! RUN: %python %S/../test_errors.py %s %flang -fopenacc -facc-allow-default-none-scalars -Wacc-implicit-scalar + +! With -facc-allow-default-none-scalars, scalar variables without explicit +! data clauses under DEFAULT(NONE) are allowed and get a warning +! (-Wacc-implicit-scalar) instead of an error. Arrays continue to error. + +subroutine default_none_scalars_extension() + integer :: a + integer :: b(10) + !$acc parallel default(none) + !WARNING: 'a' has no data clause under DEFAULT(NONE); implicit attribute inferred (-facc-allow-default-none-scalars enables pre-OpenACC-3.2 behavior) [-Wacc-implicit-scalar] + a = 1 + !ERROR: The DEFAULT(NONE) clause requires that 'b' must be listed in a data-mapping clause + b(1) = 2 + !$acc end parallel +end subroutine diff --git a/flang/test/Semantics/OpenACC/acc-default-none-scalars.f90 b/flang/test/Semantics/OpenACC/acc-default-none-scalars.f90 new file mode 100644 index 0000000000000..30aa8bf83e0c2 --- /dev/null +++ b/flang/test/Semantics/OpenACC/acc-default-none-scalars.f90 @@ -0,0 +1,15 @@ +! RUN: %python %S/../test_errors.py %s %flang -fopenacc + +! Without -facc-allow-default-none-scalars, DEFAULT(NONE) errors on both +! scalars and arrays per OpenACC v3.2 section 2.5.14. + +subroutine default_none_scalars_error() + integer :: a + integer :: b(10) + !$acc parallel default(none) + !ERROR: The DEFAULT(NONE) clause requires that 'a' must be listed in a data-mapping clause + a = 1 + !ERROR: The DEFAULT(NONE) clause requires that 'b' must be listed in a data-mapping clause + b(1) = 2 + !$acc end parallel +end subroutine >From f01523aca505f2df3ca97f94082d563dcbe2c471 Mon Sep 17 00:00:00 2001 From: Andre Kuhlenschmidt <[email protected]> Date: Wed, 13 May 2026 20:36:54 -0700 Subject: [PATCH 2/2] [flang][OpenACC][nfc] Consolidate default-none-scalars tests; trim docs Merge acc-default-none-scalars-ext.f90 into acc-default-none-scalars.f90 so both the flag-off (error) and flag-on (warn) cases live in one file. Remove the Motivation paragraph from OpenACC-extensions.md (rationale belongs in the commit message, not the reference doc). Co-Authored-By: Claude Sonnet 4.6 <[email protected]> --- flang/docs/OpenACC-extensions.md | 3 --- .../OpenACC/acc-default-none-scalars-ext.f90 | 16 ---------------- .../OpenACC/acc-default-none-scalars.f90 | 11 ++++++----- 3 files changed, 6 insertions(+), 24 deletions(-) delete mode 100644 flang/test/Semantics/OpenACC/acc-default-none-scalars-ext.f90 diff --git a/flang/docs/OpenACC-extensions.md b/flang/docs/OpenACC-extensions.md index c630b631fd012..732e82a03045d 100644 --- a/flang/docs/OpenACC-extensions.md +++ b/flang/docs/OpenACC-extensions.md @@ -55,6 +55,3 @@ regardless of this flag. When a scalar is implicitly attributed under this extension, a warning is emitted at `-pedantic` level (or explicitly via `-Wacc-implicit-scalar`). - -**Motivation:** NVIDIA Fortran (`nvfortran`) implements the pre-3.2 behavior. -This flag provides a migration path for legacy code that relied on it. diff --git a/flang/test/Semantics/OpenACC/acc-default-none-scalars-ext.f90 b/flang/test/Semantics/OpenACC/acc-default-none-scalars-ext.f90 deleted file mode 100644 index f5ad7ea44cbd8..0000000000000 --- a/flang/test/Semantics/OpenACC/acc-default-none-scalars-ext.f90 +++ /dev/null @@ -1,16 +0,0 @@ -! RUN: %python %S/../test_errors.py %s %flang -fopenacc -facc-allow-default-none-scalars -Wacc-implicit-scalar - -! With -facc-allow-default-none-scalars, scalar variables without explicit -! data clauses under DEFAULT(NONE) are allowed and get a warning -! (-Wacc-implicit-scalar) instead of an error. Arrays continue to error. - -subroutine default_none_scalars_extension() - integer :: a - integer :: b(10) - !$acc parallel default(none) - !WARNING: 'a' has no data clause under DEFAULT(NONE); implicit attribute inferred (-facc-allow-default-none-scalars enables pre-OpenACC-3.2 behavior) [-Wacc-implicit-scalar] - a = 1 - !ERROR: The DEFAULT(NONE) clause requires that 'b' must be listed in a data-mapping clause - b(1) = 2 - !$acc end parallel -end subroutine diff --git a/flang/test/Semantics/OpenACC/acc-default-none-scalars.f90 b/flang/test/Semantics/OpenACC/acc-default-none-scalars.f90 index 30aa8bf83e0c2..329bfdebd8d3d 100644 --- a/flang/test/Semantics/OpenACC/acc-default-none-scalars.f90 +++ b/flang/test/Semantics/OpenACC/acc-default-none-scalars.f90 @@ -1,13 +1,14 @@ -! RUN: %python %S/../test_errors.py %s %flang -fopenacc +! RUN: %python %S/../test_errors.py %s %flang -fopenacc -facc-allow-default-none-scalars -Wacc-implicit-scalar -! Without -facc-allow-default-none-scalars, DEFAULT(NONE) errors on both -! scalars and arrays per OpenACC v3.2 section 2.5.14. +! With -facc-allow-default-none-scalars, scalar variables without explicit +! data clauses under DEFAULT(NONE) are allowed and get a warning +! (-Wacc-implicit-scalar) instead of an error. Arrays continue to error. -subroutine default_none_scalars_error() +subroutine default_none_scalars() integer :: a integer :: b(10) !$acc parallel default(none) - !ERROR: The DEFAULT(NONE) clause requires that 'a' must be listed in a data-mapping clause + !WARNING: 'a' has no data clause under DEFAULT(NONE); implicit attribute inferred (-facc-allow-default-none-scalars enables pre-OpenACC-3.2 behavior) [-Wacc-implicit-scalar] a = 1 !ERROR: The DEFAULT(NONE) clause requires that 'b' must be listed in a data-mapping clause b(1) = 2 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
