diff --git a/.github/workflows/flang-arm64-tests.yml b/.github/workflows/flang-arm64-tests.yml index b4f2a2c955c2..792187c438d5 100644 --- a/.github/workflows/flang-arm64-tests.yml +++ b/.github/workflows/flang-arm64-tests.yml @@ -57,7 +57,7 @@ jobs: - name: Build and install libpgmath & flang run: | cd ${{ env.build_path }}/flang - ./build-flang.sh -t ${{ matrix.target }} -p ${{ env.install_prefix }} -n $(nproc) + ./build-flang.sh -t ${{ matrix.target }} -p ${{ env.install_prefix }} -n $(nproc) -l ${{ env.build_path }}/classic-flang-llvm-project/llvm - name: Copy llvm-lit run: | diff --git a/.github/workflows/flang-tests.yml b/.github/workflows/flang-tests.yml index 279dccc78b96..216d5711e8d0 100644 --- a/.github/workflows/flang-tests.yml +++ b/.github/workflows/flang-tests.yml @@ -63,7 +63,7 @@ jobs: - name: Build and install libpgmath & flang run: | cd ../../flang - ./build-flang.sh -t ${{ matrix.target }} -p ${{ env.install_prefix }} -n $(nproc) -c -s + ./build-flang.sh -t ${{ matrix.target }} -p ${{ env.install_prefix }} -n $(nproc) -c -s -l $(realpath ../classic-flang-llvm-project/classic-flang-llvm-project/llvm) - name: Copy llvm-lit run: | diff --git a/build-llvm-project.sh b/build-llvm-project.sh index e36a50625dea..3f57dcb0d9b3 100755 --- a/build-llvm-project.sh +++ b/build-llvm-project.sh @@ -4,13 +4,14 @@ TARGET="X86" BUILD_TYPE="Release" INSTALL_PREFIX="/usr/local" +CROSS_TARGETS="" NPROC=1 USE_CCACHE="0" DO_INSTALL="0" USE_SUDO="0" C_COMPILER_PATH="/usr/bin/gcc" CXX_COMPILER_PATH="/usr/bin/g++" -LLVM_ENABLE_PROJECTS="clang;openmp" +LLVM_EXTRA_PROJECTS="" EXTRA_CMAKE_OPTS="" VERBOSE="" @@ -19,41 +20,42 @@ set -e # Exit script on first error. function print_usage { echo "Usage: ./build-llvm-project.sh [options]"; echo ""; - echo "Build and install classic-flang-llvm-project."; + echo "Build and install classic-flang-llvm-project (including clang, lld, and openmp)."; echo "Run this script in a directory with project sources."; echo "Example:"; echo " $ git clone https://github.com/flang-compiler/classic-flang-llvm-project"; echo " $ cd classic-flang-llvm-project"; - echo " $ .github/workflows/build-llvm-project.sh -t X86 -p /install/prefix/ \\"; - echo " $ -a /usr/bin/gcc-10 -b /usr/bin/g++-10 -i -s"; + echo " $ ./build-llvm-project.sh -t X86 -p /opt/classic-flang/ -i -s"; echo ""; echo "Options:"; echo " -t Target to build for (X86, AArch64, PowerPC). Default: X86"; echo " -d Set the CMake build type. Default: Release"; echo " -p Install prefix. Default: /usr/local"; + echo " -X Cross-compile OpenMP for given list of target triples. Default: none"; echo " -n Number of parallel jobs. Default: 1"; echo " -c Use ccache. Default: 0 - do not use ccache"; echo " -i Install the build. Default 0 - just build, do not install"; echo " -s Use sudo to install. Default: 0 - do not use sudo"; echo " -a C compiler path. Default: /usr/bin/gcc"; echo " -b C++ compiler path. Default: /usr/bin/g++"; - echo " -e List of the LLVM sub-projects to build. Default: clang;openmp"; + echo " -e List of additional LLVM sub-projects to build. Default: none"; echo " -x Extra CMake options. Default: ''"; echo " -v Enable verbose output"; } -while getopts "t:d:p:n:cisa:b:e:x:v?" opt; do +while getopts "t:d:p:X:n:cisa:b:e:x:v?" opt; do case "$opt" in t) TARGET=$OPTARG;; d) BUILD_TYPE=$OPTARG;; p) INSTALL_PREFIX=$OPTARG;; + X) CROSS_TARGETS=$OPTARG;; n) NPROC=$OPTARG;; c) USE_CCACHE="1";; i) DO_INSTALL="1";; s) USE_SUDO="1";; a) C_COMPILER_PATH=$OPTARG;; b) CXX_COMPILER_PATH=$OPTARG;; - e) LLVM_ENABLE_PROJECTS=$OPTARG;; + e) LLVM_EXTRA_PROJECTS=$OPTARG;; x) EXTRA_CMAKE_OPTS="$OPTARG";; v) VERBOSE="1";; ?) print_usage; exit 0;; @@ -61,14 +63,7 @@ while getopts "t:d:p:n:cisa:b:e:x:v?" opt; do done CMAKE_OPTIONS="-DCMAKE_INSTALL_PREFIX=$INSTALL_PREFIX \ - -DCMAKE_BUILD_TYPE=$BUILD_TYPE \ - -DCMAKE_C_COMPILER=$C_COMPILER_PATH \ - -DCMAKE_CXX_COMPILER=$CXX_COMPILER_PATH \ - -DLLVM_TARGETS_TO_BUILD=$TARGET \ - -DLLVM_ENABLE_CLASSIC_FLANG=ON \ - -DFLANG_BUILD_NEW_DRIVER=OFF" -# Warning: the -DLLVM_ENABLE_PROJECTS option is specified with cmake -# to avoid issues with nested quotation marks + -DCMAKE_BUILD_TYPE=$BUILD_TYPE" if [ $USE_CCACHE == "1" ]; then echo "Build using ccache" @@ -77,16 +72,19 @@ if [ $USE_CCACHE == "1" ]; then -DCMAKE_CXX_COMPILER_LAUNCHER=ccache" fi -if [ -n "$EXTRA_CMAKE_OPTS" ]; then - CMAKE_OPTIONS="$CMAKE_OPTIONS $EXTRA_CMAKE_OPTS" -fi - -# Build and install +# Build and install. mkdir -p build && cd build if [ -n "$VERBOSE" ]; then set -x fi -cmake $CMAKE_OPTIONS -DLLVM_ENABLE_PROJECTS=$LLVM_ENABLE_PROJECTS ../llvm +cmake $CMAKE_OPTIONS \ + -DCMAKE_C_COMPILER=$C_COMPILER_PATH \ + -DCMAKE_CXX_COMPILER=$CXX_COMPILER_PATH \ + -DLLVM_ENABLE_CLASSIC_FLANG=ON \ + -DLLVM_ENABLE_PROJECTS="clang;lld;openmp;$LLVM_EXTRA_PROJECTS" \ + -DLLVM_TARGETS_TO_BUILD="$TARGET" \ + $EXTRA_CMAKE_OPTS \ + ../llvm set +x make -j$NPROC VERBOSE=$VERBOSE if [ $DO_INSTALL == "1" ]; then @@ -100,3 +98,44 @@ if [ $DO_INSTALL == "1" ]; then fi cd .. +# Cross-compile OpenMP libraries if requested. +IFS=';' read -ra CROSS_TARGET_LIST <<< "$CROSS_TARGETS" +for T in ${CROSS_TARGET_LIST[@]}; do + mkdir -p "build/openmp-$T" + pushd "build/openmp-$T" + CMAKE_OPTIONS="$CMAKE_OPTIONS \ + -DCMAKE_AR=$INSTALL_PREFIX/bin/llvm-ar \ + -DCMAKE_ASM_COMPILER=$INSTALL_PREFIX/bin/clang \ + -DCMAKE_ASM_COMPILER_TARGET=$T \ + -DCMAKE_C_COMPILER=$INSTALL_PREFIX/bin/clang \ + -DCMAKE_C_COMPILER_TARGET=$T \ + -DCMAKE_CXX_COMPILER=$INSTALL_PREFIX/bin/clang++ \ + -DCMAKE_CXX_COMPILER_TARGET=$T \ + -DCMAKE_RANLIB=$INSTALL_PREFIX/bin/llvm-ranlib \ + -DCMAKE_SHARED_LINKER_FLAGS=-fuse-ld=lld" + if [ -n "$VERBOSE" ]; then + set -x + fi + cmake $CMAKE_OPTIONS \ + -DLLVM_DEFAULT_TARGET_TRIPLE=$T \ + -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON \ + -DLLVM_ENABLE_RUNTIMES="openmp" \ + -DLIBOMP_OMPT_SUPPORT=OFF \ + -DOPENMP_ENABLE_LIBOMPTARGET=OFF \ + -DOPENMP_ENABLE_OMPT_TOOLS=OFF \ + -DOPENMP_LLVM_TOOLS_DIR=$PWD/../bin \ + $EXTRA_CMAKE_OPTS \ + ../../runtimes + set +x + make -j$NPROC VERBOSE=$VERBOSE + if [ $DO_INSTALL -eq 1 ]; then + if [ $USE_SUDO -eq 1 ]; then + echo "Install with sudo" + sudo make install + else + echo "Install without sudo" + make install + fi + fi + popd +done diff --git a/clang/CMakeLists.txt b/clang/CMakeLists.txt index 24e656eced6d..3f02ebae02c2 100644 --- a/clang/CMakeLists.txt +++ b/clang/CMakeLists.txt @@ -413,6 +413,11 @@ if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY) endif() endif() +option(LLVM_ENABLE_CLASSIC_FLANG "Build support for classic Flang instead of the new built-in Flang" OFF) +if(LLVM_ENABLE_CLASSIC_FLANG) + add_definitions( -DENABLE_CLASSIC_FLANG ) +endif() + option(CLANG_BUILD_TOOLS "Build the Clang tools. If OFF, just generate build targets." ON) diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td index 288786b8ce93..d1103729cbca 100644 --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -156,6 +156,10 @@ def err_drv_invalid_linker_name : Error< "invalid linker name in argument '%0'">; def err_drv_invalid_rtlib_name : Error< "invalid runtime library name in argument '%0'">; +def err_drv_invalid_allocatable_mode : Error< + "invalid semantic mode for assignments to allocatables in argument '%0'">; +def err_drv_unsupported_fixed_line_length : Error< + "unsupported fixed-format line length in argument '%0'">; def err_drv_unsupported_rtlib_for_platform : Error< "unsupported runtime library '%0' for platform '%1'">; def err_drv_invalid_unwindlib_name : Error< @@ -384,6 +388,8 @@ def err_drv_small_columns : Error< def warn_drv_fraw_string_literals_in_cxx11 : Warning< "ignoring '-f%select{no-|}0raw-string-literals', which is only valid for C and C++ standards before C++11">, InGroup; +def err_drv_clang_unsupported_minfo_arg : Error< + "'%0' option does not support '%1' value">; def err_drv_invalid_malign_branch_EQ : Error< "invalid argument '%0' to -malign-branch=; each element must be one of: %1">; diff --git a/clang/include/clang/Basic/MacroBuilder.h b/clang/include/clang/Basic/MacroBuilder.h index d83f27c236e3..a84c16d0eaac 100644 --- a/clang/include/clang/Basic/MacroBuilder.h +++ b/clang/include/clang/Basic/MacroBuilder.h @@ -24,12 +24,13 @@ class MacroBuilder { raw_ostream &Out; public: MacroBuilder(raw_ostream &Output) : Out(Output) {} + virtual ~MacroBuilder() {} /// Append a \#define line for macro of the form "\#define Name Value\n". /// If DeprecationMsg is provided, also append a pragma to deprecate the /// defined macro. - void defineMacro(const Twine &Name, const Twine &Value = "1", - Twine DeprecationMsg = "") { + virtual void defineMacro(const Twine &Name, const Twine &Value = "1", + Twine DeprecationMsg = "") { Out << "#define " << Name << ' ' << Value << '\n'; if (!DeprecationMsg.isTriviallyEmpty()) Out << "#pragma clang deprecated(" << Name << ", \"" << DeprecationMsg diff --git a/clang/include/clang/Basic/Sanitizers.def b/clang/include/clang/Basic/Sanitizers.def index f234488eaa80..68b00d948eb1 100644 --- a/clang/include/clang/Basic/Sanitizers.def +++ b/clang/include/clang/Basic/Sanitizers.def @@ -196,6 +196,9 @@ SANITIZER_GROUP("bounds", Bounds, ArrayBounds | LocalBounds) // Scudo hardened allocator SANITIZER("scudo", Scudo) +// Fortran contiguous pointer checks +SANITIZER("discontiguous", Discontiguous) + // Magic group, containing all sanitizers. For example, "-fno-sanitize=all" // can be used to disable all the sanitizers. SANITIZER_GROUP("all", All, ~SanitizerMask()) diff --git a/clang/include/clang/Driver/CMakeLists.txt b/clang/include/clang/Driver/CMakeLists.txt index a9d988047920..8543ae37ca4c 100644 --- a/clang/include/clang/Driver/CMakeLists.txt +++ b/clang/include/clang/Driver/CMakeLists.txt @@ -1,3 +1,7 @@ set(LLVM_TARGET_DEFINITIONS Options.td) -tablegen(LLVM Options.inc -gen-opt-parser-defs) +if(LLVM_ENABLE_CLASSIC_FLANG) + tablegen(LLVM Options.inc -DENABLE_CLASSIC_FLANG -gen-opt-parser-defs) +else() + tablegen(LLVM Options.inc -gen-opt-parser-defs) +endif() add_public_tablegen_target(ClangDriverOptions) diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 02e5c4cbb4bf..7af3a7e204d7 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -195,7 +195,11 @@ def hip_Group : OptionGroup<"">, Group, def m_Group : OptionGroup<"">, Group, DocName<"Target-dependent compilation options">, +#ifdef ENABLE_CLASSIC_FLANG + Visibility<[ClangOption, CLOption, FlangOption]>; +#else Visibility<[ClangOption, CLOption]>; +#endif def hlsl_Group : OptionGroup<"">, Group, DocName<"HLSL options">, @@ -231,10 +235,18 @@ def m_wasm_Features_Group : OptionGroup<"">, def m_wasm_Features_Driver_Group : OptionGroup<"">, Group, DocName<"WebAssembly Driver">; def m_x86_Features_Group : OptionGroup<"">, +#ifdef ENABLE_CLASSIC_FLANG + Group, Visibility<[ClangOption, CLOption, FlangOption]>, +#else Group, Visibility<[ClangOption, CLOption]>, +#endif DocName<"X86">; def m_x86_AVX10_Features_Group : OptionGroup<"">, +#ifdef ENABLE_CLASSIC_FLANG + Group, Visibility<[ClangOption, CLOption, FlangOption]>, +#else Group, Visibility<[ClangOption, CLOption]>, +#endif DocName<"X86 AVX10">; def m_riscv_Features_Group : OptionGroup<"">, Group, DocName<"RISC-V">; @@ -684,7 +696,11 @@ def ccc_gcc_name : Separate<["-"], "ccc-gcc-name">, InternalDriverOpt, class InternalDebugOpt : Group, Flags<[NoXarchOption, HelpHidden]>, +#ifdef ENABLE_CLASSIC_FLANG + Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>; +#else Visibility<[ClangOption, CLOption, DXCOption]>; +#endif def ccc_install_dir : Separate<["-"], "ccc-install-dir">, InternalDebugOpt, HelpText<"Simulate installation in the given directory">; def ccc_print_phases : Flag<["-"], "ccc-print-phases">, @@ -1545,6 +1561,11 @@ def d_Joined : Joined<["-"], "d">, Group; def emit_ast : Flag<["-"], "emit-ast">, Visibility<[ClangOption, CLOption, DXCOption]>, HelpText<"Emit Clang AST files for source inputs">; +#ifdef ENABLE_CLASSIC_FLANG +def emit_flang_llvm : Flag<["-"], "emit-flang-llvm">, + Visibility<[FlangOption]>, + HelpText<"Emit Flang LLVM files for source inputs">; +#endif def emit_llvm : Flag<["-"], "emit-llvm">, Visibility<[ClangOption, CC1Option, FC1Option, FlangOption]>, Group, @@ -3459,10 +3480,17 @@ def fveclib : Joined<["-"], "fveclib=">, Group, HelpTextForVariants<[ClangOption, CC1Option], "Use the given vector functions library. " "Note: -fveclib={ArmPL,SLEEF} implies -fno-math-errno">, +#ifdef ENABLE_CLASSIC_FLANG + Values<"Accelerate,libmvec,MASSV,PGMATH,SVML,SLEEF,Darwin_libsystem_m,ArmPL,AMDLIBM,none">, + NormalizedValuesScope<"llvm::driver::VectorLibrary">, + NormalizedValues<["Accelerate", "LIBMVEC", "MASSV", "PGMATH", "SVML", "SLEEF", + "Darwin_libsystem_m", "ArmPL", "AMDLIBM", "NoLibrary"]>, +#else Values<"Accelerate,libmvec,MASSV,SVML,SLEEF,Darwin_libsystem_m,ArmPL,AMDLIBM,none">, NormalizedValuesScope<"llvm::driver::VectorLibrary">, NormalizedValues<["Accelerate", "LIBMVEC", "MASSV", "SVML", "SLEEF", "Darwin_libsystem_m", "ArmPL", "AMDLIBM", "NoLibrary"]>, +#endif MarshallingInfoEnum, "NoLibrary">; def fno_lax_vector_conversions : Flag<["-"], "fno-lax-vector-conversions">, Group, Alias, AliasArgs<["none"]>; @@ -3500,7 +3528,11 @@ def fno_realloc_lhs : Flag<["-"], "fno-realloc-lhs">, Group, def fno_stack_protector : Flag<["-"], "fno-stack-protector">, Group, HelpText<"Disable the use of stack protectors">; def fno_strict_aliasing : Flag<["-"], "fno-strict-aliasing">, Group, +#ifdef ENABLE_CLASSIC_FLANG + Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>, +#else Visibility<[ClangOption, CLOption, DXCOption]>, +#endif HelpText<"Disable optimizations based on strict aliasing rules">; def fstruct_path_tbaa : Flag<["-"], "fstruct-path-tbaa">, Group; def fno_struct_path_tbaa : Flag<["-"], "fno-struct-path-tbaa">, Group; @@ -3772,6 +3804,9 @@ defm openmp_optimistic_collapse : BoolFOption<"openmp-optimistic-collapse", PosFlag, NegFlag, BothFlags<[NoArgumentUnused, HelpHidden], []>>; def static_openmp: Flag<["-"], "static-openmp">, +#ifdef ENABLE_CLASSIC_FLANG + Visibility<[ClangOption, FlangOption]>, +#endif HelpText<"Use the static host OpenMP runtime while linking.">; def fopenmp_new_driver : Flag<["-"], "fopenmp-new-driver">, Flags<[HelpHidden]>, HelpText<"Use the new driver for OpenMP offloading.">; @@ -4518,15 +4553,31 @@ def gdbx : Flag<["-"], "gdbx">, Group; // Equivalent to our default dwarf version. Forces usual dwarf emission when // CodeView is enabled. def gdwarf : Flag<["-"], "gdwarf">, Group, +#ifdef ENABLE_CLASSIC_FLANG + Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>, +#else Visibility<[ClangOption, CLOption, DXCOption]>, +#endif HelpText<"Generate source-level debug information with the default dwarf version">; def gdwarf_2 : Flag<["-"], "gdwarf-2">, Group, +#ifdef ENABLE_CLASSIC_FLANG + Visibility<[ClangOption, FlangOption]>, +#endif HelpText<"Generate source-level debug information with dwarf version 2">; def gdwarf_3 : Flag<["-"], "gdwarf-3">, Group, +#ifdef ENABLE_CLASSIC_FLANG + Visibility<[ClangOption, FlangOption]>, +#endif HelpText<"Generate source-level debug information with dwarf version 3">; def gdwarf_4 : Flag<["-"], "gdwarf-4">, Group, +#ifdef ENABLE_CLASSIC_FLANG + Visibility<[ClangOption, FlangOption]>, +#endif HelpText<"Generate source-level debug information with dwarf version 4">; def gdwarf_5 : Flag<["-"], "gdwarf-5">, Group, +#ifdef ENABLE_CLASSIC_FLANG + Visibility<[ClangOption, FlangOption]>, +#endif HelpText<"Generate source-level debug information with dwarf version 5">; def gdwarf64 : Flag<["-"], "gdwarf64">, Group, Visibility<[ClangOption, CC1Option, CC1AsOption]>, @@ -4612,9 +4663,16 @@ def gno_simple_template_names : Flag<["-"], "gno-simple-template-names">, def ggnu_pubnames : Flag<["-"], "ggnu-pubnames">, Group, Visibility<[ClangOption, CC1Option]>; def gno_gnu_pubnames : Flag<["-"], "gno-gnu-pubnames">, Group; +#ifdef ENABLE_CLASSIC_FLANG +def gpubnames : Flag<["-"], "gpubnames">, Group, + Visibility<[ClangOption, CC1Option, FlangOption]>; +def gno_pubnames : Flag<["-"], "gno-pubnames">, Group, + Visibility<[ClangOption, CC1Option, FlangOption]>; +#else def gpubnames : Flag<["-"], "gpubnames">, Group, Visibility<[ClangOption, CC1Option]>; def gno_pubnames : Flag<["-"], "gno-pubnames">, Group; +#endif def gdwarf_aranges : Flag<["-"], "gdwarf-aranges">, Group; def gmodules : Flag <["-"], "gmodules">, Group, HelpText<"Generate debug info with external references to clang modules" @@ -5970,24 +6028,12 @@ def target : Joined<["--"], "target=">, Flags<[NoXarchOption]>, def darwin_target_variant : Separate<["-"], "darwin-target-variant">, Flags<[NoXarchOption]>, Visibility<[ClangOption, CLOption]>, HelpText<"Generate code for an additional runtime variant of the deployment target">; - -//===----------------------------------------------------------------------===// -// Print CPU info options (clang, clang-cl, flang) -//===----------------------------------------------------------------------===// - -let Visibility = [ClangOption, CC1Option, CLOption, FlangOption, FC1Option] in { - def print_supported_cpus : Flag<["-", "--"], "print-supported-cpus">, Group, - HelpText<"Print supported cpu models for the given target (if target is not " - "specified,it will print the supported cpus for the default target)">, + Visibility<[ClangOption, CC1Option, CLOption]>, + HelpText<"Print supported cpu models for the given target (if target is not specified," + " it will print the supported cpus for the default target)">, MarshallingInfoFlag>; - -def : Flag<["-"], "mcpu=help">, Alias; -def : Flag<["-"], "mtune=help">, Alias; - -} // let Visibility = [ClangOption, CC1Option, CLOption, FlangOption, FC1Option] - def print_supported_extensions : Flag<["-", "--"], "print-supported-extensions">, Visibility<[ClangOption, CC1Option, CLOption]>, HelpText<"Print supported -march extensions (RISC-V, AArch64 and ARM only)">, @@ -5997,10 +6043,16 @@ def print_enabled_extensions : Flag<["-", "--"], "print-enabled-extensions">, HelpText<"Print the extensions enabled by the given target and -march/-mcpu options." " (AArch64 and RISC-V only)">, MarshallingInfoFlag>; +def : Flag<["-"], "mcpu=help">, Alias; +def : Flag<["-"], "mtune=help">, Alias; def time : Flag<["-"], "time">, HelpText<"Time individual commands">; def traditional_cpp : Flag<["-", "--"], "traditional-cpp">, +#ifdef ENABLE_CLASSIC_FLANG + Visibility<[ClangOption, CC1Option, FlangOption]>, +#else Visibility<[ClangOption, CC1Option]>, +#endif HelpText<"Enable some traditional CPP emulation">, MarshallingInfoFlag>; def traditional : Flag<["-", "--"], "traditional">; @@ -6077,7 +6129,12 @@ def fno_integrated_objemitter : Flag<["-"], "fno-integrated-objemitter">, Group, HelpText<"Use external machine object code emitter.">; +#ifdef ENABLE_CLASSIC_FLANG +def : Flag<["-"], "integrated-as">, Alias, + Visibility<[ClangOption, CC1Option, FlangOption]>; +#else def : Flag<["-"], "integrated-as">, Alias; +#endif def : Flag<["-"], "no-integrated-as">, Alias, Visibility<[ClangOption, CC1Option, FlangOption]>; @@ -6937,6 +6994,20 @@ def module_dir : JoinedOrSeparate<["-"], "module-dir">, MetaVarName<"">, It is also added to the list of directories to be searched by an USE statement. The default is the current directory.}]>; +#ifdef ENABLE_CLASSIC_FLANG +// Define a group for Fortran source format options. +def fortran_format_Group : OptionGroup<"Fortran format Group">, Group; +def ffixed_form : Flag<["-"], "ffixed-form">, Group, + HelpText<"Process source files in fixed form">; +def fno_fixed_form : Flag<["-"], "fno-fixed-form">, Group, + HelpText<"Disable fixed-form format for Fortran">; +def ffree_form : Flag<["-"], "ffree-form">, Group, + HelpText<"Process source files in free form">; +def fno_free_form : Flag<["-"], "fno-free-form">, Group, + HelpText<"Disable free-form format for Fortran">; +def ffixed_line_length_VALUE : Joined<["-"], "ffixed-line-length-">, Group, + HelpText<"Set line length in fixed-form format Fortran, current supporting only 72 and 132 characters">; +#else def ffixed_form : Flag<["-"], "ffixed-form">, Group, HelpText<"Process source files in fixed form">; def ffree_form : Flag<["-"], "ffree-form">, Group, @@ -6946,14 +7017,21 @@ def ffixed_line_length_EQ : Joined<["-"], "ffixed-line-length=">, Group DocBrief<[{Set column after which characters are ignored in typical fixed-form lines in the source file}]>; def ffixed_line_length_VALUE : Joined<["-"], "ffixed-line-length-">, Group, Alias; +#endif def fconvert_EQ : Joined<["-"], "fconvert=">, Group, HelpText<"Set endian conversion of data for unformatted files">; def fdefault_double_8 : Flag<["-"],"fdefault-double-8">, Group, HelpText<"Set the default double precision kind to an 8 byte wide type">; def fdefault_integer_8 : Flag<["-"],"fdefault-integer-8">, Group, HelpText<"Set the default integer and logical kind to an 8 byte wide type">; +#ifdef ENABLE_CLASSIC_FLANG +def fno_default_integer_8 : Flag<["-"], "fno-default-integer-8">, Group; +#endif def fdefault_real_8 : Flag<["-"],"fdefault-real-8">, Group, HelpText<"Set the default real kind to an 8 byte wide type">; +#ifdef ENABLE_CLASSIC_FLANG +def fno_default_real_8 : Flag<["-"], "fno-default-real-8">, Group; +#endif def fdisable_real_3 : Flag<["-"],"fdisable-real-3">, Group, HelpText<"Disable real(KIND=3) from TargetCharacteristics">, Flags<[HelpHidden]>; def fdisable_real_10 : Flag<["-"],"fdisable-real-10">, Group, @@ -6972,6 +7050,17 @@ def fintrinsic_modules_path : Separate<["-"], "fintrinsic-modules-path">, Group DocBrief<[{This option specifies the location of pre-compiled intrinsic modules, if they are not in the default location expected by the compiler.}]>; +#ifdef ENABLE_CLASSIC_FLANG +def fbackslash : Flag<["-"], "fbackslash">, Group, + HelpText<"Specify that backslash in string introduces an escape character">, + DocBrief<[{Change the interpretation of backslashes in string literals from +a single backslash character to "C-style" escape characters.}]>; +def fno_backslash : Flag<["-"], "fno-backslash">, Group; +// Add the options -f(no-)implicit-none and -f(no-)automatic for compatibility +// reason. They are not implemented yet in Classic Flang for now. +defm implicit_none : BooleanFFlag<"implicit-none">, Group; +def fno_automatic : Flag<["-"], "fno-automatic">, Group; +#else defm backslash : OptInFC1FFlag<"backslash", "Specify that backslash in string introduces an escape character">; defm xor_operator : OptInFC1FFlag<"xor-operator", "Enable .XOR. as a synonym of .NEQV.">; defm logical_abbreviations : OptInFC1FFlag<"logical-abbreviations", "Enable logical abbreviations">; @@ -6984,6 +7073,7 @@ defm unsigned : OptInFC1FFlag<"unsigned", "Enables UNSIGNED type">; def fno_automatic : Flag<["-"], "fno-automatic">, Group, HelpText<"Implies the SAVE attribute for non-automatic local objects in subprograms unless RECURSIVE">; +#endif defm save_main_program : BoolOptionWithoutMarshalling<"f", "save-main-program", PosFlag, Group; } // let Visibility = [FC1Option, FlangOption] +#ifdef ENABLE_CLASSIC_FLANG +def J : JoinedOrSeparate<["-"], "J">, + Flags<[RenderJoined]>, Visibility<[FlangOption, FC1Option]>, + Group; + +let Visibility = [FlangOption] in { +def no_fortran_main : Flag<["-"], "fno-fortran-main">, + Visibility<[FlangOption]>, Group, + HelpText<"Do not include Fortran_main.a (provided by Flang) when linking">; +} // let Visibility = [ FlangOption ] +#else def J : JoinedOrSeparate<["-"], "J">, Flags<[RenderJoined]>, Visibility<[FlangOption, FC1Option]>, Group, Alias; +#endif //===----------------------------------------------------------------------===// // FC1 Options @@ -9136,3 +9238,146 @@ def wasm_opt : Flag<["--"], "wasm-opt">, Group, HelpText<"Enable the wasm-opt optimizer (default)">, MarshallingInfoNegativeFlag>; + +#ifdef ENABLE_CLASSIC_FLANG +// Classic Flang options that we recognize in the driver and pass along when +// invoking flang1/flang2 to compile Fortran code. +def flang_rt_Group : OptionGroup<"Flang runtime library Group">; +def pgi_fortran_Group : OptionGroup<"PGI Fortran compatibility Group">, + Flags<[HelpHidden]>; + +// Classic Flang-specific options +multiclass BooleanKFlag { + def _on : Flag<["-"], "K"#name>; + def _off : Flag<["-"], "Kno"#name>; +} + +multiclass BooleanMFlag { + def _on : Flag<["-"], "M"#name>; + def _off : Flag<["-"], "Mno"#name>; +} + +let Visibility = [FlangOption] in { + +def Mfixed : Flag<["-"], "Mfixed">, Group, + HelpText<"Force fixed-form format Fortran">, + Flags<[HelpHidden]>; +def Mfree_on: Flag<["-"], "Mfree">, Group, + HelpText<"Enable free-form format for Fortran">, + Flags<[HelpHidden]>; +def Mfree_off: Flag<["-"], "Mnofree">, Group, + HelpText<"Disable free-form format for Fortran">, + Flags<[HelpHidden]>; +def Mfreeform_on: Flag<["-"], "Mfreeform">, Group, + HelpText<"Enable free-form format for Fortran">, + Flags<[HelpHidden]>; +def Mfreeform_off: Flag<["-"], "Mnofreeform">, Group, + HelpText<"Disable free-form format for Fortran">, + Flags<[HelpHidden]>; + +def Minfo_EQ : CommaJoined<["-"], "Minfo=">, + HelpText<"Diagnostic information about successful optimizations">, + Values<"all,vect,inline">; +def Minfoall : Flag<["-"], "Minfo">, + HelpText<"Diagnostic information about all successful optimizations">; +def Mneginfo_EQ : CommaJoined<["-"], "Mneginfo=">, + HelpText<"Diagnostic information about missed optimizations">, + Values<"all,vect,inline">; +def Mneginfoall : Flag<["-"], "Mneginfo">, + HelpText<"Diagnostic information about all missed optimizations">; + +def Mipa: Joined<["-"], "Mipa">, Group; +def Mstackarrays: Joined<["-"], "Mstack_arrays">, Group; +def pc: JoinedOrSeparate<["-"], "pc">, Group; +def Mfprelaxed: Joined<["-"], "Mfprelaxed">, Group; +def Mnofprelaxed: Joined<["-"], "Mnofprelaxed">, Group; +defm Mstride0: BooleanMFlag<"stride0">, Group; +defm Mrecursive: BooleanMFlag<"recursive">, Group; +defm Mreentrant: BooleanMFlag<"reentrant">, Group; +defm Mbounds: BooleanMFlag<"bounds">, Group; +def Mdaz_on: Flag<["-"], "Mdaz">, Group, + HelpText<"Treat denormalized numbers as zero">; +def Mdaz_off: Flag<["-"], "Mnodaz">, Group, + HelpText<"Disable treating denormalized numbers as zero">; +def Kieee_on : Flag<["-"], "Kieee">, Group, + HelpText<"Enable IEEE division">; +def Kieee_off : Flag<["-"], "Knoieee">, Group, + HelpText<"Disable IEEE division">; +def Mextend : Flag<["-"], "Mextend">, Group, + HelpText<"Allow lines up to 132 characters in Fortran sources">; +def Mpreprocess : Flag<["-"], "Mpreprocess">, Group, + HelpText<"Preprocess Fortran files">; +def Mstandard: Flag<["-"], "Mstandard">, Group, + HelpText<"Check Fortran standard conformance">; +def Mchkptr: Flag<["-"], "Mchkptr">, Group; +def Mwritable_constants: Flag<["-"], "Mwritable-constants">, Group, + HelpText<"Store constants in the writable data segment">; +defm Minline: BooleanMFlag<"inline">, Group; +def fma: Flag<["-"], "fma">, Group, + HelpText<"Enable generation of FMA instructions">; +def nofma: Flag<["-"], "nofma">, Group, + HelpText<"Disable generation of FMA instructions">; +defm Mfma: BooleanMFlag<"fma">, Group, + HelpText<"Enable generation of FMA instructions">; +def mp: Flag<["-"], "mp">, Group, + HelpText<"Enable OpenMP">; +def nomp: Flag<["-"], "nomp">, Group, + HelpText<"Do not link with OpenMP library libomp">; +def Mflushz_on: Flag<["-"], "Mflushz">, Group, + HelpText<"Set SSE to flush-to-zero mode">; +def Mflushz_off: Flag<["-"], "Mnoflushz">, Group, + HelpText<"Disabling setting SSE to flush-to-zero mode">; +def Msave_on: Flag<["-"], "Msave">, Group, + HelpText<"Assume all Fortran variables have SAVE attribute">; +def Msave_off: Flag<["-"], "Mnosave">, Group, + HelpText<"Assume no Fortran variables have SAVE attribute">; +def Mcache_align_on: Flag<["-"], "Mcache_align">, Group, + HelpText<"Align large objects on cache-line boundaries">; +def Mcache_align_off: Flag<["-"], "Mnocache_align">, Group, + HelpText<"Disable aligning large objects on cache-line boundaries">; +def ModuleDir : Separate<["-"], "module">, Group, + HelpText<"Fortran module path">; +def Minform_EQ : Joined<["-"], "Minform=">, + HelpText<"Set error level of messages to display">; +def Mallocatable_EQ : Joined<["-"], "Mallocatable=">, + HelpText<"Select semantics for assignments to allocatables (F03 or F95)">; +def Mbyteswapio: Flag<["-"], "Mbyteswapio">, Group, + HelpText<"Swap byte-order for unformatted input/output">; +def byteswapio: Flag<["-"], "byteswapio">, Group, + HelpText<"Swap byte-order for unformatted input/output">; +def Mbackslash: Flag<["-"], "Mbackslash">, Group, + HelpText<"Treat backslash like any other character in character strings">; +def Mnobackslash: Flag<["-"], "Mnobackslash">, Group, + HelpText<"Treat backslash as C-style escape character">; +def staticFlangLibs: Flag<["-"], "static-flang-libs">, Group, + HelpText<"Link using static Flang libraries">; +def noFlangLibs: Flag<["-"], "no-flang-libs">, Group, + HelpText<"Do not link against Flang libraries">; +def r8: Flag<["-"], "r8">, Group, + HelpText<"Treat REAL as REAL*8">; +def i8: Flag<["-"], "i8">, Group, + HelpText<"Treat INTEGER and LOGICAL as INTEGER*8 and LOGICAL*8">; +def Mnomain: Flag<["-"], "Mnomain">, Group, + HelpText<"Don't link in Fortran main">; +def frelaxed_math : Flag<["-"], "frelaxed-math">, Group, + HelpText<"Use relaxed Math intrinsic functions">; +def Memit_dwarf_common_blocks_name: Flag<["-"], "Memit-dwarf-common-blocks-name">, + Group, HelpText<"Emit COMMON blocks name in DWARF">; +def Munixlogical: Flag<["-"], "Munixlogical">, Group, + HelpText<"Use unixlogical for all loigical operations">; + +// Flang internal debug options +def Mx_EQ : Joined<["-"], "Mx,">, Group; +def My_EQ : Joined<["-"], "My,">, Group; +def Hx_EQ : Joined<["-"], "Hx,">, Group; +def Hy_EQ : Joined<["-"], "Hy,">, Group; +def Wm_EQ : Joined<["-"], "Wm,">, Group; + +def Mq_EQ : Joined<["-"], "Mq,">, Group; +def Hq_EQ : Joined<["-"], "Hq,">, Group; +def Mqq_EQ : Joined<["-"], "Mqq,">, Group; +def Hqq_EQ : Joined<["-"], "Hqq,">, Group; +def Wh_EQ : Joined<["-"], "Wh,">, Group; + +} // let Visibility = [FlangOption] +#endif diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h index 7d1d8feebf35..f9586e013d02 100644 --- a/clang/include/clang/Driver/ToolChain.h +++ b/clang/include/clang/Driver/ToolChain.h @@ -673,6 +673,16 @@ class ToolChain { AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const; +#ifdef ENABLE_CLASSIC_FLANG + /// \brief Add the flang arguments for system include paths. + /// + /// This routine is responsible for adding the -stdinc argument to + /// include headers and module files from standard system header directories. + virtual void + AddFlangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &Flang1Args) const { } +#endif + /// Add options that need to be passed to cc1 for this target. virtual void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, @@ -790,6 +800,13 @@ class ToolChain { virtual void AddHIPRuntimeLibArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const {} +#ifdef ENABLE_CLASSIC_FLANG + /// AddFortranStdlibLibArgs - Add the system specific linker arguments to use + /// for the given Fortran runtime library type. + virtual void AddFortranStdlibLibArgs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const; +#endif + /// Return sanitizers which are available in this toolchain. virtual SanitizerMask getSupportedSanitizers() const; diff --git a/clang/include/clang/Driver/Types.def b/clang/include/clang/Driver/Types.def index 214c5e7a789f..bd3aa208678a 100644 --- a/clang/include/clang/Driver/Types.def +++ b/clang/include/clang/Driver/Types.def @@ -88,8 +88,15 @@ TYPE("assembler-with-cpp", Asm, PP_Asm, "S", phases // modules when Flang needs to emit pre-processed files. Therefore, the // `PP_TYPE` is set to `PP_Fortran` so that the driver is fine with // "pre-processing a pre-processed file". +#ifdef ENABLE_CLASSIC_FLANG +TYPE("f77", PP_F_FixedForm, INVALID, "f", phases::Compile, phases::Backend, phases::Assemble, phases::Link) +TYPE("f77-cpp-input", F_FixedForm, PP_F_FixedForm, "F", phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble, phases::Link) +TYPE("f95", PP_F_FreeForm, INVALID, "f95", phases::Compile, phases::Backend, phases::Assemble, phases::Link) +TYPE("f95-cpp-input", F_FreeForm, PP_F_FreeForm, "F95", phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble, phases::Link) +#else TYPE("f95", PP_Fortran, PP_Fortran, "i", phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble, phases::Link) TYPE("f95-cpp-input", Fortran, PP_Fortran, nullptr, phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble, phases::Link) +#endif TYPE("java", Java, INVALID, nullptr, phases::Compile, phases::Backend, phases::Assemble, phases::Link) // LLVM IR/LTO types. We define separate types for IR and LTO because LTO diff --git a/clang/include/clang/Driver/Types.h b/clang/include/clang/Driver/Types.h index 121b58a6b477..cab331a74b36 100644 --- a/clang/include/clang/Driver/Types.h +++ b/clang/include/clang/Driver/Types.h @@ -95,6 +95,14 @@ namespace types { /// isOpenCL - Is this an "OpenCL" input. bool isOpenCL(ID Id); +#ifdef ENABLE_CLASSIC_FLANG + /// isFreeFormFortran -- is it a free form layout Fortran input + bool isFreeFormFortran(ID Id); + + /// isFixedFormFortran -- is it a fixed form layout Fortran input + bool isFixedFormFortran(ID Id); +#endif + /// isHLSL - Is this an HLSL input. bool isHLSL(ID Id); diff --git a/clang/include/clang/Frontend/Utils.h b/clang/include/clang/Frontend/Utils.h index 604e42067a3f..25811b66d0ad 100644 --- a/clang/include/clang/Frontend/Utils.h +++ b/clang/include/clang/Frontend/Utils.h @@ -15,10 +15,13 @@ #include "clang/Basic/Diagnostic.h" #include "clang/Basic/LLVM.h" +#include "clang/Basic/TargetInfo.h" #include "clang/Driver/OptionUtils.h" #include "clang/Frontend/DependencyOutputOptions.h" +#include "llvm/ADT/APInt.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSet.h" @@ -31,6 +34,12 @@ #include #include +namespace llvm { + +class StringRef; + +} // namespace llvm + namespace clang { class ASTReader; @@ -39,6 +48,7 @@ class CompilerInvocation; class DiagnosticsEngine; class ExternalSemaSource; class FrontendOptions; +class MacroBuilder; class PCHContainerReader; class Preprocessor; class PreprocessorOptions; @@ -56,6 +66,29 @@ void InitializePreprocessor(Preprocessor &PP, const PreprocessorOptions &PPOpts, void DoPrintPreprocessedInput(Preprocessor &PP, raw_ostream *OS, const PreprocessorOutputOptions &Opts); +/// DefineTypeSize - Emit a macro to the predefines buffer that declares a macro +/// named MacroName with the max value for a type with width 'TypeWidth' a +/// signedness of 'isSigned' and with a value suffix of 'ValSuffix' (e.g. LL). +template +static void DefineTypeSize(const Twine &MacroName, unsigned TypeWidth, + StringRef ValSuffix, bool isSigned, + T &Builder) { + static_assert(std::is_base_of::value, "Illegal T value"); + llvm::APInt MaxVal = isSigned ? llvm::APInt::getSignedMaxValue(TypeWidth) + : llvm::APInt::getMaxValue(TypeWidth); + Builder.defineMacro(MacroName, toString(MaxVal, 10, isSigned) + ValSuffix); +} + +/// DefineTypeSize - An overloaded helper that uses TargetInfo to determine +/// the width, suffix, and signedness of the given type +template +static void DefineTypeSize(const Twine &MacroName, TargetInfo::IntType Ty, + const TargetInfo &TI, T &Builder) { + static_assert(std::is_base_of::value, "Illegal T value"); + DefineTypeSize(MacroName, TI.getTypeWidth(Ty), TI.getTypeConstantSuffix(Ty), + TI.isTypeSigned(Ty), Builder); +} + /// An interface for collecting the dependencies of a compilation. Users should /// use \c attachToPreprocessor and \c attachToASTReader to get all of the /// dependencies. diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index 3e65eeb3755d..f74ecd177fcc 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -613,8 +613,11 @@ bool EmitAssemblyHelper::AddEmitPasses(legacy::PassManager &CodeGenPasses, raw_pwrite_stream &OS, raw_pwrite_stream *DwoOS) { // Add LibraryInfo. - std::unique_ptr TLII( - llvm::driver::createTLII(TargetTriple, CodeGenOpts.getVecLib())); + bool TargetHasAVX512 = + std::find(TargetOpts.Features.begin(), TargetOpts.Features.end(), + "+avx512f") != TargetOpts.Features.end(); + std::unique_ptr TLII(llvm::driver::createTLII( + TargetTriple, CodeGenOpts.getVecLib(), TargetHasAVX512)); CodeGenPasses.add(new TargetLibraryInfoWrapperPass(*TLII)); // Normal mode, emit a .s or .o file by running the code generator. Note, @@ -964,8 +967,11 @@ void EmitAssemblyHelper::RunOptimizationPipeline( // Register the target library analysis directly and give it a customized // preset TLI. - std::unique_ptr TLII( - llvm::driver::createTLII(TargetTriple, CodeGenOpts.getVecLib())); + bool TargetHasAVX512 = + std::find(TargetOpts.Features.begin(), TargetOpts.Features.end(), + "+avx512f") != TargetOpts.Features.end(); + std::unique_ptr TLII(llvm::driver::createTLII( + TargetTriple, CodeGenOpts.getVecLib(), TargetHasAVX512)); FAM.registerPass([&] { return TargetLibraryAnalysis(*TLII); }); // Register all the basic analyses with the managers. diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index d28ef60f84e9..c99a20d619e0 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -4202,7 +4202,8 @@ CGDebugInfo::getGlobalVariableForwardDeclaration(const VarDecl *VD) { auto Align = getDeclAlignIfRequired(VD, CGM.getContext()); auto *GV = DBuilder.createTempGlobalVariableFwdDecl( DContext, Name, LinkageName, Unit, Line, getOrCreateType(T, Unit), - !VD->isExternallyVisible(), nullptr, TemplateParameters, Align); + !VD->isExternallyVisible(), nullptr, TemplateParameters, + llvm::DINode::FlagZero, Align); FwdDeclReplaceMap.emplace_back( std::piecewise_construct, std::make_tuple(cast(VD->getCanonicalDecl())), @@ -5723,7 +5724,7 @@ void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var, Var->hasLocalLinkage(), true, Expr.empty() ? nullptr : DBuilder.createExpression(Expr), getOrCreateStaticDataMemberDeclarationOrNull(D), TemplateParameters, - Align, Annotations); + llvm::DINode::FlagZero, Align, Annotations); Var->addDebugInfo(GVE); } DeclCache[D->getCanonicalDecl()].reset(GVE); @@ -5802,7 +5803,7 @@ void CGDebugInfo::EmitGlobalVariable(const ValueDecl *VD, const APValue &Init) { GV.reset(DBuilder.createGlobalVariableExpression( DContext, Name, StringRef(), Unit, getLineNumber(VD->getLocation()), Ty, true, true, InitExpr, getOrCreateStaticDataMemberDeclarationOrNull(VarD), - TemplateParameters, Align)); + TemplateParameters, llvm::DINode::FlagZero, Align)); } void CGDebugInfo::EmitExternalVariable(llvm::GlobalVariable *Var, @@ -5820,7 +5821,8 @@ void CGDebugInfo::EmitExternalVariable(llvm::GlobalVariable *Var, llvm::DIGlobalVariableExpression *GVE = DBuilder.createGlobalVariableExpression( DContext, Name, StringRef(), Unit, getLineNumber(D->getLocation()), - Ty, false, false, nullptr, nullptr, nullptr, Align); + Ty, false, false, nullptr, nullptr, nullptr, llvm::DINode::FlagZero, + Align); Var->addDebugInfo(GVE); } diff --git a/clang/lib/Driver/CMakeLists.txt b/clang/lib/Driver/CMakeLists.txt index 5bdb6614389c..d38d1b136987 100644 --- a/clang/lib/Driver/CMakeLists.txt +++ b/clang/lib/Driver/CMakeLists.txt @@ -14,6 +14,12 @@ if(WIN32) set(system_libs version) endif() +if(LLVM_ENABLE_CLASSIC_FLANG) + set(TOOLCHAINS_FLANG_CPP ToolChains/ClassicFlang.cpp) +else() + set(TOOLCHAINS_FLANG_CPP ToolChains/Flang.cpp) +endif() + add_clang_library(clangDriver Action.cpp Compilation.cpp @@ -53,7 +59,7 @@ add_clang_library(clangDriver ToolChains/Cuda.cpp ToolChains/Darwin.cpp ToolChains/DragonFly.cpp - ToolChains/Flang.cpp + ${TOOLCHAINS_FLANG_CPP} ToolChains/FreeBSD.cpp ToolChains/Fuchsia.cpp ToolChains/Gnu.cpp diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 87855fdb7997..8b9765d26832 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -410,11 +410,15 @@ phases::ID Driver::getFinalPhase(const DerivedArgList &DAL, (PhaseArg = DAL.getLastArg(options::OPT_fmodule_header, options::OPT_fmodule_header_EQ))) { FinalPhase = phases::Precompile; + // -{fsyntax-only,-analyze,emit-ast} only run up to the compiler. } else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) || (PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) || (PhaseArg = DAL.getLastArg(options::OPT_print_enabled_extensions)) || (PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) || +#ifdef ENABLE_CLASSIC_FLANG + (PhaseArg = DAL.getLastArg(options::OPT_emit_flang_llvm)) || +#endif (PhaseArg = DAL.getLastArg(options::OPT_verify_pch)) || (PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) || (PhaseArg = DAL.getLastArg(options::OPT_rewrite_legacy_objc)) || @@ -2934,7 +2938,15 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args, // stdin must be handled specially. if (memcmp(Value, "-", 2) == 0) { if (IsFlangMode()) { +#ifdef ENABLE_CLASSIC_FLANG + // If running with -E, treat as needing preprocessing + if (!Args.hasArgNoClaim(options::OPT_E)) + Ty = types::TY_PP_F_FreeForm; + else + Ty = types::TY_F_FreeForm; +#else Ty = types::TY_Fortran; +#endif } else if (IsDXCMode()) { Ty = types::TY_HLSL; } else { @@ -2958,6 +2970,16 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args, // idea of what .s is. if (const char *Ext = strrchr(Value, '.')) Ty = TC.LookupTypeForExtension(Ext + 1); +#ifdef ENABLE_CLASSIC_FLANG + // If called with -E, treat the inputs as needing preprocessing + // regardless of extension + if (IsFlangMode() && Args.hasArgNoClaim(options::OPT_E)) { + if (Ty == types::TY_PP_F_FreeForm) + Ty = types::TY_F_FreeForm; + else if (Ty == types::TY_PP_F_FixedForm) + Ty = types::TY_F_FixedForm; + } +#endif if (Ty == types::TY_INVALID) { if (IsCLMode() && (Args.hasArgNoClaim(options::OPT_E) || CCGenDiagnostics)) @@ -4259,6 +4281,14 @@ void Driver::handleArguments(Compilation &C, DerivedArgList &Args, if (InputArg->isClaimed()) continue; +#ifdef ENABLE_CLASSIC_FLANG + // If the input is detected as already preprocessed (e.g. has the .f95 + // extension), and the user specifies -E, preprocess the file anyway. + if (IsFlangMode() && InitialPhase == phases::Compile && + FinalPhase == phases::Preprocess) + continue; +#endif + // Claim here to avoid the more general unused warning. InputArg->claim(); @@ -4604,8 +4634,7 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args, // Use the -mcpu=? flag as the dummy input to cc1. Actions.clear(); - Action *InputAc = C.MakeAction( - *A, IsFlangMode() ? types::TY_Fortran : types::TY_C); + Action *InputAc = C.MakeAction(*A, types::TY_C); Actions.push_back( C.MakeAction(InputAc, types::TY_Nothing)); for (auto &I : Inputs) @@ -5090,6 +5119,10 @@ Action *Driver::ConstructPhaseAction( return C.MakeAction(Input, types::TY_Nothing); if (Args.hasArg(options::OPT_extract_api)) return C.MakeAction(Input, types::TY_API_INFO); +#ifdef ENABLE_CLASSIC_FLANG + if (IsFlangMode()) + return C.MakeAction(Input, types::TY_LLVM_IR); +#endif return C.MakeAction(Input, types::TY_LLVM_BC); } case phases::Backend: { @@ -5557,6 +5590,12 @@ class ToolSelector final { if (!T->hasIntegratedBackend() && !(OutputIsLLVM && T->canEmitIR())) return nullptr; +#ifdef ENABLE_CLASSIC_FLANG + // Classic Flang is not integrated with the backend. + if (C.getDriver().IsFlangMode() && !T->hasIntegratedAssembler()) + return nullptr; +#endif + if (T->canEmitIR() && ((SaveTemps && !InputIsBitcode) || EmbedBitcode)) return nullptr; @@ -5572,8 +5611,17 @@ class ToolSelector final { /// are appended to \a CollapsedOffloadAction. void combineWithPreprocessor(const Tool *T, ActionList &Inputs, ActionList &CollapsedOffloadAction) { +#ifdef ENABLE_CLASSIC_FLANG + // flang1 always combines preprocessing and compilation. + // Do not return early even when -save-temps is used. + if (!T || !T->hasIntegratedCPP() || + (strcmp(T->getName(), "classic-flang") && + !canCollapsePreprocessorAction())) + return; +#else if (!T || !canCollapsePreprocessorAction() || !T->hasIntegratedCPP()) return; +#endif // Attempt to get a preprocessor action dependence. ActionList PreprocessJobOffloadActions; @@ -6855,8 +6903,11 @@ bool Driver::ShouldUseFlangCompiler(const JobAction &JA) const { return false; // And say "no" if this is not a kind of action flang understands. - if (!isa(JA) && !isa(JA) && - !isa(JA) && !isa(JA)) + if (!isa(JA) && !isa(JA) +#ifndef ENABLE_CLASSIC_FLANG + && !isa(JA) +#endif + ) return false; return true; diff --git a/clang/lib/Driver/OffloadBundler.cpp b/clang/lib/Driver/OffloadBundler.cpp index 12d763e5c65b..4dbd02ef1825 100644 --- a/clang/lib/Driver/OffloadBundler.cpp +++ b/clang/lib/Driver/OffloadBundler.cpp @@ -918,6 +918,10 @@ CreateFileHandler(MemoryBuffer &FirstInput, return std::make_unique(/*Comment=*/"#"); if (FilesType == "ll") return std::make_unique(/*Comment=*/";"); +#ifdef ENABLE_CLASSIC_FLANG + if (FilesType == "f95") + return std::make_unique(/*Comment=*/"!"); +#endif if (FilesType == "bc") return std::make_unique(BundlerConfig); if (FilesType == "s") diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index acf9d264d631..a74f3f389427 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -11,6 +11,9 @@ #include "ToolChains/Arch/ARM.h" #include "ToolChains/Arch/RISCV.h" #include "ToolChains/Clang.h" +#ifdef ENABLE_CLASSIC_FLANG +#include "ToolChains/ClassicFlang.h" +#endif #include "ToolChains/CommonArgs.h" #include "ToolChains/Flang.h" #include "ToolChains/InterfaceStubs.h" @@ -554,7 +557,11 @@ Tool *ToolChain::getClang() const { Tool *ToolChain::getFlang() const { if (!Flang) +#ifdef ENABLE_CLASSIC_FLANG + Flang.reset(new tools::ClassicFlang(*this)); +#else Flang.reset(new tools::Flang(*this)); +#endif return Flang.get(); } @@ -1047,13 +1054,13 @@ std::string ToolChain::GetStaticLibToolPath() const { types::ID ToolChain::LookupTypeForExtension(StringRef Ext) const { types::ID id = types::lookupTypeForExtension(Ext); - +#ifndef ENABLE_CLASSIC_FLANG // Flang always runs the preprocessor and has no notion of "preprocessed // fortran". Here, TY_PP_Fortran is coerced to TY_Fortran to avoid treating // them differently. if (D.IsFlangMode() && id == types::TY_PP_Fortran) id = types::TY_Fortran; - +#endif return id; } @@ -1413,6 +1420,31 @@ void ToolChain::AddCCKextLibArgs(const ArgList &Args, CmdArgs.push_back("-lcc_kext"); } +#ifdef ENABLE_CLASSIC_FLANG +void ToolChain::AddFortranStdlibLibArgs(const ArgList &Args, + ArgStringList &CmdArgs) const { + bool StaticFlangLibs = false; + if (Args.hasArg(options::OPT_staticFlangLibs)) { + StaticFlangLibs = true; + Args.ClaimAllArgs(options::OPT_staticFlangLibs); + } + + if (StaticFlangLibs && !Args.hasArg(options::OPT_static)) + CmdArgs.push_back("-Bstatic"); + CmdArgs.push_back("-lflang"); + CmdArgs.push_back("-lflangrti"); + CmdArgs.push_back("-lpgmath"); + if (StaticFlangLibs && !Args.hasArg(options::OPT_static)) + CmdArgs.push_back("-Bdynamic"); + + // Always link Fortran executables with pthreads. + CmdArgs.push_back("-lpthread"); + + if (!Triple.isOSDarwin()) + CmdArgs.push_back("-lrt"); +} +#endif + bool ToolChain::isFastMathRuntimeAvailable(const ArgList &Args, std::string &Path) const { // Don't implicitly link in mode-changing libraries in a shared library, since diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 57b7d2bd4698..99d5a1a3edf8 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -5869,6 +5869,66 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, } A->render(Args, CmdArgs); } +#ifdef ENABLE_CLASSIC_FLANG + // Use PGMATH for Classic Flang by default. + else { + CmdArgs.push_back("-fveclib=PGMATH"); + } + + std::string PassRemarkVal(""), PassRemarkOpt(""); + if (Args.getLastArg(options::OPT_Minfoall)) { + PassRemarkVal = ".*"; + Args.ClaimAllArgs(options::OPT_Minfoall); + } else if (Arg *A = Args.getLastArg(options::OPT_Minfo_EQ)) { + for (StringRef val : A->getValues()) { + if (val == "all") { + PassRemarkVal = ".*"; + break; + } else if (val == "inline" || val == "vect") { + PassRemarkVal += PassRemarkVal.empty() ? "" : "|"; + PassRemarkVal += val; + } else { + D.Diag(diag::err_drv_clang_unsupported_minfo_arg) + << A->getOption().getName() + << val.str(); + break; + } + } + } + PassRemarkOpt = "-pass-remarks=" + PassRemarkVal; + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back(Args.MakeArgString(PassRemarkOpt)); + Args.ClaimAllArgs(options::OPT_Minfo_EQ); + PassRemarkVal.clear(); + PassRemarkOpt.clear(); + + if (Args.getLastArg(options::OPT_Mneginfoall)) { + PassRemarkVal = ".*"; + Args.ClaimAllArgs(options::OPT_Mneginfoall); + } else if (Arg *A = Args.getLastArg(options::OPT_Mneginfo_EQ)) { + for (StringRef val : A->getValues()) { + if (val == "all") { + PassRemarkVal = ".*"; + break; + } else if (val == "inline" || val == "vect") { + PassRemarkVal += PassRemarkVal.empty() ? "" : "|"; + PassRemarkVal += val; + } else { + D.Diag(diag::err_drv_clang_unsupported_minfo_arg) + << A->getOption().getName() + << val.str(); + break; + } + } + } + PassRemarkOpt = "-pass-remarks-missed=" + PassRemarkVal; + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back(Args.MakeArgString(PassRemarkOpt)); + PassRemarkOpt = "-pass-remarks-analysis=" + PassRemarkVal; + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back(Args.MakeArgString(PassRemarkOpt)); + Args.ClaimAllArgs(options::OPT_Mneginfo_EQ); +#endif if (Args.hasFlag(options::OPT_fmerge_all_constants, options::OPT_fno_merge_all_constants, false)) diff --git a/clang/lib/Driver/ToolChains/ClassicFlang.cpp b/clang/lib/Driver/ToolChains/ClassicFlang.cpp new file mode 100644 index 000000000000..6354b32a18ca --- /dev/null +++ b/clang/lib/Driver/ToolChains/ClassicFlang.cpp @@ -0,0 +1,1237 @@ +//===-- ClassicFlang.cpp - Flang+LLVM ToolChain Implementations -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "ClassicFlang.h" +#include "CommonArgs.h" +#include "clang/Driver/InputInfo.h" +#include "clang/Basic/CharInfo.h" +#include "clang/Basic/LangOptions.h" +#include "clang/Basic/MacroBuilder.h" +#include "clang/Basic/ObjCRuntime.h" +#include "clang/Basic/TargetInfo.h" +#include "clang/Basic/TargetOptions.h" +#include "clang/Basic/Version.h" +#include "clang/Config/config.h" +#include "clang/Driver/DriverDiagnostic.h" +#include "clang/Driver/Options.h" +#include "clang/Driver/SanitizerArgs.h" +#include "clang/Driver/XRayArgs.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Frontend/Utils.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/Option/ArgList.h" +#include "llvm/Support/CodeGen.h" +#include "llvm/Support/Compression.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Path.h" +#include "llvm/Support/Process.h" +#include "llvm/Support/YAMLParser.h" +#include "llvm/TargetParser/TargetParser.h" + +#ifdef LLVM_ON_UNIX +#include // For getuid(). +#endif + +using namespace clang::driver; +using namespace clang::driver::tools; +using namespace clang; +using namespace llvm::opt; + +class ClassicFlangMacroBuilder : public MacroBuilder { + ArgStringList &CmdArgs; + const ArgList &DriverArgs; + public: + ClassicFlangMacroBuilder(ArgStringList &UpperCmdArgs, const ArgList &DriverArgs, llvm::raw_string_ostream &Output) + : MacroBuilder(Output), CmdArgs(UpperCmdArgs), DriverArgs(DriverArgs) { + } + virtual void defineMacro(const Twine &Name, const Twine &Value = "1", + Twine DeprecationMsg = "") override { + CmdArgs.push_back("-def"); + CmdArgs.push_back(DriverArgs.MakeArgString(Name + Twine('=') + Value)); + } +}; + +void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, const InputInfoList &Inputs, + const ArgList &Args, const char *LinkingOutput) const { + const Driver &D = getToolChain().getDriver(); + const llvm::Triple &Triple = getToolChain().getEffectiveTriple(); + ArgStringList CommonCmdArgs; + ArgStringList UpperCmdArgs; + ArgStringList LowerCmdArgs; + SmallString<256> Stem; + std::string OutFile; + bool NeedIEEE = true; + bool NeedFastMath = false; + bool NeedRelaxedMath = false; + bool AssociativeMath = false; + bool SignedZeros = true; + + // Check number of inputs for sanity. We need at least one input. + assert(Inputs.size() >= 1 && "Must have at least one input."); + + /***** Process file arguments to both parts *****/ + const InputInfo &Input = Inputs[0]; + types::ID InputType = Input.getType(); + // Check file type sanity + assert(types::isAcceptedByFlang(InputType) && "Can only accept Fortran"); + + if (Args.hasArg(options::OPT_fsyntax_only, options::OPT_E)) { + // For -fsyntax-only and -E produce temp files only + Stem = C.getDriver().GetTemporaryPath("", ""); + } else { + OutFile = Output.getFilename(); + Stem = llvm::sys::path::filename(OutFile); + llvm::sys::path::replace_extension(Stem, ""); + } + +#ifdef ENABLE_CLASSIC_FLANG + if (Args.hasArg(options::OPT_emit_flang_llvm)) { + // -emit-flang-llvm only supports asm output so claim -S to prevent warning + Args.ClaimAllArgs(options::OPT_S); + } +#endif + + // Add input file name to the compilation line + UpperCmdArgs.push_back(Input.getBaseInput()); + + // Add temporary output for ILM + const char * ILMFile = Args.MakeArgString(Stem + ".ilm"); + LowerCmdArgs.push_back(ILMFile); + C.addTempFile(ILMFile); + + // Generate -cmdline + std::string CmdLine("'+flang"); + // ignore the first argument which reads "--driver-mode=fortran" + for (unsigned i = 1; i < Args.getNumInputArgStrings(); ++i) { + CmdLine.append(" "); + CmdLine.append(Args.getArgString(i)); + } + CmdLine.append("'"); + + CommonCmdArgs.push_back("-cmdline"); + CommonCmdArgs.push_back(Args.MakeArgString(CmdLine)); + + /***** Process common args *****/ + + // Add "inform level" flag + if (Args.hasArg(options::OPT_Minform_EQ)) { + // Parse arguments to set its value + for (Arg *A : Args.filtered(options::OPT_Minform_EQ)) { + A->claim(); + CommonCmdArgs.push_back("-inform"); + CommonCmdArgs.push_back(A->getValue(0)); + } + } else { + // Default value + CommonCmdArgs.push_back("-inform"); + CommonCmdArgs.push_back("warn"); + } + + for (auto Arg : Args.filtered(options::OPT_Msave_on)) { + Arg->claim(); + CommonCmdArgs.push_back("-save"); + } + + for (auto Arg : Args.filtered(options::OPT_Msave_off)) { + Arg->claim(); + CommonCmdArgs.push_back("-nosave"); + } + + // Treat denormalized numbers as zero: On + for (auto Arg : Args.filtered(options::OPT_Mdaz_on)) { + Arg->claim(); + CommonCmdArgs.push_back("-x"); + CommonCmdArgs.push_back("129"); + CommonCmdArgs.push_back("4"); + CommonCmdArgs.push_back("-y"); + CommonCmdArgs.push_back("129"); + CommonCmdArgs.push_back("0x400"); + } + + // Treat denormalized numbers as zero: Off + for (auto Arg : Args.filtered(options::OPT_Mdaz_off)) { + Arg->claim(); + CommonCmdArgs.push_back("-y"); + CommonCmdArgs.push_back("129"); + CommonCmdArgs.push_back("4"); + CommonCmdArgs.push_back("-x"); + CommonCmdArgs.push_back("129"); + CommonCmdArgs.push_back("0x400"); + } + + // Store constants in writable data segment + for (auto Arg : Args.filtered(options::OPT_Mwritable_constants)) { + Arg->claim(); + LowerCmdArgs.push_back("-x"); + LowerCmdArgs.push_back("183"); + LowerCmdArgs.push_back("0x20000000"); + } + + // Bounds checking: On + for (auto Arg : Args.filtered(options::OPT_Mbounds_on)) { + Arg->claim(); + CommonCmdArgs.push_back("-x"); + CommonCmdArgs.push_back("70"); + CommonCmdArgs.push_back("2"); + } + + // Bounds checking: Off + for (auto Arg : Args.filtered(options::OPT_Mbounds_off)) { + Arg->claim(); + CommonCmdArgs.push_back("-y"); + CommonCmdArgs.push_back("70"); + CommonCmdArgs.push_back("2"); + } + + // Generate code allowing recursive subprograms + for (auto Arg : Args.filtered(options::OPT_Mrecursive_on)) { + Arg->claim(); + CommonCmdArgs.push_back("-recursive"); + } + + // Disable recursive subprograms + for (auto Arg : Args.filtered(options::OPT_Mrecursive_off)) { + Arg->claim(); + CommonCmdArgs.push_back("-norecursive"); + } + + // Enable generating reentrant code (disable optimizations that inhibit it) + for (auto Arg : Args.filtered(options::OPT_Mreentrant_on)) { + Arg->claim(); + CommonCmdArgs.push_back("-reentrant"); + } + + // Allow optimizations inhibiting reentrancy + for (auto Arg : Args.filtered(options::OPT_Mreentrant_off)) { + Arg->claim(); + CommonCmdArgs.push_back("-noreentrant"); + } + + // Swap byte order for unformatted IO + for (auto Arg : Args.filtered(options::OPT_Mbyteswapio, options::OPT_byteswapio)) { + Arg->claim(); + CommonCmdArgs.push_back("-x"); + CommonCmdArgs.push_back("125"); + CommonCmdArgs.push_back("2"); + } + + // Contiguous pointer checks + if (Arg *A = Args.getLastArg(options::OPT_fsanitize_EQ)) { + for (StringRef val : A->getValues()) { + if (val == "discontiguous" || val == "undefined") { + // -x 54 0x40 -x 54 0x80 -x 54 0x200 + UpperCmdArgs.push_back("-x"); + UpperCmdArgs.push_back("54"); + UpperCmdArgs.push_back("0x2c0"); + + // -fsanitze=discontiguous has no meaning in LLVM, only flang driver needs to + // recognize it. However -fsanitize=undefined needs to be passed on for further + // processing by the non-flang part of the driver. + if (val == "discontiguous") + A->claim(); + break; + } + } + } + + if (auto *A = + Args.getLastArg(options::OPT_fno_backslash, options::OPT_Mbackslash, + options::OPT_fbackslash, options::OPT_Mnobackslash)) { + for (auto Arg : + Args.filtered(options::OPT_fno_backslash, options::OPT_Mbackslash, + options::OPT_fbackslash, options::OPT_Mnobackslash)) { + Arg->claim(); + } + // Treat backslashes as regular characters + if (A->getOption().matches(options::OPT_fno_backslash) || + A->getOption().matches(options::OPT_Mbackslash)) { + CommonCmdArgs.push_back("-x"); + CommonCmdArgs.push_back("124"); + CommonCmdArgs.push_back("0x40"); + } + // Treat backslashes as C-style escape characters + if (A->getOption().matches(options::OPT_fbackslash) || + A->getOption().matches(options::OPT_Mnobackslash)) { + CommonCmdArgs.push_back("-y"); + CommonCmdArgs.push_back("124"); + CommonCmdArgs.push_back("0x40"); + } + } else { + // By default treat backslashes as regular characters + CommonCmdArgs.push_back("-x"); + CommonCmdArgs.push_back("124"); + CommonCmdArgs.push_back("0x40"); + } + + // handle OpemMP options + if (auto *A = Args.getLastArg(options::OPT_mp, options::OPT_nomp, + options::OPT_fopenmp, options::OPT_fno_openmp)) { + for (auto Arg : Args.filtered(options::OPT_mp, options::OPT_nomp)) { + Arg->claim(); + } + for (auto Arg : Args.filtered(options::OPT_fopenmp, + options::OPT_fno_openmp)) { + Arg->claim(); + } + + if (A->getOption().matches(options::OPT_mp) || + A->getOption().matches(options::OPT_fopenmp)) { + + CommonCmdArgs.push_back("-mp"); + + // Allocate threadprivate data local to the thread + CommonCmdArgs.push_back("-x"); + CommonCmdArgs.push_back("69"); + CommonCmdArgs.push_back("0x200"); + + // Use the 'fair' schedule as the default static schedule + // for parallel do loops + CommonCmdArgs.push_back("-x"); + CommonCmdArgs.push_back("69"); + CommonCmdArgs.push_back("0x400"); + + // Disable use of native atomic instructions + // for OpenMP atomics pending either a named + // option or a libatomic bundled with flang. + UpperCmdArgs.push_back("-x"); + UpperCmdArgs.push_back("69"); + UpperCmdArgs.push_back("0x1000"); + } + } + + // Align large objects on cache lines + for (auto Arg : Args.filtered(options::OPT_Mcache_align_on)) { + Arg->claim(); + CommonCmdArgs.push_back("-x"); + CommonCmdArgs.push_back("119"); + CommonCmdArgs.push_back("0x10000000"); + LowerCmdArgs.push_back("-x"); + LowerCmdArgs.push_back("129"); + LowerCmdArgs.push_back("0x40000000"); + } + + // Disable special alignment of large objects + for (auto Arg : Args.filtered(options::OPT_Mcache_align_off)) { + Arg->claim(); + CommonCmdArgs.push_back("-y"); + CommonCmdArgs.push_back("119"); + CommonCmdArgs.push_back("0x10000000"); + LowerCmdArgs.push_back("-y"); + LowerCmdArgs.push_back("129"); + LowerCmdArgs.push_back("0x40000000"); + } + + // -Mstack_arrays + for (auto Arg : Args.filtered(options::OPT_Mstackarrays)) { + Arg->claim(); + CommonCmdArgs.push_back("-x"); + CommonCmdArgs.push_back("54"); + CommonCmdArgs.push_back("8"); + } + + // -Memit-dwarf-common-blocks-name, only add xbit to flang2. + for (auto Arg : Args.filtered(options::OPT_Memit_dwarf_common_blocks_name)) { + Arg->claim(); + LowerCmdArgs.push_back("-x"); + LowerCmdArgs.push_back("183"); + LowerCmdArgs.push_back("0x40000000"); + } + + // -Munixlogical, only add xbit to flang2. + for (auto Arg : Args.filtered(options::OPT_Munixlogical)) { + Arg->claim(); + LowerCmdArgs.push_back("-x"); + LowerCmdArgs.push_back("125"); + LowerCmdArgs.push_back("0x8"); + } + + // Last argument of -g/-gdwarfX should be taken. + Arg *GArg = Args.getLastArg(options::OPT_g_Flag); + Arg *GDwarfArg = Args.getLastArg(options::OPT_gdwarf_2, + options::OPT_gdwarf_3, + options::OPT_gdwarf_4, + options::OPT_gdwarf_5); + + if (GArg || GDwarfArg) { + + for (auto Arg : Args.filtered(options::OPT_g_Flag, options::OPT_gdwarf_2, + options::OPT_gdwarf_3, options::OPT_gdwarf_4, + options::OPT_gdwarf_5)) { + Arg->claim(); + } + + CommonCmdArgs.push_back("-x"); + CommonCmdArgs.push_back("120"); + + if (!GDwarfArg) // -g without -gdwarf-X produces default (DWARFv4) + CommonCmdArgs.push_back("0x1000000"); + else if (GDwarfArg->getOption().matches(options::OPT_gdwarf_2)) // -gdwarf-2 + CommonCmdArgs.push_back("0x200"); + else if (GDwarfArg->getOption().matches(options::OPT_gdwarf_3)) // -gdwarf-3 + CommonCmdArgs.push_back("0x4000"); + else if (GDwarfArg->getOption().matches(options::OPT_gdwarf_4)) // -gdwarf-4 + CommonCmdArgs.push_back("0x1000000"); + else if (GDwarfArg->getOption().matches(options::OPT_gdwarf_5)) // -gdwarf-5 + CommonCmdArgs.push_back("0x2000000"); + // Handle `-gpubnames` option separately. + for (auto Arg : Args.filtered(options::OPT_gpubnames)) { + Arg->claim(); + CommonCmdArgs.push_back("-x"); + CommonCmdArgs.push_back("120"); + CommonCmdArgs.push_back("0x40000000"); // -gpubnames + } + } + + // -Mipa has no effect + if (Arg *A = Args.getLastArg(options::OPT_Mipa)) { + D.Diag(diag::warn_drv_clang_unsupported) + << A->getAsString(Args); + } + + // -Minline has no effect + if (Arg *A = Args.getLastArg(options::OPT_Minline_on)) { + D.Diag(diag::warn_drv_clang_unsupported) + << A->getAsString(Args); + } + + // Handle -fdefault-real-8 (and its alias, -r8) and -fno-default-real-8 + if (Arg *A = Args.getLastArg(options::OPT_r8, + options::OPT_fdefault_real_8, + options::OPT_fno_default_real_8)) { + const char * fl; + // For -f version add -x flag, for -fno add -y + if (A->getOption().matches(options::OPT_fno_default_real_8)) { + fl = "-y"; + } else { + fl = "-x"; + } + + for (Arg *A : Args.filtered(options::OPT_r8, + options::OPT_fdefault_real_8, + options::OPT_fno_default_real_8)) { + A->claim(); + } + + UpperCmdArgs.push_back(fl); + UpperCmdArgs.push_back("124"); + UpperCmdArgs.push_back("0x8"); + UpperCmdArgs.push_back(fl); + UpperCmdArgs.push_back("124"); + UpperCmdArgs.push_back("0x80000"); + } + + // Process and claim -i8/-fdefault-integer-8/-fno-default-integer-8 argument + if (Arg *A = Args.getLastArg(options::OPT_i8, + options::OPT_fdefault_integer_8, + options::OPT_fno_default_integer_8)) { + const char * fl; + + if (A->getOption().matches(options::OPT_fno_default_integer_8)) { + fl = "-y"; + } else { + fl = "-x"; + } + + for (Arg *A : Args.filtered(options::OPT_i8, + options::OPT_fdefault_integer_8, + options::OPT_fno_default_integer_8)) { + A->claim(); + } + + UpperCmdArgs.push_back(fl); + UpperCmdArgs.push_back("124"); + UpperCmdArgs.push_back("0x10"); + } + + // Pass an arbitrary flag for first part of Fortran frontend + for (Arg *A : Args.filtered(options::OPT_Wh_EQ)) { + A->claim(); + StringRef Value = A->getValue(); + SmallVector PassArgs; + Value.split(PassArgs, StringRef(",")); + for (StringRef PassArg : PassArgs) { + UpperCmdArgs.push_back(Args.MakeArgString(PassArg)); + } + } + + // Flush to zero mode + // Disabled by default, but can be enabled by a switch + if (Args.hasArg(options::OPT_Mflushz_on)) { + // For -Mflushz set -x 129 2 for second part of Fortran frontend + for (Arg *A: Args.filtered(options::OPT_Mflushz_on)) { + A->claim(); + LowerCmdArgs.push_back("-x"); + LowerCmdArgs.push_back("129"); + LowerCmdArgs.push_back("2"); + } + } else { + LowerCmdArgs.push_back("-y"); + LowerCmdArgs.push_back("129"); + LowerCmdArgs.push_back("2"); + for (Arg *A: Args.filtered(options::OPT_Mflushz_off)) { + A->claim(); + } + } + + // For -fPIC set -x 62 8 for second part of Fortran frontend + for (Arg *A: Args.filtered(options::OPT_fPIC)) { + A->claim(); + LowerCmdArgs.push_back("-x"); + LowerCmdArgs.push_back("62"); + LowerCmdArgs.push_back("8"); + } + + StringRef OptOStr("0"); + if (Arg *A = Args.getLastArg(options::OPT_O_Group)) { + if (A->getOption().matches(options::OPT_O4)) { + OptOStr = "4"; // FIXME what should this be? + } else if (A->getOption().matches(options::OPT_Ofast)) { + OptOStr = "2"; // FIXME what should this be? + } else if (A->getOption().matches(options::OPT_O0)) { + // intentionally do nothing + } else { + assert(A->getOption().matches(options::OPT_O) && "Must have a -O flag"); + StringRef S(A->getValue()); + if ((S == "s") || (S == "z")) { + // -Os = size; -Oz = more size + OptOStr = "2"; // FIXME -Os|-Oz => -opt ? + } else if ((S == "1") || (S == "2") || (S == "3")) { + OptOStr = S; + } else { + OptOStr = "4"; + } + } + } + unsigned OptLevel = std::stoi(OptOStr.str()); + + if (Args.hasArg(options::OPT_g_Group)) { + // pass -g to lower and upper + CommonCmdArgs.push_back("-debug"); + } + + /* Pick the last among conflicting flags, if a positive and negative flag + exists for ex. "-ffast-math -fno-fast-math" they get nullified. Also any + previously overwritten flag remains that way. + For ex. "-Kieee -ffast-math -fno-fast-math". -Kieee gets overwritten by + -ffast-math which then gets negated by -fno-fast-math, finally behaving as + if none of those flags were passed. + */ + for(Arg *A: Args.filtered(options::OPT_ffast_math, options::OPT_fno_fast_math, + options::OPT_Ofast, options::OPT_Kieee_off, + options::OPT_Kieee_on, options::OPT_frelaxed_math, + options::OPT_fassociative_math, + options::OPT_fno_associative_math, + options::OPT_fsigned_zeros, + options::OPT_fno_signed_zeros)) { + if (A->getOption().matches(options::OPT_ffast_math) || + A->getOption().matches(options::OPT_Ofast)) { + NeedIEEE = NeedRelaxedMath = false; + NeedFastMath = true; + } else if (A->getOption().matches(options::OPT_Kieee_on)) { + NeedFastMath = NeedRelaxedMath = AssociativeMath = false; + NeedIEEE = SignedZeros = true; + } else if (A->getOption().matches(options::OPT_frelaxed_math)) { + NeedFastMath = NeedIEEE = false; + NeedRelaxedMath = true; + } else if (A->getOption().matches(options::OPT_fno_fast_math)) { + NeedFastMath = false; + } else if (A->getOption().matches(options::OPT_Kieee_off)) { + NeedIEEE = false; + } else if (A->getOption().matches(options::OPT_fassociative_math)) { + AssociativeMath = true; + NeedIEEE = SignedZeros = false; + } else if (A->getOption().matches(options::OPT_fno_associative_math)) { + AssociativeMath = false; + } else if (A->getOption().matches(options::OPT_fsigned_zeros)) { + SignedZeros = true; + AssociativeMath = false; + } else if (A->getOption().matches(options::OPT_fno_signed_zeros)) { + SignedZeros = NeedIEEE = false; + } + A->claim(); + } + + // fp-contract=fast is the default + bool EnableFPContraction = true; + if (Arg *A = Args.getLastArg(options::OPT_ffp_contract, + options::OPT_Mfma_on, + options::OPT_fma, + options::OPT_Mfma_off, + options::OPT_nofma)) { + auto Opt = A->getOption(); + if (Opt.matches(options::OPT_ffp_contract)) { + StringRef Val = A->getValue(); + if ((Val == "fast") || (Val == "on")) { + EnableFPContraction = true; + } else if (Val == "off") { + EnableFPContraction = false; + } else { + D.Diag(diag::err_drv_unsupported_option_argument) + << A->getOption().getName() << Val; + } + } else if(Opt.matches(options::OPT_Mfma_on) || + Opt.matches(options::OPT_fma)) { + EnableFPContraction = true; + } else { + EnableFPContraction = false; + } + } + + if(OptLevel == 0) + EnableFPContraction = false; + + // Emit contract math instructions. + // Step 1 : Generate fma instructions in flang (can override with fma flag) + // Step 2 : Propagate fma contract information to LLVM to further + // exploit contraction opportunities + if (EnableFPContraction) { + LowerCmdArgs.push_back("-x"); + LowerCmdArgs.push_back("172"); + LowerCmdArgs.push_back("0x40000000"); + LowerCmdArgs.push_back("-x"); + LowerCmdArgs.push_back("179"); + LowerCmdArgs.push_back("1"); + // Step 2 + LowerCmdArgs.push_back("-x"); + LowerCmdArgs.push_back("216"); + LowerCmdArgs.push_back("0x1000"); + } else { + LowerCmdArgs.push_back("-x"); + LowerCmdArgs.push_back("171"); + LowerCmdArgs.push_back("0x40000000"); + LowerCmdArgs.push_back("-x"); + LowerCmdArgs.push_back("178"); + LowerCmdArgs.push_back("1"); + } + + if (NeedFastMath) { + // Lower: -x 216 1 + LowerCmdArgs.push_back("-x"); + LowerCmdArgs.push_back("216"); + LowerCmdArgs.push_back("1"); + // Common: -ieee 0 + CommonCmdArgs.push_back("-ieee"); + CommonCmdArgs.push_back("0"); + } else if (NeedIEEE) { + // Common: -y 129 2 + CommonCmdArgs.push_back("-y"); + CommonCmdArgs.push_back("129"); + CommonCmdArgs.push_back("2"); + // Lower: -x 6 0x100 + LowerCmdArgs.push_back("-x"); + LowerCmdArgs.push_back("6"); + LowerCmdArgs.push_back("0x100"); + // Lower: -x 42 0x400000 + LowerCmdArgs.push_back("-x"); + LowerCmdArgs.push_back("42"); + LowerCmdArgs.push_back("0x400000"); + // Lower: -y 129 4 + LowerCmdArgs.push_back("-y"); + LowerCmdArgs.push_back("129"); + LowerCmdArgs.push_back("4"); + // Lower: -x 129 0x400 + LowerCmdArgs.push_back("-x"); + LowerCmdArgs.push_back("129"); + LowerCmdArgs.push_back("0x400"); + // Lower: -y 216 1 (OPT_fno_fast_math) + LowerCmdArgs.push_back("-y"); + LowerCmdArgs.push_back("216"); + LowerCmdArgs.push_back("1"); + // Common: -ieee 1 + CommonCmdArgs.push_back("-ieee"); + CommonCmdArgs.push_back("1"); + } else if (NeedRelaxedMath) { + // Lower: -x 15 0x400 + LowerCmdArgs.push_back("-x"); + LowerCmdArgs.push_back("15"); + LowerCmdArgs.push_back("0x400"); + // Lower: -y 216 1 (OPT_fno_fast_math) + LowerCmdArgs.push_back("-y"); + LowerCmdArgs.push_back("216"); + LowerCmdArgs.push_back("1"); + // Common: -ieee 0 + CommonCmdArgs.push_back("-ieee"); + CommonCmdArgs.push_back("0"); + } else { + // Common: -ieee 0 + CommonCmdArgs.push_back("-ieee"); + CommonCmdArgs.push_back("0"); + } + + /***** Upper part of the Fortran frontend *****/ + + // TODO do we need to invoke this under GDB sometimes? + std::string flang1 = "flang1"; + if (getToolChain().isCrossCompiling()) + flang1 = getToolChain().getEffectiveTriple().getTriple() + "-" + flang1; + const char *UpperExec = + Args.MakeArgString(getToolChain().GetProgramPath(flang1.c_str())); + + UpperCmdArgs.push_back("-opt"); UpperCmdArgs.push_back(Args.MakeArgString(OptOStr)); + UpperCmdArgs.push_back("-terse"); UpperCmdArgs.push_back("1"); + UpperCmdArgs.push_back("-inform"); UpperCmdArgs.push_back("warn"); + UpperCmdArgs.push_back("-nohpf"); + UpperCmdArgs.push_back("-nostatic"); + UpperCmdArgs.append(CommonCmdArgs.begin(), CommonCmdArgs.end()); // Append common arguments + UpperCmdArgs.push_back("-x"); UpperCmdArgs.push_back("19"); UpperCmdArgs.push_back("0x400000"); + UpperCmdArgs.push_back("-quad"); + UpperCmdArgs.push_back("-x"); UpperCmdArgs.push_back("68"); UpperCmdArgs.push_back("0x1"); + UpperCmdArgs.push_back("-x"); UpperCmdArgs.push_back("59"); UpperCmdArgs.push_back("4"); + UpperCmdArgs.push_back("-x"); UpperCmdArgs.push_back("15"); UpperCmdArgs.push_back("2"); + UpperCmdArgs.push_back("-x"); UpperCmdArgs.push_back("49"); UpperCmdArgs.push_back("0x400004"); + UpperCmdArgs.push_back("-x"); UpperCmdArgs.push_back("51"); UpperCmdArgs.push_back("0x20"); + UpperCmdArgs.push_back("-x"); UpperCmdArgs.push_back("57"); UpperCmdArgs.push_back("0x4c"); + UpperCmdArgs.push_back("-x"); UpperCmdArgs.push_back("58"); UpperCmdArgs.push_back("0x10000"); + UpperCmdArgs.push_back("-x"); UpperCmdArgs.push_back("124"); UpperCmdArgs.push_back("0x1000"); + UpperCmdArgs.push_back("-tp"); UpperCmdArgs.push_back("px"); + UpperCmdArgs.push_back("-x"); UpperCmdArgs.push_back("57"); UpperCmdArgs.push_back("0xfb0000"); + UpperCmdArgs.push_back("-x"); UpperCmdArgs.push_back("58"); UpperCmdArgs.push_back("0x78031040"); + UpperCmdArgs.push_back("-x"); UpperCmdArgs.push_back("47"); UpperCmdArgs.push_back("0x08"); + UpperCmdArgs.push_back("-x"); UpperCmdArgs.push_back("48"); UpperCmdArgs.push_back("4608"); + UpperCmdArgs.push_back("-x"); UpperCmdArgs.push_back("49"); UpperCmdArgs.push_back("0x100"); + if (OptLevel >= 2) { + UpperCmdArgs.push_back("-x"); + UpperCmdArgs.push_back("70"); + UpperCmdArgs.push_back("0x6c00"); + UpperCmdArgs.push_back("-x"); + UpperCmdArgs.push_back("119"); + UpperCmdArgs.push_back("0x10000000"); + UpperCmdArgs.push_back("-x"); + UpperCmdArgs.push_back("129"); + UpperCmdArgs.push_back("2"); + UpperCmdArgs.push_back("-x"); + UpperCmdArgs.push_back("47"); + UpperCmdArgs.push_back("0x400000"); + UpperCmdArgs.push_back("-x"); + UpperCmdArgs.push_back("52"); + UpperCmdArgs.push_back("2"); + } + + // Add system include arguments. + getToolChain().AddFlangSystemIncludeArgs(Args, UpperCmdArgs); + + // Use clang's predefined macros + DiagnosticsEngine DE(new DiagnosticIDs(), new DiagnosticOptions, new IgnoringDiagConsumer()); + std::shared_ptr TO = std::make_shared(); + TO->Triple = Triple.getTriple(); + std::shared_ptr TI(clang::TargetInfo::CreateTargetInfo(DE, TO)); + std::string PredefineBuffer; + llvm::raw_string_ostream Predefines(PredefineBuffer); + ClassicFlangMacroBuilder Builder(UpperCmdArgs, Args, Predefines); + + LangOptions LO; + VersionTuple VT = getToolChain().computeMSVCVersion(&D, Args); + if (!VT.empty()) { + // Set the MSCompatibility version. Subminor version has 5 decimal digits. + // Minor and major versions have 2 decimal digits each. + LO.MSCompatibilityVersion = VT.getMajor() * 10000000 + + VT.getMinor().value_or(0) * 100000 + + VT.getSubminor().value_or(0); + } + + // Define Target specific macros like __linux__ + TI->getTargetDefines(LO, Builder); + + Builder.defineMacro("__SIZE_TYPE__", + TargetInfo::getTypeName(TI->getSizeType())); + Builder.defineMacro( + "__PTRDIFF_TYPE__", + TargetInfo::getTypeName(TI->getPtrDiffType(LangAS::Default))); + + if (TI->getPointerWidth(LangAS::Default) == 64 && TI->getLongWidth() == 64 + && TI->getIntWidth() == 32) { + Builder.defineMacro("_LP64"); + Builder.defineMacro("__LP64__"); + } + + if (TI->getPointerWidth(LangAS::Default) == 32 && TI->getLongWidth() == 32 + && TI->getIntWidth() == 32) { + Builder.defineMacro("_ILP32"); + Builder.defineMacro("__ILP32__"); + } + + DefineTypeSize("__LONG_MAX__", TargetInfo::SignedLong, *TI, Builder); + + // Add additional predefined macros + switch (Triple.getArch()) { + case llvm::Triple::aarch64: + UpperCmdArgs.push_back("-def"); UpperCmdArgs.push_back("__ARM_ARCH__=8"); + break; + case llvm::Triple::x86_64: + UpperCmdArgs.push_back("-def"); UpperCmdArgs.push_back("__amd_64__amd64__"); + UpperCmdArgs.push_back("-def"); UpperCmdArgs.push_back("__k8"); + UpperCmdArgs.push_back("-def"); UpperCmdArgs.push_back("__k8__"); + break; + default: /* generic 64-bit */ + ; + } + UpperCmdArgs.push_back("-def"); UpperCmdArgs.push_back("__THROW="); + UpperCmdArgs.push_back("-def"); UpperCmdArgs.push_back("__extension__="); + UpperCmdArgs.push_back("-def"); UpperCmdArgs.push_back("__PGLLVM__"); + + // Enable preprocessor + if (Args.hasArg(options::OPT_Mpreprocess) || + Args.hasArg(options::OPT_cpp) || + Args.hasArg(options::OPT_E) || + types::getPreprocessedType(InputType) != types::TY_INVALID) { + UpperCmdArgs.push_back("-preprocess"); + for (auto Arg : Args.filtered(options::OPT_Mpreprocess, options::OPT_cpp, options::OPT_E)) { + Arg->claim(); + } + + // When -E option is provided, run only the fortran preprocessor. + // Only in -E mode, consume -P if it exists + if (Args.hasArg(options::OPT_E)) { + UpperCmdArgs.push_back("-es"); + // Line marker mode is disabled + if (Args.hasArg(options::OPT_P)) { + Args.ClaimAllArgs(options::OPT_P); + } else { + // -pp enables line marker mode in fortran preprocessor + UpperCmdArgs.push_back("-pp"); + } + } + } + + // Enable standards checking + if (Args.hasArg(options::OPT_Mstandard)) { + UpperCmdArgs.push_back("-standard"); + for (auto Arg : Args.filtered(options::OPT_Mstandard)) { + Arg->claim(); + } + } + + // Free or fixed form file + if (Args.hasArg(options::OPT_fortran_format_Group)) { + // Override file name suffix, scan arguments for that + for (Arg *A : Args.filtered(options::OPT_fortran_format_Group)) { + A->claim(); + switch (A->getOption().getID()) { + default: + llvm_unreachable("missed a case"); + case options::OPT_ffixed_form: + case options::OPT_fno_free_form: + case options::OPT_Mfixed: + case options::OPT_Mfree_off: + case options::OPT_Mfreeform_off: + UpperCmdArgs.push_back("-nofreeform"); + break; + case options::OPT_ffree_form: + case options::OPT_fno_fixed_form: + case options::OPT_Mfree_on: + case options::OPT_Mfreeform_on: + UpperCmdArgs.push_back("-freeform"); + break; + } + } + } else { + // Deduce format from file name suffix + if (types::isFreeFormFortran(InputType)) { + UpperCmdArgs.push_back("-freeform"); + } else { + UpperCmdArgs.push_back("-nofreeform"); + } + } + + // Extend lines to 132 characters + for (auto Arg : Args.filtered(options::OPT_Mextend)) { + Arg->claim(); + UpperCmdArgs.push_back("-extend"); + } + + for (auto Arg : Args.filtered(options::OPT_ffixed_line_length_VALUE)) { + StringRef Value = Arg->getValue(); + if (Value == "72") { + Arg->claim(); + } else if (Value == "132") { + Arg->claim(); + UpperCmdArgs.push_back("-extend"); + } else { + D.Diag(diag::err_drv_unsupported_fixed_line_length) + << Arg->getAsString(Args); + } + } + + // Add user-defined include directories + for (auto Arg : Args.filtered(options::OPT_I)) { + Arg->claim(); + UpperCmdArgs.push_back("-idir"); + UpperCmdArgs.push_back(Arg->getValue(0)); + } + + // Add user-defined module directories + for (auto Arg : Args.filtered(options::OPT_ModuleDir, options::OPT_J)) { + Arg->claim(); + UpperCmdArgs.push_back("-moddir"); + UpperCmdArgs.push_back(Arg->getValue(0)); + } + + // "Define" preprocessor flags + for (auto Arg : Args.filtered(options::OPT_D)) { + Arg->claim(); + UpperCmdArgs.push_back("-def"); + UpperCmdArgs.push_back(Arg->getValue(0)); + } + + // "Define" preprocessor flags + for (auto Arg : Args.filtered(options::OPT_U)) { + Arg->claim(); + UpperCmdArgs.push_back("-undef"); + UpperCmdArgs.push_back(Arg->getValue(0)); + } + + UpperCmdArgs.push_back("-vect"); UpperCmdArgs.push_back("48"); + + // Semantics for assignments to allocatables + if (Arg *A = Args.getLastArg(options::OPT_Mallocatable_EQ)) { + // Argument is passed explicitly + StringRef Value = A->getValue(); + if (Value == "03") { // Enable Fortran 2003 semantics + UpperCmdArgs.push_back("-x"); // Set XBIT + } else if (Value == "95") { // Enable Fortran 2003 semantics + UpperCmdArgs.push_back("-y"); // Unset XBIT + } else { + D.Diag(diag::err_drv_invalid_allocatable_mode) + << A->getAsString(Args); + } + } else { // No argument passed + UpperCmdArgs.push_back("-x"); // Default is 03 + } + UpperCmdArgs.push_back("54"); UpperCmdArgs.push_back("1"); // XBIT value + + UpperCmdArgs.push_back("-x"); UpperCmdArgs.push_back("70"); UpperCmdArgs.push_back("0x40000000"); + UpperCmdArgs.push_back("-y"); UpperCmdArgs.push_back("163"); UpperCmdArgs.push_back("0xc0000000"); + UpperCmdArgs.push_back("-x"); UpperCmdArgs.push_back("189"); UpperCmdArgs.push_back("0x10"); + + // Enable NULL pointer checking + if (Args.hasArg(options::OPT_Mchkptr)) { + UpperCmdArgs.push_back("-x"); + UpperCmdArgs.push_back("70"); + UpperCmdArgs.push_back("4"); + for (auto Arg : Args.filtered(options::OPT_Mchkptr)) { + Arg->claim(); + } + } + + // Set a -x flag for first part of Fortran frontend + for (Arg *A : Args.filtered(options::OPT_Hx_EQ)) { + A->claim(); + StringRef Value = A->getValue(); + auto XFlag = Value.split(","); + UpperCmdArgs.push_back("-x"); + UpperCmdArgs.push_back(Args.MakeArgString(XFlag.first)); + UpperCmdArgs.push_back(Args.MakeArgString(XFlag.second)); + } + + // Set a -y flag for first part of Fortran frontend + for (Arg *A : Args.filtered(options::OPT_Hy_EQ)) { + A->claim(); + StringRef Value = A->getValue(); + auto XFlag = Value.split(","); + UpperCmdArgs.push_back("-y"); + UpperCmdArgs.push_back(Args.MakeArgString(XFlag.first)); + UpperCmdArgs.push_back(Args.MakeArgString(XFlag.second)); + } + + // Set a -q (debug) flag for first part of Fortran frontend + for (Arg *A : Args.filtered(options::OPT_Hq_EQ)) { + A->claim(); + StringRef Value = A->getValue(); + auto XFlag = Value.split(","); + UpperCmdArgs.push_back("-q"); + UpperCmdArgs.push_back(Args.MakeArgString(XFlag.first)); + UpperCmdArgs.push_back(Args.MakeArgString(XFlag.second)); + } + + // Set a -qq (debug) flag for first part of Fortran frontend + for (Arg *A : Args.filtered(options::OPT_Hqq_EQ)) { + A->claim(); + StringRef Value = A->getValue(); + auto XFlag = Value.split(","); + UpperCmdArgs.push_back("-qq"); + UpperCmdArgs.push_back(Args.MakeArgString(XFlag.first)); + UpperCmdArgs.push_back(Args.MakeArgString(XFlag.second)); + } + + const char * STBFile = Args.MakeArgString(Stem + ".stb"); + C.addTempFile(STBFile); + UpperCmdArgs.push_back("-stbfile"); + UpperCmdArgs.push_back(STBFile); + + const char * ModuleExportFile = Args.MakeArgString(Stem + ".cmod"); + C.addTempFile(ModuleExportFile); + UpperCmdArgs.push_back("-modexport"); + UpperCmdArgs.push_back(ModuleExportFile); + + const char * ModuleIndexFile = Args.MakeArgString(Stem + ".cmdx"); + C.addTempFile(ModuleIndexFile); + UpperCmdArgs.push_back("-modindex"); + UpperCmdArgs.push_back(ModuleIndexFile); + + UpperCmdArgs.push_back("-output"); + UpperCmdArgs.push_back(ILMFile); + + SmallString<256> Path; + if(Args.getAllArgValues(options::OPT_fopenmp_targets_EQ).size() > 0) { + SmallString<128> TargetInfo; + Path = llvm::sys::path::parent_path(Output.getFilename()); + Arg* Tgts = Args.getLastArg(options::OPT_fopenmp_targets_EQ); + assert(Tgts && Tgts->getNumValues() && + "OpenMP offloading has to have targets specified."); + for (unsigned i = 0; i < Tgts->getNumValues(); ++i) { + if (i) + TargetInfo += ','; + llvm::Triple T(Tgts->getValue(i)); + TargetInfo += T.getTriple(); + } + UpperCmdArgs.push_back("-fopenmp-targets"); + UpperCmdArgs.push_back(Args.MakeArgString(TargetInfo.str())); + } + + C.addCommand(std::make_unique(JA, *this, ResponseFileSupport::AtFileUTF8(), UpperExec, UpperCmdArgs, Inputs)); + + // For -fsyntax-only or -E that is it + if (Args.hasArg(options::OPT_fsyntax_only) || + Args.hasArg(options::OPT_E)) return; + + /***** Lower part of Fortran frontend *****/ + std::string flang2 = "flang2"; + if (getToolChain().isCrossCompiling()) + flang2 = getToolChain().getEffectiveTriple().getTriple() + "-" + flang2; + const char *LowerExec = + Args.MakeArgString(getToolChain().GetProgramPath(flang2.c_str())); + + // TODO FLANG arg handling + LowerCmdArgs.push_back("-fn"); LowerCmdArgs.push_back(Input.getBaseInput()); + LowerCmdArgs.push_back("-opt"); LowerCmdArgs.push_back(Args.MakeArgString(OptOStr)); + LowerCmdArgs.push_back("-terse"); LowerCmdArgs.push_back("1"); + LowerCmdArgs.push_back("-inform"); LowerCmdArgs.push_back("warn"); + LowerCmdArgs.append(CommonCmdArgs.begin(), CommonCmdArgs.end()); // Append common arguments + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("68"); LowerCmdArgs.push_back("0x1"); + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("51"); LowerCmdArgs.push_back("0x20"); + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("119"); LowerCmdArgs.push_back("0xa10000"); + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("122"); LowerCmdArgs.push_back("0x40"); + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("123"); LowerCmdArgs.push_back("0x1000"); + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("127"); LowerCmdArgs.push_back("4"); + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("127"); LowerCmdArgs.push_back("17"); + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("19"); LowerCmdArgs.push_back("0x400000"); + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("28"); LowerCmdArgs.push_back("0x40000"); + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("120"); LowerCmdArgs.push_back("0x10000000"); + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("70"); LowerCmdArgs.push_back("0x8000"); + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("122"); LowerCmdArgs.push_back("1"); + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("125"); LowerCmdArgs.push_back("0x20000"); + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("164"); LowerCmdArgs.push_back("0x800000"); + LowerCmdArgs.push_back("-quad"); + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("59"); LowerCmdArgs.push_back("4"); + LowerCmdArgs.push_back("-tp"); LowerCmdArgs.push_back("px"); + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("120"); LowerCmdArgs.push_back("0x1000"); // debug lite + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("124"); LowerCmdArgs.push_back("0x1400"); + LowerCmdArgs.push_back("-y"); LowerCmdArgs.push_back("15"); LowerCmdArgs.push_back("2"); + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("57"); LowerCmdArgs.push_back("0x3b0000"); + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("58"); LowerCmdArgs.push_back("0x48000000"); + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("49"); LowerCmdArgs.push_back("0x100"); + LowerCmdArgs.push_back("-astype"); LowerCmdArgs.push_back("0"); + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("183"); LowerCmdArgs.push_back("4"); + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("121"); LowerCmdArgs.push_back("0x800"); + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("54"); LowerCmdArgs.push_back("0x10"); + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("70"); LowerCmdArgs.push_back("0x40000000"); + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("249"); LowerCmdArgs.push_back("200"); // LLVM version + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("124"); LowerCmdArgs.push_back("1"); + LowerCmdArgs.push_back("-y"); LowerCmdArgs.push_back("163"); LowerCmdArgs.push_back("0xc0000000"); + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("189"); LowerCmdArgs.push_back("0x10"); + LowerCmdArgs.push_back("-y"); LowerCmdArgs.push_back("189"); LowerCmdArgs.push_back("0x4000000"); + + if (!SignedZeros) { + LowerCmdArgs.push_back("-x"); + LowerCmdArgs.push_back("216"); + LowerCmdArgs.push_back("0x8"); + } + if (AssociativeMath) { + LowerCmdArgs.push_back("-x"); + LowerCmdArgs.push_back("216"); + LowerCmdArgs.push_back("0x10"); + } + + // Remove "noinline" attriblute + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("183"); LowerCmdArgs.push_back("0x10"); + + // Add target features + std::vector Features; + std::string FeatureList = ""; + getTargetFeatureList(D, Triple, Args, UpperCmdArgs, false, Features); + if (!Features.empty()) { + for (auto Feature : unifyTargetFeatures(Features)) { + if (!FeatureList.empty()) + FeatureList += ','; + FeatureList += Feature; + } + + LowerCmdArgs.push_back("-target_features"); + LowerCmdArgs.push_back(Args.MakeArgString(FeatureList)); + } + + // Add vscale range + unsigned vscaleMin = 0; + unsigned vscaleMax = 0; + bool hasSVE = false; + if (Arg *A = Args.getLastArg(options::OPT_msve_vector_bits_EQ)) { + StringRef Val = A->getValue(); + if (Val == "128" || Val == "256" || Val == "512" || Val == "1024" || + Val == "2048" || Val == "128+" || Val == "256+" || Val == "512+" || + Val == "1024+" || Val == "2048+") { + unsigned Bits = 0; + if (Val.ends_with("+")) + Val = Val.substr(0, Val.size() - 1); + else { + bool Invalid = Val.getAsInteger(10, Bits); (void)Invalid; + assert(!Invalid && "Failed to parse value"); + vscaleMax = Bits / 128; + } + + bool Invalid = Val.getAsInteger(10, Bits); (void)Invalid; + assert(!Invalid && "Failed to parse value"); + vscaleMin = Bits / 128; + } else if (Val != "scalable") + getToolChain().getDriver().Diag(diag::warn_drv_clang_unsupported) + << A->getOption().getName() << Val; + } + for (auto Feature : unifyTargetFeatures(Features)) { + if (Feature.starts_with("+sve")) { + hasSVE = true; + break; + } + } + if (vscaleMin || vscaleMax) { + LowerCmdArgs.push_back("-vscale_range_min"); + LowerCmdArgs.push_back(Args.MakeArgString( + std::to_string(vscaleMin ? vscaleMin : 1))); + LowerCmdArgs.push_back("-vscale_range_max"); + LowerCmdArgs.push_back(Args.MakeArgString(std::to_string(vscaleMax))); + } else { + if (hasSVE) { + LowerCmdArgs.push_back("-vscale_range_min"); + LowerCmdArgs.push_back(Args.MakeArgString(std::to_string(1))); + LowerCmdArgs.push_back("-vscale_range_max"); + LowerCmdArgs.push_back(Args.MakeArgString(std::to_string(16))); + } + } + + // Set a -x flag for second part of Fortran frontend + for (Arg *A : Args.filtered(options::OPT_Mx_EQ)) { + A->claim(); + StringRef Value = A->getValue(); + auto XFlag = Value.split(","); + LowerCmdArgs.push_back("-x"); + LowerCmdArgs.push_back(Args.MakeArgString(XFlag.first)); + LowerCmdArgs.push_back(Args.MakeArgString(XFlag.second)); + } + + // Set a -y flag for second part of Fortran frontend + for (Arg *A : Args.filtered(options::OPT_My_EQ)) { + A->claim(); + StringRef Value = A->getValue(); + auto XFlag = Value.split(","); + LowerCmdArgs.push_back("-y"); + LowerCmdArgs.push_back(Args.MakeArgString(XFlag.first)); + LowerCmdArgs.push_back(Args.MakeArgString(XFlag.second)); + } + + // Set a -q (debug) flag for second part of Fortran frontend + for (Arg *A : Args.filtered(options::OPT_Mq_EQ)) { + A->claim(); + StringRef Value = A->getValue(); + auto XFlag = Value.split(","); + LowerCmdArgs.push_back("-q"); + LowerCmdArgs.push_back(Args.MakeArgString(XFlag.first)); + LowerCmdArgs.push_back(Args.MakeArgString(XFlag.second)); + } + + // Set a -qq (debug) flag for second part of Fortran frontend + for (Arg *A : Args.filtered(options::OPT_Mqq_EQ)) { + A->claim(); + StringRef Value = A->getValue(); + auto XFlag = Value.split(","); + LowerCmdArgs.push_back("-qq"); + LowerCmdArgs.push_back(Args.MakeArgString(XFlag.first)); + LowerCmdArgs.push_back(Args.MakeArgString(XFlag.second)); + } + + // Pass an arbitrary flag for second part of Fortran frontend + for (Arg *A : Args.filtered(options::OPT_Wm_EQ)) { + A->claim(); + StringRef Value = A->getValue(); + SmallVector PassArgs; + Value.split(PassArgs, StringRef(",")); + for (StringRef PassArg : PassArgs) { + LowerCmdArgs.push_back(Args.MakeArgString(PassArg)); + } + } + + LowerCmdArgs.push_back("-stbfile"); + LowerCmdArgs.push_back(STBFile); + + Path = llvm::sys::path::parent_path(Output.getFilename()); + bool IsOpenMPDevice = JA.isDeviceOffloading(Action::OFK_OpenMP); + + /* OpenMP GPU Offload */ + if(Args.getAllArgValues(options::OPT_fopenmp_targets_EQ).size() > 0) { + SmallString<128> TargetInfo;//("-fopenmp-targets "); + SmallString<256> TargetInfoAsm;//("-fopenmp-targets-asm "); + + Arg* Tgts = Args.getLastArg(options::OPT_fopenmp_targets_EQ); + assert(Tgts && Tgts->getNumValues() && + "OpenMP offloading has to have targets specified."); + for (unsigned i = 0; i < Tgts->getNumValues(); ++i) { + if (i) + TargetInfo += ','; + // We need to get the string from the triple because it may be not exactly + // the same as the one we get directly from the arguments. + llvm::Triple T(Tgts->getValue(i)); + TargetInfo += T.getTriple(); + // We also need to give a output file + TargetInfoAsm += Path; + TargetInfoAsm += "/"; + TargetInfoAsm += Stem; + TargetInfoAsm += "-"; + TargetInfoAsm += T.getTriple(); + TargetInfoAsm += ".ll"; + } + // The driver is aware that flang2 can generate multiple files at the same time. + // We mimic it here by exchanging the output files. + // The driver always uses the output file of -asm. + LowerCmdArgs.push_back("-fopenmp-targets"); + LowerCmdArgs.push_back(Args.MakeArgString(TargetInfo.str())); + if(IsOpenMPDevice) { + LowerCmdArgs.push_back("-fopenmp-targets-asm"); + LowerCmdArgs.push_back(Args.MakeArgString(OutFile)); + LowerCmdArgs.push_back("-asm"); + LowerCmdArgs.push_back(Args.MakeArgString(TargetInfoAsm.str())); + } else { + LowerCmdArgs.push_back("-fopenmp-targets-asm"); + LowerCmdArgs.push_back(Args.MakeArgString(TargetInfoAsm.str())); + LowerCmdArgs.push_back("-asm"); + LowerCmdArgs.push_back(Args.MakeArgString(OutFile)); + } + } else { + LowerCmdArgs.push_back("-asm"); + LowerCmdArgs.push_back(Args.MakeArgString(OutFile)); + } + + bool IsWindowsMSVC = getToolChain().getTriple().isWindowsMSVCEnvironment(); + if (IsWindowsMSVC && !Args.hasArg(options::OPT_noFlangLibs)) { + getToolChain().AddFortranStdlibLibArgs(Args, LowerCmdArgs); + for (auto Arg : Args.filtered(options::OPT_noFlangLibs)) { + Arg->claim(); + } + } + + C.addCommand(std::make_unique(JA, *this, ResponseFileSupport::AtFileUTF8(), LowerExec, LowerCmdArgs, Inputs)); +} + diff --git a/clang/lib/Driver/ToolChains/ClassicFlang.h b/clang/lib/Driver/ToolChains/ClassicFlang.h new file mode 100644 index 000000000000..5864e0776601 --- /dev/null +++ b/clang/lib/Driver/ToolChains/ClassicFlang.h @@ -0,0 +1,49 @@ +//===--- ClassicFlang.h - Flang ToolChain Implementations -------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ClassicFlang_H +#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ClassicFlang_H + +#include "MSVC.h" +#include "clang/Driver/Driver.h" +#include "clang/Driver/Tool.h" +#include "clang/Driver/Types.h" +#include "llvm/Frontend/Debug/Options.h" +#include "llvm/Option/Option.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/TargetParser/Triple.h" + +namespace clang { +namespace driver { + +namespace tools { + +/// \brief Flang Fortran frontend +class LLVM_LIBRARY_VISIBILITY ClassicFlang : public Tool { +public: + ClassicFlang(const ToolChain &TC) + : Tool("classic-flang", + "Fortran frontend to LLVM", TC) {} + + bool hasGoodDiagnostics() const override { return true; } + bool hasIntegratedAssembler() const override { return false; } + bool hasIntegratedCPP() const override { return true; } + + void ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, const InputInfoList &Inputs, + const llvm::opt::ArgList &TCArgs, + const char *LinkingOutput) const override; +}; + +} // end namespace tools + +} // end namespace driver +} // end namespace clang + +#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ClassicFlang_H diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index ae635fb6a180..7e9e139888aa 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -342,6 +342,20 @@ static bool shouldIgnoreUnsupportedTargetFeature(const Arg &TargetFeatureArg, return TargetFeatureArg.getOption().matches(options::OPT_mno_cumode); } +#ifdef ENABLE_CLASSIC_FLANG +/// \brief Determine if Fortran "main" object is needed +bool tools::needFortranMain(const Driver &D, const ArgList &Args) { + return (needFortranLibs(D, Args) && !Args.hasArg(options::OPT_Mnomain) && + !Args.hasArg(options::OPT_no_fortran_main)); +} + +/// \brief Determine if Fortran link libraies are needed +bool tools::needFortranLibs(const Driver &D, const ArgList &Args) { + return (D.IsFlangMode() && !Args.hasArg(options::OPT_nostdlib) && + !Args.hasArg(options::OPT_noFlangLibs)); +} +#endif + void tools::addPathIfExists(const Driver &D, const Twine &Path, ToolChain::path_list &Paths) { if (D.getVFS().exists(Path)) @@ -450,6 +464,9 @@ void tools::AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs, const ArgList &Args, ArgStringList &CmdArgs, const JobAction &JA) { const Driver &D = TC.getDriver(); +#ifdef ENABLE_CLASSIC_FLANG + bool SeenFirstLinkerInput = false; +#endif // Add extra linker input arguments which are not treated as inputs // (constructed via -Xarch_). @@ -483,6 +500,15 @@ void tools::AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs, if (II.isNothing()) continue; +#ifdef ENABLE_CLASSIC_FLANG + // Add Fortan "main" before the first linker input + if (!SeenFirstLinkerInput) { + if (needFortranMain(D, Args)) { + CmdArgs.push_back("-lflangmain"); + } + SeenFirstLinkerInput = true; + } +#endif // Otherwise, this is a linker input argument. const Arg &A = II.getInputArg(); @@ -527,6 +553,16 @@ void tools::AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs, addArchSpecificRPath(TC, Args, CmdArgs); } } +#ifdef ENABLE_CLASSIC_FLANG + if (!SeenFirstLinkerInput && needFortranMain(D, Args)) { + CmdArgs.push_back("-lflangmain"); + } + + // Claim "no Fortran main" arguments + for (auto Arg : Args.filtered(options::OPT_no_fortran_main, options::OPT_Mnomain)) { + Arg->claim(); + } +#endif } void tools::addLinkerCompressDebugSectionsOption( @@ -724,10 +760,18 @@ static void getWebAssemblyTargetFeatures(const Driver &D, options::OPT_m_wasm_Features_Group); } +#ifndef ENABLE_CLASSIC_FLANG void tools::getTargetFeatures(const Driver &D, const llvm::Triple &Triple, const ArgList &Args, ArgStringList &CmdArgs, bool ForAS, bool IsAux) { std::vector Features; +#else +void tools::getTargetFeatureList(const Driver &D, + const llvm::Triple &Triple, + const ArgList &Args, ArgStringList &CmdArgs, + bool ForAS, + std::vector &Features) { +#endif switch (Triple.getArch()) { default: break; @@ -802,6 +846,15 @@ void tools::getTargetFeatures(const Driver &D, const llvm::Triple &Triple, loongarch::getLoongArchTargetFeatures(D, Triple, Args, Features); break; } +#ifdef ENABLE_CLASSIC_FLANG +} + +void tools::getTargetFeatures(const Driver &D, const llvm::Triple &Triple, + const ArgList &Args, ArgStringList &CmdArgs, + bool ForAS, bool IsAux) { + std::vector Features; + getTargetFeatureList(D, Triple, Args, CmdArgs, ForAS, Features); +#endif for (auto Feature : unifyTargetFeatures(Features)) { CmdArgs.push_back(IsAux ? "-aux-target-feature" : "-target-feature"); @@ -1249,7 +1302,11 @@ bool tools::addOpenMPRuntime(const Compilation &C, ArgStringList &CmdArgs, bool ForceStaticHostRuntime, bool IsOffloadingHost, bool GompNeedsRT) { if (!Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ, - options::OPT_fno_openmp, false)) { + options::OPT_fno_openmp, false) +#ifdef ENABLE_CLASSIC_FLANG + && !Args.hasFlag(options::OPT_mp, options::OPT_nomp, false) +#endif + ) { // We need libomptarget (liboffload) if it's the choosen offloading runtime. if (Args.hasFlag(options::OPT_foffload_via_llvm, options::OPT_fno_offload_via_llvm, false)) @@ -1321,6 +1378,12 @@ void tools::addOpenMPHostOffloadingArgs(const Compilation &C, /// Add Fortran runtime libs void tools::addFortranRuntimeLibs(const ToolChain &TC, const ArgList &Args, llvm::opt::ArgStringList &CmdArgs) { +#ifdef ENABLE_CLASSIC_FLANG + if (needFortranLibs(TC.getDriver(), Args)) + TC.AddFortranStdlibLibArgs(Args, CmdArgs); + else + Args.ClaimAllArgs(options::OPT_noFlangLibs); +#else // Link FortranRuntime and FortranDecimal // These are handled earlier on Windows by telling the frontend driver to // add the correct libraries to link against as dependents in the object @@ -1356,6 +1419,7 @@ void tools::addFortranRuntimeLibs(const ToolChain &TC, const ArgList &Args, if (OMPRuntime == Driver::OMPRT_OMP && RuntimeLib == ToolChain::RLT_Libgcc) CmdArgs.push_back("-latomic"); } +#endif } void tools::addFortranRuntimeLibraryPath(const ToolChain &TC, diff --git a/clang/lib/Driver/ToolChains/CommonArgs.h b/clang/lib/Driver/ToolChains/CommonArgs.h index b6ddd99b8727..0bdff7d9ad78 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.h +++ b/clang/lib/Driver/ToolChains/CommonArgs.h @@ -24,6 +24,12 @@ namespace clang { namespace driver { namespace tools { +#ifdef ENABLE_CLASSIC_FLANG +bool needFortranLibs(const Driver &D, const llvm::opt::ArgList &Args); + +bool needFortranMain(const Driver &D, const llvm::opt::ArgList &Args); +#endif + void addPathIfExists(const Driver &D, const Twine &Path, ToolChain::path_list &Paths); @@ -170,6 +176,17 @@ void AddTargetFeature(const llvm::opt::ArgList &Args, std::string getCPUName(const Driver &D, const llvm::opt::ArgList &Args, const llvm::Triple &T, bool FromAs = false); +#ifdef ENABLE_CLASSIC_FLANG +// Helper function extracted from upstream getTargetFeatures. Classic Flang +// uses this helper to render the target feature options for the Fortran +// frontend. +void getTargetFeatureList(const Driver &D, + const llvm::Triple &Triple, + const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs, + bool ForAS, std::vector &Features); +#endif + void getTargetFeatures(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, bool ForAS, diff --git a/clang/lib/Driver/ToolChains/Cuda.cpp b/clang/lib/Driver/ToolChains/Cuda.cpp index 0922a97ed7c1..9cd31fcae396 100644 --- a/clang/lib/Driver/ToolChains/Cuda.cpp +++ b/clang/lib/Driver/ToolChains/Cuda.cpp @@ -1074,3 +1074,38 @@ VersionTuple CudaToolChain::computeMSVCVersion(const Driver *D, const ArgList &Args) const { return HostTC.computeMSVCVersion(D, Args); } + +#ifdef ENABLE_CLASSIC_FLANG +static void AddFlangSysIncludeArg(const ArgList &DriverArgs, + ArgStringList &Flang1Args, + ToolChain::path_list IncludePathList) { + std::string ArgValue; // Path argument value + + // Make up argument value consisting of paths separated by colons + bool first = true; + for (auto P : IncludePathList) { + if (first) { + first = false; + } else { + ArgValue += ":"; + } + ArgValue += P; + } + + // Add the argument + Flang1Args.push_back("-stdinc"); + Flang1Args.push_back(DriverArgs.MakeArgString(ArgValue)); +} + +void CudaToolChain::AddFlangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &Flang1Args) const { + path_list IncludePathList; + const Driver &D = getDriver(); + if (DriverArgs.hasArg(options::OPT_nostdinc)) + return; + SmallString<128> P(D.Dir); + llvm::sys::path::append(P, "../include"); + IncludePathList.push_back(P.c_str()); + AddFlangSysIncludeArg(DriverArgs, Flang1Args, IncludePathList); +} +#endif diff --git a/clang/lib/Driver/ToolChains/Cuda.h b/clang/lib/Driver/ToolChains/Cuda.h index 7a6a6fb20901..78cc11fe7b66 100644 --- a/clang/lib/Driver/ToolChains/Cuda.h +++ b/clang/lib/Driver/ToolChains/Cuda.h @@ -222,6 +222,11 @@ class LLVM_LIBRARY_VISIBILITY CudaToolChain : public NVPTXToolChain { llvm::opt::ArgStringList &CC1Args) const override; void AddIAMCUIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; +#ifdef ENABLE_CLASSIC_FLANG + void + AddFlangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &Flang1Args) const override; +#endif SanitizerMask getSupportedSanitizers() const override; diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp index 1ae865f37911..bdaca25503f3 100644 --- a/clang/lib/Driver/ToolChains/Flang.cpp +++ b/clang/lib/Driver/ToolChains/Flang.cpp @@ -777,9 +777,6 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA, } } else if (isa(JA)) { CmdArgs.push_back("-emit-obj"); - } else if (isa(JA)) { - // The precompile job action is only needed for options such as -mcpu=help. - // Those will already have been handled by the fc1 driver. } else { assert(false && "Unexpected action class for Flang tool."); } @@ -952,6 +949,8 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(Output.getFilename()); } + assert(Input.isFilename() && "Invalid input."); + if (Args.getLastArg(options::OPT_save_temps_EQ)) Args.AddLastArg(CmdArgs, options::OPT_save_temps_EQ); @@ -971,18 +970,7 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA, } } - // The input could be Ty_Nothing when "querying" options such as -mcpu=help - // are used. - ArrayRef FrontendInputs = Input; - if (Input.isNothing()) - FrontendInputs = {}; - - for (const InputInfo &Input : FrontendInputs) { - if (Input.isFilename()) - CmdArgs.push_back(Input.getFilename()); - else - Input.getInputArg().renderAsInput(Args, CmdArgs); - } + CmdArgs.push_back(Input.getFilename()); const char *Exec = Args.MakeArgString(D.GetProgramPath("flang", TC)); C.addCommand(std::make_unique(JA, *this, diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp index 0767fe6c5879..562ff80a2dd1 100644 --- a/clang/lib/Driver/ToolChains/Linux.cpp +++ b/clang/lib/Driver/ToolChains/Linux.cpp @@ -632,6 +632,200 @@ std::string Linux::getDynamicLinker(const ArgList &Args) const { return "/" + LibDir + "/" + Loader; } +#ifdef ENABLE_CLASSIC_FLANG +/// Convert path list to Fortran frontend argument +static void AddFlangSysIncludeArg(const ArgList &DriverArgs, + ArgStringList &Flang1Args, + ToolChain::path_list IncludePathList) { + std::string ArgValue; // Path argument value + + // Make up argument value consisting of paths separated by colons + bool first = true; + for (auto P : IncludePathList) { + if (first) { + first = false; + } else { + ArgValue += ":"; + } + ArgValue += P; + } + + // Add the argument + Flang1Args.push_back("-stdinc"); + Flang1Args.push_back(DriverArgs.MakeArgString(ArgValue)); +} + +void Linux::AddFlangSystemIncludeArgs(const ArgList &DriverArgs, + ArgStringList &Flang1Args) const { + path_list IncludePathList; + const Driver &D = getDriver(); + std::string SysRoot = computeSysRoot(); + + if (DriverArgs.hasArg(options::OPT_nostdinc)) + return; + + { + SmallString<128> P(D.Dir); + if (isCrossCompiling()) + llvm::sys::path::append(P, "../include", + getEffectiveTriple().getTriple()); + else + llvm::sys::path::append(P, "../include"); + IncludePathList.push_back(P.c_str()); + } + + if (!DriverArgs.hasArg(options::OPT_nostdlibinc)) + IncludePathList.push_back(SysRoot + "/usr/local/include"); + + if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) { + SmallString<128> P(D.ResourceDir); + llvm::sys::path::append(P, "include"); + IncludePathList.push_back(P.c_str()); + } + + if (DriverArgs.hasArg(options::OPT_nostdlibinc)) { + AddFlangSysIncludeArg(DriverArgs, Flang1Args, IncludePathList); + return; + } + + // Check for configure-time C include directories. + StringRef CIncludeDirs(C_INCLUDE_DIRS); + if (CIncludeDirs != "") { + SmallVector dirs; + CIncludeDirs.split(dirs, ":"); + for (StringRef dir : dirs) { + StringRef Prefix = + llvm::sys::path::is_absolute(dir) ? StringRef(SysRoot) : ""; + IncludePathList.push_back(Prefix.str() + dir.str()); + } + AddFlangSysIncludeArg(DriverArgs, Flang1Args, IncludePathList); + return; + } + + // Lacking those, try to detect the correct set of system includes for the + // target triple. + + // Add include directories specific to the selected multilib set and multilib. + if (GCCInstallation.isValid()) { + const auto &Callback = Multilibs.includeDirsCallback(); + if (Callback) { + for (const auto &Path : Callback(GCCInstallation.getMultilib())) + addExternCSystemIncludeIfExists( + DriverArgs, Flang1Args, GCCInstallation.getInstallPath() + Path); + } + } + + // Implement generic Debian multiarch support. + const StringRef X86_64MultiarchIncludeDirs[] = { + "/usr/include/x86_64-linux-gnu", + + // FIXME: These are older forms of multiarch. It's not clear that they're + // in use in any released version of Debian, so we should consider + // removing them. + "/usr/include/i686-linux-gnu/64", "/usr/include/i486-linux-gnu/64"}; + const StringRef X86MultiarchIncludeDirs[] = { + "/usr/include/i386-linux-gnu", + + // FIXME: These are older forms of multiarch. It's not clear that they're + // in use in any released version of Debian, so we should consider + // removing them. + "/usr/include/x86_64-linux-gnu/32", "/usr/include/i686-linux-gnu", + "/usr/include/i486-linux-gnu"}; + const StringRef AArch64MultiarchIncludeDirs[] = { + "/usr/include/aarch64-linux-gnu"}; + const StringRef ARMMultiarchIncludeDirs[] = { + "/usr/include/arm-linux-gnueabi"}; + const StringRef ARMHFMultiarchIncludeDirs[] = { + "/usr/include/arm-linux-gnueabihf"}; + const StringRef MIPSMultiarchIncludeDirs[] = {"/usr/include/mips-linux-gnu"}; + const StringRef MIPSELMultiarchIncludeDirs[] = { + "/usr/include/mipsel-linux-gnu"}; + const StringRef MIPS64MultiarchIncludeDirs[] = { + "/usr/include/mips64-linux-gnu", "/usr/include/mips64-linux-gnuabi64"}; + const StringRef MIPS64ELMultiarchIncludeDirs[] = { + "/usr/include/mips64el-linux-gnu", + "/usr/include/mips64el-linux-gnuabi64"}; + const StringRef PPCMultiarchIncludeDirs[] = { + "/usr/include/powerpc-linux-gnu"}; + const StringRef PPC64MultiarchIncludeDirs[] = { + "/usr/include/powerpc64-linux-gnu"}; + const StringRef PPC64LEMultiarchIncludeDirs[] = { + "/usr/include/powerpc64le-linux-gnu"}; + const StringRef SparcMultiarchIncludeDirs[] = { + "/usr/include/sparc-linux-gnu"}; + const StringRef Sparc64MultiarchIncludeDirs[] = { + "/usr/include/sparc64-linux-gnu"}; + ArrayRef MultiarchIncludeDirs; + switch (getTriple().getArch()) { + case llvm::Triple::x86_64: + MultiarchIncludeDirs = X86_64MultiarchIncludeDirs; + break; + case llvm::Triple::x86: + MultiarchIncludeDirs = X86MultiarchIncludeDirs; + break; + case llvm::Triple::aarch64: + case llvm::Triple::aarch64_be: + MultiarchIncludeDirs = AArch64MultiarchIncludeDirs; + break; + case llvm::Triple::arm: + if (getTriple().getEnvironment() == llvm::Triple::GNUEABIHF) + MultiarchIncludeDirs = ARMHFMultiarchIncludeDirs; + else + MultiarchIncludeDirs = ARMMultiarchIncludeDirs; + break; + case llvm::Triple::mips: + MultiarchIncludeDirs = MIPSMultiarchIncludeDirs; + break; + case llvm::Triple::mipsel: + MultiarchIncludeDirs = MIPSELMultiarchIncludeDirs; + break; + case llvm::Triple::mips64: + MultiarchIncludeDirs = MIPS64MultiarchIncludeDirs; + break; + case llvm::Triple::mips64el: + MultiarchIncludeDirs = MIPS64ELMultiarchIncludeDirs; + break; + case llvm::Triple::ppc: + MultiarchIncludeDirs = PPCMultiarchIncludeDirs; + break; + case llvm::Triple::ppc64: + MultiarchIncludeDirs = PPC64MultiarchIncludeDirs; + break; + case llvm::Triple::ppc64le: + MultiarchIncludeDirs = PPC64LEMultiarchIncludeDirs; + break; + case llvm::Triple::sparc: + MultiarchIncludeDirs = SparcMultiarchIncludeDirs; + break; + case llvm::Triple::sparcv9: + MultiarchIncludeDirs = Sparc64MultiarchIncludeDirs; + break; + default: + break; + } + for (StringRef Dir : MultiarchIncludeDirs) { + if (llvm::sys::fs::exists(SysRoot + Dir)) { + IncludePathList.push_back(SysRoot + Dir.str()); + break; + } + } + + if (getTriple().getOS() == llvm::Triple::RTEMS) { + AddFlangSysIncludeArg(DriverArgs, Flang1Args, IncludePathList); + return; + } + + // Add an include of '/include' directly. This isn't provided by default by + // system GCCs, but is often used with cross-compiling GCCs, and harmless to + // add even when Clang is acting as-if it were a system compiler. + IncludePathList.push_back(SysRoot + "/include"); + + IncludePathList.push_back(SysRoot + "/usr/include"); + + AddFlangSysIncludeArg(DriverArgs, Flang1Args, IncludePathList); +} +#endif + void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs, ArgStringList &CC1Args) const { const Driver &D = getDriver(); diff --git a/clang/lib/Driver/ToolChains/Linux.h b/clang/lib/Driver/ToolChains/Linux.h index 2eb2d05786fe..3d64e210a3c0 100644 --- a/clang/lib/Driver/ToolChains/Linux.h +++ b/clang/lib/Driver/ToolChains/Linux.h @@ -27,6 +27,11 @@ class LLVM_LIBRARY_VISIBILITY Linux : public Generic_ELF { const llvm::Triple &TargetTriple, StringRef SysRoot) const override; +#ifdef ENABLE_CLASSIC_FLANG + void + AddFlangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &Flang1Args) const override; +#endif void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; diff --git a/clang/lib/Driver/ToolChains/MSVC.cpp b/clang/lib/Driver/ToolChains/MSVC.cpp index bae41fc06c03..7f9f98169ec7 100644 --- a/clang/lib/Driver/ToolChains/MSVC.cpp +++ b/clang/lib/Driver/ToolChains/MSVC.cpp @@ -271,6 +271,13 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA, } } +#ifdef ENABLE_CLASSIC_FLANG + if (C.getDriver().IsFlangMode()) { + CmdArgs.push_back(Args.MakeArgString(std::string("-libpath:") + + TC.getDriver().Dir + "/../lib")); + } +#endif + // Add compiler-rt lib in case if it was explicitly // specified as an argument for --rtlib option. if (!Args.hasArg(options::OPT_nostdlib)) { @@ -521,6 +528,74 @@ void MSVCToolChain::AddHIPRuntimeLibArgs(const ArgList &Args, "amdhip64.lib"}); } +#ifdef ENABLE_CLASSIC_FLANG +void MSVCToolChain::AddFortranStdlibLibArgs(const ArgList &Args, + ArgStringList &CmdArgs) const { + bool staticFlangLibs = false; + bool useOpenMP = false; + + if (Args.hasArg(options::OPT_staticFlangLibs)) { + for (auto *A: Args.filtered(options::OPT_staticFlangLibs)) { + A->claim(); + staticFlangLibs = true; + } + } + + Arg *A = Args.getLastArg(options::OPT_mp, options::OPT_nomp, + options::OPT_fopenmp, options::OPT_fno_openmp); + if (A && + (A->getOption().matches(options::OPT_mp) || + A->getOption().matches(options::OPT_fopenmp))) { + useOpenMP = true; + } + + if (needFortranMain(getDriver(), Args)) { + // flangmain is always static + CmdArgs.push_back("-linker"); + CmdArgs.push_back("/subsystem:console"); + CmdArgs.push_back("-linker"); + CmdArgs.push_back("/defaultlib:flangmain.lib"); + } + + if (staticFlangLibs) { + CmdArgs.push_back("-linker"); + CmdArgs.push_back("/defaultlib:libflang.lib"); + CmdArgs.push_back("-linker"); + CmdArgs.push_back("/defaultlib:libflangrti.lib"); + CmdArgs.push_back("-linker"); + CmdArgs.push_back("/defaultlib:libpgmath.lib"); + } else { + CmdArgs.push_back("-linker"); + CmdArgs.push_back("/defaultlib:flang.lib"); + CmdArgs.push_back("-linker"); + CmdArgs.push_back("/defaultlib:flangrti.lib"); + CmdArgs.push_back("-linker"); + CmdArgs.push_back("/defaultlib:pgmath.lib"); + } + if (useOpenMP) { + CmdArgs.push_back("-linker"); + CmdArgs.push_back("/nodefaultlib:vcomp.lib"); + CmdArgs.push_back("-linker"); + CmdArgs.push_back("/nodefaultlib:vcompd.lib"); + CmdArgs.push_back("-linker"); + CmdArgs.push_back("/defaultlib:libomp.lib"); + } + + // Allways link Fortran executables with Pthreads + // CmdArgs.push_back("-lpthread"); + + // These options are added clang-cl in Clang.cpp for C/C++ + // In clang-cl.exe -MD and -MT control these options, but in + // flang.exe like clang.exe these are different options for + // dependency tracking. Let's assume that if somebody needs + // static flang libs, they don't need static C runtime libs. + // FIXME: Use LLVM_USE_CRT_ variable + // to use libcmt.lib or msvcrt.lib + CmdArgs.push_back("-linker"); + CmdArgs.push_back("/defaultlib:libcmt.lib"); +} +#endif + void MSVCToolChain::printVerboseInfo(raw_ostream &OS) const { CudaInstallation->print(OS); RocmInstallation->print(OS); @@ -645,6 +720,42 @@ void MSVCToolChain::AddSystemIncludeWithSubfolder( addSystemInclude(DriverArgs, CC1Args, path); } +#ifdef ENABLE_CLASSIC_FLANG +/// Convert path list to Fortran frontend argument +static void AddFlangSysIncludeArg(const ArgList &DriverArgs, + ArgStringList &Flang1Args, + ToolChain::path_list IncludePathList) { + std::string ArgValue; // Path argument value + + // Make up argument value consisting of paths separated by colons + bool first = true; + for (auto P : IncludePathList) { + if (first) { + first = false; + } else { + ArgValue += ";"; + } + ArgValue += P; + } + + // Add the argument + Flang1Args.push_back("-stdinc"); + Flang1Args.push_back(DriverArgs.MakeArgString(ArgValue)); +} + +void MSVCToolChain::AddFlangSystemIncludeArgs(const ArgList &DriverArgs, + ArgStringList &Flang1Args) const { +path_list IncludePathList; + const Driver &D = getDriver(); + if (DriverArgs.hasArg(options::OPT_nostdinc)) + return; + SmallString<128> P(D.Dir); + llvm::sys::path::append(P, "../include"); + IncludePathList.push_back(P.c_str()); + AddFlangSysIncludeArg(DriverArgs, Flang1Args, IncludePathList); +} +#endif + void MSVCToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs, ArgStringList &CC1Args) const { if (DriverArgs.hasArg(options::OPT_nostdinc)) diff --git a/clang/lib/Driver/ToolChains/MSVC.h b/clang/lib/Driver/ToolChains/MSVC.h index b35390c52a04..530d8f3cf121 100644 --- a/clang/lib/Driver/ToolChains/MSVC.h +++ b/clang/lib/Driver/ToolChains/MSVC.h @@ -85,6 +85,12 @@ class LLVM_LIBRARY_VISIBILITY MSVCToolChain : public ToolChain { return VSLayout == llvm::ToolsetLayout::VS2017OrNewer; } +#ifdef ENABLE_CLASSIC_FLANG + void + AddFlangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &Flang1Args) const override; +#endif + void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; @@ -95,6 +101,11 @@ class LLVM_LIBRARY_VISIBILITY MSVCToolChain : public ToolChain { void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; +#ifdef ENABLE_CLASSIC_FLANG + void AddFortranStdlibLibArgs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const override; +#endif + void AddHIPIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; diff --git a/clang/lib/Driver/Types.cpp b/clang/lib/Driver/Types.cpp old mode 100644 new mode 100755 index eaca74a7b552..e8d828f1b729 --- a/clang/lib/Driver/Types.cpp +++ b/clang/lib/Driver/Types.cpp @@ -52,9 +52,11 @@ const char *types::getTypeName(ID Id) { types::ID types::getPreprocessedType(ID Id) { ID PPT = getInfo(Id).PreprocessedType; +#ifndef ENABLE_CLASSIC_FLANG assert((getInfo(Id).Phases.contains(phases::Preprocess) != (PPT == TY_INVALID)) && "Unexpected Preprocess Type."); +#endif return PPT; } @@ -131,6 +133,10 @@ bool types::isAcceptedByClang(ID Id) { case TY_Asm: case TY_C: case TY_PP_C: case TY_CL: case TY_PP_CL: case TY_CLCXX: case TY_PP_CLCXX: +#ifdef ENABLE_CLASSIC_FLANG + case TY_F_FreeForm: case TY_PP_F_FreeForm: + case TY_F_FixedForm: case TY_PP_F_FixedForm: +#endif case TY_CUDA: case TY_PP_CUDA: case TY_CUDA_DEVICE: case TY_HIP: @@ -161,6 +167,13 @@ bool types::isAcceptedByFlang(ID Id) { default: return false; +#ifdef ENABLE_CLASSIC_FLANG + case TY_F_FreeForm: + case TY_PP_F_FreeForm: + case TY_F_FixedForm: + case TY_PP_F_FixedForm: + return true; +#else case TY_Fortran: case TY_PP_Fortran: return true; @@ -170,6 +183,7 @@ bool types::isAcceptedByFlang(ID Id) { case TY_PP_CUDA: case TY_CUDA: return true; +#endif } } @@ -290,6 +304,22 @@ bool types::isHIP(ID Id) { } } +#ifdef ENABLE_CLASSIC_FLANG +bool types::isFreeFormFortran(ID Id) { + if (!isAcceptedByFlang(Id)) + return false; + + return (Id == TY_F_FreeForm || Id == TY_PP_F_FreeForm); +} + +bool types::isFixedFormFortran(ID Id) { + if (!isAcceptedByFlang(Id)) + return false; + + return (Id == TY_F_FixedForm || Id == TY_PP_F_FixedForm); +} +#endif + bool types::isHLSL(ID Id) { return Id == TY_HLSL; } bool types::isSrcFile(ID Id) { @@ -300,8 +330,13 @@ types::ID types::lookupTypeForExtension(llvm::StringRef Ext) { return llvm::StringSwitch(Ext) .Case("c", TY_C) .Case("C", TY_CXX) +#ifdef ENABLE_CLASSIC_FLANG + .Case("F", TY_F_FixedForm) + .Case("f", TY_PP_F_FixedForm) +#else .Case("F", TY_Fortran) .Case("f", TY_PP_Fortran) +#endif .Case("h", TY_CHeader) .Case("H", TY_CXXHeader) .Case("i", TY_PP_C) @@ -336,6 +371,20 @@ types::ID types::lookupTypeForExtension(llvm::StringRef Ext) { .Case("cui", TY_PP_CUDA) .Case("cxx", TY_CXX) .Case("CXX", TY_CXX) +#ifdef ENABLE_CLASSIC_FLANG + .Case("for", TY_PP_F_FixedForm) + .Case("FOR", TY_PP_F_FixedForm) + .Case("fpp", TY_F_FixedForm) + .Case("FPP", TY_F_FixedForm) + .Case("f90", TY_PP_F_FreeForm) + .Case("f95", TY_PP_F_FreeForm) + .Case("f03", TY_PP_F_FreeForm) + .Case("f08", TY_PP_F_FreeForm) + .Case("F90", TY_F_FreeForm) + .Case("F95", TY_F_FreeForm) + .Case("F03", TY_F_FreeForm) + .Case("F08", TY_F_FreeForm) +#else .Case("F03", TY_Fortran) .Case("f03", TY_PP_Fortran) .Case("F08", TY_Fortran) @@ -348,6 +397,7 @@ types::ID types::lookupTypeForExtension(llvm::StringRef Ext) { .Case("FOR", TY_PP_Fortran) .Case("fpp", TY_Fortran) .Case("FPP", TY_Fortran) +#endif .Case("gch", TY_PCH) .Case("hip", TY_HIP) .Case("hipi", TY_PP_HIP) diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp index 17f624e96453..c747c844f9c0 100644 --- a/clang/lib/Frontend/InitPreprocessor.cpp +++ b/clang/lib/Frontend/InitPreprocessor.cpp @@ -166,26 +166,6 @@ static void DefineFloatMacros(MacroBuilder &Builder, StringRef Prefix, Builder.defineMacro(DefPrefix + "MIN__", Twine(Min)+Ext); } - -/// DefineTypeSize - Emit a macro to the predefines buffer that declares a macro -/// named MacroName with the max value for a type with width 'TypeWidth' a -/// signedness of 'isSigned' and with a value suffix of 'ValSuffix' (e.g. LL). -static void DefineTypeSize(const Twine &MacroName, unsigned TypeWidth, - StringRef ValSuffix, bool isSigned, - MacroBuilder &Builder) { - llvm::APInt MaxVal = isSigned ? llvm::APInt::getSignedMaxValue(TypeWidth) - : llvm::APInt::getMaxValue(TypeWidth); - Builder.defineMacro(MacroName, toString(MaxVal, 10, isSigned) + ValSuffix); -} - -/// DefineTypeSize - An overloaded helper that uses TargetInfo to determine -/// the width, suffix, and signedness of the given type -static void DefineTypeSize(const Twine &MacroName, TargetInfo::IntType Ty, - const TargetInfo &TI, MacroBuilder &Builder) { - DefineTypeSize(MacroName, TI.getTypeWidth(Ty), TI.getTypeConstantSuffix(Ty), - TI.isTypeSigned(Ty), Builder); -} - static void DefineFmt(const LangOptions &LangOpts, const Twine &Prefix, TargetInfo::IntType Ty, const TargetInfo &TI, MacroBuilder &Builder) { diff --git a/clang/test/CMakeLists.txt b/clang/test/CMakeLists.txt index 5369dc92f69e..b91fcd45de4d 100644 --- a/clang/test/CMakeLists.txt +++ b/clang/test/CMakeLists.txt @@ -13,6 +13,7 @@ llvm_canonicalize_cmake_booleans( ENABLE_BACKTRACES LLVM_BUILD_EXAMPLES LLVM_BYE_LINK_INTO_TOOLS + LLVM_ENABLE_CLASSIC_FLANG LLVM_ENABLE_PLUGINS LLVM_ENABLE_ZLIB LLVM_ENABLE_ZSTD diff --git a/clang/test/CodeGen/libpgmath-logfun-aarch64.ll b/clang/test/CodeGen/libpgmath-logfun-aarch64.ll new file mode 100644 index 000000000000..141fed29ccd1 --- /dev/null +++ b/clang/test/CodeGen/libpgmath-logfun-aarch64.ll @@ -0,0 +1,58 @@ +; REQUIRES: aarch64-registered-target + +; RUN: %clang -target aarch64-unknown-linux-gnu -Ofast -S %s -o - | FileCheck %s + +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + +define void @fun_(i64* nocapture %z) local_unnamed_addr #0 { +L.entry: + %0 = bitcast i64* %z to i8* + %1 = bitcast i64* %z to float* + %2 = load float, float* %1, align 4 + %3 = fpext float %2 to double + %4 = fadd double %3, 5.000000e-01 + %5 = tail call double @__pd_log_1(double %4) #1 + %6 = fptrunc double %5 to float + %7 = tail call float @__ps_exp_1(float %6) #2 + store float %7, float* %1, align 4 + %8 = getelementptr i8, i8* %0, i64 4 + %9 = bitcast i8* %8 to float* + %10 = load float, float* %9, align 4 + %11 = fpext float %10 to double + %12 = fadd double %11, 5.000000e-01 + %13 = tail call double @__pd_log_1(double %12) #1 + %14 = fptrunc double %13 to float + %15 = tail call float @__ps_exp_1(float %14) #2 + store float %15, float* %9, align 4 + %16 = getelementptr i64, i64* %z, i64 1 + %17 = bitcast i64* %16 to float* + %18 = load float, float* %17, align 4 + %19 = fpext float %18 to double + %20 = fadd double %19, 5.000000e-01 + %21 = tail call double @__pd_log_1(double %20) #1 + %22 = fptrunc double %21 to float + %23 = tail call float @__ps_exp_1(float %22) #2 + store float %23, float* %17, align 4 + %24 = getelementptr i8, i8* %0, i64 12 + %25 = bitcast i8* %24 to float* + %26 = load float, float* %25, align 4 + %27 = fpext float %26 to double + %28 = fadd double %27, 5.000000e-01 + %29 = tail call double @__pd_log_1(double %28) #1 + %30 = fptrunc double %29 to float + %31 = tail call float @__ps_exp_1(float %30) #2 + store float %31, float* %25, align 4 + ret void + +; CHECK-NOT: __pd_log_4 +; CHECK: __pd_log_2 +; CHECK: __pd_log_2 +} + +; Function Attrs: nounwind readnone willreturn +declare float @__ps_exp_1(float) #0 + +; Function Attrs: nounwind readnone willreturn +declare double @__pd_log_1(double) #0 + +attributes #0 = { nounwind readnone willreturn } diff --git a/clang/test/CodeGen/libpgmath-logfun-x86_64.ll b/clang/test/CodeGen/libpgmath-logfun-x86_64.ll new file mode 100644 index 000000000000..3ce1d910947f --- /dev/null +++ b/clang/test/CodeGen/libpgmath-logfun-x86_64.ll @@ -0,0 +1,57 @@ +; REQUIRES: x86-registered-target + +; RUN: %clang -target x86_64-unknown-linux-gnu -msse -Ofast -S %s -o - | FileCheck %s + +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + +define void @fun_(i64* nocapture %z) local_unnamed_addr #0 { +L.entry: + %0 = bitcast i64* %z to i8* + %1 = bitcast i64* %z to float* + %2 = load float, float* %1, align 4 + %3 = fpext float %2 to double + %4 = fadd double %3, 5.000000e-01 + %5 = tail call double @__pd_log_1(double %4) #1 + %6 = fptrunc double %5 to float + %7 = tail call float @__ps_exp_1(float %6) #2 + store float %7, float* %1, align 4 + %8 = getelementptr i8, i8* %0, i64 4 + %9 = bitcast i8* %8 to float* + %10 = load float, float* %9, align 4 + %11 = fpext float %10 to double + %12 = fadd double %11, 5.000000e-01 + %13 = tail call double @__pd_log_1(double %12) #1 + %14 = fptrunc double %13 to float + %15 = tail call float @__ps_exp_1(float %14) #2 + store float %15, float* %9, align 4 + %16 = getelementptr i64, i64* %z, i64 1 + %17 = bitcast i64* %16 to float* + %18 = load float, float* %17, align 4 + %19 = fpext float %18 to double + %20 = fadd double %19, 5.000000e-01 + %21 = tail call double @__pd_log_1(double %20) #1 + %22 = fptrunc double %21 to float + %23 = tail call float @__ps_exp_1(float %22) #2 + store float %23, float* %17, align 4 + %24 = getelementptr i8, i8* %0, i64 12 + %25 = bitcast i8* %24 to float* + %26 = load float, float* %25, align 4 + %27 = fpext float %26 to double + %28 = fadd double %27, 5.000000e-01 + %29 = tail call double @__pd_log_1(double %28) #1 + %30 = fptrunc double %29 to float + %31 = tail call float @__ps_exp_1(float %30) #2 + store float %31, float* %25, align 4 + ret void + +; CHECK-NOT: __pd_log_1 +; CHECK: __pd_log_4 +} + +; Function Attrs: nounwind readnone willreturn +declare float @__ps_exp_1(float) #0 + +; Function Attrs: nounwind readnone willreturn +declare double @__pd_log_1(double) #0 + +attributes #0 = { nounwind readnone willreturn } diff --git a/clang/test/Driver/autocomplete.c b/clang/test/Driver/autocomplete.c index 8cc604dbff87..e279718b0a49 100644 --- a/clang/test/Driver/autocomplete.c +++ b/clang/test/Driver/autocomplete.c @@ -86,7 +86,7 @@ // FVECLIBALL-NEXT: libmvec // FVECLIBALL-NEXT: MASSV // FVECLIBALL-NEXT: none -// FVECLIBALL-NEXT: SLEEF +// FVECLIBALL: SLEEF // FVECLIBALL-NEXT: SVML // RUN: %clang --autocomplete=-fshow-overloads= | FileCheck %s -check-prefix=FSOVERALL // FSOVERALL: all diff --git a/clang/test/Driver/emit-flang-attrs.f90 b/clang/test/Driver/emit-flang-attrs.f90 new file mode 100644 index 000000000000..7a455a9a9551 --- /dev/null +++ b/clang/test/Driver/emit-flang-attrs.f90 @@ -0,0 +1,60 @@ +! REQUIRES: aarch64-registered-target +! REQUIRES: classic_flang +! RUN: %flang -### -target aarch64-linux-gnu -march=armv8-a -c %s 2>&1 | FileCheck --check-prefix=CHECK-ATTRS-NEON %s +! RUN: %flang -### -target aarch64-linux-gnu -march=armv8-a+sve -c %s 2>&1 | FileCheck --check-prefix=CHECK-ATTRS-SVE %s +! RUN: %flang -### -target aarch64-linux-gnu -march=armv8-a+nosve -c %s 2>&1 | FileCheck --check-prefix=CHECK-ATTRS-NOSVE %s +! RUN: %flang -### -target aarch64-linux-gnu -march=armv8-a+sve+nosve -c %s 2>&1 | FileCheck --check-prefix=CHECK-ATTRS-SVE-REVERT %s +! RUN: %flang -### -target aarch64-linux-gnu -march=armv8-a+sve2+nosve2 -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-SVE2-REVERT +! RUN: %flang -### -target aarch64-linux-gnu -march=armv8-a+sve2-aes -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-SVE2-AES +! RUN: %flang -### -target aarch64-linux-gnu -march=armv8-a+sve2-sm4 -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-SVE2-SM4 +! RUN: %flang -### -target aarch64-linux-gnu -march=armv8-a+sve2-sha3 -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-SVE2-SHA3 +! RUN: %flang -### -target aarch64-linux-gnu -march=armv8-a+sve2-bitperm+nosve2-bitperm -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-SVE2-BITPERM-REVERT +! RUN: %flang -### -target aarch64-linux-gnu -march=armv8-a+sve2 -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-SVE2-IMPLY +! RUN: %flang -### -target aarch64-linux-gnu -march=armv8-a+nosve+sve2 -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-SVE2-CONFLICT-REV +! RUN: %flang -### -target aarch64-linux-gnu -march=armv8-a+sve+sve2 -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-SVE-SVE2 +! RUN: %flang -### -target aarch64-linux-gnu -march=armv8-a+sve2-bitperm -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-SVE2-BITPERM +! RUN: %flang -### -target aarch64-linux-gnu -march=armv8-a+nosve+sve2-aes -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-SVE-SUBFEATURE-CONFLICT-REV +! RUN: %flang -### -target aarch64-linux-gnu -march=armv8-a+sve2-sm4+nosve2 -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-SVE2-SUBFEATURE-CONFLICT +! RUN: %flang -### -target aarch64-linux-gnu -march=armv8-a+sve2-bitperm+nosve2-aes -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-SVE2-SUBFEATURE-MIX +! RUN: %flang -### -target aarch64-linux-gnu -march=armv8-a+sve2-sm4+nosve2-sm4 -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-SVE2-SM4-REVERT +! RUN: %flang -### -target aarch64-linux-gnu -march=armv8-a+sve2-sha3+nosve2-sha3 %s 2>&1 | FileCheck %s --check-prefix=CHECK-SVE2-SHA3-REVERT +! RUN: %flang -### -target aarch64-linux-gnu -march=armv8-a+sve2-aes+nosve2-aes %s 2>&1 | FileCheck %s --check-prefix=CHECK-SVE2-AES-REVERT + +! CHECK-ATTRS-NEON: "{{.*}}flang2" +! CHECK-ATTRS-NEON-SAME: "-target_features" "+v8a,+fp-armv8,+neon" +! CHECK-ATTRS-SVE: "{{.*}}flang2" +! CHECK-ATTRS-SVE-SAME: "-target_features" "+v8a,+fp-armv8,+fullfp16,+neon,+sve" +! CHECK-ATTRS-NOSVE: "{{.*}}flang2" +! CHECK-ATTRS-NOSVE-SAME: "-target_features" "+v8a,+fp-armv8,+neon" +! CHECK-ATTRS-SVE-REVERT: "{{.*}}flang2" +! CHECK-ATTRS-SVE-REVERT-SAME: "-target_features" "+v8a,+fp-armv8,+fullfp16,+neon,-sve" +! CHECK-SVE2-REVERT: "{{.*}}flang2" +! CHECK-SVE2-REVERT-SAME: "-target_features" "+v8a,+fp-armv8,+fullfp16,+neon,+sve,-sve2" +! CHECK-SVE2-AES: "{{.*}}flang2" +! CHECK-SVE2-AES-SAME: "-target_features" "+v8a,+fp-armv8,+fullfp16,+neon,+sve,+sve2-aes,+sve2" +! CHECK-SVE2-SM4: "{{.*}}flang2" +! CHECK-SVE2-SM4-SAME: "-target_features" "+v8a,+fp-armv8,+fullfp16,+neon,+sve,+sve2-sm4,+sve2" +! CHECK-SVE2-SHA3: "{{.*}}flang2" +! CHECK-SVE2-SHA3-SAME: "-target_features" "+v8a,+fp-armv8,+fullfp16,+neon,+sve,+sve2-sha3,+sve2" +! CHECK-SVE2-BITPERM-REVERT: "{{.*}}flang2" +! CHECK-SVE2-BITPERM-REVERT-SAME: "-target_features" "+v8a,+fp-armv8,+fullfp16,+neon,+sve,-sve2-bitperm,+sve2" +! CHECK-SVE2-IMPLY: "{{.*}}flang2" +! CHECK-SVE2-IMPLY-SAME: "-target_features" "+v8a,+fp-armv8,+fullfp16,+neon,+sve,+sve2" +! CHECK-SVE2-CONFLICT-REV: "{{.*}}flang2" +! CHECK-SVE2-CONFLICT-REV-SAME: "-target_features" "+v8a,+fp-armv8,+fullfp16,+neon,+sve,+sve2" +! CHECK-SVE-SVE2: "{{.*}}flang2" +! CHECK-SVE-SVE2-SAME: "-target_features" "+v8a,+fp-armv8,+fullfp16,+neon,+sve,+sve2" +! CHECK-SVE2-BITPERM: "{{.*}}flang2" +! CHECK-SVE2-BITPERM-SAME: "-target_features" "+v8a,+fp-armv8,+fullfp16,+neon,+sve,+sve2-bitperm,+sve2" +! CHECK-SVE-SUBFEATURE-CONFLICT-REV: "{{.*}}flang2" +! CHECK-SVE-SUBFEATURE-CONFLICT-REV-SAME: "-target_features" "+v8a,+fp-armv8,+fullfp16,+neon,+sve,+sve2-aes,+sve2" +! CHECK-SVE2-SUBFEATURE-CONFLICT: "{{.*}}flang2" +! CHECK-SVE2-SUBFEATURE-CONFLICT-SAME: "-target_features" "+v8a,+fp-armv8,+fullfp16,+neon,+sve,-sve2-sm4,-sve2" +! CHECK-SVE2-SUBFEATURE-MIX: "{{.*}}flang2" +! CHECK-SVE2-SUBFEATURE-MIX-SAME: "-target_features" "+v8a,+fp-armv8,+fullfp16,+neon,+sve,+sve2-bitperm,+sve2" +! CHECK-SVE2-SM4-REVERT: "{{.*}}flang2" +! CHECK-SVE2-SM4-REVERT-SAME: "-target_features" "+v8a,+fp-armv8,+fullfp16,+neon,+sve,-sve2-sm4,+sve2" +! CHECK-SVE2-SHA3-REVERT: "{{.*}}flang2" +! CHECK-SVE2-SHA3-REVERT-SAME: "-target_features" "+v8a,+fp-armv8,+fullfp16,+neon,+sve,-sve2-sha3,+sve2" +! CHECK-SVE2-AES-REVERT: "{{.*}}flang2" +! CHECK-SVE2-AES-REVERT-SAME: "-target_features" "+v8a,+fp-armv8,+fullfp16,+neon,+sve,-sve2-aes,+sve2" diff --git a/clang/test/Driver/flang/Inputs/llvm-ir-input.ll b/clang/test/Driver/flang/Inputs/llvm-ir-input.ll new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/clang/test/Driver/flang/classic-flang-cross-compile.F95 b/clang/test/Driver/flang/classic-flang-cross-compile.F95 new file mode 100644 index 000000000000..8ab407d175d2 --- /dev/null +++ b/clang/test/Driver/flang/classic-flang-cross-compile.F95 @@ -0,0 +1,15 @@ +! REQUIRES: classic_flang +! REQUIRES: host-x86_64 + +! Check if the cross-compiling flang1/flang2 binaries and include paths +! are used by Clang when cross-compiling. + +! RUN: %clang --driver-mode=flang -target aarch64-unknown-linux-gnu %s -### 2>&1 \ +! RUN: | FileCheck %s + +! RUN: %clang --driver-mode=flang -target aarch64-linux-gnu %s -### 2>&1 \ +! RUN: | FileCheck %s + +! CHECK: aarch64-unknown-linux-gnu-flang1 +! CHECK-SAME: include/aarch64-unknown-linux-gnu +! CHECK: aarch64-unknown-linux-gnu-flang2 diff --git a/clang/test/Driver/flang/classic-flang-emit-flang-llvm.f95 b/clang/test/Driver/flang/classic-flang-emit-flang-llvm.f95 new file mode 100644 index 000000000000..225207c85db7 --- /dev/null +++ b/clang/test/Driver/flang/classic-flang-emit-flang-llvm.f95 @@ -0,0 +1,10 @@ +! REQUIRES: classic_flang + +! Check that the -emit-flang-llvm option dumps LLVM IR pre-optimisation + +! RUN: %clang --driver-mode=flang -emit-flang-llvm -S -o %t.ll %s -### 2>&1 \ +! RUN: | FileCheck %s +! CHECK-NOT: argument unused during compilation: '-S' +! CHECK: "{{.*}}flang1" +! CHECK-NEXT: "{{.*}}flang2" +! CHECK-NOT: "{{.*}}clang{{.*}}" "-cc1" diff --git a/clang/test/Driver/flang/classic-flang-fp-contract.f95 b/clang/test/Driver/flang/classic-flang-fp-contract.f95 new file mode 100644 index 000000000000..b181065d1cac --- /dev/null +++ b/clang/test/Driver/flang/classic-flang-fp-contract.f95 @@ -0,0 +1,27 @@ +! REQUIRES: classic_flang + +! RUN: %flang -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FLANG2-FP-CONTRACT-ABSENCE +! RUN: %flang -O1 -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FLANG2-FP-CONTRACT +! RUN: %flang -O2 -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FLANG2-FP-CONTRACT +! RUN: %flang -O3 -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FLANG2-FP-CONTRACT +! RUN: %flang -Ofast -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FLANG2-FP-CONTRACT +! RUN: %flang -ffp-contract=fast -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FLANG2-FP-CONTRACT-ABSENCE +! RUN: %flang -O1 -ffp-contract=fast -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FLANG2-FP-CONTRACT +! RUN: %flang -O2 -ffp-contract=fast -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FLANG2-FP-CONTRACT +! RUN: %flang -O3 -ffp-contract=fast -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FLANG2-FP-CONTRACT +! RUN: %flang -Ofast -ffp-contract=fast -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FLANG2-FP-CONTRACT +! RUN: %flang -ffp-contract=on -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FLANG2-FP-CONTRACT-ABSENCE +! RUN: %flang -O1 -ffp-contract=on -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FLANG2-FP-CONTRACT +! RUN: %flang -O2 -ffp-contract=on -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FLANG2-FP-CONTRACT +! RUN: %flang -O3 -ffp-contract=on -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FLANG2-FP-CONTRACT +! RUN: %flang -Ofast -ffp-contract=on -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FLANG2-FP-CONTRACT +! RUN: %flang -ffp-contract=off -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FLANG2-FP-CONTRACT-ABSENCE +! RUN: %flang -O1 -ffp-contract=off -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FLANG2-FP-CONTRACT-ABSENCE +! RUN: %flang -O2 -ffp-contract=off -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FLANG2-FP-CONTRACT-ABSENCE +! RUN: %flang -O3 -ffp-contract=off -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FLANG2-FP-CONTRACT-ABSENCE +! RUN: %flang -Ofast -ffp-contract=off -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FLANG2-FP-CONTRACT-ABSENCE + +! CHECK-FLANG2-FP-CONTRACT: "{{.*}}flang2" +! CHECK-FLANG2-FP-CONTRACT-SAME: "-x" "172" "0x40000000" "-x" "179" "1" "-x" "216" "0x1000" +! CHECK-FLANG2-FP-CONTRACT-ABSENCE: "{{.*}}flang2" +! CHECK-FLANG2-FP-CONTRACT-ABSENCE-SAME: "-x" "171" "0x40000000" "-x" "178" "1" diff --git a/clang/test/Driver/flang/classic-flang-must-preprocess.F b/clang/test/Driver/flang/classic-flang-must-preprocess.F new file mode 100644 index 000000000000..cf2e4207a4a0 --- /dev/null +++ b/clang/test/Driver/flang/classic-flang-must-preprocess.F @@ -0,0 +1,12 @@ +! REQUIRES: classic_flang + +! Check that the driver invokes flang1 correctly for fixed-form Fortran code +! which requires preprocessing. + +! RUN: %clang --driver-mode=flang -target x86_64-unknown-linux-gnu -c %s -### 2>&1 \ +! RUN: | FileCheck %s +! CHECK: "{{.*}}flang1" +! CHECK-SAME: "-preprocess" +! CHECK-SAME: "-nofreeform" +! CHECK-NEXT: "{{.*}}flang2" +! CHECK-NEXT: {{clang.* "-cc1"}} diff --git a/clang/test/Driver/flang/classic-flang-must-preprocess.F95 b/clang/test/Driver/flang/classic-flang-must-preprocess.F95 new file mode 100644 index 000000000000..85ec49fe3fab --- /dev/null +++ b/clang/test/Driver/flang/classic-flang-must-preprocess.F95 @@ -0,0 +1,12 @@ +! REQUIRES: classic_flang + +! Check that the driver invokes flang1 correctly for free-form Fortran code +! which requires preprocessing. + +! RUN: %clang --driver-mode=flang -target x86_64-unknown-linux-gnu -c %s -### 2>&1 \ +! RUN: | FileCheck %s +! CHECK: "{{.*}}flang1" +! CHECK-SAME: "-preprocess" +! CHECK-SAME: "-freeform" +! CHECK-NEXT: "{{.*}}flang2" +! CHECK-NEXT: {{clang.* "-cc1"}} diff --git a/clang/test/Driver/flang/classic-flang-version.f b/clang/test/Driver/flang/classic-flang-version.f new file mode 100644 index 000000000000..c2082d3af8b7 --- /dev/null +++ b/clang/test/Driver/flang/classic-flang-version.f @@ -0,0 +1,3 @@ +! REQUIRES: classic-flang +! RUN: %flang --version | FileCheck %s +! CHECK: flang version {{.*}} ({{.*}}flang-compiler/classic-flang-llvm-project.git {{.*}}) diff --git a/clang/test/Driver/flang/classic-flang-vscale-mbits.f95 b/clang/test/Driver/flang/classic-flang-vscale-mbits.f95 new file mode 100644 index 000000000000..5515deb0925d --- /dev/null +++ b/clang/test/Driver/flang/classic-flang-vscale-mbits.f95 @@ -0,0 +1,28 @@ +// RUN: %clang --driver-mode=flang -### -S --target=aarch64 -march=armv8-a+sve -msve-vector-bits=128 %s 2>&1 | FileCheck -check-prefix=CHECK-SVE-128 %s +// RUN: %clang --driver-mode=flang -### -S --target=aarch64 -march=armv8-a+sve -msve-vector-bits=128+ %s 2>&1 | FileCheck -check-prefix=CHECK-SVE-128PLUS %s +// RUN: %clang --driver-mode=flang -### -S --target=aarch64 -march=armv8-a+sve -msve-vector-bits=256 %s 2>&1 | FileCheck -check-prefix=CHECK-SVE-256 %s +// RUN: %clang --driver-mode=flang -### -S --target=aarch64 -march=armv8-a+sve -msve-vector-bits=256+ %s 2>&1 | FileCheck -check-prefix=CHECK-SVE-256PLUS %s +// RUN: %clang --driver-mode=flang -### -S --target=aarch64 -march=armv8-a+sve2 -msve-vector-bits=512 %s 2>&1 | FileCheck -check-prefix=CHECK-SVE2-512 %s +// RUN: %clang --driver-mode=flang -### -S --target=aarch64 -march=armv8-a+sve2 -msve-vector-bits=512+ %s 2>&1 | FileCheck -check-prefix=CHECK-SVE2-512PLUS %s +// RUN: %clang --driver-mode=flang -### -S --target=aarch64 -march=armv8-a+sve2-sha3 -msve-vector-bits=2048 %s 2>&1 | FileCheck -check-prefix=CHECK-SVE2SHA3-2048 %s +// RUN: %clang --driver-mode=flang -### -S --target=aarch64 -march=armv8-a+sve2-sha3 -msve-vector-bits=2048+ %s 2>&1 | FileCheck -check-prefix=CHECK-SVE2SHA3-2048PLUS %s +// RUN: %clang --driver-mode=flang -### -S --target=aarch64 -march=armv8-a+sve2 -msve-vector-bits=scalable %s 2>&1 | FileCheck -check-prefix=CHECK-SVE2-SCALABLE %s + +// CHECK-SVE-128: "-target_features" "+v8a,+fp-armv8,+fullfp16,+neon,+sve" +// CHECK-SVE-128-DAG: "-vscale_range_min" "1" "-vscale_range_max" "1" +// CHECK-SVE-128PLUS: "-target_features" "+v8a,+fp-armv8,+fullfp16,+neon,+sve" +// CHECK-SVE-128PLUS-DAG: "-vscale_range_min" "1" "-vscale_range_max" "0" +// CHECK-SVE-256: "-target_features" "+v8a,+fp-armv8,+fullfp16,+neon,+sve" +// CHECK-SVE-256-DAG: "-vscale_range_min" "2" "-vscale_range_max" "2" +// CHECK-SVE-256PLUS: "-target_features" "+v8a,+fp-armv8,+fullfp16,+neon,+sve" +// CHECK-SVE-256PLUS-DAG: "-vscale_range_min" "2" "-vscale_range_max" "0" +// CHECK-SVE2-512: "-target_features" "+v8a,+fp-armv8,+fullfp16,+neon,+sve,+sve2" +// CHECK-SVE2-512-DAG: "-vscale_range_min" "4" "-vscale_range_max" "4" +// CHECK-SVE2-512PLUS: "-target_features" "+v8a,+fp-armv8,+fullfp16,+neon,+sve,+sve2" +// CHECK-SVE2-512PLUS-DAG: "-vscale_range_min" "4" "-vscale_range_max" "0" +// CHECK-SVE2SHA3-2048: "-target_features" "+v8a,+fp-armv8,+fullfp16,+neon,+sha2,+sha3,+sve,+sve2,+sve2-sha3" +// CHECK-SVE2SHA3-2048-DAG: "-vscale_range_min" "16" "-vscale_range_max" "16" +// CHECK-SVE2SHA3-2048PLUS: "-target_features" "+v8a,+fp-armv8,+fullfp16,+neon,+sha2,+sha3,+sve,+sve2,+sve2-sha3" +// CHECK-SVE2SHA3-2048PLUS-DAG: "-vscale_range_min" "16" "-vscale_range_max" "0" +// CHECK-SVE2-SCALABLE: "-target_features" "+v8a,+fp-armv8,+fullfp16,+neon,+sve,+sve2" +// CHECK-SVE2-SCALABLE-DAG: "-vscale_range_min" "1" "-vscale_range_max" "16" diff --git a/clang/test/Driver/flang/classic-flang-vscale.f95 b/clang/test/Driver/flang/classic-flang-vscale.f95 new file mode 100644 index 000000000000..455bfc35c5cf --- /dev/null +++ b/clang/test/Driver/flang/classic-flang-vscale.f95 @@ -0,0 +1,28 @@ +// RUN: %clang --driver-mode=flang -### -S --target=aarch64 -march=armv8-a %s 2>&1 | FileCheck -check-prefix=CHECK-NEON %s +// RUN: %clang --driver-mode=flang -### -S --target=aarch64 -march=armv8-a+sve %s 2>&1 | FileCheck -check-prefix=CHECK-SVE %s +// RUN: %clang --driver-mode=flang -### -S --target=aarch64 -march=armv8-a+sve2 %s 2>&1 | FileCheck -check-prefix=CHECK-SVE2 %s +// RUN: %clang --driver-mode=flang -### -S --target=aarch64 -march=armv8-a+sve2-sha3 %s 2>&1 | FileCheck -check-prefix=CHECK-SVE2SHA3 %s +// RUN: %clang --driver-mode=flang -### -S --target=aarch64 -march=armv8-a+sve+nosve %s 2>&1 | FileCheck -check-prefix=CHECK-SVE-NOSVE %s +// RUN: %clang --driver-mode=flang -### -S --target=aarch64 -march=armv8-a+sve2+nosve2-sha3 %s 2>&1 | FileCheck -check-prefix=CHECK-SVE2-NOSVE2SHA3 %s +// RUN: %clang --driver-mode=flang -### -S --target=aarch64 -march=armv8-a+sve2-sha3+nosve2 %s 2>&1 | FileCheck -check-prefix=CHECK-SVE2SHA3-NOSVE2 %s +// RUN: %clang --driver-mode=flang -### -S --target=aarch64 -march=armv8-a+sve2-sha3+nosve %s 2>&1 | FileCheck -check-prefix=CHECK-SVE2SHA3-NOSVE %s + +// CHECK-NEON: "-target_features" "+v8a,+fp-armv8,+neon" +// CHECK-NEON-NOT: "-vscale_range_min" +// CHECK-NEON-NOT: "-vscale_range_max" +// CHECK-SVE: "-target_features" "+v8a,+fp-armv8,+fullfp16,+neon,+sve" +// CHECK-SVE-DAG: "-vscale_range_min" "1" "-vscale_range_max" "16" +// CHECK-SVE2: "-target_features" "+v8a,+fp-armv8,+fullfp16,+neon,+sve,+sve2" +// CHECK-SVE2-DAG: "-vscale_range_min" "1" "-vscale_range_max" "16" +// CHECK-SVE2SHA3: "-target_features" "+v8a,+fp-armv8,+fullfp16,+neon,+sha2,+sha3,+sve,+sve2,+sve2-sha3" +// CHECK-SVE2SHA3-DAG: "-vscale_range_min" "1" "-vscale_range_max" "16" +// CHECK-SVE-NOSVE: "-target_features" "+v8a,+fp-armv8,+fullfp16,+neon,-sve" +// CHECK-SVE-NOSVE-NOT: "-vscale_range_min" +// CHECK-SVE-NOSVE-NOT: "-vscale_range_max" +// CHECK-SVE2-NOSVE2SHA3: "-target_features" "+v8a,+fp-armv8,+fullfp16,+neon,+sve,+sve2" +// CHECK-SVE2-NOSVE2SHA3-DAG: "-vscale_range_min" "1" "-vscale_range_max" "16" +// CHECK-SVE2SHA3-NOSVE2: "-target_features" "+v8a,+fp-armv8,+fullfp16,+neon,+sha2,+sha3,+sve,-sve2,-sve2-sha3" +// CHECK-SVE2SHA3-NOSVE2-DAG: "-vscale_range_min" "1" "-vscale_range_max" "16" +// CHECK-SVE2SHA3-NOSVE: "-target_features" "+v8a,+fp-armv8,+fullfp16,+neon,+sha2,+sha3,-sve,-sve2,-sve2-sha3" +// CHECK-SVE2SHA3-NOSVE-NOT: "-vscale_range_min" +// CHECK-SVE2SHA3-NOSVE-NOT: "-vscale_range_max" diff --git a/clang/test/Driver/flang/classic-flang.f b/clang/test/Driver/flang/classic-flang.f new file mode 100644 index 000000000000..c680abc076ae --- /dev/null +++ b/clang/test/Driver/flang/classic-flang.f @@ -0,0 +1,26 @@ +! REQUIRES: classic_flang + +! Check that the driver invokes flang1 correctly for preprocessed fixed-form +! Fortran code. + +! RUN: %clang --driver-mode=flang -target x86_64-unknown-linux-gnu -c %s -### 2>&1 \ +! RUN: | FileCheck %s +! CHECK: "{{.*}}flang1" +! CHECK-NOT: "-preprocess" +! CHECK-SAME: "-nofreeform" +! CHECK-NEXT: "{{.*}}flang2" +! CHECK-NEXT: {{clang.* "-cc1"}} + +! Check that the driver invokes flang1 correctly when preprocessing is +! explicitly requested. + +! RUN: %clang --driver-mode=flang -target x86_64-unknown-linux-gnu -E %s -### 2>&1 \ +! RUN: | FileCheck --check-prefix=CHECK-PREPROCESS %s +! CHECK-PREPROCESS: "{{.*}}flang1" +! CHECK-PREPROCESS-SAME: "-preprocess" +! CHECK-PREPROCESS-SAME: "-es" +! CHECK-PREPROCESS-SAME: "-pp" +! CHECK-PREPROCESS-NOT: "{{.*}}flang1" +! CHECK-PREPROCESS-NOT: "{{.*}}flang2" +! CHECK-PREPROCESS-NOT: {{clang.* "-cc1"}} +! CHECK-PREPROCESS-NOT: {{clang.* "-cc1as"}} diff --git a/clang/test/Driver/flang/classic-flang.f95 b/clang/test/Driver/flang/classic-flang.f95 new file mode 100644 index 000000000000..75edb96db745 --- /dev/null +++ b/clang/test/Driver/flang/classic-flang.f95 @@ -0,0 +1,139 @@ +! REQUIRES: classic_flang + +! Check that the driver invokes flang1 correctly for preprocessed free-form +! Fortran code. Also check that the backend is invoked correctly. +! In particular, target-dependent flags (e.g. -mavx for x86_64) should be visible. + +! RUN: %clang --driver-mode=flang -target x86_64-unknown-linux-gnu -mavx -c %s -### 2>&1 \ +! RUN: | FileCheck --check-prefix=CHECK-OBJECT %s +! CHECK-OBJECT: "{{.*}}flang1" +! CHECK-OBJECT-NOT: "-preprocess" +! CHECK-OBJECT-SAME: "-freeform" +! CHECK-OBJECT-NEXT: "{{.*}}flang2" +! CHECK-OBJECT-SAME: "-asm" [[LLFILE:.*.ll]] +! CHECK-OBJECT-NEXT: {{clang.* "-cc1"}} +! CHECK-OBJECT-SAME: "-target-feature" "+avx" +! CHECK-OBJECT-SAME: "-o" "classic-flang.o" +! CHECK-OBJECT-SAME: "-x" "ir" +! CHECK-OBJECT-SAME: [[LLFILE]] + +! Check that the driver invokes flang1 correctly when preprocessing is +! explicitly requested. + +! RUN: %clang --driver-mode=flang -target x86_64-unknown-linux-gnu -E %s -### 2>&1 \ +! RUN: | FileCheck --check-prefix=CHECK-PREPROCESS %s +! CHECK-PREPROCESS: "{{.*}}flang1" +! CHECK-PREPROCESS-SAME: "-preprocess" +! CHECK-PREPROCESS-SAME: "-es" +! CHECK-PREPROCESS-SAME: "-pp" +! CHECK-PREPROCESS-NOT: "{{.*}}flang1" +! CHECK-PREPROCESS-NOT: "{{.*}}flang2" +! CHECK-PREPROCESS-NOT: {{clang.* "-cc1"}} +! CHECK-PREPROCESS-NOT: {{clang.* "-cc1as"}} + +! Check that the backend job (clang -cc1) is not combined into the compile job +! (flang2) even if -integrated-as is specified. +! Also, check that AArch64-specific target-dependent flags are visible. + +! RUN: %clang --driver-mode=flang -target aarch64-unknown-linux-gnu -integrated-as -mno-outline-atomics -S %s -### 2>&1 \ +! RUN: | FileCheck --check-prefix=CHECK-ASM %s +! CHECK-ASM: "{{.*}}flang1" +! CHECK-ASM-NEXT: "{{.*}}flang2" +! CHECK-ASM-SAME: "-asm" [[LLFILE:.*.ll]] +! CHECK-ASM-NEXT: {{clang.* "-cc1"}} +! CHECK-ASM-SAME: "-target-feature" "-outline-atomics" +! CHECK-ASM-SAME: "-o" "classic-flang.s" +! CHECK-ASM-SAME: "-x" "ir" +! CHECK-ASM-SAME: [[LLFILE]] + +! Check that other target-independent compiler flags are visible. +! RUN: %clang --driver-mode=flang -target x86_64-unknown-linux-gnu --gcc-install-dir=%S/../Inputs/debian_multiarch_tree/usr/lib/gcc/x86_64-linux-gnu/10/ -fno-strict-aliasing -funroll-loops %s -### 2>&1 \ +! RUN: | FileCheck --check-prefix=CHECK-FFLAGS %s +! CHECK-FFLAGS: "{{.*}}flang1" +! CHECK-FFLAGS-NEXT: "{{.*}}flang2" +! CHECK-FFLAGS-SAME: "-asm" [[LLFILE:.*.ll]] +! CHECK-FFLAGS-NEXT: {{clang.* "-cc1"}} +! CHECK-FFLAGS-SAME: "-relaxed-aliasing" +! CHECK-FFLAGS-SAME: "-funroll-loops" +! CHECK-FFLAGS-SAME: "-x" "ir" +! CHECK-FFLAGS-SAME: [[LLFILE]] +! CHECK-FFLAGS-NEXT: "{{.*}}ld{{(.exe)?}}" +! CHECK-FFLAGS-SAME: "-L{{[^ ]*[/\\]+}}debian_multiarch_tree/usr/lib/gcc/x86_64-linux-gnu/10" + +! Check that the linker job is given the correct libraries and library paths. + +! RUN: %flang -target x86_64-linux-gnu -ccc-install-dir %S/../Inputs/basic_linux_tree/usr/bin -mp \ +! RUN: %s -lfoo -### 2>&1 | FileCheck --check-prefixes=CHECK-LD,CHECK-MAIN,CHECK-DYNAMIC-FLANG,CHECK-DYNAMIC-OMP %s +! RUN: %flang -target x86_64-linux-gnu -ccc-install-dir %S/../Inputs/basic_linux_tree/usr/bin -mp -nomp \ +! RUN: %s -lfoo -### 2>&1 | FileCheck --check-prefixes=CHECK-LD,CHECK-MAIN,CHECK-DYNAMIC-FLANG,CHECK-NO-OMP %s +! RUN: %flang -target x86_64-linux-gnu -ccc-install-dir %S/../Inputs/basic_linux_tree/usr/bin -fopenmp \ +! RUN: %s -lfoo -### 2>&1 | FileCheck --check-prefixes=CHECK-LD,CHECK-MAIN,CHECK-DYNAMIC-FLANG,CHECK-DYNAMIC-OMP %s +! RUN: %flang -target x86_64-linux-gnu -ccc-install-dir %S/../Inputs/basic_linux_tree/usr/bin -fopenmp -fno-openmp \ +! RUN: %s -lfoo -### 2>&1 | FileCheck --check-prefixes=CHECK-LD,CHECK-MAIN,CHECK-DYNAMIC-FLANG,CHECK-NO-OMP %s +! RUN: %flang -target x86_64-linux-gnu -ccc-install-dir %S/../Inputs/basic_linux_tree/usr/bin -fopenmp -static-openmp \ +! RUN: %s -lfoo -### 2>&1 | FileCheck --check-prefixes=CHECK-LD,CHECK-MAIN,CHECK-DYNAMIC-FLANG,CHECK-STATIC-OMP %s +! RUN: %flang -target x86_64-linux-gnu -ccc-install-dir %S/../Inputs/basic_linux_tree/usr/bin -fopenmp -static-flang-libs \ +! RUN: %s -lfoo -### 2>&1 | FileCheck --check-prefixes=CHECK-LD,CHECK-MAIN,CHECK-STATIC-FLANG,CHECK-DYNAMIC-OMP %s +! RUN: %flang -target x86_64-linux-gnu -ccc-install-dir %S/../Inputs/basic_linux_tree/usr/bin -static-flang-libs \ +! RUN: %s -lfoo -### 2>&1 | FileCheck --check-prefixes=CHECK-LD,CHECK-MAIN,CHECK-STATIC-FLANG,CHECK-NO-OMP %s +! RUN: %flang -target x86_64-linux-gnu -ccc-install-dir %S/../Inputs/basic_linux_tree/usr/bin -Mnomain \ +! RUN: %s -lfoo -### 2>&1 | FileCheck --check-prefixes=CHECK-LD,CHECK-NOMAIN,CHECK-DYNAMIC-FLANG %s +! RUN: %flang -target x86_64-linux-gnu -ccc-install-dir %S/../Inputs/basic_linux_tree/usr/bin -fno-fortran-main \ +! RUN: %s -lfoo -### 2>&1 | FileCheck --check-prefixes=CHECK-LD,CHECK-NOMAIN,CHECK-DYNAMIC-FLANG %s +! CHECK-LD: "{{.*}}ld{{(.exe)?}}" +! CHECK-LD-NOT: "-static" +! CHECK-LD-SAME: "{{[^"]*}}classic-flang-{{[^ ]*}}.o" +! CHECK-MAIN-SAME: "-lflangmain" +! CHECK-NOMAIN-NOT: "-lflangmain" +! CHECK-LD-SAME: "-lfoo" "-L{{[^ ]*[/\\]+}}basic_linux_tree{{[/\\]+}}usr{{[/\\]+}}lib" +! CHECK-DYNAMIC-FLANG-NOT: "-Bstatic" +! CHECK-DYNAMIC-FLANG: "-lflang" "-lflangrti" "-lpgmath" "-lpthread" "-lrt" "-lm" +! CHECK-DYNAMIC-FLANG-NOT: "-Bdynamic" +! CHECK-STATIC-FLANG: "-Bstatic" "-lflang" "-lflangrti" "-lpgmath" "-Bdynamic" "-lpthread" "-lrt" "-lm" +! CHECK-DYNAMIC-OMP-NOT: "-Bstatic" +! CHECK-DYNAMIC-OMP: "-lomp" "-L{{[^ ]*[/\\]+}}basic_linux_tree{{[/\\]+}}usr{{[/\\]+}}lib" +! CHECK-DYNAMIC-OMP-NOT: "-Bdynamic" +! CHECK-STATIC-OMP: "-Bstatic" "-lomp" "-Bdynamic" "-L{{[^ ]*[/\\]+}}basic_linux_tree{{[/\\]+}}usr{{[/\\]+}}lib" +! CHECK-NO-OMP-NOT: "-lomp" + +! RUN: %flang -target x86_64-linux-gnu -ccc-install-dir %S/../Inputs/basic_linux_tree/usr/bin -static -static-flang-libs \ +! RUN: %s -lfoo -### 2>&1 | FileCheck --check-prefixes=CHECK-LD-STATIC,CHECK-NO-OMP %s +! RUN: %flang -target x86_64-linux-gnu -ccc-install-dir %S/../Inputs/basic_linux_tree/usr/bin -static -fopenmp \ +! RUN: %s -lfoo -### 2>&1 | FileCheck --check-prefixes=CHECK-LD-STATIC,CHECK-STATIC-BOTH %s +! RUN: %flang -target x86_64-linux-gnu -ccc-install-dir %S/../Inputs/basic_linux_tree/usr/bin -static -fopenmp -static-openmp \ +! RUN: %s -lfoo -### 2>&1 | FileCheck --check-prefixes=CHECK-LD-STATIC,CHECK-STATIC-BOTH %s +! CHECK-LD-STATIC: "{{.*}}ld{{(.exe)?}}" +! CHECK-LD-STATIC: "-static" "-o" "a.out" +! CHECK-LD-STATIC: "{{[^"]*}}classic-flang-{{[^ ]*}}.o" "-lflangmain" "-lfoo" "-L{{[^ ]*[/\\]+}}basic_linux_tree{{[/\\]+}}usr{{[/\\]+}}lib" +! CHECK-LD-STATIC-NOT: "-Bstatic" +! CHECK-LD-STATIC: "-lflang" "-lflangrti" "-lpgmath" "-lpthread" "-lrt" "-lm" +! CHECK-LD-STATIC-NOT: "-Bdynamic" +! CHECK-STATIC-BOTH-NOT: "-Bstatic" +! CHECK-STATIC-BOTH: "-lomp" +! CHECK-STATIC-BOTH-NOT: "-Bdynamic" + +! RUN: %flang -target x86_64-linux-gnu -ccc-install-dir %S/../Inputs/basic_linux_tree/usr/bin -no-flang-libs \ +! RUN: %s -lfoo -### 2>&1 | FileCheck --check-prefixes=CHECK-NOFLANGLIBS %s +! CHECK-NOFLANGLIBS: "{{.*}}ld{{(.exe)?}}" +! CHECK-NOFLANGLIBS-SAME: "{{[^"]*}}classic-flang-{{[^ ]*}}.o" +! CHECK-NOFLANGLIBS-NOT: "-lflangmain" +! CHECK-NOFLANGLIBS-SAME: "-lfoo" "-L{{[^ ]*[/\\]+}}basic_linux_tree{{[/\\]+}}usr{{[/\\]+}}lib" +! CHECK-NOFLANGLIBS-NOT: "-lflang" "-lflangrti" "-lpgmath" +! CHECK-NOFLANGLIBS: "-lm" "-lgcc" +! CHECK-NOFLANGLIBS: "-lgcc_s" +! CHECK-NOFLANGLIBS: "-lc" + +! In Flang mode, we always link with libm, even with -nostdlib. +! RUN: %flang -target x86_64-linux-gnu -ccc-install-dir %S/../Inputs/basic_linux_tree/usr/bin -nostdlib \ +! RUN: %s -lfoo -### 2>&1 | FileCheck --check-prefixes=CHECK-NOSTDLIB %s +! CHECK-NOSTDLIB: "{{.*}}ld{{(.exe)?}}" +! CHECK-NOSTDLIB-SAME: "{{[^"]*}}classic-flang-{{[^ ]*}}.o" +! CHECK-NOSTDLIB-NOT: "-lflangmain" +! CHECK-NOSTDLIB-SAME: "-lfoo" +! CHECK-NOSTDLIB-NOT: "-L{{[^ ]*[/\\]+}}basic_linux_tree{{[/\\]+}}usr{{[/\\]+}}lib" +! CHECK-NOSTDLIB-NOT: "-lflang" "-lflangrti" "-lpgmath" +! CHECK-NOSTDLIB-NOT: "-lpthread" "-lrt" +! CHECK-NOSTDLIB-NOT: "-lm" +! CHECK-NOSTDLIB-NOT: "-lgcc" +! CHECK-NOSTDLIB-NOT: "-lgcc_s" +! CHECK-NOSTDLIB-NOT: "-lc" diff --git a/clang/test/Driver/flang/flang.f90 b/clang/test/Driver/flang/flang.f90 index b52977ee66d7..20e43d050475 100644 --- a/clang/test/Driver/flang/flang.f90 +++ b/clang/test/Driver/flang/flang.f90 @@ -1,5 +1,7 @@ ! Check that flang -fc1 is invoked when in --driver-mode=flang. +! UNSUPPORTED: classic_flang + ! This is a copy of flang_ucase.F90 because the driver has logic in it which ! differentiates between F90 and f90 files. Flang will not treat these files ! differently. diff --git a/clang/test/Driver/flang/flang_ucase.F90 b/clang/test/Driver/flang/flang_ucase.F90 index 88aedc39fb94..e3352018a678 100644 --- a/clang/test/Driver/flang/flang_ucase.F90 +++ b/clang/test/Driver/flang/flang_ucase.F90 @@ -1,5 +1,7 @@ ! Check that flang -fc1 is invoked when in --driver-mode=flang. +! UNSUPPORTED: classic_flang + ! This is a copy of flang.f90 because the driver has logic in it which ! differentiates between F90 and f90 files. Flang will not treat these files ! differently. diff --git a/clang/test/Driver/flang/llvm-ir-input.f b/clang/test/Driver/flang/llvm-ir-input.f new file mode 100644 index 000000000000..c34bf28328cb --- /dev/null +++ b/clang/test/Driver/flang/llvm-ir-input.f @@ -0,0 +1,7 @@ +! Check that LLVM IR input is passed to clang instead of flang1. + +! REQUIRES: classic_flang +! RUN: %clang --driver-mode=flang -S %S/Inputs/llvm-ir-input.ll -### 2>&1 | FileCheck %s + +! CHECK-NOT: flang1 +! CHECK: "{{.*}}clang{{.*}}" "-cc1" diff --git a/clang/test/Driver/flang/multiple-inputs-mixed.f90 b/clang/test/Driver/flang/multiple-inputs-mixed.f90 index 98d8cab00bdf..50e92aa96c85 100644 --- a/clang/test/Driver/flang/multiple-inputs-mixed.f90 +++ b/clang/test/Driver/flang/multiple-inputs-mixed.f90 @@ -1,5 +1,7 @@ ! Check that flang can handle mixed C and fortran inputs. +! UNSUPPORTED: classic_flang + ! RUN: %clang --driver-mode=flang -### -fsyntax-only %S/Inputs/one.f90 %S/Inputs/other.c 2>&1 | FileCheck --check-prefixes=CHECK-SYNTAX-ONLY %s ! CHECK-SYNTAX-ONLY-LABEL: "{{[^"]*}}flang{{[^"/]*}}" "-fc1" ! CHECK-SYNTAX-ONLY: "{{[^"]*}}/Inputs/one.f90" diff --git a/clang/test/Driver/flang/multiple-inputs.f90 b/clang/test/Driver/flang/multiple-inputs.f90 index 3c0f22e5d3e5..f88c8f37f0a4 100644 --- a/clang/test/Driver/flang/multiple-inputs.f90 +++ b/clang/test/Driver/flang/multiple-inputs.f90 @@ -1,5 +1,7 @@ ! Check that flang driver can handle multiple inputs at once. +! UNSUPPORTED: classic_flang + ! RUN: %clang --driver-mode=flang -### -fsyntax-only %S/Inputs/one.f90 %S/Inputs/two.f90 2>&1 | FileCheck --check-prefixes=CHECK-SYNTAX-ONLY %s ! CHECK-SYNTAX-ONLY-LABEL: "{{[^"]*}}flang{{[^"/]*}}" "-fc1" ! CHECK-SYNTAX-ONLY: "{{[^"]*}}/Inputs/one.f90" diff --git a/clang/test/Driver/flang/reassoc.f90 b/clang/test/Driver/flang/reassoc.f90 new file mode 100644 index 000000000000..fe42087f7070 --- /dev/null +++ b/clang/test/Driver/flang/reassoc.f90 @@ -0,0 +1,59 @@ +! REQUIRES: classic_flang + +! Tests for flags which generate nsw, reassoc attributes + +! RUN: %flang -Kieee %s -### 2>&1 | FileCheck --check-prefixes=IEEE,NO_FAST,NO_RELAXED,NO_REASSOC,NO_NSZ %s +! RUN: %flang -Knoieee %s -### 2>&1 | FileCheck --check-prefixes=NO_IEEE,NO_FAST,NO_RELAXED,NO_REASSOC,NO_NSZ %s +! RUN: %flang -ffast-math %s -### 2>&1 | FileCheck --check-prefixes=NO_IEEE,FAST,NO_RELAXED,NO_REASSOC,NO_NSZ %s +! RUN: %flang -fno-fast-math %s -### 2>&1 | FileCheck --check-prefixes=NO_FAST,NO_RELAXED,NO_REASSOC,NO_NSZ %s +! RUN: %flang -frelaxed-math %s -### 2>&1 | FileCheck --check-prefixes=NO_IEEE,NO_FAST,RELAXED,NO_REASSOC,NO_NSZ %s +! RUN: %flang -fassociative-math %s -### 2>&1 | FileCheck --check-prefixes=NO_IEEE,NO_FAST,NO_RELAXED,REASSOC_NSZ %s +! RUN: %flang -fno-associative-math %s -### 2>&1 | FileCheck --check-prefixes=NO_FAST,NO_RELAXED,NO_REASSOC,NO_NSZ %s +! RUN: %flang -fsigned-zeros %s -### 2>&1 | FileCheck --check-prefixes=NO_FAST,NO_RELAXED,NO_REASSOC,NO_NSZ %s +! RUN: %flang -fno-signed-zeros %s -### 2>&1 | FileCheck --check-prefixes=NO_IEEE,NO_FAST,NO_RELAXED,NO_REASSOC,NSZ %s + +! RUN: %flang -fno-associative-math -fno-signed-zeros %s -### 2>&1 | FileCheck --check-prefixes=NO_IEEE,NO_FAST,NO_RELAXED,NO_REASSOC,NSZ %s +! RUN: %flang -fno-associative-math -fsigned-zeros %s -### 2>&1 | FileCheck --check-prefixes=NO_FAST,NO_RELAXED,NO_REASSOC,NO_NSZ %s +! RUN: %flang -fassociative-math -fno-signed-zeros %s -### 2>&1 | FileCheck --check-prefixes=NO_IEEE,NO_FAST,NO_RELAXED,REASSOC_NSZ %s +! RUN: %flang -fassociative-math -fsigned-zeros %s -### 2>&1 | FileCheck --check-prefixes=NO_IEEE,NO_FAST,NO_RELAXED,NO_REASSOC,NO_NSZ %s + +! RUN: %flang -Kieee -fassociative-math %s -### 2>&1 | FileCheck --check-prefixes=NO_IEEE,NO_FAST,NO_RELAXED,REASSOC_NSZ %s +! RUN: %flang -Kieee -fno-associative-math %s -### 2>&1 | FileCheck --check-prefixes=IEEE,NO_FAST,NO_RELAXED,NO_REASSOC,NO_NSZ %s +! RUN: %flang -Kieee -fsigned-zeros %s -### 2>&1 | FileCheck --check-prefixes=IEEE,NO_FAST,NO_RELAXED,NO_REASSOC,NO_NSZ %s +! RUN: %flang -Kieee -fno-signed-zeros %s -### 2>&1 | FileCheck --check-prefixes=NO_IEEE,NO_FAST,NO_RELAXED,NO_REASSOC,NSZ %s +! RUN: %flang -ffast-math -fassociative-math %s -### 2>&1 | FileCheck --check-prefixes=NO_IEEE,NO_RELAXED,REASSOC_NSZ %s +! RUN: %flang -ffast-math -fno-associative-math %s -### 2>&1 | FileCheck --check-prefixes=NO_IEEE,FAST,NO_RELAXED,NO_REASSOC,NO_NSZ %s +! RUN: %flang -ffast-math -fsigned-zeros %s -### 2>&1 | FileCheck --check-prefixes=NO_IEEE,FAST,NO_RELAXED,NO_REASSOC,NO_NSZ %s +! RUN: %flang -ffast-math -fno-signed-zeros %s -### 2>&1 | FileCheck --check-prefixes=NO_IEEE,NO_RELAXED,NO_REASSOC,NSZ %s +! RUN: %flang -frelaxed-math -fassociative-math %s -### 2>&1 | FileCheck --check-prefixes=NO_IEEE,NO_FAST,REASSOC_NSZ %s +! RUN: %flang -frelaxed-math -fno-associative-math %s -### 2>&1 | FileCheck --check-prefixes=NO_IEEE,NO_FAST,RELAXED,NO_REASSOC,NO_NSZ %s +! RUN: %flang -frelaxed-math -fsigned-zeros %s -### 2>&1 | FileCheck --check-prefixes=NO_IEEE,NO_FAST,RELAXED,NO_REASSOC,NO_NSZ %s +! RUN: %flang -frelaxed-math -fno-signed-zeros %s -### 2>&1 | FileCheck --check-prefixes=NO_IEEE,NO_FAST,NO_REASSOC,NSZ %s + +! RUN: %flang -fassociative-math -Kieee %s -### 2>&1 | FileCheck --check-prefixes=IEEE,NO_FAST,NO_RELAXED,NO_REASSOC,NO_NSZ %s +! RUN: %flang -fno-associative-math -Kieee %s -### 2>&1 | FileCheck --check-prefixes=IEEE,NO_FAST,NO_RELAXED,NO_REASSOC,NO_NSZ %s +! RUN: %flang -fsigned-zeros -Kieee %s -### 2>&1 | FileCheck --check-prefixes=IEEE,NO_FAST,NO_RELAXED,NO_REASSOC,NO_NSZ %s +! RUN: %flang -fno-signed-zeros -Kieee %s -### 2>&1 | FileCheck --check-prefixes=IEEE,NO_FAST,NO_RELAXED,NO_REASSOC,NO_NSZ %s +! RUN: %flang -fassociative-math -ffast-math %s -### 2>&1 | FileCheck --check-prefixes=NO_IEEE,NO_RELAXED,REASSOC_NSZ %s +! RUN: %flang -fno-associative-math -ffast-math %s -### 2>&1 | FileCheck --check-prefixes=NO_IEEE,FAST,NO_RELAXED,NO_REASSOC,NO_NSZ %s +! RUN: %flang -fsigned-zeros -ffast-math %s -### 2>&1 | FileCheck --check-prefixes=NO_IEEE,FAST,NO_RELAXED,NO_REASSOC,NO_NSZ %s +! RUN: %flang -fno-signed-zeros -ffast-math %s -### 2>&1 | FileCheck --check-prefixes=NO_IEEE,NO_RELAXED,NO_REASSOC,NSZ %s +! RUN: %flang -fassociative-math -frelaxed-math %s -### 2>&1 | FileCheck --check-prefixes=NO_IEEE,NO_FAST,REASSOC_NSZ %s +! RUN: %flang -fno-associative-math -frelaxed-math %s -### 2>&1 | FileCheck --check-prefixes=NO_IEEE,NO_FAST,RELAXED,NO_REASSOC,NO_NSZ %s +! RUN: %flang -fsigned-zeros -frelaxed-math %s -### 2>&1 | FileCheck --check-prefixes=NO_IEEE,NO_FAST,RELAXED,NO_REASSOC,NO_NSZ %s +! RUN: %flang -fno-signed-zeros -frelaxed-math %s -### 2>&1 | FileCheck --check-prefixes=NO_IEEE,NO_FAST,NO_REASSOC,NSZ %s + +! IEEE: {{.*}}flang2{{.*}} "-ieee" "1" +! NO_IEEE-NOT: {{.*}}flang2{{.*}} "-ieee" "1" + +! FAST: {{.*}}flang2{{.*}} "-x" "216" "1" +! NO_FAST-NOT: {{.*}}flang2{{.*}} "-x" "216" "1" + +! RELAXED: {{.*}}flang2{{.*}} "-x" "15" "0x400" +! NO_RELAXED-NOT: {{.*}}flang2{{.*}} "-x" "15" "0x400" + +! REASSOC_NSZ: {{.*}}flang2{{.*}} "-x" "216" "0x8" "-x" "216" "0x10" +! NO_REASSOC-NOT: {{.*}}flang2{{.*}} "-x" "216" "0x10" + +! NSZ: {{.*}}flang2{{.*}} "-x" "216" "0x8" +! NO_NSZ-NOT: {{.*}}flang2{{.*}} "-x" "216" "0x8" diff --git a/clang/test/Driver/fortran-phases.f90 b/clang/test/Driver/fortran-phases.f90 new file mode 100644 index 000000000000..57d5f2c92b78 --- /dev/null +++ b/clang/test/Driver/fortran-phases.f90 @@ -0,0 +1,119 @@ +! Test to see that the correct phases are run for the commandline input + +! REQUIRES: classic_flang + +! RUN: %flang -ccc-print-phases 2>&1 %s | FileCheck %s --check-prefix=LINK-NOPP +! RUN: %flang -ccc-print-phases -c 2>&1 %s | FileCheck %s --check-prefix=CONLY-NOPP +! RUN: %flang -ccc-print-phases -S 2>&1 %s | FileCheck %s --check-prefix=AONLY-NOPP +! RUN: %flang -ccc-print-phases -c -emit-llvm 2>&1 %s | FileCheck %s --check-prefix=LLONLY-NOPP +! RUN: %flang -ccc-print-phases -S -emit-llvm 2>&1 %s | FileCheck %s --check-prefix=LLONLY-NOPP +! RUN: %flang -ccc-print-phases -emit-flang-llvm 2>&1 %s | FileCheck %s --check-prefix=FLLONLY-NOPP +! RUN: %flang -ccc-print-phases -fsyntax-only 2>&1 %s | FileCheck %s --check-prefix=SONLY-NOPP +! RUN: %flang -ccc-print-phases -E 2>&1 %s | FileCheck %s --check-prefix=PPONLY-NOPP + +! RUN: %flang -ccc-print-phases 2>&1 -x f95-cpp-input %s | FileCheck %s --check-prefix=LINK +! RUN: %flang -ccc-print-phases 2>&1 -x f95-cpp-input %s | FileCheck %s --check-prefix=LINK +! RUN: %flang -ccc-print-phases -c 2>&1 -x f95-cpp-input %s | FileCheck %s --check-prefix=CONLY +! RUN: %flang -ccc-print-phases -S 2>&1 -x f95-cpp-input %s | FileCheck %s --check-prefix=AONLY +! RUN: %flang -ccc-print-phases -c -emit-llvm 2>&1 -x f95-cpp-input %s | FileCheck %s --check-prefix=LLONLY +! RUN: %flang -ccc-print-phases -S -emit-llvm 2>&1 -x f95-cpp-input %s | FileCheck %s --check-prefix=LLONLY +! RUN: %flang -ccc-print-phases -emit-flang-llvm 2>&1 -x f95-cpp-input %s | FileCheck %s --check-prefix=FLLONLY +! RUN: %flang -ccc-print-phases -fsyntax-only 2>&1 -x f95-cpp-input %s | FileCheck %s --check-prefix=SONLY +! RUN: %flang -ccc-print-phases -E 2>&1 -x f95-cpp-input %s | FileCheck %s --check-prefix=PPONLY + +! LINK-NOPP: 0: input, {{.*}}, f95 +! LINK-NOPP: 1: compiler, {0}, ir +! LINK-NOPP: 2: backend, {1}, assembler +! LINK-NOPP: 3: assembler, {2}, object +! LINK-NOPP: 4: linker, {3}, image + +! CONLY-NOPP: 0: input, {{.*}}, f95 +! CONLY-NOPP: 1: compiler, {0}, ir +! CONLY-NOPP: 2: backend, {1}, assembler +! CONLY-NOPP: 3: assembler, {2}, object +! CONLY-NOPP-NOT: {{.*}}: linker, {{{.*}}}, image + +! AONLY-NOPP: 0: input, {{.*}}, f95 +! AONLY-NOPP: 1: compiler, {0}, ir +! AONLY-NOPP: 2: backend, {1}, assembler +! AONLY-NOPP-NOT: {{.*}}: assembler, {{{.*}}}, object +! AONLY-NOPP-NOT: {{.*}}: linker, {{{.*}}}, image + +! LLONLY-NOPP: 0: input, {{.*}}, f95 +! LLONLY-NOPP: 1: compiler, {0}, ir +! LLONLY-NOPP-NOT: {{.*}}: backend, {{{.*}}}, assembler +! LLONLY-NOPP-NOT: {{.*}}: assembler, {{{.*}}}, object +! LLONLY-NOPP-NOT: {{.*}}: linker, {{{.*}}}, image + +! FLLONLY-NOPP: 0: input, {{.*}}, f95 +! FLLONLY-NOPP: 1: compiler, {0}, ir +! FLLONLY-NOPP-NOT: {{.*}}: backend, {{{.*}}}, assembler +! FLLONLY-NOPP-NOT: {{.*}}: assembler, {{{.*}}}, object +! FLLONLY-NOPP-NOT: {{.*}}: linker, {{{.*}}}, image + +! SONLY-NOPP: 0: input, {{.*}}, f95 +! SONLY-NOPP-NOT: {{.*}}: compiler, {{{.*}}}, ir +! SONLY-NOPP-NOT: {{.*}}: backend, {{{.*}}}, assembler +! SONLY-NOPP-NOT: {{.*}}: assembler, {{{.*}}}, object +! SONLY-NOPP-NOT: {{.*}}: linker, {{{.*}}}, image + +! flang always preprocesses with -E regardless of file extension +! PPONLY-NOPP: 0: input, {{.*}}, f95 +! PPONLY-NOPP: 1: preprocessor, {0}, f95 +! PPONLY-NOPP-NOT: {{.*}}: compiler, {{{.*}}}, ir +! PPONLY-NOPP-NOT: {{.*}}: backend, {{{.*}}}, assembler +! PPONLY-NOPP-NOT: {{.*}}: assembler, {{{.*}}}, object +! PPONLY-NOPP-NOT: {{.*}}: linker, {{{.*}}}, image + +! LINK: 0: input, {{.*}}, f95-cpp-input +! LINK: 1: preprocessor, {0}, f95 +! LINK: 2: compiler, {1}, ir +! LINK: 3: backend, {2}, assembler +! LINK: 4: assembler, {3}, object +! LINK: 5: linker, {4}, image + +! CONLY: 0: input, {{.*}}, f95-cpp-input +! CONLY: 1: preprocessor, {0}, f95 +! CONLY: 2: compiler, {1}, ir +! CONLY: 3: backend, {2}, assembler +! CONLY: 4: assembler, {3}, object +! CONLY-NOT: {{.*}}: linker, {{{.*}}}, image + +! AONLY: 0: input, {{.*}}, f95-cpp-input +! AONLY: 1: preprocessor, {0}, f95 +! AONLY: 2: compiler, {1}, ir +! AONLY: 3: backend, {2}, assembler +! AONLY-NOT: {{.*}}: assembler, {{{.*}}}, object +! AONLY-NOT: {{.*}}: linker, {{{.*}}}, image + +! LLONLY: 0: input, {{.*}}, f95-cpp-input +! LLONLY: 1: preprocessor, {0}, f95 +! LLONLY: 2: compiler, {1}, ir +! LLONLY-NOT: {{.*}}: backend, {{{.*}}}, assembler +! LLONLY-NOT: {{.*}}: assembler, {{{.*}}}, object +! LLONLY-NOT: {{.*}}: linker, {{{.*}}}, image + +! FLLONLY: 0: input, {{.*}}, f95-cpp-input +! FLLONLY: 1: preprocessor, {0}, f95 +! FLLONLY: 2: compiler, {1}, ir +! FLLONLY-NOT: {{.*}}: backend, {{{.*}}}, assembler +! FLLONLY-NOT: {{.*}}: assembler, {{{.*}}}, object +! FLLONLY-NOT: {{.*}}: linker, {{{.*}}}, image + +! SONLY: 0: input, {{.*}}, f95-cpp-input +! SONLY: 1: preprocessor, {0}, f95 +! SONLY-NOT: {{.*}}: compiler, {{{.*}}}, ir +! SONLY-NOT: {{.*}}: backend, {{{.*}}}, assembler +! SONLY-NOT: {{.*}}: assembler, {{{.*}}}, object +! SONLY-NOT: {{.*}}: linker, {{{.*}}}, image + +! PPONLY: 0: input, {{.*}}, f95-cpp-input +! PPONLY: 1: preprocessor, {0}, f95 +! PPONLY-NOT: {{.*}}: compiler, {{{.*}}}, ir +! PPONLY-NOT: {{.*}}: backend, {{{.*}}}, assembler +! PPONLY-NOT: {{.*}}: assembler, {{{.*}}}, object +! PPONLY-NOT: {{.*}}: linker, {{{.*}}}, image + +program hello + write(*, *) "Hello" +end program hello diff --git a/clang/test/Driver/fortran-preprocessor.f90 b/clang/test/Driver/fortran-preprocessor.f90 new file mode 100644 index 000000000000..d9e5620145ac --- /dev/null +++ b/clang/test/Driver/fortran-preprocessor.f90 @@ -0,0 +1,48 @@ +! REQUIRES: classic_flang + +! -cpp should preprocess as it goes, regardless of input file extension +! RUN: %flang -cpp -c -DHELLO="hello all" -### %s 2>&1 | FileCheck %s --check-prefixes=ALL,CPP,PP +! RUN: %flang -cpp -c -DHELLO="hello all" -### -x f95-cpp-input %s 2>&1 | FileCheck %s --check-prefixes=ALL,CPP,PP +! -E should preprocess then stop, regardless of input file extension +! RUN: %flang -E -DHELLO="hello all" -### %s 2>&1 | FileCheck %s --check-prefixes=ALL,E,PPONLY +! RUN: %flang -E -DHELLO="hello all" -### -x f95-cpp-input %s 2>&1 | FileCheck %s --check-prefixes=ALL,E,PPONLY +! -cpp and -E are redundant +! RUN: %flang -E -cpp -DHELLO="hello all" -### %s 2>&1 | FileCheck %s --check-prefixes=ALL,E,PPONLY + +! Don't link when given linker input +! RUN: %flang -E -cpp -Wl,-rpath=blah -### %s 2>&1 | FileCheck %s --check-prefixes=ALL,E,PPONLY + +! Explicitly test this nonsence case causing a bug with LLVM 13/14 +! RUN: %flang -E -traditional-cpp -DHELLO="hello all" -x f95-cpp-input -### %s 2>&1 | FileCheck %s --check-prefixes=ALL,E,PPONLY + +! Test -save-temps does not break things (same codepath as -traditional-cpp bug above) +! RUN: %flang -E -DHELLO="hello all" -save-temps -### %s 2>&1 | FileCheck %s --check-prefixes=ALL,E,PPONLY +! RUN: %flang -E -DHELLO="hello all" -save-temps -### -x f95-cpp-input %s 2>&1 | FileCheck %s --check-prefixes=ALL,E,PPONLY +! RUN: %flang -cpp -c -DHELLO="hello all" -save-temps -### %s 2>&1 | FileCheck %s --check-prefixes=ALL,CPP,PP +! RUN: %flang -cpp -c -DHELLO="hello all" -save-temps -### -x f95-cpp-input %s 2>&1 | FileCheck %s --check-prefixes=ALL,CPP,PP + +! Test for the correct cmdline flags +! Consume up to flang1 line +! ALL-LABEL: "{{.*}}flang1" +! CPP-NOT: "-es" +! CPP: "-preprocess" +! CPP-NOT: "-es" + +! E-DAG: "-es" +! E-DAG: "-preprocess" + +! CPP should continue to build object +! PP: "{{.*}}flang2" +! PPONLY-NOT: "{{.*}}flang2" + +! flang1 and flang2 should only be called at most once! +! ALL-NOT: "{{.*}}flang1" +! ALL-NOT: "{{.*}}flang2" + +! These commands should never call a linker! +! ALL-NOT: "{{.*}}ld" + +program hello + write(*, *) HELLO +end program hello + diff --git a/clang/test/Driver/fortran.f95 b/clang/test/Driver/fortran.f95 index 275b1886b2fd..260616d10f15 100644 --- a/clang/test/Driver/fortran.f95 +++ b/clang/test/Driver/fortran.f95 @@ -1,6 +1,8 @@ ! Check that the clang driver can invoke gcc to compile Fortran when in ! --driver-mode=clang. This is legacy behaviour - see also --driver-mode=flang. +! UNSUPPORTED: classic_flang + ! RUN: %clang --target=x86_64-unknown-linux-gnu -integrated-as -c %s -### 2>&1 \ ! RUN: | FileCheck --check-prefix=CHECK-OBJECT %s ! CHECK-OBJECT: gcc diff --git a/clang/test/Driver/gfortran.f90 b/clang/test/Driver/gfortran.f90 index c985428650ec..1276703b1f6e 100644 --- a/clang/test/Driver/gfortran.f90 +++ b/clang/test/Driver/gfortran.f90 @@ -1,4 +1,5 @@ ! XFAIL: * +! UNSUPPORTED: classic_flang ! Test that Clang can forward all of the flags which are documented as ! being supported by gfortran to GCC when falling back to GCC for ! a fortran input file. diff --git a/clang/test/Driver/lit.local.cfg b/clang/test/Driver/lit.local.cfg index 6370e9f92d89..5ec1f9a8fc71 100644 --- a/clang/test/Driver/lit.local.cfg +++ b/clang/test/Driver/lit.local.cfg @@ -12,6 +12,9 @@ config.suffixes = [ ".f90", ".F90", ".f95", + '.F95', + '.f', + '.F', ".cu", ".rs", ".cl", diff --git a/clang/test/lit.cfg.py b/clang/test/lit.cfg.py index e4b39c4f7159..4a2b447fd59e 100644 --- a/clang/test/lit.cfg.py +++ b/clang/test/lit.cfg.py @@ -367,3 +367,8 @@ def calculate_arch_features(arch_string): # possibly be present in system and user configuration files, so disable # default configs for the test runs. config.environment["CLANG_NO_DEFAULT_CONFIG"] = "1" + +if config.use_classic_flang: + config.available_features.add("classic_flang") + +config.available_features.add("host-" + config.host_arch) diff --git a/clang/test/lit.site.cfg.py.in b/clang/test/lit.site.cfg.py.in index 1cbd876ac5bb..7250f2df3a61 100644 --- a/clang/test/lit.site.cfg.py.in +++ b/clang/test/lit.site.cfg.py.in @@ -44,6 +44,7 @@ config.standalone_build = @CLANG_BUILT_STANDALONE@ config.ppc_linux_default_ieeelongdouble = @PPC_LINUX_DEFAULT_IEEELONGDOUBLE@ config.have_llvm_driver = @LLVM_TOOL_LLVM_DRIVER_BUILD@ config.substitutions.append(("%llvm-version-major", "@LLVM_VERSION_MAJOR@")) +config.use_classic_flang = @LLVM_ENABLE_CLASSIC_FLANG@ import lit.llvm lit.llvm.initialize(lit_config, config) diff --git a/clang/tools/driver/CMakeLists.txt b/clang/tools/driver/CMakeLists.txt index ad336fcc45b6..2b3d719ba435 100644 --- a/clang/tools/driver/CMakeLists.txt +++ b/clang/tools/driver/CMakeLists.txt @@ -77,7 +77,7 @@ endif() add_dependencies(clang clang-resource-headers) if(NOT CLANG_LINKS_TO_CREATE) - set(CLANG_LINKS_TO_CREATE clang++ clang-cl clang-cpp) + set(CLANG_LINKS_TO_CREATE clang++ clang-cl clang-cpp flang) endif() if (CLANG_ENABLE_HLSL) diff --git a/clang/tools/driver/cc1as_main.cpp b/clang/tools/driver/cc1as_main.cpp index 7fe97cc6e6ac..865af5070494 100644 --- a/clang/tools/driver/cc1as_main.cpp +++ b/clang/tools/driver/cc1as_main.cpp @@ -679,7 +679,7 @@ int cc1as_main(ArrayRef Argv, const char *Argv0, void *MainAddr) { llvm::outs(), "clang -cc1as [options] file...", "Clang Integrated Assembler", /*ShowHidden=*/false, /*ShowAllAliases=*/false, - llvm::opt::Visibility(driver::options::CC1AsOption)); + llvm::opt::Visibility(clang::driver::options::CC1AsOption)); return 0; } diff --git a/cmake/Modules/GetClangResourceDir.cmake b/cmake/Modules/GetClangResourceDir.cmake index def5bd60424e..026f3e9a1e2c 100644 --- a/cmake/Modules/GetClangResourceDir.cmake +++ b/cmake/Modules/GetClangResourceDir.cmake @@ -13,7 +13,11 @@ function(get_clang_resource_dir out_var) set(ret_dir bin/${CLANG_RESOURCE_DIR}) else() if (NOT CLANG_VERSION_MAJOR) - string(REGEX MATCH "^[0-9]+" CLANG_VERSION_MAJOR ${PACKAGE_VERSION}) + if (NOT PACKAGE_VERSION) + string(REGEX MATCH "^[0-9]+" CLANG_VERSION_MAJOR ${LLVM_VERSION_MAJOR}) + else() + string(REGEX MATCH "^[0-9]+" CLANG_VERSION_MAJOR ${PACKAGE_VERSION}) + endif() endif() set(ret_dir lib${LLVM_LIBDIR_SUFFIX}/clang/${CLANG_VERSION_MAJOR}) endif() diff --git a/flang/include/flang/Frontend/FrontendOptions.h b/flang/include/flang/Frontend/FrontendOptions.h index a4cb021e309d..82ca99672ec6 100644 --- a/flang/include/flang/Frontend/FrontendOptions.h +++ b/flang/include/flang/Frontend/FrontendOptions.h @@ -236,8 +236,7 @@ class FrontendInputFile { struct FrontendOptions { FrontendOptions() : showHelp(false), showVersion(false), instrumentedParse(false), - showColors(false), printSupportedCPUs(false), - needProvenanceRangeToCharBlockMappings(false) {} + showColors(false), needProvenanceRangeToCharBlockMappings(false) {} /// Show the -help text. unsigned showHelp : 1; @@ -251,9 +250,6 @@ struct FrontendOptions { /// Enable color diagnostics. unsigned showColors : 1; - /// Print the supported cpus for the current target - unsigned printSupportedCPUs : 1; - /// Enable Provenance to character-stream mapping. Allows e.g. IDEs to find /// symbols based on source-code location. This is not needed in regular /// compilation. diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp index 68b5950d3a51..7d03ad676e61 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -638,8 +638,6 @@ static bool parseFrontendArgs(FrontendOptions &opts, llvm::opt::ArgList &args, opts.outputFile = args.getLastArgValue(clang::driver::options::OPT_o); opts.showHelp = args.hasArg(clang::driver::options::OPT_help); opts.showVersion = args.hasArg(clang::driver::options::OPT_version); - opts.printSupportedCPUs = - args.hasArg(clang::driver::options::OPT_print_supported_cpus); // Get the input kind (from the value passed via `-x`) InputKind dashX(Language::Unknown); diff --git a/flang/test/Driver/print-supported-cpus.f90 b/flang/test/Driver/print-supported-cpus.f90 deleted file mode 100644 index 60b725d4e1dc..000000000000 --- a/flang/test/Driver/print-supported-cpus.f90 +++ /dev/null @@ -1,46 +0,0 @@ -! Test --print-supported-cpus and associated aliases, -mcpu=help and -! -mtune=help - -! RUN: %if x86-registered-target %{ \ -! RUN: %flang --target=x86_64-unknown-linux-gnu --print-supported-cpus 2>&1 \ -! RUN: | FileCheck %s --check-prefixes=X86,CHECK \ -! RUN: %} -! RUN: %if x86-registered-target %{ \ -! RUN: %flang --target=x86_64-unknown-linux-gnu -mcpu=help 2>&1 \ -! RUN: | FileCheck %s --check-prefixes=X86,CHECK \ -! RUN: %} -! RUN: %if x86-registered-target %{ \ -! RUN: %flang --target=x86_64-unknown-linux-gnu -mtune=help 2>&1 \ -! RUN: | FileCheck %s --check-prefixes=X86,CHECK \ -! RUN: %} - -! RUN: %if aarch64-registered-target %{ \ -! RUN: %flang --target=aarch64-unknown-linux-gnu --print-supported-cpus 2>&1 \ -! RUN: | FileCheck %s --check-prefixes=AARCH64,CHECK \ -! RUN: %} -! RUN: %if aarch64-registered-target %{ \ -! RUN: %flang --target=aarch64-unknown-linux-gnu -mcpu=help 2>&1 \ -! RUN: | FileCheck %s --check-prefixes=AARCH64,CHECK \ -! RUN: %} -! RUN: %if aarch64-registered-target %{ \ -! RUN: %flang --target=aarch64-unknown-linux-gnu -mtune=help 2>&1 \ -! RUN: | FileCheck %s --check-prefixes=AARCH64,CHECK \ -! RUN: %} - -! CHECK-NOT: warning: argument unused during compilation - -! X86: Target: x86_64-unknown-linux-gnu -! X86: corei7 - -! AARCH64: Target: aarch64-unknown-linux-gnu -! AARCH64: cortex-a73 -! AARCH64: cortex-a75 - -! The footer displayed contains a reference to clang. This should be changed to -! flang, but that requires a change in llvm/MCSubtargetInfo. When that happens, -! this test will need to be updated and this comment can be removed. - -! CHECK: Use -mcpu or -mtune to specify the target's processor. -! CHECK: For example, clang --target=aarch64-unknown-linux-gnu - - end program diff --git a/flang/tools/flang-driver/fc1_main.cpp b/flang/tools/flang-driver/fc1_main.cpp index 561a0dd5524e..b5b062aaac26 100644 --- a/flang/tools/flang-driver/fc1_main.cpp +++ b/flang/tools/flang-driver/fc1_main.cpp @@ -21,35 +21,15 @@ #include "flang/Frontend/TextDiagnosticBuffer.h" #include "flang/FrontendTool/Utils.h" #include "clang/Driver/DriverDiagnostic.h" -#include "llvm/MC/TargetRegistry.h" #include "llvm/Option/Arg.h" #include "llvm/Option/ArgList.h" #include "llvm/Option/OptTable.h" #include "llvm/Support/TargetSelect.h" -#include "llvm/Support/raw_ostream.h" #include using namespace Fortran::frontend; -/// Print supported cpus of the given target. -static int printSupportedCPUs(llvm::StringRef triple) { - std::string error; - const llvm::Target *target = - llvm::TargetRegistry::lookupTarget(triple, error); - if (!target) { - llvm::errs() << error; - return 1; - } - - // the target machine will handle the mcpu printing - llvm::TargetOptions targetOpts; - std::unique_ptr targetMachine( - target->createTargetMachine(triple, "", "+cpuhelp", targetOpts, - std::nullopt)); - return 0; -} - int fc1_main(llvm::ArrayRef argv, const char *argv0) { // Create CompilerInstance std::unique_ptr flang(new CompilerInstance()); @@ -78,10 +58,6 @@ int fc1_main(llvm::ArrayRef argv, const char *argv0) { llvm::InitializeAllTargetMCs(); llvm::InitializeAllAsmPrinters(); - // --print-supported-cpus takes priority over the actual compilation. - if (flang->getFrontendOpts().printSupportedCPUs) - return printSupportedCPUs(flang->getInvocation().getTargetOpts().triple); - diagsBuffer->flushDiagnostics(flang->getDiagnostics()); if (!success) diff --git a/llvm/cmake/modules/HandleLLVMOptions.cmake b/llvm/cmake/modules/HandleLLVMOptions.cmake index 5db06ccdadbe..8b30e7ce6032 100644 --- a/llvm/cmake/modules/HandleLLVMOptions.cmake +++ b/llvm/cmake/modules/HandleLLVMOptions.cmake @@ -144,6 +144,14 @@ if( LLVM_ENABLE_ASSERTIONS ) endif() endif() +option(LLVM_ENABLE_CLASSIC_FLANG "Build support for classic Flang instead of the new built-in Flang" OFF) +if(LLVM_ENABLE_CLASSIC_FLANG) + set(LLVM_ENABLE_CLASSIC_FLANG 1) + add_definitions( -DENABLE_CLASSIC_FLANG ) +else() + set(LLVM_ENABLE_CLASSIC_FLANG 0) +endif() + # If we are targeting a GPU architecture in a runtimes build we want to ignore # all the standard flag handling. if(LLVM_RUNTIMES_GPU_BUILD) diff --git a/llvm/include/llvm-c/DebugInfo.h b/llvm/include/llvm-c/DebugInfo.h index ac7ee5a7cc9a..486895474ec8 100644 --- a/llvm/include/llvm-c/DebugInfo.h +++ b/llvm/include/llvm-c/DebugInfo.h @@ -1165,7 +1165,8 @@ LLVMMetadataRef LLVMDIBuilderCreateGlobalVariableExpression( LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, const char *Linkage, size_t LinkLen, LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Ty, LLVMBool LocalToUnit, - LLVMMetadataRef Expr, LLVMMetadataRef Decl, uint32_t AlignInBits); + LLVMMetadataRef Expr, LLVMMetadataRef Decl, LLVMDIFlags Flags, + uint32_t AlignInBits); /** @@ -1263,7 +1264,7 @@ LLVMMetadataRef LLVMDIBuilderCreateTempGlobalVariableFwdDecl( LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, const char *Linkage, size_t LnkLen, LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Ty, LLVMBool LocalToUnit, - LLVMMetadataRef Decl, uint32_t AlignInBits); + LLVMMetadataRef Decl, LLVMDIFlags Flags, uint32_t AlignInBits); /** * Only use in "new debug format" (LLVMIsNewDbgInfoFormat() is true). diff --git a/llvm/include/llvm/Analysis/TargetLibraryInfo.h b/llvm/include/llvm/Analysis/TargetLibraryInfo.h index f51d2bb9d50a..02c37cf401f4 100644 --- a/llvm/include/llvm/Analysis/TargetLibraryInfo.h +++ b/llvm/include/llvm/Analysis/TargetLibraryInfo.h @@ -112,6 +112,8 @@ class TargetLibraryInfoImpl { bool isValidProtoForLibFunc(const FunctionType &FTy, LibFunc F, const Module &M) const; + Triple T; + public: /// List of known vector-functions libraries. /// @@ -126,6 +128,10 @@ class TargetLibraryInfoImpl { DarwinLibSystemM, // Use Darwin's libsystem_m. LIBMVEC_X86, // GLIBC Vector Math library. MASSV, // IBM MASS vector library. +#ifdef ENABLE_CLASSIC_FLANG + PGMATH, // PGI math library. + PGMATH_AVX512, // PGI math library (AVX512 subset). +#endif SVML, // Intel short vector math library. SLEEFGNUABI, // SLEEF - SIMD Library for Evaluating Elementary Functions. ArmPL, // Arm Performance Libraries. diff --git a/llvm/include/llvm/Analysis/VecFuncs.def b/llvm/include/llvm/Analysis/VecFuncs.def index 251331b9f860..2cbd41162ff4 100644 --- a/llvm/include/llvm/Analysis/VecFuncs.def +++ b/llvm/include/llvm/Analysis/VecFuncs.def @@ -1618,6 +1618,615 @@ TLI_DEFINE_VECFUNC("sincos", "amd_vrd8_sincos", FIXED(8), NOMASK, "_ZGV_LLVM_N8v TLI_DEFINE_VECFUNC("sincosf", "amd_vrs4_sincosf", FIXED(4), NOMASK, "_ZGV_LLVM_N4vl4l4") TLI_DEFINE_VECFUNC("sincosf", "amd_vrs8_sincosf", FIXED(8), NOMASK, "_ZGV_LLVM_N8vl4l4") TLI_DEFINE_VECFUNC("sincosf", "amd_vrs16_sincosf", FIXED(16), NOMASK, "_ZGV_LLVM_N16vl4l4") +#elif defined(TLI_DEFINE_PGMATH_AARCH64_VECFUNCS) +// Classic flang libpgmath library's Vector Functions for AArch64 + +TLI_DEFINE_VECFUNC("__fd_sin_1", "__fd_sin_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__fs_sin_1", "__fs_sin_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__pd_sin_1", "__pd_sin_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__ps_sin_1", "__ps_sin_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__rd_sin_1", "__rd_sin_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__rs_sin_1", "__rs_sin_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__fd_cos_1", "__fd_cos_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__fs_cos_1", "__fs_cos_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__pd_cos_1", "__pd_cos_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__ps_cos_1", "__ps_cos_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__rd_cos_1", "__rd_cos_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__rs_cos_1", "__rs_cos_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__fd_sincos_1", "__fd_sincos_2", FIXED(2), "_ZGV_LLVM_N2vl8l8") +TLI_DEFINE_VECFUNC("__fs_sincos_1", "__fs_sincos_4", FIXED(4), "_ZGV_LLVM_N4vl4l4") + +TLI_DEFINE_VECFUNC("__pd_sincos_1", "__pd_sincos_2", FIXED(2), "_ZGV_LLVM_N2vl8l8") +TLI_DEFINE_VECFUNC("__ps_sincos_1", "__ps_sincos_4", FIXED(4), "_ZGV_LLVM_N4vl4l4") + +TLI_DEFINE_VECFUNC("__rd_sincos_1", "__rd_sincos_2", FIXED(2), "_ZGV_LLVM_N2vl8l8") +TLI_DEFINE_VECFUNC("__rs_sincos_1", "__rs_sincos_4", FIXED(4), "_ZGV_LLVM_N4vl4l4") + +TLI_DEFINE_VECFUNC("__fd_tan_1", "__fd_tan_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__fs_tan_1", "__fs_tan_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__pd_tan_1", "__pd_tan_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__ps_tan_1", "__ps_tan_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__rd_tan_1", "__rd_tan_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__rs_tan_1", "__rs_tan_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__fd_sinh_1", "__fd_sinh_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__fs_sinh_1", "__fs_sinh_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__pd_sinh_1", "__pd_sinh_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__ps_sinh_1", "__ps_sinh_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__rd_sinh_1", "__rd_sinh_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__rs_sinh_1", "__rs_sinh_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__fd_cosh_1", "__fd_cosh_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__fs_cosh_1", "__fs_cosh_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__pd_cosh_1", "__pd_cosh_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__ps_cosh_1", "__ps_cosh_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__rd_cosh_1", "__rd_cosh_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__rs_cosh_1", "__rs_cosh_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__fd_tanh_1", "__fd_tanh_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__fs_tanh_1", "__fs_tanh_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__pd_tanh_1", "__pd_tanh_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__ps_tanh_1", "__ps_tanh_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__rd_tanh_1", "__rd_tanh_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__rs_tanh_1", "__rs_tanh_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__fd_asin_1", "__fd_asin_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__fs_asin_1", "__fs_asin_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__pd_asin_1", "__pd_asin_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__ps_asin_1", "__ps_asin_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__rd_asin_1", "__rd_asin_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__rs_asin_1", "__rs_asin_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__fd_acos_1", "__fd_acos_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__fs_acos_1", "__fs_acos_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__pd_acos_1", "__pd_acos_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__ps_acos_1", "__ps_acos_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__rd_acos_1", "__rd_acos_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__rs_acos_1", "__rs_acos_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__fd_atan_1", "__fd_atan_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__fs_atan_1", "__fs_atan_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__pd_atan_1", "__pd_atan_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__ps_atan_1", "__ps_atan_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__rd_atan_1", "__rd_atan_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__rs_atan_1", "__rs_atan_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__fd_atan2_1", "__fd_atan2_2", FIXED(2), "_ZGV_LLVM_N2vv") +TLI_DEFINE_VECFUNC("__fs_atan2_1", "__fs_atan2_4", FIXED(4), "_ZGV_LLVM_N4vv") + +TLI_DEFINE_VECFUNC("__pd_atan2_1", "__pd_atan2_2", FIXED(2), "_ZGV_LLVM_N2vv") +TLI_DEFINE_VECFUNC("__ps_atan2_1", "__ps_atan2_4", FIXED(4), "_ZGV_LLVM_N4vv") + +TLI_DEFINE_VECFUNC("__rd_atan2_1", "__rd_atan2_2", FIXED(2), "_ZGV_LLVM_N2vv") +TLI_DEFINE_VECFUNC("__rs_atan2_1", "__rs_atan2_4", FIXED(4), "_ZGV_LLVM_N4vv") + +TLI_DEFINE_VECFUNC("__fd_pow_1", "__fd_pow_2", FIXED(2), "_ZGV_LLVM_N2vv") +TLI_DEFINE_VECFUNC("__fs_pow_1", "__fs_pow_4", FIXED(4), "_ZGV_LLVM_N4vv") + +TLI_DEFINE_VECFUNC("__pd_pow_1", "__pd_pow_2", FIXED(2), "_ZGV_LLVM_N2vv") +TLI_DEFINE_VECFUNC("__ps_pow_1", "__ps_pow_4", FIXED(4), "_ZGV_LLVM_N4vv") + +TLI_DEFINE_VECFUNC("__rd_pow_1", "__rd_pow_2", FIXED(2), "_ZGV_LLVM_N2vv") +TLI_DEFINE_VECFUNC("__rs_pow_1", "__rs_pow_4", FIXED(4), "_ZGV_LLVM_N4vv") + +TLI_DEFINE_VECFUNC("__fs_powi_1", "__fs_powi_4", FIXED(4), "_ZGV_LLVM_N4vv") + +TLI_DEFINE_VECFUNC("__ps_powi_1", "__ps_powi_4", FIXED(4), "_ZGV_LLVM_N4vv") + +TLI_DEFINE_VECFUNC("__rs_powi_1", "__rs_powi_4", FIXED(4), "_ZGV_LLVM_N4vv") + +TLI_DEFINE_VECFUNC("__fd_powi1_1", "__fd_powi1_2", FIXED(2), "_ZGV_LLVM_N2vv") +TLI_DEFINE_VECFUNC("__fs_powi1_1", "__fs_powi1_4", FIXED(4), "_ZGV_LLVM_N4vv") + +TLI_DEFINE_VECFUNC("__pd_powi1_1", "__pd_powi1_2", FIXED(2), "_ZGV_LLVM_N2vv") +TLI_DEFINE_VECFUNC("__ps_powi1_1", "__ps_powi1_4", FIXED(4), "_ZGV_LLVM_N4vv") + +TLI_DEFINE_VECFUNC("__rd_powi1_1", "__rd_powi1_2", FIXED(2), "_ZGV_LLVM_N2vv") +TLI_DEFINE_VECFUNC("__rs_powi1_1", "__rs_powi1_4", FIXED(4), "_ZGV_LLVM_N4vv") + +TLI_DEFINE_VECFUNC("__fd_powk_1", "__fd_powk_2", FIXED(2), "_ZGV_LLVM_N2vv") +TLI_DEFINE_VECFUNC("__fs_powk_1", "__fs_powk_4", FIXED(4), "_ZGV_LLVM_N4vv") + +TLI_DEFINE_VECFUNC("__pd_powk_1", "__pd_powk_2", FIXED(2), "_ZGV_LLVM_N2vv") +TLI_DEFINE_VECFUNC("__ps_powk_1", "__ps_powk_4", FIXED(4), "_ZGV_LLVM_N4vv") + +TLI_DEFINE_VECFUNC("__rd_powk_1", "__rd_powk_2", FIXED(2), "_ZGV_LLVM_N2vv") +TLI_DEFINE_VECFUNC("__rs_powk_1", "__rs_powk_4", FIXED(4), "_ZGV_LLVM_N4vv") + +TLI_DEFINE_VECFUNC("__fd_powk1_1", "__fd_powk1_2", FIXED(2), "_ZGV_LLVM_N2vv") +TLI_DEFINE_VECFUNC("__fs_powk1_1", "__fs_powk1_4", FIXED(4), "_ZGV_LLVM_N4vv") + +TLI_DEFINE_VECFUNC("__pd_powk1_1", "__pd_powk1_2", FIXED(2), "_ZGV_LLVM_N2vv") +TLI_DEFINE_VECFUNC("__ps_powk1_1", "__ps_powk1_4", FIXED(4), "_ZGV_LLVM_N4vv") + +TLI_DEFINE_VECFUNC("__rd_powk1_1", "__rd_powk1_2", FIXED(2), "_ZGV_LLVM_N2vv") +TLI_DEFINE_VECFUNC("__rs_powk1_1", "__rs_powk1_4", FIXED(4), "_ZGV_LLVM_N4vv") + +TLI_DEFINE_VECFUNC("__fd_log10_1", "__fd_log10_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__fs_log10_1", "__fs_log10_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__pd_log10_1", "__pd_log10_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__ps_log10_1", "__ps_log10_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__rd_log10_1", "__rd_log10_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__rs_log10_1", "__rs_log10_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__fd_log_1", "__fd_log_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__fs_log_1", "__fs_log_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__pd_log_1", "__pd_log_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__ps_log_1", "__ps_log_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__rd_log_1", "__rd_log_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__rs_log_1", "__rs_log_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__fd_exp_1", "__fd_exp_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__fs_exp_1", "__fs_exp_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__pd_exp_1", "__pd_exp_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__ps_exp_1", "__ps_exp_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__rd_exp_1", "__rd_exp_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__rs_exp_1", "__rs_exp_4", FIXED(4), "_ZGV_LLVM_N4v") + +#elif defined(TLI_DEFINE_PGMATH_X86_VECFUNCS) +// Classic flang libpgmath library's Vector Functions for X86 + +TLI_DEFINE_VECFUNC("__fd_sin_1", "__fd_sin_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__fd_sin_1", "__fd_sin_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__fs_sin_1", "__fs_sin_4", FIXED(4), "_ZGV_LLVM_N4v") +TLI_DEFINE_VECFUNC("__fs_sin_1", "__fs_sin_8", FIXED(8), "_ZGV_LLVM_N8v") + +TLI_DEFINE_VECFUNC("__pd_sin_1", "__pd_sin_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__pd_sin_1", "__pd_sin_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__ps_sin_1", "__ps_sin_4", FIXED(4), "_ZGV_LLVM_N4v") +TLI_DEFINE_VECFUNC("__ps_sin_1", "__ps_sin_8", FIXED(8), "_ZGV_LLVM_N8v") + +TLI_DEFINE_VECFUNC("__rd_sin_1", "__rd_sin_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__rd_sin_1", "__rd_sin_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__rs_sin_1", "__rs_sin_4", FIXED(4), "_ZGV_LLVM_N4v") +TLI_DEFINE_VECFUNC("__rs_sin_1", "__rs_sin_8", FIXED(8), "_ZGV_LLVM_N8v") + +TLI_DEFINE_VECFUNC("__fd_cos_1", "__fd_cos_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__fd_cos_1", "__fd_cos_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__fs_cos_1", "__fs_cos_4", FIXED(4), "_ZGV_LLVM_N4v") +TLI_DEFINE_VECFUNC("__fs_cos_1", "__fs_cos_8", FIXED(8), "_ZGV_LLVM_N8v") + +TLI_DEFINE_VECFUNC("__pd_cos_1", "__pd_cos_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__pd_cos_1", "__pd_cos_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__ps_cos_1", "__ps_cos_4", FIXED(4), "_ZGV_LLVM_N4v") +TLI_DEFINE_VECFUNC("__ps_cos_1", "__ps_cos_8", FIXED(8), "_ZGV_LLVM_N8v") + +TLI_DEFINE_VECFUNC("__rd_cos_1", "__rd_cos_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__rd_cos_1", "__rd_cos_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__rs_cos_1", "__rs_cos_4", FIXED(4), "_ZGV_LLVM_N4v") +TLI_DEFINE_VECFUNC("__rs_cos_1", "__rs_cos_8", FIXED(8), "_ZGV_LLVM_N8v") + +TLI_DEFINE_VECFUNC("__fd_tan_1", "__fd_tan_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__fd_tan_1", "__fd_tan_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__fs_tan_1", "__fs_tan_4", FIXED(4), "_ZGV_LLVM_N4v") +TLI_DEFINE_VECFUNC("__fs_tan_1", "__fs_tan_8", FIXED(8), "_ZGV_LLVM_N8v") + +TLI_DEFINE_VECFUNC("__pd_tan_1", "__pd_tan_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__pd_tan_1", "__pd_tan_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__ps_tan_1", "__ps_tan_4", FIXED(4), "_ZGV_LLVM_N4v") +TLI_DEFINE_VECFUNC("__ps_tan_1", "__ps_tan_8", FIXED(8), "_ZGV_LLVM_N8v") + +TLI_DEFINE_VECFUNC("__rd_tan_1", "__rd_tan_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__rd_tan_1", "__rd_tan_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__rs_tan_1", "__rs_tan_4", FIXED(4), "_ZGV_LLVM_N4v") +TLI_DEFINE_VECFUNC("__rs_tan_1", "__rs_tan_8", FIXED(8), "_ZGV_LLVM_N8v") + +TLI_DEFINE_VECFUNC("__fd_sinh_1", "__fd_sinh_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__fd_sinh_1", "__fd_sinh_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__fs_sinh_1", "__fs_sinh_4", FIXED(4), "_ZGV_LLVM_N4v") +TLI_DEFINE_VECFUNC("__fs_sinh_1", "__fs_sinh_8", FIXED(8), "_ZGV_LLVM_N8v") + +TLI_DEFINE_VECFUNC("__pd_sinh_1", "__pd_sinh_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__pd_sinh_1", "__pd_sinh_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__ps_sinh_1", "__ps_sinh_4", FIXED(4), "_ZGV_LLVM_N4v") +TLI_DEFINE_VECFUNC("__ps_sinh_1", "__ps_sinh_8", FIXED(8), "_ZGV_LLVM_N8v") + +TLI_DEFINE_VECFUNC("__rd_sinh_1", "__rd_sinh_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__rd_sinh_1", "__rd_sinh_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__rs_sinh_1", "__rs_sinh_4", FIXED(4), "_ZGV_LLVM_N4v") +TLI_DEFINE_VECFUNC("__rs_sinh_1", "__rs_sinh_8", FIXED(8), "_ZGV_LLVM_N8v") + +TLI_DEFINE_VECFUNC("__fd_cosh_1", "__fd_cosh_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__fd_cosh_1", "__fd_cosh_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__fs_cosh_1", "__fs_cosh_4", FIXED(4), "_ZGV_LLVM_N4v") +TLI_DEFINE_VECFUNC("__fs_cosh_1", "__fs_cosh_8", FIXED(8), "_ZGV_LLVM_N8v") + +TLI_DEFINE_VECFUNC("__pd_cosh_1", "__pd_cosh_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__pd_cosh_1", "__pd_cosh_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__ps_cosh_1", "__ps_cosh_4", FIXED(4), "_ZGV_LLVM_N4v") +TLI_DEFINE_VECFUNC("__ps_cosh_1", "__ps_cosh_8", FIXED(8), "_ZGV_LLVM_N8v") + +TLI_DEFINE_VECFUNC("__rd_cosh_1", "__rd_cosh_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__rd_cosh_1", "__rd_cosh_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__rs_cosh_1", "__rs_cosh_4", FIXED(4), "_ZGV_LLVM_N4v") +TLI_DEFINE_VECFUNC("__rs_cosh_1", "__rs_cosh_8", FIXED(8), "_ZGV_LLVM_N8v") + +TLI_DEFINE_VECFUNC("__fd_tanh_1", "__fd_tanh_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__fd_tanh_1", "__fd_tanh_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__fs_tanh_1", "__fs_tanh_4", FIXED(4), "_ZGV_LLVM_N4v") +TLI_DEFINE_VECFUNC("__fs_tanh_1", "__fs_tanh_8", FIXED(8), "_ZGV_LLVM_N8v") + +TLI_DEFINE_VECFUNC("__pd_tanh_1", "__pd_tanh_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__pd_tanh_1", "__pd_tanh_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__ps_tanh_1", "__ps_tanh_4", FIXED(4), "_ZGV_LLVM_N4v") +TLI_DEFINE_VECFUNC("__ps_tanh_1", "__ps_tanh_8", FIXED(8), "_ZGV_LLVM_N8v") + +TLI_DEFINE_VECFUNC("__rd_tanh_1", "__rd_tanh_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__rd_tanh_1", "__rd_tanh_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__rs_tanh_1", "__rs_tanh_4", FIXED(4), "_ZGV_LLVM_N4v") +TLI_DEFINE_VECFUNC("__rs_tanh_1", "__rs_tanh_8", FIXED(8), "_ZGV_LLVM_N8v") + +TLI_DEFINE_VECFUNC("__fd_asin_1", "__fd_asin_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__fd_asin_1", "__fd_asin_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__fs_asin_1", "__fs_asin_4", FIXED(4), "_ZGV_LLVM_N4v") +TLI_DEFINE_VECFUNC("__fs_asin_1", "__fs_asin_8", FIXED(8), "_ZGV_LLVM_N8v") + +TLI_DEFINE_VECFUNC("__pd_asin_1", "__pd_asin_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__pd_asin_1", "__pd_asin_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__ps_asin_1", "__ps_asin_4", FIXED(4), "_ZGV_LLVM_N4v") +TLI_DEFINE_VECFUNC("__ps_asin_1", "__ps_asin_8", FIXED(8), "_ZGV_LLVM_N8v") + +TLI_DEFINE_VECFUNC("__rd_asin_1", "__rd_asin_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__rd_asin_1", "__rd_asin_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__rs_asin_1", "__rs_asin_4", FIXED(4), "_ZGV_LLVM_N4v") +TLI_DEFINE_VECFUNC("__rs_asin_1", "__rs_asin_8", FIXED(8), "_ZGV_LLVM_N8v") + +TLI_DEFINE_VECFUNC("__fd_acos_1", "__fd_acos_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__fd_acos_1", "__fd_acos_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__fs_acos_1", "__fs_acos_4", FIXED(4), "_ZGV_LLVM_N4v") +TLI_DEFINE_VECFUNC("__fs_acos_1", "__fs_acos_8", FIXED(8), "_ZGV_LLVM_N8v") + +TLI_DEFINE_VECFUNC("__pd_acos_1", "__pd_acos_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__pd_acos_1", "__pd_acos_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__ps_acos_1", "__ps_acos_4", FIXED(4), "_ZGV_LLVM_N4v") +TLI_DEFINE_VECFUNC("__ps_acos_1", "__ps_acos_8", FIXED(8), "_ZGV_LLVM_N8v") + +TLI_DEFINE_VECFUNC("__rd_acos_1", "__rd_acos_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__rd_acos_1", "__rd_acos_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__rs_acos_1", "__rs_acos_4", FIXED(4), "_ZGV_LLVM_N4v") +TLI_DEFINE_VECFUNC("__rs_acos_1", "__rs_acos_8", FIXED(8), "_ZGV_LLVM_N8v") + +TLI_DEFINE_VECFUNC("__fd_atan_1", "__fd_atan_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__fd_atan_1", "__fd_atan_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__fs_atan_1", "__fs_atan_4", FIXED(4), "_ZGV_LLVM_N4v") +TLI_DEFINE_VECFUNC("__fs_atan_1", "__fs_atan_8", FIXED(8), "_ZGV_LLVM_N8v") + +TLI_DEFINE_VECFUNC("__pd_atan_1", "__pd_atan_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__pd_atan_1", "__pd_atan_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__ps_atan_1", "__ps_atan_4", FIXED(4), "_ZGV_LLVM_N4v") +TLI_DEFINE_VECFUNC("__ps_atan_1", "__ps_atan_8", FIXED(8), "_ZGV_LLVM_N8v") + +TLI_DEFINE_VECFUNC("__rd_atan_1", "__rd_atan_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__rd_atan_1", "__rd_atan_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__rs_atan_1", "__rs_atan_4", FIXED(4), "_ZGV_LLVM_N4v") +TLI_DEFINE_VECFUNC("__rs_atan_1", "__rs_atan_8", FIXED(8), "_ZGV_LLVM_N8v") + +TLI_DEFINE_VECFUNC("__fd_atan2_1", "__fd_atan2_2", FIXED(2), "_ZGV_LLVM_N2vv") +TLI_DEFINE_VECFUNC("__fd_atan2_1", "__fd_atan2_4", FIXED(4), "_ZGV_LLVM_N4vv") + +TLI_DEFINE_VECFUNC("__fs_atan2_1", "__fs_atan2_4", FIXED(4), "_ZGV_LLVM_N4vv") +TLI_DEFINE_VECFUNC("__fs_atan2_1", "__fs_atan2_8", FIXED(8), "_ZGV_LLVM_N8vv") + +TLI_DEFINE_VECFUNC("__pd_atan2_1", "__pd_atan2_2", FIXED(2), "_ZGV_LLVM_N2vv") +TLI_DEFINE_VECFUNC("__pd_atan2_1", "__pd_atan2_4", FIXED(4), "_ZGV_LLVM_N4vv") + +TLI_DEFINE_VECFUNC("__ps_atan2_1", "__ps_atan2_4", FIXED(4), "_ZGV_LLVM_N4vv") +TLI_DEFINE_VECFUNC("__ps_atan2_1", "__ps_atan2_8", FIXED(8), "_ZGV_LLVM_N8vv") + +TLI_DEFINE_VECFUNC("__rd_atan2_1", "__rd_atan2_2", FIXED(2), "_ZGV_LLVM_N2vv") +TLI_DEFINE_VECFUNC("__rd_atan2_1", "__rd_atan2_4", FIXED(4), "_ZGV_LLVM_N4vv") + +TLI_DEFINE_VECFUNC("__rs_atan2_1", "__rs_atan2_4", FIXED(4), "_ZGV_LLVM_N4vv") +TLI_DEFINE_VECFUNC("__rs_atan2_1", "__rs_atan2_8", FIXED(8), "_ZGV_LLVM_N8vv") + +TLI_DEFINE_VECFUNC("__fd_pow_1", "__fd_pow_2", FIXED(2), "_ZGV_LLVM_N2vv") +TLI_DEFINE_VECFUNC("__fd_pow_1", "__fd_pow_4", FIXED(4), "_ZGV_LLVM_N4vv") + +TLI_DEFINE_VECFUNC("__fs_pow_1", "__fs_pow_4", FIXED(4), "_ZGV_LLVM_N4vv") +TLI_DEFINE_VECFUNC("__fs_pow_1", "__fs_pow_8", FIXED(8), "_ZGV_LLVM_N8vv") + +TLI_DEFINE_VECFUNC("__pd_pow_1", "__pd_pow_2", FIXED(2), "_ZGV_LLVM_N2vv") +TLI_DEFINE_VECFUNC("__pd_pow_1", "__pd_pow_4", FIXED(4), "_ZGV_LLVM_N4vv") + +TLI_DEFINE_VECFUNC("__ps_pow_1", "__ps_pow_4", FIXED(4), "_ZGV_LLVM_N4vv") +TLI_DEFINE_VECFUNC("__ps_pow_1", "__ps_pow_8", FIXED(8), "_ZGV_LLVM_N8vv") + +TLI_DEFINE_VECFUNC("__rd_pow_1", "__rd_pow_2", FIXED(2), "_ZGV_LLVM_N2vv") +TLI_DEFINE_VECFUNC("__rd_pow_1", "__rd_pow_4", FIXED(4), "_ZGV_LLVM_N4vv") + +TLI_DEFINE_VECFUNC("__rs_pow_1", "__rs_pow_4", FIXED(4), "_ZGV_LLVM_N4vv") +TLI_DEFINE_VECFUNC("__rs_pow_1", "__rs_pow_8", FIXED(8), "_ZGV_LLVM_N8vv") + +TLI_DEFINE_VECFUNC("__fs_powi_1", "__fs_powi_4", FIXED(4), "_ZGV_LLVM_N4vv") +TLI_DEFINE_VECFUNC("__fs_powi_1", "__fs_powi_8", FIXED(8), "_ZGV_LLVM_N8vv") + +TLI_DEFINE_VECFUNC("__ps_powi_1", "__ps_powi_4", FIXED(4), "_ZGV_LLVM_N4vv") +TLI_DEFINE_VECFUNC("__ps_powi_1", "__ps_powi_8", FIXED(8), "_ZGV_LLVM_N8vv") + +TLI_DEFINE_VECFUNC("__rs_powi_1", "__rs_powi_4", FIXED(4), "_ZGV_LLVM_N4vv") +TLI_DEFINE_VECFUNC("__rs_powi_1", "__rs_powi_8", FIXED(8), "_ZGV_LLVM_N8vv") + +TLI_DEFINE_VECFUNC("__fd_powi1_1", "__fd_powi1_2", FIXED(2), "_ZGV_LLVM_N2vv") +TLI_DEFINE_VECFUNC("__fd_powi1_1", "__fd_powi1_4", FIXED(4), "_ZGV_LLVM_N4vv") + +TLI_DEFINE_VECFUNC("__fs_powi1_1", "__fs_powi1_4", FIXED(4), "_ZGV_LLVM_N4vv") +TLI_DEFINE_VECFUNC("__fs_powi1_1", "__fs_powi1_8", FIXED(8), "_ZGV_LLVM_N8vv") + +TLI_DEFINE_VECFUNC("__pd_powi1_1", "__pd_powi1_2", FIXED(2), "_ZGV_LLVM_N2vv") +TLI_DEFINE_VECFUNC("__pd_powi1_1", "__pd_powi1_4", FIXED(4), "_ZGV_LLVM_N4vv") + +TLI_DEFINE_VECFUNC("__ps_powi1_1", "__ps_powi1_4", FIXED(4), "_ZGV_LLVM_N4vv") +TLI_DEFINE_VECFUNC("__ps_powi1_1", "__ps_powi1_8", FIXED(8), "_ZGV_LLVM_N8vv") + +TLI_DEFINE_VECFUNC("__rd_powi1_1", "__rd_powi1_2", FIXED(2), "_ZGV_LLVM_N2vv") +TLI_DEFINE_VECFUNC("__rd_powi1_1", "__rd_powi1_4", FIXED(4), "_ZGV_LLVM_N4vv") + +TLI_DEFINE_VECFUNC("__rs_powi1_1", "__rs_powi1_4", FIXED(4), "_ZGV_LLVM_N4vv") +TLI_DEFINE_VECFUNC("__rs_powi1_1", "__rs_powi1_8", FIXED(8), "_ZGV_LLVM_N8vv") + +TLI_DEFINE_VECFUNC("__fd_powk_1", "__fd_powk_2", FIXED(2), "_ZGV_LLVM_N2vv") +TLI_DEFINE_VECFUNC("__fd_powk_1", "__fd_powk_4", FIXED(4), "_ZGV_LLVM_N4vv") + +TLI_DEFINE_VECFUNC("__fs_powk_1", "__fs_powk_4", FIXED(4), "_ZGV_LLVM_N4vv") +TLI_DEFINE_VECFUNC("__fs_powk_1", "__fs_powk_8", FIXED(8), "_ZGV_LLVM_N8vv") + +TLI_DEFINE_VECFUNC("__pd_powk_1", "__pd_powk_2", FIXED(2), "_ZGV_LLVM_N2vv") +TLI_DEFINE_VECFUNC("__pd_powk_1", "__pd_powk_4", FIXED(4), "_ZGV_LLVM_N4vv") + +TLI_DEFINE_VECFUNC("__ps_powk_1", "__ps_powk_4", FIXED(4), "_ZGV_LLVM_N4vv") +TLI_DEFINE_VECFUNC("__ps_powk_1", "__ps_powk_8", FIXED(8), "_ZGV_LLVM_N8vv") + +TLI_DEFINE_VECFUNC("__rd_powk_1", "__rd_powk_2", FIXED(2), "_ZGV_LLVM_N2vv") +TLI_DEFINE_VECFUNC("__rd_powk_1", "__rd_powk_4", FIXED(4), "_ZGV_LLVM_N4vv") + +TLI_DEFINE_VECFUNC("__rs_powk_1", "__rs_powk_4", FIXED(4), "_ZGV_LLVM_N4vv") +TLI_DEFINE_VECFUNC("__rs_powk_1", "__rs_powk_8", FIXED(8), "_ZGV_LLVM_N8vv") + +TLI_DEFINE_VECFUNC("__fd_powk1_1", "__fd_powk1_2", FIXED(2), "_ZGV_LLVM_N2vv") +TLI_DEFINE_VECFUNC("__fd_powk1_1", "__fd_powk1_4", FIXED(4), "_ZGV_LLVM_N4vv") + +TLI_DEFINE_VECFUNC("__fs_powk1_1", "__fs_powk1_4", FIXED(4), "_ZGV_LLVM_N4vv") +TLI_DEFINE_VECFUNC("__fs_powk1_1", "__fs_powk1_8", FIXED(8), "_ZGV_LLVM_N8vv") + +TLI_DEFINE_VECFUNC("__pd_powk1_1", "__pd_powk1_2", FIXED(2), "_ZGV_LLVM_N2vv") +TLI_DEFINE_VECFUNC("__pd_powk1_1", "__pd_powk1_4", FIXED(4), "_ZGV_LLVM_N4vv") + +TLI_DEFINE_VECFUNC("__ps_powk1_1", "__ps_powk1_4", FIXED(4), "_ZGV_LLVM_N4vv") +TLI_DEFINE_VECFUNC("__ps_powk1_1", "__ps_powk1_8", FIXED(8), "_ZGV_LLVM_N8vv") + +TLI_DEFINE_VECFUNC("__rd_powk1_1", "__rd_powk1_2", FIXED(2), "_ZGV_LLVM_N2vv") +TLI_DEFINE_VECFUNC("__rd_powk1_1", "__rd_powk1_4", FIXED(4), "_ZGV_LLVM_N4vv") + +TLI_DEFINE_VECFUNC("__rs_powk1_1", "__rs_powk1_4", FIXED(4), "_ZGV_LLVM_N4vv") +TLI_DEFINE_VECFUNC("__rs_powk1_1", "__rs_powk1_8", FIXED(8), "_ZGV_LLVM_N8vv") + +TLI_DEFINE_VECFUNC("__fd_log10_1", "__fd_log10_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__fd_log10_1", "__fd_log10_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__fs_log10_1", "__fs_log10_4", FIXED(4), "_ZGV_LLVM_N4v") +TLI_DEFINE_VECFUNC("__fs_log10_1", "__fs_log10_8", FIXED(8), "_ZGV_LLVM_N8v") + +TLI_DEFINE_VECFUNC("__pd_log10_1", "__pd_log10_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__pd_log10_1", "__pd_log10_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__ps_log10_1", "__ps_log10_4", FIXED(4), "_ZGV_LLVM_N4v") +TLI_DEFINE_VECFUNC("__ps_log10_1", "__ps_log10_8", FIXED(8), "_ZGV_LLVM_N8v") + +TLI_DEFINE_VECFUNC("__rd_log10_1", "__rd_log10_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__rd_log10_1", "__rd_log10_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__rs_log10_1", "__rs_log10_4", FIXED(4), "_ZGV_LLVM_N4v") +TLI_DEFINE_VECFUNC("__rs_log10_1", "__rs_log10_8", FIXED(8), "_ZGV_LLVM_N8v") + +TLI_DEFINE_VECFUNC("__fd_log_1", "__fd_log_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__fd_log_1", "__fd_log_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__fs_log_1", "__fs_log_4", FIXED(4), "_ZGV_LLVM_N4v") +TLI_DEFINE_VECFUNC("__fs_log_1", "__fs_log_8", FIXED(8), "_ZGV_LLVM_N8v") + +TLI_DEFINE_VECFUNC("__pd_log_1", "__pd_log_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__pd_log_1", "__pd_log_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__ps_log_1", "__ps_log_4", FIXED(4), "_ZGV_LLVM_N4v") +TLI_DEFINE_VECFUNC("__ps_log_1", "__ps_log_8", FIXED(8), "_ZGV_LLVM_N8v") + +TLI_DEFINE_VECFUNC("__rd_log_1", "__rd_log_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__rd_log_1", "__rd_log_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__rs_log_1", "__rs_log_4", FIXED(4), "_ZGV_LLVM_N4v") +TLI_DEFINE_VECFUNC("__rs_log_1", "__rs_log_8", FIXED(8), "_ZGV_LLVM_N8v") + +TLI_DEFINE_VECFUNC("__fs_exp_1", "__fs_exp_4", FIXED(4), "_ZGV_LLVM_N4v") +TLI_DEFINE_VECFUNC("__fs_exp_1", "__fs_exp_8", FIXED(8), "_ZGV_LLVM_N8v") + +TLI_DEFINE_VECFUNC("__pd_exp_1", "__pd_exp_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__pd_exp_1", "__pd_exp_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__ps_exp_1", "__ps_exp_4", FIXED(4), "_ZGV_LLVM_N4v") +TLI_DEFINE_VECFUNC("__ps_exp_1", "__ps_exp_8", FIXED(8), "_ZGV_LLVM_N8v") + +TLI_DEFINE_VECFUNC("__rd_exp_1", "__rd_exp_2", FIXED(2), "_ZGV_LLVM_N2v") +TLI_DEFINE_VECFUNC("__rd_exp_1", "__rd_exp_4", FIXED(4), "_ZGV_LLVM_N4v") + +TLI_DEFINE_VECFUNC("__rs_exp_1", "__rs_exp_4", FIXED(4), "_ZGV_LLVM_N4v") +TLI_DEFINE_VECFUNC("__rs_exp_1", "__rs_exp_8", FIXED(8), "_ZGV_LLVM_N8v") + +#elif defined(TLI_DEFINE_PGMATH_X86_AVX512_VECFUNCS) +TLI_DEFINE_VECFUNC("__fd_sin_1", "__fd_sin_8", FIXED(8), "_ZGV_LLVM_N8v") +TLI_DEFINE_VECFUNC("__fs_sin_1", "__fs_sin_16", FIXED(16), "_ZGV_LLVM_N16v") +TLI_DEFINE_VECFUNC("__pd_sin_1", "__pd_sin_8", FIXED(8), "_ZGV_LLVM_N8v") +TLI_DEFINE_VECFUNC("__ps_sin_1", "__ps_sin_16", FIXED(16), "_ZGV_LLVM_N16v") +TLI_DEFINE_VECFUNC("__rd_sin_1", "__rd_sin_8", FIXED(8), "_ZGV_LLVM_N8v") +TLI_DEFINE_VECFUNC("__rs_sin_1", "__rs_sin_16", FIXED(16), "_ZGV_LLVM_N16v") + +TLI_DEFINE_VECFUNC("__fd_cos_1", "__fd_cos_8", FIXED(8), "_ZGV_LLVM_N8v") +TLI_DEFINE_VECFUNC("__fs_cos_1", "__fs_cos_16", FIXED(16), "_ZGV_LLVM_N16v") +TLI_DEFINE_VECFUNC("__pd_cos_1", "__pd_cos_8", FIXED(8), "_ZGV_LLVM_N8v") +TLI_DEFINE_VECFUNC("__ps_cos_1", "__ps_cos_16", FIXED(16), "_ZGV_LLVM_N16v") +TLI_DEFINE_VECFUNC("__rd_cos_1", "__rd_cos_8", FIXED(8), "_ZGV_LLVM_N8v") +TLI_DEFINE_VECFUNC("__rs_cos_1", "__rs_cos_16", FIXED(16), "_ZGV_LLVM_N16v") + +TLI_DEFINE_VECFUNC("__fd_tan_1", "__fd_tan_8", FIXED(8), "_ZGV_LLVM_N8v") +TLI_DEFINE_VECFUNC("__fs_tan_1", "__fs_tan_16", FIXED(16), "_ZGV_LLVM_N16v") +TLI_DEFINE_VECFUNC("__pd_tan_1", "__pd_tan_8", FIXED(8), "_ZGV_LLVM_N8v") +TLI_DEFINE_VECFUNC("__ps_tan_1", "__ps_tan_16", FIXED(16), "_ZGV_LLVM_N16v") +TLI_DEFINE_VECFUNC("__rd_tan_1", "__rd_tan_8", FIXED(8), "_ZGV_LLVM_N8v") +TLI_DEFINE_VECFUNC("__rs_tan_1", "__rs_tan_16", FIXED(16), "_ZGV_LLVM_N16v") + +TLI_DEFINE_VECFUNC("__fd_sinh_1", "__fd_sinh_8", FIXED(8), "_ZGV_LLVM_N8v") +TLI_DEFINE_VECFUNC("__fs_sinh_1", "__fs_sinh_16", FIXED(16), "_ZGV_LLVM_N16v") +TLI_DEFINE_VECFUNC("__pd_sinh_1", "__pd_sinh_8", FIXED(8), "_ZGV_LLVM_N8v") +TLI_DEFINE_VECFUNC("__ps_sinh_1", "__ps_sinh_16", FIXED(16), "_ZGV_LLVM_N16v") +TLI_DEFINE_VECFUNC("__rd_sinh_1", "__rd_sinh_8", FIXED(8), "_ZGV_LLVM_N8v") +TLI_DEFINE_VECFUNC("__rs_sinh_1", "__rs_sinh_16", FIXED(16), "_ZGV_LLVM_N16v") + +TLI_DEFINE_VECFUNC("__fd_cosh_1", "__fd_cosh_8", FIXED(8), "_ZGV_LLVM_N8v") +TLI_DEFINE_VECFUNC("__fs_cosh_1", "__fs_cosh_16", FIXED(16), "_ZGV_LLVM_N16v") +TLI_DEFINE_VECFUNC("__pd_cosh_1", "__pd_cosh_8", FIXED(8), "_ZGV_LLVM_N8v") +TLI_DEFINE_VECFUNC("__ps_cosh_1", "__ps_cosh_16", FIXED(16), "_ZGV_LLVM_N16v") +TLI_DEFINE_VECFUNC("__rd_cosh_1", "__rd_cosh_8", FIXED(8), "_ZGV_LLVM_N8v") +TLI_DEFINE_VECFUNC("__rs_cosh_1", "__rs_cosh_16", FIXED(16), "_ZGV_LLVM_N16v") + +TLI_DEFINE_VECFUNC("__fd_tanh_1", "__fd_tanh_8", FIXED(8), "_ZGV_LLVM_N8v") +TLI_DEFINE_VECFUNC("__fs_tanh_1", "__fs_tanh_16", FIXED(16), "_ZGV_LLVM_N16v") +TLI_DEFINE_VECFUNC("__pd_tanh_1", "__pd_tanh_8", FIXED(8), "_ZGV_LLVM_N8v") +TLI_DEFINE_VECFUNC("__ps_tanh_1", "__ps_tanh_16", FIXED(16), "_ZGV_LLVM_N16v") +TLI_DEFINE_VECFUNC("__rd_tanh_1", "__rd_tanh_8", FIXED(8), "_ZGV_LLVM_N8v") +TLI_DEFINE_VECFUNC("__rs_tanh_1", "__rs_tanh_16", FIXED(16), "_ZGV_LLVM_N16v") + +TLI_DEFINE_VECFUNC("__fd_asin_1", "__fd_asin_8", FIXED(8), "_ZGV_LLVM_N8v") +TLI_DEFINE_VECFUNC("__fs_asin_1", "__fs_asin_16", FIXED(16), "_ZGV_LLVM_N16v") +TLI_DEFINE_VECFUNC("__pd_asin_1", "__pd_asin_8", FIXED(8), "_ZGV_LLVM_N8v") +TLI_DEFINE_VECFUNC("__ps_asin_1", "__ps_asin_16", FIXED(16), "_ZGV_LLVM_N16v") +TLI_DEFINE_VECFUNC("__rd_asin_1", "__rd_asin_8", FIXED(8), "_ZGV_LLVM_N8v") +TLI_DEFINE_VECFUNC("__rs_asin_1", "__rs_asin_16", FIXED(16), "_ZGV_LLVM_N16v") + +TLI_DEFINE_VECFUNC("__fd_acos_1", "__fd_acos_8", FIXED(8), "_ZGV_LLVM_N8v") +TLI_DEFINE_VECFUNC("__fs_acos_1", "__fs_acos_16", FIXED(16), "_ZGV_LLVM_N16v") +TLI_DEFINE_VECFUNC("__pd_acos_1", "__pd_acos_8", FIXED(8), "_ZGV_LLVM_N8v") +TLI_DEFINE_VECFUNC("__ps_acos_1", "__ps_acos_16", FIXED(16), "_ZGV_LLVM_N16v") +TLI_DEFINE_VECFUNC("__rd_acos_1", "__rd_acos_8", FIXED(8), "_ZGV_LLVM_N8v") +TLI_DEFINE_VECFUNC("__rs_acos_1", "__rs_acos_16", FIXED(16), "_ZGV_LLVM_N16v") + +TLI_DEFINE_VECFUNC("__fd_atan_1", "__fd_atan_8", FIXED(8), "_ZGV_LLVM_N8v") +TLI_DEFINE_VECFUNC("__fs_atan_1", "__fs_atan_16", FIXED(16), "_ZGV_LLVM_N16v") +TLI_DEFINE_VECFUNC("__pd_atan_1", "__pd_atan_8", FIXED(8), "_ZGV_LLVM_N8v") +TLI_DEFINE_VECFUNC("__ps_atan_1", "__ps_atan_16", FIXED(16), "_ZGV_LLVM_N16v") +TLI_DEFINE_VECFUNC("__rd_atan_1", "__rd_atan_8", FIXED(8), "_ZGV_LLVM_N8v") +TLI_DEFINE_VECFUNC("__rs_atan_1", "__rs_atan_16", FIXED(16), "_ZGV_LLVM_N16v") + +TLI_DEFINE_VECFUNC("__fd_atan2_1", "__fd_atan2_8", FIXED(8), "_ZGV_LLVM_N8vv") +TLI_DEFINE_VECFUNC("__fs_atan2_1", "__fs_atan2_16", FIXED(16), "_ZGV_LLVM_N16vv") +TLI_DEFINE_VECFUNC("__pd_atan2_1", "__pd_atan2_8", FIXED(8), "_ZGV_LLVM_N8vv") +TLI_DEFINE_VECFUNC("__ps_atan2_1", "__ps_atan2_16", FIXED(16), "_ZGV_LLVM_N16vv") +TLI_DEFINE_VECFUNC("__rd_atan2_1", "__rd_atan2_8", FIXED(8), "_ZGV_LLVM_N8vv") +TLI_DEFINE_VECFUNC("__rs_atan2_1", "__rs_atan2_16", FIXED(16), "_ZGV_LLVM_N16vv") + +TLI_DEFINE_VECFUNC("__fd_pow_1", "__fd_pow_8", FIXED(8), "_ZGV_LLVM_N8vv") +TLI_DEFINE_VECFUNC("__fs_pow_1", "__fs_pow_16", FIXED(16), "_ZGV_LLVM_N16vv") +TLI_DEFINE_VECFUNC("__pd_pow_1", "__pd_pow_8", FIXED(8), "_ZGV_LLVM_N8vv") +TLI_DEFINE_VECFUNC("__ps_pow_1", "__ps_pow_16", FIXED(16), "_ZGV_LLVM_N16vv") +TLI_DEFINE_VECFUNC("__rd_pow_1", "__rd_pow_8", FIXED(8), "_ZGV_LLVM_N8vv") +TLI_DEFINE_VECFUNC("__rs_pow_1", "__rs_pow_16", FIXED(16), "_ZGV_LLVM_N16vv") + +TLI_DEFINE_VECFUNC("__fs_powi_1", "__fs_powi_16", FIXED(16), "_ZGV_LLVM_N16vv") +TLI_DEFINE_VECFUNC("__ps_powi_1", "__ps_powi_16", FIXED(16), "_ZGV_LLVM_N16vv") +TLI_DEFINE_VECFUNC("__rs_powi_1", "__rs_powi_16", FIXED(16), "_ZGV_LLVM_N16vv") + +TLI_DEFINE_VECFUNC("__fd_powi1_1", "__fd_powi1_8", FIXED(8), "_ZGV_LLVM_N8vv") +TLI_DEFINE_VECFUNC("__fs_powi1_1", "__fs_powi1_16", FIXED(16), "_ZGV_LLVM_N16vv") +TLI_DEFINE_VECFUNC("__pd_powi1_1", "__pd_powi1_8", FIXED(8), "_ZGV_LLVM_N8vv") +TLI_DEFINE_VECFUNC("__ps_powi1_1", "__ps_powi1_16", FIXED(16), "_ZGV_LLVM_N16vv") +TLI_DEFINE_VECFUNC("__rd_powi1_1", "__rd_powi1_8", FIXED(8), "_ZGV_LLVM_N8vv") +TLI_DEFINE_VECFUNC("__rs_powi1_1", "__rs_powi1_16", FIXED(16), "_ZGV_LLVM_N16vv") + +TLI_DEFINE_VECFUNC("__fd_powk_1", "__fd_powk_8", FIXED(8), "_ZGV_LLVM_N8vv") +TLI_DEFINE_VECFUNC("__fs_powk_1", "__fs_powk_16", FIXED(16), "_ZGV_LLVM_N16vv") +TLI_DEFINE_VECFUNC("__pd_powk_1", "__pd_powk_8", FIXED(8), "_ZGV_LLVM_N8vv") +TLI_DEFINE_VECFUNC("__ps_powk_1", "__ps_powk_16", FIXED(16), "_ZGV_LLVM_N16vv") +TLI_DEFINE_VECFUNC("__rd_powk_1", "__rd_powk_8", FIXED(8), "_ZGV_LLVM_N8vv") +TLI_DEFINE_VECFUNC("__rs_powk_1", "__rs_powk_16", FIXED(16), "_ZGV_LLVM_N16vv") + +TLI_DEFINE_VECFUNC("__fd_powk1_1", "__fd_powk1_8", FIXED(8), "_ZGV_LLVM_N8vv") +TLI_DEFINE_VECFUNC("__fs_powk1_1", "__fs_powk1_16", FIXED(16), "_ZGV_LLVM_N16vv") +TLI_DEFINE_VECFUNC("__pd_powk1_1", "__pd_powk1_8", FIXED(8), "_ZGV_LLVM_N8vv") +TLI_DEFINE_VECFUNC("__ps_powk1_1", "__ps_powk1_16", FIXED(16), "_ZGV_LLVM_N16vv") +TLI_DEFINE_VECFUNC("__rd_powk1_1", "__rd_powk1_8", FIXED(8), "_ZGV_LLVM_N8vv") +TLI_DEFINE_VECFUNC("__rs_powk1_1", "__rs_powk1_16", FIXED(16), "_ZGV_LLVM_N16vv") + +TLI_DEFINE_VECFUNC("__fd_log10_1", "__fd_log10_8", FIXED(8), "_ZGV_LLVM_N8v") +TLI_DEFINE_VECFUNC("__fs_log10_1", "__fs_log10_16", FIXED(16), "_ZGV_LLVM_N16v") +TLI_DEFINE_VECFUNC("__pd_log10_1", "__pd_log10_8", FIXED(8), "_ZGV_LLVM_N8v") +TLI_DEFINE_VECFUNC("__ps_log10_1", "__ps_log10_16", FIXED(16), "_ZGV_LLVM_N16v") +TLI_DEFINE_VECFUNC("__rd_log10_1", "__rd_log10_8", FIXED(8), "_ZGV_LLVM_N8v") +TLI_DEFINE_VECFUNC("__rs_log10_1", "__rs_log10_16", FIXED(16), "_ZGV_LLVM_N16v") + +TLI_DEFINE_VECFUNC("__fd_log_1", "__fd_log_8", FIXED(8), "_ZGV_LLVM_N8v") +TLI_DEFINE_VECFUNC("__fs_log_1", "__fs_log_16", FIXED(16), "_ZGV_LLVM_N16v") +TLI_DEFINE_VECFUNC("__pd_log_1", "__pd_log_8", FIXED(8), "_ZGV_LLVM_N8v") +TLI_DEFINE_VECFUNC("__ps_log_1", "__ps_log_16", FIXED(16), "_ZGV_LLVM_N16v") +TLI_DEFINE_VECFUNC("__rd_log_1", "__rd_log_8", FIXED(8), "_ZGV_LLVM_N8v") +TLI_DEFINE_VECFUNC("__rs_log_1", "__rs_log_16", FIXED(16), "_ZGV_LLVM_N16v") + +TLI_DEFINE_VECFUNC("__fs_exp_1", "__fs_exp_16", FIXED(16), "_ZGV_LLVM_N16v") +TLI_DEFINE_VECFUNC("__pd_exp_1", "__pd_exp_8", FIXED(8), "_ZGV_LLVM_N8v") +TLI_DEFINE_VECFUNC("__ps_exp_1", "__ps_exp_16", FIXED(16), "_ZGV_LLVM_N16v") +TLI_DEFINE_VECFUNC("__rd_exp_1", "__rd_exp_8", FIXED(8), "_ZGV_LLVM_N8v") +TLI_DEFINE_VECFUNC("__rs_exp_1", "__rs_exp_16", FIXED(16), "_ZGV_LLVM_N16v") + #else #error "Must choose which vector library functions are to be defined." #endif diff --git a/llvm/include/llvm/Frontend/Driver/CodeGenOptions.h b/llvm/include/llvm/Frontend/Driver/CodeGenOptions.h index 0180670c4c69..637e766f0cbd 100644 --- a/llvm/include/llvm/Frontend/Driver/CodeGenOptions.h +++ b/llvm/include/llvm/Frontend/Driver/CodeGenOptions.h @@ -26,6 +26,9 @@ enum class VectorLibrary { Accelerate, // Use the Accelerate framework. LIBMVEC, // GLIBC vector math library. MASSV, // IBM MASS vector library. +#ifdef ENABLE_CLASSIC_FLANG + PGMATH, // PGI math library. +#endif SVML, // Intel short vector math library. SLEEF, // SLEEF SIMD Library for Evaluating Elementary Functions. Darwin_libsystem_m, // Use Darwin's libsystem_m vector functions. @@ -34,7 +37,8 @@ enum class VectorLibrary { }; TargetLibraryInfoImpl *createTLII(llvm::Triple &TargetTriple, - VectorLibrary Veclib); + VectorLibrary Veclib, + bool targetAVX512); } // end namespace llvm::driver diff --git a/llvm/include/llvm/IR/DIBuilder.h b/llvm/include/llvm/IR/DIBuilder.h index f777206d0d73..ff2a8b9fcc58 100644 --- a/llvm/include/llvm/IR/DIBuilder.h +++ b/llvm/include/llvm/IR/DIBuilder.h @@ -711,15 +711,22 @@ namespace llvm { DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *File, unsigned LineNo, DIType *Ty, bool IsLocalToUnit, bool isDefined = true, DIExpression *Expr = nullptr, MDNode *Decl = nullptr, - MDTuple *TemplateParams = nullptr, uint32_t AlignInBits = 0, - DINodeArray Annotations = nullptr); + MDTuple *TemplateParams = nullptr, +#ifdef ENABLE_CLASSIC_FLANG + DINode::DIFlags Flags = DINode::FlagZero, +#endif + uint32_t AlignInBits = 0, DINodeArray Annotations = nullptr); /// Identical to createGlobalVariable /// except that the resulting DbgNode is temporary and meant to be RAUWed. DIGlobalVariable *createTempGlobalVariableFwdDecl( DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *File, - unsigned LineNo, DIType *Ty, bool IsLocalToUnit, MDNode *Decl = nullptr, - MDTuple *TemplateParams = nullptr, uint32_t AlignInBits = 0); + unsigned LineNo, DIType *Ty, bool isLocalToUnit, MDNode *Decl = nullptr, + MDTuple *TemplateParams = nullptr, +#ifdef ENABLE_CLASSIC_FLANG + DINode::DIFlags Flags = DINode::FlagZero, +#endif + uint32_t AlignInBits = 0); /// Create a new descriptor for an auto variable. This is a local variable /// that is not a subprogram parameter. @@ -850,6 +857,19 @@ namespace llvm { StringRef Name, DIFile *File, unsigned LineNo); +#ifdef ENABLE_CLASSIC_FLANG + /// Create common block entry for a Fortran common block + /// \param Scope Scope of this common block + /// \param Name The name of this common block + /// \param File The file this common block is defined + /// \param LineNo Line number + /// \param VarList List of variables that a located in common block + /// \param AlignInBits Common block alignment + DICommonBlock *createCommonBlock(DIScope *Scope, DIGlobalVariable *decl, + StringRef Name, DIFile *File, + unsigned LineNo, uint32_t AlignInBits = 0); + +#endif /// This creates new descriptor for a namespace with the specified /// parent scope. /// \param Scope Namespace scope diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h index 5ea8c0d7b448..9f46126ec0d1 100644 --- a/llvm/include/llvm/IR/DebugInfoMetadata.h +++ b/llvm/include/llvm/IR/DebugInfoMetadata.h @@ -3318,12 +3318,14 @@ class DIGlobalVariable : public DIVariable { bool IsLocalToUnit; bool IsDefinition; + DIFlags Flags; DIGlobalVariable(LLVMContext &C, StorageType Storage, unsigned Line, - bool IsLocalToUnit, bool IsDefinition, uint32_t AlignInBits, - ArrayRef Ops) + bool IsLocalToUnit, bool IsDefinition, DIFlags Flags, + uint32_t AlignInBits, ArrayRef Ops) : DIVariable(C, DIGlobalVariableKind, Storage, Line, Ops, AlignInBits), - IsLocalToUnit(IsLocalToUnit), IsDefinition(IsDefinition) {} + IsLocalToUnit(IsLocalToUnit), IsDefinition(IsDefinition), + Flags(Flags) {} ~DIGlobalVariable() = default; static DIGlobalVariable * @@ -3331,12 +3333,12 @@ class DIGlobalVariable : public DIVariable { StringRef LinkageName, DIFile *File, unsigned Line, DIType *Type, bool IsLocalToUnit, bool IsDefinition, DIDerivedType *StaticDataMemberDeclaration, MDTuple *TemplateParams, - uint32_t AlignInBits, DINodeArray Annotations, StorageType Storage, - bool ShouldCreate = true) { + DIFlags Flags, uint32_t AlignInBits, DINodeArray Annotations, + StorageType Storage, bool ShouldCreate = true) { return getImpl(Context, Scope, getCanonicalMDString(Context, Name), getCanonicalMDString(Context, LinkageName), File, Line, Type, IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration, - cast_or_null(TemplateParams), AlignInBits, + cast_or_null(TemplateParams), Flags, AlignInBits, Annotations.get(), Storage, ShouldCreate); } static DIGlobalVariable * @@ -3344,14 +3346,14 @@ class DIGlobalVariable : public DIVariable { MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type, bool IsLocalToUnit, bool IsDefinition, Metadata *StaticDataMemberDeclaration, Metadata *TemplateParams, - uint32_t AlignInBits, Metadata *Annotations, StorageType Storage, - bool ShouldCreate = true); + DIFlags Flags, uint32_t AlignInBits, Metadata *Annotations, + StorageType Storage, bool ShouldCreate = true); TempDIGlobalVariable cloneImpl() const { return getTemporary(getContext(), getScope(), getName(), getLinkageName(), getFile(), getLine(), getType(), isLocalToUnit(), isDefinition(), getStaticDataMemberDeclaration(), - getTemplateParams(), getAlignInBits(), + getTemplateParams(), getFlags(), getAlignInBits(), getAnnotations()); } @@ -3361,22 +3363,26 @@ class DIGlobalVariable : public DIVariable { (DIScope * Scope, StringRef Name, StringRef LinkageName, DIFile *File, unsigned Line, DIType *Type, bool IsLocalToUnit, bool IsDefinition, DIDerivedType *StaticDataMemberDeclaration, MDTuple *TemplateParams, - uint32_t AlignInBits, DINodeArray Annotations), + DIFlags Flags, uint32_t AlignInBits, DINodeArray Annotations), (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, - StaticDataMemberDeclaration, TemplateParams, AlignInBits, Annotations)) + StaticDataMemberDeclaration, TemplateParams, Flags, AlignInBits, + Annotations)) DEFINE_MDNODE_GET( DIGlobalVariable, (Metadata * Scope, MDString *Name, MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type, bool IsLocalToUnit, bool IsDefinition, Metadata *StaticDataMemberDeclaration, Metadata *TemplateParams, - uint32_t AlignInBits, Metadata *Annotations), + DIFlags Flags, uint32_t AlignInBits, Metadata *Annotations), (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, - StaticDataMemberDeclaration, TemplateParams, AlignInBits, Annotations)) + StaticDataMemberDeclaration, TemplateParams, Flags, AlignInBits, + Annotations)) TempDIGlobalVariable clone() const { return cloneImpl(); } bool isLocalToUnit() const { return IsLocalToUnit; } bool isDefinition() const { return IsDefinition; } + DIFlags getFlags() const { return Flags; } + bool isArtificial() const { return getFlags() & FlagArtificial; } StringRef getDisplayName() const { return getStringOperand(4); } StringRef getLinkageName() const { return getStringOperand(5); } DIDerivedType *getStaticDataMemberDeclaration() const { diff --git a/llvm/lib/Analysis/TargetLibraryInfo.cpp b/llvm/lib/Analysis/TargetLibraryInfo.cpp index 8557901192e4..33b1b8ca64dc 100644 --- a/llvm/lib/Analysis/TargetLibraryInfo.cpp +++ b/llvm/lib/Analysis/TargetLibraryInfo.cpp @@ -33,6 +33,12 @@ static cl::opt ClVectorLibrary( "GLIBC Vector Math library"), clEnumValN(TargetLibraryInfoImpl::MASSV, "MASSV", "IBM MASS vector library"), +#ifdef ENABLE_CLASSIC_FLANG + clEnumValN(TargetLibraryInfoImpl::PGMATH, "PGMATH", + "PGI math library"), + clEnumValN(TargetLibraryInfoImpl::PGMATH_AVX512, "PGMATH_AVX512", + "PGI math library (AVX512)"), +#endif clEnumValN(TargetLibraryInfoImpl::SVML, "SVML", "Intel SVML library"), clEnumValN(TargetLibraryInfoImpl::SLEEFGNUABI, "sleefgnuabi", @@ -920,13 +926,13 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, initializeLibCalls(TLI, T, StandardNames); } -TargetLibraryInfoImpl::TargetLibraryInfoImpl() { +TargetLibraryInfoImpl::TargetLibraryInfoImpl() : T(Triple()) { // Default to nothing being available. memset(AvailableArray, 0, sizeof(AvailableArray)); - initializeBase(*this, Triple()); + initializeBase(*this, T); } -TargetLibraryInfoImpl::TargetLibraryInfoImpl(const Triple &T) { +TargetLibraryInfoImpl::TargetLibraryInfoImpl(const Triple &T) : T(T) { // Default to everything being available. memset(AvailableArray, -1, sizeof(AvailableArray)); @@ -938,7 +944,7 @@ TargetLibraryInfoImpl::TargetLibraryInfoImpl(const TargetLibraryInfoImpl &TLI) ShouldExtI32Return(TLI.ShouldExtI32Return), ShouldSignExtI32Param(TLI.ShouldSignExtI32Param), ShouldSignExtI32Return(TLI.ShouldSignExtI32Return), - SizeOfInt(TLI.SizeOfInt) { + SizeOfInt(TLI.SizeOfInt), T(TLI.T) { memcpy(AvailableArray, TLI.AvailableArray, sizeof(AvailableArray)); VectorDescs = TLI.VectorDescs; ScalarDescs = TLI.ScalarDescs; @@ -950,7 +956,7 @@ TargetLibraryInfoImpl::TargetLibraryInfoImpl(TargetLibraryInfoImpl &&TLI) ShouldExtI32Return(TLI.ShouldExtI32Return), ShouldSignExtI32Param(TLI.ShouldSignExtI32Param), ShouldSignExtI32Return(TLI.ShouldSignExtI32Return), - SizeOfInt(TLI.SizeOfInt) { + SizeOfInt(TLI.SizeOfInt), T(TLI.T) { std::move(std::begin(TLI.AvailableArray), std::end(TLI.AvailableArray), AvailableArray); VectorDescs = TLI.VectorDescs; @@ -964,6 +970,7 @@ TargetLibraryInfoImpl &TargetLibraryInfoImpl::operator=(const TargetLibraryInfoI ShouldSignExtI32Param = TLI.ShouldSignExtI32Param; ShouldSignExtI32Return = TLI.ShouldSignExtI32Return; SizeOfInt = TLI.SizeOfInt; + T = TLI.T; memcpy(AvailableArray, TLI.AvailableArray, sizeof(AvailableArray)); return *this; } @@ -975,6 +982,7 @@ TargetLibraryInfoImpl &TargetLibraryInfoImpl::operator=(TargetLibraryInfoImpl && ShouldSignExtI32Param = TLI.ShouldSignExtI32Param; ShouldSignExtI32Return = TLI.ShouldSignExtI32Return; SizeOfInt = TLI.SizeOfInt; + T = TLI.T; std::move(std::begin(TLI.AvailableArray), std::end(TLI.AvailableArray), AvailableArray); return *this; @@ -1403,6 +1411,39 @@ void TargetLibraryInfoImpl::addVectorizableFunctionsFromVecLib( addVectorizableFunctions(VecFuncs_AMDLIBM); break; } +#ifdef ENABLE_CLASSIC_FLANG + // NOTE: All routines listed here are not available on all the architectures. + // Based on the size of vector registers available and the size of data, the + // vector width should be chosen correctly. + case PGMATH: { + if (T.getArch() == Triple::aarch64) { + const VecDesc VecFuncs[] = { + #define TLI_DEFINE_PGMATH_AARCH64_VECFUNCS + #include "llvm/Analysis/VecFuncs.def" + #undef TLI_DEFINE_PGMATH_AARCH64_VECFUNCS + }; + addVectorizableFunctions(VecFuncs); + } else if (T.getArch() == Triple::x86_64) { + const VecDesc VecFuncs[] = { + #define TLI_DEFINE_PGMATH_X86_VECFUNCS + #include "llvm/Analysis/VecFuncs.def" + #undef TLI_DEFINE_PGMATH_X86_VECFUNCS + }; + addVectorizableFunctions(VecFuncs); + } + break; + } + case PGMATH_AVX512: { + const VecDesc VecFuncs[] = { + #define TLI_DEFINE_PGMATH_X86_AVX512_VECFUNCS + #include "llvm/Analysis/VecFuncs.def" + #undef TLI_DEFINE_PGMATH_X86_AVX512_VECFUNCS + }; + addVectorizableFunctions(VecFuncs); + break; + } +#endif + case NoLibrary: break; } diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index fa0079bac435..cb9853f3ff53 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -5844,6 +5844,22 @@ bool LLParser::parseDITemplateValueParameter(MDNode *&Result, bool IsDistinct) { /// isDefinition: true, templateParams: !3, /// declaration: !4, align: 8) bool LLParser::parseDIGlobalVariable(MDNode *&Result, bool IsDistinct) { +#ifdef ENABLE_CLASSIC_FLANG +#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ + OPTIONAL(name, MDStringField, (/* AllowEmpty */ true)); \ + OPTIONAL(scope, MDField, ); \ + OPTIONAL(linkageName, MDStringField, ); \ + OPTIONAL(file, MDField, ); \ + OPTIONAL(line, LineField, ); \ + OPTIONAL(type, MDField, ); \ + OPTIONAL(isLocal, MDBoolField, ); \ + OPTIONAL(isDefinition, MDBoolField, (true)); \ + OPTIONAL(templateParams, MDField, ); \ + OPTIONAL(declaration, MDField, ); \ + OPTIONAL(flags, DIFlagField, ); \ + OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX)); \ + OPTIONAL(annotations, MDField, ); +#else #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ OPTIONAL(name, MDStringField, (/* AllowEmpty */ false)); \ OPTIONAL(scope, MDField, ); \ @@ -5855,8 +5871,10 @@ bool LLParser::parseDIGlobalVariable(MDNode *&Result, bool IsDistinct) { OPTIONAL(isDefinition, MDBoolField, (true)); \ OPTIONAL(templateParams, MDField, ); \ OPTIONAL(declaration, MDField, ); \ + OPTIONAL(flags, DIFlagField, ); \ OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX)); \ OPTIONAL(annotations, MDField, ); +#endif PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS @@ -5864,8 +5882,8 @@ bool LLParser::parseDIGlobalVariable(MDNode *&Result, bool IsDistinct) { GET_OR_DISTINCT(DIGlobalVariable, (Context, scope.Val, name.Val, linkageName.Val, file.Val, line.Val, type.Val, isLocal.Val, isDefinition.Val, - declaration.Val, templateParams.Val, align.Val, - annotations.Val)); + declaration.Val, templateParams.Val, flags.Val, + align.Val, annotations.Val)); return false; } diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp index 1caa8480efc5..09536cfdaaae 100644 --- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp +++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp @@ -2025,25 +2025,43 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( break; } case bitc::METADATA_GLOBAL_VAR: { - if (Record.size() < 11 || Record.size() > 13) + if (Record.size() < 11 || Record.size() > 14) return error("Invalid record"); IsDistinct = Record[0] & 1; unsigned Version = Record[0] >> 1; - if (Version == 2) { + if (Version == 3) { + // Add support for DIFlags + Metadata *Annotations = nullptr; + if (Record.size() > 13) + Annotations = getMDOrNull(Record[13]); + + MetadataList.assignValue( + GET_OR_DISTINCT( + DIGlobalVariable, + (Context, getMDOrNull(Record[1]), getMDString(Record[2]), + getMDString(Record[3]), getMDOrNull(Record[4]), Record[5], + getDITypeRefOrNull(Record[6]), Record[7], Record[8], + getMDOrNull(Record[9]), getMDOrNull(Record[10]), + static_cast(Record[11]), Record[12], + Annotations)), + NextMetadataNo); + + NextMetadataNo++; + } else if (Version == 2) { Metadata *Annotations = nullptr; if (Record.size() > 12) Annotations = getMDOrNull(Record[12]); MetadataList.assignValue( - GET_OR_DISTINCT(DIGlobalVariable, - (Context, getMDOrNull(Record[1]), - getMDString(Record[2]), getMDString(Record[3]), - getMDOrNull(Record[4]), Record[5], - getDITypeRefOrNull(Record[6]), Record[7], Record[8], - getMDOrNull(Record[9]), getMDOrNull(Record[10]), - Record[11], Annotations)), + GET_OR_DISTINCT( + DIGlobalVariable, + (Context, getMDOrNull(Record[1]), getMDString(Record[2]), + getMDString(Record[3]), getMDOrNull(Record[4]), Record[5], + getDITypeRefOrNull(Record[6]), Record[7], Record[8], + getMDOrNull(Record[9]), getMDOrNull(Record[10]), + DINode::FlagZero, Record[11], Annotations)), NextMetadataNo); NextMetadataNo++; @@ -2056,7 +2074,8 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( (Context, getMDOrNull(Record[1]), getMDString(Record[2]), getMDString(Record[3]), getMDOrNull(Record[4]), Record[5], getDITypeRefOrNull(Record[6]), Record[7], Record[8], - getMDOrNull(Record[10]), nullptr, Record[11], nullptr)), + getMDOrNull(Record[10]), nullptr, DINode::FlagZero, Record[11], + nullptr)), NextMetadataNo); NextMetadataNo++; @@ -2089,7 +2108,8 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( (Context, getMDOrNull(Record[1]), getMDString(Record[2]), getMDString(Record[3]), getMDOrNull(Record[4]), Record[5], getDITypeRefOrNull(Record[6]), Record[7], Record[8], - getMDOrNull(Record[10]), nullptr, AlignInBits, nullptr)); + getMDOrNull(Record[10]), nullptr, DINode::FlagZero, AlignInBits, + nullptr)); DIGlobalVariableExpression *DGVE = nullptr; if (Attach || Expr) diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index 31c96400dd0f..04dd2320e639 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -2198,7 +2198,7 @@ void ModuleBitcodeWriter::writeDITemplateValueParameter( void ModuleBitcodeWriter::writeDIGlobalVariable( const DIGlobalVariable *N, SmallVectorImpl &Record, unsigned Abbrev) { - const uint64_t Version = 2 << 1; + const uint64_t Version = 3 << 1; Record.push_back((uint64_t)N->isDistinct() | Version); Record.push_back(VE.getMetadataOrNullID(N->getScope())); Record.push_back(VE.getMetadataOrNullID(N->getRawName())); @@ -2210,6 +2210,7 @@ void ModuleBitcodeWriter::writeDIGlobalVariable( Record.push_back(N->isDefinition()); Record.push_back(VE.getMetadataOrNullID(N->getStaticDataMemberDeclaration())); Record.push_back(VE.getMetadataOrNullID(N->getTemplateParams())); + Record.push_back(N->getFlags()); Record.push_back(N->getAlignInBits()); Record.push_back(VE.getMetadataOrNullID(N->getAnnotations().get())); diff --git a/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h b/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h index 5358f7b54f41..462ca6fb1f0b 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h +++ b/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h @@ -115,6 +115,29 @@ class DbgValueLoc { SmallVector ValueLocEntries; bool IsVariadic; + /// Type of entry that this represents. + enum EntryType { + E_Location, + E_Integer, + E_ConstantFP, + E_ConstantInt, + E_TargetIndexLocation + }; + enum EntryType EntryKind; + + /// Either a constant, + union { + int64_t Int; + const ConstantFP *CFP; + const ConstantInt *CIP; + } Constant; + + union { + /// Or a location in the machine frame. + MachineLocation Loc; + /// Or a location from target specific location. + TargetIndexLocation TIL; + }; public: DbgValueLoc(const DIExpression *Expr, ArrayRef Locs) @@ -137,6 +160,37 @@ class DbgValueLoc { assert(((Expr && Expr->isValid()) || !Loc.isLocation()) && "DBG_VALUE with a machine location must have a valid expression."); } + DbgValueLoc(const DIExpression *Expr, int64_t i) + : Expression(Expr), EntryKind(E_Integer) { + Constant.Int = i; + } + DbgValueLoc(const DIExpression *Expr, const ConstantFP *CFP) + : Expression(Expr), EntryKind(E_ConstantFP) { + Constant.CFP = CFP; + } + DbgValueLoc(const DIExpression *Expr, const ConstantInt *CIP) + : Expression(Expr), EntryKind(E_ConstantInt) { + Constant.CIP = CIP; + } + DbgValueLoc(const DIExpression *Expr, MachineLocation Loc) + : Expression(Expr), EntryKind(E_Location), Loc(Loc) { + assert(cast(Expr)->isValid()); + } + DbgValueLoc(const DIExpression *Expr, TargetIndexLocation Loc) + : Expression(Expr), EntryKind(E_TargetIndexLocation), TIL(Loc) {} + + bool isLocation() const { return EntryKind == E_Location; } + bool isTargetIndexLocation() const { + return EntryKind == E_TargetIndexLocation; + } + bool isInt() const { return EntryKind == E_Integer; } + bool isConstantFP() const { return EntryKind == E_ConstantFP; } + bool isConstantInt() const { return EntryKind == E_ConstantInt; } + int64_t getInt() const { return Constant.Int; } + const ConstantFP *getConstantFP() const { return Constant.CFP; } + const ConstantInt *getConstantInt() const { return Constant.CIP; } + MachineLocation getLoc() const { return Loc; } + TargetIndexLocation getTargetIndexLocation() const { return TIL; } bool isFragment() const { return getExpression()->isFragment(); } bool isEntryVal() const { return getExpression()->isEntryValue(); } diff --git a/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.cpp b/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.cpp index 700e24a08b5d..8213fb9de54e 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.cpp @@ -38,6 +38,11 @@ void DebugLocStream::finalizeEntry() { } DebugLocStream::ListBuilder::~ListBuilder() { +#ifdef ENABLE_CLASSIC_FLANG + if (Finalized) + return; + Finalized = true; +#endif if (!Locs.finalizeList(Asm)) return; V.emplace(ListIndex, TagOffset); diff --git a/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.h b/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.h index 6f553dc85c64..25f4f571b899 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.h +++ b/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.h @@ -156,12 +156,18 @@ class DebugLocStream::ListBuilder { AsmPrinter &Asm; DbgVariable &V; size_t ListIndex; +#ifdef ENABLE_CLASSIC_FLANG + bool Finalized; +#endif std::optional TagOffset; public: ListBuilder(DebugLocStream &Locs, DwarfCompileUnit &CU, AsmPrinter &Asm, DbgVariable &V) : Locs(Locs), Asm(Asm), V(V), ListIndex(Locs.startList(&CU)), +#ifdef ENABLE_CLASSIC_FLANG + Finalized(false), +#endif TagOffset(std::nullopt) {} void setTagOffset(uint8_t TO) { diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp index 2f96366b78e9..1a95ef450d6e 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -205,6 +205,9 @@ DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE( else addGlobalName(GV->getName(), *VariableDIE, DeclContext); + if (GV->isArtificial()) + addFlag(*VariableDIE, dwarf::DW_AT_artificial); + addAnnotation(*VariableDIE, GV->getAnnotations()); if (uint32_t AlignInBytes = GV->getAlignInBytes()) diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h index 9662c617d730..9538cd0d46d9 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -339,6 +339,8 @@ struct SymbolCU { DwarfCompileUnit *CU; }; +class DummyDwarfExpression; + /// The kind of accelerator tables we should emit. enum class AccelTableKind { Default, ///< Platform default. @@ -507,6 +509,8 @@ class DwarfDebug : public DebugHandlerBase { /// Map for tracking Fortran deferred CHARACTER lengths. DenseMap StringTypeLocMap; + DenseMap VariableInDependentType; + AddressPool AddrPool; /// Accelerator tables. diff --git a/llvm/lib/Frontend/Driver/CodeGenOptions.cpp b/llvm/lib/Frontend/Driver/CodeGenOptions.cpp index 2d74a91f62dc..b0f7989c353c 100644 --- a/llvm/lib/Frontend/Driver/CodeGenOptions.cpp +++ b/llvm/lib/Frontend/Driver/CodeGenOptions.cpp @@ -13,7 +13,8 @@ namespace llvm::driver { TargetLibraryInfoImpl *createTLII(llvm::Triple &TargetTriple, - driver::VectorLibrary Veclib) { + driver::VectorLibrary Veclib, + bool TargetHasAVX512) { TargetLibraryInfoImpl *TLII = new TargetLibraryInfoImpl(TargetTriple); using VectorLibrary = llvm::driver::VectorLibrary; @@ -30,6 +31,15 @@ TargetLibraryInfoImpl *createTLII(llvm::Triple &TargetTriple, TLII->addVectorizableFunctionsFromVecLib(TargetLibraryInfoImpl::MASSV, TargetTriple); break; +#ifdef ENABLE_CLASSIC_FLANG + case VectorLibrary::PGMATH: + TLII->addVectorizableFunctionsFromVecLib(TargetLibraryInfoImpl::PGMATH, + TargetTriple); + if (TargetHasAVX512) + TLII->addVectorizableFunctionsFromVecLib( + TargetLibraryInfoImpl::PGMATH_AVX512, TargetTriple); + break; +#endif case VectorLibrary::SVML: TLII->addVectorizableFunctionsFromVecLib(TargetLibraryInfoImpl::SVML, TargetTriple); diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index a37a8901489c..faed3a26008d 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -2464,6 +2464,7 @@ static void writeDIGlobalVariable(raw_ostream &Out, const DIGlobalVariable *N, Printer.printBool("isDefinition", N->isDefinition()); Printer.printMetadata("declaration", N->getRawStaticDataMemberDeclaration()); Printer.printMetadata("templateParams", N->getRawTemplateParams()); + Printer.printDIFlags("flags", N->getFlags()); Printer.printInt("align", N->getAlignInBits()); Printer.printMetadata("annotations", N->getRawAnnotations()); Out << ")"; diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp index 752a43213b71..9e1f6630cb37 100644 --- a/llvm/lib/IR/DIBuilder.cpp +++ b/llvm/lib/IR/DIBuilder.cpp @@ -761,14 +761,14 @@ DIGlobalVariableExpression *DIBuilder::createGlobalVariableExpression( DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *F, unsigned LineNumber, DIType *Ty, bool IsLocalToUnit, bool isDefined, DIExpression *Expr, MDNode *Decl, MDTuple *TemplateParams, - uint32_t AlignInBits, DINodeArray Annotations) { + DINode::DIFlags Flags, uint32_t AlignInBits, DINodeArray Annotations) { checkGlobalVariableScope(Context); auto *GV = DIGlobalVariable::getDistinct( VMContext, cast_or_null(Context), Name, LinkageName, F, LineNumber, Ty, IsLocalToUnit, isDefined, - cast_or_null(Decl), TemplateParams, AlignInBits, - Annotations); + cast_or_null(Decl), TemplateParams, Flags, + AlignInBits, Annotations); if (!Expr) Expr = createExpression(); auto *N = DIGlobalVariableExpression::get(VMContext, GV, Expr); @@ -779,14 +779,14 @@ DIGlobalVariableExpression *DIBuilder::createGlobalVariableExpression( DIGlobalVariable *DIBuilder::createTempGlobalVariableFwdDecl( DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *F, unsigned LineNumber, DIType *Ty, bool IsLocalToUnit, MDNode *Decl, - MDTuple *TemplateParams, uint32_t AlignInBits) { + MDTuple *TemplateParams, DINode::DIFlags Flags, uint32_t AlignInBits) { checkGlobalVariableScope(Context); return DIGlobalVariable::getTemporary( VMContext, cast_or_null(Context), Name, LinkageName, F, LineNumber, Ty, IsLocalToUnit, false, - cast_or_null(Decl), TemplateParams, AlignInBits, - nullptr) + cast_or_null(Decl), TemplateParams, Flags, + AlignInBits, nullptr) .release(); } diff --git a/llvm/lib/IR/DebugInfo.cpp b/llvm/lib/IR/DebugInfo.cpp index 8c973eb8cf30..c368ca7e8592 100644 --- a/llvm/lib/IR/DebugInfo.cpp +++ b/llvm/lib/IR/DebugInfo.cpp @@ -1623,12 +1623,13 @@ LLVMMetadataRef LLVMDIBuilderCreateGlobalVariableExpression( LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, const char *Linkage, size_t LinkLen, LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Ty, LLVMBool LocalToUnit, - LLVMMetadataRef Expr, LLVMMetadataRef Decl, uint32_t AlignInBits) { + LLVMMetadataRef Expr, LLVMMetadataRef Decl, LLVMDIFlags Flags, + uint32_t AlignInBits) { return wrap(unwrap(Builder)->createGlobalVariableExpression( unwrapDI(Scope), {Name, NameLen}, {Linkage, LinkLen}, unwrapDI(File), LineNo, unwrapDI(Ty), LocalToUnit, true, unwrap(Expr), unwrapDI(Decl), - nullptr, AlignInBits)); + nullptr, map_from_llvmDIFlags(Flags), AlignInBits)); } LLVMMetadataRef LLVMDIGlobalVariableExpressionGetVariable(LLVMMetadataRef GVE) { @@ -1673,11 +1674,12 @@ LLVMMetadataRef LLVMDIBuilderCreateTempGlobalVariableFwdDecl( LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, const char *Linkage, size_t LnkLen, LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Ty, LLVMBool LocalToUnit, - LLVMMetadataRef Decl, uint32_t AlignInBits) { + LLVMMetadataRef Decl, LLVMDIFlags Flags, uint32_t AlignInBits) { return wrap(unwrap(Builder)->createTempGlobalVariableFwdDecl( unwrapDI(Scope), {Name, NameLen}, {Linkage, LnkLen}, unwrapDI(File), LineNo, unwrapDI(Ty), LocalToUnit, - unwrapDI(Decl), nullptr, AlignInBits)); + unwrapDI(Decl), nullptr, map_from_llvmDIFlags(Flags), + AlignInBits)); } LLVMDbgRecordRef LLVMDIBuilderInsertDeclareRecordBefore( diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp index 915cdd301f2c..51fb01fa4fc3 100644 --- a/llvm/lib/IR/DebugInfoMetadata.cpp +++ b/llvm/lib/IR/DebugInfoMetadata.cpp @@ -1283,15 +1283,16 @@ DIGlobalVariable::getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name, MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type, bool IsLocalToUnit, bool IsDefinition, Metadata *StaticDataMemberDeclaration, - Metadata *TemplateParams, uint32_t AlignInBits, - Metadata *Annotations, StorageType Storage, - bool ShouldCreate) { + Metadata *TemplateParams, DIFlags Flags, + uint32_t AlignInBits, Metadata *Annotations, + StorageType Storage, bool ShouldCreate) { assert(isCanonical(Name) && "Expected canonical MDString"); assert(isCanonical(LinkageName) && "Expected canonical MDString"); DEFINE_GETIMPL_LOOKUP( DIGlobalVariable, (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, - StaticDataMemberDeclaration, TemplateParams, AlignInBits, Annotations)); + StaticDataMemberDeclaration, TemplateParams, Flags, AlignInBits, + Annotations)); Metadata *Ops[] = {Scope, Name, File, @@ -1302,7 +1303,8 @@ DIGlobalVariable::getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name, TemplateParams, Annotations}; DEFINE_GETIMPL_STORE(DIGlobalVariable, - (Line, IsLocalToUnit, IsDefinition, AlignInBits), Ops); + (Line, IsLocalToUnit, IsDefinition, Flags, AlignInBits), + Ops); } DILocalVariable * diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h index 69d90c58964f..90af19ba2ae9 100644 --- a/llvm/lib/IR/LLVMContextImpl.h +++ b/llvm/lib/IR/LLVMContextImpl.h @@ -1082,6 +1082,7 @@ template <> struct MDNodeKeyImpl { bool IsDefinition; Metadata *StaticDataMemberDeclaration; Metadata *TemplateParams; + unsigned Flags; uint32_t AlignInBits; Metadata *Annotations; @@ -1089,20 +1090,21 @@ template <> struct MDNodeKeyImpl { Metadata *File, unsigned Line, Metadata *Type, bool IsLocalToUnit, bool IsDefinition, Metadata *StaticDataMemberDeclaration, Metadata *TemplateParams, + unsigned Flags, uint32_t AlignInBits, Metadata *Annotations) : Scope(Scope), Name(Name), LinkageName(LinkageName), File(File), Line(Line), Type(Type), IsLocalToUnit(IsLocalToUnit), IsDefinition(IsDefinition), StaticDataMemberDeclaration(StaticDataMemberDeclaration), - TemplateParams(TemplateParams), AlignInBits(AlignInBits), - Annotations(Annotations) {} + TemplateParams(TemplateParams), Flags(Flags), + AlignInBits(AlignInBits), Annotations(Annotations) {} MDNodeKeyImpl(const DIGlobalVariable *N) : Scope(N->getRawScope()), Name(N->getRawName()), LinkageName(N->getRawLinkageName()), File(N->getRawFile()), Line(N->getLine()), Type(N->getRawType()), IsLocalToUnit(N->isLocalToUnit()), IsDefinition(N->isDefinition()), StaticDataMemberDeclaration(N->getRawStaticDataMemberDeclaration()), - TemplateParams(N->getRawTemplateParams()), + TemplateParams(N->getRawTemplateParams()), Flags(N->getFlags()), AlignInBits(N->getAlignInBits()), Annotations(N->getRawAnnotations()) {} bool isKeyOf(const DIGlobalVariable *RHS) const { @@ -1114,6 +1116,7 @@ template <> struct MDNodeKeyImpl { StaticDataMemberDeclaration == RHS->getRawStaticDataMemberDeclaration() && TemplateParams == RHS->getRawTemplateParams() && + Flags == RHS->getFlags() && AlignInBits == RHS->getAlignInBits() && Annotations == RHS->getRawAnnotations(); } @@ -1128,7 +1131,7 @@ template <> struct MDNodeKeyImpl { // TODO: make hashing work fine with such situations return hash_combine(Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, /* AlignInBits, */ - StaticDataMemberDeclaration, Annotations); + StaticDataMemberDeclaration, Flags, Annotations); } }; diff --git a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp index 54b328b79a64..da490fdb359a 100644 --- a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp +++ b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp @@ -1718,8 +1718,8 @@ InstrLowerer::getOrCreateRegionCounters(InstrProfCntrInstBase *Inc) { SP, CounterPtr->getName(), /*LinkageName=*/StringRef(), SP->getFile(), /*LineNo=*/0, DB.createUnspecifiedType("Profile Data Type"), CounterPtr->hasLocalLinkage(), /*IsDefined=*/true, /*Expr=*/nullptr, - /*Decl=*/nullptr, /*TemplateParams=*/nullptr, /*AlignInBits=*/0, - Annotations); + /*Decl=*/nullptr, /*TemplateParams=*/nullptr, + /*Flags=*/DINode::FlagZero, /*AlignInBits=*/0, Annotations); CounterPtr->addDebugInfo(DICounter); DB.finalize(); } diff --git a/llvm/test/Assembler/invalid-diglobalvariable-empty-name.ll b/llvm/test/Assembler/invalid-diglobalvariable-empty-name.ll index a4e69f3c8b75..d3c476a03198 100644 --- a/llvm/test/Assembler/invalid-diglobalvariable-empty-name.ll +++ b/llvm/test/Assembler/invalid-diglobalvariable-empty-name.ll @@ -1,4 +1,5 @@ ; RUN: not llvm-as < %s -disable-output 2>&1 | FileCheck %s +; UNSUPPORTED: classic_flang ; CHECK: :[[@LINE+1]]:30: error: 'name' cannot be empty !0 = !DIGlobalVariable(name: "") diff --git a/llvm/test/DebugInfo/Generic/fortran-subprogram-at.ll b/llvm/test/DebugInfo/Generic/fortran-subprogram-at.ll new file mode 100644 index 000000000000..988c388fe218 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/fortran-subprogram-at.ll @@ -0,0 +1,24 @@ +; Test for DIFlagPure, DIFlagElement and DIFlagRecursive. These three +; DIFlags are used to attach DW_AT_pure, DW_AT_element, and DW_AT_recursive +; attributes to DW_TAG_subprogram DIEs. + +; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s +; CHECK: !DISubprogram({{.*}}, spFlags: DISPFlagDefinition | DISPFlagPure | DISPFlagElemental | DISPFlagRecursive, + +!llvm.module.flags = !{!0, !1} +!llvm.dbg.cu = !{!2} + +define void @subprgm() !dbg !6 { +L: + ret void +} + +!0 = !{i32 2, !"Dwarf Version", i32 2} +!1 = !{i32 1, !"Debug Info Version", i32 3} +!2 = distinct !DICompileUnit(language: DW_LANG_Fortran90, file: !3, producer: "Flang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, retainedTypes: !4, globals: !4, imports: !4) +!3 = !DIFile(filename: "fortran-subprogram-at.f", directory: "/") +!4 = !{} +!5 = !DIBasicType(name: "real", size: 32, align: 32, encoding: DW_ATE_float) +!6 = distinct !DISubprogram(name: "subprgm", scope: !2, file: !3, line: 256, type: !7, scopeLine: 256, spFlags: DISPFlagDefinition | DISPFlagPure | DISPFlagElemental | DISPFlagRecursive, unit: !2) +!7 = !DISubroutineType(types: !8) +!8 = !{null, !5} diff --git a/llvm/test/DebugInfo/Generic/more-subprogram-attr.ll b/llvm/test/DebugInfo/Generic/more-subprogram-attr.ll new file mode 100644 index 000000000000..0533cf6b2367 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/more-subprogram-attr.ll @@ -0,0 +1,38 @@ +; REQUIRES: object-emission + +; RUN: %llc_dwarf -O0 -filetype=obj < %s > %t +; RUN: llvm-dwarfdump -v -debug-info %t | FileCheck %s + +; Make sure we're emitting DW_AT_{pure,elemental,recursive}. +; CHECK: DW_TAG_subprogram +; CHECK-NOT: {{DW_TAG|NULL}} +; CHECK: DW_AT_name {{.*}} "main" +; CHECK-NOT: {{DW_TAG|NULL}} +; CHECK: DW_AT_pure [DW_FORM_flag_present] (true) +; CHECK: DW_AT_elemental [DW_FORM_flag_present] (true) +; CHECK: DW_AT_recursive [DW_FORM_flag_present] (true) + +define dso_local i32 @main() !dbg !7 { +entry: + %retval = alloca i32, align 4 + store i32 0, i32* %retval, align 4 + ret i32 0, !dbg !12 +} + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) +!1 = !DIFile(filename: "x.c", directory: "/tmp") +!2 = !{} +!3 = !{i32 2, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!"clang"} +!7 = distinct !DISubprogram(name: "main", scope: !8, file: !8, line: 1, type: !9, scopeLine: 2, spFlags: DISPFlagDefinition | DISPFlagPure | DISPFlagElemental | DISPFlagRecursive, unit: !0, retainedNodes: !2) +!8 = !DIFile(filename: "x.c", directory: "/tmp") +!9 = !DISubroutineType(types: !10) +!10 = !{!11} +!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!12 = !DILocation(line: 3, column: 3, scope: !7) diff --git a/llvm/test/DebugInfo/X86/DICommonBlock.ll b/llvm/test/DebugInfo/X86/DICommonBlock.ll new file mode 100644 index 000000000000..6cfb7a90640d --- /dev/null +++ b/llvm/test/DebugInfo/X86/DICommonBlock.ll @@ -0,0 +1,36 @@ +; ModuleID = 'none.f90' +; RUN: llc %s -o %t -filetype=obj +; RUN: llvm-dwarfdump -debug-info %t | FileCheck %s +; CHECK: DW_TAG_common_block + +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-apple-macosx" + +@common_a = common global [32 x i8] zeroinitializer, align 8, !dbg !13 + +define i32 @subr() !dbg !9 { + %1 = getelementptr inbounds [32 x i8], [32 x i8]* @common_a, i64 0, i32 8 + %2 = bitcast i8* %1 to i32* + %3 = load i32, i32* %2 + ret i32 %3 +} + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!6, !7} +!llvm.ident = !{!8} + +!0 = distinct !DICompileUnit(language: DW_LANG_Fortran90, file: !1, producer: "PGI Fortran", isOptimized: false, runtimeVersion: 2, emissionKind: FullDebug, retainedTypes: !14, globals: !2) +!1 = !DIFile(filename: "none.f90", directory: "/not/here/") +!2 = !{!13} +!3 = !{} +!4 = !DIGlobalVariable(name: "common /a/", scope: !5, file: !1, line: 4, isLocal: false, isDefinition: true, type: !12) +!5 = !DICommonBlock(scope: !9, declaration: !4, name: "a", file: !1, line: 4) +!6 = !{i32 2, !"Dwarf Version", i32 4} +!7 = !{i32 2, !"Debug Info Version", i32 3} +!8 = !{!"PGI Fortran"} +!9 = distinct !DISubprogram(name: "subrtn", scope: !0, file: !1, line: 1, type: !10, isLocal: false, isDefinition: true, unit: !0) +!10 = !DISubroutineType(types: !11) +!11 = !{!12, !12} +!12 = !DIBasicType(name: "int", size: 32) +!13 = !DIGlobalVariableExpression(var: !4, expr: !DIExpression()) +!14 = !{!12, !10} diff --git a/llvm/test/lit.cfg.py b/llvm/test/lit.cfg.py index aad7a088551b..5dee62323980 100644 --- a/llvm/test/lit.cfg.py +++ b/llvm/test/lit.cfg.py @@ -684,3 +684,6 @@ def host_unwind_supports_jit(): if config.has_logf128: config.available_features.add("has_logf128") + +if config.use_classic_flang: + config.available_features.add("classic_flang") diff --git a/llvm/test/lit.site.cfg.py.in b/llvm/test/lit.site.cfg.py.in index 0d02920323d2..470e5fe579e7 100644 --- a/llvm/test/lit.site.cfg.py.in +++ b/llvm/test/lit.site.cfg.py.in @@ -65,6 +65,7 @@ config.spirv_tools_tests = @LLVM_INCLUDE_SPIRV_TOOLS_TESTS@ config.have_vc_rev = @LLVM_APPEND_VC_REV@ config.force_vc_rev = "@LLVM_FORCE_VC_REVISION@" config.has_logf128 = @LLVM_HAS_LOGF128@ +config.use_classic_flang = @LLVM_ENABLE_CLASSIC_FLANG@ import lit.llvm lit.llvm.initialize(lit_config, config) diff --git a/llvm/tools/llvm-c-test/debuginfo.c b/llvm/tools/llvm-c-test/debuginfo.c index baf4ddfcc9a3..6a14362fbba1 100644 --- a/llvm/tools/llvm-c-test/debuginfo.c +++ b/llvm/tools/llvm-c-test/debuginfo.c @@ -70,7 +70,7 @@ int llvm_test_dibuilder(void) { LLVMDIBuilderCreateConstantValueExpression(DIB, 0); LLVMDIBuilderCreateGlobalVariableExpression( DIB, Module, "globalClass", 11, "", 0, File, 1, ClassTy, true, - GlobalClassValueExpr, NULL, 0); + GlobalClassValueExpr, NULL, LLVMDIFlagZero, 0); LLVMMetadataRef Int64Ty = LLVMDIBuilderCreateBasicType(DIB, "Int64", 5, 64, 0, LLVMDIFlagZero); @@ -81,7 +81,7 @@ int llvm_test_dibuilder(void) { LLVMDIBuilderCreateConstantValueExpression(DIB, 0); LLVMDIBuilderCreateGlobalVariableExpression( DIB, Module, "global", 6, "", 0, File, 1, Int64TypeDef, true, - GlobalVarValueExpr, NULL, 0); + GlobalVarValueExpr, NULL, LLVMDIFlagZero, 0); LLVMMetadataRef NameSpace = LLVMDIBuilderCreateNameSpace(DIB, Module, "NameSpace", 9, false); diff --git a/llvm/unittests/IR/MetadataTest.cpp b/llvm/unittests/IR/MetadataTest.cpp index 628221339c89..020e66dc535a 100644 --- a/llvm/unittests/IR/MetadataTest.cpp +++ b/llvm/unittests/IR/MetadataTest.cpp @@ -2932,12 +2932,13 @@ TEST_F(DIGlobalVariableTest, get) { DIDerivedType *StaticDataMemberDeclaration = cast(getDerivedType()); + DINode::DIFlags Flags = static_cast(7); uint32_t AlignInBits = 8; auto *N = DIGlobalVariable::get( Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, - IsDefinition, StaticDataMemberDeclaration, templateParams, AlignInBits, - nullptr); + IsDefinition, StaticDataMemberDeclaration, templateParams, Flags, + AlignInBits, nullptr); EXPECT_EQ(dwarf::DW_TAG_variable, N->getTag()); EXPECT_EQ(Scope, N->getScope()); @@ -2950,57 +2951,66 @@ TEST_F(DIGlobalVariableTest, get) { EXPECT_EQ(IsDefinition, N->isDefinition()); EXPECT_EQ(StaticDataMemberDeclaration, N->getStaticDataMemberDeclaration()); EXPECT_EQ(templateParams, N->getTemplateParams()); + EXPECT_EQ(Flags, N->getFlags()); EXPECT_EQ(AlignInBits, N->getAlignInBits()); EXPECT_EQ(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration, - templateParams, AlignInBits, nullptr)); + templateParams, Flags, AlignInBits, + nullptr)); EXPECT_NE(N, DIGlobalVariable::get( Context, getSubprogram(), Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, - StaticDataMemberDeclaration, templateParams, AlignInBits, - nullptr)); + StaticDataMemberDeclaration, templateParams, Flags, + AlignInBits, nullptr)); EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, "other", LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration, - templateParams, AlignInBits, nullptr)); + templateParams, Flags, AlignInBits, + nullptr)); EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, "other", File, Line, Type, IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration, - templateParams, AlignInBits, nullptr)); + templateParams, Flags, AlignInBits, nullptr)); EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, getFile(), Line, Type, IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration, - templateParams, AlignInBits, nullptr)); + templateParams, Flags, AlignInBits, nullptr)); EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, Line + 1, Type, IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration, - templateParams, AlignInBits, nullptr)); + templateParams, Flags, AlignInBits, nullptr)); EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, Line, getDerivedType(), IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration, - templateParams, AlignInBits, nullptr)); + templateParams, Flags, AlignInBits, nullptr)); EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, Line, Type, !IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration, - templateParams, AlignInBits, nullptr)); + templateParams, Flags, AlignInBits, nullptr)); EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, !IsDefinition, StaticDataMemberDeclaration, - templateParams, AlignInBits, nullptr)); + templateParams, Flags, AlignInBits, nullptr)); EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, cast(getDerivedType()), - templateParams, AlignInBits, nullptr)); + templateParams, Flags, AlignInBits, nullptr)); EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration, nullptr, + Flags, AlignInBits, nullptr)); + EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, + Line, Type, IsLocalToUnit, IsDefinition, + StaticDataMemberDeclaration, + templateParams, + static_cast(Flags + 1), AlignInBits, nullptr)); EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration, - templateParams, (AlignInBits << 1), + templateParams, Flags, (AlignInBits << 1), nullptr)); TempDIGlobalVariable Temp = N->clone(); @@ -3023,16 +3033,17 @@ TEST_F(DIGlobalVariableExpressionTest, get) { auto *Expr2 = DIExpression::get(Context, {1, 2, 3}); DIDerivedType *StaticDataMemberDeclaration = cast(getDerivedType()); + DINode::DIFlags Flags = static_cast(7); uint32_t AlignInBits = 8; auto *Var = DIGlobalVariable::get( Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, - IsDefinition, StaticDataMemberDeclaration, templateParams, AlignInBits, - nullptr); + IsDefinition, StaticDataMemberDeclaration, templateParams, Flags, + AlignInBits, nullptr); auto *Var2 = DIGlobalVariable::get( Context, Scope, "other", LinkageName, File, Line, Type, IsLocalToUnit, - IsDefinition, StaticDataMemberDeclaration, templateParams, AlignInBits, - nullptr); + IsDefinition, StaticDataMemberDeclaration, templateParams, Flags, + AlignInBits, nullptr); auto *N = DIGlobalVariableExpression::get(Context, Var, Expr); EXPECT_EQ(Var, N->getVariable()); diff --git a/llvm/utils/lit/lit/TestingConfig.py b/llvm/utils/lit/lit/TestingConfig.py index b0d8e7149e55..291422f9f0ee 100644 --- a/llvm/utils/lit/lit/TestingConfig.py +++ b/llvm/utils/lit/lit/TestingConfig.py @@ -27,6 +27,7 @@ def fromdefaults(litConfig): "TERM", "CLANG", "CLANG_TOOLCHAIN_PROGRAM_TIMEOUT", + "FLANG", "LLDB", "LD_PRELOAD", "LLVM_SYMBOLIZER_PATH", diff --git a/llvm/utils/lit/lit/llvm/config.py b/llvm/utils/lit/lit/llvm/config.py index 5f762ec7f351..f8aaabe08ebf 100644 --- a/llvm/utils/lit/lit/llvm/config.py +++ b/llvm/utils/lit/lit/llvm/config.py @@ -519,6 +519,8 @@ def use_clang( just-built or optionally an installed clang, and add a set of standard substitutions useful to any test suite that makes use of clang. + Also sets up use of flang + """ # Clear some environment variables that might affect Clang. # @@ -653,6 +655,14 @@ def use_clang( self.add_tool_substitutions(tool_substitutions) self.config.substitutions.append(("%resource_dir", builtin_include_dir)) + self.config.flang = self.use_llvm_tool( + 'flang', search_env='FLANG', required=required) + if self.config.flang: + tool_substitutions = [ + ToolSubst('%flang', command=self.config.flang) + ] + self.add_tool_substitutions(tool_substitutions) + # There will be no default target triple if one was not specifically # set, and the host's architecture is not an enabled target. if self.config.target_triple: diff --git a/offload/test/api/ompx_3d.c b/offload/test/api/ompx_3d.c index 2ae17c226f3a..d9aeb03be673 100644 --- a/offload/test/api/ompx_3d.c +++ b/offload/test/api/ompx_3d.c @@ -1,5 +1,10 @@ // RUN: %libomptarget-compile-run-and-check-generic +// This test currently fails on GitHub runners which do not have enough +// CPUs to allow the creation of the number of threads needed. +// +// XFAIL: * + #include #include #include diff --git a/offload/test/api/ompx_3d.cpp b/offload/test/api/ompx_3d.cpp index 5b5491263a91..877d25636b7b 100644 --- a/offload/test/api/ompx_3d.cpp +++ b/offload/test/api/ompx_3d.cpp @@ -1,5 +1,10 @@ // RUN: %libomptarget-compilexx-run-and-check-generic +// This test currently fails on GitHub runners which do not have enough +// CPUs to allow the creation of the number of threads needed. +// +// XFAIL: * + #include #include #include diff --git a/openmp/runtime/src/CMakeLists.txt b/openmp/runtime/src/CMakeLists.txt index 698e185d9c4d..c0e7b927d79a 100644 --- a/openmp/runtime/src/CMakeLists.txt +++ b/openmp/runtime/src/CMakeLists.txt @@ -366,14 +366,14 @@ endif() # Building the Fortran module files # One compilation step creates both omp_lib.mod and omp_lib_kinds.mod configure_file(${LIBOMP_INC_DIR}/omp_lib.h.var omp_lib.h @ONLY) -configure_file(${LIBOMP_INC_DIR}/omp_lib.F90.var omp_lib.F90 @ONLY) +configure_file(${LIBOMP_INC_DIR}/omp_lib.f90.var omp_lib.f90 @ONLY) set(BUILD_FORTRAN_MODULES False) if (NOT ${LIBOMP_FORTRAN_MODULES_COMPILER} STREQUAL "") # If libomp is built as an LLVM runtime and the flang compiler is available, # compile the Fortran module files. message(STATUS "configuring openmp to build Fortran module files using ${LIBOMP_FORTRAN_MODULES_COMPILER}") - set(LIBOMP_FORTRAN_SOURCE_FILE omp_lib.F90) + set(LIBOMP_FORTRAN_SOURCE_FILE omp_lib.f90) add_custom_target(libomp-mod ALL DEPENDS omp_lib.mod omp_lib_kinds.mod) add_custom_command( OUTPUT omp_lib.mod omp_lib_kinds.mod @@ -393,7 +393,7 @@ elseif(${LIBOMP_FORTRAN_MODULES}) set_target_properties(libomp-mod PROPERTIES FOLDER "OpenMP/Misc") libomp_get_fflags(LIBOMP_CONFIGURED_FFLAGS) if(CMAKE_Fortran_COMPILER_SUPPORTS_F90) - set(LIBOMP_FORTRAN_SOURCE_FILE omp_lib.F90) + set(LIBOMP_FORTRAN_SOURCE_FILE omp_lib.f90) else() message(FATAL_ERROR "Fortran module build requires Fortran 90 compiler") endif() diff --git a/openmp/runtime/src/include/omp_lib.F90.var b/openmp/runtime/src/include/omp_lib.f90.var similarity index 99% rename from openmp/runtime/src/include/omp_lib.F90.var rename to openmp/runtime/src/include/omp_lib.f90.var index 5133915c7d8c..e450360c50b7 100644 --- a/openmp/runtime/src/include/omp_lib.F90.var +++ b/openmp/runtime/src/include/omp_lib.f90.var @@ -430,102 +430,82 @@ end subroutine omp_fulfill_event subroutine omp_init_lock(svar) bind(c) -#ifdef __INTEL_COMPILER !DIR$ IF(__INTEL_COMPILER.GE.1400) !DIR$ attributes known_intrinsic :: omp_init_lock !DIR$ ENDIF -#endif use omp_lib_kinds integer (kind=omp_lock_kind) svar end subroutine omp_init_lock subroutine omp_destroy_lock(svar) bind(c) -#ifdef __INTEL_COMPILER !DIR$ IF(__INTEL_COMPILER.GE.1400) !DIR$ attributes known_intrinsic :: omp_destroy_lock !DIR$ ENDIF -#endif use omp_lib_kinds integer (kind=omp_lock_kind) svar end subroutine omp_destroy_lock subroutine omp_set_lock(svar) bind(c) -#ifdef __INTEL_COMPILER !DIR$ IF(__INTEL_COMPILER.GE.1400) !DIR$ attributes known_intrinsic :: omp_set_lock !DIR$ ENDIF -#endif use omp_lib_kinds integer (kind=omp_lock_kind) svar end subroutine omp_set_lock subroutine omp_unset_lock(svar) bind(c) -#ifdef __INTEL_COMPILER !DIR$ IF(__INTEL_COMPILER.GE.1400) !DIR$ attributes known_intrinsic :: omp_unset_lock !DIR$ ENDIF -#endif use omp_lib_kinds integer (kind=omp_lock_kind) svar end subroutine omp_unset_lock function omp_test_lock(svar) bind(c) -#ifdef __INTEL_COMPILER !DIR$ IF(__INTEL_COMPILER.GE.1400) !DIR$ attributes known_intrinsic :: omp_test_lock !DIR$ ENDIF -#endif use omp_lib_kinds logical (kind=omp_logical_kind) omp_test_lock integer (kind=omp_lock_kind) svar end function omp_test_lock subroutine omp_init_nest_lock(nvar) bind(c) -#ifdef __INTEL_COMPILER !DIR$ IF(__INTEL_COMPILER.GE.1400) !DIR$ attributes known_intrinsic :: omp_init_nest_lock !DIR$ ENDIF -#endif use omp_lib_kinds integer (kind=omp_nest_lock_kind) nvar end subroutine omp_init_nest_lock subroutine omp_destroy_nest_lock(nvar) bind(c) -#ifdef __INTEL_COMPILER !DIR$ IF(__INTEL_COMPILER.GE.1400) !DIR$ attributes known_intrinsic :: omp_destroy_nest_lock !DIR$ ENDIF -#endif use omp_lib_kinds integer (kind=omp_nest_lock_kind) nvar end subroutine omp_destroy_nest_lock subroutine omp_set_nest_lock(nvar) bind(c) -#ifdef __INTEL_COMPILER !DIR$ IF(__INTEL_COMPILER.GE.1400) !DIR$ attributes known_intrinsic :: omp_set_nest_lock !DIR$ ENDIF -#endif use omp_lib_kinds integer (kind=omp_nest_lock_kind) nvar end subroutine omp_set_nest_lock subroutine omp_unset_nest_lock(nvar) bind(c) -#ifdef __INTEL_COMPILER !DIR$ IF(__INTEL_COMPILER.GE.1400) !DIR$ attributes known_intrinsic :: omp_unset_nest_lock !DIR$ ENDIF -#endif use omp_lib_kinds integer (kind=omp_nest_lock_kind) nvar end subroutine omp_unset_nest_lock function omp_test_nest_lock(nvar) bind(c) -#ifdef __INTEL_COMPILER !DIR$ IF(__INTEL_COMPILER.GE.1400) !DIR$ attributes known_intrinsic :: omp_test_nest_lock !DIR$ ENDIF -#endif use omp_lib_kinds integer (kind=omp_integer_kind) omp_test_nest_lock integer (kind=omp_nest_lock_kind) nvar diff --git a/openmp/runtime/src/include/omp_lib.h.var b/openmp/runtime/src/include/omp_lib.h.var index db1dc889d129..74f4c2c6aa43 100644 --- a/openmp/runtime/src/include/omp_lib.h.var +++ b/openmp/runtime/src/include/omp_lib.h.var @@ -488,102 +488,82 @@ end subroutine omp_fulfill_event subroutine omp_init_lock(svar) bind(c) -#ifdef __INTEL_COMPILER !DIR$ IF(__INTEL_COMPILER.GE.1400) !DIR$ attributes known_intrinsic :: omp_init_lock !DIR$ ENDIF -#endif import integer (kind=omp_lock_kind) svar end subroutine omp_init_lock subroutine omp_destroy_lock(svar) bind(c) -#ifdef __INTEL_COMPILER !DIR$ IF(__INTEL_COMPILER.GE.1400) !DIR$ attributes known_intrinsic :: omp_destroy_lock !DIR$ ENDIF -#endif import integer (kind=omp_lock_kind) svar end subroutine omp_destroy_lock subroutine omp_set_lock(svar) bind(c) -#ifdef __INTEL_COMPILER !DIR$ IF(__INTEL_COMPILER.GE.1400) !DIR$ attributes known_intrinsic :: omp_set_lock !DIR$ ENDIF -#endif import integer (kind=omp_lock_kind) svar end subroutine omp_set_lock subroutine omp_unset_lock(svar) bind(c) -#ifdef __INTEL_COMPILER !DIR$ IF(__INTEL_COMPILER.GE.1400) !DIR$ attributes known_intrinsic :: omp_unset_lock !DIR$ ENDIF -#endif import integer (kind=omp_lock_kind) svar end subroutine omp_unset_lock function omp_test_lock(svar) bind(c) -#ifdef __INTEL_COMPILER !DIR$ IF(__INTEL_COMPILER.GE.1400) !DIR$ attributes known_intrinsic :: omp_test_lock !DIR$ ENDIF -#endif import logical (kind=omp_logical_kind) omp_test_lock integer (kind=omp_lock_kind) svar end function omp_test_lock subroutine omp_init_nest_lock(nvar) bind(c) -#ifdef __INTEL_COMPILER !DIR$ IF(__INTEL_COMPILER.GE.1400) !DIR$ attributes known_intrinsic :: omp_init_nest_lock !DIR$ ENDIF -#endif import integer (kind=omp_nest_lock_kind) nvar end subroutine omp_init_nest_lock subroutine omp_destroy_nest_lock(nvar) bind(c) -#ifdef __INTEL_COMPILER !DIR$ IF(__INTEL_COMPILER.GE.1400) !DIR$ attributes known_intrinsic :: omp_destroy_nest_lock !DIR$ ENDIF -#endif import integer (kind=omp_nest_lock_kind) nvar end subroutine omp_destroy_nest_lock subroutine omp_set_nest_lock(nvar) bind(c) -#ifdef __INTEL_COMPILER !DIR$ IF(__INTEL_COMPILER.GE.1400) !DIR$ attributes known_intrinsic :: omp_set_nest_lock !DIR$ ENDIF -#endif import integer (kind=omp_nest_lock_kind) nvar end subroutine omp_set_nest_lock subroutine omp_unset_nest_lock(nvar) bind(c) -#ifdef __INTEL_COMPILER !DIR$ IF(__INTEL_COMPILER.GE.1400) !DIR$ attributes known_intrinsic :: omp_unset_nest_lock !DIR$ ENDIF -#endif import integer (kind=omp_nest_lock_kind) nvar end subroutine omp_unset_nest_lock function omp_test_nest_lock(nvar) bind(c) -#ifdef __INTEL_COMPILER !DIR$ IF(__INTEL_COMPILER.GE.1400) !DIR$ attributes known_intrinsic :: omp_test_nest_lock !DIR$ ENDIF -#endif import integer (kind=omp_integer_kind) omp_test_nest_lock integer (kind=omp_nest_lock_kind) nvar @@ -1012,7 +992,6 @@ end subroutine kmp_set_warnings_off end interface -#ifdef __INTEL_COMPILER !DIR$ IF DEFINED (__INTEL_OFFLOAD) !DIR$ IF(__INTEL_COMPILER.LT.1900) @@ -1181,4 +1160,3 @@ !$omp declare target(omp_init_nest_lock_with_hint ) !DIR$ ENDIF !DIR$ ENDIF -#endif diff --git a/openmp/runtime/test/affinity/kmp-affinity.c b/openmp/runtime/test/affinity/kmp-affinity.c index 5ee492f5441c..2064a82303e1 100644 --- a/openmp/runtime/test/affinity/kmp-affinity.c +++ b/openmp/runtime/test/affinity/kmp-affinity.c @@ -4,6 +4,11 @@ // RUN: env KMP_AFFINITY=granularity=socket,compact %libomp-run // REQUIRES: linux +// This test currently fails on GitHub runners. See: +// https://github.com/flang-compiler/classic-flang-llvm-project/issues/171 +// +// XFAIL: linux + #include #include #include diff --git a/openmp/runtime/test/affinity/omp-places.c b/openmp/runtime/test/affinity/omp-places.c index cf9780890c17..92a9a2130d2b 100644 --- a/openmp/runtime/test/affinity/omp-places.c +++ b/openmp/runtime/test/affinity/omp-places.c @@ -4,6 +4,11 @@ // RUN: env OMP_PLACES=sockets %libomp-run // REQUIRES: linux +// This test currently fails on GitHub runners. See: +// https://github.com/flang-compiler/classic-flang-llvm-project/issues/171 +// +// XFAIL: linux + #include #include #include diff --git a/openmp/runtime/test/ompt/teams/distribute_dispatch.c b/openmp/runtime/test/ompt/teams/distribute_dispatch.c index 1dcede84f28e..ff1d68f2d697 100644 --- a/openmp/runtime/test/ompt/teams/distribute_dispatch.c +++ b/openmp/runtime/test/ompt/teams/distribute_dispatch.c @@ -4,6 +4,11 @@ /// GCC lowering of distribute results in calls to /// omp_get_num_teams/omp_get_team_num rather than region calls // UNSUPPORTED: gcc + +// This test expects 4 teams of 1 thread each to be created, and fails +// on CI runners with insufficient resources. +// UNSUPPORTED: linux + #include "callback.h" #define WORK_SIZE 64 diff --git a/scripts/build_llvm_project.py b/scripts/build_llvm_project.py new file mode 100644 index 000000000000..86a4fea61cff --- /dev/null +++ b/scripts/build_llvm_project.py @@ -0,0 +1,153 @@ +#!/usr/bin/env python + +import argparse +import os +import platform +import settings +import shutil +import subprocess +import sys + +from pathlib import Path, PurePath + +def default_toolchain(): + system = platform.uname()[0] + machine = platform.uname()[4] + toolchain = Path(settings.THIS_DIR, + 'cmake', + f'toolchain_{system.lower()}_{machine.lower()}.cmake') + return toolchain if toolchain.is_file else None + +def get_arguments(): + parser = argparse.ArgumentParser( + description="Help configure and build classic-flang-llvm-project") + + buildopt = parser.add_argument_group('general build options') + buildopt.add_argument('-t', '--target', metavar='ARCH', choices=['X86', 'AArch64', 'PowerPC'], default='X86', + help='Control which targets are enabled (%(choices)s) (default: %(default)s)') + buildopt.add_argument('-p', '--install-prefix', metavar='PATH', nargs='?', default=None, const=False, + help='Specify installation directory (default: platform-specific location)') + buildopt.add_argument('-i', '--install', action='store_true', default=False, + help='Install LLVM (default: do not install)') + buildopt.add_argument('-j', '--jobs', metavar='N', type=int, default=os.cpu_count(), + help='Number of parallel build jobs (default: %(default)s)') + buildopt.add_argument('--toolchain', metavar='FILE', default=default_toolchain().as_posix(), + help='Specify toolchain file (default: %(default)s)') + buildopt.add_argument('-d', '--builddir', metavar='DIR', default='build', + help=f'Specify build directory (default: {settings.LLVM_DIR}/%(default)s)') + buildopt.add_argument('--clean', action='store_true', default=False, + help='Clean build') + buildopt.add_argument('-b', '--build-type', metavar='TYPE', default='Release', + help='Set build type (default: %(default)s)') + buildopt.add_argument('-x', '--cmake-param', metavar='OPT', action='append', default=[], + help='Add custom argument to CMake') + buildopt.add_argument('-e', '--llvm-enable-projects', metavar='OPT', action='append', default=['clang'] if sys.platform == 'win32' else ['clang', 'openmp'], + help='Enable LLVM projects to build (in quotation marks separated by semicolons e.g.: "clang;openmp")') + buildopt.add_argument('-c', '--use-ccache', action="store_true", default=False, + help='Using ccache during the build (default: %(default)s)') + buildopt.add_argument('--cc', metavar='OPT', default=None, + help='Use specific C compiler') + buildopt.add_argument('--cxx', metavar='OPT', default=None, + help='Use specific C++ compiler') + buildopt.add_argument('-v', '--verbose', action='store_true', default=False, + help='Verbose build (default: %(default)s') + arguments = parser.parse_args() + return arguments + +def generate_buildoptions(arguments): + base_cmake_args = [ + f'-DCMAKE_BUILD_TYPE={arguments.build_type}', + f'-DCMAKE_TOOLCHAIN_FILE={arguments.toolchain}' + ] + + generator = 'Ninja' if sys.platform == 'win32' else 'Unix Makefiles' + base_cmake_args.append(f'-G{generator}') + + if arguments.install_prefix: + install_root = Path(arguments.install_prefix) + base_cmake_args.append(f'-DCMAKE_INSTALL_PREFIX={install_root.as_posix()}') + + if arguments.use_ccache: + base_cmake_args.append('-DCMAKE_C_COMPILER_LAUNCHER=ccache') + base_cmake_args.append('-DCMAKE_CXX_COMPILER_LAUNCHER=ccache') + + if arguments.cmake_param: + base_cmake_args.extend(arguments.cmake_param) + + if arguments.cc: + base_cmake_args.append(f'-DCMAKE_C_COMPILER={arguments.cc}') + + if arguments.cxx: + base_cmake_args.append(f'-DCMAKE_CXX_COMPILER={arguments.cxx}') + + if arguments.verbose: + base_cmake_args.append('-DCMAKE_VERBOSE_MAKEFILE=ON') + + return base_cmake_args + +def normalize_builddir(project_srcdir, builddir, clean): + build_path = '' + if PurePath(builddir).is_absolute(): + build_path = Path(builddir, PurePath(project_srcdir).name) + else: + build_path = Path(project_srcdir, builddir) + + if clean and build_path.exists(): + shutil.rmtree(build_path) + + return build_path.as_posix() + +def configure_llvm(arguments): + build_path = normalize_builddir( + settings.LLVM_DIR, arguments.builddir, arguments.clean) + + build_options = generate_buildoptions(arguments) + additional_options = [ + f'-DLLVM_TARGETS_TO_BUILD={arguments.target}', + '-DLLVM_ENABLE_CLASSIC_FLANG=ON', + ] + if(arguments.llvm_enable_projects): + additional_options.append(f'-DLLVM_ENABLE_PROJECTS={";".join(x for x in arguments.llvm_enable_projects)}') + build_options.extend(additional_options) + cmake_cmd = ['cmake', '-B', build_path, '-S', Path.joinpath(settings.LLVM_DIR,'llvm')] + cmake_cmd.extend(build_options) + subprocess.run(cmake_cmd, check=True) + + return build_path + +def build_project(build_path, arguments): + build_cmd = ['cmake', '--build', build_path, '--config', + arguments.build_type, '-j', str(arguments.jobs)] + subprocess.run(build_cmd, check=True) + +def install_project(build_path, arguments): + install_cmd = ['cmake', '--build', build_path, '--config', + arguments.build_type, '--target', 'install'] + subprocess.run(install_cmd, check=True) + +def print_success(): + print() + print('=' * 30) + print('Build succeeded!') + print('=' * 30) + print() + +def print_header(title): + print() + print('*' * 30) + print(f'{title}...') + print('*' * 30) + print() + +def main(): + arguments = get_arguments() + + print_header('Building classic LLVM') + build_path = configure_llvm(arguments) + build_project(build_path, arguments) + if arguments.install: + install_project(build_path, arguments) + +if __name__ == "__main__": + main() + print_success() diff --git a/scripts/cmake/toolchain_linux_x86_64.cmake b/scripts/cmake/toolchain_linux_x86_64.cmake new file mode 100644 index 000000000000..daa8f7bba151 --- /dev/null +++ b/scripts/cmake/toolchain_linux_x86_64.cmake @@ -0,0 +1,2 @@ +set(CMAKE_C_COMPILER clang) +set(CMAKE_CXX_COMPILER clang++) diff --git a/scripts/cmake/toolchain_windows_amd64.cmake b/scripts/cmake/toolchain_windows_amd64.cmake new file mode 100644 index 000000000000..2457d64e5595 --- /dev/null +++ b/scripts/cmake/toolchain_windows_amd64.cmake @@ -0,0 +1,2 @@ +set(CMAKE_C_COMPILER "clang-cl") +set(CMAKE_CXX_COMPILER "clang-cl") diff --git a/scripts/cmake/toolchain_windows_arm64.cmake b/scripts/cmake/toolchain_windows_arm64.cmake new file mode 100644 index 000000000000..3edd83a2d72d --- /dev/null +++ b/scripts/cmake/toolchain_windows_arm64.cmake @@ -0,0 +1,6 @@ +set(triple arm64-windows) + +set(CMAKE_C_COMPILER clang-cl) +set(CMAKE_C_COMPILER_TARGET ${triple}) +set(CMAKE_CXX_COMPILER clang-cl) +set(CMAKE_CXX_COMPILER_TARGET ${triple}) diff --git a/scripts/settings.py b/scripts/settings.py new file mode 100644 index 000000000000..d24f8b521af3 --- /dev/null +++ b/scripts/settings.py @@ -0,0 +1,5 @@ +from pathlib import Path + +THIS_DIR = Path(__file__).resolve().parent +LLVM_DIR = THIS_DIR.parent +TOOLCHAIN_DIR = THIS_DIR.joinpath('cmake')