diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -2650,8 +2650,8 @@ def fopenmp : Flag<["-"], "fopenmp">, Group, Flags<[CC1Option, NoArgumentUnused, FlangOption, FC1Option]>, HelpText<"Parse OpenMP pragmas and generate parallel code.">; def fno_openmp : Flag<["-"], "fno-openmp">, Group, Flags<[NoArgumentUnused]>; -def fopenmp_version_EQ : Joined<["-"], "fopenmp-version=">, Group, Flags<[CC1Option, NoArgumentUnused]>, - HelpText<"Set OpenMP version (e.g. 45 for OpenMP 4.5, 50 for OpenMP 5.0). Default value is 50.">; +def fopenmp_version_EQ : Joined<["-"], "fopenmp-version=">, Group, Flags<[CC1Option, NoArgumentUnused, FlangOption, FC1Option]>, + HelpText<"Set OpenMP version (e.g. 45 for OpenMP 4.5, 50 for OpenMP 5.0). Default value is 50 for Clang and 11 for Flang">; defm openmp_extensions: BoolFOption<"openmp-extensions", LangOpts<"OpenMPExtensions">, DefaultTrue, PosFlagsetAttr( + mlir::StringAttr::get(module.getContext(), llvm::Twine{"omp.version"}), + mlir::omp::VersionAttr::get(module.getContext(), version)); +} + #endif // FORTRAN_TOOLS_CROSS_TOOL_HELPERS_H diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -720,9 +720,15 @@ Fortran::common::LanguageFeature::OpenACC); } if (args.hasArg(clang::driver::options::OPT_fopenmp)) { + // By default OpenMP is set to 1.1 version + res.getLangOpts().OpenMPVersion = 11; res.getFrontendOpts().features.Enable( Fortran::common::LanguageFeature::OpenMP); - + if (int Version = getLastArgIntValue( + args, clang::driver::options::OPT_fopenmp_version_EQ, + res.getLangOpts().OpenMPVersion, diags)) { + res.getLangOpts().OpenMPVersion = Version; + } if (args.hasArg(clang::driver::options::OPT_fopenmp_is_device)) { res.getLangOpts().OpenMPIsDevice = 1; diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp --- a/flang/lib/Frontend/FrontendActions.cpp +++ b/flang/lib/Frontend/FrontendActions.cpp @@ -285,6 +285,8 @@ ci.getInvocation().getLangOpts()); setOffloadModuleInterfaceTargetAttribute(*mlirModule, tm->getTargetCPU(), tm->getTargetFeatureString()); + setOpenMPVersionAttribute(*mlirModule, + ci.getInvocation().getLangOpts().OpenMPVersion); } const llvm::DataLayout &dl = tm->createDataLayout(); diff --git a/flang/test/Driver/driver-help-hidden.f90 b/flang/test/Driver/driver-help-hidden.f90 --- a/flang/test/Driver/driver-help-hidden.f90 +++ b/flang/test/Driver/driver-help-hidden.f90 @@ -55,6 +55,8 @@ ! CHECK-NEXT: -fno-version-loops-for-stride ! CHECK-NEXT: Do not create unit-strided loops (default) ! CHECK-NEXT: -fopenacc Enable OpenACC +! CHECK-NEXT: -fopenmp-version= +! CHECK-NEXT: Set OpenMP version (e.g. 45 for OpenMP 4.5, 50 for OpenMP 5.0). Default value is 50 for Clang and 11 for Flang ! CHECK-NEXT: -fopenmp Parse OpenMP pragmas and generate parallel code. ! CHECK-NEXT: -fpass-plugin= Load pass plugin from a dynamic shared object file (only with new pass manager). ! CHECK-NEXT: -freciprocal-math Allow division operations to be reassociated diff --git a/flang/test/Driver/driver-help.f90 b/flang/test/Driver/driver-help.f90 --- a/flang/test/Driver/driver-help.f90 +++ b/flang/test/Driver/driver-help.f90 @@ -51,6 +51,8 @@ ! HELP-NEXT: -fno-version-loops-for-stride ! HELP-NEXT: Do not create unit-strided loops (default) ! HELP-NEXT: -fopenacc Enable OpenACC +! HELP-NEXT: -fopenmp-version= +! HELP-NEXT: Set OpenMP version (e.g. 45 for OpenMP 4.5, 50 for OpenMP 5.0). Default value is 50 for Clang and 11 for Flang ! HELP-NEXT: -fopenmp Parse OpenMP pragmas and generate parallel code. ! HELP-NEXT: -fpass-plugin= Load pass plugin from a dynamic shared object file (only with new pass manager). ! HELP-NEXT: -freciprocal-math Allow division operations to be reassociated @@ -157,6 +159,8 @@ ! HELP-FC1-NEXT: Path to the IR file produced by the frontend for the host. ! HELP-FC1-NEXT: -fopenmp-is-device Generate code only for an OpenMP target device. ! HELP-FC1-NEXT: -fopenmp-target-debug Enable debugging in the OpenMP offloading device RTL +! HELP-FC1-NEXT: -fopenmp-version= +! HELP-FC1-NEXT: Set OpenMP version (e.g. 45 for OpenMP 4.5, 50 for OpenMP 5.0). Default value is 50 for Clang and 11 for Flang ! HELP-FC1-NEXT: -fopenmp Parse OpenMP pragmas and generate parallel code. ! HELP-FC1-NEXT: -fpass-plugin= Load pass plugin from a dynamic shared object file (only with new pass manager). ! HELP-FC1-NEXT: -freciprocal-math Allow division operations to be reassociated diff --git a/flang/test/Driver/omp-driver-offload.f90 b/flang/test/Driver/omp-driver-offload.f90 --- a/flang/test/Driver/omp-driver-offload.f90 +++ b/flang/test/Driver/omp-driver-offload.f90 @@ -104,6 +104,12 @@ ! CHECK-RTL-ALL: "-fopenmp-assume-threads-oversubscription" "-fopenmp-assume-no-thread-state" "-fopenmp-assume-no-nested-parallelism" ! CHECK-RTL-ALL: {{.*}}.f90" +! RUN: %flang -### %s -o %t 2>&1 \ +! RUN: -fopenmp -fopenmp-targets=amdgcn-amd-amdhsa \ +! RUN: -fopenmp-version=45 \ +! RUN: | FileCheck %s --check-prefixes=CHECK-OPENMP-VERSION +! CHECK-OPENMP-VERSION: "{{[^"]*}}flang-new" "-fc1" {{.*}} "-fopenmp" "-fopenmp-version=45" {{.*}}.f90" + ! Test diagnostic error when host IR file is non-existent ! RUN: not %flang_fc1 %s -o %t 2>&1 -fopenmp -fopenmp-is-device \ ! RUN: -fopenmp-host-ir-file-path non-existant-file.bc \ diff --git a/flang/test/Lower/OpenMP/rtl-flags.f90 b/flang/test/Lower/OpenMP/rtl-flags.f90 --- a/flang/test/Lower/OpenMP/rtl-flags.f90 +++ b/flang/test/Lower/OpenMP/rtl-flags.f90 @@ -1,5 +1,7 @@ !RUN: %flang_fc1 -emit-fir -fopenmp -fopenmp-is-device %s -o - | FileCheck %s --check-prefix=DEFAULT-DEVICE-FIR -!RUN: %flang_fc1 -emit-fir -fopenmp %s -o - | FileCheck %s --check-prefix=DEFAULT-HOST-FIR +!RUN: %flang_fc1 -emit-fir -fopenmp -fopenmp-version=45 %s -o - | FileCheck %s --check-prefix=DEFAULT-HOST-FIR +!RUN: %flang_fc1 -emit-fir -fopenmp -fopenmp-is-device -fopenmp-version=45 %s -o - | FileCheck %s --check-prefix=DEFAULT-DEVICE-FIR-VERSION +!RUN: %flang_fc1 -emit-fir -fopenmp -fopenmp-version=45 %s -o - | FileCheck %s --check-prefix=DEFAULT-HOST-FIR-VERSION !RUN: %flang_fc1 -emit-fir -fopenmp -fopenmp-target-debug -fopenmp-is-device %s -o - | FileCheck %s --check-prefix=DBG-DEVICE-FIR !RUN: %flang_fc1 -emit-fir -fopenmp -fopenmp-target-debug=111 -fopenmp-is-device %s -o - | FileCheck %s --check-prefix=DBG-EQ-DEVICE-FIR !RUN: %flang_fc1 -emit-fir -fopenmp -fopenmp-assume-teams-oversubscription -fopenmp-is-device %s -o - | FileCheck %s --check-prefix=TEAMS-OSUB-DEVICE-FIR @@ -8,7 +10,9 @@ !RUN: %flang_fc1 -emit-fir -fopenmp -fopenmp-assume-no-nested-parallelism -fopenmp-is-device %s -o - | FileCheck %s --check-prefix=NEST-PAR-DEVICE-FIR !RUN: %flang_fc1 -emit-fir -fopenmp -fopenmp-target-debug -fopenmp-assume-teams-oversubscription -fopenmp-assume-no-nested-parallelism -fopenmp-assume-threads-oversubscription -fopenmp-assume-no-thread-state -fopenmp-is-device %s -o - | FileCheck %s --check-prefix=ALL-DEVICE-FIR !RUN: bbc -emit-fir -fopenmp -fopenmp-is-device -o - %s | FileCheck %s --check-prefix=DEFAULT-DEVICE-FIR +!RUN: bbc -emit-fir -fopenmp -fopenmp-is-device -fopenmp-version=45 -o - %s | FileCheck %s --check-prefix=DEFAULT-DEVICE-FIR-VERSION !RUN: bbc -emit-fir -fopenmp -o - %s | FileCheck %s --check-prefix=DEFAULT-HOST-FIR +!RUN: bbc -emit-fir -fopenmp -fopenmp-version=45 -o - %s | FileCheck %s --check-prefix=DEFAULT-HOST-FIR-VERSION !RUN: bbc -emit-fir -fopenmp -fopenmp-target-debug=111 -fopenmp-is-device -o - %s | FileCheck %s --check-prefix=DBG-EQ-DEVICE-FIR !RUN: bbc -emit-fir -fopenmp -fopenmp-assume-teams-oversubscription -fopenmp-is-device -o - %s | FileCheck %s --check-prefix=TEAMS-OSUB-DEVICE-FIR !RUN: bbc -emit-fir -fopenmp -fopenmp-assume-threads-oversubscription -fopenmp-is-device -o - %s | FileCheck %s --check-prefix=THREAD-OSUB-DEVICE-FIR @@ -16,14 +20,16 @@ !RUN: bbc -emit-fir -fopenmp -fopenmp-assume-no-nested-parallelism -fopenmp-is-device -o - %s | FileCheck %s --check-prefix=NEST-PAR-DEVICE-FIR !RUN: bbc -emit-fir -fopenmp -fopenmp-target-debug=1 -fopenmp-assume-teams-oversubscription -fopenmp-assume-no-nested-parallelism -fopenmp-assume-threads-oversubscription -fopenmp-assume-no-thread-state -fopenmp-is-device -o - %s | FileCheck %s --check-prefix=ALL-DEVICE-FIR -!DEFAULT-DEVICE-FIR: module attributes {{{.*}}, omp.flags = #omp.flags<>, omp.is_device = #omp.isdevice{{.*}}} -!DEFAULT-HOST-FIR: module attributes {{{.*}}, omp.is_device = #omp.isdevice{{.*}}} -!DBG-DEVICE-FIR: module attributes {{{.*}}, omp.flags = #omp.flags{{.*}}} -!DBG-EQ-DEVICE-FIR: module attributes {{{.*}}, omp.flags = #omp.flags{{.*}}} -!TEAMS-OSUB-DEVICE-FIR: module attributes {{{.*}}, omp.flags = #omp.flags{{.*}}} -!THREAD-OSUB-DEVICE-FIR: module attributes {{{.*}}, omp.flags = #omp.flags{{.*}}} -!THREAD-STATE-DEVICE-FIR: module attributes {{{.*}}, omp.flags = #omp.flags{{.*}}} -!NEST-PAR-DEVICE-FIR: module attributes {{{.*}}, omp.flags = #omp.flags{{.*}}} -!ALL-DEVICE-FIR: module attributes {{{.*}}, omp.flags = #omp.flags{{.*}}} +!DEFAULT-DEVICE-FIR: module attributes {{{.*}}, omp.flags = #omp.flags, omp.is_device = #omp.isdevice{{.*}}} +!DEFAULT-DEVICE-FIR-VERSION: module attributes {{{.*}}, omp.flags = #omp.flags, omp.is_device = #omp.isdevice, omp.version = #omp.version{{.*}} +!DEFAULT-HOST-FIR: module attributes {{{.*}}, omp.is_device = #omp.isdevice{{.*}} +!DEFAULT-HOST-FIR-VERSION: module attributes {{{.*}}, omp.is_device = #omp.isdevice, omp.version = #omp.version{{.*}} +!DBG-DEVICE-FIR: module attributes {{{.*}}, omp.flags = #omp.flags{{.*}}} +!DBG-EQ-DEVICE-FIR: module attributes {{{.*}}, omp.flags = #omp.flags{{.*}}} +!TEAMS-OSUB-DEVICE-FIR: module attributes {{{.*}}, omp.flags = #omp.flags{{.*}}} +!THREAD-OSUB-DEVICE-FIR: module attributes {{{.*}}, omp.flags = #omp.flags{{.*}}} +!THREAD-STATE-DEVICE-FIR: module attributes {{{.*}}, omp.flags = #omp.flags{{.*}}} +!NEST-PAR-DEVICE-FIR: module attributes {{{.*}}, omp.flags = #omp.flags{{.*}}} +!ALL-DEVICE-FIR: module attributes {{{.*}}, omp.flags = #omp.flags{{.*}}} subroutine omp_subroutine() end subroutine omp_subroutine diff --git a/flang/tools/bbc/bbc.cpp b/flang/tools/bbc/bbc.cpp --- a/flang/tools/bbc/bbc.cpp +++ b/flang/tools/bbc/bbc.cpp @@ -132,6 +132,11 @@ // A simplified subset of the OpenMP RTL Flags from Flang, only the primary // positive options are available, no negative options e.g. fopen_assume* vs // fno_open_assume* +static llvm::cl::opt + setOpenMPVersion("fopenmp-version", + llvm::cl::desc("OpenMP standard version"), + llvm::cl::init(11)); + static llvm::cl::opt setOpenMPTargetDebug( "fopenmp-target-debug", llvm::cl::desc("Enable debugging in the OpenMP offloading device RTL"), @@ -277,11 +282,12 @@ burnside.lower(parseTree, semanticsContext); mlir::ModuleOp mlirModule = burnside.getModule(); if (enableOpenMP) { - auto offloadModuleOpts = - OffloadModuleOpts(setOpenMPTargetDebug, setOpenMPTeamSubscription, - setOpenMPThreadSubscription, setOpenMPNoThreadState, - setOpenMPNoNestedParallelism, enableOpenMPDevice); + auto offloadModuleOpts = OffloadModuleOpts( + setOpenMPTargetDebug, setOpenMPTeamSubscription, + setOpenMPThreadSubscription, setOpenMPNoThreadState, + setOpenMPNoNestedParallelism, enableOpenMPDevice, setOpenMPVersion); setOffloadModuleInterfaceAttributes(mlirModule, offloadModuleOpts); + setOpenMPVersionAttribute(mlirModule, setOpenMPVersion); } std::error_code ec; std::string outputName = outputFilename;