From 95c75cbd176c627f792ea5f72df6032eecbddc07 Mon Sep 17 00:00:00 2001 From: Eric Schweitz Date: Wed, 21 Aug 2019 13:26:26 -0700 Subject: [PATCH 01/47] Port Classic Flang to LLVM 15 This commit cherry-picks 427c0e83a9f271c3b3f0028201a0c310c7143464 from the release_14x branch, which is a combination of the following legacy patches: Commit 82b38d24a518: [ClassicFlang] Port release_90 changes from flang-compiler/llvm Cherry-picked commit 2085211cfcca70411dc63f0d08763facc8a02090 by Eric Schweitz, resolved merge conflicts, fixed build failures (e.g. adapted CGDebugInfo.cpp to the new API), and fixed the DIGlobalVariable unit tests, which have been broken since commit edfad65eebdf045b050f37380b6b61d673513982. Commit 885dd87e5fdc: [DebugInfo] Removal of DIFortranArrayType and DIFortranSubrange These extensions are no more required after merge of below PR. Commit 5c9b2e0867d5: Modification to incorporate comments from @bryanpkc. Commit 822de2c2a9cc: [AsmPrinter] Fix redundant names and types A bug was introduced in 82b38d24a51871a210a184dd558e9b955a421e8e while cherry-picking a DIGlobalVariable-related patch. Commit 45a70a89626a: Port driver changes from release/11x Cherry-picked c51f89679135f84675f492d560ec5535c2000cfe by Varun Jayathirtha from release_90, and resolved merge conflicts. To avoid conflicts with the new Flang, lib/Driver/ToolChains/Flang.{cpp,h} have been renamed to ClassicFlang.{cpp,h}, and the ENABLE_CLASSIC_FLANG macro is introduced to select which incarnation of Flang to build. The macro is set by running CMake with -DLLVM_ENABLE_CLASSIC_FLANG. After merge with LLVM 11: Move flang options to the end of the definitions list. Commit a9a803645a7d: Port Classic Flang to LLVM 13 File changes to TargetLibraryInfo and DebugLocEntry to adapt to the code from release/13.x and make it work. Comment out the changes due a segmentation fault, code need to be reviewed properly once all commits are in Commit fe989b724392: Fix -fveclib=PGMATH The use of #ifdef in include/clang/Driver/Options.td was incorrect and unsupported. As a result -fveclib=PGMATH was silently ignored, and in LLVM 12, it causes the invocation to fail. This patch unguards the option so that it is parsed correctly, but lets the FLANG_LLVM_EXTENSIONS macro continue to toggle the feature. Commit 7c224ae4708d: Fix use of classic Flang as preprocessor Commit 8403c8335f9a: Merge FLANG_LLVM_EXTENSIONS macro into ENABLE_CLASSIC_FLANG Commit 486741e2e30f: Fix test failures when in classic Flang mode Add a new lit feature tag "classic_flang" to select which tests can or cannot be run when the driver is built for classic Flang. Handle LLVM_ENABLE_CLASSIC_FLANG in llvm/cmake/modules/HandleLLVMOptions.cmake instead of clang/CMakeLists.txt so that macro works in both clang and llvm. Commit a10f592d3b02: Port Classic Flang to LLVM 13 LLVM port from release_12x to release_13x, changes done in order to make project able to be build. Commit d3853218de1a (partial): Change to Options.td in order to add the correct invocation for ffixed_line_length_VALUE. This commit also includes the following legacy patch: Commit 5da2c11605e0: Add DebugInfo tests Commit c379c8d515c0: [ClassicFlang][Driver] Correct the LLVM version passed by the Driver --- clang/CMakeLists.txt | 5 + clang/include/clang/Basic/CodeGenOptions.h | 3 + .../clang/Basic/DiagnosticDriverKinds.td | 6 + clang/include/clang/Basic/MacroBuilder.h | 3 +- clang/include/clang/Basic/Sanitizers.def | 2 + clang/include/clang/Driver/Action.h | 11 + clang/include/clang/Driver/Options.td | 190 ++- clang/include/clang/Driver/Phases.h | 1 + clang/include/clang/Driver/ToolChain.h | 15 + clang/include/clang/Driver/Types.def | 7 + clang/include/clang/Driver/Types.h | 8 + clang/include/clang/Frontend/Utils.h | 31 + clang/lib/CodeGen/BackendUtil.cpp | 6 + clang/lib/CodeGen/CGDebugInfo.cpp | 10 +- clang/lib/Driver/Action.cpp | 7 + clang/lib/Driver/CMakeLists.txt | 5 + clang/lib/Driver/Driver.cpp | 41 + clang/lib/Driver/OffloadBundler.cpp | 4 + clang/lib/Driver/Phases.cpp | 1 + clang/lib/Driver/ToolChain.cpp | 59 +- clang/lib/Driver/ToolChains/Clang.cpp | 60 + clang/lib/Driver/ToolChains/ClassicFlang.cpp | 1067 +++++++++++++++++ clang/lib/Driver/ToolChains/ClassicFlang.h | 49 + clang/lib/Driver/ToolChains/CommonArgs.cpp | 35 + clang/lib/Driver/ToolChains/CommonArgs.h | 2 + clang/lib/Driver/ToolChains/Cuda.cpp | 33 + clang/lib/Driver/ToolChains/Cuda.h | 6 + clang/lib/Driver/ToolChains/Gnu.cpp | 10 + clang/lib/Driver/ToolChains/Linux.cpp | 188 +++ clang/lib/Driver/ToolChains/Linux.h | 3 + clang/lib/Driver/Types.cpp | 49 + clang/lib/Frontend/InitPreprocessor.cpp | 20 - clang/test/Driver/autocomplete.c | 2 +- clang/test/Driver/flang/classic_flang.f95 | 28 + clang/test/Driver/flang/flang.f90 | 2 + clang/test/Driver/flang/flang_ucase.F90 | 2 + .../Driver/flang/multiple-inputs-mixed.f90 | 2 + clang/test/Driver/flang/multiple-inputs.f90 | 2 + clang/test/Driver/fortran.f95 | 2 + clang/test/Driver/gfortran.f90 | 1 + clang/test/lit.cfg.py | 3 + clang/test/lit.site.cfg.py.in | 1 + clang/tools/driver/CMakeLists.txt | 2 +- llvm/cmake/modules/HandleLLVMOptions.cmake | 8 + llvm/include/llvm-c/DebugInfo.h | 5 +- .../include/llvm/Analysis/TargetLibraryInfo.h | 3 + llvm/include/llvm/IR/DIBuilder.h | 28 +- llvm/include/llvm/IR/DebugInfoMetadata.h | 32 +- llvm/lib/Analysis/TargetLibraryInfo.cpp | 455 +++++++ llvm/lib/AsmParser/LLParser.cpp | 22 +- llvm/lib/Bitcode/Reader/MetadataLoader.cpp | 42 +- llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 3 +- llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h | 89 ++ .../lib/CodeGen/AsmPrinter/DebugLocStream.cpp | 5 + llvm/lib/CodeGen/AsmPrinter/DebugLocStream.h | 6 + .../CodeGen/AsmPrinter/DwarfCompileUnit.cpp | 3 + .../lib/CodeGen/AsmPrinter/DwarfCompileUnit.h | 8 + llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 76 ++ llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h | 12 + llvm/lib/IR/AsmWriter.cpp | 1 + llvm/lib/IR/DIBuilder.cpp | 12 +- llvm/lib/IR/DebugInfo.cpp | 10 +- llvm/lib/IR/DebugInfoMetadata.cpp | 12 +- llvm/lib/IR/LLVMContextImpl.h | 11 +- .../Instrumentation/InstrProfiling.cpp | 4 +- .../Transforms/Vectorize/LoopVectorize.cpp | 6 +- .../invalid-diglobalvariable-empty-name.ll | 1 + .../Generic/fortran-subprogram-at.ll | 24 + .../DebugInfo/Generic/more-subprogram-attr.ll | 38 + llvm/test/DebugInfo/X86/DICommonBlock.ll | 36 + llvm/test/lit.cfg.py | 3 + llvm/test/lit.site.cfg.py.in | 1 + llvm/tools/llvm-c-test/debuginfo.c | 4 +- llvm/unittests/IR/MetadataTest.cpp | 47 +- 74 files changed, 2884 insertions(+), 107 deletions(-) create mode 100644 clang/lib/Driver/ToolChains/ClassicFlang.cpp create mode 100644 clang/lib/Driver/ToolChains/ClassicFlang.h mode change 100644 => 100755 clang/lib/Driver/Types.cpp create mode 100644 clang/test/Driver/flang/classic_flang.f95 create mode 100644 llvm/test/DebugInfo/Generic/fortran-subprogram-at.ll create mode 100644 llvm/test/DebugInfo/Generic/more-subprogram-attr.ll create mode 100644 llvm/test/DebugInfo/X86/DICommonBlock.ll diff --git a/clang/CMakeLists.txt b/clang/CMakeLists.txt index d558b0522e82..949f12d3ce8c 100644 --- a/clang/CMakeLists.txt +++ b/clang/CMakeLists.txt @@ -392,6 +392,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/CodeGenOptions.h b/clang/include/clang/Basic/CodeGenOptions.h index 14fc94fe27f9..41577b97e030 100644 --- a/clang/include/clang/Basic/CodeGenOptions.h +++ b/clang/include/clang/Basic/CodeGenOptions.h @@ -59,6 +59,9 @@ public: 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 libsytem_m vector functions. diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td index 1b69324d073a..09a1949d7596 100644 --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -131,6 +131,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< @@ -354,6 +358,8 @@ def err_drv_negative_columns : Error< "invalid value '%1' in '%0', value must be 'none' or a positive integer">; def err_drv_small_columns : Error< "invalid value '%1' in '%0', value must be '%2' or greater">; +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 96e67cbbfa3f..bfc5e38c15e3 100644 --- a/clang/include/clang/Basic/MacroBuilder.h +++ b/clang/include/clang/Basic/MacroBuilder.h @@ -24,9 +24,10 @@ 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". - void defineMacro(const Twine &Name, const Twine &Value = "1") { + virtual void defineMacro(const Twine &Name, const Twine &Value = "1") { Out << "#define " << Name << ' ' << Value << '\n'; } diff --git a/clang/include/clang/Basic/Sanitizers.def b/clang/include/clang/Basic/Sanitizers.def index c2137e3f61f6..4f0a2bf332ef 100644 --- a/clang/include/clang/Basic/Sanitizers.def +++ b/clang/include/clang/Basic/Sanitizers.def @@ -107,6 +107,8 @@ SANITIZER("signed-integer-overflow", SignedIntegerOverflow) SANITIZER("unreachable", Unreachable) SANITIZER("vla-bound", VLABound) SANITIZER("vptr", Vptr) +// fortran contiguous pointer checks +SANITIZER("discontiguous", Discontiguous) // IntegerSanitizer SANITIZER("unsigned-integer-overflow", UnsignedIntegerOverflow) diff --git a/clang/include/clang/Driver/Action.h b/clang/include/clang/Driver/Action.h index 04fa8b01b418..077800eaeb09 100644 --- a/clang/include/clang/Driver/Action.h +++ b/clang/include/clang/Driver/Action.h @@ -62,6 +62,7 @@ public: AnalyzeJobClass, MigrateJobClass, CompileJobClass, + FortranFrontendJobClass, BackendJobClass, AssembleJobClass, LinkJobClass, @@ -470,6 +471,16 @@ public: } }; +class FortranFrontendJobAction : public JobAction { + void anchor() override; +public: + FortranFrontendJobAction(Action *Input, types::ID OutputType); + + static bool classof(const Action *A) { + return A->getKind() == FortranFrontendJobClass; + } +}; + class CompileJobAction : public JobAction { void anchor() override; diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index d4f7315bf8cb..0799121f864e 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -590,7 +590,11 @@ class InternalDriverOpt : Group, Flags<[NoXarchOption, HelpHidden]>; def driver_mode : Joined<["--"], "driver-mode=">, Group, Flags<[CoreOption, NoXarchOption, HelpHidden]>, +#ifdef ENABLE_CLASSIC_FLANG + HelpText<"Set the driver mode to either 'gcc', 'g++', 'cpp', 'cl', or 'fortran'">; +#else HelpText<"Set the driver mode to either 'gcc', 'g++', 'cpp', or 'cl'">; +#endif def rsp_quoting : Joined<["--"], "rsp-quoting=">, Group, Flags<[CoreOption, NoXarchOption, HelpHidden]>, HelpText<"Set the rsp quoting to either 'posix', or 'windows'">; @@ -2640,10 +2644,17 @@ def fno_experimental_isel : Flag<["-"], "fno-experimental-isel">, Group; def fveclib : Joined<["-"], "fveclib=">, Group, Flags<[CC1Option]>, HelpText<"Use the given vector functions library">, +#ifdef ENABLE_CLASSIC_FLANG + Values<"Accelerate,libmvec,MASSV,PGMATH,SVML,SLEEF,Darwin_libsystem_m,ArmPL,none">, + NormalizedValuesScope<"CodeGenOptions">, + NormalizedValues<["Accelerate", "LIBMVEC", "MASSV", "PGMATH", "SVML", "SLEEF", + "Darwin_libsystem_m", "ArmPL", "NoLibrary"]>, +#else Values<"Accelerate,libmvec,MASSV,SVML,SLEEF,Darwin_libsystem_m,ArmPL,none">, NormalizedValuesScope<"CodeGenOptions">, NormalizedValues<["Accelerate", "LIBMVEC", "MASSV", "SVML", "SLEEF", "Darwin_libsystem_m", "ArmPL", "NoLibrary"]>, +#endif MarshallingInfoEnum, "NoLibrary">; def fno_lax_vector_conversions : Flag<["-"], "fno-lax-vector-conversions">, Group, Alias, AliasArgs<["none"]>; @@ -5382,6 +5393,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, @@ -5391,26 +5416,38 @@ 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 fopenacc : Flag<["-"], "fopenacc">, Group, HelpText<"Enable OpenACC">; def fdefault_double_8 : Flag<["-"],"fdefault-double-8">, Group, HelpText<"Set the default double precision 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_integer_8 : Flag<["-"],"fdefault-integer-8">, Group, HelpText<"Set the default integer and logical kind to an 8 byte wide type">; 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 flarge_sizes : Flag<["-"],"flarge-sizes">, Group, HelpText<"Use INTEGER(KIND=8) for the result type in size-related intrinsics">; - def falternative_parameter_statement : Flag<["-"], "falternative-parameter-statement">, Group, HelpText<"Enable the old style PARAMETER statement">; def fintrinsic_modules_path : Separate<["-"], "fintrinsic-modules-path">, Group, MetaVarName<"">, HelpText<"Specify where to find the compiled intrinsic modules">, 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; +#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">; @@ -5419,6 +5456,7 @@ defm underscoring : OptInFC1FFlag<"underscoring", "Appends one trailing undersco def fno_automatic : Flag<["-"], "fno-automatic">, Group, HelpText<"Implies the SAVE attribute for non-automatic local objects in subprograms unless RECURSIVE">; +#endif defm stack_arrays : BoolOptionWithoutMarshalling<"f", "stack-arrays", PosFlag, @@ -5426,12 +5464,19 @@ defm stack_arrays : BoolOptionWithoutMarshalling<"f", "stack-arrays", defm loop_versioning : BoolOptionWithoutMarshalling<"f", "version-loops-for-stride", PosFlag, NegFlag>; + } // let Flags = [FC1Option, FlangOption, FlangOnlyOption] +#ifdef ENABLE_CLASSIC_FLANG +def J : JoinedOrSeparate<["-"], "J">, + Flags<[RenderJoined]>, + Group; +#else def J : JoinedOrSeparate<["-"], "J">, Flags<[RenderJoined, FlangOption, FC1Option, FlangOnlyOption]>, Group, Alias; +#endif //===----------------------------------------------------------------------===// // FC1 Options @@ -7458,6 +7503,147 @@ def fcgl : DXCFlag<"fcgl">, Alias; def enable_16bit_types : DXCFlag<"enable-16bit-types">, Alias, HelpText<"Enable 16-bit types and disable min precision types." "Available in HLSL 2018 and shader model 6.2.">; + +#ifdef ENABLE_CLASSIC_FLANG +// gfortran options that we recognize in the driver and pass along when +// invoking GCC 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>; +} + +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 no_fortran_main: Flag<["-"], "fno-fortran-main">, Group, + HelpText<"Don't link in Fortran main">; +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; +#endif def hlsl_entrypoint : Option<["-"], "hlsl-entry", KIND_SEPARATE>, Group, Flags<[CC1Option]>, diff --git a/clang/include/clang/Driver/Phases.h b/clang/include/clang/Driver/Phases.h index 9003c5857351..f8cac9548d02 100644 --- a/clang/include/clang/Driver/Phases.h +++ b/clang/include/clang/Driver/Phases.h @@ -17,6 +17,7 @@ namespace phases { enum ID { Preprocess, Precompile, + FortranFrontend, Compile, Backend, Assemble, diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h index 2e74507f7126..7603b12eec64 100644 --- a/clang/include/clang/Driver/ToolChain.h +++ b/clang/include/clang/Driver/ToolChain.h @@ -151,6 +151,7 @@ private: mutable std::unique_ptr Clang; mutable std::unique_ptr Flang; + mutable std::unique_ptr FortranFrontend; mutable std::unique_ptr Assemble; mutable std::unique_ptr Link; mutable std::unique_ptr StaticLibTool; @@ -161,6 +162,7 @@ private: Tool *getClang() const; Tool *getFlang() const; + Tool *getFortranFrontend() const; Tool *getAssemble() const; Tool *getLink() const; Tool *getStaticLibTool() const; @@ -651,6 +653,14 @@ public: AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const; + /// \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 { } + /// Add options that need to be passed to cc1 for this target. virtual void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, @@ -757,6 +767,11 @@ public: virtual void AddHIPRuntimeLibArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const {} + /// 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; + /// 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 aaea3ec0f9c8..3085927e3680 100644 --- a/clang/include/clang/Driver/Types.def +++ b/clang/include/clang/Driver/Types.def @@ -77,8 +77,15 @@ TYPE("c++-module-cpp-output", PP_CXXModule, INVALID, "iim", phases TYPE("ada", Ada, INVALID, nullptr, phases::Compile, phases::Backend, phases::Assemble, phases::Link) TYPE("assembler", PP_Asm, INVALID, "s", phases::Assemble, phases::Link) TYPE("assembler-with-cpp", Asm, PP_Asm, "S", phases::Preprocess, phases::Assemble, phases::Link) +#ifdef ENABLE_CLASSIC_FLANG +TYPE("f77", PP_F_FixedForm, INVALID, "f", phases::FortranFrontend, phases::Backend, phases::Assemble, phases::Link) +TYPE("f77-cpp-input", F_FixedForm, PP_F_FixedForm, "F", phases::FortranFrontend, phases::Backend, phases::Assemble, phases::Link) +TYPE("f95", PP_F_FreeForm, INVALID, "f95", phases::FortranFrontend, phases::Backend, phases::Assemble, phases::Link) +TYPE("f95-cpp-input", F_FreeForm, PP_F_FreeForm, "F95", phases::FortranFrontend, phases::Backend, phases::Assemble, phases::Link) +#else TYPE("f95", PP_Fortran, INVALID, "i", 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 4a21af3534de..3a8b785a4c39 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 143cf4359f00..f9a7e25c0049 100644 --- a/clang/include/clang/Frontend/Utils.h +++ b/clang/include/clang/Frontend/Utils.h @@ -17,6 +17,7 @@ #include "clang/Basic/LLVM.h" #include "clang/Driver/OptionUtils.h" #include "clang/Frontend/DependencyOutputOptions.h" +#include "clang/Basic/TargetInfo.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/StringMap.h" @@ -31,6 +32,12 @@ #include #include +namespace llvm { + +class StringRef; + +} // namespace llvm + namespace clang { class ASTReader; @@ -39,6 +46,7 @@ class CompilerInvocation; class DiagnosticsEngine; class ExternalSemaSource; class FrontendOptions; +class MacroBuilder; class PCHContainerReader; class Preprocessor; class PreprocessorOptions; @@ -54,6 +62,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 483f3e787a78..f962d60870d1 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -272,6 +272,12 @@ static TargetLibraryInfoImpl *createTLII(llvm::Triple &TargetTriple, TLII->addVectorizableFunctionsFromVecLib(TargetLibraryInfoImpl::MASSV, TargetTriple); break; +#ifdef ENABLE_CLASSIC_FLANG + case CodeGenOptions::PGMATH: + TLII->addVectorizableFunctionsFromVecLib(TargetLibraryInfoImpl::PGMATH, + TargetTriple); + break; +#endif case CodeGenOptions::SVML: TLII->addVectorizableFunctionsFromVecLib(TargetLibraryInfoImpl::SVML, TargetTriple); diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index d8eb2aecb87a..3b140860cce4 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -3980,7 +3980,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())), @@ -5467,7 +5468,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); @@ -5563,7 +5564,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, @@ -5581,7 +5582,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/Action.cpp b/clang/lib/Driver/Action.cpp index 849bf6035ebd..e81dbebd1db3 100644 --- a/clang/lib/Driver/Action.cpp +++ b/clang/lib/Driver/Action.cpp @@ -29,6 +29,7 @@ const char *Action::getClassName(ActionClass AC) { return "api-extractor"; case AnalyzeJobClass: return "analyzer"; case MigrateJobClass: return "migrator"; + case FortranFrontendJobClass: return "fortran-frontend"; case CompileJobClass: return "compiler"; case BackendJobClass: return "backend"; case AssembleJobClass: return "assembler"; @@ -372,6 +373,12 @@ void MigrateJobAction::anchor() {} MigrateJobAction::MigrateJobAction(Action *Input, types::ID OutputType) : JobAction(MigrateJobClass, Input, OutputType) {} +void FortranFrontendJobAction::anchor() {} + +FortranFrontendJobAction::FortranFrontendJobAction(Action *Input, + types::ID OutputType) + : JobAction(FortranFrontendJobClass, Input, OutputType) {} + void CompileJobAction::anchor() {} CompileJobAction::CompileJobAction(Action *Input, types::ID OutputType) diff --git a/clang/lib/Driver/CMakeLists.txt b/clang/lib/Driver/CMakeLists.txt index a6bd2d41e797..1b4df4db0a08 100644 --- a/clang/lib/Driver/CMakeLists.txt +++ b/clang/lib/Driver/CMakeLists.txt @@ -14,6 +14,10 @@ if(WIN32) set(system_libs version) endif() +if(LLVM_ENABLE_CLASSIC_FLANG) + set(CLASSIC_FLANG_FILES ToolChains/ClassicFlang.cpp) +endif() + add_clang_library(clangDriver Action.cpp Compilation.cpp @@ -92,6 +96,7 @@ add_clang_library(clangDriver ToolChains/ZOS.cpp Types.cpp XRayArgs.cpp + ${CLASSIC_FLANG_FILES} DEPENDS ClangDriverOptions diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index a7e4edb3ab5a..3fafd43384e1 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -363,11 +363,30 @@ phases::ID Driver::getFinalPhase(const DerivedArgList &DAL, // -{E,EP,P,M,MM} only run the preprocessor. if (CCCIsCPP() || (PhaseArg = DAL.getLastArg(options::OPT_E)) || +#ifdef ENABLE_CLASSIC_FLANG + (PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) || +#endif (PhaseArg = DAL.getLastArg(options::OPT__SLASH_EP)) || (PhaseArg = DAL.getLastArg(options::OPT_M, options::OPT_MM)) || (PhaseArg = DAL.getLastArg(options::OPT__SLASH_P)) || CCGenDiagnostics) { +#ifdef ENABLE_CLASSIC_FLANG + // -fsyntax-only or -E stops Fortran compilation after FortranFrontend + if (IsFlangMode() && (DAL.getLastArg(options::OPT_E) || + DAL.getLastArg(options::OPT_fsyntax_only))) { + FinalPhase = phases::FortranFrontend; + + // if not Fortran, fsyntax_only implies 'Compile' is the FinalPhase + } else if (DAL.getLastArg(options::OPT_fsyntax_only)) { + FinalPhase = phases::Compile; + + // everything else has 'Preprocess' as its FinalPhase + } else { + FinalPhase = phases::Preprocess; + } +#else FinalPhase = phases::Preprocess; +#endif // --precompile only runs up to precompilation. // Options that cause the output of C++20 compiled module interfaces or @@ -377,9 +396,15 @@ phases::ID Driver::getFinalPhase(const DerivedArgList &DAL, (PhaseArg = DAL.getLastArg(options::OPT_fmodule_header, options::OPT_fmodule_header_EQ))) { FinalPhase = phases::Precompile; + +#ifdef ENABLE_CLASSIC_FLANG + // -{analyze,emit-ast} only run up to the compiler. + } else if ((PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) || +#else // -{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)) || +#endif (PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) || (PhaseArg = DAL.getLastArg(options::OPT_verify_pch)) || (PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) || @@ -2665,7 +2690,11 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args, // stdin must be handled specially. if (memcmp(Value, "-", 2) == 0) { if (IsFlangMode()) { +#ifdef ENABLE_CLASSIC_FLANG + Ty = types::TY_C; +#else Ty = types::TY_Fortran; +#endif } else { // If running with -E, treat as a C input (this changes the // builtin macros, for example). This may be overridden by -ObjC @@ -4011,6 +4040,11 @@ void Driver::handleArguments(Compilation &C, DerivedArgList &Args, if (InputArg->isClaimed()) continue; + // Fortran input is preprocessed using the frontend. + if (InitialPhase == phases::FortranFrontend && + FinalPhase == phases::Preprocess) + continue; + // Claim here to avoid the more general unused warning. InputArg->claim(); @@ -4725,6 +4759,13 @@ Action *Driver::ConstructPhaseAction( return C.MakeAction(Input, OutputTy); } + case phases::FortranFrontend: { + if (Args.hasArg(options::OPT_fsyntax_only)) + return C.MakeAction(Input, + types::TY_Nothing); + return C.MakeAction(Input, + types::TY_LLVM_IR); + } case phases::Compile: { if (Args.hasArg(options::OPT_fsyntax_only)) return C.MakeAction(Input, types::TY_Nothing); diff --git a/clang/lib/Driver/OffloadBundler.cpp b/clang/lib/Driver/OffloadBundler.cpp index 0ddfb07fdad5..acc4e9128cb1 100644 --- a/clang/lib/Driver/OffloadBundler.cpp +++ b/clang/lib/Driver/OffloadBundler.cpp @@ -864,6 +864,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/Phases.cpp b/clang/lib/Driver/Phases.cpp index 01598c59bd9e..f0216c5ab7c2 100644 --- a/clang/lib/Driver/Phases.cpp +++ b/clang/lib/Driver/Phases.cpp @@ -16,6 +16,7 @@ const char *phases::getPhaseName(ID Id) { switch (Id) { case Preprocess: return "preprocessor"; case Precompile: return "precompiler"; + case FortranFrontend: return "fortran-frontend"; case Compile: return "compiler"; case Backend: return "backend"; case Assemble: return "assembler"; diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index 0146d8af3549..dc5ab1d8f2ce 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -10,6 +10,9 @@ #include "ToolChains/Arch/AArch64.h" #include "ToolChains/Arch/ARM.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" @@ -463,6 +466,16 @@ Tool *ToolChain::getAssemble() const { return Assemble.get(); } +Tool *ToolChain::getFortranFrontend() const { +#ifdef ENABLE_CLASSIC_FLANG + if (!FortranFrontend) + FortranFrontend.reset(new tools::ClassicFlang(*this)); + return FortranFrontend.get(); +#else + llvm_unreachable("Fortran is not supported by this toolchain"); +#endif +} + Tool *ToolChain::getClangAs() const { if (!Assemble) Assemble.reset(new tools::ClangAs(*this)); @@ -546,6 +559,9 @@ Tool *ToolChain::getTool(Action::ActionClass AC) const { return getOffloadPackager(); case Action::LinkerWrapperJobClass: return getLinkerWrapper(); + + case Action::FortranFrontendJobClass: + return getFortranFrontend(); } llvm_unreachable("Invalid tool kind."); @@ -864,13 +880,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; } @@ -1223,6 +1239,45 @@ void ToolChain::AddCCKextLibArgs(const ArgList &Args, CmdArgs.push_back("-lcc_kext"); } +void ToolChain::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 (staticFlangLibs) + CmdArgs.push_back("-Bstatic"); + CmdArgs.push_back("-lflang"); + CmdArgs.push_back("-lflangrti"); + CmdArgs.push_back("-lpgmath"); + if (useOpenMP) + CmdArgs.push_back("-lomp"); + else + CmdArgs.push_back("-lompstub"); + if (staticFlangLibs) + CmdArgs.push_back("-Bdynamic"); + + CmdArgs.push_back("-lm"); + CmdArgs.push_back("-lrt"); + + // Allways link Fortran executables with Pthreads + CmdArgs.push_back("-lpthread"); +} + bool ToolChain::isFastMathRuntimeAvailable(const ArgList &Args, std::string &Path) const { // Do not check for -fno-fast-math or -fno-unsafe-math when -Ofast passed diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 793af55a1e5f..3cd4089c917b 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -5367,6 +5367,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 (const StringRef &val : A->getValues()) { + if (val.equals("all")) { + PassRemarkVal = ".*"; + break; + } else if (val.equals("inline") || val.equals("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 (const StringRef &val : A->getValues()) { + if (val.equals("all")) { + PassRemarkVal = ".*"; + break; + } else if (val.equals("inline") || val.equals("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..9573ac2dde09 --- /dev/null +++ b/clang/lib/Driver/ToolChains/ClassicFlang.cpp @@ -0,0 +1,1067 @@ +//===-- 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/TargetParser.h" +#include "llvm/Support/YAMLParser.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") { + 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 { + ArgStringList CommonCmdArgs; + ArgStringList UpperCmdArgs; + ArgStringList LowerCmdArgs; + SmallString<256> Stem; + std::string OutFile; + bool NeedIEEE = false; + bool NeedFastMath = false; + bool NeedRelaxedMath = false; + + // 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)) { + // For -fsyntax-only produce temp files only + Stem = C.getDriver().GetTemporaryPath("", ""); + } else { + OutFile = Output.getFilename(); + Stem = llvm::sys::path::filename(OutFile); + llvm::sys::path::replace_extension(Stem, ""); + } + + // 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 (const StringRef &val : A->getValues()) { + if (val.equals("discontiguous") || val.equals("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.equals("discontiguous")) + A->claim(); + break; + } + } + } + + // Treat backslashes as regular characters + for (auto Arg : Args.filtered(options::OPT_fno_backslash, options::OPT_Mbackslash)) { + Arg->claim(); + CommonCmdArgs.push_back("-x"); + CommonCmdArgs.push_back("124"); + CommonCmdArgs.push_back("0x40"); + } + + // Treat backslashes as C-style escape characters + for (auto Arg : Args.filtered(options::OPT_fbackslash, options::OPT_Mnobackslash)) { + Arg->claim(); + CommonCmdArgs.push_back("-y"); + 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"); + } + + // -g should produce DWARFv2 + for (auto Arg : Args.filtered(options::OPT_g_Flag)) { + Arg->claim(); + CommonCmdArgs.push_back("-x"); + CommonCmdArgs.push_back("120"); + CommonCmdArgs.push_back("0x200"); + } + + // -gdwarf-2 + for (auto Arg : Args.filtered(options::OPT_gdwarf_2)) { + Arg->claim(); + CommonCmdArgs.push_back("-x"); + CommonCmdArgs.push_back("120"); + CommonCmdArgs.push_back("0x200"); + } + + // -gdwarf-3 + for (auto Arg : Args.filtered(options::OPT_gdwarf_3)) { + Arg->claim(); + CommonCmdArgs.push_back("-x"); + CommonCmdArgs.push_back("120"); + CommonCmdArgs.push_back("0x4000"); + } + + // -Mipa has no effect + if (Arg *A = Args.getLastArg(options::OPT_Mipa)) { + getToolChain().getDriver().Diag(diag::warn_drv_clang_unsupported) + << A->getAsString(Args); + } + + // -Minline has no effect + if (Arg *A = Args.getLastArg(options::OPT_Minline_on)) { + getToolChain().getDriver().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_default_real_8_fno)) { + const char * fl; + // For -f version add -x flag, for -fno add -y + if (A->getOption().matches(options::OPT_default_real_8_fno)) { + fl = "-y"; + } else { + fl = "-x"; + } + + for (Arg *A : Args.filtered(options::OPT_r8, + options::OPT_fdefault_real_8, + options::OPT_default_real_8_fno)) { + 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_default_integer_8_fno)) { + const char * fl; + + if (A->getOption().matches(options::OPT_default_integer_8_fno)) { + fl = "-y"; + } else { + fl = "-x"; + } + + for (Arg *A : Args.filtered(options::OPT_i8, + options::OPT_fdefault_integer_8, + options::OPT_default_integer_8_fno)) { + 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(); + } + } + + // Enable FMA + for (Arg *A: Args.filtered(options::OPT_Mfma_on, options::OPT_fma)) { + A->claim(); + LowerCmdArgs.push_back("-x"); + LowerCmdArgs.push_back("172"); + LowerCmdArgs.push_back("0x40000000"); + LowerCmdArgs.push_back("-x"); + LowerCmdArgs.push_back("179"); + LowerCmdArgs.push_back("1"); + } + + // Disable FMA + for (Arg *A: Args.filtered(options::OPT_Mfma_off, options::OPT_nofma)) { + A->claim(); + LowerCmdArgs.push_back("-x"); + LowerCmdArgs.push_back("171"); + LowerCmdArgs.push_back("0x40000000"); + LowerCmdArgs.push_back("-x"); + LowerCmdArgs.push_back("178"); + LowerCmdArgs.push_back("1"); + } + + // 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)) { + 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 = false; + NeedIEEE = 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; + } + A->claim(); + } + + if (NeedFastMath) { + // Lower: -x 216 1 + LowerCmdArgs.push_back("-x"); + LowerCmdArgs.push_back("216"); + LowerCmdArgs.push_back("1"); + // Lower: -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"); + // Lower: -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"); + // Lower: -ieee 0 + CommonCmdArgs.push_back("-ieee"); + CommonCmdArgs.push_back("0"); + } else { + // Lower: -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? + const char *UpperExec = Args.MakeArgString(getToolChain().GetProgramPath("flang1")); + + 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 = getToolChain().getEffectiveTriple().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(&getToolChain().getDriver(), 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 (getToolChain().getEffectiveTriple().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_free_form_off: + 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_fixed_form_off: + 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 { + getToolChain().getDriver().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 { + getToolChain().getDriver().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 *****/ + + const char *LowerExec = Args.MakeArgString(getToolChain().GetProgramPath("flang2")); + + // 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("150"); // 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"); + + // Remove "noinline" attriblute + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("183"); LowerCmdArgs.push_back("0x10"); + + // 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)); + } + + 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..23ea1fe6b95d --- /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/Basic/DebugInfoOptions.h" +#include "clang/Driver/Driver.h" +#include "clang/Driver/Tool.h" +#include "clang/Driver/Types.h" +#include "llvm/ADT/Triple.h" +#include "llvm/Option/Option.h" +#include "llvm/Support/raw_ostream.h" + +namespace clang { +namespace driver { + +namespace tools { + +/// \brief Flang Fortran frontend +class LLVM_LIBRARY_VISIBILITY ClassicFlang : public Tool { +public: + ClassicFlang(const ToolChain &TC) + : Tool("flang:frontend", + "Fortran frontend to LLVM", TC) {} + + bool hasGoodDiagnostics() const override { return true; } + bool hasIntegratedAssembler() const override { return false; } + bool hasIntegratedCPP() const override { return false; } + + 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 0d6907b8e5c7..f79dd847a3e5 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -146,6 +146,23 @@ static bool shouldIgnoreUnsupportedTargetFeature(const Arg &TargetFeatureArg, return TargetFeatureArg.getOption().matches(options::OPT_mno_cumode); } +/// \brief Determine if Fortran "main" object is needed +static bool 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) { + if (D.IsFlangMode() && !Args.hasArg(options::OPT_nostdlib) && + !Args.hasArg(options::OPT_noFlangLibs)) { + return true; + } + + return false; +} + void tools::addPathIfExists(const Driver &D, const Twine &Path, ToolChain::path_list &Paths) { if (D.getVFS().exists(Path)) @@ -256,6 +273,7 @@ void tools::AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs, const ArgList &Args, ArgStringList &CmdArgs, const JobAction &JA) { const Driver &D = TC.getDriver(); + bool SeenFirstLinkerInput = false; // Add extra linker input arguments which are not treated as inputs // (constructed via -Xarch_). @@ -289,6 +307,14 @@ void tools::AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs, if (II.isNothing()) continue; + // Add Fortan "main" before the first linker input + if (!SeenFirstLinkerInput) { + if (needFortranMain(D, Args)) { + CmdArgs.push_back("-lflangmain"); + } + SeenFirstLinkerInput = true; + } + // Otherwise, this is a linker input argument. const Arg &A = II.getInputArg(); @@ -300,6 +326,15 @@ void tools::AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs, else A.renderAsInput(Args, CmdArgs); } + + 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(); + } } void tools::addLinkerCompressDebugSectionsOption( diff --git a/clang/lib/Driver/ToolChains/CommonArgs.h b/clang/lib/Driver/ToolChains/CommonArgs.h index 6a8de0f1c36d..c149ae57a2ee 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.h +++ b/clang/lib/Driver/ToolChains/CommonArgs.h @@ -23,6 +23,8 @@ namespace clang { namespace driver { namespace tools { +bool needFortranLibs(const Driver &D, const llvm::opt::ArgList &Args); + void addPathIfExists(const Driver &D, const Twine &Path, ToolChain::path_list &Paths); diff --git a/clang/lib/Driver/ToolChains/Cuda.cpp b/clang/lib/Driver/ToolChains/Cuda.cpp index 3a577650eb08..f4b8a6ae437e 100644 --- a/clang/lib/Driver/ToolChains/Cuda.cpp +++ b/clang/lib/Driver/ToolChains/Cuda.cpp @@ -1034,3 +1034,36 @@ VersionTuple CudaToolChain::computeMSVCVersion(const Driver *D, const ArgList &Args) const { return HostTC.computeMSVCVersion(D, Args); } + +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.InstalledDir); + llvm::sys::path::append(P, "../include"); + IncludePathList.push_back(P.c_str()); + AddFlangSysIncludeArg(DriverArgs, Flang1Args, IncludePathList); +} diff --git a/clang/lib/Driver/ToolChains/Cuda.h b/clang/lib/Driver/ToolChains/Cuda.h index 39df6e06fb26..7e8eb6cb81c6 100644 --- a/clang/lib/Driver/ToolChains/Cuda.h +++ b/clang/lib/Driver/ToolChains/Cuda.h @@ -223,6 +223,12 @@ public: const ToolChain &HostTC; +#ifdef ENABLE_CLASSIC_FLANG + void + AddFlangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &Flang1Args) const override; +#endif + /// Uses nvptx-arch tool to get arch of the system GPU. Will return error /// if unable to find one. virtual Expected> diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp index 0bb5433a658a..14a9bc56c88f 100644 --- a/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/clang/lib/Driver/ToolChains/Gnu.cpp @@ -554,6 +554,16 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, // The profile runtime also needs access to system libraries. getToolChain().addProfileRTLibs(Args, CmdArgs); + // Add Fortran runtime libraries + if (needFortranLibs(D, Args)) { + ToolChain.AddFortranStdlibLibArgs(Args, CmdArgs); + } else { + // Claim "no Flang libraries" arguments if any + for (auto Arg : Args.filtered(options::OPT_noFlangLibs)) { + Arg->claim(); + } + } + if (D.CCCIsCXX() && !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs, options::OPT_r)) { diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp index 1ba222bf83b1..833d019ff156 100644 --- a/clang/lib/Driver/ToolChains/Linux.cpp +++ b/clang/lib/Driver/ToolChains/Linux.cpp @@ -608,6 +608,194 @@ std::string Linux::getDynamicLinker(const ArgList &Args) const { return "/" + LibDir + "/" + Loader; } +/// 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.InstalledDir); + 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); +} + 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 524391743090..0f6122b8cee1 100644 --- a/clang/lib/Driver/ToolChains/Linux.h +++ b/clang/lib/Driver/ToolChains/Linux.h @@ -28,6 +28,9 @@ public: StringRef SysRoot) const override; void + AddFlangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &Flang1Args) const override; + void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; void addLibStdCxxIncludePaths( diff --git a/clang/lib/Driver/Types.cpp b/clang/lib/Driver/Types.cpp old mode 100644 new mode 100755 index 7d6308d757bc..57e050e576f0 --- a/clang/lib/Driver/Types.cpp +++ b/clang/lib/Driver/Types.cpp @@ -55,9 +55,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; } @@ -134,6 +136,10 @@ bool types::isAcceptedByClang(ID Id) { case TY_Asm: case TY_C: case TY_PP_C: case TY_CL: case TY_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: @@ -164,8 +170,15 @@ 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: +#else case TY_Fortran: case TY_PP_Fortran: +#endif return true; case TY_LLVM_IR: case TY_LLVM_BC: @@ -286,6 +299,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) { @@ -296,8 +325,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) @@ -331,6 +365,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) @@ -343,6 +391,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 f8fae82fba12..7b01cb01a45e 100644 --- a/clang/lib/Frontend/InitPreprocessor.cpp +++ b/clang/lib/Frontend/InitPreprocessor.cpp @@ -161,26 +161,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 Twine &Prefix, TargetInfo::IntType Ty, const TargetInfo &TI, MacroBuilder &Builder) { bool IsSigned = TI.isTypeSigned(Ty); diff --git a/clang/test/Driver/autocomplete.c b/clang/test/Driver/autocomplete.c index d6f57708b67e..8c4921c9dbd5 100644 --- a/clang/test/Driver/autocomplete.c +++ b/clang/test/Driver/autocomplete.c @@ -85,7 +85,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/flang/classic_flang.f95 b/clang/test/Driver/flang/classic_flang.f95 new file mode 100644 index 000000000000..5d3098786905 --- /dev/null +++ b/clang/test/Driver/flang/classic_flang.f95 @@ -0,0 +1,28 @@ +! Check that the driver can invoke flang1 and flang2 to compile Fortran with +! --driver-mode=flang (default when the file extension is .f95). + +! REQUIRES: 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: flang1 +! CHECK-OBJECT: flang2 +! CHECK-OBJECT-SAME: "-asm" [[LLFILE:.*.ll]] +! CHECK-OBJECT-NOT: cc1as +! CHECK-OBJECT: clang +! CHECK-OBJECT-SAME: -cc1 +! CHECK-OBJECT-SAME: "-o" "classic_flang.o" +! CHECK-OBJECT-SAME: "-x" "ir" +! CHECK-OBJECT-SAME: [[LLFILE]] + +! RUN: %clang -target x86_64-unknown-linux-gnu -integrated-as -S %s -### 2>&1 \ +! RUN: | FileCheck --check-prefix=CHECK-ASM %s +! CHECK-ASM: flang1 +! CHECK-ASM: flang2 +! CHECK-ASM-SAME: "-asm" [[LLFILE:.*.ll]] +! CHECK-ASM-NOT: cc1as +! CHECK-ASM: clang +! CHECK-ASM-SAME: -cc1 +! CHECK-ASM-SAME: "-o" "classic_flang.s" +! CHECK-ASM-SAME: "-x" "ir" +! CHECK-ASM-SAME: [[LLFILE]] diff --git a/clang/test/Driver/flang/flang.f90 b/clang/test/Driver/flang/flang.f90 index 5d8edf6308b0..8caa45f6342c 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 50305ee337e1..21f7c469144b 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/multiple-inputs-mixed.f90 b/clang/test/Driver/flang/multiple-inputs-mixed.f90 index 2395dbecf1fe..8f3918f7cb21 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-new{{[^"/]*}}" "-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 ada999e927a6..4068ac3a0966 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-new{{[^"/]*}}" "-fc1" ! CHECK-SYNTAX-ONLY: "{{[^"]*}}/Inputs/one.f90" diff --git a/clang/test/Driver/fortran.f95 b/clang/test/Driver/fortran.f95 index db3ff2da17e8..e364180a1f9c 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/lit.cfg.py b/clang/test/lit.cfg.py index 68e038475a5c..bb6fb1ae5146 100644 --- a/clang/test/lit.cfg.py +++ b/clang/test/lit.cfg.py @@ -395,3 +395,6 @@ if "system-aix" in config.available_features: # 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") diff --git a/clang/test/lit.site.cfg.py.in b/clang/test/lit.site.cfg.py.in index ef75770a2c3c..bc278740e0d0 100644 --- a/clang/test/lit.site.cfg.py.in +++ b/clang/test/lit.site.cfg.py.in @@ -41,6 +41,7 @@ config.llvm_external_lit = path(r"@LLVM_EXTERNAL_LIT@") 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.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 2182486f93a5..c269561fde69 100644 --- a/clang/tools/driver/CMakeLists.txt +++ b/clang/tools/driver/CMakeLists.txt @@ -59,7 +59,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/llvm/cmake/modules/HandleLLVMOptions.cmake b/llvm/cmake/modules/HandleLLVMOptions.cmake index 76723be696e5..492ea25b179b 100644 --- a/llvm/cmake/modules/HandleLLVMOptions.cmake +++ b/llvm/cmake/modules/HandleLLVMOptions.cmake @@ -89,6 +89,14 @@ if( LLVM_ENABLE_ASSERTIONS ) add_compile_definitions(_LIBCPP_ENABLE_HARDENED_MODE) 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(LLVM_ENABLE_EXPENSIVE_CHECKS) add_compile_definitions(EXPENSIVE_CHECKS) diff --git a/llvm/include/llvm-c/DebugInfo.h b/llvm/include/llvm-c/DebugInfo.h index 5924294708cc..09d584c24711 100644 --- a/llvm/include/llvm-c/DebugInfo.h +++ b/llvm/include/llvm-c/DebugInfo.h @@ -1148,7 +1148,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); /** @@ -1246,7 +1247,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); /** * Insert a new llvm.dbg.declare intrinsic call before the given instruction. diff --git a/llvm/include/llvm/Analysis/TargetLibraryInfo.h b/llvm/include/llvm/Analysis/TargetLibraryInfo.h index 5d62e837c1f3..94fd912d50c9 100644 --- a/llvm/include/llvm/Analysis/TargetLibraryInfo.h +++ b/llvm/include/llvm/Analysis/TargetLibraryInfo.h @@ -95,6 +95,9 @@ public: 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. +#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/IR/DIBuilder.h b/llvm/include/llvm/IR/DIBuilder.h index ecd6dd7b0a4f..e0e64c662f18 100644 --- a/llvm/include/llvm/IR/DIBuilder.h +++ b/llvm/include/llvm/IR/DIBuilder.h @@ -681,15 +681,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. @@ -820,6 +827,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 656122405209..9bd86172a4c0 100644 --- a/llvm/include/llvm/IR/DebugInfoMetadata.h +++ b/llvm/include/llvm/IR/DebugInfoMetadata.h @@ -3062,12 +3062,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 * @@ -3075,12 +3077,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 * @@ -3088,14 +3090,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()); } @@ -3105,22 +3107,26 @@ public: (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 05fa67d0bbf1..4ad200e5ce6e 100644 --- a/llvm/lib/Analysis/TargetLibraryInfo.cpp +++ b/llvm/lib/Analysis/TargetLibraryInfo.cpp @@ -30,6 +30,10 @@ 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"), +#endif clEnumValN(TargetLibraryInfoImpl::SVML, "SVML", "Intel SVML library"), clEnumValN(TargetLibraryInfoImpl::SLEEFGNUABI, "sleefgnuabi", @@ -1234,6 +1238,457 @@ void TargetLibraryInfoImpl::addVectorizableFunctionsFromVecLib( } 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: { + const VecDesc VecFuncs[] = { + {"__fd_sin_1", "__fd_sin_2", FIXED(2)}, + {"__fd_sin_1", "__fd_sin_4", FIXED(4)}, + {"__fd_sin_1", "__fd_sin_8", FIXED(8)}, + + {"__fs_sin_1", "__fs_sin_4", FIXED(4)}, + {"__fs_sin_1", "__fs_sin_8", FIXED(8)}, + {"__fs_sin_1", "__fs_sin_16", FIXED(16)}, + + {"__pd_sin_1", "__pd_sin_2", FIXED(2)}, + {"__pd_sin_1", "__pd_sin_4", FIXED(4)}, + {"__pd_sin_1", "__pd_sin_8", FIXED(8)}, + + {"__ps_sin_1", "__ps_sin_4", FIXED(4)}, + {"__ps_sin_1", "__ps_sin_8", FIXED(8)}, + {"__ps_sin_1", "__ps_sin_16", FIXED(16)}, + + {"__rd_sin_1", "__rd_sin_2", FIXED(2)}, + {"__rd_sin_1", "__rd_sin_4", FIXED(4)}, + {"__rd_sin_1", "__rd_sin_8", FIXED(8)}, + + {"__rs_sin_1", "__rs_sin_4", FIXED(4)}, + {"__rs_sin_1", "__rs_sin_8", FIXED(8)}, + {"__rs_sin_1", "__rs_sin_16", FIXED(16)}, + + {"__fd_cos_1", "__fd_cos_2", FIXED(2)}, + {"__fd_cos_1", "__fd_cos_4", FIXED(4)}, + {"__fd_cos_1", "__fd_cos_8", FIXED(8)}, + + {"__fs_cos_1", "__fs_cos_4", FIXED(4)}, + {"__fs_cos_1", "__fs_cos_8", FIXED(8)}, + {"__fs_cos_1", "__fs_cos_16", FIXED(16)}, + + {"__pd_cos_1", "__pd_cos_2", FIXED(2)}, + {"__pd_cos_1", "__pd_cos_4", FIXED(4)}, + {"__pd_cos_1", "__pd_cos_8", FIXED(8)}, + + {"__ps_cos_1", "__ps_cos_4", FIXED(4)}, + {"__ps_cos_1", "__ps_cos_8", FIXED(8)}, + {"__ps_cos_1", "__ps_cos_16", FIXED(16)}, + + {"__rd_cos_1", "__rd_cos_2", FIXED(2)}, + {"__rd_cos_1", "__rd_cos_4", FIXED(4)}, + {"__rd_cos_1", "__rd_cos_8", FIXED(8)}, + + {"__rs_cos_1", "__rs_cos_4", FIXED(4)}, + {"__rs_cos_1", "__rs_cos_8", FIXED(8)}, + {"__rs_cos_1", "__rs_cos_16", FIXED(16)}, + + {"__fd_sincos_1", "__fd_sincos_2", FIXED(2)}, + {"__fd_sincos_1", "__fd_sincos_4", FIXED(4)}, + {"__fd_sincos_1", "__fd_sincos_8", FIXED(8)}, + + {"__fs_sincos_1", "__fs_sincos_4", FIXED(4)}, + {"__fs_sincos_1", "__fs_sincos_8", FIXED(8)}, + {"__fs_sincos_1", "__fs_sincos_16", FIXED(16)}, + + {"__pd_sincos_1", "__pd_sincos_2", FIXED(2)}, + {"__pd_sincos_1", "__pd_sincos_4", FIXED(4)}, + {"__pd_sincos_1", "__pd_sincos_8", FIXED(8)}, + + {"__ps_sincos_1", "__ps_sincos_4", FIXED(4)}, + {"__ps_sincos_1", "__ps_sincos_8", FIXED(8)}, + {"__ps_sincos_1", "__ps_sincos_16", FIXED(16)}, + + {"__rd_sincos_1", "__rd_sincos_2", FIXED(2)}, + {"__rd_sincos_1", "__rd_sincos_4", FIXED(4)}, + {"__rd_sincos_1", "__rd_sincos_8", FIXED(8)}, + + {"__rs_sincos_1", "__rs_sincos_4", FIXED(4)}, + {"__rs_sincos_1", "__rs_sincos_8", FIXED(8)}, + {"__rs_sincos_1", "__rs_sincos_16", FIXED(16)}, + + {"__fd_tan_1", "__fd_tan_2", FIXED(2)}, + {"__fd_tan_1", "__fd_tan_4", FIXED(4)}, + {"__fd_tan_1", "__fd_tan_8", FIXED(8)}, + + {"__fs_tan_1", "__fs_tan_4", FIXED(4)}, + {"__fs_tan_1", "__fs_tan_8", FIXED(8)}, + {"__fs_tan_1", "__fs_tan_16", FIXED(16)}, + + {"__pd_tan_1", "__pd_tan_2", FIXED(2)}, + {"__pd_tan_1", "__pd_tan_4", FIXED(4)}, + {"__pd_tan_1", "__pd_tan_8", FIXED(8)}, + + {"__ps_tan_1", "__ps_tan_4", FIXED(4)}, + {"__ps_tan_1", "__ps_tan_8", FIXED(8)}, + {"__ps_tan_1", "__ps_tan_16", FIXED(16)}, + + {"__rd_tan_1", "__rd_tan_2", FIXED(2)}, + {"__rd_tan_1", "__rd_tan_4", FIXED(4)}, + {"__rd_tan_1", "__rd_tan_8", FIXED(8)}, + + {"__rs_tan_1", "__rs_tan_4", FIXED(4)}, + {"__rs_tan_1", "__rs_tan_8", FIXED(8)}, + {"__rs_tan_1", "__rs_tan_16", FIXED(16)}, + + {"__fd_sinh_1", "__fd_sinh_2", FIXED(2)}, + {"__fd_sinh_1", "__fd_sinh_4", FIXED(4)}, + {"__fd_sinh_1", "__fd_sinh_8", FIXED(8)}, + + {"__fs_sinh_1", "__fs_sinh_4", FIXED(4)}, + {"__fs_sinh_1", "__fs_sinh_8", FIXED(8)}, + {"__fs_sinh_1", "__fs_sinh_16", FIXED(16)}, + + {"__pd_sinh_1", "__pd_sinh_2", FIXED(2)}, + {"__pd_sinh_1", "__pd_sinh_4", FIXED(4)}, + {"__pd_sinh_1", "__pd_sinh_8", FIXED(8)}, + + {"__ps_sinh_1", "__ps_sinh_4", FIXED(4)}, + {"__ps_sinh_1", "__ps_sinh_8", FIXED(8)}, + {"__ps_sinh_1", "__ps_sinh_16", FIXED(16)}, + + {"__rd_sinh_1", "__rd_sinh_2", FIXED(2)}, + {"__rd_sinh_1", "__rd_sinh_4", FIXED(4)}, + {"__rd_sinh_1", "__rd_sinh_8", FIXED(8)}, + + {"__rs_sinh_1", "__rs_sinh_4", FIXED(4)}, + {"__rs_sinh_1", "__rs_sinh_8", FIXED(8)}, + {"__rs_sinh_1", "__rs_sinh_16", FIXED(16)}, + + {"__fd_cosh_1", "__fd_cosh_2", FIXED(2)}, + {"__fd_cosh_1", "__fd_cosh_4", FIXED(4)}, + {"__fd_cosh_1", "__fd_cosh_8", FIXED(8)}, + + {"__fs_cosh_1", "__fs_cosh_4", FIXED(4)}, + {"__fs_cosh_1", "__fs_cosh_8", FIXED(8)}, + {"__fs_cosh_1", "__fs_cosh_16", FIXED(16)}, + + {"__pd_cosh_1", "__pd_cosh_2", FIXED(2)}, + {"__pd_cosh_1", "__pd_cosh_4", FIXED(4)}, + {"__pd_cosh_1", "__pd_cosh_8", FIXED(8)}, + + {"__ps_cosh_1", "__ps_cosh_4", FIXED(4)}, + {"__ps_cosh_1", "__ps_cosh_8", FIXED(8)}, + {"__ps_cosh_1", "__ps_cosh_16", FIXED(16)}, + + {"__rd_cosh_1", "__rd_cosh_2", FIXED(2)}, + {"__rd_cosh_1", "__rd_cosh_4", FIXED(4)}, + {"__rd_cosh_1", "__rd_cosh_8", FIXED(8)}, + + {"__rs_cosh_1", "__rs_cosh_4", FIXED(4)}, + {"__rs_cosh_1", "__rs_cosh_8", FIXED(8)}, + {"__rs_cosh_1", "__rs_cosh_16", FIXED(16)}, + + {"__fd_tanh_1", "__fd_tanh_2", FIXED(2)}, + {"__fd_tanh_1", "__fd_tanh_4", FIXED(4)}, + {"__fd_tanh_1", "__fd_tanh_8", FIXED(8)}, + + {"__fs_tanh_1", "__fs_tanh_4", FIXED(4)}, + {"__fs_tanh_1", "__fs_tanh_8", FIXED(8)}, + {"__fs_tanh_1", "__fs_tanh_16", FIXED(16)}, + + {"__pd_tanh_1", "__pd_tanh_2", FIXED(2)}, + {"__pd_tanh_1", "__pd_tanh_4", FIXED(4)}, + {"__pd_tanh_1", "__pd_tanh_8", FIXED(8)}, + + {"__ps_tanh_1", "__ps_tanh_4", FIXED(4)}, + {"__ps_tanh_1", "__ps_tanh_8", FIXED(8)}, + {"__ps_tanh_1", "__ps_tanh_16", FIXED(16)}, + + {"__rd_tanh_1", "__rd_tanh_2", FIXED(2)}, + {"__rd_tanh_1", "__rd_tanh_4", FIXED(4)}, + {"__rd_tanh_1", "__rd_tanh_8", FIXED(8)}, + + {"__rs_tanh_1", "__rs_tanh_4", FIXED(4)}, + {"__rs_tanh_1", "__rs_tanh_8", FIXED(8)}, + {"__rs_tanh_1", "__rs_tanh_16", FIXED(16)}, + + {"__fd_asin_1", "__fd_asin_2", FIXED(2)}, + {"__fd_asin_1", "__fd_asin_4", FIXED(4)}, + {"__fd_asin_1", "__fd_asin_8", FIXED(8)}, + + {"__fs_asin_1", "__fs_asin_4", FIXED(4)}, + {"__fs_asin_1", "__fs_asin_8", FIXED(8)}, + {"__fs_asin_1", "__fs_asin_16", FIXED(16)}, + + {"__pd_asin_1", "__pd_asin_2", FIXED(2)}, + {"__pd_asin_1", "__pd_asin_4", FIXED(4)}, + {"__pd_asin_1", "__pd_asin_8", FIXED(8)}, + + {"__ps_asin_1", "__ps_asin_4", FIXED(4)}, + {"__ps_asin_1", "__ps_asin_8", FIXED(8)}, + {"__ps_asin_1", "__ps_asin_16", FIXED(16)}, + + {"__rd_asin_1", "__rd_asin_2", FIXED(2)}, + {"__rd_asin_1", "__rd_asin_4", FIXED(4)}, + {"__rd_asin_1", "__rd_asin_8", FIXED(8)}, + + {"__rs_asin_1", "__rs_asin_4", FIXED(4)}, + {"__rs_asin_1", "__rs_asin_8", FIXED(8)}, + {"__rs_asin_1", "__rs_asin_16", FIXED(16)}, + + {"__fd_acos_1", "__fd_acos_2", FIXED(2)}, + {"__fd_acos_1", "__fd_acos_4", FIXED(4)}, + {"__fd_acos_1", "__fd_acos_8", FIXED(8)}, + + {"__fs_acos_1", "__fs_acos_4", FIXED(4)}, + {"__fs_acos_1", "__fs_acos_8", FIXED(8)}, + {"__fs_acos_1", "__fs_acos_16", FIXED(16)}, + + {"__pd_acos_1", "__pd_acos_2", FIXED(2)}, + {"__pd_acos_1", "__pd_acos_4", FIXED(4)}, + {"__pd_acos_1", "__pd_acos_8", FIXED(8)}, + + {"__ps_acos_1", "__ps_acos_4", FIXED(4)}, + {"__ps_acos_1", "__ps_acos_8", FIXED(8)}, + {"__ps_acos_1", "__ps_acos_16", FIXED(16)}, + + {"__rd_acos_1", "__rd_acos_2", FIXED(2)}, + {"__rd_acos_1", "__rd_acos_4", FIXED(4)}, + {"__rd_acos_1", "__rd_acos_8", FIXED(8)}, + + {"__rs_acos_1", "__rs_acos_4", FIXED(4)}, + {"__rs_acos_1", "__rs_acos_8", FIXED(8)}, + {"__rs_acos_1", "__rs_acos_16", FIXED(16)}, + + {"__fd_atan_1", "__fd_atan_2", FIXED(2)}, + {"__fd_atan_1", "__fd_atan_4", FIXED(4)}, + {"__fd_atan_1", "__fd_atan_8", FIXED(8)}, + + {"__fs_atan_1", "__fs_atan_4", FIXED(4)}, + {"__fs_atan_1", "__fs_atan_8", FIXED(8)}, + {"__fs_atan_1", "__fs_atan_16", FIXED(16)}, + + {"__pd_atan_1", "__pd_atan_2", FIXED(2)}, + {"__pd_atan_1", "__pd_atan_4", FIXED(4)}, + {"__pd_atan_1", "__pd_atan_8", FIXED(8)}, + + {"__ps_atan_1", "__ps_atan_4", FIXED(4)}, + {"__ps_atan_1", "__ps_atan_8", FIXED(8)}, + {"__ps_atan_1", "__ps_atan_16", FIXED(16)}, + + {"__rd_atan_1", "__rd_atan_2", FIXED(2)}, + {"__rd_atan_1", "__rd_atan_4", FIXED(4)}, + {"__rd_atan_1", "__rd_atan_8", FIXED(8)}, + + {"__rs_atan_1", "__rs_atan_4", FIXED(4)}, + {"__rs_atan_1", "__rs_atan_8", FIXED(8)}, + {"__rs_atan_1", "__rs_atan_16", FIXED(16)}, + + {"__fd_atan2_1", "__fd_atan2_2", FIXED(2)}, + {"__fd_atan2_1", "__fd_atan2_4", FIXED(4)}, + {"__fd_atan2_1", "__fd_atan2_8", FIXED(8)}, + + {"__fs_atan2_1", "__fs_atan2_4", FIXED(4)}, + {"__fs_atan2_1", "__fs_atan2_8", FIXED(8)}, + {"__fs_atan2_1", "__fs_atan2_16", FIXED(16)}, + + {"__pd_atan2_1", "__pd_atan2_2", FIXED(2)}, + {"__pd_atan2_1", "__pd_atan2_4", FIXED(4)}, + {"__pd_atan2_1", "__pd_atan2_8", FIXED(8)}, + + {"__ps_atan2_1", "__ps_atan2_4", FIXED(4)}, + {"__ps_atan2_1", "__ps_atan2_8", FIXED(8)}, + {"__ps_atan2_1", "__ps_atan2_16", FIXED(16)}, + + {"__rd_atan2_1", "__rd_atan2_2", FIXED(2)}, + {"__rd_atan2_1", "__rd_atan2_4", FIXED(4)}, + {"__rd_atan2_1", "__rd_atan2_8", FIXED(8)}, + + {"__rs_atan2_1", "__rs_atan2_4", FIXED(4)}, + {"__rs_atan2_1", "__rs_atan2_8", FIXED(8)}, + {"__rs_atan2_1", "__rs_atan2_16", FIXED(16)}, + + {"__fd_pow_1", "__fd_pow_2", FIXED(2)}, + {"__fd_pow_1", "__fd_pow_4", FIXED(4)}, + {"__fd_pow_1", "__fd_pow_8", FIXED(8)}, + + {"__fs_pow_1", "__fs_pow_4", FIXED(4)}, + {"__fs_pow_1", "__fs_pow_8", FIXED(8)}, + {"__fs_pow_1", "__fs_pow_16", FIXED(16)}, + + {"__pd_pow_1", "__pd_pow_2", FIXED(2)}, + {"__pd_pow_1", "__pd_pow_4", FIXED(4)}, + {"__pd_pow_1", "__pd_pow_8", FIXED(8)}, + + {"__ps_pow_1", "__ps_pow_4", FIXED(4)}, + {"__ps_pow_1", "__ps_pow_8", FIXED(8)}, + {"__ps_pow_1", "__ps_pow_16", FIXED(16)}, + + {"__rd_pow_1", "__rd_pow_2", FIXED(2)}, + {"__rd_pow_1", "__rd_pow_4", FIXED(4)}, + {"__rd_pow_1", "__rd_pow_8", FIXED(8)}, + + {"__rs_pow_1", "__rs_pow_4", FIXED(4)}, + {"__rs_pow_1", "__rs_pow_8", FIXED(8)}, + {"__rs_pow_1", "__rs_pow_16", FIXED(16)}, + + {"__fs_powi_1", "__fs_powi_4", FIXED(4)}, + {"__fs_powi_1", "__fs_powi_8", FIXED(8)}, + {"__fs_powi_1", "__fs_powi_16", FIXED(16)}, + + {"__ps_powi_1", "__ps_powi_4", FIXED(4)}, + {"__ps_powi_1", "__ps_powi_8", FIXED(8)}, + {"__ps_powi_1", "__ps_powi_16", FIXED(16)}, + + {"__rs_powi_1", "__rs_powi_4", FIXED(4)}, + {"__rs_powi_1", "__rs_powi_8", FIXED(8)}, + {"__rs_powi_1", "__rs_powi_16", FIXED(16)}, + + {"__fd_powi1_1", "__fd_powi1_2", FIXED(2)}, + {"__fd_powi1_1", "__fd_powi1_4", FIXED(4)}, + {"__fd_powi1_1", "__fd_powi1_8", FIXED(8)}, + + {"__fs_powi1_1", "__fs_powi1_4", FIXED(4)}, + {"__fs_powi1_1", "__fs_powi1_8", FIXED(8)}, + {"__fs_powi1_1", "__fs_powi1_16", FIXED(16)}, + + {"__pd_powi1_1", "__pd_powi1_2", FIXED(2)}, + {"__pd_powi1_1", "__pd_powi1_4", FIXED(4)}, + {"__pd_powi1_1", "__pd_powi1_8", FIXED(8)}, + + {"__ps_powi1_1", "__ps_powi1_4", FIXED(4)}, + {"__ps_powi1_1", "__ps_powi1_8", FIXED(8)}, + {"__ps_powi1_1", "__ps_powi1_16", FIXED(16)}, + + {"__rd_powi1_1", "__rd_powi1_2", FIXED(2)}, + {"__rd_powi1_1", "__rd_powi1_4", FIXED(4)}, + {"__rd_powi1_1", "__rd_powi1_8", FIXED(8)}, + + {"__rs_powi1_1", "__rs_powi1_4", FIXED(4)}, + {"__rs_powi1_1", "__rs_powi1_8", FIXED(8)}, + {"__rs_powi1_1", "__rs_powi1_16", FIXED(16)}, + + {"__fd_powk_1", "__fd_powk_2", FIXED(2)}, + {"__fd_powk_1", "__fd_powk_4", FIXED(4)}, + {"__fd_powk_1", "__fd_powk_8", FIXED(8)}, + + {"__fs_powk_1", "__fs_powk_4", FIXED(4)}, + {"__fs_powk_1", "__fs_powk_8", FIXED(8)}, + {"__fs_powk_1", "__fs_powk_16", FIXED(16)}, + + {"__pd_powk_1", "__pd_powk_2", FIXED(2)}, + {"__pd_powk_1", "__pd_powk_4", FIXED(4)}, + {"__pd_powk_1", "__pd_powk_8", FIXED(8)}, + + {"__ps_powk_1", "__ps_powk_4", FIXED(4)}, + {"__ps_powk_1", "__ps_powk_8", FIXED(8)}, + {"__ps_powk_1", "__ps_powk_16", FIXED(16)}, + + {"__rd_powk_1", "__rd_powk_2", FIXED(2)}, + {"__rd_powk_1", "__rd_powk_4", FIXED(4)}, + {"__rd_powk_1", "__rd_powk_8", FIXED(8)}, + + {"__rs_powk_1", "__rs_powk_4", FIXED(4)}, + {"__rs_powk_1", "__rs_powk_8", FIXED(8)}, + {"__rs_powk_1", "__rs_powk_16", FIXED(16)}, + + {"__fd_powk1_1", "__fd_powk1_2", FIXED(2)}, + {"__fd_powk1_1", "__fd_powk1_4", FIXED(4)}, + {"__fd_powk1_1", "__fd_powk1_8", FIXED(8)}, + + {"__fs_powk1_1", "__fs_powk1_4", FIXED(4)}, + {"__fs_powk1_1", "__fs_powk1_8", FIXED(8)}, + {"__fs_powk1_1", "__fs_powk1_16", FIXED(16)}, + + {"__pd_powk1_1", "__pd_powk1_2", FIXED(2)}, + {"__pd_powk1_1", "__pd_powk1_4", FIXED(4)}, + {"__pd_powk1_1", "__pd_powk1_8", FIXED(8)}, + + {"__ps_powk1_1", "__ps_powk1_4", FIXED(4)}, + {"__ps_powk1_1", "__ps_powk1_8", FIXED(8)}, + {"__ps_powk1_1", "__ps_powk1_16", FIXED(16)}, + + {"__rd_powk1_1", "__rd_powk1_2", FIXED(2)}, + {"__rd_powk1_1", "__rd_powk1_4", FIXED(4)}, + {"__rd_powk1_1", "__rd_powk1_8", FIXED(8)}, + + {"__rs_powk1_1", "__rs_powk1_4", FIXED(4)}, + {"__rs_powk1_1", "__rs_powk1_8", FIXED(8)}, + {"__rs_powk1_1", "__rs_powk1_16", FIXED(16)}, + + {"__fd_log10_1", "__fd_log10_2", FIXED(2)}, + {"__fd_log10_1", "__fd_log10_4", FIXED(4)}, + {"__fd_log10_1", "__fd_log10_8", FIXED(8)}, + + {"__fs_log10_1", "__fs_log10_4", FIXED(4)}, + {"__fs_log10_1", "__fs_log10_8", FIXED(8)}, + {"__fs_log10_1", "__fs_log10_16", FIXED(16)}, + + {"__pd_log10_1", "__pd_log10_2", FIXED(2)}, + {"__pd_log10_1", "__pd_log10_4", FIXED(4)}, + {"__pd_log10_1", "__pd_log10_8", FIXED(8)}, + + {"__ps_log10_1", "__ps_log10_4", FIXED(4)}, + {"__ps_log10_1", "__ps_log10_8", FIXED(8)}, + {"__ps_log10_1", "__ps_log10_16", FIXED(16)}, + + {"__rd_log10_1", "__rd_log10_2", FIXED(2)}, + {"__rd_log10_1", "__rd_log10_4", FIXED(4)}, + {"__rd_log10_1", "__rd_log10_8", FIXED(8)}, + + {"__rs_log10_1", "__rs_log10_4", FIXED(4)}, + {"__rs_log10_1", "__rs_log10_8", FIXED(8)}, + {"__rs_log10_1", "__rs_log10_16", FIXED(16)}, + + {"__fd_log_1", "__fd_log_2", FIXED(2)}, + {"__fd_log_1", "__fd_log_4", FIXED(4)}, + {"__fd_log_1", "__fd_log_8", FIXED(8)}, + + {"__fs_log_1", "__fs_log_4", FIXED(4)}, + {"__fs_log_1", "__fs_log_8", FIXED(8)}, + {"__fs_log_1", "__fs_log_16", FIXED(16)}, + + {"__pd_log_1", "__pd_log_2", FIXED(2)}, + {"__pd_log_1", "__pd_log_4", FIXED(4)}, + {"__pd_log_1", "__pd_log_8", FIXED(8)}, + + {"__ps_log_1", "__ps_log_4", FIXED(4)}, + {"__ps_log_1", "__ps_log_8", FIXED(8)}, + {"__ps_log_1", "__ps_log_16", FIXED(16)}, + + {"__rd_log_1", "__rd_log_2", FIXED(2)}, + {"__rd_log_1", "__rd_log_4", FIXED(4)}, + {"__rd_log_1", "__rd_log_8", FIXED(8)}, + + {"__rs_log_1", "__rs_log_4", FIXED(4)}, + {"__rs_log_1", "__rs_log_8", FIXED(8)}, + {"__rs_log_1", "__rs_log_16", FIXED(16)}, + + {"__fs_exp_1", "__fs_exp_4", FIXED(4)}, + {"__fs_exp_1", "__fs_exp_8", FIXED(8)}, + {"__fs_exp_1", "__fs_exp_16", FIXED(16)}, + + {"__pd_exp_1", "__pd_exp_2", FIXED(2)}, + {"__pd_exp_1", "__pd_exp_4", FIXED(4)}, + {"__pd_exp_1", "__pd_exp_8", FIXED(8)}, + + {"__ps_exp_1", "__ps_exp_4", FIXED(4)}, + {"__ps_exp_1", "__ps_exp_8", FIXED(8)}, + {"__ps_exp_1", "__ps_exp_16", FIXED(16)}, + + {"__rd_exp_1", "__rd_exp_2", FIXED(2)}, + {"__rd_exp_1", "__rd_exp_4", FIXED(4)}, + {"__rd_exp_1", "__rd_exp_8", FIXED(8)}, + + {"__rs_exp_1", "__rs_exp_4", FIXED(4)}, + {"__rs_exp_1", "__rs_exp_8", FIXED(8)}, + {"__rs_exp_1", "__rs_exp_16", FIXED(16)} + }; + addVectorizableFunctions(VecFuncs); + break; + } +#endif + case NoLibrary: break; } diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index 5f0d1a76de79..d7eb34e3d148 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -5405,6 +5405,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, ); \ @@ -5416,8 +5432,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 @@ -5425,8 +5443,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 0a9a80688a41..c21e5e5dba97 100644 --- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp +++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp @@ -1979,25 +1979,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++; @@ -2010,7 +2028,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++; @@ -2043,7 +2062,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 9416c7f5a03e..013e7ce2d425 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -2014,7 +2014,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())); @@ -2026,6 +2026,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 726aba18bb80..0835eba21891 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) @@ -139,6 +162,37 @@ public: 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(); } @@ -174,6 +228,15 @@ public: LLVM_DUMP_METHOD void dump() const { for (const DbgValueLocEntry &DV : ValueLocEntries) DV.dump(); +// if (isLocation()) { +// llvm::dbgs() << "Loc = { reg=" << Loc.getReg() << " "; +// if (Loc.isIndirect()) +// llvm::dbgs() << "+0"; +// llvm::dbgs() << "} "; +// } else if (isConstantInt()) +// Constant.CIP->dump(); +// else if (isConstantFP()) +// Constant.CFP->dump(); if (Expression) Expression->dump(); } @@ -250,6 +313,9 @@ public: DebugLocStream::ListBuilder &List, const DIBasicType *BT, DwarfCompileUnit &TheCU); + +// void finalize(const AsmPrinter &AP, DebugLocStream::ListBuilder &List, +// const DIStringType *ST, DwarfCompileUnit &TheCU); }; /// Compare two DbgValueLocEntries for equality. @@ -278,6 +344,29 @@ inline bool operator==(const DbgValueLoc &A, const DbgValueLoc &B) { A.Expression == B.Expression && A.IsVariadic == B.IsVariadic; } +//inline bool operator==(const DbgValueLoc &A, +// const DbgValueLoc &B) { +// if (A.EntryKind != B.EntryKind) +// return false; +// +// if (A.Expression != B.Expression) +// return false; +// +// switch (A.EntryKind) { +// case DbgValueLoc::E_Location: +// return A.Loc == B.Loc; +// case DbgValueLoc::E_TargetIndexLocation: +// return A.TIL == B.TIL; +// case DbgValueLoc::E_Integer: +// return A.Constant.Int == B.Constant.Int; +// case DbgValueLoc::E_ConstantFP: +// return A.Constant.CFP == B.Constant.CFP; +// case DbgValueLoc::E_ConstantInt: +// return A.Constant.CIP == B.Constant.CIP; +// } +// llvm_unreachable("unhandled EntryKind"); +//} + /// Compare two fragments based on their offset. inline bool operator<(const DbgValueLoc &A, const DbgValueLoc &B) { diff --git a/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.cpp b/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.cpp index 8c6109880afc..fbfcf65a34ec 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.initializeDbgValue(&MI); diff --git a/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.h b/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.h index a96bdd034918..0600f4f09d5e 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.h +++ b/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.h @@ -158,12 +158,18 @@ class DebugLocStream::ListBuilder { DbgVariable &V; const MachineInstr &MI; size_t ListIndex; +#ifdef ENABLE_CLASSIC_FLANG + bool Finalized; +#endif std::optional TagOffset; public: ListBuilder(DebugLocStream &Locs, DwarfCompileUnit &CU, AsmPrinter &Asm, DbgVariable &V, const MachineInstr &MI) : Locs(Locs), Asm(Asm), V(V), MI(MI), 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 58ed21379d29..78ff0d351492 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -185,6 +185,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/DwarfCompileUnit.h b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h index 6ef73ebd4f7f..17be1c4796f7 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h @@ -158,6 +158,14 @@ public: std::vector ExprRefedBaseTypes; +private: + DenseMap> *globalVarMap; +public: + void setGlobalVarMap( + DenseMap> *p = nullptr) { + globalVarMap = p; + } + /// Get or create global variable DIE. DIE * getOrCreateGlobalVariableDIE(const DIGlobalVariable *GV, diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 1ae17ec9b874..16cae978d177 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -1225,11 +1225,17 @@ void DwarfDebug::beginModule(Module *M) { } DenseSet Processed; +#if 0 + CU.setGlobalVarMap(&GVMap); +#endif for (auto *GVE : CUNode->getGlobalVariables()) { DIGlobalVariable *GV = GVE->getVariable(); if (Processed.insert(GV).second) CU.getOrCreateGlobalVariableDIE(GV, sortGlobalExprs(GVMap[GV])); } +#if 0 + CU.setGlobalVarMap(); +#endif for (auto *Ty : CUNode->getEnumTypes()) CU.getOrCreateTypeDIE(cast(Ty)); @@ -1869,10 +1875,28 @@ DbgEntity *DwarfDebug::createConcreteEntity(DwarfCompileUnit &TheCU, return ConcreteEntities.back().get(); } +#if 0 +void DwarfDebug::populateDependentTypeMap() { + for (const auto &I : DbgValues) { + InlinedEntity IV = I.first; + if (I.second.empty()) + continue; + if (const DIVariable *DIV = dyn_cast(IV.first)) { + if (const DIStringType *ST = dyn_cast( + static_cast(DIV->getType()))) + if (const DIVariable *LV = ST->getStringLength()) + VariableInDependentType[LV] = ST; + } + } +} +#endif + // Find variables for each lexical scope. void DwarfDebug::collectEntityInfo(DwarfCompileUnit &TheCU, const DISubprogram *SP, DenseSet &Processed) { +// clearDependentTracking(); +// populateDependentTypeMap(); // Grab the variable info that was squirreled away in the MMI side-table. collectVariableInfoFromMFTable(TheCU, Processed); @@ -1891,6 +1915,11 @@ void DwarfDebug::collectEntityInfo(DwarfCompileUnit &TheCU, LexicalScope *Scope = nullptr; const DILocalVariable *LocalVar = cast(IV.first); +#if 0 + const DILocalVariable *LocalVar = dyn_cast(IV.first); + if (!LocalVar) + continue; +#endif if (const DILocation *IA = IV.second) Scope = LScopes.findInlinedScope(LocalVar->getScope(), IA); else @@ -1949,6 +1978,24 @@ void DwarfDebug::collectEntityInfo(DwarfCompileUnit &TheCU, // Finalize the entry by lowering it into a DWARF bytestream. for (auto &Entry : Entries) Entry.finalize(*Asm, List, BT, TheCU); +#if 0 + List.finalize(); + + if (VariableInDependentType.count(LocalVar)) { + const DIType *DT = VariableInDependentType[LocalVar]; + if (const DIStringType *ST = dyn_cast(DT)) { + unsigned Offset; + DbgVariable TVar = {LocalVar, IV.second}; + DebugLocStream::ListBuilder LB(DebugLocs, TheCU, *Asm, TVar, *MInsn); + for (auto &Entry : Entries) + Entry.finalize(*Asm, LB, ST, TheCU); + LB.finalize(); + Offset = TVar.getDebugLocListIndex(); + if (Offset != ~0u) + addStringTypeLoc(ST, Offset); + } + } +#endif } // For each InlinedEntity collected from DBG_LABEL instructions, convert to @@ -2757,6 +2804,35 @@ void DebugLocEntry::finalize(const AsmPrinter &AP, List.setTagOffset(*DwarfExpr.TagOffset); } +#if 0 +inline static DbgValueLoc mkDbgValueLoc(const DIExpression *expr, + DbgValueLoc &value) { + if (value.isInt()) + return DbgValueLoc(expr, value.getInt()); + if (value.isLocation()) + return DbgValueLoc(expr, value.getLoc()); + if (value.isConstantInt()) + return DbgValueLoc(expr, value.getConstantInt()); + assert(value.isConstantFP()); + return DbgValueLoc(expr, value.getConstantFP()); +} + +void DebugLocEntry::finalize(const AsmPrinter &AP, + DebugLocStream::ListBuilder &List, + const DIStringType *ST, + DwarfCompileUnit &TheCU) { + DebugLocStream::EntryBuilder Entry(List, Begin, End); + BufferByteStreamer Streamer = Entry.getStreamer(); + DebugLocDwarfExpression DwarfExpr(AP.getDwarfVersion(), Streamer, TheCU); + DbgValueLoc &Value = Values[0]; + assert(!Value.isFragment()); + assert(Values.size() == 1 && "only fragments may have >1 value"); + Value = mkDbgValueLoc(ST->getStringLengthExp(), Value); + DwarfDebug::emitDebugLocValue(AP, nullptr, Value, DwarfExpr); + DwarfExpr.finalize(); +} +#endif + void DwarfDebug::emitDebugLocEntryLocation(const DebugLocStream::Entry &Entry, const DwarfCompileUnit *CU) { // Emit the size. diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h index 1af4b643eb17..0a20551058a1 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -284,6 +284,8 @@ struct SymbolCU { DwarfCompileUnit *CU; }; +class DummyDwarfExpression; + /// The kind of accelerator tables we should emit. enum class AccelTableKind { Default, ///< Platform default. @@ -437,6 +439,8 @@ private: /// Map for tracking Fortran deferred CHARACTER lengths. DenseMap StringTypeLocMap; + DenseMap VariableInDependentType; + AddressPool AddrPool; /// Accelerator tables. @@ -624,6 +628,14 @@ private: /// Emit the reference to the section. void emitSectionReference(const DwarfCompileUnit &CU); +#if 0 + /// Populate dependent type variable map + void populateDependentTypeMap(); +#endif + + /// Clear dependent type tracking map + void clearDependentTracking() { VariableInDependentType.clear(); } + protected: /// Gather pre-function debug information. void beginFunctionImpl(const MachineFunction *MF) override; diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index be4a3ed79d88..c47dd4664ea6 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -2281,6 +2281,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 1ce8c17f8a88..af6ebf702165 100644 --- a/llvm/lib/IR/DIBuilder.cpp +++ b/llvm/lib/IR/DIBuilder.cpp @@ -725,14 +725,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); @@ -743,14 +743,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 48b5501c55ba..3696beccdd0c 100644 --- a/llvm/lib/IR/DebugInfo.cpp +++ b/llvm/lib/IR/DebugInfo.cpp @@ -1547,12 +1547,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) { @@ -1597,11 +1598,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)); } LLVMValueRef diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp index 4933b6032688..d599896ee456 100644 --- a/llvm/lib/IR/DebugInfoMetadata.cpp +++ b/llvm/lib/IR/DebugInfoMetadata.cpp @@ -1258,15 +1258,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, @@ -1277,7 +1278,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 4cc3f8da6b75..8a621725f55e 100644 --- a/llvm/lib/IR/LLVMContextImpl.h +++ b/llvm/lib/IR/LLVMContextImpl.h @@ -1055,6 +1055,7 @@ template <> struct MDNodeKeyImpl { bool IsDefinition; Metadata *StaticDataMemberDeclaration; Metadata *TemplateParams; + unsigned Flags; uint32_t AlignInBits; Metadata *Annotations; @@ -1062,20 +1063,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 { @@ -1087,6 +1089,7 @@ template <> struct MDNodeKeyImpl { StaticDataMemberDeclaration == RHS->getRawStaticDataMemberDeclaration() && TemplateParams == RHS->getRawTemplateParams() && + Flags == RHS->getFlags() && AlignInBits == RHS->getAlignInBits() && Annotations == RHS->getRawAnnotations(); } @@ -1101,7 +1104,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 a7b1953ce81c..136132d7e65a 100644 --- a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp +++ b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp @@ -1052,8 +1052,8 @@ InstrProfiling::getOrCreateRegionCounters(InstrProfInstBase *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(); } else { diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp index b603bbe55dc9..3451db126afd 100644 --- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -5766,8 +5766,10 @@ void LoopVectorizationCostModel::collectElementTypesForWidening() { if (ValuesToIgnore.count(&I)) continue; - // Only examine Loads, Stores and PHINodes. - if (!isa(I) && !isa(I) && !isa(I)) + // Examine Loads, Stores, PHINodes + // Also examine instructions which convert to a float/double + if (!isa(I) && !isa(I) && !isa(I) && + !isa(I) && !isa(I) && !isa(I)) continue; // Examine PHI nodes that are reduction variables. Update the type to 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 4114bf7f54b2..9cc8520960c2 100644 --- a/llvm/test/lit.cfg.py +++ b/llvm/test/lit.cfg.py @@ -645,3 +645,6 @@ if "aix" in config.target_triple: # "OBJECT_MODE" to 'any' by default on AIX OS. if "system-aix" in config.available_features: config.environment["OBJECT_MODE"] = "any" + +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 57ee2100dfb7..fc7ab6536309 100644 --- a/llvm/test/lit.site.cfg.py.in +++ b/llvm/test/lit.site.cfg.py.in @@ -61,6 +61,7 @@ config.expensive_checks = @LLVM_ENABLE_EXPENSIVE_CHECKS@ config.reverse_iteration = @LLVM_ENABLE_REVERSE_ITERATION@ config.dxil_tests = @LLVM_INCLUDE_DXIL_TESTS@ config.have_llvm_driver = @LLVM_TOOL_LLVM_DRIVER_BUILD@ +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 a3e41be12e95..906c96f1c24b 100644 --- a/llvm/tools/llvm-c-test/debuginfo.c +++ b/llvm/tools/llvm-c-test/debuginfo.c @@ -64,7 +64,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); @@ -75,7 +75,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 5342360109d0..4bce26851d2f 100644 --- a/llvm/unittests/IR/MetadataTest.cpp +++ b/llvm/unittests/IR/MetadataTest.cpp @@ -2896,12 +2896,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()); @@ -2914,57 +2915,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(); @@ -2987,16 +2997,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()); -- Gitee From 71edede3b52e8bec9ac9e473f3481f729beeace8 Mon Sep 17 00:00:00 2001 From: Bryan Chan Date: Sun, 1 May 2022 21:43:45 -0400 Subject: [PATCH 02/47] [ClassicFlang][Driver] Coexist with LLVM Flang Make TableGen respect the ENABLE_CLASSIC_FLANG macro and better separate the driver options that are mutually exclusive. When the macro is defined, do not build LLVM Flang at all. --- build.sh | 1 + clang/include/clang/Driver/CMakeLists.txt | 13 ++++++++++--- clang/include/clang/Driver/Options.td | 11 ++++++----- clang/include/clang/Driver/ToolChain.h | 4 ++++ clang/lib/Driver/CMakeLists.txt | 7 ++++--- clang/lib/Driver/ToolChain.cpp | 6 ++++++ clang/lib/Driver/ToolChains/ClassicFlang.cpp | 16 ++++++++-------- clang/lib/Driver/ToolChains/CommonArgs.cpp | 10 ++++++++-- clang/lib/Driver/ToolChains/CommonArgs.h | 2 ++ clang/lib/Driver/ToolChains/Cuda.cpp | 2 ++ clang/lib/Driver/ToolChains/Cuda.h | 11 +++++------ clang/lib/Driver/ToolChains/Gnu.cpp | 2 ++ clang/lib/Driver/ToolChains/Linux.cpp | 2 ++ clang/lib/Driver/ToolChains/Linux.h | 2 ++ 14 files changed, 62 insertions(+), 27 deletions(-) diff --git a/build.sh b/build.sh index f8402bbe9fb2..75812c54d8b3 100755 --- a/build.sh +++ b/build.sh @@ -178,6 +178,7 @@ fi mkdir -p "$build_prefix" && cd "$build_prefix" cmake $CMAKE_OPTIONS \ -DCOMPILER_RT_BUILD_SANITIZERS=on \ + -DLLVM_ENABLE_CLASSIC_FLANG=on \ -DLLVM_ENABLE_PROJECTS=$enabled_projects \ -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind" \ -DLLVM_USE_LINKER=gold \ diff --git a/clang/include/clang/Driver/CMakeLists.txt b/clang/include/clang/Driver/CMakeLists.txt index ea55ba0f1f27..8c0af1528a96 100644 --- a/clang/include/clang/Driver/CMakeLists.txt +++ b/clang/include/clang/Driver/CMakeLists.txt @@ -1,7 +1,14 @@ set(LLVM_TARGET_DEFINITIONS Options.td) + +set(CLANG_DRIVER_OPTIONS) if (BUILD_FOR_OPENEULER) -tablegen(LLVM Options.inc -gen-opt-parser-defs -DBUILD_FOR_OPENEULER) -else() -tablegen(LLVM Options.inc -gen-opt-parser-defs) + list(APPEND CLANG_DRIVER_OPTIONS -DBUILD_FOR_OPENEULER ) endif() + +if (LLVM_ENABLE_CLASSIC_FLANG) + list(APPEND CLANG_DRIVER_OPTIONS -DENABLE_CLASSIC_FLANG ) +endif() + +tablegen(LLVM Options.inc ${CLANG_DRIVER_OPTIONS} -gen-opt-parser-defs ) + add_public_tablegen_target(ClangDriverOptions) diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 0799121f864e..9eb398020df1 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -591,7 +591,7 @@ class InternalDriverOpt : Group, def driver_mode : Joined<["--"], "driver-mode=">, Group, Flags<[CoreOption, NoXarchOption, HelpHidden]>, #ifdef ENABLE_CLASSIC_FLANG - HelpText<"Set the driver mode to either 'gcc', 'g++', 'cpp', 'cl', or 'fortran'">; + HelpText<"Set the driver mode to one of: 'gcc', 'g++', 'cpp', 'cl', or 'flang'">; #else HelpText<"Set the driver mode to either 'gcc', 'g++', 'cpp', or 'cl'">; #endif @@ -5423,11 +5423,11 @@ def fopenacc : Flag<["-"], "fopenacc">, Group, HelpText<"Enable OpenACC">; 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_integer_8 : Flag<["-"],"fdefault-integer-8">, Group, - HelpText<"Set the default integer and logical kind to an 8 byte wide type">; 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 @@ -5435,6 +5435,7 @@ def fno_default_real_8 : Flag<["-"], "fno-default-real-8">, Group; #endif def flarge_sizes : Flag<["-"],"flarge-sizes">, Group, HelpText<"Use INTEGER(KIND=8) for the result type in size-related intrinsics">; + def falternative_parameter_statement : Flag<["-"], "falternative-parameter-statement">, Group, HelpText<"Enable the old style PARAMETER statement">; def fintrinsic_modules_path : Separate<["-"], "fintrinsic-modules-path">, Group, MetaVarName<"">, @@ -7505,8 +7506,8 @@ def enable_16bit_types : DXCFlag<"enable-16bit-types">, Alias "Available in HLSL 2018 and shader model 6.2.">; #ifdef ENABLE_CLASSIC_FLANG -// gfortran options that we recognize in the driver and pass along when -// invoking GCC to compile Fortran code. +// 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]>; diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h index 7603b12eec64..9e3513a50915 100644 --- a/clang/include/clang/Driver/ToolChain.h +++ b/clang/include/clang/Driver/ToolChain.h @@ -653,6 +653,7 @@ public: 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 @@ -660,6 +661,7 @@ public: 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, @@ -767,10 +769,12 @@ public: 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/lib/Driver/CMakeLists.txt b/clang/lib/Driver/CMakeLists.txt index 1b4df4db0a08..ac30007588b1 100644 --- a/clang/lib/Driver/CMakeLists.txt +++ b/clang/lib/Driver/CMakeLists.txt @@ -15,7 +15,9 @@ if(WIN32) endif() if(LLVM_ENABLE_CLASSIC_FLANG) - set(CLASSIC_FLANG_FILES ToolChains/ClassicFlang.cpp) + set(TOOLCHAINS_FLANG_CPP ToolChains/ClassicFlang.cpp) +else() + set(TOOLCHAINS_FLANG_CPP ToolChains/Flang.cpp) endif() add_clang_library(clangDriver @@ -60,7 +62,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 @@ -96,7 +98,6 @@ add_clang_library(clangDriver ToolChains/ZOS.cpp Types.cpp XRayArgs.cpp - ${CLASSIC_FLANG_FILES} DEPENDS ClangDriverOptions diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index dc5ab1d8f2ce..12fe81676804 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -443,9 +443,13 @@ Tool *ToolChain::getClang() const { } Tool *ToolChain::getFlang() const { +#ifndef ENABLE_CLASSIC_FLANG if (!Flang) Flang.reset(new tools::Flang(*this)); return Flang.get(); +#else + llvm_unreachable("Flang is not supported by this toolchain"); +#endif } Tool *ToolChain::buildAssembler() const { @@ -1239,6 +1243,7 @@ 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; @@ -1277,6 +1282,7 @@ void ToolChain::AddFortranStdlibLibArgs(const ArgList &Args, // Allways link Fortran executables with Pthreads CmdArgs.push_back("-lpthread"); } +#endif bool ToolChain::isFastMathRuntimeAvailable(const ArgList &Args, std::string &Path) const { diff --git a/clang/lib/Driver/ToolChains/ClassicFlang.cpp b/clang/lib/Driver/ToolChains/ClassicFlang.cpp index 9573ac2dde09..b73ca45031ba 100644 --- a/clang/lib/Driver/ToolChains/ClassicFlang.cpp +++ b/clang/lib/Driver/ToolChains/ClassicFlang.cpp @@ -366,10 +366,10 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, // 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_default_real_8_fno)) { + 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_default_real_8_fno)) { + if (A->getOption().matches(options::OPT_fno_default_real_8)) { fl = "-y"; } else { fl = "-x"; @@ -377,7 +377,7 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, for (Arg *A : Args.filtered(options::OPT_r8, options::OPT_fdefault_real_8, - options::OPT_default_real_8_fno)) { + options::OPT_fno_default_real_8)) { A->claim(); } @@ -392,10 +392,10 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, // 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_default_integer_8_fno)) { + options::OPT_fno_default_integer_8)) { const char * fl; - if (A->getOption().matches(options::OPT_default_integer_8_fno)) { + if (A->getOption().matches(options::OPT_fno_default_integer_8)) { fl = "-y"; } else { fl = "-x"; @@ -403,7 +403,7 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, for (Arg *A : Args.filtered(options::OPT_i8, options::OPT_fdefault_integer_8, - options::OPT_default_integer_8_fno)) { + options::OPT_fno_default_integer_8)) { A->claim(); } @@ -730,14 +730,14 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, default: llvm_unreachable("missed a case"); case options::OPT_ffixed_form: - case options::OPT_free_form_off: + 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_fixed_form_off: + case options::OPT_fno_fixed_form: case options::OPT_Mfree_on: case options::OPT_Mfreeform_on: UpperCmdArgs.push_back("-freeform"); diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index f79dd847a3e5..5e66d347d0ad 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -146,6 +146,7 @@ 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 static bool needFortranMain(const Driver &D, const ArgList &Args) { return (needFortranLibs(D, Args) @@ -162,6 +163,7 @@ bool tools::needFortranLibs(const Driver &D, const ArgList &Args) { return false; } +#endif void tools::addPathIfExists(const Driver &D, const Twine &Path, ToolChain::path_list &Paths) { @@ -273,7 +275,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_). @@ -307,6 +311,7 @@ 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)) { @@ -314,7 +319,7 @@ void tools::AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs, } SeenFirstLinkerInput = true; } - +#endif // Otherwise, this is a linker input argument. const Arg &A = II.getInputArg(); @@ -326,7 +331,7 @@ void tools::AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs, else A.renderAsInput(Args, CmdArgs); } - +#ifdef ENABLE_CLASSIC_FLANG if (!SeenFirstLinkerInput && needFortranMain(D, Args)) { CmdArgs.push_back("-lflangmain"); } @@ -335,6 +340,7 @@ void tools::AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs, for (auto Arg : Args.filtered(options::OPT_no_fortran_main, options::OPT_Mnomain)) { Arg->claim(); } +#endif } void tools::addLinkerCompressDebugSectionsOption( diff --git a/clang/lib/Driver/ToolChains/CommonArgs.h b/clang/lib/Driver/ToolChains/CommonArgs.h index c149ae57a2ee..740c235a37a5 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.h +++ b/clang/lib/Driver/ToolChains/CommonArgs.h @@ -23,7 +23,9 @@ namespace clang { namespace driver { namespace tools { +#ifdef ENABLE_CLASSIC_FLANG bool needFortranLibs(const Driver &D, const llvm::opt::ArgList &Args); +#endif void addPathIfExists(const Driver &D, const Twine &Path, ToolChain::path_list &Paths); diff --git a/clang/lib/Driver/ToolChains/Cuda.cpp b/clang/lib/Driver/ToolChains/Cuda.cpp index f4b8a6ae437e..36fddca2d177 100644 --- a/clang/lib/Driver/ToolChains/Cuda.cpp +++ b/clang/lib/Driver/ToolChains/Cuda.cpp @@ -1035,6 +1035,7 @@ VersionTuple CudaToolChain::computeMSVCVersion(const Driver *D, return HostTC.computeMSVCVersion(D, Args); } +#ifdef ENABLE_CLASSIC_FLANG static void AddFlangSysIncludeArg(const ArgList &DriverArgs, ArgStringList &Flang1Args, ToolChain::path_list IncludePathList) { @@ -1067,3 +1068,4 @@ void CudaToolChain::AddFlangSystemIncludeArgs(const llvm::opt::ArgList &DriverAr 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 7e8eb6cb81c6..3eded1f53e42 100644 --- a/clang/lib/Driver/ToolChains/Cuda.h +++ b/clang/lib/Driver/ToolChains/Cuda.h @@ -214,6 +214,11 @@ public: 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; @@ -223,12 +228,6 @@ public: const ToolChain &HostTC; -#ifdef ENABLE_CLASSIC_FLANG - void - AddFlangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, - llvm::opt::ArgStringList &Flang1Args) const override; -#endif - /// Uses nvptx-arch tool to get arch of the system GPU. Will return error /// if unable to find one. virtual Expected> diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp index 14a9bc56c88f..5c8b92bcc0d6 100644 --- a/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/clang/lib/Driver/ToolChains/Gnu.cpp @@ -554,6 +554,7 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, // The profile runtime also needs access to system libraries. getToolChain().addProfileRTLibs(Args, CmdArgs); +#ifdef ENABLE_CLASSIC_FLANG // Add Fortran runtime libraries if (needFortranLibs(D, Args)) { ToolChain.AddFortranStdlibLibArgs(Args, CmdArgs); @@ -563,6 +564,7 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, Arg->claim(); } } +#endif if (D.CCCIsCXX() && !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs, diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp index 833d019ff156..7f0714676a9d 100644 --- a/clang/lib/Driver/ToolChains/Linux.cpp +++ b/clang/lib/Driver/ToolChains/Linux.cpp @@ -608,6 +608,7 @@ 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, @@ -795,6 +796,7 @@ void Linux::AddFlangSystemIncludeArgs(const ArgList &DriverArgs, AddFlangSysIncludeArg(DriverArgs, Flang1Args, IncludePathList); } +#endif void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs, ArgStringList &CC1Args) const { diff --git a/clang/lib/Driver/ToolChains/Linux.h b/clang/lib/Driver/ToolChains/Linux.h index 0f6122b8cee1..b6db4160811d 100644 --- a/clang/lib/Driver/ToolChains/Linux.h +++ b/clang/lib/Driver/ToolChains/Linux.h @@ -27,9 +27,11 @@ public: 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; -- Gitee From a17878a3c45abd936348c060d8b3974194fd2b33 Mon Sep 17 00:00:00 2001 From: Alok Kumar Sharma <60725621+alokkrsharma@users.noreply.github.com> Date: Sun, 20 Sep 2020 17:21:34 +0530 Subject: [PATCH 03/47] Support for DWARF 4/5 and fix of issues related to -gdwarf-X options (#92) * Support for -gdwarf-5 option in Flang driver. Summary: FLANG driver doesnt pass -gdwarf-4/5 to flang1 in form of xbits, while it passes for -gdwarf-2/3 -gdwarf-2 => -x 120 0x200 -gdwarf-3 => -x 120 0x4000 Due to this -gdwarf-5 is never honored and default option -gdwarf-4 is taken. # flang -gdwarf-5 test.f90 # llvm-dwarfdump a.out | grep version 0x00000000: Compile Unit: length = 0x0000008e version = 0x0004 Now 0x1000000/0x2000000 will be passed for -gdwarf-4/5 -gdwarf-4 => -x 120 0x1000000 -gdwarf-5 => -x 120 0x2000000 Testing: - GNU gdb fortran testsuite - check-llvm - check-debuginfo * Flang doenst choose correct dwarf version when multiple -g/-gdwarfN mentioned Summary: When multiple -g/-gdwarfN options are passed together at compile time, flang chooses the least one. Clang/gfortran etc choose the last one. -gdwarf-5 -gdwarf-3 => flang chooses 5 while clang/gfortran choose 3 -gdwarf-5 -g => flang choses the default while clang/gfortran choose 5 Testing: - check-llvm - check-debuginfo * Default dwarf version should be 4 for -g with flang Currently flang dumps dwarf version 2 for -g and 4 for absence of -g ------------------------- $ flang my.f90 $ llvm-dwarfdump a.out | grep version 0x00000000: Compile Unit: length = 0x0000003d version = 0x0004 abbr_offset = 0x0000 addr_size = 0x08 (next unit at 0x00000041) $ flang -g my.f90 $ llvm-dwarfdump a.out | grep version 0x00000000: Compile Unit: length = 0x00000047 version = 0x0002 abbr_offset = 0x0000 addr_size = 0x08 (next unit at 0x0000004b) ------------------------- It should be 4 for -g as it is the case with clang. --- clang/lib/Driver/ToolChains/ClassicFlang.cpp | 42 +++++++++++--------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/clang/lib/Driver/ToolChains/ClassicFlang.cpp b/clang/lib/Driver/ToolChains/ClassicFlang.cpp index b73ca45031ba..ce2d62f87399 100644 --- a/clang/lib/Driver/ToolChains/ClassicFlang.cpp +++ b/clang/lib/Driver/ToolChains/ClassicFlang.cpp @@ -327,28 +327,34 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, LowerCmdArgs.push_back("0x8"); } - // -g should produce DWARFv2 - for (auto Arg : Args.filtered(options::OPT_g_Flag)) { - Arg->claim(); - CommonCmdArgs.push_back("-x"); - CommonCmdArgs.push_back("120"); - CommonCmdArgs.push_back("0x200"); - } + // 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(); + } - // -gdwarf-2 - for (auto Arg : Args.filtered(options::OPT_gdwarf_2)) { - Arg->claim(); CommonCmdArgs.push_back("-x"); CommonCmdArgs.push_back("120"); - CommonCmdArgs.push_back("0x200"); - } - // -gdwarf-3 - for (auto Arg : Args.filtered(options::OPT_gdwarf_3)) { - Arg->claim(); - CommonCmdArgs.push_back("-x"); - CommonCmdArgs.push_back("120"); - CommonCmdArgs.push_back("0x4000"); + 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"); } // -Mipa has no effect -- Gitee From 55407f6a003414d617e06f0d0672cad2a747e15d Mon Sep 17 00:00:00 2001 From: Bryan Chan Date: Mon, 12 Oct 2020 14:19:48 -0400 Subject: [PATCH 04/47] Reduce downstream delta This commit is motivated by reducing the merge burden by shrinking the diff between llvm upstream and classic-flang-llvm-project. Outside of Flang, Fortran code is fed through the Compile phase, and the appropriate tooling is picked up through ToolChain::SelectTool. Classic Flang introduced a FortranFrontend, but these days this seems unnecessary. Fortran can go through the same machinery as everything else. * Use the Preprocess phase to preprocess Fortran code. This phase is always combined with the Compile phase. * Use the Compile phase to lower Fortran code to LLVM IR, and use the Backend phase to compile and optimize the IR. These phases are never combined. * Remove FortranFrontendJobClass. * Remove FortranFrontend tool (instead it's just the Flang tool, which in Classic Flang mode is Classic Flang). * Update tests which inspect the output of the Classic Flang tooling, and ensures that the driver does the right thing for various types of inputs. Based on a patch from Peter Waller . --- clang/include/clang/Driver/Action.h | 11 ---- clang/include/clang/Driver/Phases.h | 1 - clang/include/clang/Driver/ToolChain.h | 2 - clang/include/clang/Driver/Types.def | 8 +-- clang/lib/Driver/Action.cpp | 7 --- clang/lib/Driver/Driver.cpp | 50 ++++++++----------- clang/lib/Driver/Phases.cpp | 1 - clang/lib/Driver/ToolChain.cpp | 21 ++------ clang/lib/Driver/ToolChains/ClassicFlang.h | 2 +- .../flang/classic-flang-must-preprocess.F | 12 +++++ .../flang/classic-flang-must-preprocess.F95 | 12 +++++ clang/test/Driver/flang/classic-flang.f | 26 ++++++++++ clang/test/Driver/flang/classic-flang.f95 | 43 ++++++++++++++++ clang/test/Driver/flang/classic_flang.f95 | 28 ----------- clang/test/Driver/lit.local.cfg | 3 ++ 15 files changed, 125 insertions(+), 102 deletions(-) create mode 100644 clang/test/Driver/flang/classic-flang-must-preprocess.F create mode 100644 clang/test/Driver/flang/classic-flang-must-preprocess.F95 create mode 100644 clang/test/Driver/flang/classic-flang.f create mode 100644 clang/test/Driver/flang/classic-flang.f95 delete mode 100644 clang/test/Driver/flang/classic_flang.f95 diff --git a/clang/include/clang/Driver/Action.h b/clang/include/clang/Driver/Action.h index 077800eaeb09..04fa8b01b418 100644 --- a/clang/include/clang/Driver/Action.h +++ b/clang/include/clang/Driver/Action.h @@ -62,7 +62,6 @@ public: AnalyzeJobClass, MigrateJobClass, CompileJobClass, - FortranFrontendJobClass, BackendJobClass, AssembleJobClass, LinkJobClass, @@ -471,16 +470,6 @@ public: } }; -class FortranFrontendJobAction : public JobAction { - void anchor() override; -public: - FortranFrontendJobAction(Action *Input, types::ID OutputType); - - static bool classof(const Action *A) { - return A->getKind() == FortranFrontendJobClass; - } -}; - class CompileJobAction : public JobAction { void anchor() override; diff --git a/clang/include/clang/Driver/Phases.h b/clang/include/clang/Driver/Phases.h index f8cac9548d02..9003c5857351 100644 --- a/clang/include/clang/Driver/Phases.h +++ b/clang/include/clang/Driver/Phases.h @@ -17,7 +17,6 @@ namespace phases { enum ID { Preprocess, Precompile, - FortranFrontend, Compile, Backend, Assemble, diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h index 9e3513a50915..735e72491488 100644 --- a/clang/include/clang/Driver/ToolChain.h +++ b/clang/include/clang/Driver/ToolChain.h @@ -151,7 +151,6 @@ private: mutable std::unique_ptr Clang; mutable std::unique_ptr Flang; - mutable std::unique_ptr FortranFrontend; mutable std::unique_ptr Assemble; mutable std::unique_ptr Link; mutable std::unique_ptr StaticLibTool; @@ -162,7 +161,6 @@ private: Tool *getClang() const; Tool *getFlang() const; - Tool *getFortranFrontend() const; Tool *getAssemble() const; Tool *getLink() const; Tool *getStaticLibTool() const; diff --git a/clang/include/clang/Driver/Types.def b/clang/include/clang/Driver/Types.def index 3085927e3680..2f241b02676b 100644 --- a/clang/include/clang/Driver/Types.def +++ b/clang/include/clang/Driver/Types.def @@ -78,10 +78,10 @@ TYPE("ada", Ada, INVALID, nullptr, phases TYPE("assembler", PP_Asm, INVALID, "s", phases::Assemble, phases::Link) TYPE("assembler-with-cpp", Asm, PP_Asm, "S", phases::Preprocess, phases::Assemble, phases::Link) #ifdef ENABLE_CLASSIC_FLANG -TYPE("f77", PP_F_FixedForm, INVALID, "f", phases::FortranFrontend, phases::Backend, phases::Assemble, phases::Link) -TYPE("f77-cpp-input", F_FixedForm, PP_F_FixedForm, "F", phases::FortranFrontend, phases::Backend, phases::Assemble, phases::Link) -TYPE("f95", PP_F_FreeForm, INVALID, "f95", phases::FortranFrontend, phases::Backend, phases::Assemble, phases::Link) -TYPE("f95-cpp-input", F_FreeForm, PP_F_FreeForm, "F95", phases::FortranFrontend, phases::Backend, phases::Assemble, phases::Link) +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, INVALID, "i", 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) diff --git a/clang/lib/Driver/Action.cpp b/clang/lib/Driver/Action.cpp index e81dbebd1db3..849bf6035ebd 100644 --- a/clang/lib/Driver/Action.cpp +++ b/clang/lib/Driver/Action.cpp @@ -29,7 +29,6 @@ const char *Action::getClassName(ActionClass AC) { return "api-extractor"; case AnalyzeJobClass: return "analyzer"; case MigrateJobClass: return "migrator"; - case FortranFrontendJobClass: return "fortran-frontend"; case CompileJobClass: return "compiler"; case BackendJobClass: return "backend"; case AssembleJobClass: return "assembler"; @@ -373,12 +372,6 @@ void MigrateJobAction::anchor() {} MigrateJobAction::MigrateJobAction(Action *Input, types::ID OutputType) : JobAction(MigrateJobClass, Input, OutputType) {} -void FortranFrontendJobAction::anchor() {} - -FortranFrontendJobAction::FortranFrontendJobAction(Action *Input, - types::ID OutputType) - : JobAction(FortranFrontendJobClass, Input, OutputType) {} - void CompileJobAction::anchor() {} CompileJobAction::CompileJobAction(Action *Input, types::ID OutputType) diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 3fafd43384e1..be8d421535ed 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -363,27 +363,15 @@ phases::ID Driver::getFinalPhase(const DerivedArgList &DAL, // -{E,EP,P,M,MM} only run the preprocessor. if (CCCIsCPP() || (PhaseArg = DAL.getLastArg(options::OPT_E)) || -#ifdef ENABLE_CLASSIC_FLANG - (PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) || -#endif (PhaseArg = DAL.getLastArg(options::OPT__SLASH_EP)) || (PhaseArg = DAL.getLastArg(options::OPT_M, options::OPT_MM)) || (PhaseArg = DAL.getLastArg(options::OPT__SLASH_P)) || CCGenDiagnostics) { #ifdef ENABLE_CLASSIC_FLANG - // -fsyntax-only or -E stops Fortran compilation after FortranFrontend - if (IsFlangMode() && (DAL.getLastArg(options::OPT_E) || - DAL.getLastArg(options::OPT_fsyntax_only))) { - FinalPhase = phases::FortranFrontend; - - // if not Fortran, fsyntax_only implies 'Compile' is the FinalPhase - } else if (DAL.getLastArg(options::OPT_fsyntax_only)) { + if (IsFlangMode()) FinalPhase = phases::Compile; - - // everything else has 'Preprocess' as its FinalPhase - } else { + else FinalPhase = phases::Preprocess; - } #else FinalPhase = phases::Preprocess; #endif @@ -397,14 +385,9 @@ phases::ID Driver::getFinalPhase(const DerivedArgList &DAL, options::OPT_fmodule_header_EQ))) { FinalPhase = phases::Precompile; -#ifdef ENABLE_CLASSIC_FLANG - // -{analyze,emit-ast} only run up to the compiler. - } else if ((PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) || -#else // -{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)) || -#endif (PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) || (PhaseArg = DAL.getLastArg(options::OPT_verify_pch)) || (PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) || @@ -4040,10 +4023,13 @@ void Driver::handleArguments(Compilation &C, DerivedArgList &Args, if (InputArg->isClaimed()) continue; - // Fortran input is preprocessed using the frontend. - if (InitialPhase == phases::FortranFrontend && +#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(); @@ -4759,13 +4745,6 @@ Action *Driver::ConstructPhaseAction( return C.MakeAction(Input, OutputTy); } - case phases::FortranFrontend: { - if (Args.hasArg(options::OPT_fsyntax_only)) - return C.MakeAction(Input, - types::TY_Nothing); - return C.MakeAction(Input, - types::TY_LLVM_IR); - } case phases::Compile: { if (Args.hasArg(options::OPT_fsyntax_only)) return C.MakeAction(Input, types::TY_Nothing); @@ -4786,6 +4765,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: { @@ -5240,6 +5223,10 @@ class ToolSelector final { if (!T->hasIntegratedBackend() && !(OutputIsLLVM && T->canEmitIR())) return nullptr; + // Classic Flang is not integrated with the backend. + if (C.getDriver().IsFlangMode() && !T->hasIntegratedAssembler()) + return nullptr; + if (T->canEmitIR() && ((SaveTemps && !InputIsBitcode) || EmbedBitcode)) return nullptr; @@ -6459,8 +6446,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)) + if (!isa(JA) && !isa(JA) +#ifndef ENABLE_CLASSIC_FLANG + && !isa(JA) +#endif + ) return false; return true; diff --git a/clang/lib/Driver/Phases.cpp b/clang/lib/Driver/Phases.cpp index f0216c5ab7c2..01598c59bd9e 100644 --- a/clang/lib/Driver/Phases.cpp +++ b/clang/lib/Driver/Phases.cpp @@ -16,7 +16,6 @@ const char *phases::getPhaseName(ID Id) { switch (Id) { case Preprocess: return "preprocessor"; case Precompile: return "precompiler"; - case FortranFrontend: return "fortran-frontend"; case Compile: return "compiler"; case Backend: return "backend"; case Assemble: return "assembler"; diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index 12fe81676804..70f1e0a37d17 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -443,13 +443,13 @@ Tool *ToolChain::getClang() const { } Tool *ToolChain::getFlang() const { -#ifndef ENABLE_CLASSIC_FLANG if (!Flang) - Flang.reset(new tools::Flang(*this)); - return Flang.get(); +#ifdef ENABLE_CLASSIC_FLANG + Flang.reset(new tools::ClassicFlang(*this)); #else - llvm_unreachable("Flang is not supported by this toolchain"); + Flang.reset(new tools::Flang(*this)); #endif + return Flang.get(); } Tool *ToolChain::buildAssembler() const { @@ -470,16 +470,6 @@ Tool *ToolChain::getAssemble() const { return Assemble.get(); } -Tool *ToolChain::getFortranFrontend() const { -#ifdef ENABLE_CLASSIC_FLANG - if (!FortranFrontend) - FortranFrontend.reset(new tools::ClassicFlang(*this)); - return FortranFrontend.get(); -#else - llvm_unreachable("Fortran is not supported by this toolchain"); -#endif -} - Tool *ToolChain::getClangAs() const { if (!Assemble) Assemble.reset(new tools::ClangAs(*this)); @@ -563,9 +553,6 @@ Tool *ToolChain::getTool(Action::ActionClass AC) const { return getOffloadPackager(); case Action::LinkerWrapperJobClass: return getLinkerWrapper(); - - case Action::FortranFrontendJobClass: - return getFortranFrontend(); } llvm_unreachable("Invalid tool kind."); diff --git a/clang/lib/Driver/ToolChains/ClassicFlang.h b/clang/lib/Driver/ToolChains/ClassicFlang.h index 23ea1fe6b95d..5af119c2f79e 100644 --- a/clang/lib/Driver/ToolChains/ClassicFlang.h +++ b/clang/lib/Driver/ToolChains/ClassicFlang.h @@ -33,7 +33,7 @@ public: bool hasGoodDiagnostics() const override { return true; } bool hasIntegratedAssembler() const override { return false; } - bool hasIntegratedCPP() const override { return false; } + bool hasIntegratedCPP() const override { return true; } void ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, 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..d52c1cf8d3c0 --- /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..7d452a535784 --- /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.f b/clang/test/Driver/flang/classic-flang.f new file mode 100644 index 000000000000..98f74d9626d7 --- /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..0b92c799392a --- /dev/null +++ b/clang/test/Driver/flang/classic-flang.f95 @@ -0,0 +1,43 @@ +! REQUIRES: classic_flang + +! Check that the driver invokes flang1 correctly for preprocessed free-form +! Fortran code. Also check that the backend is invoked correctly. + +! RUN: %clang --driver-mode=flang -target x86_64-unknown-linux-gnu -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: "-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. + +! RUN: %clang --driver-mode=flang -target x86_64-unknown-linux-gnu -integrated-as -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: "-o" "classic-flang.s" +! CHECK-ASM-SAME: "-x" "ir" +! CHECK-ASM-SAME: [[LLFILE]] diff --git a/clang/test/Driver/flang/classic_flang.f95 b/clang/test/Driver/flang/classic_flang.f95 deleted file mode 100644 index 5d3098786905..000000000000 --- a/clang/test/Driver/flang/classic_flang.f95 +++ /dev/null @@ -1,28 +0,0 @@ -! Check that the driver can invoke flang1 and flang2 to compile Fortran with -! --driver-mode=flang (default when the file extension is .f95). - -! REQUIRES: 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: flang1 -! CHECK-OBJECT: flang2 -! CHECK-OBJECT-SAME: "-asm" [[LLFILE:.*.ll]] -! CHECK-OBJECT-NOT: cc1as -! CHECK-OBJECT: clang -! CHECK-OBJECT-SAME: -cc1 -! CHECK-OBJECT-SAME: "-o" "classic_flang.o" -! CHECK-OBJECT-SAME: "-x" "ir" -! CHECK-OBJECT-SAME: [[LLFILE]] - -! RUN: %clang -target x86_64-unknown-linux-gnu -integrated-as -S %s -### 2>&1 \ -! RUN: | FileCheck --check-prefix=CHECK-ASM %s -! CHECK-ASM: flang1 -! CHECK-ASM: flang2 -! CHECK-ASM-SAME: "-asm" [[LLFILE:.*.ll]] -! CHECK-ASM-NOT: cc1as -! CHECK-ASM: clang -! CHECK-ASM-SAME: -cc1 -! CHECK-ASM-SAME: "-o" "classic_flang.s" -! CHECK-ASM-SAME: "-x" "ir" -! CHECK-ASM-SAME: [[LLFILE]] 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", -- Gitee From 7cfa5a4a6b5c48037b74efc7ad2f2fbe6791ba75 Mon Sep 17 00:00:00 2001 From: Sourabh Singh Tomar Date: Fri, 16 Apr 2021 12:29:12 +0530 Subject: [PATCH 05/47] [DebugInfo] Support of `-gpubnames` in Driver --- clang/lib/Driver/ToolChains/ClassicFlang.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/clang/lib/Driver/ToolChains/ClassicFlang.cpp b/clang/lib/Driver/ToolChains/ClassicFlang.cpp index ce2d62f87399..9a8a640cc6e5 100644 --- a/clang/lib/Driver/ToolChains/ClassicFlang.cpp +++ b/clang/lib/Driver/ToolChains/ClassicFlang.cpp @@ -355,6 +355,13 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, 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 -- Gitee From f41eebfe12c7d43d73841c81c14c8f8c03690c51 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Fri, 6 Aug 2021 05:10:31 -0700 Subject: [PATCH 06/47] [Driver] Support macOS --- clang/lib/Driver/ToolChain.cpp | 4 +++- clang/lib/Driver/ToolChains/Darwin.cpp | 12 ++++++++++++ clang/lib/Driver/ToolChains/Gnu.cpp | 2 +- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index 70f1e0a37d17..e63feeb69566 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -1264,7 +1264,9 @@ void ToolChain::AddFortranStdlibLibArgs(const ArgList &Args, CmdArgs.push_back("-Bdynamic"); CmdArgs.push_back("-lm"); - CmdArgs.push_back("-lrt"); + + if (!Triple.isOSDarwin()) + CmdArgs.push_back("-lrt"); // Allways link Fortran executables with Pthreads CmdArgs.push_back("-lpthread"); diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp index 65bd6c6a7eb3..022195f2b2a5 100644 --- a/clang/lib/Driver/ToolChains/Darwin.cpp +++ b/clang/lib/Driver/ToolChains/Darwin.cpp @@ -718,6 +718,18 @@ void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA, if (getToolChain().ShouldLinkCXXStdlib(Args)) getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs); +#ifdef ENABLE_CLASSIC_FLANG + // Add Fortran runtime libraries + if (needFortranLibs(getToolChain().getDriver(), Args)) { + getToolChain().AddFortranStdlibLibArgs(Args, CmdArgs); + } else { + // Claim "no Flang libraries" arguments if any + for (auto Arg : Args.filtered(options::OPT_noFlangLibs)) { + Arg->claim(); + } + } +#endif + bool NoStdOrDefaultLibs = Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs); bool ForceLinkBuiltins = Args.hasArg(options::OPT_fapple_link_rtlib); diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp index 5c8b92bcc0d6..fc5e12450ceb 100644 --- a/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/clang/lib/Driver/ToolChains/Gnu.cpp @@ -559,7 +559,7 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, if (needFortranLibs(D, Args)) { ToolChain.AddFortranStdlibLibArgs(Args, CmdArgs); } else { - // Claim "no Flang libraries" arguments if any + // Claim "no Flang libraries" arguments if any for (auto Arg : Args.filtered(options::OPT_noFlangLibs)) { Arg->claim(); } -- Gitee From ffb0f2a408b0a96e721d04ea41b1cffdb50b4751 Mon Sep 17 00:00:00 2001 From: Itay Bookstein Date: Wed, 22 Sep 2021 16:56:52 +0300 Subject: [PATCH 07/47] [DebugInfo]: Remove dangerous dead function (-Wreturn-stack-address) Signed-off-by: Itay Bookstein --- llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h | 8 -------- llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 6 ------ 2 files changed, 14 deletions(-) diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h index 17be1c4796f7..6ef73ebd4f7f 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h @@ -158,14 +158,6 @@ public: std::vector ExprRefedBaseTypes; -private: - DenseMap> *globalVarMap; -public: - void setGlobalVarMap( - DenseMap> *p = nullptr) { - globalVarMap = p; - } - /// Get or create global variable DIE. DIE * getOrCreateGlobalVariableDIE(const DIGlobalVariable *GV, diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 16cae978d177..cdcd7bf3145f 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -1225,17 +1225,11 @@ void DwarfDebug::beginModule(Module *M) { } DenseSet Processed; -#if 0 - CU.setGlobalVarMap(&GVMap); -#endif for (auto *GVE : CUNode->getGlobalVariables()) { DIGlobalVariable *GV = GVE->getVariable(); if (Processed.insert(GV).second) CU.getOrCreateGlobalVariableDIE(GV, sortGlobalExprs(GVMap[GV])); } -#if 0 - CU.setGlobalVarMap(); -#endif for (auto *Ty : CUNode->getEnumTypes()) CU.getOrCreateTypeDIE(cast(Ty)); -- Gitee From d10e308c5d7cf961b04bc729854970f1f74ad881 Mon Sep 17 00:00:00 2001 From: Itay Bookstein Date: Wed, 22 Sep 2021 17:12:19 +0300 Subject: [PATCH 08/47] [ClassicFlang][Driver] Fix warnings * -Wsuggest-override for ClassicFlangMacroBuilder::defineMacro * -Wrange-loop-construct when iterating over llvm::opt::Arg::getValues Signed-off-by: Itay Bookstein --- clang/lib/Driver/ToolChains/Clang.cpp | 4 ++-- clang/lib/Driver/ToolChains/ClassicFlang.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 3cd4089c917b..c5ba8a690687 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -5378,7 +5378,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, PassRemarkVal = ".*"; Args.ClaimAllArgs(options::OPT_Minfoall); } else if (Arg *A = Args.getLastArg(options::OPT_Minfo_EQ)) { - for (const StringRef &val : A->getValues()) { + for (StringRef val : A->getValues()) { if (val.equals("all")) { PassRemarkVal = ".*"; break; @@ -5404,7 +5404,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, PassRemarkVal = ".*"; Args.ClaimAllArgs(options::OPT_Mneginfoall); } else if (Arg *A = Args.getLastArg(options::OPT_Mneginfo_EQ)) { - for (const StringRef &val : A->getValues()) { + for (StringRef val : A->getValues()) { if (val.equals("all")) { PassRemarkVal = ".*"; break; diff --git a/clang/lib/Driver/ToolChains/ClassicFlang.cpp b/clang/lib/Driver/ToolChains/ClassicFlang.cpp index 9a8a640cc6e5..53deef2dcdcc 100644 --- a/clang/lib/Driver/ToolChains/ClassicFlang.cpp +++ b/clang/lib/Driver/ToolChains/ClassicFlang.cpp @@ -50,7 +50,7 @@ class ClassicFlangMacroBuilder : public MacroBuilder { 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") { + virtual void defineMacro(const Twine &Name, const Twine &Value = "1") override { CmdArgs.push_back("-def"); CmdArgs.push_back(DriverArgs.MakeArgString(Name + Twine('=') + Value)); } @@ -212,7 +212,7 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, // Contiguous pointer checks if (Arg *A = Args.getLastArg(options::OPT_fsanitize_EQ)) { - for (const StringRef &val : A->getValues()) { + for (StringRef val : A->getValues()) { if (val.equals("discontiguous") || val.equals("undefined") ) { // -x 54 0x40 -x 54 0x80 -x 54 0x200 UpperCmdArgs.push_back("-x"); -- Gitee From 4047987dda25ad70f6037b116563582a2da03a76 Mon Sep 17 00:00:00 2001 From: Richard Barton Date: Wed, 26 Jan 2022 17:30:32 +0000 Subject: [PATCH 09/47] [driver] Add -emit-flang-llvm option -emit-flang-llvm instructs flang to stop after flang2 and dump the LLVM IR. Can be useful for debugging and also would be a useful option for testing flang output more accurately. Signed-off-by: Richard Barton --- clang/include/clang/Driver/Options.td | 4 ++++ clang/lib/Driver/Driver.cpp | 3 +++ clang/lib/Driver/ToolChains/ClassicFlang.cpp | 7 +++++++ 3 files changed, 14 insertions(+) diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 9eb398020df1..3d7fa803c504 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -1187,6 +1187,10 @@ def d_Flag : Flag<["-"], "d">, Group; def d_Joined : Joined<["-"], "d">, Group; def emit_ast : Flag<["-"], "emit-ast">, Flags<[CoreOption]>, HelpText<"Emit Clang AST files for source inputs">; +#ifdef ENABLE_CLASSIC_FLANG +def emit_flang_llvm : Flag<["-"], "emit-flang-llvm">, + HelpText<"Emit Flang LLVM files for source inputs">; +#endif def emit_llvm : Flag<["-"], "emit-llvm">, Flags<[CC1Option, FC1Option, FlangOption]>, Group, HelpText<"Use the LLVM representation for assembler and object files">; def emit_interface_stubs : Flag<["-"], "emit-interface-stubs">, Flags<[CC1Option]>, Group, diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index be8d421535ed..a22b9a9b6b51 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -389,6 +389,9 @@ phases::ID Driver::getFinalPhase(const DerivedArgList &DAL, } else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) || (PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) || (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)) || diff --git a/clang/lib/Driver/ToolChains/ClassicFlang.cpp b/clang/lib/Driver/ToolChains/ClassicFlang.cpp index 53deef2dcdcc..fcc0e13a80c2 100644 --- a/clang/lib/Driver/ToolChains/ClassicFlang.cpp +++ b/clang/lib/Driver/ToolChains/ClassicFlang.cpp @@ -86,6 +86,13 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, 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()); -- Gitee From c0bea773fbe56b0d3d3b85b249d0eccb1d646aed Mon Sep 17 00:00:00 2001 From: Richard Barton Date: Tue, 1 Feb 2022 08:21:08 +0000 Subject: [PATCH 10/47] [driver] Add regression test --- .../Driver/flang/classic-flang-emit-flang-llvm.f95 | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 clang/test/Driver/flang/classic-flang-emit-flang-llvm.f95 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" -- Gitee From 0563b04a6a42c3e1a202227c5ef0a30c1de8ed12 Mon Sep 17 00:00:00 2001 From: Richard Barton Date: Mon, 15 Nov 2021 09:47:24 +0000 Subject: [PATCH 11/47] [driver] Add infrastructure for testing the flang-driver in lit Add %flang as a tool substitution available in lit tests. This apes the way %clang is defined and adds a $FLANG override in a similar vein. To avoid this being dead code, add a single test to check the flang driver is reporting the correct phases when running under various phase control options. Signed-off-by: Richard Barton --- clang/test/Driver/fortran-phases.f90 | 102 +++++++++++++++++++++++++++ llvm/utils/lit/lit/TestingConfig.py | 1 + llvm/utils/lit/lit/llvm/config.py | 10 +++ 3 files changed, 113 insertions(+) create mode 100644 clang/test/Driver/fortran-phases.f90 diff --git a/clang/test/Driver/fortran-phases.f90 b/clang/test/Driver/fortran-phases.f90 new file mode 100644 index 000000000000..5a79bb26bcde --- /dev/null +++ b/clang/test/Driver/fortran-phases.f90 @@ -0,0 +1,102 @@ +! 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 -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 -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: 4: linker, {3}, image + +! AONLY-NOPP: 0: input, {{.*}}, f95 +! AONLY-NOPP: 1: compiler, {0}, ir +! AONLY-NOPP: 2: backend, {1}, assembler +! AONLY-NOPP-NOT: 3: assembler, {2}, object +! AONLY-NOPP-NOT: 4: linker, {3}, image + +! LLONLY-NOPP: 0: input, {{.*}}, f95 +! LLONLY-NOPP: 1: compiler, {0}, ir +! LLONLY-NOPP-NOT: 2: backend, {1}, assembler +! LLONLY-NOPP-NOT: 3: assembler, {2}, object +! LLONLY-NOPP-NOT: 4: linker, {3}, image + +! SONLY-NOPP: 0: input, {{.*}}, f95 +! SONLY-NOPP-NOT: 1: compiler, {0}, ir +! SONLY-NOPP-NOT: 2: backend, {1}, assembler +! SONLY-NOPP-NOT: 3: assembler, {2}, object +! SONLY-NOPP-NOT: 4: linker, {3}, image + +! PPONLY-NOPP: 0: input, {{.*}}, f95 +! PPONLY-NOPP: 1: compiler, {0}, ir +! PPONLY-NOPP-NOT: 2: backend, {1}, assembler +! PPONLY-NOPP-NOT: 3: assembler, {2}, object +! PPONLY-NOPP-NOT: 4: linker, {3}, 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: 5: linker, {4}, image + +! AONLY: 0: input, {{.*}}, f95-cpp-input +! AONLY: 1: preprocessor, {0}, f95 +! AONLY: 2: compiler, {1}, ir +! AONLY: 3: backend, {2}, assembler +! AONLY-NOT: 4: assembler, {3}, object +! AONLY-NOT: 5: linker, {4}, image + +! LLONLY: 0: input, {{.*}}, f95-cpp-input +! LLONLY: 1: preprocessor, {0}, f95 +! LLONLY: 2: compiler, {1}, ir +! LLONLY-NOT: 3: backend, {2}, assembler +! LLONLY-NOT: 4: assembler, {3}, object +! LLONLY-NOT: 5: linker, {4}, image + +! SONLY: 0: input, {{.*}}, f95-cpp-input +! SONLY: 1: preprocessor, {0}, f95 +! SONLY-NOT: 2: compiler, {1}, ir +! SONLY-NOT: 3: backend, {2}, assembler +! SONLY-NOT: 4: assembler, {3}, object +! SONLY-NOT: 5: linker, {4}, image + +! PPONLY: 0: input, {{.*}}, f95-cpp-input +! PPONLY: 1: preprocessor, {0}, f95 +! PPONLY: 2: compiler, {1}, ir +! PPONLY-NOT: 3: backend, {2}, assembler +! PPONLY-NOT: 4: assembler, {3}, object +! PPONLY-NOT: 5: linker, {4}, image + +program hello + write(*, *) "Hello" +end program hello diff --git a/llvm/utils/lit/lit/TestingConfig.py b/llvm/utils/lit/lit/TestingConfig.py index 76fd66502009..399b74c4f00d 100644 --- a/llvm/utils/lit/lit/TestingConfig.py +++ b/llvm/utils/lit/lit/TestingConfig.py @@ -26,6 +26,7 @@ class TestingConfig(object): "SYSTEMROOT", "TERM", "CLANG", + "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 16cc2968034b..d8dec6160071 100644 --- a/llvm/utils/lit/lit/llvm/config.py +++ b/llvm/utils/lit/lit/llvm/config.py @@ -500,6 +500,8 @@ class LLVMConfig(object): 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. # @@ -631,6 +633,14 @@ class LLVMConfig(object): 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) + self.config.substitutions.append( ( "%itanium_abi_triple", -- Gitee From 9727e7af4303690d6310e789e6afd11c4373d34e Mon Sep 17 00:00:00 2001 From: Bryan Chan Date: Mon, 25 Apr 2022 15:18:45 -0400 Subject: [PATCH 12/47] [LoopVectorize] Revert Classic Flang patch causing AArch64 test failure This patch partially reverts the following commit from an early version of Classic Flang LLVM: https://github.com/flang-compiler/llvm/commit/68669092a5ad1fd29f62346dc30973f86cfacbfe When the LoopVectorize.cpp change in that commit is ported to LLVM 14, it causes a failure in the following test: llvm/test/Transforms/LoopVectorize/AArch64/smallest-and-widest-types.ll Reverting the change allows all tests to run cleanly. --- llvm/lib/Transforms/Vectorize/LoopVectorize.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp index 3451db126afd..b603bbe55dc9 100644 --- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -5766,10 +5766,8 @@ void LoopVectorizationCostModel::collectElementTypesForWidening() { if (ValuesToIgnore.count(&I)) continue; - // Examine Loads, Stores, PHINodes - // Also examine instructions which convert to a float/double - if (!isa(I) && !isa(I) && !isa(I) && - !isa(I) && !isa(I) && !isa(I)) + // Only examine Loads, Stores and PHINodes. + if (!isa(I) && !isa(I) && !isa(I)) continue; // Examine PHI nodes that are reduction variables. Update the type to -- Gitee From 6a03555f54eb25282e2f3fb2e481e36de75362e3 Mon Sep 17 00:00:00 2001 From: Richard Barton Date: Fri, 12 Nov 2021 17:10:05 +0000 Subject: [PATCH 13/47] [driver] Pass LLVM target_features to flang Port commit 64bf2a644bba to LLVM 16 and resolve merge conflicts. The original commit message follows: Pass LLVM target features (-mattr strings) to flang to embed in generated .ll files. For normal compilation this won't make much difference as the attributes are passed to clang after flang2 and can be applied there but this is crucial to enable LTO with flang as clang will not apply the attributes when building the flang2 output. libLTO will need to read these out of the object files to apply them. Signed-off-by: Richard Barton --- clang/lib/Driver/ToolChains/ClassicFlang.cpp | 32 +++++++++++++++----- clang/lib/Driver/ToolChains/CommonArgs.cpp | 17 +++++++++++ clang/lib/Driver/ToolChains/CommonArgs.h | 11 +++++++ clang/test/Driver/emit-flang-attrs.f90 | 11 +++++++ 4 files changed, 64 insertions(+), 7 deletions(-) create mode 100644 clang/test/Driver/emit-flang-attrs.f90 diff --git a/clang/lib/Driver/ToolChains/ClassicFlang.cpp b/clang/lib/Driver/ToolChains/ClassicFlang.cpp index fcc0e13a80c2..340fa8936181 100644 --- a/clang/lib/Driver/ToolChains/ClassicFlang.cpp +++ b/clang/lib/Driver/ToolChains/ClassicFlang.cpp @@ -59,6 +59,8 @@ class ClassicFlangMacroBuilder : public MacroBuilder { 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; @@ -373,13 +375,13 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, // -Mipa has no effect if (Arg *A = Args.getLastArg(options::OPT_Mipa)) { - getToolChain().getDriver().Diag(diag::warn_drv_clang_unsupported) + D.Diag(diag::warn_drv_clang_unsupported) << A->getAsString(Args); } // -Minline has no effect if (Arg *A = Args.getLastArg(options::OPT_Minline_on)) { - getToolChain().getDriver().Diag(diag::warn_drv_clang_unsupported) + D.Diag(diag::warn_drv_clang_unsupported) << A->getAsString(Args); } @@ -653,14 +655,14 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, // Use clang's predefined macros DiagnosticsEngine DE(new DiagnosticIDs(), new DiagnosticOptions, new IgnoringDiagConsumer()); std::shared_ptr TO = std::make_shared(); - TO->Triple = getToolChain().getEffectiveTriple().getTriple(); + 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(&getToolChain().getDriver(), Args); + 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. @@ -693,7 +695,7 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, DefineTypeSize("__LONG_MAX__", TargetInfo::SignedLong, *TI, Builder); // Add additional predefined macros - switch (getToolChain().getEffectiveTriple().getArch()) { + switch (Triple.getArch()) { case llvm::Triple::aarch64: UpperCmdArgs.push_back("-def"); UpperCmdArgs.push_back("__ARM_ARCH__=8"); break; @@ -787,7 +789,7 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, Arg->claim(); UpperCmdArgs.push_back("-extend"); } else { - getToolChain().getDriver().Diag(diag::err_drv_unsupported_fixed_line_length) + D.Diag(diag::err_drv_unsupported_fixed_line_length) << Arg->getAsString(Args); } } @@ -831,7 +833,7 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, } else if (Value == "95") { // Enable Fortran 2003 semantics UpperCmdArgs.push_back("-y"); // Unset XBIT } else { - getToolChain().getDriver().Diag(diag::err_drv_invalid_allocatable_mode) + D.Diag(diag::err_drv_invalid_allocatable_mode) << A->getAsString(Args); } } else { // No argument passed @@ -981,6 +983,22 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, // 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 (unsigned I = 0, N = Features.size(); I < N; ++I) { + StringRef Name = Features[I]; + FeatureList += Name.str(); + if (I < (N - 1)) + FeatureList += ','; + } + + LowerCmdArgs.push_back("-target_features"); + LowerCmdArgs.push_back(Args.MakeArgString(FeatureList)); + } + // Set a -x flag for second part of Fortran frontend for (Arg *A : Args.filtered(options::OPT_Mx_EQ)) { A->claim(); diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index 5e66d347d0ad..125ec9de5062 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -530,10 +530,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; @@ -608,6 +616,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"); diff --git a/clang/lib/Driver/ToolChains/CommonArgs.h b/clang/lib/Driver/ToolChains/CommonArgs.h index 740c235a37a5..dfade523bb80 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.h +++ b/clang/lib/Driver/ToolChains/CommonArgs.h @@ -177,6 +177,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/test/Driver/emit-flang-attrs.f90 b/clang/test/Driver/emit-flang-attrs.f90 new file mode 100644 index 000000000000..91331ac227fa --- /dev/null +++ b/clang/test/Driver/emit-flang-attrs.f90 @@ -0,0 +1,11 @@ +// 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 +// CHECK-ATTRS-NEON: "{{.*}}flang2" +// CHECK-ATTRS-NEON-SAME: "-target_features" "+neon,+v8a +// CHECK-ATTRS-SVE: "{{.*}}flang2" +// CHECK-ATTRS-SVE-SAME: "-target_features" "+neon,+v8a,+sve +// CHECK-ATTRS-NOSVE: "{{.*}}flang2" +// CHECK-ATTRS-NOSVE-SAME: "-target_features" "+neon,+v8a,-sve -- Gitee From 44c210b4268dfa2422cfcec96d434d816763b46b Mon Sep 17 00:00:00 2001 From: Richard Barton Date: Thu, 18 Nov 2021 11:16:20 +0000 Subject: [PATCH 14/47] [flang-driver] Uniquify the target_features string Use existing clang support for uniquifying target feature lists to pass a unique list through to flang. --- clang/lib/Driver/ToolChains/ClassicFlang.cpp | 7 +++---- clang/test/Driver/emit-flang-attrs.f90 | 1 + 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/clang/lib/Driver/ToolChains/ClassicFlang.cpp b/clang/lib/Driver/ToolChains/ClassicFlang.cpp index 340fa8936181..cbc18846dabc 100644 --- a/clang/lib/Driver/ToolChains/ClassicFlang.cpp +++ b/clang/lib/Driver/ToolChains/ClassicFlang.cpp @@ -988,11 +988,10 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, std::string FeatureList = ""; getTargetFeatureList(D, Triple, Args, UpperCmdArgs, false, Features); if (!Features.empty()) { - for (unsigned I = 0, N = Features.size(); I < N; ++I) { - StringRef Name = Features[I]; - FeatureList += Name.str(); - if (I < (N - 1)) + for (auto Feature : unifyTargetFeatures(Features)) { + if (!FeatureList.empty()) FeatureList += ','; + FeatureList += Feature; } LowerCmdArgs.push_back("-target_features"); diff --git a/clang/test/Driver/emit-flang-attrs.f90 b/clang/test/Driver/emit-flang-attrs.f90 index 91331ac227fa..d9a2ea954f80 100644 --- a/clang/test/Driver/emit-flang-attrs.f90 +++ b/clang/test/Driver/emit-flang-attrs.f90 @@ -3,6 +3,7 @@ // 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-NOSVE %s // CHECK-ATTRS-NEON: "{{.*}}flang2" // CHECK-ATTRS-NEON-SAME: "-target_features" "+neon,+v8a // CHECK-ATTRS-SVE: "{{.*}}flang2" -- Gitee From 7d1ce4074b4624d0180999241e35405c9c108cfe Mon Sep 17 00:00:00 2001 From: Paul Osmialowski Date: Fri, 21 Jan 2022 10:00:58 +0000 Subject: [PATCH 15/47] [driver] Pass msve-vector-bits to flang as vscale range Signed-off-by: Paul Osmialowski --- clang/lib/Driver/ToolChains/ClassicFlang.cpp | 34 ++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/clang/lib/Driver/ToolChains/ClassicFlang.cpp b/clang/lib/Driver/ToolChains/ClassicFlang.cpp index cbc18846dabc..4f3fd6077f76 100644 --- a/clang/lib/Driver/ToolChains/ClassicFlang.cpp +++ b/clang/lib/Driver/ToolChains/ClassicFlang.cpp @@ -998,6 +998,40 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, LowerCmdArgs.push_back(Args.MakeArgString(FeatureList)); } + // Add vscale range + unsigned vscaleMin = 1U; + unsigned vscaleMax = 16U; + bool hasVscaleRange = false; + if (Arg *A = Args.getLastArg(options::OPT_msve_vector_bits_EQ)) { + StringRef Val = A->getValue(); + + if (Val.equals("scalable")) + hasVscaleRange = true; + else { + unsigned bits = (std::stoul(Val.str()) >> 7U); + + if ((bits < vscaleMin) || (bits > vscaleMax)) { + D.Diag(diag::warn_drv_clang_unsupported) << A->getAsString(Args); + hasVscaleRange = false; + } else { + vscaleMin = vscaleMax = bits; + hasVscaleRange = true; + } + } + } + for (auto Feature : unifyTargetFeatures(Features)) { + if (Feature.startswith("+sve")) { + hasVscaleRange = true; + break; + } + } + if (hasVscaleRange) { + LowerCmdArgs.push_back("-vscale_range_min"); + LowerCmdArgs.push_back(Args.MakeArgString(std::to_string(vscaleMin))); + LowerCmdArgs.push_back("-vscale_range_max"); + LowerCmdArgs.push_back(Args.MakeArgString(std::to_string(vscaleMax))); + } + // Set a -x flag for second part of Fortran frontend for (Arg *A : Args.filtered(options::OPT_Mx_EQ)) { A->claim(); -- Gitee From a3ef41f3989bcd480c514835fc222c3eb2c0f275 Mon Sep 17 00:00:00 2001 From: pwisniewskimobica Date: Thu, 13 Jan 2022 10:11:43 +0100 Subject: [PATCH 16/47] [Driver][Test] Add more variants to test/Driver/emit-flang-attrs.f90 --- clang/test/Driver/emit-flang-attrs.f90 | 70 +++++++++++++++++++++----- 1 file changed, 58 insertions(+), 12 deletions(-) diff --git a/clang/test/Driver/emit-flang-attrs.f90 b/clang/test/Driver/emit-flang-attrs.f90 index d9a2ea954f80..df23a8aa6e87 100644 --- a/clang/test/Driver/emit-flang-attrs.f90 +++ b/clang/test/Driver/emit-flang-attrs.f90 @@ -1,12 +1,58 @@ -// 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-NOSVE %s -// CHECK-ATTRS-NEON: "{{.*}}flang2" -// CHECK-ATTRS-NEON-SAME: "-target_features" "+neon,+v8a -// CHECK-ATTRS-SVE: "{{.*}}flang2" -// CHECK-ATTRS-SVE-SAME: "-target_features" "+neon,+v8a,+sve -// CHECK-ATTRS-NOSVE: "{{.*}}flang2" -// CHECK-ATTRS-NOSVE-SAME: "-target_features" "+neon,+v8a,-sve +! 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-NOSVE %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" "+neon,+v8a" +! CHECK-ATTRS-SVE: "{{.*}}flang2" +! CHECK-ATTRS-SVE-SAME: "-target_features" "+neon,+v8a,+sve" +! CHECK-ATTRS-NOSVE: "{{.*}}flang2" +! CHECK-ATTRS-NOSVE-SAME: "-target_features" "+neon,+v8a,-sve,-sve2,-sve2-bitperm,-sve2-sha3,-sve2-aes,-sve2-sm4" +! CHECK-SVE2-REVERT: "{{.*}}flang2" +! CHECK-SVE2-REVERT-SAME: "-target_features" "+neon,+v8a,+sve,-sve2,-sve2-bitperm,-sve2-sha3,-sve2-aes,-sve2-sm4" +! CHECK-SVE2-AES: "{{.*}}flang2" +! CHECK-SVE2-AES-SAME: "-target_features" "+neon,+v8a,+sve2-aes,+sve,+sve2" +! CHECK-SVE2-SM4: "{{.*}}flang2" +! CHECK-SVE2-SM4-SAME: "-target_features" "+neon,+v8a,+sve2-sm4,+sve,+sve2" +! CHECK-SVE2-SHA3: "{{.*}}flang2" +! CHECK-SVE2-SHA3-SAME: "-target_features" "+neon,+v8a,+sve2-sha3,+sve,+sve2" +! CHECK-SVE2-BITPERM-REVERT: "{{.*}}flang2" +! CHECK-SVE2-BITPERM-REVERT-SAME: "-target_features" "+neon,+v8a,+sve,+sve2,-sve2-bitperm" +! CHECK-SVE2-IMPLY: "{{.*}}flang2" +! CHECK-SVE2-IMPLY-SAME: "-target_features" "+neon,+v8a,+sve2,+sve" +! CHECK-SVE2-CONFLICT-REV: "{{.*}}flang2" +! CHECK-SVE2-CONFLICT-REV-SAME: "-target_features" "+neon,+v8a,-sve2-bitperm,-sve2-sha3,-sve2-aes,-sve2-sm4,+sve2,+sve" +! CHECK-SVE-SVE2: "{{.*}}flang2" +! CHECK-SVE-SVE2-SAME: "-target_features" "+neon,+v8a,+sve2,+sve" +! CHECK-SVE2-BITPERM: "{{.*}}flang2" +! CHECK-SVE2-BITPERM-SAME: "-target_features" "+neon,+v8a,+sve2-bitperm,+sve,+sve2" +! CHECK-SVE-SUBFEATURE-CONFLICT-REV: "{{.*}}flang2" +! CHECK-SVE-SUBFEATURE-CONFLICT-REV-SAME: "-target_features" "+neon,+v8a,-sve2-bitperm,-sve2-sha3,-sve2-sm4,+sve2-aes,+sve,+sve2" +! CHECK-SVE2-SUBFEATURE-CONFLICT: "{{.*}}flang2" +! CHECK-SVE2-SUBFEATURE-CONFLICT-SAME: "-target_features" "+neon,+v8a,+sve,-sve2,-sve2-bitperm,-sve2-sha3,-sve2-aes,-sve2-sm4" +! CHECK-SVE2-SUBFEATURE-MIX: "{{.*}}flang2" +! CHECK-SVE2-SUBFEATURE-MIX-SAME: "-target_features" "+neon,+v8a,+sve2-bitperm,+sve,+sve2,-sve2-aes" +! CHECK-SVE2-SM4-REVERT: "{{.*}}flang2" +! CHECK-SVE2-SM4-REVERT-SAME: "-target_features" "+neon,+v8a,+sve,+sve2,-sve2-sm4" +! CHECK-SVE2-SHA3-REVERT: "{{.*}}flang2" +! CHECK-SVE2-SHA3-REVERT-SAME: "-target_features" "+neon,+v8a,+sve,+sve2,-sve2-sha3" +! CHECK-SVE2-AES-REVERT: "{{.*}}flang2" +! CHECK-SVE2-AES-REVERT-SAME: "-target_features" "+neon,+v8a,+sve,+sve2,-sve2-aes" -- Gitee From 065924139fc405ba11c35f6bbfa6b41496f5487b Mon Sep 17 00:00:00 2001 From: Richard Barton Date: Tue, 22 Mar 2022 09:26:00 +0000 Subject: [PATCH 17/47] Fix classic flang version screen Version screen has been erroneously reporting as flang-new since LLVM 12 --- clang/lib/Driver/Driver.cpp | 4 ++++ clang/test/Driver/flang/classic-flang-version.f | 3 +++ 2 files changed, 7 insertions(+) create mode 100644 clang/test/Driver/flang/classic-flang-version.f diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index a22b9a9b6b51..09345113f72d 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -1994,7 +1994,11 @@ void Driver::PrintHelp(bool ShowHidden) const { void Driver::PrintVersion(const Compilation &C, raw_ostream &OS) const { if (IsFlangMode()) { +#ifdef ENABLE_CLASSIC_FLANG + OS << getClangToolFullVersion("flang") << '\n'; +#else OS << getClangToolFullVersion("flang-new") << '\n'; +#endif } else { // FIXME: The following handlers should use a callback mechanism, we don't // know what the client would like to do. 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 {{.*}}) -- Gitee From 717a9c60503608a139bcdf318070fc7265762ed9 Mon Sep 17 00:00:00 2001 From: Richard Barton Date: Fri, 18 Mar 2022 16:47:15 +0000 Subject: [PATCH 18/47] Canonicalize some ENABLE_CLASSIC_FLANG These CMake variables are used to set python variables in the lit config. As such, they need to bet set with a valid CMake boolean value that is also a valid python boolean value (1, True, etc.) and not one that is not (ON, NO, etc.) to work. This is fragile. Call the LLVM cmake helper function on these two downstream CMake --- clang/test/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/clang/test/CMakeLists.txt b/clang/test/CMakeLists.txt index 31b494f39cce..b88694deb818 100644 --- a/clang/test/CMakeLists.txt +++ b/clang/test/CMakeLists.txt @@ -10,6 +10,7 @@ llvm_canonicalize_cmake_booleans( CLANG_PLUGIN_SUPPORT CLANG_SPAWN_CC1 ENABLE_BACKTRACES + LLVM_ENABLE_CLASSIC_FLANG LLVM_ENABLE_ZLIB LLVM_ENABLE_ZSTD LLVM_ENABLE_PER_TARGET_RUNTIME_DIR -- Gitee From ead4dc6a0b75c5053f02d37aa0d37f165b4d5e12 Mon Sep 17 00:00:00 2001 From: Richard Barton Date: Fri, 18 Mar 2022 16:44:23 +0000 Subject: [PATCH 19/47] [NFC] Add missing ENABLE_CLASSIC_FLANG guard. Signed-off-by: Richard Barton --- clang/lib/Driver/Driver.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 09345113f72d..2185dd5af495 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -5230,9 +5230,11 @@ 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; -- Gitee From 8a91ee13933433cd6320047316e91df0db76c176 Mon Sep 17 00:00:00 2001 From: Richard Barton Date: Tue, 3 May 2022 17:38:49 +0100 Subject: [PATCH 20/47] Fix flang driver preprocessor issue Fix a bug where flang -E -save-temps input.F90 would preprocess the input file twice. Add a new test for preprocessor behaviour that would expose the bug and updated fortran-phases test for new behaviour. Also added -emit-flang-llvm to that test for completeness. Signed-off-by: Richard Barton --- clang/lib/Driver/Driver.cpp | 23 +++--- clang/lib/Driver/ToolChains/ClassicFlang.cpp | 4 +- clang/test/Driver/fortran-phases.f90 | 73 ++++++++++++-------- clang/test/Driver/fortran-preprocessor.f90 | 47 +++++++++++++ 4 files changed, 109 insertions(+), 38 deletions(-) create mode 100644 clang/test/Driver/fortran-preprocessor.f90 diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 2185dd5af495..1b27782c2f14 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -367,14 +367,7 @@ phases::ID Driver::getFinalPhase(const DerivedArgList &DAL, (PhaseArg = DAL.getLastArg(options::OPT_M, options::OPT_MM)) || (PhaseArg = DAL.getLastArg(options::OPT__SLASH_P)) || CCGenDiagnostics) { -#ifdef ENABLE_CLASSIC_FLANG - if (IsFlangMode()) - FinalPhase = phases::Compile; - else - FinalPhase = phases::Preprocess; -#else FinalPhase = phases::Preprocess; -#endif // --precompile only runs up to precompilation. // Options that cause the output of C++20 compiled module interfaces or @@ -2681,7 +2674,11 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args, if (memcmp(Value, "-", 2) == 0) { if (IsFlangMode()) { #ifdef ENABLE_CLASSIC_FLANG - Ty = types::TY_C; + // 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 @@ -2706,6 +2703,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)) diff --git a/clang/lib/Driver/ToolChains/ClassicFlang.cpp b/clang/lib/Driver/ToolChains/ClassicFlang.cpp index 4f3fd6077f76..6ce95320aa0e 100644 --- a/clang/lib/Driver/ToolChains/ClassicFlang.cpp +++ b/clang/lib/Driver/ToolChains/ClassicFlang.cpp @@ -79,8 +79,8 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, // Check file type sanity assert(types::isAcceptedByFlang(InputType) && "Can only accept Fortran"); - if (Args.hasArg(options::OPT_fsyntax_only)) { - // For -fsyntax-only produce temp files only + 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(); diff --git a/clang/test/Driver/fortran-phases.f90 b/clang/test/Driver/fortran-phases.f90 index 5a79bb26bcde..57d5f2c92b78 100644 --- a/clang/test/Driver/fortran-phases.f90 +++ b/clang/test/Driver/fortran-phases.f90 @@ -7,6 +7,7 @@ ! 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 @@ -16,6 +17,7 @@ ! 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 @@ -29,31 +31,39 @@ ! CONLY-NOPP: 1: compiler, {0}, ir ! CONLY-NOPP: 2: backend, {1}, assembler ! CONLY-NOPP: 3: assembler, {2}, object -! CONLY-NOPP-NOT: 4: linker, {3}, image +! 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: 3: assembler, {2}, object -! AONLY-NOPP-NOT: 4: linker, {3}, image +! AONLY-NOPP-NOT: {{.*}}: assembler, {{{.*}}}, object +! AONLY-NOPP-NOT: {{.*}}: linker, {{{.*}}}, image ! LLONLY-NOPP: 0: input, {{.*}}, f95 ! LLONLY-NOPP: 1: compiler, {0}, ir -! LLONLY-NOPP-NOT: 2: backend, {1}, assembler -! LLONLY-NOPP-NOT: 3: assembler, {2}, object -! LLONLY-NOPP-NOT: 4: linker, {3}, image +! 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: 1: compiler, {0}, ir -! SONLY-NOPP-NOT: 2: backend, {1}, assembler -! SONLY-NOPP-NOT: 3: assembler, {2}, object -! SONLY-NOPP-NOT: 4: linker, {3}, image +! 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: compiler, {0}, ir -! PPONLY-NOPP-NOT: 2: backend, {1}, assembler -! PPONLY-NOPP-NOT: 3: assembler, {2}, object -! PPONLY-NOPP-NOT: 4: linker, {3}, image +! 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 @@ -67,35 +77,42 @@ ! CONLY: 2: compiler, {1}, ir ! CONLY: 3: backend, {2}, assembler ! CONLY: 4: assembler, {3}, object -! CONLY-NOT: 5: linker, {4}, image +! 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: 4: assembler, {3}, object -! AONLY-NOT: 5: linker, {4}, image +! 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: 3: backend, {2}, assembler -! LLONLY-NOT: 4: assembler, {3}, object -! LLONLY-NOT: 5: linker, {4}, image +! 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: 2: compiler, {1}, ir -! SONLY-NOT: 3: backend, {2}, assembler -! SONLY-NOT: 4: assembler, {3}, object -! SONLY-NOT: 5: linker, {4}, image +! 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: 2: compiler, {1}, ir -! PPONLY-NOT: 3: backend, {2}, assembler -! PPONLY-NOT: 4: assembler, {3}, object -! PPONLY-NOT: 5: linker, {4}, image +! PPONLY-NOT: {{.*}}: compiler, {{{.*}}}, ir +! PPONLY-NOT: {{.*}}: backend, {{{.*}}}, assembler +! PPONLY-NOT: {{.*}}: assembler, {{{.*}}}, object +! PPONLY-NOT: {{.*}}: linker, {{{.*}}}, image program hello write(*, *) "Hello" diff --git a/clang/test/Driver/fortran-preprocessor.f90 b/clang/test/Driver/fortran-preprocessor.f90 new file mode 100644 index 000000000000..99f4186ba83c --- /dev/null +++ b/clang/test/Driver/fortran-preprocessor.f90 @@ -0,0 +1,47 @@ +! 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" -### -c 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 -### -c 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 +! RUN: %flang -cpp -c -DHELLO="hello all" -save-temps -### -c f95-cpp-input %s 2>&1 | FileCheck %s --check-prefixes=ALL,CPP + +! 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" + +! flang1 should only be called once! +! ALL-NOT: "{{.*}}flang1" + +! CPP should continue to build object +! PP: "{{.*}}flang2" +! PPONLY-NOT: "{{.*}}flang2" + +! These commands should never call a linker! +! ALL-NOT: "{{.*}}ld" + +program hello + write(*, *) HELLO +end program hello + -- Gitee From 1c4cd4bd9110f49896cd0938c744ca9c4baef76d Mon Sep 17 00:00:00 2001 From: Paul Osmialowski Date: Fri, 15 Jul 2022 09:17:08 +0100 Subject: [PATCH 21/47] classic flang: enable IEEE by default (and sort Lower/Common inconsistency out) Signed-off-by: Paul Osmialowski --- clang/lib/Driver/ToolChains/ClassicFlang.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/clang/lib/Driver/ToolChains/ClassicFlang.cpp b/clang/lib/Driver/ToolChains/ClassicFlang.cpp index 6ce95320aa0e..c506797b8c3f 100644 --- a/clang/lib/Driver/ToolChains/ClassicFlang.cpp +++ b/clang/lib/Driver/ToolChains/ClassicFlang.cpp @@ -66,7 +66,7 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, ArgStringList LowerCmdArgs; SmallString<256> Stem; std::string OutFile; - bool NeedIEEE = false; + bool NeedIEEE = true; bool NeedFastMath = false; bool NeedRelaxedMath = false; @@ -555,7 +555,7 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("216"); LowerCmdArgs.push_back("1"); - // Lower: -ieee 0 + // Common: -ieee 0 CommonCmdArgs.push_back("-ieee"); CommonCmdArgs.push_back("0"); } else if (NeedIEEE) { @@ -583,7 +583,7 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, LowerCmdArgs.push_back("-y"); LowerCmdArgs.push_back("216"); LowerCmdArgs.push_back("1"); - // Lower: -ieee 1 + // Common: -ieee 1 CommonCmdArgs.push_back("-ieee"); CommonCmdArgs.push_back("1"); } else if (NeedRelaxedMath) { @@ -595,11 +595,11 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, LowerCmdArgs.push_back("-y"); LowerCmdArgs.push_back("216"); LowerCmdArgs.push_back("1"); - // Lower: -ieee 0 + // Common: -ieee 0 CommonCmdArgs.push_back("-ieee"); CommonCmdArgs.push_back("0"); } else { - // Lower: -ieee 0 + // Common: -ieee 0 CommonCmdArgs.push_back("-ieee"); CommonCmdArgs.push_back("0"); } -- Gitee From 80974b09a8a85d65790b09956c94ba9289b3595d Mon Sep 17 00:00:00 2001 From: Kiran Chandramohan Date: Tue, 8 May 2018 17:49:59 +0100 Subject: [PATCH 22/47] Changes to flang's fp-contract behaviour 1) All fma and contraction behvaviour follows from the -ffp-contract= flag setting. 2) At optimization level 0, -ffp-contract=fast flag will not be honoured. 3) At all other levels, -ffp-contract=fast will be the default behaviour and the flag is honoured. --- clang/lib/Driver/ToolChains/ClassicFlang.cpp | 75 +++++++++++++------ .../flang/classic-flang-fp-contract.f95 | 27 +++++++ 2 files changed, 80 insertions(+), 22 deletions(-) create mode 100644 clang/test/Driver/flang/classic-flang-fp-contract.f95 diff --git a/clang/lib/Driver/ToolChains/ClassicFlang.cpp b/clang/lib/Driver/ToolChains/ClassicFlang.cpp index c506797b8c3f..499e69c38bb6 100644 --- a/clang/lib/Driver/ToolChains/ClassicFlang.cpp +++ b/clang/lib/Driver/ToolChains/ClassicFlang.cpp @@ -464,28 +464,6 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, } } - // Enable FMA - for (Arg *A: Args.filtered(options::OPT_Mfma_on, options::OPT_fma)) { - A->claim(); - LowerCmdArgs.push_back("-x"); - LowerCmdArgs.push_back("172"); - LowerCmdArgs.push_back("0x40000000"); - LowerCmdArgs.push_back("-x"); - LowerCmdArgs.push_back("179"); - LowerCmdArgs.push_back("1"); - } - - // Disable FMA - for (Arg *A: Args.filtered(options::OPT_Mfma_off, options::OPT_nofma)) { - A->claim(); - LowerCmdArgs.push_back("-x"); - LowerCmdArgs.push_back("171"); - LowerCmdArgs.push_back("0x40000000"); - LowerCmdArgs.push_back("-x"); - LowerCmdArgs.push_back("178"); - LowerCmdArgs.push_back("1"); - } - // For -fPIC set -x 62 8 for second part of Fortran frontend for (Arg *A: Args.filtered(options::OPT_fPIC)) { A->claim(); @@ -550,6 +528,59 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, 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"); 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" -- Gitee From 2de23520999a584bba3f4a6f4402d4da8b68ff43 Mon Sep 17 00:00:00 2001 From: Peixin-Qiao Date: Mon, 8 Aug 2022 15:03:08 +0800 Subject: [PATCH 23/47] [Driver] Remove the "-lompstub" in the driver In some workloads, users get "-lompstub" by running "flang -v" and link it explicitly, which may cause failure when compiling programs with OpenMP (flang -fopenmp test.f90 -lompstub). There is no runtime call in ompstub.c generated when "-fopenmp" is not added to compile the program. When "-fopenmp" is added to compile the program, the runtime in llvm/openmp(libomp.so) will be used. If users use some runtime library routines such as "omp_get_thread_num" and compiles it without the option "-fopenmp", both gfortran and ifort report errors of "undefined reference to ...". After remove "-lompstub" in the driver, classic-flang reports the error, too. So, it's safe to remove the "-lompstub" in the driver. --- clang/lib/Driver/ToolChain.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index e63feeb69566..9476be85c6f7 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -1258,8 +1258,6 @@ void ToolChain::AddFortranStdlibLibArgs(const ArgList &Args, CmdArgs.push_back("-lpgmath"); if (useOpenMP) CmdArgs.push_back("-lomp"); - else - CmdArgs.push_back("-lompstub"); if (staticFlangLibs) CmdArgs.push_back("-Bdynamic"); -- Gitee From 61c0c9fa9acce0b287ec31d4151270ef1abc285b Mon Sep 17 00:00:00 2001 From: Bryan Chan Date: Sat, 10 Sep 2022 19:41:06 -0400 Subject: [PATCH 24/47] [Driver] Pass Classic Flang libraries to the linker correctly In LLVM 15, the Fortran and OpenMP runtime libraries are added to the linker command line using common methods (addFortranRuntime* and addOpenMPRuntime*). This commit adds Classic Flang awareness to addFortranRuntime*, so that Classic Flang doesn't attempt to link with LLVM Flang libraries. Re-using the same methods as Clang and LLVM Flang also helps reduce downstream delta. A Classic Flang test is added to ensure that the linker command is constructed correctly. --- clang/lib/Driver/ToolChain.cpp | 32 ++++----------- clang/lib/Driver/ToolChains/CommonArgs.cpp | 16 +++++++- clang/lib/Driver/ToolChains/CommonArgs.h | 3 ++ clang/lib/Driver/ToolChains/Darwin.cpp | 16 ++------ clang/lib/Driver/ToolChains/Gnu.cpp | 16 ++------ clang/lib/Driver/ToolChains/MSVC.cpp | 4 ++ clang/lib/Driver/ToolChains/MinGW.cpp | 4 ++ clang/test/Driver/flang/classic-flang.f95 | 46 ++++++++++++++++++++++ 8 files changed, 88 insertions(+), 49 deletions(-) diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index 9476be85c6f7..3d92b7c2a3bd 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -1232,42 +1232,26 @@ void ToolChain::AddCCKextLibArgs(const ArgList &Args, #ifdef ENABLE_CLASSIC_FLANG void ToolChain::AddFortranStdlibLibArgs(const ArgList &Args, - ArgStringList &CmdArgs) const { - bool staticFlangLibs = false; - bool useOpenMP = false; - + ArgStringList &CmdArgs) const { + bool StaticFlangLibs = 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; + StaticFlangLibs = true; + Args.ClaimAllArgs(options::OPT_staticFlangLibs); } - if (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 (useOpenMP) - CmdArgs.push_back("-lomp"); - if (staticFlangLibs) + if (StaticFlangLibs && !Args.hasArg(options::OPT_static)) CmdArgs.push_back("-Bdynamic"); - CmdArgs.push_back("-lm"); + // Always link Fortran executables with pthreads. + CmdArgs.push_back("-lpthread"); if (!Triple.isOSDarwin()) CmdArgs.push_back("-lrt"); - - // Allways link Fortran executables with Pthreads - CmdArgs.push_back("-lpthread"); } #endif diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index 125ec9de5062..811143497cb4 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -947,7 +947,11 @@ bool tools::addOpenMPRuntime(ArgStringList &CmdArgs, const ToolChain &TC, const ArgList &Args, 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 + ) return false; Driver::OpenMPRuntimeKind RTKind = TC.getDriver().getOpenMPRuntime(Args); @@ -992,7 +996,16 @@ bool tools::addOpenMPRuntime(ArgStringList &CmdArgs, const ToolChain &TC, } void tools::addFortranRuntimeLibs(const ToolChain &TC, +#ifdef ENABLE_CLASSIC_FLANG + const llvm::opt::ArgList &Args, +#endif llvm::opt::ArgStringList &CmdArgs) { +#ifdef ENABLE_CLASSIC_FLANG + if (needFortranLibs(TC.getDriver(), Args)) + TC.AddFortranStdlibLibArgs(Args, CmdArgs); + else + Args.ClaimAllArgs(options::OPT_noFlangLibs); +#else if (TC.getTriple().isKnownWindowsMSVCEnvironment()) { CmdArgs.push_back("Fortran_main.lib"); CmdArgs.push_back("FortranRuntime.lib"); @@ -1002,6 +1015,7 @@ void tools::addFortranRuntimeLibs(const ToolChain &TC, CmdArgs.push_back("-lFortranRuntime"); CmdArgs.push_back("-lFortranDecimal"); } +#endif } void tools::addFortranRuntimeLibraryPath(const ToolChain &TC, diff --git a/clang/lib/Driver/ToolChains/CommonArgs.h b/clang/lib/Driver/ToolChains/CommonArgs.h index dfade523bb80..e7d83fec4e40 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.h +++ b/clang/lib/Driver/ToolChains/CommonArgs.h @@ -135,6 +135,9 @@ bool addOpenMPRuntime(llvm::opt::ArgStringList &CmdArgs, const ToolChain &TC, /// Adds Fortran runtime libraries to \p CmdArgs. void addFortranRuntimeLibs(const ToolChain &TC, +#ifdef ENABLE_CLASSIC_FLANG + const llvm::opt::ArgList &Args, +#endif llvm::opt::ArgStringList &CmdArgs); /// Adds the path for the Fortran runtime libraries to \p CmdArgs. diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp index 022195f2b2a5..3b8e4d7e133a 100644 --- a/clang/lib/Driver/ToolChains/Darwin.cpp +++ b/clang/lib/Driver/ToolChains/Darwin.cpp @@ -679,7 +679,11 @@ void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA, // to generate executables. if (getToolChain().getDriver().IsFlangMode()) { addFortranRuntimeLibraryPath(getToolChain(), Args, CmdArgs); +#ifdef ENABLE_CLASSIC_FLANG + addFortranRuntimeLibs(getToolChain(), Args, CmdArgs); +#else addFortranRuntimeLibs(getToolChain(), CmdArgs); +#endif } if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) @@ -718,18 +722,6 @@ void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA, if (getToolChain().ShouldLinkCXXStdlib(Args)) getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs); -#ifdef ENABLE_CLASSIC_FLANG - // Add Fortran runtime libraries - if (needFortranLibs(getToolChain().getDriver(), Args)) { - getToolChain().AddFortranStdlibLibArgs(Args, CmdArgs); - } else { - // Claim "no Flang libraries" arguments if any - for (auto Arg : Args.filtered(options::OPT_noFlangLibs)) { - Arg->claim(); - } - } -#endif - bool NoStdOrDefaultLibs = Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs); bool ForceLinkBuiltins = Args.hasArg(options::OPT_fapple_link_rtlib); diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp index fc5e12450ceb..076a2d4a21d8 100644 --- a/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/clang/lib/Driver/ToolChains/Gnu.cpp @@ -554,18 +554,6 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, // The profile runtime also needs access to system libraries. getToolChain().addProfileRTLibs(Args, CmdArgs); -#ifdef ENABLE_CLASSIC_FLANG - // Add Fortran runtime libraries - if (needFortranLibs(D, Args)) { - ToolChain.AddFortranStdlibLibArgs(Args, CmdArgs); - } else { - // Claim "no Flang libraries" arguments if any - for (auto Arg : Args.filtered(options::OPT_noFlangLibs)) { - Arg->claim(); - } - } -#endif - if (D.CCCIsCXX() && !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs, options::OPT_r)) { @@ -590,7 +578,11 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, // AddRuntTimeLibs). if (D.IsFlangMode()) { addFortranRuntimeLibraryPath(ToolChain, Args, CmdArgs); +#ifdef ENABLE_CLASSIC_FLANG + addFortranRuntimeLibs(ToolChain, Args, CmdArgs); +#else addFortranRuntimeLibs(ToolChain, CmdArgs); +#endif CmdArgs.push_back("-lm"); } diff --git a/clang/lib/Driver/ToolChains/MSVC.cpp b/clang/lib/Driver/ToolChains/MSVC.cpp index a9fe9da4620f..3cd2f022883b 100644 --- a/clang/lib/Driver/ToolChains/MSVC.cpp +++ b/clang/lib/Driver/ToolChains/MSVC.cpp @@ -131,7 +131,11 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA, if (C.getDriver().IsFlangMode()) { addFortranRuntimeLibraryPath(TC, Args, CmdArgs); +#ifdef ENABLE_CLASSIC_FLANG + addFortranRuntimeLibs(TC, Args, CmdArgs); +#else addFortranRuntimeLibs(TC, CmdArgs); +#endif // Inform the MSVC linker that we're generating a console application, i.e. // one with `main` as the "user-defined" entry point. The `main` function is diff --git a/clang/lib/Driver/ToolChains/MinGW.cpp b/clang/lib/Driver/ToolChains/MinGW.cpp index 503dbf3f0dea..264cc7ab06c8 100644 --- a/clang/lib/Driver/ToolChains/MinGW.cpp +++ b/clang/lib/Driver/ToolChains/MinGW.cpp @@ -240,7 +240,11 @@ void tools::MinGW::Linker::ConstructJob(Compilation &C, const JobAction &JA, if (C.getDriver().IsFlangMode()) { addFortranRuntimeLibraryPath(TC, Args, CmdArgs); +#ifdef ENABLE_CLASSIC_FLANG + addFortranRuntimeLibs(TC, Args, CmdArgs); +#else addFortranRuntimeLibs(TC, CmdArgs); +#endif } // TODO: Add profile stuff here diff --git a/clang/test/Driver/flang/classic-flang.f95 b/clang/test/Driver/flang/classic-flang.f95 index 0b92c799392a..463bdb7e429b 100644 --- a/clang/test/Driver/flang/classic-flang.f95 +++ b/clang/test/Driver/flang/classic-flang.f95 @@ -41,3 +41,49 @@ ! CHECK-ASM-SAME: "-o" "classic-flang.s" ! CHECK-ASM-SAME: "-x" "ir" ! CHECK-ASM-SAME: [[LLFILE]] + +! 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-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-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-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-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-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-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-STATIC-FLANG,CHECK-NO-OMP %s + +! CHECK-LD: "{{.*}}ld" +! CHECK-LD-NOT: "-static" +! CHECK-LD: "{{[^"]*}}classic-flang-{{[^ ]*}}.o" "-lflangmain" "-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" "-rpath" "{{[^ ]*}}/basic_linux_tree/usr/lib" +! CHECK-DYNAMIC-OMP-NOT: "-Bdynamic" +! CHECK-STATIC-OMP: "-Bstatic" "-lomp" "-Bdynamic" "-rpath" "{{[^ ]*}}/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" +! 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" -- Gitee From 3f9689e0ede8c7268bf128efda73f479e58184e6 Mon Sep 17 00:00:00 2001 From: Bryan Chan Date: Thu, 8 Sep 2022 09:35:31 -0400 Subject: [PATCH 25/47] [OpenMP] Exclude a test that fails on smaller GitHub runners --- openmp/runtime/test/ompt/teams/distribute_dispatch.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/openmp/runtime/test/ompt/teams/distribute_dispatch.c b/openmp/runtime/test/ompt/teams/distribute_dispatch.c index 3254a287236f..d4ad7b80c573 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 -- Gitee From 8644a9b28b0a0b578034c3312ffeb897c5af1c19 Mon Sep 17 00:00:00 2001 From: Bryan Chan Date: Thu, 3 Nov 2022 08:57:43 -0400 Subject: [PATCH 26/47] [AsmPrinter] Delete dead code; NFC Delete some snippets that had been commented out since commit a10f592d3b027 in release_13x. --- llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h | 35 ----------- llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 70 --------------------- llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h | 8 --- 3 files changed, 113 deletions(-) diff --git a/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h b/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h index 0835eba21891..ee8be3921ab7 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h +++ b/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h @@ -228,15 +228,6 @@ public: LLVM_DUMP_METHOD void dump() const { for (const DbgValueLocEntry &DV : ValueLocEntries) DV.dump(); -// if (isLocation()) { -// llvm::dbgs() << "Loc = { reg=" << Loc.getReg() << " "; -// if (Loc.isIndirect()) -// llvm::dbgs() << "+0"; -// llvm::dbgs() << "} "; -// } else if (isConstantInt()) -// Constant.CIP->dump(); -// else if (isConstantFP()) -// Constant.CFP->dump(); if (Expression) Expression->dump(); } @@ -313,9 +304,6 @@ public: DebugLocStream::ListBuilder &List, const DIBasicType *BT, DwarfCompileUnit &TheCU); - -// void finalize(const AsmPrinter &AP, DebugLocStream::ListBuilder &List, -// const DIStringType *ST, DwarfCompileUnit &TheCU); }; /// Compare two DbgValueLocEntries for equality. @@ -344,29 +332,6 @@ inline bool operator==(const DbgValueLoc &A, const DbgValueLoc &B) { A.Expression == B.Expression && A.IsVariadic == B.IsVariadic; } -//inline bool operator==(const DbgValueLoc &A, -// const DbgValueLoc &B) { -// if (A.EntryKind != B.EntryKind) -// return false; -// -// if (A.Expression != B.Expression) -// return false; -// -// switch (A.EntryKind) { -// case DbgValueLoc::E_Location: -// return A.Loc == B.Loc; -// case DbgValueLoc::E_TargetIndexLocation: -// return A.TIL == B.TIL; -// case DbgValueLoc::E_Integer: -// return A.Constant.Int == B.Constant.Int; -// case DbgValueLoc::E_ConstantFP: -// return A.Constant.CFP == B.Constant.CFP; -// case DbgValueLoc::E_ConstantInt: -// return A.Constant.CIP == B.Constant.CIP; -// } -// llvm_unreachable("unhandled EntryKind"); -//} - /// Compare two fragments based on their offset. inline bool operator<(const DbgValueLoc &A, const DbgValueLoc &B) { diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index cdcd7bf3145f..1ae17ec9b874 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -1869,28 +1869,10 @@ DbgEntity *DwarfDebug::createConcreteEntity(DwarfCompileUnit &TheCU, return ConcreteEntities.back().get(); } -#if 0 -void DwarfDebug::populateDependentTypeMap() { - for (const auto &I : DbgValues) { - InlinedEntity IV = I.first; - if (I.second.empty()) - continue; - if (const DIVariable *DIV = dyn_cast(IV.first)) { - if (const DIStringType *ST = dyn_cast( - static_cast(DIV->getType()))) - if (const DIVariable *LV = ST->getStringLength()) - VariableInDependentType[LV] = ST; - } - } -} -#endif - // Find variables for each lexical scope. void DwarfDebug::collectEntityInfo(DwarfCompileUnit &TheCU, const DISubprogram *SP, DenseSet &Processed) { -// clearDependentTracking(); -// populateDependentTypeMap(); // Grab the variable info that was squirreled away in the MMI side-table. collectVariableInfoFromMFTable(TheCU, Processed); @@ -1909,11 +1891,6 @@ void DwarfDebug::collectEntityInfo(DwarfCompileUnit &TheCU, LexicalScope *Scope = nullptr; const DILocalVariable *LocalVar = cast(IV.first); -#if 0 - const DILocalVariable *LocalVar = dyn_cast(IV.first); - if (!LocalVar) - continue; -#endif if (const DILocation *IA = IV.second) Scope = LScopes.findInlinedScope(LocalVar->getScope(), IA); else @@ -1972,24 +1949,6 @@ void DwarfDebug::collectEntityInfo(DwarfCompileUnit &TheCU, // Finalize the entry by lowering it into a DWARF bytestream. for (auto &Entry : Entries) Entry.finalize(*Asm, List, BT, TheCU); -#if 0 - List.finalize(); - - if (VariableInDependentType.count(LocalVar)) { - const DIType *DT = VariableInDependentType[LocalVar]; - if (const DIStringType *ST = dyn_cast(DT)) { - unsigned Offset; - DbgVariable TVar = {LocalVar, IV.second}; - DebugLocStream::ListBuilder LB(DebugLocs, TheCU, *Asm, TVar, *MInsn); - for (auto &Entry : Entries) - Entry.finalize(*Asm, LB, ST, TheCU); - LB.finalize(); - Offset = TVar.getDebugLocListIndex(); - if (Offset != ~0u) - addStringTypeLoc(ST, Offset); - } - } -#endif } // For each InlinedEntity collected from DBG_LABEL instructions, convert to @@ -2798,35 +2757,6 @@ void DebugLocEntry::finalize(const AsmPrinter &AP, List.setTagOffset(*DwarfExpr.TagOffset); } -#if 0 -inline static DbgValueLoc mkDbgValueLoc(const DIExpression *expr, - DbgValueLoc &value) { - if (value.isInt()) - return DbgValueLoc(expr, value.getInt()); - if (value.isLocation()) - return DbgValueLoc(expr, value.getLoc()); - if (value.isConstantInt()) - return DbgValueLoc(expr, value.getConstantInt()); - assert(value.isConstantFP()); - return DbgValueLoc(expr, value.getConstantFP()); -} - -void DebugLocEntry::finalize(const AsmPrinter &AP, - DebugLocStream::ListBuilder &List, - const DIStringType *ST, - DwarfCompileUnit &TheCU) { - DebugLocStream::EntryBuilder Entry(List, Begin, End); - BufferByteStreamer Streamer = Entry.getStreamer(); - DebugLocDwarfExpression DwarfExpr(AP.getDwarfVersion(), Streamer, TheCU); - DbgValueLoc &Value = Values[0]; - assert(!Value.isFragment()); - assert(Values.size() == 1 && "only fragments may have >1 value"); - Value = mkDbgValueLoc(ST->getStringLengthExp(), Value); - DwarfDebug::emitDebugLocValue(AP, nullptr, Value, DwarfExpr); - DwarfExpr.finalize(); -} -#endif - void DwarfDebug::emitDebugLocEntryLocation(const DebugLocStream::Entry &Entry, const DwarfCompileUnit *CU) { // Emit the size. diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h index 0a20551058a1..e526614792c7 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -628,14 +628,6 @@ private: /// Emit the reference to the section. void emitSectionReference(const DwarfCompileUnit &CU); -#if 0 - /// Populate dependent type variable map - void populateDependentTypeMap(); -#endif - - /// Clear dependent type tracking map - void clearDependentTracking() { VariableInDependentType.clear(); } - protected: /// Gather pre-function debug information. void beginFunctionImpl(const MachineFunction *MF) override; -- Gitee From 85a59249131d81146929783d6443c9bd77e04b76 Mon Sep 17 00:00:00 2001 From: wangfangcao Date: Wed, 2 Nov 2022 10:13:53 +0800 Subject: [PATCH 27/47] [driver] Allow -msve-vector-bits=+ syntax to mean no maximum vscale --- clang/lib/Driver/ToolChains/ClassicFlang.cpp | 51 ++++++++++++------- .../flang/classic-flang-vscale-mbits.f95 | 28 ++++++++++ .../Driver/flang/classic-flang-vscale.f95 | 28 ++++++++++ 3 files changed, 88 insertions(+), 19 deletions(-) create mode 100644 clang/test/Driver/flang/classic-flang-vscale-mbits.f95 create mode 100644 clang/test/Driver/flang/classic-flang-vscale.f95 diff --git a/clang/lib/Driver/ToolChains/ClassicFlang.cpp b/clang/lib/Driver/ToolChains/ClassicFlang.cpp index 499e69c38bb6..56837014c384 100644 --- a/clang/lib/Driver/ToolChains/ClassicFlang.cpp +++ b/clang/lib/Driver/ToolChains/ClassicFlang.cpp @@ -1030,37 +1030,50 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, } // Add vscale range - unsigned vscaleMin = 1U; - unsigned vscaleMax = 16U; - bool hasVscaleRange = false; + 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.equals("scalable")) - hasVscaleRange = true; - else { - unsigned bits = (std::stoul(Val.str()) >> 7U); - - if ((bits < vscaleMin) || (bits > vscaleMax)) { - D.Diag(diag::warn_drv_clang_unsupported) << A->getAsString(Args); - hasVscaleRange = false; - } else { - vscaleMin = vscaleMax = bits; - hasVscaleRange = true; + if (Val.equals("128") || Val.equals("256") || Val.equals("512") || + Val.equals("1024") || Val.equals("2048") || Val.equals("128+") || + Val.equals("256+") || Val.equals("512+") || Val.equals("1024+") || + Val.equals("2048+")) { + unsigned Bits = 0; + if (Val.endswith("+")) + 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.equals("scalable")) + getToolChain().getDriver().Diag(diag::warn_drv_clang_unsupported) + << A->getOption().getName() << Val; } for (auto Feature : unifyTargetFeatures(Features)) { if (Feature.startswith("+sve")) { - hasVscaleRange = true; + hasSVE = true; break; } } - if (hasVscaleRange) { + if (vscaleMin || vscaleMax) { LowerCmdArgs.push_back("-vscale_range_min"); - LowerCmdArgs.push_back(Args.MakeArgString(std::to_string(vscaleMin))); + 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 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..f0ed43aa027a --- /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" "+neon,+v8a,+sve" +// CHECK-SVE-128-DAG: "-vscale_range_min" "1" "-vscale_range_max" "1" +// CHECK-SVE-128PLUS: "-target_features" "+neon,+v8a,+sve" +// CHECK-SVE-128PLUS-DAG: "-vscale_range_min" "1" "-vscale_range_max" "0" +// CHECK-SVE-256: "-target_features" "+neon,+v8a,+sve" +// CHECK-SVE-256-DAG: "-vscale_range_min" "2" "-vscale_range_max" "2" +// CHECK-SVE-256PLUS: "-target_features" "+neon,+v8a,+sve" +// CHECK-SVE-256PLUS-DAG: "-vscale_range_min" "2" "-vscale_range_max" "0" +// CHECK-SVE2-512: "-target_features" "+neon,+v8a,+sve2,+sve" +// CHECK-SVE2-512-DAG: "-vscale_range_min" "4" "-vscale_range_max" "4" +// CHECK-SVE2-512PLUS: "-target_features" "+neon,+v8a,+sve2,+sve" +// CHECK-SVE2-512PLUS-DAG: "-vscale_range_min" "4" "-vscale_range_max" "0" +// CHECK-SVE2SHA3-2048: "-target_features" "+neon,+v8a,+sve2-sha3,+sve,+sve2" +// CHECK-SVE2SHA3-2048-DAG: "-vscale_range_min" "16" "-vscale_range_max" "16" +// CHECK-SVE2SHA3-2048PLUS: "-target_features" "+neon,+v8a,+sve2-sha3,+sve,+sve2" +// CHECK-SVE2SHA3-2048PLUS-DAG: "-vscale_range_min" "16" "-vscale_range_max" "0" +// CHECK-SVE2-SCALABLE: "-target_features" "+neon,+v8a,+sve2,+sve" +// 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..8110be594db5 --- /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" "+neon,+v8a" +// CHECK-NEON-NOT: "-vscale_range_min" +// CHECK-NEON-NOT: "-vscale_range_max" +// CHECK-SVE: "-target_features" "+neon,+v8a,+sve" +// CHECK-SVE-DAG: "-vscale_range_min" "1" "-vscale_range_max" "16" +// CHECK-SVE2: "-target_features" "+neon,+v8a,+sve2,+sve" +// CHECK-SVE2-DAG: "-vscale_range_min" "1" "-vscale_range_max" "16" +// CHECK-SVE2SHA3: "-target_features" "+neon,+v8a,+sve2-sha3,+sve,+sve2" +// CHECK-SVE2SHA3-DAG: "-vscale_range_min" "1" "-vscale_range_max" "16" +// CHECK-SVE-NOSVE: "-target_features" "+neon,+v8a,-sve,-sve2,-sve2-bitperm,-sve2-sha3,-sve2-aes,-sve2-sm4" +// CHECK-SVE-NOSVE-NOT: "-vscale_range_min" +// CHECK-SVE-NOSVE-NOT: "-vscale_range_max" +// CHECK-SVE2-NOSVE2SHA3: "-target_features" "+neon,+v8a,+sve2,+sve,-sve2-sha3" +// CHECK-SVE2-NOSVE2SHA3-DAG: "-vscale_range_min" "1" "-vscale_range_max" "16" +// CHECK-SVE2SHA3-NOSVE2: "-target_features" "+neon,+v8a,+sve,-sve2,-sve2-bitperm,-sve2-sha3,-sve2-aes,-sve2-sm4" +// CHECK-SVE2SHA3-NOSVE2-DAG: "-vscale_range_min" "1" "-vscale_range_max" "16" +// CHECK-SVE2SHA3-NOSVE: "-target_features" "+neon,+v8a,-sve,-sve2,-sve2-bitperm,-sve2-sha3,-sve2-aes,-sve2-sm4" +// CHECK-SVE2SHA3-NOSVE-NOT: "-vscale_range_min" +// CHECK-SVE2SHA3-NOSVE-NOT: "-vscale_range_max" -- Gitee From 231cab6c4e08f0f507e47fd649b6291b975c3947 Mon Sep 17 00:00:00 2001 From: Kiran Chandramohan Date: Tue, 21 Jan 2020 23:37:22 +0000 Subject: [PATCH 28/47] Changes for reassoc attributes This patch adds code to generate the driver flags so that llvm bridge in flang2 can generate the nsz, reassoc attributes to arithmetic instructions. Also included is a testcase. --- clang/lib/Driver/ToolChains/ClassicFlang.cpp | 33 ++++++++++- clang/test/Driver/flang/reassoc.f90 | 59 ++++++++++++++++++++ 2 files changed, 89 insertions(+), 3 deletions(-) create mode 100644 clang/test/Driver/flang/reassoc.f90 diff --git a/clang/lib/Driver/ToolChains/ClassicFlang.cpp b/clang/lib/Driver/ToolChains/ClassicFlang.cpp index 56837014c384..262f11d28b82 100644 --- a/clang/lib/Driver/ToolChains/ClassicFlang.cpp +++ b/clang/lib/Driver/ToolChains/ClassicFlang.cpp @@ -69,6 +69,8 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, 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."); @@ -509,14 +511,18 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, */ 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_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 = false; - NeedIEEE = true; + NeedFastMath = NeedRelaxedMath = AssociativeMath = false; + NeedIEEE = SignedZeros = true; } else if (A->getOption().matches(options::OPT_frelaxed_math)) { NeedFastMath = NeedIEEE = false; NeedRelaxedMath = true; @@ -524,6 +530,16 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, 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(); } @@ -1011,6 +1027,17 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, 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"); 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" -- Gitee From 918f190525cf074ba61e46bac65373f185c1c723 Mon Sep 17 00:00:00 2001 From: Paul Osmialowski Date: Mon, 1 Aug 2022 22:12:35 +0100 Subject: [PATCH 29/47] [llvm] Provide separate veclib mapping of PGMATH functions for AArch64 This patch fixes link-time issues experienced while compiling some more obscure Fortran workloads. For those programs, calls to the libpgmath functions not defined for AArch64 were generated, e.g. `__pg_log_4` or `__fd_log_4`. This patch eliminates such possibility. Signed-off-by: Paul Osmialowski --- .../test/CodeGen/libpgmath-logfun-aarch64.ll | 60 ++ clang/test/CodeGen/libpgmath-logfun-x86_64.ll | 57 ++ .../include/llvm/Analysis/TargetLibraryInfo.h | 3 +- llvm/include/llvm/Analysis/VecFuncs.def | 616 ++++++++++++++++++ llvm/lib/Analysis/TargetLibraryInfo.cpp | 467 +------------ 5 files changed, 755 insertions(+), 448 deletions(-) create mode 100644 clang/test/CodeGen/libpgmath-logfun-aarch64.ll create mode 100644 clang/test/CodeGen/libpgmath-logfun-x86_64.ll diff --git a/clang/test/CodeGen/libpgmath-logfun-aarch64.ll b/clang/test/CodeGen/libpgmath-logfun-aarch64.ll new file mode 100644 index 000000000000..045d14fdf407 --- /dev/null +++ b/clang/test/CodeGen/libpgmath-logfun-aarch64.ll @@ -0,0 +1,60 @@ +; 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_1 +; CHECK: __pd_log_1 +; CHECK: __pd_log_1 +; CHECK: __pd_log_1 +} + +; 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/llvm/include/llvm/Analysis/TargetLibraryInfo.h b/llvm/include/llvm/Analysis/TargetLibraryInfo.h index 94fd912d50c9..490252cd018a 100644 --- a/llvm/include/llvm/Analysis/TargetLibraryInfo.h +++ b/llvm/include/llvm/Analysis/TargetLibraryInfo.h @@ -22,7 +22,6 @@ namespace llvm { template class ArrayRef; class Function; class Module; -class Triple; /// Describes a possible vectorization of a function. /// Function 'VectorFnName' is equivalent to 'ScalarFnName' vectorized @@ -81,6 +80,8 @@ class TargetLibraryInfoImpl { bool isValidProtoForLibFunc(const FunctionType &FTy, LibFunc F, const Module &M) const; + Triple T; + public: /// List of known vector-functions libraries. /// diff --git a/llvm/include/llvm/Analysis/VecFuncs.def b/llvm/include/llvm/Analysis/VecFuncs.def index b884c1e3911e..836420060b1d 100644 --- a/llvm/include/llvm/Analysis/VecFuncs.def +++ b/llvm/include/llvm/Analysis/VecFuncs.def @@ -909,6 +909,620 @@ TLI_DEFINE_VECFUNC("tgammaf", "armpl_vtgammaq_f32", FIXED(4), NOMASK) TLI_DEFINE_VECFUNC("tgamma", "armpl_svtgamma_f64_x", SCALABLE(2), MASKED) TLI_DEFINE_VECFUNC("tgammaf", "armpl_svtgamma_f32_x", SCALABLE(4), MASKED) +#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)) +TLI_DEFINE_VECFUNC("__fs_sin_1", "__fs_sin_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__pd_sin_1", "__pd_sin_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__ps_sin_1", "__ps_sin_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__rd_sin_1", "__rd_sin_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__rs_sin_1", "__rs_sin_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__fd_cos_1", "__fd_cos_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__fs_cos_1", "__fs_cos_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__pd_cos_1", "__pd_cos_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__ps_cos_1", "__ps_cos_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__rd_cos_1", "__rd_cos_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__rs_cos_1", "__rs_cos_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__fd_sincos_1", "__fd_sincos_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__fs_sincos_1", "__fs_sincos_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__pd_sincos_1", "__pd_sincos_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__ps_sincos_1", "__ps_sincos_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__rd_sincos_1", "__rd_sincos_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__rs_sincos_1", "__rs_sincos_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__fd_tan_1", "__fd_tan_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__fs_tan_1", "__fs_tan_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__pd_tan_1", "__pd_tan_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__ps_tan_1", "__ps_tan_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__rd_tan_1", "__rd_tan_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__rs_tan_1", "__rs_tan_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__fd_sinh_1", "__fd_sinh_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__fs_sinh_1", "__fs_sinh_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__pd_sinh_1", "__pd_sinh_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__ps_sinh_1", "__ps_sinh_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__rd_sinh_1", "__rd_sinh_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__rs_sinh_1", "__rs_sinh_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__fd_cosh_1", "__fd_cosh_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__fs_cosh_1", "__fs_cosh_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__pd_cosh_1", "__pd_cosh_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__ps_cosh_1", "__ps_cosh_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__rd_cosh_1", "__rd_cosh_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__rs_cosh_1", "__rs_cosh_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__fd_tanh_1", "__fd_tanh_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__fs_tanh_1", "__fs_tanh_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__pd_tanh_1", "__pd_tanh_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__ps_tanh_1", "__ps_tanh_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__rd_tanh_1", "__rd_tanh_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__rs_tanh_1", "__rs_tanh_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__fd_asin_1", "__fd_asin_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__fs_asin_1", "__fs_asin_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__pd_asin_1", "__pd_asin_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__ps_asin_1", "__ps_asin_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__rd_asin_1", "__rd_asin_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__rs_asin_1", "__rs_asin_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__fd_acos_1", "__fd_acos_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__fs_acos_1", "__fs_acos_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__pd_acos_1", "__pd_acos_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__ps_acos_1", "__ps_acos_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__rd_acos_1", "__rd_acos_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__rs_acos_1", "__rs_acos_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__fd_atan_1", "__fd_atan_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__fs_atan_1", "__fs_atan_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__pd_atan_1", "__pd_atan_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__ps_atan_1", "__ps_atan_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__rd_atan_1", "__rd_atan_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__rs_atan_1", "__rs_atan_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__fd_atan2_1", "__fd_atan2_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__fs_atan2_1", "__fs_atan2_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__pd_atan2_1", "__pd_atan2_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__ps_atan2_1", "__ps_atan2_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__rd_atan2_1", "__rd_atan2_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__rs_atan2_1", "__rs_atan2_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__fd_pow_1", "__fd_pow_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__fs_pow_1", "__fs_pow_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__pd_pow_1", "__pd_pow_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__ps_pow_1", "__ps_pow_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__rd_pow_1", "__rd_pow_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__rs_pow_1", "__rs_pow_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__fs_powi_1", "__fs_powi_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__ps_powi_1", "__ps_powi_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__rs_powi_1", "__rs_powi_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__fd_powi1_1", "__fd_powi1_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__fs_powi1_1", "__fs_powi1_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__pd_powi1_1", "__pd_powi1_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__ps_powi1_1", "__ps_powi1_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__rd_powi1_1", "__rd_powi1_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__rs_powi1_1", "__rs_powi1_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__fd_powk_1", "__fd_powk_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__fs_powk_1", "__fs_powk_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__pd_powk_1", "__pd_powk_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__ps_powk_1", "__ps_powk_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__rd_powk_1", "__rd_powk_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__rs_powk_1", "__rs_powk_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__fd_powk1_1", "__fd_powk1_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__fs_powk1_1", "__fs_powk1_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__pd_powk1_1", "__pd_powk1_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__ps_powk1_1", "__ps_powk1_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__rd_powk1_1", "__rd_powk1_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__rs_powk1_1", "__rs_powk1_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__fd_log10_1", "__fd_log10_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__fs_log10_1", "__fs_log10_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__pd_log10_1", "__pd_log10_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__ps_log10_1", "__ps_log10_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__rd_log10_1", "__rd_log10_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__rs_log10_1", "__rs_log10_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__fd_log_1", "__fd_log_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__fs_log_1", "__fs_log_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__pd_log_1", "__pd_log_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__ps_log_1", "__ps_log_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__rd_log_1", "__rd_log_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__rs_log_1", "__rs_log_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__fd_exp_1", "__fd_exp_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__fs_exp_1", "__fs_exp_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__pd_exp_1", "__pd_exp_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__ps_exp_1", "__ps_exp_4", FIXED(4)) + +TLI_DEFINE_VECFUNC("__rd_exp_1", "__rd_exp_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__rs_exp_1", "__rs_exp_4", FIXED(4)) + +#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)) +TLI_DEFINE_VECFUNC("__fd_sin_1", "__fd_sin_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__fd_sin_1", "__fd_sin_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__fs_sin_1", "__fs_sin_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__fs_sin_1", "__fs_sin_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__fs_sin_1", "__fs_sin_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__pd_sin_1", "__pd_sin_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__pd_sin_1", "__pd_sin_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__pd_sin_1", "__pd_sin_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__ps_sin_1", "__ps_sin_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__ps_sin_1", "__ps_sin_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__ps_sin_1", "__ps_sin_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__rd_sin_1", "__rd_sin_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__rd_sin_1", "__rd_sin_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__rd_sin_1", "__rd_sin_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__rs_sin_1", "__rs_sin_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__rs_sin_1", "__rs_sin_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__rs_sin_1", "__rs_sin_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__fd_cos_1", "__fd_cos_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__fd_cos_1", "__fd_cos_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__fd_cos_1", "__fd_cos_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__fs_cos_1", "__fs_cos_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__fs_cos_1", "__fs_cos_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__fs_cos_1", "__fs_cos_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__pd_cos_1", "__pd_cos_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__pd_cos_1", "__pd_cos_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__pd_cos_1", "__pd_cos_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__ps_cos_1", "__ps_cos_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__ps_cos_1", "__ps_cos_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__ps_cos_1", "__ps_cos_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__rd_cos_1", "__rd_cos_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__rd_cos_1", "__rd_cos_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__rd_cos_1", "__rd_cos_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__rs_cos_1", "__rs_cos_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__rs_cos_1", "__rs_cos_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__rs_cos_1", "__rs_cos_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__fd_sincos_1", "__fd_sincos_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__fd_sincos_1", "__fd_sincos_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__fd_sincos_1", "__fd_sincos_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__fs_sincos_1", "__fs_sincos_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__fs_sincos_1", "__fs_sincos_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__fs_sincos_1", "__fs_sincos_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__pd_sincos_1", "__pd_sincos_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__pd_sincos_1", "__pd_sincos_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__pd_sincos_1", "__pd_sincos_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__ps_sincos_1", "__ps_sincos_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__ps_sincos_1", "__ps_sincos_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__ps_sincos_1", "__ps_sincos_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__rd_sincos_1", "__rd_sincos_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__rd_sincos_1", "__rd_sincos_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__rd_sincos_1", "__rd_sincos_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__rs_sincos_1", "__rs_sincos_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__rs_sincos_1", "__rs_sincos_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__rs_sincos_1", "__rs_sincos_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__fd_tan_1", "__fd_tan_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__fd_tan_1", "__fd_tan_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__fd_tan_1", "__fd_tan_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__fs_tan_1", "__fs_tan_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__fs_tan_1", "__fs_tan_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__fs_tan_1", "__fs_tan_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__pd_tan_1", "__pd_tan_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__pd_tan_1", "__pd_tan_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__pd_tan_1", "__pd_tan_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__ps_tan_1", "__ps_tan_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__ps_tan_1", "__ps_tan_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__ps_tan_1", "__ps_tan_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__rd_tan_1", "__rd_tan_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__rd_tan_1", "__rd_tan_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__rd_tan_1", "__rd_tan_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__rs_tan_1", "__rs_tan_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__rs_tan_1", "__rs_tan_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__rs_tan_1", "__rs_tan_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__fd_sinh_1", "__fd_sinh_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__fd_sinh_1", "__fd_sinh_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__fd_sinh_1", "__fd_sinh_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__fs_sinh_1", "__fs_sinh_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__fs_sinh_1", "__fs_sinh_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__fs_sinh_1", "__fs_sinh_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__pd_sinh_1", "__pd_sinh_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__pd_sinh_1", "__pd_sinh_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__pd_sinh_1", "__pd_sinh_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__ps_sinh_1", "__ps_sinh_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__ps_sinh_1", "__ps_sinh_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__ps_sinh_1", "__ps_sinh_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__rd_sinh_1", "__rd_sinh_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__rd_sinh_1", "__rd_sinh_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__rd_sinh_1", "__rd_sinh_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__rs_sinh_1", "__rs_sinh_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__rs_sinh_1", "__rs_sinh_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__rs_sinh_1", "__rs_sinh_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__fd_cosh_1", "__fd_cosh_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__fd_cosh_1", "__fd_cosh_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__fd_cosh_1", "__fd_cosh_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__fs_cosh_1", "__fs_cosh_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__fs_cosh_1", "__fs_cosh_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__fs_cosh_1", "__fs_cosh_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__pd_cosh_1", "__pd_cosh_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__pd_cosh_1", "__pd_cosh_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__pd_cosh_1", "__pd_cosh_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__ps_cosh_1", "__ps_cosh_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__ps_cosh_1", "__ps_cosh_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__ps_cosh_1", "__ps_cosh_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__rd_cosh_1", "__rd_cosh_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__rd_cosh_1", "__rd_cosh_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__rd_cosh_1", "__rd_cosh_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__rs_cosh_1", "__rs_cosh_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__rs_cosh_1", "__rs_cosh_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__rs_cosh_1", "__rs_cosh_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__fd_tanh_1", "__fd_tanh_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__fd_tanh_1", "__fd_tanh_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__fd_tanh_1", "__fd_tanh_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__fs_tanh_1", "__fs_tanh_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__fs_tanh_1", "__fs_tanh_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__fs_tanh_1", "__fs_tanh_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__pd_tanh_1", "__pd_tanh_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__pd_tanh_1", "__pd_tanh_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__pd_tanh_1", "__pd_tanh_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__ps_tanh_1", "__ps_tanh_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__ps_tanh_1", "__ps_tanh_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__ps_tanh_1", "__ps_tanh_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__rd_tanh_1", "__rd_tanh_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__rd_tanh_1", "__rd_tanh_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__rd_tanh_1", "__rd_tanh_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__rs_tanh_1", "__rs_tanh_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__rs_tanh_1", "__rs_tanh_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__rs_tanh_1", "__rs_tanh_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__fd_asin_1", "__fd_asin_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__fd_asin_1", "__fd_asin_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__fd_asin_1", "__fd_asin_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__fs_asin_1", "__fs_asin_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__fs_asin_1", "__fs_asin_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__fs_asin_1", "__fs_asin_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__pd_asin_1", "__pd_asin_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__pd_asin_1", "__pd_asin_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__pd_asin_1", "__pd_asin_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__ps_asin_1", "__ps_asin_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__ps_asin_1", "__ps_asin_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__ps_asin_1", "__ps_asin_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__rd_asin_1", "__rd_asin_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__rd_asin_1", "__rd_asin_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__rd_asin_1", "__rd_asin_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__rs_asin_1", "__rs_asin_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__rs_asin_1", "__rs_asin_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__rs_asin_1", "__rs_asin_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__fd_acos_1", "__fd_acos_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__fd_acos_1", "__fd_acos_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__fd_acos_1", "__fd_acos_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__fs_acos_1", "__fs_acos_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__fs_acos_1", "__fs_acos_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__fs_acos_1", "__fs_acos_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__pd_acos_1", "__pd_acos_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__pd_acos_1", "__pd_acos_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__pd_acos_1", "__pd_acos_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__ps_acos_1", "__ps_acos_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__ps_acos_1", "__ps_acos_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__ps_acos_1", "__ps_acos_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__rd_acos_1", "__rd_acos_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__rd_acos_1", "__rd_acos_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__rd_acos_1", "__rd_acos_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__rs_acos_1", "__rs_acos_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__rs_acos_1", "__rs_acos_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__rs_acos_1", "__rs_acos_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__fd_atan_1", "__fd_atan_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__fd_atan_1", "__fd_atan_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__fd_atan_1", "__fd_atan_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__fs_atan_1", "__fs_atan_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__fs_atan_1", "__fs_atan_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__fs_atan_1", "__fs_atan_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__pd_atan_1", "__pd_atan_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__pd_atan_1", "__pd_atan_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__pd_atan_1", "__pd_atan_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__ps_atan_1", "__ps_atan_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__ps_atan_1", "__ps_atan_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__ps_atan_1", "__ps_atan_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__rd_atan_1", "__rd_atan_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__rd_atan_1", "__rd_atan_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__rd_atan_1", "__rd_atan_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__rs_atan_1", "__rs_atan_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__rs_atan_1", "__rs_atan_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__rs_atan_1", "__rs_atan_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__fd_atan2_1", "__fd_atan2_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__fd_atan2_1", "__fd_atan2_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__fd_atan2_1", "__fd_atan2_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__fs_atan2_1", "__fs_atan2_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__fs_atan2_1", "__fs_atan2_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__fs_atan2_1", "__fs_atan2_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__pd_atan2_1", "__pd_atan2_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__pd_atan2_1", "__pd_atan2_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__pd_atan2_1", "__pd_atan2_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__ps_atan2_1", "__ps_atan2_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__ps_atan2_1", "__ps_atan2_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__ps_atan2_1", "__ps_atan2_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__rd_atan2_1", "__rd_atan2_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__rd_atan2_1", "__rd_atan2_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__rd_atan2_1", "__rd_atan2_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__rs_atan2_1", "__rs_atan2_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__rs_atan2_1", "__rs_atan2_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__rs_atan2_1", "__rs_atan2_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__fd_pow_1", "__fd_pow_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__fd_pow_1", "__fd_pow_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__fd_pow_1", "__fd_pow_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__fs_pow_1", "__fs_pow_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__fs_pow_1", "__fs_pow_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__fs_pow_1", "__fs_pow_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__pd_pow_1", "__pd_pow_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__pd_pow_1", "__pd_pow_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__pd_pow_1", "__pd_pow_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__ps_pow_1", "__ps_pow_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__ps_pow_1", "__ps_pow_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__ps_pow_1", "__ps_pow_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__rd_pow_1", "__rd_pow_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__rd_pow_1", "__rd_pow_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__rd_pow_1", "__rd_pow_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__rs_pow_1", "__rs_pow_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__rs_pow_1", "__rs_pow_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__rs_pow_1", "__rs_pow_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__fs_powi_1", "__fs_powi_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__fs_powi_1", "__fs_powi_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__fs_powi_1", "__fs_powi_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__ps_powi_1", "__ps_powi_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__ps_powi_1", "__ps_powi_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__ps_powi_1", "__ps_powi_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__rs_powi_1", "__rs_powi_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__rs_powi_1", "__rs_powi_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__rs_powi_1", "__rs_powi_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__fd_powi1_1", "__fd_powi1_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__fd_powi1_1", "__fd_powi1_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__fd_powi1_1", "__fd_powi1_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__fs_powi1_1", "__fs_powi1_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__fs_powi1_1", "__fs_powi1_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__fs_powi1_1", "__fs_powi1_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__pd_powi1_1", "__pd_powi1_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__pd_powi1_1", "__pd_powi1_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__pd_powi1_1", "__pd_powi1_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__ps_powi1_1", "__ps_powi1_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__ps_powi1_1", "__ps_powi1_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__ps_powi1_1", "__ps_powi1_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__rd_powi1_1", "__rd_powi1_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__rd_powi1_1", "__rd_powi1_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__rd_powi1_1", "__rd_powi1_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__rs_powi1_1", "__rs_powi1_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__rs_powi1_1", "__rs_powi1_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__rs_powi1_1", "__rs_powi1_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__fd_powk_1", "__fd_powk_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__fd_powk_1", "__fd_powk_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__fd_powk_1", "__fd_powk_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__fs_powk_1", "__fs_powk_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__fs_powk_1", "__fs_powk_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__fs_powk_1", "__fs_powk_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__pd_powk_1", "__pd_powk_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__pd_powk_1", "__pd_powk_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__pd_powk_1", "__pd_powk_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__ps_powk_1", "__ps_powk_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__ps_powk_1", "__ps_powk_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__ps_powk_1", "__ps_powk_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__rd_powk_1", "__rd_powk_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__rd_powk_1", "__rd_powk_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__rd_powk_1", "__rd_powk_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__rs_powk_1", "__rs_powk_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__rs_powk_1", "__rs_powk_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__rs_powk_1", "__rs_powk_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__fd_powk1_1", "__fd_powk1_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__fd_powk1_1", "__fd_powk1_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__fd_powk1_1", "__fd_powk1_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__fs_powk1_1", "__fs_powk1_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__fs_powk1_1", "__fs_powk1_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__fs_powk1_1", "__fs_powk1_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__pd_powk1_1", "__pd_powk1_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__pd_powk1_1", "__pd_powk1_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__pd_powk1_1", "__pd_powk1_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__ps_powk1_1", "__ps_powk1_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__ps_powk1_1", "__ps_powk1_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__ps_powk1_1", "__ps_powk1_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__rd_powk1_1", "__rd_powk1_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__rd_powk1_1", "__rd_powk1_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__rd_powk1_1", "__rd_powk1_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__rs_powk1_1", "__rs_powk1_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__rs_powk1_1", "__rs_powk1_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__rs_powk1_1", "__rs_powk1_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__fd_log10_1", "__fd_log10_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__fd_log10_1", "__fd_log10_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__fd_log10_1", "__fd_log10_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__fs_log10_1", "__fs_log10_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__fs_log10_1", "__fs_log10_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__fs_log10_1", "__fs_log10_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__pd_log10_1", "__pd_log10_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__pd_log10_1", "__pd_log10_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__pd_log10_1", "__pd_log10_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__ps_log10_1", "__ps_log10_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__ps_log10_1", "__ps_log10_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__ps_log10_1", "__ps_log10_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__rd_log10_1", "__rd_log10_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__rd_log10_1", "__rd_log10_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__rd_log10_1", "__rd_log10_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__rs_log10_1", "__rs_log10_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__rs_log10_1", "__rs_log10_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__rs_log10_1", "__rs_log10_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__fd_log_1", "__fd_log_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__fd_log_1", "__fd_log_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__fd_log_1", "__fd_log_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__fs_log_1", "__fs_log_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__fs_log_1", "__fs_log_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__fs_log_1", "__fs_log_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__pd_log_1", "__pd_log_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__pd_log_1", "__pd_log_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__pd_log_1", "__pd_log_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__ps_log_1", "__ps_log_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__ps_log_1", "__ps_log_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__ps_log_1", "__ps_log_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__rd_log_1", "__rd_log_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__rd_log_1", "__rd_log_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__rd_log_1", "__rd_log_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__rs_log_1", "__rs_log_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__rs_log_1", "__rs_log_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__rs_log_1", "__rs_log_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__fs_exp_1", "__fs_exp_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__fs_exp_1", "__fs_exp_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__fs_exp_1", "__fs_exp_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__pd_exp_1", "__pd_exp_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__pd_exp_1", "__pd_exp_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__pd_exp_1", "__pd_exp_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__ps_exp_1", "__ps_exp_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__ps_exp_1", "__ps_exp_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__ps_exp_1", "__ps_exp_16", FIXED(16)) + +TLI_DEFINE_VECFUNC("__rd_exp_1", "__rd_exp_2", FIXED(2)) +TLI_DEFINE_VECFUNC("__rd_exp_1", "__rd_exp_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__rd_exp_1", "__rd_exp_8", FIXED(8)) + +TLI_DEFINE_VECFUNC("__rs_exp_1", "__rs_exp_4", FIXED(4)) +TLI_DEFINE_VECFUNC("__rs_exp_1", "__rs_exp_8", FIXED(8)) +TLI_DEFINE_VECFUNC("__rs_exp_1", "__rs_exp_16", FIXED(16)) + #else #error "Must choose which vector library functions are to be defined." #endif @@ -929,3 +1543,5 @@ TLI_DEFINE_VECFUNC("tgammaf", "armpl_svtgamma_f32_x", SCALABLE(4), MASKED) #undef TLI_DEFINE_SLEEFGNUABI_SCALABLE_VECFUNCS #undef TLI_DEFINE_MASSV_VECFUNCS_NAMES #undef TLI_DEFINE_ARMPL_VECFUNCS +#undef TLI_DEFINE_PGMATH_AARCH64_VECFUNCS +#undef TLI_DEFINE_PGMATH_X86_VECFUNCS diff --git a/llvm/lib/Analysis/TargetLibraryInfo.cpp b/llvm/lib/Analysis/TargetLibraryInfo.cpp index 4ad200e5ce6e..a6593f6b3757 100644 --- a/llvm/lib/Analysis/TargetLibraryInfo.cpp +++ b/llvm/lib/Analysis/TargetLibraryInfo.cpp @@ -871,14 +871,14 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, TLI.addVectorizableFunctionsFromVecLib(ClVectorLibrary, T); } -TargetLibraryInfoImpl::TargetLibraryInfoImpl() { +TargetLibraryInfoImpl::TargetLibraryInfoImpl() : T(Triple()) { // Default to everything being available. memset(AvailableArray, -1, sizeof(AvailableArray)); - initialize(*this, Triple(), StandardNames); + initialize(*this, T, StandardNames); } -TargetLibraryInfoImpl::TargetLibraryInfoImpl(const Triple &T) { +TargetLibraryInfoImpl::TargetLibraryInfoImpl(const Triple &T) : T(T) { // Default to everything being available. memset(AvailableArray, -1, sizeof(AvailableArray)); @@ -890,7 +890,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; @@ -902,7 +902,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; @@ -916,6 +916,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; } @@ -927,6 +928,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; @@ -1243,448 +1245,19 @@ void TargetLibraryInfoImpl::addVectorizableFunctionsFromVecLib( // Based on the size of vector registers available and the size of data, the // vector width should be chosen correctly. case PGMATH: { - const VecDesc VecFuncs[] = { - {"__fd_sin_1", "__fd_sin_2", FIXED(2)}, - {"__fd_sin_1", "__fd_sin_4", FIXED(4)}, - {"__fd_sin_1", "__fd_sin_8", FIXED(8)}, - - {"__fs_sin_1", "__fs_sin_4", FIXED(4)}, - {"__fs_sin_1", "__fs_sin_8", FIXED(8)}, - {"__fs_sin_1", "__fs_sin_16", FIXED(16)}, - - {"__pd_sin_1", "__pd_sin_2", FIXED(2)}, - {"__pd_sin_1", "__pd_sin_4", FIXED(4)}, - {"__pd_sin_1", "__pd_sin_8", FIXED(8)}, - - {"__ps_sin_1", "__ps_sin_4", FIXED(4)}, - {"__ps_sin_1", "__ps_sin_8", FIXED(8)}, - {"__ps_sin_1", "__ps_sin_16", FIXED(16)}, - - {"__rd_sin_1", "__rd_sin_2", FIXED(2)}, - {"__rd_sin_1", "__rd_sin_4", FIXED(4)}, - {"__rd_sin_1", "__rd_sin_8", FIXED(8)}, - - {"__rs_sin_1", "__rs_sin_4", FIXED(4)}, - {"__rs_sin_1", "__rs_sin_8", FIXED(8)}, - {"__rs_sin_1", "__rs_sin_16", FIXED(16)}, - - {"__fd_cos_1", "__fd_cos_2", FIXED(2)}, - {"__fd_cos_1", "__fd_cos_4", FIXED(4)}, - {"__fd_cos_1", "__fd_cos_8", FIXED(8)}, - - {"__fs_cos_1", "__fs_cos_4", FIXED(4)}, - {"__fs_cos_1", "__fs_cos_8", FIXED(8)}, - {"__fs_cos_1", "__fs_cos_16", FIXED(16)}, - - {"__pd_cos_1", "__pd_cos_2", FIXED(2)}, - {"__pd_cos_1", "__pd_cos_4", FIXED(4)}, - {"__pd_cos_1", "__pd_cos_8", FIXED(8)}, - - {"__ps_cos_1", "__ps_cos_4", FIXED(4)}, - {"__ps_cos_1", "__ps_cos_8", FIXED(8)}, - {"__ps_cos_1", "__ps_cos_16", FIXED(16)}, - - {"__rd_cos_1", "__rd_cos_2", FIXED(2)}, - {"__rd_cos_1", "__rd_cos_4", FIXED(4)}, - {"__rd_cos_1", "__rd_cos_8", FIXED(8)}, - - {"__rs_cos_1", "__rs_cos_4", FIXED(4)}, - {"__rs_cos_1", "__rs_cos_8", FIXED(8)}, - {"__rs_cos_1", "__rs_cos_16", FIXED(16)}, - - {"__fd_sincos_1", "__fd_sincos_2", FIXED(2)}, - {"__fd_sincos_1", "__fd_sincos_4", FIXED(4)}, - {"__fd_sincos_1", "__fd_sincos_8", FIXED(8)}, - - {"__fs_sincos_1", "__fs_sincos_4", FIXED(4)}, - {"__fs_sincos_1", "__fs_sincos_8", FIXED(8)}, - {"__fs_sincos_1", "__fs_sincos_16", FIXED(16)}, - - {"__pd_sincos_1", "__pd_sincos_2", FIXED(2)}, - {"__pd_sincos_1", "__pd_sincos_4", FIXED(4)}, - {"__pd_sincos_1", "__pd_sincos_8", FIXED(8)}, - - {"__ps_sincos_1", "__ps_sincos_4", FIXED(4)}, - {"__ps_sincos_1", "__ps_sincos_8", FIXED(8)}, - {"__ps_sincos_1", "__ps_sincos_16", FIXED(16)}, - - {"__rd_sincos_1", "__rd_sincos_2", FIXED(2)}, - {"__rd_sincos_1", "__rd_sincos_4", FIXED(4)}, - {"__rd_sincos_1", "__rd_sincos_8", FIXED(8)}, - - {"__rs_sincos_1", "__rs_sincos_4", FIXED(4)}, - {"__rs_sincos_1", "__rs_sincos_8", FIXED(8)}, - {"__rs_sincos_1", "__rs_sincos_16", FIXED(16)}, - - {"__fd_tan_1", "__fd_tan_2", FIXED(2)}, - {"__fd_tan_1", "__fd_tan_4", FIXED(4)}, - {"__fd_tan_1", "__fd_tan_8", FIXED(8)}, - - {"__fs_tan_1", "__fs_tan_4", FIXED(4)}, - {"__fs_tan_1", "__fs_tan_8", FIXED(8)}, - {"__fs_tan_1", "__fs_tan_16", FIXED(16)}, - - {"__pd_tan_1", "__pd_tan_2", FIXED(2)}, - {"__pd_tan_1", "__pd_tan_4", FIXED(4)}, - {"__pd_tan_1", "__pd_tan_8", FIXED(8)}, - - {"__ps_tan_1", "__ps_tan_4", FIXED(4)}, - {"__ps_tan_1", "__ps_tan_8", FIXED(8)}, - {"__ps_tan_1", "__ps_tan_16", FIXED(16)}, - - {"__rd_tan_1", "__rd_tan_2", FIXED(2)}, - {"__rd_tan_1", "__rd_tan_4", FIXED(4)}, - {"__rd_tan_1", "__rd_tan_8", FIXED(8)}, - - {"__rs_tan_1", "__rs_tan_4", FIXED(4)}, - {"__rs_tan_1", "__rs_tan_8", FIXED(8)}, - {"__rs_tan_1", "__rs_tan_16", FIXED(16)}, - - {"__fd_sinh_1", "__fd_sinh_2", FIXED(2)}, - {"__fd_sinh_1", "__fd_sinh_4", FIXED(4)}, - {"__fd_sinh_1", "__fd_sinh_8", FIXED(8)}, - - {"__fs_sinh_1", "__fs_sinh_4", FIXED(4)}, - {"__fs_sinh_1", "__fs_sinh_8", FIXED(8)}, - {"__fs_sinh_1", "__fs_sinh_16", FIXED(16)}, - - {"__pd_sinh_1", "__pd_sinh_2", FIXED(2)}, - {"__pd_sinh_1", "__pd_sinh_4", FIXED(4)}, - {"__pd_sinh_1", "__pd_sinh_8", FIXED(8)}, - - {"__ps_sinh_1", "__ps_sinh_4", FIXED(4)}, - {"__ps_sinh_1", "__ps_sinh_8", FIXED(8)}, - {"__ps_sinh_1", "__ps_sinh_16", FIXED(16)}, - - {"__rd_sinh_1", "__rd_sinh_2", FIXED(2)}, - {"__rd_sinh_1", "__rd_sinh_4", FIXED(4)}, - {"__rd_sinh_1", "__rd_sinh_8", FIXED(8)}, - - {"__rs_sinh_1", "__rs_sinh_4", FIXED(4)}, - {"__rs_sinh_1", "__rs_sinh_8", FIXED(8)}, - {"__rs_sinh_1", "__rs_sinh_16", FIXED(16)}, - - {"__fd_cosh_1", "__fd_cosh_2", FIXED(2)}, - {"__fd_cosh_1", "__fd_cosh_4", FIXED(4)}, - {"__fd_cosh_1", "__fd_cosh_8", FIXED(8)}, - - {"__fs_cosh_1", "__fs_cosh_4", FIXED(4)}, - {"__fs_cosh_1", "__fs_cosh_8", FIXED(8)}, - {"__fs_cosh_1", "__fs_cosh_16", FIXED(16)}, - - {"__pd_cosh_1", "__pd_cosh_2", FIXED(2)}, - {"__pd_cosh_1", "__pd_cosh_4", FIXED(4)}, - {"__pd_cosh_1", "__pd_cosh_8", FIXED(8)}, - - {"__ps_cosh_1", "__ps_cosh_4", FIXED(4)}, - {"__ps_cosh_1", "__ps_cosh_8", FIXED(8)}, - {"__ps_cosh_1", "__ps_cosh_16", FIXED(16)}, - - {"__rd_cosh_1", "__rd_cosh_2", FIXED(2)}, - {"__rd_cosh_1", "__rd_cosh_4", FIXED(4)}, - {"__rd_cosh_1", "__rd_cosh_8", FIXED(8)}, - - {"__rs_cosh_1", "__rs_cosh_4", FIXED(4)}, - {"__rs_cosh_1", "__rs_cosh_8", FIXED(8)}, - {"__rs_cosh_1", "__rs_cosh_16", FIXED(16)}, - - {"__fd_tanh_1", "__fd_tanh_2", FIXED(2)}, - {"__fd_tanh_1", "__fd_tanh_4", FIXED(4)}, - {"__fd_tanh_1", "__fd_tanh_8", FIXED(8)}, - - {"__fs_tanh_1", "__fs_tanh_4", FIXED(4)}, - {"__fs_tanh_1", "__fs_tanh_8", FIXED(8)}, - {"__fs_tanh_1", "__fs_tanh_16", FIXED(16)}, - - {"__pd_tanh_1", "__pd_tanh_2", FIXED(2)}, - {"__pd_tanh_1", "__pd_tanh_4", FIXED(4)}, - {"__pd_tanh_1", "__pd_tanh_8", FIXED(8)}, - - {"__ps_tanh_1", "__ps_tanh_4", FIXED(4)}, - {"__ps_tanh_1", "__ps_tanh_8", FIXED(8)}, - {"__ps_tanh_1", "__ps_tanh_16", FIXED(16)}, - - {"__rd_tanh_1", "__rd_tanh_2", FIXED(2)}, - {"__rd_tanh_1", "__rd_tanh_4", FIXED(4)}, - {"__rd_tanh_1", "__rd_tanh_8", FIXED(8)}, - - {"__rs_tanh_1", "__rs_tanh_4", FIXED(4)}, - {"__rs_tanh_1", "__rs_tanh_8", FIXED(8)}, - {"__rs_tanh_1", "__rs_tanh_16", FIXED(16)}, - - {"__fd_asin_1", "__fd_asin_2", FIXED(2)}, - {"__fd_asin_1", "__fd_asin_4", FIXED(4)}, - {"__fd_asin_1", "__fd_asin_8", FIXED(8)}, - - {"__fs_asin_1", "__fs_asin_4", FIXED(4)}, - {"__fs_asin_1", "__fs_asin_8", FIXED(8)}, - {"__fs_asin_1", "__fs_asin_16", FIXED(16)}, - - {"__pd_asin_1", "__pd_asin_2", FIXED(2)}, - {"__pd_asin_1", "__pd_asin_4", FIXED(4)}, - {"__pd_asin_1", "__pd_asin_8", FIXED(8)}, - - {"__ps_asin_1", "__ps_asin_4", FIXED(4)}, - {"__ps_asin_1", "__ps_asin_8", FIXED(8)}, - {"__ps_asin_1", "__ps_asin_16", FIXED(16)}, - - {"__rd_asin_1", "__rd_asin_2", FIXED(2)}, - {"__rd_asin_1", "__rd_asin_4", FIXED(4)}, - {"__rd_asin_1", "__rd_asin_8", FIXED(8)}, - - {"__rs_asin_1", "__rs_asin_4", FIXED(4)}, - {"__rs_asin_1", "__rs_asin_8", FIXED(8)}, - {"__rs_asin_1", "__rs_asin_16", FIXED(16)}, - - {"__fd_acos_1", "__fd_acos_2", FIXED(2)}, - {"__fd_acos_1", "__fd_acos_4", FIXED(4)}, - {"__fd_acos_1", "__fd_acos_8", FIXED(8)}, - - {"__fs_acos_1", "__fs_acos_4", FIXED(4)}, - {"__fs_acos_1", "__fs_acos_8", FIXED(8)}, - {"__fs_acos_1", "__fs_acos_16", FIXED(16)}, - - {"__pd_acos_1", "__pd_acos_2", FIXED(2)}, - {"__pd_acos_1", "__pd_acos_4", FIXED(4)}, - {"__pd_acos_1", "__pd_acos_8", FIXED(8)}, - - {"__ps_acos_1", "__ps_acos_4", FIXED(4)}, - {"__ps_acos_1", "__ps_acos_8", FIXED(8)}, - {"__ps_acos_1", "__ps_acos_16", FIXED(16)}, - - {"__rd_acos_1", "__rd_acos_2", FIXED(2)}, - {"__rd_acos_1", "__rd_acos_4", FIXED(4)}, - {"__rd_acos_1", "__rd_acos_8", FIXED(8)}, - - {"__rs_acos_1", "__rs_acos_4", FIXED(4)}, - {"__rs_acos_1", "__rs_acos_8", FIXED(8)}, - {"__rs_acos_1", "__rs_acos_16", FIXED(16)}, - - {"__fd_atan_1", "__fd_atan_2", FIXED(2)}, - {"__fd_atan_1", "__fd_atan_4", FIXED(4)}, - {"__fd_atan_1", "__fd_atan_8", FIXED(8)}, - - {"__fs_atan_1", "__fs_atan_4", FIXED(4)}, - {"__fs_atan_1", "__fs_atan_8", FIXED(8)}, - {"__fs_atan_1", "__fs_atan_16", FIXED(16)}, - - {"__pd_atan_1", "__pd_atan_2", FIXED(2)}, - {"__pd_atan_1", "__pd_atan_4", FIXED(4)}, - {"__pd_atan_1", "__pd_atan_8", FIXED(8)}, - - {"__ps_atan_1", "__ps_atan_4", FIXED(4)}, - {"__ps_atan_1", "__ps_atan_8", FIXED(8)}, - {"__ps_atan_1", "__ps_atan_16", FIXED(16)}, - - {"__rd_atan_1", "__rd_atan_2", FIXED(2)}, - {"__rd_atan_1", "__rd_atan_4", FIXED(4)}, - {"__rd_atan_1", "__rd_atan_8", FIXED(8)}, - - {"__rs_atan_1", "__rs_atan_4", FIXED(4)}, - {"__rs_atan_1", "__rs_atan_8", FIXED(8)}, - {"__rs_atan_1", "__rs_atan_16", FIXED(16)}, - - {"__fd_atan2_1", "__fd_atan2_2", FIXED(2)}, - {"__fd_atan2_1", "__fd_atan2_4", FIXED(4)}, - {"__fd_atan2_1", "__fd_atan2_8", FIXED(8)}, - - {"__fs_atan2_1", "__fs_atan2_4", FIXED(4)}, - {"__fs_atan2_1", "__fs_atan2_8", FIXED(8)}, - {"__fs_atan2_1", "__fs_atan2_16", FIXED(16)}, - - {"__pd_atan2_1", "__pd_atan2_2", FIXED(2)}, - {"__pd_atan2_1", "__pd_atan2_4", FIXED(4)}, - {"__pd_atan2_1", "__pd_atan2_8", FIXED(8)}, - - {"__ps_atan2_1", "__ps_atan2_4", FIXED(4)}, - {"__ps_atan2_1", "__ps_atan2_8", FIXED(8)}, - {"__ps_atan2_1", "__ps_atan2_16", FIXED(16)}, - - {"__rd_atan2_1", "__rd_atan2_2", FIXED(2)}, - {"__rd_atan2_1", "__rd_atan2_4", FIXED(4)}, - {"__rd_atan2_1", "__rd_atan2_8", FIXED(8)}, - - {"__rs_atan2_1", "__rs_atan2_4", FIXED(4)}, - {"__rs_atan2_1", "__rs_atan2_8", FIXED(8)}, - {"__rs_atan2_1", "__rs_atan2_16", FIXED(16)}, - - {"__fd_pow_1", "__fd_pow_2", FIXED(2)}, - {"__fd_pow_1", "__fd_pow_4", FIXED(4)}, - {"__fd_pow_1", "__fd_pow_8", FIXED(8)}, - - {"__fs_pow_1", "__fs_pow_4", FIXED(4)}, - {"__fs_pow_1", "__fs_pow_8", FIXED(8)}, - {"__fs_pow_1", "__fs_pow_16", FIXED(16)}, - - {"__pd_pow_1", "__pd_pow_2", FIXED(2)}, - {"__pd_pow_1", "__pd_pow_4", FIXED(4)}, - {"__pd_pow_1", "__pd_pow_8", FIXED(8)}, - - {"__ps_pow_1", "__ps_pow_4", FIXED(4)}, - {"__ps_pow_1", "__ps_pow_8", FIXED(8)}, - {"__ps_pow_1", "__ps_pow_16", FIXED(16)}, - - {"__rd_pow_1", "__rd_pow_2", FIXED(2)}, - {"__rd_pow_1", "__rd_pow_4", FIXED(4)}, - {"__rd_pow_1", "__rd_pow_8", FIXED(8)}, - - {"__rs_pow_1", "__rs_pow_4", FIXED(4)}, - {"__rs_pow_1", "__rs_pow_8", FIXED(8)}, - {"__rs_pow_1", "__rs_pow_16", FIXED(16)}, - - {"__fs_powi_1", "__fs_powi_4", FIXED(4)}, - {"__fs_powi_1", "__fs_powi_8", FIXED(8)}, - {"__fs_powi_1", "__fs_powi_16", FIXED(16)}, - - {"__ps_powi_1", "__ps_powi_4", FIXED(4)}, - {"__ps_powi_1", "__ps_powi_8", FIXED(8)}, - {"__ps_powi_1", "__ps_powi_16", FIXED(16)}, - - {"__rs_powi_1", "__rs_powi_4", FIXED(4)}, - {"__rs_powi_1", "__rs_powi_8", FIXED(8)}, - {"__rs_powi_1", "__rs_powi_16", FIXED(16)}, - - {"__fd_powi1_1", "__fd_powi1_2", FIXED(2)}, - {"__fd_powi1_1", "__fd_powi1_4", FIXED(4)}, - {"__fd_powi1_1", "__fd_powi1_8", FIXED(8)}, - - {"__fs_powi1_1", "__fs_powi1_4", FIXED(4)}, - {"__fs_powi1_1", "__fs_powi1_8", FIXED(8)}, - {"__fs_powi1_1", "__fs_powi1_16", FIXED(16)}, - - {"__pd_powi1_1", "__pd_powi1_2", FIXED(2)}, - {"__pd_powi1_1", "__pd_powi1_4", FIXED(4)}, - {"__pd_powi1_1", "__pd_powi1_8", FIXED(8)}, - - {"__ps_powi1_1", "__ps_powi1_4", FIXED(4)}, - {"__ps_powi1_1", "__ps_powi1_8", FIXED(8)}, - {"__ps_powi1_1", "__ps_powi1_16", FIXED(16)}, - - {"__rd_powi1_1", "__rd_powi1_2", FIXED(2)}, - {"__rd_powi1_1", "__rd_powi1_4", FIXED(4)}, - {"__rd_powi1_1", "__rd_powi1_8", FIXED(8)}, - - {"__rs_powi1_1", "__rs_powi1_4", FIXED(4)}, - {"__rs_powi1_1", "__rs_powi1_8", FIXED(8)}, - {"__rs_powi1_1", "__rs_powi1_16", FIXED(16)}, - - {"__fd_powk_1", "__fd_powk_2", FIXED(2)}, - {"__fd_powk_1", "__fd_powk_4", FIXED(4)}, - {"__fd_powk_1", "__fd_powk_8", FIXED(8)}, - - {"__fs_powk_1", "__fs_powk_4", FIXED(4)}, - {"__fs_powk_1", "__fs_powk_8", FIXED(8)}, - {"__fs_powk_1", "__fs_powk_16", FIXED(16)}, - - {"__pd_powk_1", "__pd_powk_2", FIXED(2)}, - {"__pd_powk_1", "__pd_powk_4", FIXED(4)}, - {"__pd_powk_1", "__pd_powk_8", FIXED(8)}, - - {"__ps_powk_1", "__ps_powk_4", FIXED(4)}, - {"__ps_powk_1", "__ps_powk_8", FIXED(8)}, - {"__ps_powk_1", "__ps_powk_16", FIXED(16)}, - - {"__rd_powk_1", "__rd_powk_2", FIXED(2)}, - {"__rd_powk_1", "__rd_powk_4", FIXED(4)}, - {"__rd_powk_1", "__rd_powk_8", FIXED(8)}, - - {"__rs_powk_1", "__rs_powk_4", FIXED(4)}, - {"__rs_powk_1", "__rs_powk_8", FIXED(8)}, - {"__rs_powk_1", "__rs_powk_16", FIXED(16)}, - - {"__fd_powk1_1", "__fd_powk1_2", FIXED(2)}, - {"__fd_powk1_1", "__fd_powk1_4", FIXED(4)}, - {"__fd_powk1_1", "__fd_powk1_8", FIXED(8)}, - - {"__fs_powk1_1", "__fs_powk1_4", FIXED(4)}, - {"__fs_powk1_1", "__fs_powk1_8", FIXED(8)}, - {"__fs_powk1_1", "__fs_powk1_16", FIXED(16)}, - - {"__pd_powk1_1", "__pd_powk1_2", FIXED(2)}, - {"__pd_powk1_1", "__pd_powk1_4", FIXED(4)}, - {"__pd_powk1_1", "__pd_powk1_8", FIXED(8)}, - - {"__ps_powk1_1", "__ps_powk1_4", FIXED(4)}, - {"__ps_powk1_1", "__ps_powk1_8", FIXED(8)}, - {"__ps_powk1_1", "__ps_powk1_16", FIXED(16)}, - - {"__rd_powk1_1", "__rd_powk1_2", FIXED(2)}, - {"__rd_powk1_1", "__rd_powk1_4", FIXED(4)}, - {"__rd_powk1_1", "__rd_powk1_8", FIXED(8)}, - - {"__rs_powk1_1", "__rs_powk1_4", FIXED(4)}, - {"__rs_powk1_1", "__rs_powk1_8", FIXED(8)}, - {"__rs_powk1_1", "__rs_powk1_16", FIXED(16)}, - - {"__fd_log10_1", "__fd_log10_2", FIXED(2)}, - {"__fd_log10_1", "__fd_log10_4", FIXED(4)}, - {"__fd_log10_1", "__fd_log10_8", FIXED(8)}, - - {"__fs_log10_1", "__fs_log10_4", FIXED(4)}, - {"__fs_log10_1", "__fs_log10_8", FIXED(8)}, - {"__fs_log10_1", "__fs_log10_16", FIXED(16)}, - - {"__pd_log10_1", "__pd_log10_2", FIXED(2)}, - {"__pd_log10_1", "__pd_log10_4", FIXED(4)}, - {"__pd_log10_1", "__pd_log10_8", FIXED(8)}, - - {"__ps_log10_1", "__ps_log10_4", FIXED(4)}, - {"__ps_log10_1", "__ps_log10_8", FIXED(8)}, - {"__ps_log10_1", "__ps_log10_16", FIXED(16)}, - - {"__rd_log10_1", "__rd_log10_2", FIXED(2)}, - {"__rd_log10_1", "__rd_log10_4", FIXED(4)}, - {"__rd_log10_1", "__rd_log10_8", FIXED(8)}, - - {"__rs_log10_1", "__rs_log10_4", FIXED(4)}, - {"__rs_log10_1", "__rs_log10_8", FIXED(8)}, - {"__rs_log10_1", "__rs_log10_16", FIXED(16)}, - - {"__fd_log_1", "__fd_log_2", FIXED(2)}, - {"__fd_log_1", "__fd_log_4", FIXED(4)}, - {"__fd_log_1", "__fd_log_8", FIXED(8)}, - - {"__fs_log_1", "__fs_log_4", FIXED(4)}, - {"__fs_log_1", "__fs_log_8", FIXED(8)}, - {"__fs_log_1", "__fs_log_16", FIXED(16)}, - - {"__pd_log_1", "__pd_log_2", FIXED(2)}, - {"__pd_log_1", "__pd_log_4", FIXED(4)}, - {"__pd_log_1", "__pd_log_8", FIXED(8)}, - - {"__ps_log_1", "__ps_log_4", FIXED(4)}, - {"__ps_log_1", "__ps_log_8", FIXED(8)}, - {"__ps_log_1", "__ps_log_16", FIXED(16)}, - - {"__rd_log_1", "__rd_log_2", FIXED(2)}, - {"__rd_log_1", "__rd_log_4", FIXED(4)}, - {"__rd_log_1", "__rd_log_8", FIXED(8)}, - - {"__rs_log_1", "__rs_log_4", FIXED(4)}, - {"__rs_log_1", "__rs_log_8", FIXED(8)}, - {"__rs_log_1", "__rs_log_16", FIXED(16)}, - - {"__fs_exp_1", "__fs_exp_4", FIXED(4)}, - {"__fs_exp_1", "__fs_exp_8", FIXED(8)}, - {"__fs_exp_1", "__fs_exp_16", FIXED(16)}, - - {"__pd_exp_1", "__pd_exp_2", FIXED(2)}, - {"__pd_exp_1", "__pd_exp_4", FIXED(4)}, - {"__pd_exp_1", "__pd_exp_8", FIXED(8)}, - - {"__ps_exp_1", "__ps_exp_4", FIXED(4)}, - {"__ps_exp_1", "__ps_exp_8", FIXED(8)}, - {"__ps_exp_1", "__ps_exp_16", FIXED(16)}, - - {"__rd_exp_1", "__rd_exp_2", FIXED(2)}, - {"__rd_exp_1", "__rd_exp_4", FIXED(4)}, - {"__rd_exp_1", "__rd_exp_8", FIXED(8)}, - - {"__rs_exp_1", "__rs_exp_4", FIXED(4)}, - {"__rs_exp_1", "__rs_exp_8", FIXED(8)}, - {"__rs_exp_1", "__rs_exp_16", FIXED(16)} - }; - addVectorizableFunctions(VecFuncs); + if (T.getArch() == Triple::aarch64) { + const VecDesc VecFuncs[] = { + #define TLI_DEFINE_PGMATH_AARCH64_VECFUNCS + #include "llvm/Analysis/VecFuncs.def" + }; + addVectorizableFunctions(VecFuncs); + } else if (T.getArch() == Triple::x86_64) { + const VecDesc VecFuncs[] = { + #define TLI_DEFINE_PGMATH_X86_VECFUNCS + #include "llvm/Analysis/VecFuncs.def" + }; + addVectorizableFunctions(VecFuncs); + } break; } #endif -- Gitee From 17343eb8db44ac71509d6ede42dbb2ccae067c3e Mon Sep 17 00:00:00 2001 From: Gabriel Baraldi Date: Wed, 30 Nov 2022 16:33:35 -0300 Subject: [PATCH 30/47] Delete libpgmath veclib definitions for sincos As noted in flang-compiler#11, flang currently crashes when lowering a sincos reference into a libpgmath runtime function call. The issue is that `__fd_sincos_1` is defined as returning a `<{ double, double }>` struct and there is no LLVM support for automatically vectorizing target functions of this form. In particular, it is somewhat ambiguous how to vectorize such functions, i.e. how they pack their return values into the vector registers. libpgmath itself also has a somewhat questionable implementation of the vector forms of `sincos`, relying on this beauty: https://github.com/flang-compiler/flang/blob/master/runtime/libpgmath/lib/common/mth_vreturns.c#L8-L47 This may sometimes work in practice, but it is not particularly robust. For example, this will definitely break in any sort of LTO or instrumentation setting. I think until libpgmath is updated and LLVM upstream has a consensus on how to vectorize these functions, we just need to stop trying to vectorize these functions. As noted, since LLVM was crashing anyway, no performance and functionality is lost here over current master. Fixes flang-compiler#11. Originally By: Keno Fischer --- llvm/include/llvm/Analysis/VecFuncs.def | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/llvm/include/llvm/Analysis/VecFuncs.def b/llvm/include/llvm/Analysis/VecFuncs.def index 836420060b1d..d1712d158423 100644 --- a/llvm/include/llvm/Analysis/VecFuncs.def +++ b/llvm/include/llvm/Analysis/VecFuncs.def @@ -1131,30 +1131,6 @@ TLI_DEFINE_VECFUNC("__rs_cos_1", "__rs_cos_4", FIXED(4)) TLI_DEFINE_VECFUNC("__rs_cos_1", "__rs_cos_8", FIXED(8)) TLI_DEFINE_VECFUNC("__rs_cos_1", "__rs_cos_16", FIXED(16)) -TLI_DEFINE_VECFUNC("__fd_sincos_1", "__fd_sincos_2", FIXED(2)) -TLI_DEFINE_VECFUNC("__fd_sincos_1", "__fd_sincos_4", FIXED(4)) -TLI_DEFINE_VECFUNC("__fd_sincos_1", "__fd_sincos_8", FIXED(8)) - -TLI_DEFINE_VECFUNC("__fs_sincos_1", "__fs_sincos_4", FIXED(4)) -TLI_DEFINE_VECFUNC("__fs_sincos_1", "__fs_sincos_8", FIXED(8)) -TLI_DEFINE_VECFUNC("__fs_sincos_1", "__fs_sincos_16", FIXED(16)) - -TLI_DEFINE_VECFUNC("__pd_sincos_1", "__pd_sincos_2", FIXED(2)) -TLI_DEFINE_VECFUNC("__pd_sincos_1", "__pd_sincos_4", FIXED(4)) -TLI_DEFINE_VECFUNC("__pd_sincos_1", "__pd_sincos_8", FIXED(8)) - -TLI_DEFINE_VECFUNC("__ps_sincos_1", "__ps_sincos_4", FIXED(4)) -TLI_DEFINE_VECFUNC("__ps_sincos_1", "__ps_sincos_8", FIXED(8)) -TLI_DEFINE_VECFUNC("__ps_sincos_1", "__ps_sincos_16", FIXED(16)) - -TLI_DEFINE_VECFUNC("__rd_sincos_1", "__rd_sincos_2", FIXED(2)) -TLI_DEFINE_VECFUNC("__rd_sincos_1", "__rd_sincos_4", FIXED(4)) -TLI_DEFINE_VECFUNC("__rd_sincos_1", "__rd_sincos_8", FIXED(8)) - -TLI_DEFINE_VECFUNC("__rs_sincos_1", "__rs_sincos_4", FIXED(4)) -TLI_DEFINE_VECFUNC("__rs_sincos_1", "__rs_sincos_8", FIXED(8)) -TLI_DEFINE_VECFUNC("__rs_sincos_1", "__rs_sincos_16", FIXED(16)) - TLI_DEFINE_VECFUNC("__fd_tan_1", "__fd_tan_2", FIXED(2)) TLI_DEFINE_VECFUNC("__fd_tan_1", "__fd_tan_4", FIXED(4)) TLI_DEFINE_VECFUNC("__fd_tan_1", "__fd_tan_8", FIXED(8)) -- Gitee From 9641bcc88f510e3c1a2a4f62ef7d92729734bad4 Mon Sep 17 00:00:00 2001 From: Tibor Dusnoki Date: Wed, 30 Nov 2022 18:07:20 +0100 Subject: [PATCH 31/47] Add platform independent build script for LLVM (release_15x) --- scripts/build_llvm_project.py | 151 ++++++++++++++++++++ scripts/cmake/toolchain_linux_x86_64.cmake | 2 + scripts/cmake/toolchain_windows_amd64.cmake | 2 + scripts/cmake/toolchain_windows_arm64.cmake | 6 + scripts/settings.py | 5 + 5 files changed, 166 insertions(+) create mode 100644 scripts/build_llvm_project.py create mode 100644 scripts/cmake/toolchain_linux_x86_64.cmake create mode 100644 scripts/cmake/toolchain_windows_amd64.cmake create mode 100644 scripts/cmake/toolchain_windows_arm64.cmake create mode 100644 scripts/settings.py diff --git a/scripts/build_llvm_project.py b/scripts/build_llvm_project.py new file mode 100644 index 000000000000..4ac1e8b63b2a --- /dev/null +++ b/scripts/build_llvm_project.py @@ -0,0 +1,151 @@ +#!/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=Path(settings.LLVM_DIR,'..','install'), const=False, + help='install directory (default: %(default)s) ') + 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): + install_root = Path(arguments.install_prefix) + + base_cmake_args = [ + f'-DCMAKE_INSTALL_PREFIX={install_root.as_posix()}', + f'-DCMAKE_BUILD_TYPE={arguments.build_type}', + f'-DCMAKE_TOOLCHAIN_FILE={arguments.toolchain}' + ] + if sys.platform == 'win32' and platform.uname()[4].lower() == 'arm64': + base_cmake_args.append('-GNMake Makefiles') + else: + generator = 'Ninja' if sys.platform == 'win32' else 'Unix Makefiles' + base_cmake_args.append(f'-G{generator}') + + 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.extend('-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) + 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') -- Gitee From 4e0819aed67b5f02bd34e7e5e3c4a7a95fdf0c02 Mon Sep 17 00:00:00 2001 From: Adam Kallai Date: Thu, 26 Jan 2023 17:30:15 +0100 Subject: [PATCH 32/47] win: Fix the build with verbose options The 'append' method should be used instead of extend, since the 'extend' method treats the arguments as an iterable object, so extends the current list with list of characters. --- scripts/build_llvm_project.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/build_llvm_project.py b/scripts/build_llvm_project.py index 4ac1e8b63b2a..6f08a0ce601d 100644 --- a/scripts/build_llvm_project.py +++ b/scripts/build_llvm_project.py @@ -80,7 +80,7 @@ def generate_buildoptions(arguments): base_cmake_args.append(f'-DCMAKE_CXX_COMPILER={arguments.cxx}') if arguments.verbose: - base_cmake_args.extend('-DCMAKE_VERBOSE_MAKEFILE=ON') + base_cmake_args.append('-DCMAKE_VERBOSE_MAKEFILE=ON') return base_cmake_args -- Gitee From 86a80e0c2cd7effe85fd3a5ce6b1ecc93668c422 Mon Sep 17 00:00:00 2001 From: Adam Kallai Date: Tue, 24 Jan 2023 11:22:55 +0100 Subject: [PATCH 33/47] win: Don't install llvm by default The 'llvm_build_project' build script installs llvm after the build by default. It is not necessary, if the user doesn't want. --- scripts/build_llvm_project.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/scripts/build_llvm_project.py b/scripts/build_llvm_project.py index 6f08a0ce601d..a2b8422fcfa7 100644 --- a/scripts/build_llvm_project.py +++ b/scripts/build_llvm_project.py @@ -25,8 +25,8 @@ def get_arguments(): 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=Path(settings.LLVM_DIR,'..','install'), const=False, - help='install directory (default: %(default)s) ') + buildopt.add_argument('-p', '--install-prefix', metavar='PATH', nargs='?', default=None, const=False, + help='Install directory (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(), @@ -53,19 +53,21 @@ def get_arguments(): return arguments def generate_buildoptions(arguments): - install_root = Path(arguments.install_prefix) - base_cmake_args = [ - f'-DCMAKE_INSTALL_PREFIX={install_root.as_posix()}', f'-DCMAKE_BUILD_TYPE={arguments.build_type}', f'-DCMAKE_TOOLCHAIN_FILE={arguments.toolchain}' ] + if sys.platform == 'win32' and platform.uname()[4].lower() == 'arm64': base_cmake_args.append('-GNMake Makefiles') else: 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') @@ -144,7 +146,8 @@ def main(): print_header('Building classic llvm') build_path = configure_llvm(arguments) build_project(build_path, arguments) - install_project(build_path, arguments) + if arguments.install_prefix is not None: + install_project(build_path, arguments) if __name__ == "__main__": main() -- Gitee From 4f10980eaa95bf36241aabe4e30d02c03a98943b Mon Sep 17 00:00:00 2001 From: Peixin Qiao Date: Sat, 4 Mar 2023 01:47:47 +0800 Subject: [PATCH 34/47] [Driver][ClassicFlang] Add options -fno-automatic and -f(no-)implicit-none These three options are added in release_12. When compiling programs with them using Classic Flang, there are only warnings generated. They are removed now so that the errors of "unknown argument" are reported. Add these options in Driver for compatibility reason. Please note that these options are not implemented yet in Classic Flang. --- clang/include/clang/Driver/Options.td | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 3d7fa803c504..365285966a67 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -5452,6 +5452,10 @@ def fbackslash : Flag<["-"], "fbackslash">, Group, 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.">; -- Gitee From 6ded755f6837ca0aa8b1be5f44b8d235eb759d2c Mon Sep 17 00:00:00 2001 From: Bryan Chan Date: Tue, 28 Feb 2023 18:27:35 -0500 Subject: [PATCH 35/47] [Driver] Don't use Classic Flang tools for LLVM IR input LLVM IR input should not be acceptable for Classic Flang tools. This bug was caused by an incorrect merge conflict resolution when upgrading to LLVM 15. --- clang/lib/Driver/Types.cpp | 3 ++- clang/test/Driver/flang/Inputs/llvm-ir-input.ll | 0 clang/test/Driver/flang/llvm-ir-input.f | 7 +++++++ 3 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 clang/test/Driver/flang/Inputs/llvm-ir-input.ll create mode 100644 clang/test/Driver/flang/llvm-ir-input.f diff --git a/clang/lib/Driver/Types.cpp b/clang/lib/Driver/Types.cpp index 57e050e576f0..a10c6e2c6c42 100755 --- a/clang/lib/Driver/Types.cpp +++ b/clang/lib/Driver/Types.cpp @@ -175,14 +175,15 @@ bool types::isAcceptedByFlang(ID Id) { case TY_PP_F_FreeForm: case TY_F_FixedForm: case TY_PP_F_FixedForm: + return true; #else case TY_Fortran: case TY_PP_Fortran: -#endif return true; case TY_LLVM_IR: case TY_LLVM_BC: return true; +#endif } } 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/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" -- Gitee From 0b1ce7179e48793d8afe79478331ddf21200dd3a Mon Sep 17 00:00:00 2001 From: Adam Kallai Date: Wed, 4 Jan 2023 16:49:46 +0100 Subject: [PATCH 36/47] Setup Windows x64/arm64 GitHub action for Classic Flang LLVM * Extend pre-compile_llvm workflow with a Windows job which defines build strategy for X64 and ARM64 architectures to produce prebuilt LLVM binaries for both platform. Currently Windows on ARM job is disabled, until an official will be available. * Also enable Classic Flang LLVM testing on Windows x64 only. Some tests are failing on Windows on ARM, so we don't run tests on WoA until they are fixed. * Added Windows support to 'classic-flang.f95' driver test. Modified FileChecker regex pattern to match Windows path separator and binary suffix too. --- .github/workflows/llvm-project-tests.yml | 42 ++++++- .github/workflows/pre-compile_llvm.yml | 136 ++++++++++++++++++++++ clang/test/Driver/flang/classic-flang.f95 | 12 +- 3 files changed, 178 insertions(+), 12 deletions(-) create mode 100644 .github/workflows/pre-compile_llvm.yml diff --git a/.github/workflows/llvm-project-tests.yml b/.github/workflows/llvm-project-tests.yml index 26a08a70f3db..ac36153f23e1 100644 --- a/.github/workflows/llvm-project-tests.yml +++ b/.github/workflows/llvm-project-tests.yml @@ -43,17 +43,29 @@ jobs: # We're using a specific version of macOS due to: # https://github.com/actions/virtual-environments/issues/5900 - macOS-11 + - windows-latest + include: + # Enable Windows on ARM build, when an official + # self-hosted machine is available. + # - os: self-hosted + # target: AArch64 + # arch: arm64 + - os: windows-latest + arch: amd64 + steps: - name: Setup Windows - if: startsWith(matrix.os, 'windows') + if: startsWith(matrix.os, 'windows') || startsWith(matrix.os, 'self') uses: llvm/actions/setup-windows@main with: - arch: amd64 - # On Windows, starting with win19/20220814.1, cmake choose the 32-bit - # python3.10.6 libraries instead of the 64-bit libraries when building - # lldb. Using this setup-python action to make 3.10 the default - # python fixes this. + arch: ${{ matrix.arch }} + # By default CMake chooses the most recent 32-bit libraries instead of + # the 64-bit libraries when building and testing LLVM or Clang. + # 32 bit version causes a memory error during the testing. + # On 'windows-latest' GitHub image (VS2022) 3.11 (32bit) version is installed. + # Using this setup-python action to make 3.11 (64bit) the default - name: Setup Python + if: ${{ matrix.os != 'self-hosted' }} uses: actions/setup-python@v4 with: python-version: '3.11' @@ -62,10 +74,18 @@ jobs: # actions/checkout deletes any existing files in the new git directory, # so this needs to either run before ccache-action or it has to use # clean: false. + - name: Setup psutil + # psutil is not available on Windows on ARM. + if: startsWith(matrix.os, 'windows') + run: pip install psutil + - name: Check tools + run: python --version - uses: actions/checkout@v3 with: fetch-depth: 250 - name: Setup ccache + # ccache is not available for Windows on ARM. + if: ${{ matrix.os != 'self-hosted' }} uses: hendrikmuhs/ccache-action@v1 with: # A full build of llvm, clang, lld, and lldb takes about 250MB @@ -78,6 +98,16 @@ jobs: max-size: 500M key: sccache-${{ matrix.os }} variant: sccache + - name: Test clang Windows + # Some LLVM tests are failing on Windows On ARM, + # so this step is skipped on WoA until they are fixed. + if: ${{ matrix.os == 'windows-latest' }} + run: | + $pcount = $($(Get-WmiObject -class Win32_ComputerSystem).numberoflogicalprocessors) + python .\scripts\build_llvm_project.py -d build -t ${{ matrix.target }} --cmake-param=-DLLVM_ENABLE_ASSERTIONS=ON -j $pcount + cd build + ninja check-all + shell: powershell - name: Build and Test uses: llvm/actions/build-test-llvm-project@main env: diff --git a/.github/workflows/pre-compile_llvm.yml b/.github/workflows/pre-compile_llvm.yml new file mode 100644 index 000000000000..841f6c1dc976 --- /dev/null +++ b/.github/workflows/pre-compile_llvm.yml @@ -0,0 +1,136 @@ +name: Pre-compile llvm + +on: + workflow_dispatch: + push: + branches: + - 'release_*x' + +jobs: + build: + name: Ubuntu Linux + runs-on: ubuntu-20.04 + strategy: + matrix: + target: [X86] + cc: [clang, gcc] + version: [10, 11] + + steps: + - if: matrix.cc == 'clang' + run: | + echo "cpp=clang++" >> $GITHUB_ENV + sudo add-apt-repository ppa:ubuntu-toolchain-r/ppa + sudo touch /etc/apt/sources.list.d/llvm.list + echo 'deb http://apt.llvm.org/focal/ llvm-toolchain-focal-11 main' | sudo tee -a /etc/apt/sources.list.d/llvm.list + echo 'deb-src http://apt.llvm.org/focal/ llvm-toolchain-focal-11 main' | sudo tee -a /etc/apt/sources.list.d/llvm.list + wget -q -O - http://apt.llvm.org/llvm-snapshot.gpg.key|sudo apt-key add - + sudo apt update + sudo apt install -f -y llvm-${{ matrix.version }} clang-${{ matrix.version}} + + - if: matrix.cc == 'gcc' && matrix.version == '10' + run: | + echo "cpp=g++" >> $GITHUB_ENV + sudo add-apt-repository ppa:ubuntu-toolchain-r/ppa + sudo apt install gcc-10 g++-10 + + - if: matrix.cc == 'gcc' && matrix.version == '11' + run: | + echo "cpp=g++" >> $GITHUB_ENV + sudo add-apt-repository ppa:ubuntu-toolchain-r/ppa + sudo apt install gcc-11 g++-11 + + - name: Check tools + run: | + git --version + cmake --version + make --version + ${{ matrix.cc }}-${{ matrix.version }} --version + ${{env.cpp}}-${{ matrix.version }} --version + + - name: Extract branch name + run: echo "::set-output name=branch::${GITHUB_REF#refs/heads/}" + id: extract_branch + + - name: Build llvm + run: | + # exit the llvm dir, so the path is the same on subsequent projects + cd ../.. + rm -rf classic-flang-llvm-project + # clone manually, because checkout does not allow exiting llvm dir + git clone --depth 1 --single-branch --branch ${{ steps.extract_branch.outputs.branch }} https://github.com/flang-compiler/classic-flang-llvm-project.git + cd classic-flang-llvm-project + # After build place the artifacts in classic-flang-llvm-project/classic-flang-llvm-project, so Upload can find them. + mkdir classic-flang-llvm-project + ./build-llvm-project.sh \ + -t ${{ matrix.target }} \ + -p /usr/local \ + -a /usr/bin/${{ matrix.cc }}-${{ matrix.version }} \ + -b /usr/bin/${{env.cpp}}-${{ matrix.version }} \ + -n $(nproc) \ + -x "-DLLVM_ENABLE_ASSERTIONS=ON" \ + -v + # Archive the source + build directories for future installation + cd .. + tar -zcf llvm_build.tar.gz classic-flang-llvm-project + # Upload will only look in $GITHUB_WORKSPACE or its subdirs. + mv llvm_build.tar.gz classic-flang-llvm-project/classic-flang-llvm-project/. + + - name: Upload llvm + uses: actions/upload-artifact@v2 + with: + name: llvm_build_${{ matrix.target }}_${{ matrix.cc }}_${{ matrix.version }}_${{ steps.extract_branch.outputs.branch }} + path: llvm_build.tar.gz + + build-win: + name: Windows build + runs-on: ${{ matrix.os }} + strategy: + matrix: + include: + - os: windows-latest + arch: amd64 + target: X86 + # Enable Windows on ARM build, when an official + # self-hosted machine is available. + # - os: self-hosted + # arch: arm64 + # target: AArch64 + + steps: + - uses: actions/checkout@v3 + + - name: Setup Windows + uses: llvm/actions/setup-windows@main + with: + arch: ${{ matrix.arch }} + + - name: Setup Ninja + uses: llvm/actions/install-ninja@main + + - name: Check tools + run: | + git --version + cmake --version + clang --version + ninja --version + python --version + + - name: Extract branch name + id: extract_branch + run: echo "branch=$(("${{ github.ref }}" -split "/")[-1])" >> $env:GITHUB_OUTPUT + + - name: Build llvm + shell: powershell + run: | + $pcount = $($(Get-WmiObject -class Win32_ComputerSystem).numberoflogicalprocessors) + python .\scripts\build_llvm_project.py -d build -t ${{ matrix.target }} --cmake-param=-DLLVM_ENABLE_ASSERTIONS=ON -j $pcount -v + cd .. + 7z a llvm_build.7z $pwd/classic-flang-llvm-project/ + Copy-Item llvm_build.7z -Destination $pwd/classic-flang-llvm-project/ + + - name: Upload llvm + uses: actions/upload-artifact@v3 + with: + name: llvm_build_win_${{ matrix.arch }}_clangcl_${{ steps.extract_branch.outputs.branch }} + path: ${{ github.workspace }}\llvm_build.7z diff --git a/clang/test/Driver/flang/classic-flang.f95 b/clang/test/Driver/flang/classic-flang.f95 index 463bdb7e429b..ceb57b7d116e 100644 --- a/clang/test/Driver/flang/classic-flang.f95 +++ b/clang/test/Driver/flang/classic-flang.f95 @@ -59,17 +59,17 @@ ! 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-STATIC-FLANG,CHECK-NO-OMP %s -! CHECK-LD: "{{.*}}ld" +! CHECK-LD: "{{.*}}ld{{(.exe)?}}" ! CHECK-LD-NOT: "-static" -! CHECK-LD: "{{[^"]*}}classic-flang-{{[^ ]*}}.o" "-lflangmain" "-lfoo" "-L{{[^ ]*}}/basic_linux_tree/usr/lib" +! CHECK-LD: "{{[^"]*}}classic-flang-{{[^ ]*}}.o" "-lflangmain" "-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" "-rpath" "{{[^ ]*}}/basic_linux_tree/usr/lib" +! CHECK-DYNAMIC-OMP: "-lomp" "-rpath" "{{[^ ]*[/\\]+}}basic_linux_tree{{[/\\]+}}usr{{[/\\]+}}lib" ! CHECK-DYNAMIC-OMP-NOT: "-Bdynamic" -! CHECK-STATIC-OMP: "-Bstatic" "-lomp" "-Bdynamic" "-rpath" "{{[^ ]*}}/basic_linux_tree/usr/lib" +! CHECK-STATIC-OMP: "-Bstatic" "-lomp" "-Bdynamic" "-rpath" "{{[^ ]*[/\\]+}}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 \ @@ -78,9 +78,9 @@ ! 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" +! 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: "{{[^"]*}}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" -- Gitee From ae2af16a748d97d81a09006f154689e21473d09d Mon Sep 17 00:00:00 2001 From: Adam Kallai Date: Thu, 16 Mar 2023 10:35:37 +0100 Subject: [PATCH 37/47] script: update llvm build script * Native Ninja is already available for Windows on ARM, so we can use it on both Windows platform. * Introduced a new '-i' build option to trigger whether the user wants to install LLVM or not. Previously the script relies on install_prefix option which was wrong approach. In this case we still could not defer the install for a later time if install directory was set. With this change the python build script will be consistent with official bash script. --- scripts/build_llvm_project.py | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/scripts/build_llvm_project.py b/scripts/build_llvm_project.py index a2b8422fcfa7..86a4fea61cff 100644 --- a/scripts/build_llvm_project.py +++ b/scripts/build_llvm_project.py @@ -26,27 +26,29 @@ def get_arguments(): 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='Install directory (default: do not install)') + 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)') + 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)') + 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)') + help=f'Specify build directory (default: {settings.LLVM_DIR}/%(default)s)') buildopt.add_argument('--clean', action='store_true', default=False, - help='clean build') + help='Clean build') buildopt.add_argument('-b', '--build-type', metavar='TYPE', default='Release', - help='set build type (default: %(default)s)') + help='Set build type (default: %(default)s)') buildopt.add_argument('-x', '--cmake-param', metavar='OPT', action='append', default=[], - help='add custom argument to CMake') + 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")') + 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') + help='Use specific C compiler') buildopt.add_argument('--cxx', metavar='OPT', default=None, - help='use specific C++ compiler') + 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() @@ -58,11 +60,8 @@ def generate_buildoptions(arguments): f'-DCMAKE_TOOLCHAIN_FILE={arguments.toolchain}' ] - if sys.platform == 'win32' and platform.uname()[4].lower() == 'arm64': - base_cmake_args.append('-GNMake Makefiles') - else: - generator = 'Ninja' if sys.platform == 'win32' else 'Unix Makefiles' - base_cmake_args.append(f'-G{generator}') + 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) @@ -143,10 +142,10 @@ def print_header(title): def main(): arguments = get_arguments() - print_header('Building classic llvm') + print_header('Building classic LLVM') build_path = configure_llvm(arguments) build_project(build_path, arguments) - if arguments.install_prefix is not None: + if arguments.install: install_project(build_path, arguments) if __name__ == "__main__": -- Gitee From 6b40f28e2911995db9f5ff565cc67d2a4cf37d66 Mon Sep 17 00:00:00 2001 From: Bryan Chan Date: Mon, 3 Jul 2023 12:24:44 -0400 Subject: [PATCH 38/47] [build] Specify LLVM_MAIN_SRC_DIR when running build-flang.sh Otherwise Classic Flang's CMakeLists.txt will be unable to find llvm-lit and cannot generate test-related goals, e.g. `check-all`. --- .github/workflows/flang-arm64-tests.yml | 70 +++++++++++++++++++++ .github/workflows/flang-tests.yml | 81 +++++++++++++++++++++++++ 2 files changed, 151 insertions(+) create mode 100644 .github/workflows/flang-arm64-tests.yml create mode 100644 .github/workflows/flang-tests.yml diff --git a/.github/workflows/flang-arm64-tests.yml b/.github/workflows/flang-arm64-tests.yml new file mode 100644 index 000000000000..59f310f3a272 --- /dev/null +++ b/.github/workflows/flang-arm64-tests.yml @@ -0,0 +1,70 @@ +name: Build and test Flang + +on: + pull_request: + branches: + - 'release_*x' + +jobs: + build: + runs-on: self-hosted + env: + build_path: /home/github + install_prefix: /home/github/usr/local + container: + image: ghcr.io/${{ github.repository_owner}}/ubuntu20-flang-${{ github.base_ref }}:latest + credentials: + username: github + strategy: + matrix: + target: [AArch64] + cc: [clang] + cpp: [clang++] + version: [10, 11] + include: + - target: AArch64 + cc: gcc + cpp: g++ + version: 10 + + steps: + - name: Check tools + run: | + git --version + cmake --version + make --version + ${{ matrix.cc }}-${{ matrix.version }} --version + ${{ matrix.cpp }}-${{ matrix.version }} --version + + - name: Manual checkout to build in user's home dir (pull_request) + run: | + cd ${{ env.build_path }} + git clone https://github.com/flang-compiler/classic-flang-llvm-project.git + cd classic-flang-llvm-project + git fetch origin ${{github.ref}}:pr_branch + git checkout pr_branch + + - name: Build and install llvm + run: | + cd ${{ env.build_path }}/classic-flang-llvm-project + ./build-llvm-project.sh -t ${{ matrix.target }} -p ${{ env.install_prefix }} -a /usr/bin/${{ matrix.cc }}-${{ matrix.version }} -b /usr/bin/${{ matrix.cpp }}-${{ matrix.version }} -n $(nproc) -i -x "-DLLVM_ENABLE_ASSERTIONS=ON" -v + + - name: Checkout flang + run: | + cd ${{ env.build_path }} + git clone --depth 1 --single-branch --branch master https://github.com/flang-compiler/flang.git + + - name: Build and install libpgmath & flang + run: | + cd ${{ env.build_path }}/flang + ./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: | + cd ${{ env.build_path }}/flang + cp ${{ env.build_path }}/classic-flang-llvm-project/build/bin/llvm-lit build/flang/bin/ + + - name: Test flang + run: | + cd ${{ env.build_path }}/flang/build/flang + make check-all diff --git a/.github/workflows/flang-tests.yml b/.github/workflows/flang-tests.yml new file mode 100644 index 000000000000..9d225e96c2a1 --- /dev/null +++ b/.github/workflows/flang-tests.yml @@ -0,0 +1,81 @@ +name: Build and test Flang + +on: + pull_request: + branches: + - 'release_*x' + +jobs: + build: + runs-on: ubuntu-20.04 + env: + install_prefix: /usr/local + strategy: + matrix: + target: [X86] + cc: [clang] + cpp: [clang++] + version: [10, 11] + include: + - target: X86 + cc: gcc + cpp: g++ + version: 10 + + steps: + - uses: actions/checkout@v2 + + - if: matrix.cc == 'clang' + run: | + sudo add-apt-repository ppa:ubuntu-toolchain-r/ppa + sudo touch /etc/apt/sources.list.d/llvm.list + echo 'deb http://apt.llvm.org/focal/ llvm-toolchain-focal-11 main' | sudo tee -a /etc/apt/sources.list.d/llvm.list + echo 'deb-src http://apt.llvm.org/focal/ llvm-toolchain-focal-11 main' | sudo tee -a /etc/apt/sources.list.d/llvm.list + wget -q -O - http://apt.llvm.org/llvm-snapshot.gpg.key|sudo apt-key add - + sudo apt update + sudo apt install -f -y llvm-${{ matrix.version }} clang-${{ matrix.version}} + + - if: matrix.cc == 'gcc' && matrix.version == '10' + run: | + sudo add-apt-repository ppa:ubuntu-toolchain-r/ppa + sudo apt install gcc-10 g++-10 + sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 10 + sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 20 + sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-9 10 + sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-10 20 + + - name: ccache + uses: hendrikmuhs/ccache-action@v1 + with: + key: key-${{ matrix.cc }}-${{ matrix.version }} + + - name: Check tools + run: | + git --version + cmake --version + make --version + ${{ matrix.cc }}-${{ matrix.version }} --version + ${{ matrix.cpp }}-${{ matrix.version }} --version + + - name: Build and install llvm + run: ./build-llvm-project.sh -t ${{ matrix.target }} -p ${{ env.install_prefix }} -a /usr/bin/${{ matrix.cc }}-${{ matrix.version }} -b /usr/bin/${{ matrix.cpp }}-${{ matrix.version }} -n $(nproc) -c -i -s -x "-DLLVM_ENABLE_ASSERTIONS=ON" -v + + - name: Checkout flang + run: | + cd ../.. + git clone --depth 1 --single-branch --branch master https://github.com/flang-compiler/flang.git + + - name: Build and install libpgmath & flang + run: | + cd ../../flang + ./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: | + cd ../../flang + cp ../classic-flang-llvm-project/classic-flang-llvm-project/build/bin/llvm-lit build/flang/bin/ + + - name: Test flang + run: | + cd ../../flang/build/flang + make check-all -- Gitee From 5cc4e0d43a4efceb47faed1e76052c3848abc2d9 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Wed, 20 Oct 2021 20:56:05 -0700 Subject: [PATCH 39/47] Pass Flang libraries to MSVC linker correctly The orignal PR was created by Isuruf #65 --- clang/lib/Driver/ToolChains/ClassicFlang.cpp | 8 +++ clang/lib/Driver/ToolChains/CommonArgs.cpp | 2 +- clang/lib/Driver/ToolChains/CommonArgs.h | 2 + clang/lib/Driver/ToolChains/MSVC.cpp | 75 ++++++++++++++++++++ clang/lib/Driver/ToolChains/MSVC.h | 5 ++ 5 files changed, 91 insertions(+), 1 deletion(-) diff --git a/clang/lib/Driver/ToolChains/ClassicFlang.cpp b/clang/lib/Driver/ToolChains/ClassicFlang.cpp index 262f11d28b82..89844c66db49 100644 --- a/clang/lib/Driver/ToolChains/ClassicFlang.cpp +++ b/clang/lib/Driver/ToolChains/ClassicFlang.cpp @@ -1204,6 +1204,14 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, 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/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index 811143497cb4..5db0dbb8e351 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -148,7 +148,7 @@ static bool shouldIgnoreUnsupportedTargetFeature(const Arg &TargetFeatureArg, #ifdef ENABLE_CLASSIC_FLANG /// \brief Determine if Fortran "main" object is needed -static bool needFortranMain(const Driver &D, const ArgList &Args) { +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))); diff --git a/clang/lib/Driver/ToolChains/CommonArgs.h b/clang/lib/Driver/ToolChains/CommonArgs.h index e7d83fec4e40..bd5cb1bb866e 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.h +++ b/clang/lib/Driver/ToolChains/CommonArgs.h @@ -25,6 +25,8 @@ 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, diff --git a/clang/lib/Driver/ToolChains/MSVC.cpp b/clang/lib/Driver/ToolChains/MSVC.cpp index 3cd2f022883b..22f7b2862f21 100644 --- a/clang/lib/Driver/ToolChains/MSVC.cpp +++ b/clang/lib/Driver/ToolChains/MSVC.cpp @@ -267,6 +267,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)) { @@ -514,6 +521,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); diff --git a/clang/lib/Driver/ToolChains/MSVC.h b/clang/lib/Driver/ToolChains/MSVC.h index 0f687bc70ae4..bd146b9a2632 100644 --- a/clang/lib/Driver/ToolChains/MSVC.h +++ b/clang/lib/Driver/ToolChains/MSVC.h @@ -100,6 +100,11 @@ public: void AddHIPRuntimeLibArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const override; +#ifdef ENABLE_CLASSIC_FLANG + void AddFortranStdlibLibArgs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const override; +#endif + bool getWindowsSDKLibraryPath( const llvm::opt::ArgList &Args, std::string &path) const; bool getUniversalCRTLibraryPath(const llvm::opt::ArgList &Args, -- Gitee From 4c8e1610ad6025dde0758ed2d2252fae7381849a Mon Sep 17 00:00:00 2001 From: Adam Kallai Date: Wed, 12 Jul 2023 17:59:28 +0200 Subject: [PATCH 40/47] Add Flang include directory to MSVC toolchain --- clang/lib/Driver/ToolChains/MSVC.cpp | 36 ++++++++++++++++++++++++++++ clang/lib/Driver/ToolChains/MSVC.h | 6 +++++ 2 files changed, 42 insertions(+) diff --git a/clang/lib/Driver/ToolChains/MSVC.cpp b/clang/lib/Driver/ToolChains/MSVC.cpp index 22f7b2862f21..1562e1a4b8eb 100644 --- a/clang/lib/Driver/ToolChains/MSVC.cpp +++ b/clang/lib/Driver/ToolChains/MSVC.cpp @@ -713,6 +713,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.InstalledDir); + 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 bd146b9a2632..46d5af9d114f 100644 --- a/clang/lib/Driver/ToolChains/MSVC.h +++ b/clang/lib/Driver/ToolChains/MSVC.h @@ -84,6 +84,12 @@ public: 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; -- Gitee From a5c8bfec805824f21d53e459d08177e0dd52c41a Mon Sep 17 00:00:00 2001 From: Bryan Chan Date: Fri, 15 Sep 2023 18:05:31 -0400 Subject: [PATCH 41/47] [Driver] Fix flang driver preprocessor issue The -save-temps option has been causing the driver to run flang1/flang2 on the input file twice, and the fortran-preprocessor.f90 test was unable to detect the error, because it had used -c instead of -x in a couple of RUN commands. This patch fixes the test and the driver to make sure that the frontend is not invoked multiple times with -save-temps. --- clang/lib/Driver/Driver.cpp | 9 +++++++++ clang/lib/Driver/ToolChains/ClassicFlang.h | 2 +- clang/test/Driver/fortran-preprocessor.f90 | 15 ++++++++------- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 1b27782c2f14..8bfee5928fe5 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -5258,8 +5258,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; diff --git a/clang/lib/Driver/ToolChains/ClassicFlang.h b/clang/lib/Driver/ToolChains/ClassicFlang.h index 5af119c2f79e..cc9d7c3c22f7 100644 --- a/clang/lib/Driver/ToolChains/ClassicFlang.h +++ b/clang/lib/Driver/ToolChains/ClassicFlang.h @@ -28,7 +28,7 @@ namespace tools { class LLVM_LIBRARY_VISIBILITY ClassicFlang : public Tool { public: ClassicFlang(const ToolChain &TC) - : Tool("flang:frontend", + : Tool("classic-flang", "Fortran frontend to LLVM", TC) {} bool hasGoodDiagnostics() const override { return true; } diff --git a/clang/test/Driver/fortran-preprocessor.f90 b/clang/test/Driver/fortran-preprocessor.f90 index 99f4186ba83c..d9e5620145ac 100644 --- a/clang/test/Driver/fortran-preprocessor.f90 +++ b/clang/test/Driver/fortran-preprocessor.f90 @@ -2,7 +2,7 @@ ! -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" -### -c f95-cpp-input %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 @@ -17,9 +17,9 @@ ! 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 -### -c 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 -! RUN: %flang -cpp -c -DHELLO="hello all" -save-temps -### -c f95-cpp-input %s 2>&1 | FileCheck %s --check-prefixes=ALL,CPP +! 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 @@ -31,13 +31,14 @@ ! E-DAG: "-es" ! E-DAG: "-preprocess" -! flang1 should only be called once! -! ALL-NOT: "{{.*}}flang1" - ! 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" -- Gitee From 5339c8c17bb1939bb6660a32a944923db463c045 Mon Sep 17 00:00:00 2001 From: Bryan Chan Date: Wed, 4 Oct 2023 22:36:16 -0400 Subject: [PATCH 42/47] [ClassicFlang] Update LLVM version number passed to the frontend --- clang/lib/Driver/ToolChains/ClassicFlang.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/Driver/ToolChains/ClassicFlang.cpp b/clang/lib/Driver/ToolChains/ClassicFlang.cpp index 89844c66db49..c08ca351770a 100644 --- a/clang/lib/Driver/ToolChains/ClassicFlang.cpp +++ b/clang/lib/Driver/ToolChains/ClassicFlang.cpp @@ -1021,7 +1021,7 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, 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("150"); // LLVM version + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("249"); LowerCmdArgs.push_back("170"); // 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"); -- Gitee From d34ce46ebfbf233db34890c26b37ee5c54170aa2 Mon Sep 17 00:00:00 2001 From: Bryan Chan Date: Wed, 4 Oct 2023 20:50:59 -0400 Subject: [PATCH 43/47] [ClassicFlang] Adapt header include paths Some header files have been moved to new directories in LLVM 17. StringExtras.h is no longer included transitively since D155178, and now needs to be included explicitly by clang/Frontend/Utils.h. --- clang/include/clang/Frontend/Utils.h | 1 + clang/lib/Driver/ToolChains/ClassicFlang.cpp | 2 +- clang/lib/Driver/ToolChains/ClassicFlang.h | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/clang/include/clang/Frontend/Utils.h b/clang/include/clang/Frontend/Utils.h index f9a7e25c0049..c51c617c1379 100644 --- a/clang/include/clang/Frontend/Utils.h +++ b/clang/include/clang/Frontend/Utils.h @@ -20,6 +20,7 @@ #include "clang/Basic/TargetInfo.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" diff --git a/clang/lib/Driver/ToolChains/ClassicFlang.cpp b/clang/lib/Driver/ToolChains/ClassicFlang.cpp index c08ca351770a..b8be0be20b07 100644 --- a/clang/lib/Driver/ToolChains/ClassicFlang.cpp +++ b/clang/lib/Driver/ToolChains/ClassicFlang.cpp @@ -31,8 +31,8 @@ #include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" #include "llvm/Support/Process.h" -#include "llvm/Support/TargetParser.h" #include "llvm/Support/YAMLParser.h" +#include "llvm/TargetParser/TargetParser.h" #ifdef LLVM_ON_UNIX #include // For getuid(). diff --git a/clang/lib/Driver/ToolChains/ClassicFlang.h b/clang/lib/Driver/ToolChains/ClassicFlang.h index cc9d7c3c22f7..5864e0776601 100644 --- a/clang/lib/Driver/ToolChains/ClassicFlang.h +++ b/clang/lib/Driver/ToolChains/ClassicFlang.h @@ -11,13 +11,13 @@ #define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ClassicFlang_H #include "MSVC.h" -#include "clang/Basic/DebugInfoOptions.h" #include "clang/Driver/Driver.h" #include "clang/Driver/Tool.h" #include "clang/Driver/Types.h" -#include "llvm/ADT/Triple.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 { -- Gitee From 844ede7a6f90c00c3342eb9d2a1cf17ffe0ab51d Mon Sep 17 00:00:00 2001 From: Bryan Chan Date: Wed, 4 Oct 2023 21:37:56 -0400 Subject: [PATCH 44/47] [Driver] Update test to not expect -rpath for -lomp Upstream commit 555b572e3f40 had reverted D118493, which let Clang add a toolchain-specific -rpath option to the linker command for the OpenMP library. This patch fixes up a Classic Flang driver test which is impacted by the revert. --- clang/test/Driver/flang/classic-flang.f95 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/test/Driver/flang/classic-flang.f95 b/clang/test/Driver/flang/classic-flang.f95 index ceb57b7d116e..6a1610d12e93 100644 --- a/clang/test/Driver/flang/classic-flang.f95 +++ b/clang/test/Driver/flang/classic-flang.f95 @@ -67,9 +67,9 @@ ! 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" "-rpath" "{{[^ ]*[/\\]+}}basic_linux_tree{{[/\\]+}}usr{{[/\\]+}}lib" +! CHECK-DYNAMIC-OMP: "-lomp" "-L{{[^ ]*[/\\]+}}basic_linux_tree{{[/\\]+}}usr{{[/\\]+}}lib" ! CHECK-DYNAMIC-OMP-NOT: "-Bdynamic" -! CHECK-STATIC-OMP: "-Bstatic" "-lomp" "-Bdynamic" "-rpath" "{{[^ ]*[/\\]+}}basic_linux_tree{{[/\\]+}}usr{{[/\\]+}}lib" +! 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 \ -- Gitee From 5acb48f209a79c7ac3fbdb0cea1f727b1d48342a Mon Sep 17 00:00:00 2001 From: Bryan Chan Date: Wed, 4 Oct 2023 21:43:59 -0400 Subject: [PATCH 45/47] [VecLib] Update test case to match new vectorizer behaviour The IR in clang/test/CodeGen/libpgmath-logfun-aarch64.ll can now be vectorized by a factor of two. The IR still does not call the unsupported libpgmath functions, as per the intention of the test. --- clang/test/CodeGen/libpgmath-logfun-aarch64.ll | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/clang/test/CodeGen/libpgmath-logfun-aarch64.ll b/clang/test/CodeGen/libpgmath-logfun-aarch64.ll index 045d14fdf407..141fed29ccd1 100644 --- a/clang/test/CodeGen/libpgmath-logfun-aarch64.ll +++ b/clang/test/CodeGen/libpgmath-logfun-aarch64.ll @@ -45,10 +45,8 @@ L.entry: ret void ; CHECK-NOT: __pd_log_4 -; CHECK: __pd_log_1 -; CHECK: __pd_log_1 -; CHECK: __pd_log_1 -; CHECK: __pd_log_1 +; CHECK: __pd_log_2 +; CHECK: __pd_log_2 } ; Function Attrs: nounwind readnone willreturn -- Gitee From dc39d7997feef07ff3afeda256fb53c6cf836182 Mon Sep 17 00:00:00 2001 From: Bryan Chan Date: Sat, 21 Oct 2023 12:49:13 -0400 Subject: [PATCH 46/47] [Driver] Handle -Mnomain and -fno-fortran-main correctly -Mnomain and -fno-fortran-main were ineffective unless they were both used at the same time. This patch fixes the bug, formats needFortranMain and needFortranLibs, and adds some test cases for the logic. --- clang/lib/Driver/ToolChains/CommonArgs.cpp | 13 ++---- clang/test/Driver/flang/classic-flang.f95 | 49 ++++++++++++++++++---- 2 files changed, 44 insertions(+), 18 deletions(-) diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index 5db0dbb8e351..1ccc83a468ce 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -149,19 +149,14 @@ static bool shouldIgnoreUnsupportedTargetFeature(const Arg &TargetFeatureArg, #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))); + 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) { - if (D.IsFlangMode() && !Args.hasArg(options::OPT_nostdlib) && - !Args.hasArg(options::OPT_noFlangLibs)) { - return true; - } - - return false; + return (D.IsFlangMode() && !Args.hasArg(options::OPT_nostdlib) && + !Args.hasArg(options::OPT_noFlangLibs)); } #endif diff --git a/clang/test/Driver/flang/classic-flang.f95 b/clang/test/Driver/flang/classic-flang.f95 index 6a1610d12e93..3350bd45550f 100644 --- a/clang/test/Driver/flang/classic-flang.f95 +++ b/clang/test/Driver/flang/classic-flang.f95 @@ -45,23 +45,29 @@ ! 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-DYNAMIC-FLANG,CHECK-DYNAMIC-OMP %s +! 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-DYNAMIC-FLANG,CHECK-NO-OMP %s +! 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-DYNAMIC-FLANG,CHECK-DYNAMIC-OMP %s +! 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-DYNAMIC-FLANG,CHECK-NO-OMP %s +! 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-DYNAMIC-FLANG,CHECK-STATIC-OMP %s +! 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-STATIC-FLANG,CHECK-DYNAMIC-OMP %s +! 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-STATIC-FLANG,CHECK-NO-OMP %s - +! 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: "{{[^"]*}}classic-flang-{{[^ ]*}}.o" "-lflangmain" "-lfoo" "-L{{[^ ]*[/\\]+}}basic_linux_tree{{[/\\]+}}usr{{[/\\]+}}lib" +! 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" @@ -87,3 +93,28 @@ ! 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" "-L{{[^ ]*[/\\]+}}basic_linux_tree{{[/\\]+}}usr{{[/\\]+}}lib" +! CHECK-NOSTDLIB-NOT: "-lflang" "-lflangrti" "-lpgmath" +! CHECK-NOSTDLIB-NOT: "-lpthread" "-lrt" +! CHECK-NOSTDLIB: "-lm" +! CHECK-NOSTDLIB-NOT: "-lgcc" +! CHECK-NOSTDLIB-NOT: "-lgcc_s" +! CHECK-NOSTDLIB-NOT: "-lc" -- Gitee From aa04ae5ed5e3b2fa8c9131da1cf5c575ca3711b1 Mon Sep 17 00:00:00 2001 From: Bryan Chan Date: Wed, 3 Jan 2024 13:46:57 -0500 Subject: [PATCH 47/47] [OpenMP] Exclude affinity tests that fail on GitHub runners --- openmp/runtime/test/affinity/kmp-affinity.c | 5 +++++ openmp/runtime/test/affinity/omp-places.c | 5 +++++ 2 files changed, 10 insertions(+) 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 -- Gitee