Merge ^/vendor/llvm-project/release-10.x up to its last change (upstream
commit llvmorg-10.0.0-rc2-70-ge5cb70267e7), and bump versions.
This commit is contained in:
commit
4739579419
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/projects/clang1000-import/; revision=358399
@ -13,7 +13,7 @@ def note_expr_divide_by_zero : Note<"division by zero">;
|
|||||||
def note_constexpr_invalid_cast : Note<
|
def note_constexpr_invalid_cast : Note<
|
||||||
"%select{reinterpret_cast|dynamic_cast|cast that performs the conversions of"
|
"%select{reinterpret_cast|dynamic_cast|cast that performs the conversions of"
|
||||||
" a reinterpret_cast|cast from %1}0 is not allowed in a constant expression"
|
" a reinterpret_cast|cast from %1}0 is not allowed in a constant expression"
|
||||||
"%select{| in C++ standards before C++2a||}0">;
|
"%select{| in C++ standards before C++20||}0">;
|
||||||
def note_constexpr_invalid_downcast : Note<
|
def note_constexpr_invalid_downcast : Note<
|
||||||
"cannot cast object of dynamic type %0 to type %1">;
|
"cannot cast object of dynamic type %0 to type %1">;
|
||||||
def note_constexpr_overflow : Note<
|
def note_constexpr_overflow : Note<
|
||||||
@ -33,7 +33,7 @@ def note_constexpr_no_return : Note<
|
|||||||
"control reached end of constexpr function">;
|
"control reached end of constexpr function">;
|
||||||
def note_constexpr_virtual_call : Note<
|
def note_constexpr_virtual_call : Note<
|
||||||
"cannot evaluate call to virtual function in a constant expression "
|
"cannot evaluate call to virtual function in a constant expression "
|
||||||
"in C++ standards before C++2a">;
|
"in C++ standards before C++20">;
|
||||||
def note_constexpr_pure_virtual_call : Note<
|
def note_constexpr_pure_virtual_call : Note<
|
||||||
"pure virtual function %q0 called">;
|
"pure virtual function %q0 called">;
|
||||||
def note_constexpr_polymorphic_unknown_dynamic_type : Note<
|
def note_constexpr_polymorphic_unknown_dynamic_type : Note<
|
||||||
@ -102,7 +102,7 @@ def note_constexpr_var_init_non_constant : Note<
|
|||||||
"initializer of %0 is not a constant expression">;
|
"initializer of %0 is not a constant expression">;
|
||||||
def note_constexpr_typeid_polymorphic : Note<
|
def note_constexpr_typeid_polymorphic : Note<
|
||||||
"typeid applied to expression of polymorphic type %0 is "
|
"typeid applied to expression of polymorphic type %0 is "
|
||||||
"not allowed in a constant expression in C++ standards before C++2a">;
|
"not allowed in a constant expression in C++ standards before C++20">;
|
||||||
def note_constexpr_void_comparison : Note<
|
def note_constexpr_void_comparison : Note<
|
||||||
"comparison between unequal pointers to void has unspecified result">;
|
"comparison between unequal pointers to void has unspecified result">;
|
||||||
def note_constexpr_temporary_here : Note<"temporary created here">;
|
def note_constexpr_temporary_here : Note<"temporary created here">;
|
||||||
|
@ -120,7 +120,7 @@ def err_enum_template : Error<"enumeration cannot be a template">;
|
|||||||
|
|
||||||
def warn_cxx20_compat_consteval : Warning<
|
def warn_cxx20_compat_consteval : Warning<
|
||||||
"'consteval' specifier is incompatible with C++ standards before C++20">,
|
"'consteval' specifier is incompatible with C++ standards before C++20">,
|
||||||
InGroup<CXX2aCompat>, DefaultIgnore;
|
InGroup<CXX20Compat>, DefaultIgnore;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -271,6 +271,9 @@ def warn_drv_unsupported_debug_info_opt_for_target : Warning<
|
|||||||
InGroup<UnsupportedTargetOpt>;
|
InGroup<UnsupportedTargetOpt>;
|
||||||
def warn_c_kext : Warning<
|
def warn_c_kext : Warning<
|
||||||
"ignoring -fapple-kext which is valid for C++ and Objective-C++ only">;
|
"ignoring -fapple-kext which is valid for C++ and Objective-C++ only">;
|
||||||
|
def warn_ignoring_fdiscard_for_bitcode : Warning<
|
||||||
|
"ignoring -fdiscard-value-names for LLVM Bitcode">,
|
||||||
|
InGroup<UnusedCommandLineArgument>;
|
||||||
def warn_drv_input_file_unused : Warning<
|
def warn_drv_input_file_unused : Warning<
|
||||||
"%0: '%1' input unused%select{ when '%3' is present|}2">,
|
"%0: '%1' input unused%select{ when '%3' is present|}2">,
|
||||||
InGroup<UnusedCommandLineArgument>;
|
InGroup<UnusedCommandLineArgument>;
|
||||||
|
@ -106,7 +106,7 @@ def err_fe_invalid_wchar_type
|
|||||||
def err_fe_invalid_exception_model
|
def err_fe_invalid_exception_model
|
||||||
: Error<"invalid exception model '%0' for target '%1'">;
|
: Error<"invalid exception model '%0' for target '%1'">;
|
||||||
def warn_fe_concepts_ts_flag : Warning<
|
def warn_fe_concepts_ts_flag : Warning<
|
||||||
"-fconcepts-ts is deprecated - use '-std=c++2a' for Concepts support">,
|
"-fconcepts-ts is deprecated - use '-std=c++20' for Concepts support">,
|
||||||
InGroup<Deprecated>;
|
InGroup<Deprecated>;
|
||||||
|
|
||||||
def warn_fe_serialized_diag_merge_failure : Warning<
|
def warn_fe_serialized_diag_merge_failure : Warning<
|
||||||
@ -175,9 +175,9 @@ def note_incompatible_analyzer_plugin_api : Note<
|
|||||||
def err_module_build_requires_fmodules : Error<
|
def err_module_build_requires_fmodules : Error<
|
||||||
"module compilation requires '-fmodules'">;
|
"module compilation requires '-fmodules'">;
|
||||||
def err_module_interface_requires_cpp_modules : Error<
|
def err_module_interface_requires_cpp_modules : Error<
|
||||||
"module interface compilation requires '-std=c++2a' or '-fmodules-ts'">;
|
"module interface compilation requires '-std=c++20' or '-fmodules-ts'">;
|
||||||
def err_header_module_requires_modules : Error<
|
def err_header_module_requires_modules : Error<
|
||||||
"header module compilation requires '-fmodules', '-std=c++2a', or "
|
"header module compilation requires '-fmodules', '-std=c++20', or "
|
||||||
"'-fmodules-ts'">;
|
"'-fmodules-ts'">;
|
||||||
def warn_module_config_mismatch : Warning<
|
def warn_module_config_mismatch : Warning<
|
||||||
"module file %0 cannot be loaded due to a configuration mismatch with the current "
|
"module file %0 cannot be loaded due to a configuration mismatch with the current "
|
||||||
|
@ -187,10 +187,10 @@ def Deprecated : DiagGroup<"deprecated", [DeprecatedAnonEnumEnumConversion,
|
|||||||
DeprecatedWritableStr]>,
|
DeprecatedWritableStr]>,
|
||||||
DiagCategory<"Deprecations">;
|
DiagCategory<"Deprecations">;
|
||||||
|
|
||||||
def CXX2aDesignator : DiagGroup<"c++2a-designator">;
|
def CXX20Designator : DiagGroup<"c++20-designator">;
|
||||||
// Allow -Wno-c99-designator to be used to turn off all warnings on valid C99
|
// Allow -Wno-c99-designator to be used to turn off all warnings on valid C99
|
||||||
// designators (including the warning controlled by -Wc++2a-designator).
|
// designators (including the warning controlled by -Wc++20-designator).
|
||||||
def C99Designator : DiagGroup<"c99-designator", [CXX2aDesignator]>;
|
def C99Designator : DiagGroup<"c99-designator", [CXX20Designator]>;
|
||||||
def GNUDesignator : DiagGroup<"gnu-designator">;
|
def GNUDesignator : DiagGroup<"gnu-designator">;
|
||||||
|
|
||||||
def DynamicExceptionSpec
|
def DynamicExceptionSpec
|
||||||
@ -246,9 +246,9 @@ def CXXPre14CompatPedantic : DiagGroup<"c++98-c++11-compat-pedantic",
|
|||||||
def CXXPre17Compat : DiagGroup<"c++98-c++11-c++14-compat">;
|
def CXXPre17Compat : DiagGroup<"c++98-c++11-c++14-compat">;
|
||||||
def CXXPre17CompatPedantic : DiagGroup<"c++98-c++11-c++14-compat-pedantic",
|
def CXXPre17CompatPedantic : DiagGroup<"c++98-c++11-c++14-compat-pedantic",
|
||||||
[CXXPre17Compat]>;
|
[CXXPre17Compat]>;
|
||||||
def CXXPre2aCompat : DiagGroup<"c++98-c++11-c++14-c++17-compat">;
|
def CXXPre20Compat : DiagGroup<"c++98-c++11-c++14-c++17-compat">;
|
||||||
def CXXPre2aCompatPedantic : DiagGroup<"c++98-c++11-c++14-c++17-compat-pedantic",
|
def CXXPre20CompatPedantic : DiagGroup<"c++98-c++11-c++14-c++17-compat-pedantic",
|
||||||
[CXXPre2aCompat]>;
|
[CXXPre20Compat]>;
|
||||||
|
|
||||||
def CXX98CompatBindToTemporaryCopy :
|
def CXX98CompatBindToTemporaryCopy :
|
||||||
DiagGroup<"c++98-compat-bind-to-temporary-copy">;
|
DiagGroup<"c++98-compat-bind-to-temporary-copy">;
|
||||||
@ -262,7 +262,7 @@ def CXX98Compat : DiagGroup<"c++98-compat",
|
|||||||
CXX98CompatUnnamedTypeTemplateArgs,
|
CXX98CompatUnnamedTypeTemplateArgs,
|
||||||
CXXPre14Compat,
|
CXXPre14Compat,
|
||||||
CXXPre17Compat,
|
CXXPre17Compat,
|
||||||
CXXPre2aCompat]>;
|
CXXPre20Compat]>;
|
||||||
// Warnings for C++11 features which are Extensions in C++98 mode.
|
// Warnings for C++11 features which are Extensions in C++98 mode.
|
||||||
def CXX98CompatPedantic : DiagGroup<"c++98-compat-pedantic",
|
def CXX98CompatPedantic : DiagGroup<"c++98-compat-pedantic",
|
||||||
[CXX98Compat,
|
[CXX98Compat,
|
||||||
@ -270,7 +270,7 @@ def CXX98CompatPedantic : DiagGroup<"c++98-compat-pedantic",
|
|||||||
CXX98CompatExtraSemi,
|
CXX98CompatExtraSemi,
|
||||||
CXXPre14CompatPedantic,
|
CXXPre14CompatPedantic,
|
||||||
CXXPre17CompatPedantic,
|
CXXPre17CompatPedantic,
|
||||||
CXXPre2aCompatPedantic]>;
|
CXXPre20CompatPedantic]>;
|
||||||
|
|
||||||
def CXX11Narrowing : DiagGroup<"c++11-narrowing">;
|
def CXX11Narrowing : DiagGroup<"c++11-narrowing">;
|
||||||
|
|
||||||
@ -296,33 +296,35 @@ def CXX11Compat : DiagGroup<"c++11-compat",
|
|||||||
CXX11CompatDeprecatedWritableStr,
|
CXX11CompatDeprecatedWritableStr,
|
||||||
CXXPre14Compat,
|
CXXPre14Compat,
|
||||||
CXXPre17Compat,
|
CXXPre17Compat,
|
||||||
CXXPre2aCompat]>;
|
CXXPre20Compat]>;
|
||||||
def : DiagGroup<"c++0x-compat", [CXX11Compat]>;
|
def : DiagGroup<"c++0x-compat", [CXX11Compat]>;
|
||||||
def CXX11CompatPedantic : DiagGroup<"c++11-compat-pedantic",
|
def CXX11CompatPedantic : DiagGroup<"c++11-compat-pedantic",
|
||||||
[CXX11Compat,
|
[CXX11Compat,
|
||||||
CXXPre14CompatPedantic,
|
CXXPre14CompatPedantic,
|
||||||
CXXPre17CompatPedantic,
|
CXXPre17CompatPedantic,
|
||||||
CXXPre2aCompatPedantic]>;
|
CXXPre20CompatPedantic]>;
|
||||||
|
|
||||||
def CXX14Compat : DiagGroup<"c++14-compat", [CXXPre17Compat,
|
def CXX14Compat : DiagGroup<"c++14-compat", [CXXPre17Compat,
|
||||||
CXXPre2aCompat]>;
|
CXXPre20Compat]>;
|
||||||
def CXX14CompatPedantic : DiagGroup<"c++14-compat-pedantic",
|
def CXX14CompatPedantic : DiagGroup<"c++14-compat-pedantic",
|
||||||
[CXX14Compat,
|
[CXX14Compat,
|
||||||
CXXPre17CompatPedantic,
|
CXXPre17CompatPedantic,
|
||||||
CXXPre2aCompatPedantic]>;
|
CXXPre20CompatPedantic]>;
|
||||||
|
|
||||||
def CXX17Compat : DiagGroup<"c++17-compat", [DeprecatedRegister,
|
def CXX17Compat : DiagGroup<"c++17-compat", [DeprecatedRegister,
|
||||||
DeprecatedIncrementBool,
|
DeprecatedIncrementBool,
|
||||||
CXX17CompatMangling,
|
CXX17CompatMangling,
|
||||||
CXXPre2aCompat]>;
|
CXXPre20Compat]>;
|
||||||
def CXX17CompatPedantic : DiagGroup<"c++17-compat-pedantic",
|
def CXX17CompatPedantic : DiagGroup<"c++17-compat-pedantic",
|
||||||
[CXX17Compat,
|
[CXX17Compat,
|
||||||
CXXPre2aCompatPedantic]>;
|
CXXPre20CompatPedantic]>;
|
||||||
def : DiagGroup<"c++1z-compat", [CXX17Compat]>;
|
def : DiagGroup<"c++1z-compat", [CXX17Compat]>;
|
||||||
|
|
||||||
def CXX2aCompat : DiagGroup<"c++2a-compat">;
|
def CXX20Compat : DiagGroup<"c++20-compat">;
|
||||||
def CXX2aCompatPedantic : DiagGroup<"c++2a-compat-pedantic",
|
def CXX20CompatPedantic : DiagGroup<"c++20-compat-pedantic",
|
||||||
[CXX2aCompat]>;
|
[CXX20Compat]>;
|
||||||
|
def : DiagGroup<"c++2a-compat", [CXX20Compat]>;
|
||||||
|
def : DiagGroup<"c++2a-compat-pedantic", [CXX20CompatPedantic]>;
|
||||||
|
|
||||||
def ExitTimeDestructors : DiagGroup<"exit-time-destructors">;
|
def ExitTimeDestructors : DiagGroup<"exit-time-destructors">;
|
||||||
def FlexibleArrayExtensions : DiagGroup<"flexible-array-extensions">;
|
def FlexibleArrayExtensions : DiagGroup<"flexible-array-extensions">;
|
||||||
@ -955,13 +957,14 @@ def CXX14 : DiagGroup<"c++14-extensions", [CXX14BinaryLiteral]>;
|
|||||||
// earlier C++ versions.
|
// earlier C++ versions.
|
||||||
def CXX17 : DiagGroup<"c++17-extensions">;
|
def CXX17 : DiagGroup<"c++17-extensions">;
|
||||||
|
|
||||||
// A warning group for warnings about using C++2a features as extensions in
|
// A warning group for warnings about using C++20 features as extensions in
|
||||||
// earlier C++ versions.
|
// earlier C++ versions.
|
||||||
def CXX2a : DiagGroup<"c++2a-extensions", [CXX2aDesignator]>;
|
def CXX20 : DiagGroup<"c++20-extensions", [CXX20Designator]>;
|
||||||
|
|
||||||
def : DiagGroup<"c++0x-extensions", [CXX11]>;
|
def : DiagGroup<"c++0x-extensions", [CXX11]>;
|
||||||
def : DiagGroup<"c++1y-extensions", [CXX14]>;
|
def : DiagGroup<"c++1y-extensions", [CXX14]>;
|
||||||
def : DiagGroup<"c++1z-extensions", [CXX17]>;
|
def : DiagGroup<"c++1z-extensions", [CXX17]>;
|
||||||
|
def : DiagGroup<"c++2a-extensions", [CXX20]>;
|
||||||
|
|
||||||
def DelegatingCtorCycles :
|
def DelegatingCtorCycles :
|
||||||
DiagGroup<"delegating-ctor-cycles">;
|
DiagGroup<"delegating-ctor-cycles">;
|
||||||
@ -1011,7 +1014,8 @@ def MicrosoftExplicitConstructorCall : DiagGroup<
|
|||||||
def MicrosoftEnumValue : DiagGroup<"microsoft-enum-value">;
|
def MicrosoftEnumValue : DiagGroup<"microsoft-enum-value">;
|
||||||
def MicrosoftDefaultArgRedefinition :
|
def MicrosoftDefaultArgRedefinition :
|
||||||
DiagGroup<"microsoft-default-arg-redefinition">;
|
DiagGroup<"microsoft-default-arg-redefinition">;
|
||||||
def MicrosoftTemplate : DiagGroup<"microsoft-template">;
|
def MicrosoftTemplateShadow : DiagGroup<"microsoft-template-shadow">;
|
||||||
|
def MicrosoftTemplate : DiagGroup<"microsoft-template", [MicrosoftTemplateShadow]>;
|
||||||
def MicrosoftInconsistentDllImport : DiagGroup<"inconsistent-dllimport">;
|
def MicrosoftInconsistentDllImport : DiagGroup<"inconsistent-dllimport">;
|
||||||
def MicrosoftRedeclareStatic : DiagGroup<"microsoft-redeclare-static">;
|
def MicrosoftRedeclareStatic : DiagGroup<"microsoft-redeclare-static">;
|
||||||
def MicrosoftEnumForwardReference :
|
def MicrosoftEnumForwardReference :
|
||||||
|
@ -31,12 +31,12 @@ def warn_cxx98_compat_less_colon_colon : Warning<
|
|||||||
InGroup<CXX98Compat>, DefaultIgnore;
|
InGroup<CXX98Compat>, DefaultIgnore;
|
||||||
|
|
||||||
def warn_cxx17_compat_spaceship : Warning<
|
def warn_cxx17_compat_spaceship : Warning<
|
||||||
"'<=>' operator is incompatible with C++ standards before C++2a">,
|
"'<=>' operator is incompatible with C++ standards before C++20">,
|
||||||
InGroup<CXXPre2aCompat>, DefaultIgnore;
|
InGroup<CXXPre20Compat>, DefaultIgnore;
|
||||||
def warn_cxx2a_compat_spaceship : Warning<
|
def warn_cxx2a_compat_spaceship : Warning<
|
||||||
"'<=>' is a single token in C++2a; "
|
"'<=>' is a single token in C++20; "
|
||||||
"add a space to avoid a change in behavior">,
|
"add a space to avoid a change in behavior">,
|
||||||
InGroup<CXX2aCompat>;
|
InGroup<CXX20Compat>;
|
||||||
|
|
||||||
// Trigraphs.
|
// Trigraphs.
|
||||||
def trigraph_ignored : Warning<"trigraph ignored">, InGroup<Trigraphs>;
|
def trigraph_ignored : Warning<"trigraph ignored">, InGroup<Trigraphs>;
|
||||||
@ -78,8 +78,8 @@ def ext_token_used : Extension<"extension used">,
|
|||||||
|
|
||||||
def warn_cxx11_keyword : Warning<"'%0' is a keyword in C++11">,
|
def warn_cxx11_keyword : Warning<"'%0' is a keyword in C++11">,
|
||||||
InGroup<CXX11Compat>, DefaultIgnore;
|
InGroup<CXX11Compat>, DefaultIgnore;
|
||||||
def warn_cxx2a_keyword : Warning<"'%0' is a keyword in C++2a">,
|
def warn_cxx2a_keyword : Warning<"'%0' is a keyword in C++20">,
|
||||||
InGroup<CXX2aCompat>, DefaultIgnore;
|
InGroup<CXX20Compat>, DefaultIgnore;
|
||||||
|
|
||||||
def ext_unterminated_char_or_string : ExtWarn<
|
def ext_unterminated_char_or_string : ExtWarn<
|
||||||
"missing terminating %select{'|'\"'}0 character">, InGroup<InvalidPPToken>;
|
"missing terminating %select{'|'\"'}0 character">, InGroup<InvalidPPToken>;
|
||||||
|
@ -241,10 +241,10 @@ def warn_cxx14_compat_nested_namespace_definition : Warning<
|
|||||||
"nested namespace definition is incompatible with C++ standards before C++17">,
|
"nested namespace definition is incompatible with C++ standards before C++17">,
|
||||||
InGroup<CXXPre17Compat>, DefaultIgnore;
|
InGroup<CXXPre17Compat>, DefaultIgnore;
|
||||||
def ext_inline_nested_namespace_definition : ExtWarn<
|
def ext_inline_nested_namespace_definition : ExtWarn<
|
||||||
"inline nested namespace definition is a C++2a extension">, InGroup<CXX2a>;
|
"inline nested namespace definition is a C++20 extension">, InGroup<CXX20>;
|
||||||
def warn_cxx17_compat_inline_nested_namespace_definition : Warning<
|
def warn_cxx17_compat_inline_nested_namespace_definition : Warning<
|
||||||
"inline nested namespace definition is incompatible with C++ standards before"
|
"inline nested namespace definition is incompatible with C++ standards before"
|
||||||
" C++2a">, InGroup<CXXPre2aCompat>, DefaultIgnore;
|
" C++20">, InGroup<CXXPre20Compat>, DefaultIgnore;
|
||||||
def err_inline_nested_namespace_definition : Error<
|
def err_inline_nested_namespace_definition : Error<
|
||||||
"nested namespace definition cannot be 'inline'">;
|
"nested namespace definition cannot be 'inline'">;
|
||||||
def err_expected_semi_after_attribute_list : Error<
|
def err_expected_semi_after_attribute_list : Error<
|
||||||
@ -589,11 +589,11 @@ def warn_cxx14_compat_init_statement : Warning<
|
|||||||
"%select{if|switch}0 initialization statements are incompatible with "
|
"%select{if|switch}0 initialization statements are incompatible with "
|
||||||
"C++ standards before C++17">, DefaultIgnore, InGroup<CXXPre17Compat>;
|
"C++ standards before C++17">, DefaultIgnore, InGroup<CXXPre17Compat>;
|
||||||
def ext_for_range_init_stmt : ExtWarn<
|
def ext_for_range_init_stmt : ExtWarn<
|
||||||
"range-based for loop initialization statements are a C++2a extension">,
|
"range-based for loop initialization statements are a C++20 extension">,
|
||||||
InGroup<CXX2a>;
|
InGroup<CXX20>;
|
||||||
def warn_cxx17_compat_for_range_init_stmt : Warning<
|
def warn_cxx17_compat_for_range_init_stmt : Warning<
|
||||||
"range-based for loop initialization statements are incompatible with "
|
"range-based for loop initialization statements are incompatible with "
|
||||||
"C++ standards before C++2a">, DefaultIgnore, InGroup<CXXPre2aCompat>;
|
"C++ standards before C++20">, DefaultIgnore, InGroup<CXXPre20Compat>;
|
||||||
def warn_empty_init_statement : Warning<
|
def warn_empty_init_statement : Warning<
|
||||||
"empty initialization statement of '%select{if|switch|range-based for}0' "
|
"empty initialization statement of '%select{if|switch|range-based for}0' "
|
||||||
"has no effect">, InGroup<EmptyInitStatement>, DefaultIgnore;
|
"has no effect">, InGroup<EmptyInitStatement>, DefaultIgnore;
|
||||||
@ -681,13 +681,13 @@ def err_ms_property_initializer : Error<
|
|||||||
"property declaration cannot have an in-class initializer">;
|
"property declaration cannot have an in-class initializer">;
|
||||||
|
|
||||||
def warn_cxx2a_compat_explicit_bool : Warning<
|
def warn_cxx2a_compat_explicit_bool : Warning<
|
||||||
"this expression will be parsed as explicit(bool) in C++2a">,
|
"this expression will be parsed as explicit(bool) in C++20">,
|
||||||
InGroup<CXX2aCompat>, DefaultIgnore;
|
InGroup<CXX20Compat>, DefaultIgnore;
|
||||||
def warn_cxx17_compat_explicit_bool : Warning<
|
def warn_cxx17_compat_explicit_bool : Warning<
|
||||||
"explicit(bool) is incompatible with C++ standards before C++2a">,
|
"explicit(bool) is incompatible with C++ standards before C++20">,
|
||||||
InGroup<CXXPre2aCompat>, DefaultIgnore;
|
InGroup<CXXPre20Compat>, DefaultIgnore;
|
||||||
def ext_explicit_bool : ExtWarn<"explicit(bool) is a C++2a extension">,
|
def ext_explicit_bool : ExtWarn<"explicit(bool) is a C++20 extension">,
|
||||||
InGroup<CXX2a>;
|
InGroup<CXX20>;
|
||||||
|
|
||||||
/// C++ Templates
|
/// C++ Templates
|
||||||
def err_expected_template : Error<"expected template">;
|
def err_expected_template : Error<"expected template">;
|
||||||
@ -844,11 +844,11 @@ def warn_cxx98_compat_nonstatic_member_init : Warning<
|
|||||||
"in-class initialization of non-static data members is incompatible with C++98">,
|
"in-class initialization of non-static data members is incompatible with C++98">,
|
||||||
InGroup<CXX98Compat>, DefaultIgnore;
|
InGroup<CXX98Compat>, DefaultIgnore;
|
||||||
def ext_bitfield_member_init: ExtWarn<
|
def ext_bitfield_member_init: ExtWarn<
|
||||||
"default member initializer for bit-field is a C++2a extension">,
|
"default member initializer for bit-field is a C++20 extension">,
|
||||||
InGroup<CXX2a>;
|
InGroup<CXX20>;
|
||||||
def warn_cxx17_compat_bitfield_member_init: Warning<
|
def warn_cxx17_compat_bitfield_member_init: Warning<
|
||||||
"default member initializer for bit-field is incompatible with "
|
"default member initializer for bit-field is incompatible with "
|
||||||
"C++ standards before C++2a">, InGroup<CXXPre2aCompat>, DefaultIgnore;
|
"C++ standards before C++20">, InGroup<CXXPre20Compat>, DefaultIgnore;
|
||||||
def err_incomplete_array_member_init: Error<
|
def err_incomplete_array_member_init: Error<
|
||||||
"array bound cannot be deduced from an in-class initializer">;
|
"array bound cannot be deduced from an in-class initializer">;
|
||||||
|
|
||||||
@ -944,13 +944,13 @@ def warn_cxx14_compat_constexpr_on_lambda : Warning<
|
|||||||
def ext_constexpr_on_lambda_cxx17 : ExtWarn<
|
def ext_constexpr_on_lambda_cxx17 : ExtWarn<
|
||||||
"'constexpr' on lambda expressions is a C++17 extension">, InGroup<CXX17>;
|
"'constexpr' on lambda expressions is a C++17 extension">, InGroup<CXX17>;
|
||||||
|
|
||||||
// C++2a template lambdas
|
// C++20 template lambdas
|
||||||
def ext_lambda_template_parameter_list: ExtWarn<
|
def ext_lambda_template_parameter_list: ExtWarn<
|
||||||
"explicit template parameter list for lambdas is a C++2a extension">,
|
"explicit template parameter list for lambdas is a C++20 extension">,
|
||||||
InGroup<CXX2a>;
|
InGroup<CXX20>;
|
||||||
def warn_cxx17_compat_lambda_template_parameter_list: Warning<
|
def warn_cxx17_compat_lambda_template_parameter_list: Warning<
|
||||||
"explicit template parameter list for lambdas is incompatible with "
|
"explicit template parameter list for lambdas is incompatible with "
|
||||||
"C++ standards before C++2a">, InGroup<CXXPre2aCompat>, DefaultIgnore;
|
"C++ standards before C++20">, InGroup<CXXPre20Compat>, DefaultIgnore;
|
||||||
def err_lambda_template_parameter_list_empty : Error<
|
def err_lambda_template_parameter_list_empty : Error<
|
||||||
"lambda template parameter list cannot be empty">;
|
"lambda template parameter list cannot be empty">;
|
||||||
|
|
||||||
@ -1369,7 +1369,7 @@ let CategoryName = "Concepts Issue" in {
|
|||||||
def err_concept_definition_not_identifier : Error<
|
def err_concept_definition_not_identifier : Error<
|
||||||
"name defined in concept definition must be an identifier">;
|
"name defined in concept definition must be an identifier">;
|
||||||
def ext_concept_legacy_bool_keyword : ExtWarn<
|
def ext_concept_legacy_bool_keyword : ExtWarn<
|
||||||
"ISO C++2a does not permit the 'bool' keyword after 'concept'">,
|
"ISO C++20 does not permit the 'bool' keyword after 'concept'">,
|
||||||
InGroup<DiagGroup<"concepts-ts-compat">>;
|
InGroup<DiagGroup<"concepts-ts-compat">>;
|
||||||
def err_placeholder_expected_auto_or_decltype_auto : Error<
|
def err_placeholder_expected_auto_or_decltype_auto : Error<
|
||||||
"expected 'auto' or 'decltype(auto)' after concept name">;
|
"expected 'auto' or 'decltype(auto)' after concept name">;
|
||||||
|
@ -193,10 +193,10 @@ def ext_flexible_array_init : Extension<
|
|||||||
|
|
||||||
// C++20 designated initializers
|
// C++20 designated initializers
|
||||||
def ext_cxx_designated_init : Extension<
|
def ext_cxx_designated_init : Extension<
|
||||||
"designated initializers are a C++20 extension">, InGroup<CXX2aDesignator>;
|
"designated initializers are a C++20 extension">, InGroup<CXX20Designator>;
|
||||||
def warn_cxx17_compat_designated_init : Warning<
|
def warn_cxx17_compat_designated_init : Warning<
|
||||||
"designated initializers are incompatible with C++ standards before C++20">,
|
"designated initializers are incompatible with C++ standards before C++20">,
|
||||||
InGroup<CXXPre2aCompatPedantic>, DefaultIgnore;
|
InGroup<CXXPre20CompatPedantic>, DefaultIgnore;
|
||||||
def ext_designated_init_mixed : ExtWarn<
|
def ext_designated_init_mixed : ExtWarn<
|
||||||
"mixture of designated and non-designated initializers in the same "
|
"mixture of designated and non-designated initializers in the same "
|
||||||
"initializer list is a C99 extension">, InGroup<C99Designator>;
|
"initializer list is a C99 extension">, InGroup<C99Designator>;
|
||||||
@ -444,13 +444,13 @@ def err_decomp_decl_spec : Error<
|
|||||||
"%plural{1:'%1'|:with '%1' specifiers}0">;
|
"%plural{1:'%1'|:with '%1' specifiers}0">;
|
||||||
def ext_decomp_decl_spec : ExtWarn<
|
def ext_decomp_decl_spec : ExtWarn<
|
||||||
"decomposition declaration declared "
|
"decomposition declaration declared "
|
||||||
"%plural{1:'%1'|:with '%1' specifiers}0 is a C++2a extension">,
|
"%plural{1:'%1'|:with '%1' specifiers}0 is a C++20 extension">,
|
||||||
InGroup<CXX2a>;
|
InGroup<CXX20>;
|
||||||
def warn_cxx17_compat_decomp_decl_spec : Warning<
|
def warn_cxx17_compat_decomp_decl_spec : Warning<
|
||||||
"decomposition declaration declared "
|
"decomposition declaration declared "
|
||||||
"%plural{1:'%1'|:with '%1' specifiers}0 "
|
"%plural{1:'%1'|:with '%1' specifiers}0 "
|
||||||
"is incompatible with C++ standards before C++2a">,
|
"is incompatible with C++ standards before C++20">,
|
||||||
InGroup<CXXPre2aCompat>, DefaultIgnore;
|
InGroup<CXXPre20Compat>, DefaultIgnore;
|
||||||
def err_decomp_decl_type : Error<
|
def err_decomp_decl_type : Error<
|
||||||
"decomposition declaration cannot be declared with type %0; "
|
"decomposition declaration cannot be declared with type %0; "
|
||||||
"declared type must be 'auto' or reference to 'auto'">;
|
"declared type must be 'auto' or reference to 'auto'">;
|
||||||
@ -1949,7 +1949,7 @@ def err_init_list_bad_dest_type : Error<
|
|||||||
"list">;
|
"list">;
|
||||||
def warn_cxx2a_compat_aggregate_init_with_ctors : Warning<
|
def warn_cxx2a_compat_aggregate_init_with_ctors : Warning<
|
||||||
"aggregate initialization of type %0 with user-declared constructors "
|
"aggregate initialization of type %0 with user-declared constructors "
|
||||||
"is incompatible with C++2a">, DefaultIgnore, InGroup<CXX2aCompat>;
|
"is incompatible with C++20">, DefaultIgnore, InGroup<CXX20Compat>;
|
||||||
|
|
||||||
def err_reference_bind_to_bitfield : Error<
|
def err_reference_bind_to_bitfield : Error<
|
||||||
"%select{non-const|volatile}0 reference cannot bind to "
|
"%select{non-const|volatile}0 reference cannot bind to "
|
||||||
@ -2438,7 +2438,7 @@ def err_constexpr_redecl_mismatch : Error<
|
|||||||
def err_constexpr_virtual : Error<"virtual function cannot be constexpr">;
|
def err_constexpr_virtual : Error<"virtual function cannot be constexpr">;
|
||||||
def warn_cxx17_compat_constexpr_virtual : Warning<
|
def warn_cxx17_compat_constexpr_virtual : Warning<
|
||||||
"virtual constexpr functions are incompatible with "
|
"virtual constexpr functions are incompatible with "
|
||||||
"C++ standards before C++2a">, InGroup<CXXPre2aCompat>, DefaultIgnore;
|
"C++ standards before C++20">, InGroup<CXXPre20Compat>, DefaultIgnore;
|
||||||
def err_constexpr_virtual_base : Error<
|
def err_constexpr_virtual_base : Error<
|
||||||
"constexpr %select{member function|constructor}0 not allowed in "
|
"constexpr %select{member function|constructor}0 not allowed in "
|
||||||
"%select{struct|interface|class}1 with virtual base "
|
"%select{struct|interface|class}1 with virtual base "
|
||||||
@ -2464,11 +2464,11 @@ def warn_cxx11_compat_constexpr_body_invalid_stmt : Warning<
|
|||||||
InGroup<CXXPre14Compat>, DefaultIgnore;
|
InGroup<CXXPre14Compat>, DefaultIgnore;
|
||||||
def ext_constexpr_body_invalid_stmt_cxx2a : ExtWarn<
|
def ext_constexpr_body_invalid_stmt_cxx2a : ExtWarn<
|
||||||
"use of this statement in a constexpr %select{function|constructor}0 "
|
"use of this statement in a constexpr %select{function|constructor}0 "
|
||||||
"is a C++2a extension">, InGroup<CXX2a>;
|
"is a C++20 extension">, InGroup<CXX20>;
|
||||||
def warn_cxx17_compat_constexpr_body_invalid_stmt : Warning<
|
def warn_cxx17_compat_constexpr_body_invalid_stmt : Warning<
|
||||||
"use of this statement in a constexpr %select{function|constructor}0 "
|
"use of this statement in a constexpr %select{function|constructor}0 "
|
||||||
"is incompatible with C++ standards before C++2a">,
|
"is incompatible with C++ standards before C++20">,
|
||||||
InGroup<CXXPre2aCompat>, DefaultIgnore;
|
InGroup<CXXPre20Compat>, DefaultIgnore;
|
||||||
def ext_constexpr_type_definition : ExtWarn<
|
def ext_constexpr_type_definition : ExtWarn<
|
||||||
"type definition in a constexpr %select{function|constructor}0 "
|
"type definition in a constexpr %select{function|constructor}0 "
|
||||||
"is a C++14 extension">, InGroup<CXX14>;
|
"is a C++14 extension">, InGroup<CXX14>;
|
||||||
@ -2494,11 +2494,11 @@ def err_constexpr_local_var_non_literal_type : Error<
|
|||||||
"%select{function|constructor}0">;
|
"%select{function|constructor}0">;
|
||||||
def ext_constexpr_local_var_no_init : ExtWarn<
|
def ext_constexpr_local_var_no_init : ExtWarn<
|
||||||
"uninitialized variable in a constexpr %select{function|constructor}0 "
|
"uninitialized variable in a constexpr %select{function|constructor}0 "
|
||||||
"is a C++20 extension">, InGroup<CXX2a>;
|
"is a C++20 extension">, InGroup<CXX20>;
|
||||||
def warn_cxx17_compat_constexpr_local_var_no_init : Warning<
|
def warn_cxx17_compat_constexpr_local_var_no_init : Warning<
|
||||||
"uninitialized variable in a constexpr %select{function|constructor}0 "
|
"uninitialized variable in a constexpr %select{function|constructor}0 "
|
||||||
"is incompatible with C++ standards before C++20">,
|
"is incompatible with C++ standards before C++20">,
|
||||||
InGroup<CXXPre2aCompat>, DefaultIgnore;
|
InGroup<CXXPre20Compat>, DefaultIgnore;
|
||||||
def ext_constexpr_function_never_constant_expr : ExtWarn<
|
def ext_constexpr_function_never_constant_expr : ExtWarn<
|
||||||
"constexpr %select{function|constructor}0 never produces a "
|
"constexpr %select{function|constructor}0 never produces a "
|
||||||
"constant expression">, InGroup<DiagGroup<"invalid-constexpr">>, DefaultError;
|
"constant expression">, InGroup<DiagGroup<"invalid-constexpr">>, DefaultError;
|
||||||
@ -2524,29 +2524,29 @@ def warn_cxx11_compat_constexpr_body_multiple_return : Warning<
|
|||||||
def note_constexpr_body_previous_return : Note<
|
def note_constexpr_body_previous_return : Note<
|
||||||
"previous return statement is here">;
|
"previous return statement is here">;
|
||||||
|
|
||||||
// C++2a function try blocks in constexpr
|
// C++20 function try blocks in constexpr
|
||||||
def ext_constexpr_function_try_block_cxx2a : ExtWarn<
|
def ext_constexpr_function_try_block_cxx2a : ExtWarn<
|
||||||
"function try block in constexpr %select{function|constructor}0 is "
|
"function try block in constexpr %select{function|constructor}0 is "
|
||||||
"a C++2a extension">, InGroup<CXX2a>;
|
"a C++20 extension">, InGroup<CXX20>;
|
||||||
def warn_cxx17_compat_constexpr_function_try_block : Warning<
|
def warn_cxx17_compat_constexpr_function_try_block : Warning<
|
||||||
"function try block in constexpr %select{function|constructor}0 is "
|
"function try block in constexpr %select{function|constructor}0 is "
|
||||||
"incompatible with C++ standards before C++2a">,
|
"incompatible with C++ standards before C++20">,
|
||||||
InGroup<CXXPre2aCompat>, DefaultIgnore;
|
InGroup<CXXPre20Compat>, DefaultIgnore;
|
||||||
|
|
||||||
def ext_constexpr_union_ctor_no_init : ExtWarn<
|
def ext_constexpr_union_ctor_no_init : ExtWarn<
|
||||||
"constexpr union constructor that does not initialize any member "
|
"constexpr union constructor that does not initialize any member "
|
||||||
"is a C++20 extension">, InGroup<CXX2a>;
|
"is a C++20 extension">, InGroup<CXX20>;
|
||||||
def warn_cxx17_compat_constexpr_union_ctor_no_init : Warning<
|
def warn_cxx17_compat_constexpr_union_ctor_no_init : Warning<
|
||||||
"constexpr union constructor that does not initialize any member "
|
"constexpr union constructor that does not initialize any member "
|
||||||
"is incompatible with C++ standards before C++20">,
|
"is incompatible with C++ standards before C++20">,
|
||||||
InGroup<CXXPre2aCompat>, DefaultIgnore;
|
InGroup<CXXPre20Compat>, DefaultIgnore;
|
||||||
def ext_constexpr_ctor_missing_init : ExtWarn<
|
def ext_constexpr_ctor_missing_init : ExtWarn<
|
||||||
"constexpr constructor that does not initialize all members "
|
"constexpr constructor that does not initialize all members "
|
||||||
"is a C++20 extension">, InGroup<CXX2a>;
|
"is a C++20 extension">, InGroup<CXX20>;
|
||||||
def warn_cxx17_compat_constexpr_ctor_missing_init : Warning<
|
def warn_cxx17_compat_constexpr_ctor_missing_init : Warning<
|
||||||
"constexpr constructor that does not initialize all members "
|
"constexpr constructor that does not initialize all members "
|
||||||
"is incompatible with C++ standards before C++20">,
|
"is incompatible with C++ standards before C++20">,
|
||||||
InGroup<CXXPre2aCompat>, DefaultIgnore;
|
InGroup<CXXPre20Compat>, DefaultIgnore;
|
||||||
def note_constexpr_ctor_missing_init : Note<
|
def note_constexpr_ctor_missing_init : Note<
|
||||||
"member not initialized by constructor">;
|
"member not initialized by constructor">;
|
||||||
def note_non_literal_no_constexpr_ctors : Note<
|
def note_non_literal_no_constexpr_ctors : Note<
|
||||||
@ -2678,7 +2678,7 @@ def warn_cxx98_compat_unicode_type : Warning<
|
|||||||
InGroup<CXX98Compat>, DefaultIgnore;
|
InGroup<CXX98Compat>, DefaultIgnore;
|
||||||
def warn_cxx17_compat_unicode_type : Warning<
|
def warn_cxx17_compat_unicode_type : Warning<
|
||||||
"'char8_t' type specifier is incompatible with C++ standards before C++20">,
|
"'char8_t' type specifier is incompatible with C++ standards before C++20">,
|
||||||
InGroup<CXXPre2aCompat>, DefaultIgnore;
|
InGroup<CXXPre20Compat>, DefaultIgnore;
|
||||||
|
|
||||||
// __make_integer_seq
|
// __make_integer_seq
|
||||||
def err_integer_sequence_negative_length : Error<
|
def err_integer_sequence_negative_length : Error<
|
||||||
@ -4210,7 +4210,7 @@ def err_ovl_no_viable_literal_operator : Error<
|
|||||||
def err_template_param_shadow : Error<
|
def err_template_param_shadow : Error<
|
||||||
"declaration of %0 shadows template parameter">;
|
"declaration of %0 shadows template parameter">;
|
||||||
def ext_template_param_shadow : ExtWarn<
|
def ext_template_param_shadow : ExtWarn<
|
||||||
err_template_param_shadow.Text>, InGroup<MicrosoftTemplate>;
|
err_template_param_shadow.Text>, InGroup<MicrosoftTemplateShadow>;
|
||||||
def note_template_param_here : Note<"template parameter is declared here">;
|
def note_template_param_here : Note<"template parameter is declared here">;
|
||||||
def warn_template_export_unsupported : Warning<
|
def warn_template_export_unsupported : Warning<
|
||||||
"exported templates are unsupported">;
|
"exported templates are unsupported">;
|
||||||
@ -4289,11 +4289,11 @@ def err_template_tag_noparams : Error<
|
|||||||
def warn_cxx17_compat_adl_only_template_id : Warning<
|
def warn_cxx17_compat_adl_only_template_id : Warning<
|
||||||
"use of function template name with no prior function template "
|
"use of function template name with no prior function template "
|
||||||
"declaration in function call with explicit template arguments "
|
"declaration in function call with explicit template arguments "
|
||||||
"is incompatible with C++ standards before C++2a">,
|
"is incompatible with C++ standards before C++20">,
|
||||||
InGroup<CXXPre2aCompat>, DefaultIgnore;
|
InGroup<CXXPre20Compat>, DefaultIgnore;
|
||||||
def ext_adl_only_template_id : ExtWarn<
|
def ext_adl_only_template_id : ExtWarn<
|
||||||
"use of function template name with no prior declaration in function call "
|
"use of function template name with no prior declaration in function call "
|
||||||
"with explicit template arguments is a C++2a extension">, InGroup<CXX2a>;
|
"with explicit template arguments is a C++20 extension">, InGroup<CXX20>;
|
||||||
|
|
||||||
// C++ Template Argument Lists
|
// C++ Template Argument Lists
|
||||||
def err_template_missing_args : Error<
|
def err_template_missing_args : Error<
|
||||||
@ -4435,12 +4435,12 @@ def err_pointer_to_member_oper_value_classify: Error<
|
|||||||
"pointer-to-member function type %0 can only be called on an "
|
"pointer-to-member function type %0 can only be called on an "
|
||||||
"%select{rvalue|lvalue}1">;
|
"%select{rvalue|lvalue}1">;
|
||||||
def ext_pointer_to_const_ref_member_on_rvalue : Extension<
|
def ext_pointer_to_const_ref_member_on_rvalue : Extension<
|
||||||
"invoking a pointer to a 'const &' member function on an rvalue is a C++2a extension">,
|
"invoking a pointer to a 'const &' member function on an rvalue is a C++20 extension">,
|
||||||
InGroup<CXX2a>, SFINAEFailure;
|
InGroup<CXX20>, SFINAEFailure;
|
||||||
def warn_cxx17_compat_pointer_to_const_ref_member_on_rvalue : Warning<
|
def warn_cxx17_compat_pointer_to_const_ref_member_on_rvalue : Warning<
|
||||||
"invoking a pointer to a 'const &' member function on an rvalue is "
|
"invoking a pointer to a 'const &' member function on an rvalue is "
|
||||||
"incompatible with C++ standards before C++2a">,
|
"incompatible with C++ standards before C++20">,
|
||||||
InGroup<CXXPre2aCompatPedantic>, DefaultIgnore;
|
InGroup<CXXPre20CompatPedantic>, DefaultIgnore;
|
||||||
def ext_ms_deref_template_argument: ExtWarn<
|
def ext_ms_deref_template_argument: ExtWarn<
|
||||||
"non-type template argument containing a dereference operation is a "
|
"non-type template argument containing a dereference operation is a "
|
||||||
"Microsoft extension">, InGroup<MicrosoftTemplate>;
|
"Microsoft extension">, InGroup<MicrosoftTemplate>;
|
||||||
@ -6189,7 +6189,7 @@ def err_array_init_utf8_string_into_char : Error<
|
|||||||
"UTF-8 string literal%select{ is not permitted by '-fchar8_t'|}0">;
|
"UTF-8 string literal%select{ is not permitted by '-fchar8_t'|}0">;
|
||||||
def warn_cxx2a_compat_utf8_string : Warning<
|
def warn_cxx2a_compat_utf8_string : Warning<
|
||||||
"type of UTF-8 string literal will change from array of const char to "
|
"type of UTF-8 string literal will change from array of const char to "
|
||||||
"array of const char8_t in C++2a">, InGroup<CXX2aCompat>, DefaultIgnore;
|
"array of const char8_t in C++20">, InGroup<CXX20Compat>, DefaultIgnore;
|
||||||
def note_cxx2a_compat_utf8_string_remove_u8 : Note<
|
def note_cxx2a_compat_utf8_string_remove_u8 : Note<
|
||||||
"remove 'u8' prefix to avoid a change of behavior; "
|
"remove 'u8' prefix to avoid a change of behavior; "
|
||||||
"Clang encodes unprefixed narrow string literals as UTF-8">;
|
"Clang encodes unprefixed narrow string literals as UTF-8">;
|
||||||
@ -7116,9 +7116,9 @@ let CategoryName = "Lambda Issue" in {
|
|||||||
"cannot deduce type for lambda capture %0 from initializer list">;
|
"cannot deduce type for lambda capture %0 from initializer list">;
|
||||||
def warn_cxx17_compat_init_capture_pack : Warning<
|
def warn_cxx17_compat_init_capture_pack : Warning<
|
||||||
"initialized lambda capture packs are incompatible with C++ standards "
|
"initialized lambda capture packs are incompatible with C++ standards "
|
||||||
"before C++2a">, InGroup<CXXPre2aCompat>, DefaultIgnore;
|
"before C++20">, InGroup<CXXPre20Compat>, DefaultIgnore;
|
||||||
def ext_init_capture_pack : ExtWarn<
|
def ext_init_capture_pack : ExtWarn<
|
||||||
"initialized lambda pack captures are a C++2a extension">, InGroup<CXX2a>;
|
"initialized lambda pack captures are a C++20 extension">, InGroup<CXX20>;
|
||||||
|
|
||||||
// C++14 generic lambdas.
|
// C++14 generic lambdas.
|
||||||
def warn_cxx11_compat_generic_lambda : Warning<
|
def warn_cxx11_compat_generic_lambda : Warning<
|
||||||
@ -7136,23 +7136,23 @@ let CategoryName = "Lambda Issue" in {
|
|||||||
def err_parameter_shadow_capture : Error<
|
def err_parameter_shadow_capture : Error<
|
||||||
"a lambda parameter cannot shadow an explicitly captured entity">;
|
"a lambda parameter cannot shadow an explicitly captured entity">;
|
||||||
|
|
||||||
// C++2a [=, this] captures.
|
// C++20 [=, this] captures.
|
||||||
def warn_cxx17_compat_equals_this_lambda_capture : Warning<
|
def warn_cxx17_compat_equals_this_lambda_capture : Warning<
|
||||||
"explicit capture of 'this' with a capture default of '=' is incompatible "
|
"explicit capture of 'this' with a capture default of '=' is incompatible "
|
||||||
"with C++ standards before C++2a">, InGroup<CXXPre2aCompat>, DefaultIgnore;
|
"with C++ standards before C++20">, InGroup<CXXPre20Compat>, DefaultIgnore;
|
||||||
def ext_equals_this_lambda_capture_cxx2a : ExtWarn<
|
def ext_equals_this_lambda_capture_cxx2a : ExtWarn<
|
||||||
"explicit capture of 'this' with a capture default of '=' "
|
"explicit capture of 'this' with a capture default of '=' "
|
||||||
"is a C++2a extension">, InGroup<CXX2a>;
|
"is a C++20 extension">, InGroup<CXX20>;
|
||||||
def warn_deprecated_this_capture : Warning<
|
def warn_deprecated_this_capture : Warning<
|
||||||
"implicit capture of 'this' with a capture default of '=' is deprecated">,
|
"implicit capture of 'this' with a capture default of '=' is deprecated">,
|
||||||
InGroup<DeprecatedThisCapture>, DefaultIgnore;
|
InGroup<DeprecatedThisCapture>, DefaultIgnore;
|
||||||
def note_deprecated_this_capture : Note<
|
def note_deprecated_this_capture : Note<
|
||||||
"add an explicit capture of 'this' to capture '*this' by reference">;
|
"add an explicit capture of 'this' to capture '*this' by reference">;
|
||||||
|
|
||||||
// C++2a default constructible / assignable lambdas.
|
// C++20 default constructible / assignable lambdas.
|
||||||
def warn_cxx17_compat_lambda_def_ctor_assign : Warning<
|
def warn_cxx17_compat_lambda_def_ctor_assign : Warning<
|
||||||
"%select{default construction|assignment}0 of lambda is incompatible with "
|
"%select{default construction|assignment}0 of lambda is incompatible with "
|
||||||
"C++ standards before C++2a">, InGroup<CXXPre2aCompat>, DefaultIgnore;
|
"C++ standards before C++20">, InGroup<CXXPre20Compat>, DefaultIgnore;
|
||||||
}
|
}
|
||||||
|
|
||||||
def err_return_in_captured_stmt : Error<
|
def err_return_in_captured_stmt : Error<
|
||||||
@ -7853,7 +7853,7 @@ def ext_cxx14_attr : Extension<
|
|||||||
def ext_cxx17_attr : Extension<
|
def ext_cxx17_attr : Extension<
|
||||||
"use of the %0 attribute is a C++17 extension">, InGroup<CXX17>;
|
"use of the %0 attribute is a C++17 extension">, InGroup<CXX17>;
|
||||||
def ext_cxx2a_attr : Extension<
|
def ext_cxx2a_attr : Extension<
|
||||||
"use of the %0 attribute is a C++2a extension">, InGroup<CXX2a>;
|
"use of the %0 attribute is a C++20 extension">, InGroup<CXX20>;
|
||||||
|
|
||||||
def warn_unused_comparison : Warning<
|
def warn_unused_comparison : Warning<
|
||||||
"%select{equality|inequality|relational|three-way}0 comparison result unused">,
|
"%select{equality|inequality|relational|three-way}0 comparison result unused">,
|
||||||
@ -7867,7 +7867,7 @@ def err_incomplete_type_used_in_type_trait_expr : Error<
|
|||||||
// C++20 constinit and require_constant_initialization attribute
|
// C++20 constinit and require_constant_initialization attribute
|
||||||
def warn_cxx20_compat_constinit : Warning<
|
def warn_cxx20_compat_constinit : Warning<
|
||||||
"'constinit' specifier is incompatible with C++ standards before C++20">,
|
"'constinit' specifier is incompatible with C++ standards before C++20">,
|
||||||
InGroup<CXX2aCompat>, DefaultIgnore;
|
InGroup<CXX20Compat>, DefaultIgnore;
|
||||||
def err_constinit_local_variable : Error<
|
def err_constinit_local_variable : Error<
|
||||||
"local variable cannot be declared 'constinit'">;
|
"local variable cannot be declared 'constinit'">;
|
||||||
def err_require_constant_init_failed : Error<
|
def err_require_constant_init_failed : Error<
|
||||||
@ -8322,7 +8322,7 @@ def note_deleted_type_mismatch : Note<
|
|||||||
def warn_cxx17_compat_defaulted_method_type_mismatch : Warning<
|
def warn_cxx17_compat_defaulted_method_type_mismatch : Warning<
|
||||||
"explicitly defaulting this %sub{select_special_member_kind}0 with a type "
|
"explicitly defaulting this %sub{select_special_member_kind}0 with a type "
|
||||||
"different from the implicit type is incompatible with C++ standards before "
|
"different from the implicit type is incompatible with C++ standards before "
|
||||||
"C++2a">, InGroup<CXXPre2aCompat>, DefaultIgnore;
|
"C++20">, InGroup<CXXPre20Compat>, DefaultIgnore;
|
||||||
def warn_vbase_moved_multiple_times : Warning<
|
def warn_vbase_moved_multiple_times : Warning<
|
||||||
"defaulted move assignment operator of %0 will move assign virtual base "
|
"defaulted move assignment operator of %0 will move assign virtual base "
|
||||||
"class %1 multiple times">, InGroup<DiagGroup<"multiple-move-vbase">>;
|
"class %1 multiple times">, InGroup<DiagGroup<"multiple-move-vbase">>;
|
||||||
@ -8336,10 +8336,10 @@ def select_defaulted_comparison_kind : TextSubstitution<
|
|||||||
"%select{<ERROR>|equality|three-way|equality|relational}0 comparison "
|
"%select{<ERROR>|equality|three-way|equality|relational}0 comparison "
|
||||||
"operator">;
|
"operator">;
|
||||||
def ext_defaulted_comparison : ExtWarn<
|
def ext_defaulted_comparison : ExtWarn<
|
||||||
"defaulted comparison operators are a C++20 extension">, InGroup<CXX2a>;
|
"defaulted comparison operators are a C++20 extension">, InGroup<CXX20>;
|
||||||
def warn_cxx17_compat_defaulted_comparison : Warning<
|
def warn_cxx17_compat_defaulted_comparison : Warning<
|
||||||
"defaulted comparison operators are incompatible with C++ standards "
|
"defaulted comparison operators are incompatible with C++ standards "
|
||||||
"before C++20">, InGroup<CXXPre2aCompat>, DefaultIgnore;
|
"before C++20">, InGroup<CXXPre20Compat>, DefaultIgnore;
|
||||||
def err_defaulted_comparison_template : Error<
|
def err_defaulted_comparison_template : Error<
|
||||||
"comparison operator template cannot be defaulted">;
|
"comparison operator template cannot be defaulted">;
|
||||||
def err_defaulted_comparison_out_of_class : Error<
|
def err_defaulted_comparison_out_of_class : Error<
|
||||||
|
@ -140,15 +140,17 @@ LANGSTANDARD(gnucxx17, "gnu++17",
|
|||||||
Digraphs | HexFloat | GNUMode)
|
Digraphs | HexFloat | GNUMode)
|
||||||
LANGSTANDARD_ALIAS_DEPR(gnucxx17, "gnu++1z")
|
LANGSTANDARD_ALIAS_DEPR(gnucxx17, "gnu++1z")
|
||||||
|
|
||||||
LANGSTANDARD(cxx2a, "c++2a",
|
LANGSTANDARD(cxx20, "c++20",
|
||||||
CXX, "Working draft for ISO C++ 2020",
|
CXX, "ISO C++ 2020 DIS",
|
||||||
LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus17 |
|
LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus17 |
|
||||||
CPlusPlus2a | Digraphs | HexFloat)
|
CPlusPlus2a | Digraphs | HexFloat)
|
||||||
|
LANGSTANDARD_ALIAS_DEPR(cxx20, "c++2a")
|
||||||
|
|
||||||
LANGSTANDARD(gnucxx2a, "gnu++2a",
|
LANGSTANDARD(gnucxx20, "gnu++20",
|
||||||
CXX, "Working draft for ISO C++ 2020 with GNU extensions",
|
CXX, "ISO C++ 2020 DIS with GNU extensions",
|
||||||
LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus17 |
|
LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus17 |
|
||||||
CPlusPlus2a | Digraphs | HexFloat | GNUMode)
|
CPlusPlus2a | Digraphs | HexFloat | GNUMode)
|
||||||
|
LANGSTANDARD_ALIAS_DEPR(gnucxx20, "gnu++2a")
|
||||||
|
|
||||||
// OpenCL
|
// OpenCL
|
||||||
LANGSTANDARD(opencl10, "cl1.0",
|
LANGSTANDARD(opencl10, "cl1.0",
|
||||||
|
@ -162,7 +162,7 @@ def CoawaitExpr : StmtNode<CoroutineSuspendExpr>;
|
|||||||
def DependentCoawaitExpr : StmtNode<Expr>;
|
def DependentCoawaitExpr : StmtNode<Expr>;
|
||||||
def CoyieldExpr : StmtNode<CoroutineSuspendExpr>;
|
def CoyieldExpr : StmtNode<CoroutineSuspendExpr>;
|
||||||
|
|
||||||
// C++2a Concepts expressions
|
// C++20 Concepts expressions
|
||||||
def ConceptSpecializationExpr : StmtNode<Expr>;
|
def ConceptSpecializationExpr : StmtNode<Expr>;
|
||||||
def RequiresExpr : StmtNode<Expr>;
|
def RequiresExpr : StmtNode<Expr>;
|
||||||
|
|
||||||
|
@ -67,6 +67,13 @@ class TemplateDeductionInfo {
|
|||||||
TemplateDeductionInfo(const TemplateDeductionInfo &) = delete;
|
TemplateDeductionInfo(const TemplateDeductionInfo &) = delete;
|
||||||
TemplateDeductionInfo &operator=(const TemplateDeductionInfo &) = delete;
|
TemplateDeductionInfo &operator=(const TemplateDeductionInfo &) = delete;
|
||||||
|
|
||||||
|
enum ForBaseTag { ForBase };
|
||||||
|
/// Create temporary template deduction info for speculatively deducing
|
||||||
|
/// against a base class of an argument's type.
|
||||||
|
TemplateDeductionInfo(ForBaseTag, const TemplateDeductionInfo &Info)
|
||||||
|
: Deduced(Info.Deduced), Loc(Info.Loc), DeducedDepth(Info.DeducedDepth),
|
||||||
|
ExplicitArgs(Info.ExplicitArgs) {}
|
||||||
|
|
||||||
/// Returns the location at which template argument is
|
/// Returns the location at which template argument is
|
||||||
/// occurring.
|
/// occurring.
|
||||||
SourceLocation getLocation() const {
|
SourceLocation getLocation() const {
|
||||||
|
@ -523,7 +523,13 @@ bool HasNameMatcher::matchesNodeFullFast(const NamedDecl &Node) const {
|
|||||||
if (Ctx->isFunctionOrMethod())
|
if (Ctx->isFunctionOrMethod())
|
||||||
return Patterns.foundMatch(/*AllowFullyQualified=*/false);
|
return Patterns.foundMatch(/*AllowFullyQualified=*/false);
|
||||||
|
|
||||||
for (; Ctx && isa<NamedDecl>(Ctx); Ctx = Ctx->getParent()) {
|
for (; Ctx; Ctx = Ctx->getParent()) {
|
||||||
|
// Linkage Spec can just be ignored
|
||||||
|
// FIXME: Any other DeclContext kinds that can be safely disregarded
|
||||||
|
if (isa<LinkageSpecDecl>(Ctx))
|
||||||
|
continue;
|
||||||
|
if (!isa<NamedDecl>(Ctx))
|
||||||
|
break;
|
||||||
if (Patterns.foundMatch(/*AllowFullyQualified=*/false))
|
if (Patterns.foundMatch(/*AllowFullyQualified=*/false))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
@ -1146,6 +1146,9 @@ void CodeGenAction::ExecuteAction() {
|
|||||||
CI.getTargetOpts(), CI.getLangOpts(),
|
CI.getTargetOpts(), CI.getLangOpts(),
|
||||||
CI.getFrontendOpts().ShowTimers,
|
CI.getFrontendOpts().ShowTimers,
|
||||||
std::move(LinkModules), *VMContext, nullptr);
|
std::move(LinkModules), *VMContext, nullptr);
|
||||||
|
// PR44896: Force DiscardValueNames as false. DiscardValueNames cannot be
|
||||||
|
// true here because the valued names are needed for reading textual IR.
|
||||||
|
Ctx.setDiscardValueNames(false);
|
||||||
Ctx.setDiagnosticHandler(
|
Ctx.setDiagnosticHandler(
|
||||||
std::make_unique<ClangDiagnosticHandler>(CodeGenOpts, &Result));
|
std::make_unique<ClangDiagnosticHandler>(CodeGenOpts, &Result));
|
||||||
|
|
||||||
|
@ -4266,8 +4266,16 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
|
|||||||
|
|
||||||
// Discard value names in assert builds unless otherwise specified.
|
// Discard value names in assert builds unless otherwise specified.
|
||||||
if (Args.hasFlag(options::OPT_fdiscard_value_names,
|
if (Args.hasFlag(options::OPT_fdiscard_value_names,
|
||||||
options::OPT_fno_discard_value_names, !IsAssertBuild))
|
options::OPT_fno_discard_value_names, !IsAssertBuild)) {
|
||||||
|
if (Args.hasArg(options::OPT_fdiscard_value_names) &&
|
||||||
|
(std::any_of(Inputs.begin(), Inputs.end(),
|
||||||
|
[](const clang::driver::InputInfo &II) {
|
||||||
|
return types::isLLVMIR(II.getType());
|
||||||
|
}))) {
|
||||||
|
D.Diag(diag::warn_ignoring_fdiscard_for_bitcode);
|
||||||
|
}
|
||||||
CmdArgs.push_back("-discard-value-names");
|
CmdArgs.push_back("-discard-value-names");
|
||||||
|
}
|
||||||
|
|
||||||
// Set the main file name, so that debug info works even with
|
// Set the main file name, so that debug info works even with
|
||||||
// -save-temps.
|
// -save-temps.
|
||||||
|
@ -335,7 +335,7 @@ void darwin::Linker::AddLinkArgs(Compilation &C, const ArgList &Args,
|
|||||||
Args.AddAllArgs(CmdArgs, options::OPT_init);
|
Args.AddAllArgs(CmdArgs, options::OPT_init);
|
||||||
|
|
||||||
// Add the deployment target.
|
// Add the deployment target.
|
||||||
if (!Version[0] || Version[0] >= 520)
|
if (Version[0] >= 520)
|
||||||
MachOTC.addPlatformVersionArgs(Args, CmdArgs);
|
MachOTC.addPlatformVersionArgs(Args, CmdArgs);
|
||||||
else
|
else
|
||||||
MachOTC.addMinVersionArgs(Args, CmdArgs);
|
MachOTC.addMinVersionArgs(Args, CmdArgs);
|
||||||
|
@ -344,13 +344,27 @@ static void InitializeStandardPredefinedMacros(const TargetInfo &TI,
|
|||||||
const LangOptions &LangOpts,
|
const LangOptions &LangOpts,
|
||||||
const FrontendOptions &FEOpts,
|
const FrontendOptions &FEOpts,
|
||||||
MacroBuilder &Builder) {
|
MacroBuilder &Builder) {
|
||||||
|
// C++ [cpp.predefined]p1:
|
||||||
|
// The following macro names shall be defined by the implementation:
|
||||||
|
|
||||||
|
// -- __STDC__
|
||||||
|
// [C++] Whether __STDC__ is predefined and if so, what its value is,
|
||||||
|
// are implementation-defined.
|
||||||
|
// (Removed in C++20.)
|
||||||
if (!LangOpts.MSVCCompat && !LangOpts.TraditionalCPP)
|
if (!LangOpts.MSVCCompat && !LangOpts.TraditionalCPP)
|
||||||
Builder.defineMacro("__STDC__");
|
Builder.defineMacro("__STDC__");
|
||||||
|
// -- __STDC_HOSTED__
|
||||||
|
// The integer literal 1 if the implementation is a hosted
|
||||||
|
// implementation or the integer literal 0 if it is not.
|
||||||
if (LangOpts.Freestanding)
|
if (LangOpts.Freestanding)
|
||||||
Builder.defineMacro("__STDC_HOSTED__", "0");
|
Builder.defineMacro("__STDC_HOSTED__", "0");
|
||||||
else
|
else
|
||||||
Builder.defineMacro("__STDC_HOSTED__");
|
Builder.defineMacro("__STDC_HOSTED__");
|
||||||
|
|
||||||
|
// -- __STDC_VERSION__
|
||||||
|
// [C++] Whether __STDC_VERSION__ is predefined and if so, what its
|
||||||
|
// value is, are implementation-defined.
|
||||||
|
// (Removed in C++20.)
|
||||||
if (!LangOpts.CPlusPlus) {
|
if (!LangOpts.CPlusPlus) {
|
||||||
if (LangOpts.C17)
|
if (LangOpts.C17)
|
||||||
Builder.defineMacro("__STDC_VERSION__", "201710L");
|
Builder.defineMacro("__STDC_VERSION__", "201710L");
|
||||||
@ -361,33 +375,29 @@ static void InitializeStandardPredefinedMacros(const TargetInfo &TI,
|
|||||||
else if (!LangOpts.GNUMode && LangOpts.Digraphs)
|
else if (!LangOpts.GNUMode && LangOpts.Digraphs)
|
||||||
Builder.defineMacro("__STDC_VERSION__", "199409L");
|
Builder.defineMacro("__STDC_VERSION__", "199409L");
|
||||||
} else {
|
} else {
|
||||||
// FIXME: Use correct value for C++20.
|
// -- __cplusplus
|
||||||
|
// [C++20] The integer literal 202002L.
|
||||||
if (LangOpts.CPlusPlus2a)
|
if (LangOpts.CPlusPlus2a)
|
||||||
Builder.defineMacro("__cplusplus", "201707L");
|
Builder.defineMacro("__cplusplus", "202002L");
|
||||||
// C++17 [cpp.predefined]p1:
|
// [C++17] The integer literal 201703L.
|
||||||
// The name __cplusplus is defined to the value 201703L when compiling a
|
|
||||||
// C++ translation unit.
|
|
||||||
else if (LangOpts.CPlusPlus17)
|
else if (LangOpts.CPlusPlus17)
|
||||||
Builder.defineMacro("__cplusplus", "201703L");
|
Builder.defineMacro("__cplusplus", "201703L");
|
||||||
// C++1y [cpp.predefined]p1:
|
// [C++14] The name __cplusplus is defined to the value 201402L when
|
||||||
// The name __cplusplus is defined to the value 201402L when compiling a
|
// compiling a C++ translation unit.
|
||||||
// C++ translation unit.
|
|
||||||
else if (LangOpts.CPlusPlus14)
|
else if (LangOpts.CPlusPlus14)
|
||||||
Builder.defineMacro("__cplusplus", "201402L");
|
Builder.defineMacro("__cplusplus", "201402L");
|
||||||
// C++11 [cpp.predefined]p1:
|
// [C++11] The name __cplusplus is defined to the value 201103L when
|
||||||
// The name __cplusplus is defined to the value 201103L when compiling a
|
// compiling a C++ translation unit.
|
||||||
// C++ translation unit.
|
|
||||||
else if (LangOpts.CPlusPlus11)
|
else if (LangOpts.CPlusPlus11)
|
||||||
Builder.defineMacro("__cplusplus", "201103L");
|
Builder.defineMacro("__cplusplus", "201103L");
|
||||||
// C++03 [cpp.predefined]p1:
|
// [C++03] The name __cplusplus is defined to the value 199711L when
|
||||||
// The name __cplusplus is defined to the value 199711L when compiling a
|
// compiling a C++ translation unit.
|
||||||
// C++ translation unit.
|
|
||||||
else
|
else
|
||||||
Builder.defineMacro("__cplusplus", "199711L");
|
Builder.defineMacro("__cplusplus", "199711L");
|
||||||
|
|
||||||
// C++1z [cpp.predefined]p1:
|
// -- __STDCPP_DEFAULT_NEW_ALIGNMENT__
|
||||||
// An integer literal of type std::size_t whose value is the alignment
|
// [C++17] An integer literal of type std::size_t whose value is the
|
||||||
// guaranteed by a call to operator new(std::size_t)
|
// alignment guaranteed by a call to operator new(std::size_t)
|
||||||
//
|
//
|
||||||
// We provide this in all language modes, since it seems generally useful.
|
// We provide this in all language modes, since it seems generally useful.
|
||||||
Builder.defineMacro("__STDCPP_DEFAULT_NEW_ALIGNMENT__",
|
Builder.defineMacro("__STDCPP_DEFAULT_NEW_ALIGNMENT__",
|
||||||
|
@ -1818,7 +1818,7 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S,
|
|||||||
// If this is a base class, try to perform template argument
|
// If this is a base class, try to perform template argument
|
||||||
// deduction from it.
|
// deduction from it.
|
||||||
if (NextT != RecordT) {
|
if (NextT != RecordT) {
|
||||||
TemplateDeductionInfo BaseInfo(Info.getLocation());
|
TemplateDeductionInfo BaseInfo(TemplateDeductionInfo::ForBase, Info);
|
||||||
Sema::TemplateDeductionResult BaseResult =
|
Sema::TemplateDeductionResult BaseResult =
|
||||||
DeduceTemplateArguments(S, TemplateParams, SpecParam,
|
DeduceTemplateArguments(S, TemplateParams, SpecParam,
|
||||||
QualType(NextT, 0), BaseInfo, Deduced);
|
QualType(NextT, 0), BaseInfo, Deduced);
|
||||||
|
@ -3224,8 +3224,7 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
|
|||||||
case MODULAR_CODEGEN_DECLS:
|
case MODULAR_CODEGEN_DECLS:
|
||||||
// FIXME: Skip reading this record if our ASTConsumer doesn't care about
|
// FIXME: Skip reading this record if our ASTConsumer doesn't care about
|
||||||
// them (ie: if we're not codegenerating this module).
|
// them (ie: if we're not codegenerating this module).
|
||||||
if (F.Kind == MK_MainFile ||
|
if (F.Kind == MK_MainFile)
|
||||||
getContext().getLangOpts().BuildingPCHWithObjectFile)
|
|
||||||
for (unsigned I = 0, N = Record.size(); I != N; ++I)
|
for (unsigned I = 0, N = Record.size(); I != N; ++I)
|
||||||
EagerlyDeserializedDecls.push_back(getGlobalDeclID(F, Record[I]));
|
EagerlyDeserializedDecls.push_back(getGlobalDeclID(F, Record[I]));
|
||||||
break;
|
break;
|
||||||
|
@ -502,12 +502,8 @@ uint64_t ASTDeclReader::GetCurrentCursorOffset() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ASTDeclReader::ReadFunctionDefinition(FunctionDecl *FD) {
|
void ASTDeclReader::ReadFunctionDefinition(FunctionDecl *FD) {
|
||||||
if (Record.readInt()) {
|
if (Record.readInt())
|
||||||
Reader.DefinitionSource[FD] = Loc.F->Kind == ModuleKind::MK_MainFile;
|
Reader.DefinitionSource[FD] = Loc.F->Kind == ModuleKind::MK_MainFile;
|
||||||
if (Reader.getContext().getLangOpts().BuildingPCHWithObjectFile &&
|
|
||||||
Reader.DeclIsFromPCHWithObjectFile(FD))
|
|
||||||
Reader.DefinitionSource[FD] = true;
|
|
||||||
}
|
|
||||||
if (auto *CD = dyn_cast<CXXConstructorDecl>(FD)) {
|
if (auto *CD = dyn_cast<CXXConstructorDecl>(FD)) {
|
||||||
CD->setNumCtorInitializers(Record.readInt());
|
CD->setNumCtorInitializers(Record.readInt());
|
||||||
if (CD->getNumCtorInitializers())
|
if (CD->getNumCtorInitializers())
|
||||||
@ -1422,12 +1418,8 @@ ASTDeclReader::RedeclarableResult ASTDeclReader::VisitVarDeclImpl(VarDecl *VD) {
|
|||||||
Reader.getContext().setBlockVarCopyInit(VD, CopyExpr, Record.readInt());
|
Reader.getContext().setBlockVarCopyInit(VD, CopyExpr, Record.readInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (VD->getStorageDuration() == SD_Static && Record.readInt()) {
|
if (VD->getStorageDuration() == SD_Static && Record.readInt())
|
||||||
Reader.DefinitionSource[VD] = Loc.F->Kind == ModuleKind::MK_MainFile;
|
Reader.DefinitionSource[VD] = Loc.F->Kind == ModuleKind::MK_MainFile;
|
||||||
if (Reader.getContext().getLangOpts().BuildingPCHWithObjectFile &&
|
|
||||||
Reader.DeclIsFromPCHWithObjectFile(VD))
|
|
||||||
Reader.DefinitionSource[VD] = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum VarKind {
|
enum VarKind {
|
||||||
VarNotTemplate = 0, VarTemplate, StaticDataMemberSpecialization
|
VarNotTemplate = 0, VarTemplate, StaticDataMemberSpecialization
|
||||||
@ -1686,12 +1678,8 @@ void ASTDeclReader::ReadCXXDefinitionData(
|
|||||||
Data.ODRHash = Record.readInt();
|
Data.ODRHash = Record.readInt();
|
||||||
Data.HasODRHash = true;
|
Data.HasODRHash = true;
|
||||||
|
|
||||||
if (Record.readInt()) {
|
if (Record.readInt())
|
||||||
Reader.DefinitionSource[D] = Loc.F->Kind == ModuleKind::MK_MainFile;
|
Reader.DefinitionSource[D] = Loc.F->Kind == ModuleKind::MK_MainFile;
|
||||||
if (Reader.getContext().getLangOpts().BuildingPCHWithObjectFile &&
|
|
||||||
Reader.DeclIsFromPCHWithObjectFile(D))
|
|
||||||
Reader.DefinitionSource[D] = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Data.NumBases = Record.readInt();
|
Data.NumBases = Record.readInt();
|
||||||
if (Data.NumBases)
|
if (Data.NumBases)
|
||||||
|
@ -5596,8 +5596,8 @@ void ASTRecordWriter::AddCXXDefinitionData(const CXXRecordDecl *D) {
|
|||||||
|
|
||||||
// getODRHash will compute the ODRHash if it has not been previously computed.
|
// getODRHash will compute the ODRHash if it has not been previously computed.
|
||||||
Record->push_back(D->getODRHash());
|
Record->push_back(D->getODRHash());
|
||||||
bool ModulesDebugInfo =
|
bool ModulesDebugInfo = Writer->Context->getLangOpts().ModulesDebugInfo &&
|
||||||
Writer->Context->getLangOpts().ModulesDebugInfo && !D->isDependentType();
|
Writer->WritingModule && !D->isDependentType();
|
||||||
Record->push_back(ModulesDebugInfo);
|
Record->push_back(ModulesDebugInfo);
|
||||||
if (ModulesDebugInfo)
|
if (ModulesDebugInfo)
|
||||||
Writer->ModularCodegenDecls.push_back(Writer->GetDeclRef(D));
|
Writer->ModularCodegenDecls.push_back(Writer->GetDeclRef(D));
|
||||||
|
@ -1011,16 +1011,15 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) {
|
|||||||
|
|
||||||
if (D->getStorageDuration() == SD_Static) {
|
if (D->getStorageDuration() == SD_Static) {
|
||||||
bool ModulesCodegen = false;
|
bool ModulesCodegen = false;
|
||||||
if (!D->getDescribedVarTemplate() && !D->getMemberSpecializationInfo() &&
|
if (Writer.WritingModule &&
|
||||||
|
!D->getDescribedVarTemplate() && !D->getMemberSpecializationInfo() &&
|
||||||
!isa<VarTemplateSpecializationDecl>(D)) {
|
!isa<VarTemplateSpecializationDecl>(D)) {
|
||||||
// When building a C++ Modules TS module interface unit, a strong
|
// When building a C++ Modules TS module interface unit, a strong
|
||||||
// definition in the module interface is provided by the compilation of
|
// definition in the module interface is provided by the compilation of
|
||||||
// that module interface unit, not by its users. (Inline variables are
|
// that module interface unit, not by its users. (Inline variables are
|
||||||
// still emitted in module users.)
|
// still emitted in module users.)
|
||||||
ModulesCodegen =
|
ModulesCodegen =
|
||||||
(((Writer.WritingModule &&
|
(Writer.WritingModule->Kind == Module::ModuleInterfaceUnit &&
|
||||||
Writer.WritingModule->Kind == Module::ModuleInterfaceUnit) ||
|
|
||||||
Writer.Context->getLangOpts().BuildingPCHWithObjectFile) &&
|
|
||||||
Writer.Context->GetGVALinkageForVariable(D) == GVA_StrongExternal);
|
Writer.Context->GetGVALinkageForVariable(D) == GVA_StrongExternal);
|
||||||
}
|
}
|
||||||
Record.push_back(ModulesCodegen);
|
Record.push_back(ModulesCodegen);
|
||||||
@ -2449,11 +2448,9 @@ void ASTRecordWriter::AddFunctionDefinition(const FunctionDecl *FD) {
|
|||||||
|
|
||||||
assert(FD->doesThisDeclarationHaveABody());
|
assert(FD->doesThisDeclarationHaveABody());
|
||||||
bool ModulesCodegen = false;
|
bool ModulesCodegen = false;
|
||||||
if (!FD->isDependentContext()) {
|
if (Writer->WritingModule && !FD->isDependentContext()) {
|
||||||
Optional<GVALinkage> Linkage;
|
Optional<GVALinkage> Linkage;
|
||||||
if ((Writer->WritingModule &&
|
if (Writer->WritingModule->Kind == Module::ModuleInterfaceUnit) {
|
||||||
Writer->WritingModule->Kind == Module::ModuleInterfaceUnit) ||
|
|
||||||
Writer->Context->getLangOpts().BuildingPCHWithObjectFile) {
|
|
||||||
// When building a C++ Modules TS module interface unit, a strong
|
// When building a C++ Modules TS module interface unit, a strong
|
||||||
// definition in the module interface is provided by the compilation of
|
// definition in the module interface is provided by the compilation of
|
||||||
// that module interface unit, not by its users. (Inline functions are
|
// that module interface unit, not by its users. (Inline functions are
|
||||||
|
@ -42,6 +42,12 @@ ArgumentsAdjuster getClangSyntaxOnlyAdjuster() {
|
|||||||
if (!Arg.startswith("-fcolor-diagnostics") &&
|
if (!Arg.startswith("-fcolor-diagnostics") &&
|
||||||
!Arg.startswith("-fdiagnostics-color"))
|
!Arg.startswith("-fdiagnostics-color"))
|
||||||
AdjustedArgs.push_back(Args[i]);
|
AdjustedArgs.push_back(Args[i]);
|
||||||
|
// If we strip a color option, make sure we strip any preceeding `-Xclang`
|
||||||
|
// option as well.
|
||||||
|
// FIXME: This should be added to most argument adjusters!
|
||||||
|
else if (!AdjustedArgs.empty() && AdjustedArgs.back() == "-Xclang")
|
||||||
|
AdjustedArgs.pop_back();
|
||||||
|
|
||||||
if (Arg == "-fsyntax-only")
|
if (Arg == "-fsyntax-only")
|
||||||
HasSyntaxOnly = true;
|
HasSyntaxOnly = true;
|
||||||
}
|
}
|
||||||
|
@ -62,27 +62,8 @@ typedef unsigned long long uint64_t;
|
|||||||
#include "InstrProfiling.h"
|
#include "InstrProfiling.h"
|
||||||
#include "InstrProfilingUtil.h"
|
#include "InstrProfilingUtil.h"
|
||||||
|
|
||||||
#ifndef _WIN32
|
|
||||||
#include <pthread.h>
|
|
||||||
static pthread_mutex_t gcov_flush_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
||||||
static __inline void gcov_flush_lock() {
|
|
||||||
pthread_mutex_lock(&gcov_flush_mutex);
|
|
||||||
}
|
|
||||||
static __inline void gcov_flush_unlock() {
|
|
||||||
pthread_mutex_unlock(&gcov_flush_mutex);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#include <windows.h>
|
|
||||||
static SRWLOCK gcov_flush_mutex = SRWLOCK_INIT;
|
|
||||||
static __inline void gcov_flush_lock() {
|
|
||||||
AcquireSRWLockExclusive(&gcov_flush_mutex);
|
|
||||||
}
|
|
||||||
static __inline void gcov_flush_unlock() {
|
|
||||||
ReleaseSRWLockExclusive(&gcov_flush_mutex);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* #define DEBUG_GCDAPROFILING */
|
/* #define DEBUG_GCDAPROFILING */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* --- GCOV file format I/O primitives ---
|
* --- GCOV file format I/O primitives ---
|
||||||
*/
|
*/
|
||||||
@ -639,16 +620,12 @@ void llvm_register_flush_function(fn_ptr fn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void __gcov_flush() {
|
void __gcov_flush() {
|
||||||
gcov_flush_lock();
|
|
||||||
|
|
||||||
struct fn_node* curr = flush_fn_list.head;
|
struct fn_node* curr = flush_fn_list.head;
|
||||||
|
|
||||||
while (curr) {
|
while (curr) {
|
||||||
curr->fn();
|
curr->fn();
|
||||||
curr = curr->next;
|
curr = curr->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
gcov_flush_unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
COMPILER_RT_VISIBILITY
|
COMPILER_RT_VISIBILITY
|
||||||
|
@ -1122,6 +1122,21 @@ public:
|
|||||||
__bit_iterator(const __type_for_copy_to_const& __it) _NOEXCEPT
|
__bit_iterator(const __type_for_copy_to_const& __it) _NOEXCEPT
|
||||||
: __seg_(__it.__seg_), __ctz_(__it.__ctz_) {}
|
: __seg_(__it.__seg_), __ctz_(__it.__ctz_) {}
|
||||||
|
|
||||||
|
// The non-const __bit_iterator has historically had a non-trivial
|
||||||
|
// copy constructor (as a quirk of its construction). We need to maintain
|
||||||
|
// this for ABI purposes.
|
||||||
|
using __type_for_abi_non_trivial_copy_ctor =
|
||||||
|
_If<!_IsConst, __bit_iterator, struct __private_nat>;
|
||||||
|
|
||||||
|
_LIBCPP_INLINE_VISIBILITY
|
||||||
|
__bit_iterator(__type_for_abi_non_trivial_copy_ctor const& __it) _NOEXCEPT
|
||||||
|
: __seg_(__it.__seg_), __ctz_(__it.__ctz_) {}
|
||||||
|
|
||||||
|
// Always declare the copy assignment operator since the implicit declaration
|
||||||
|
// is deprecated.
|
||||||
|
_LIBCPP_INLINE_VISIBILITY
|
||||||
|
__bit_iterator& operator=(__bit_iterator const&) = default;
|
||||||
|
|
||||||
_LIBCPP_INLINE_VISIBILITY reference operator*() const _NOEXCEPT
|
_LIBCPP_INLINE_VISIBILITY reference operator*() const _NOEXCEPT
|
||||||
{return reference(__seg_, __storage_type(1) << __ctz_);}
|
{return reference(__seg_, __storage_type(1) << __ctz_);}
|
||||||
|
|
||||||
|
@ -86,3 +86,4 @@ WebAssembly Improvements
|
|||||||
as it's best to keep them internal when possible. They can be
|
as it's best to keep them internal when possible. They can be
|
||||||
explicitly exported with `--export=__data_end` and
|
explicitly exported with `--export=__data_end` and
|
||||||
`--export=__heap_base`, respectively.
|
`--export=__heap_base`, respectively.
|
||||||
|
* wasm-ld now elides .bss sections when the memory is not imported
|
||||||
|
@ -2071,6 +2071,10 @@ bool DWARFExpression::Evaluate(
|
|||||||
// not available. Fill with zeros for now by resizing the data and
|
// not available. Fill with zeros for now by resizing the data and
|
||||||
// appending it
|
// appending it
|
||||||
curr_piece.ResizeData(piece_byte_size);
|
curr_piece.ResizeData(piece_byte_size);
|
||||||
|
// Note that "0" is not a correct value for the unknown bits.
|
||||||
|
// It would be better to also return a mask of valid bits together
|
||||||
|
// with the expression result, so the debugger can print missing
|
||||||
|
// members as "<optimized out>" or something.
|
||||||
::memset(curr_piece.GetBuffer().GetBytes(), 0, piece_byte_size);
|
::memset(curr_piece.GetBuffer().GetBytes(), 0, piece_byte_size);
|
||||||
pieces.AppendDataToHostBuffer(curr_piece);
|
pieces.AppendDataToHostBuffer(curr_piece);
|
||||||
} else {
|
} else {
|
||||||
@ -2128,7 +2132,8 @@ bool DWARFExpression::Evaluate(
|
|||||||
case Value::eValueTypeScalar: {
|
case Value::eValueTypeScalar: {
|
||||||
uint32_t bit_size = piece_byte_size * 8;
|
uint32_t bit_size = piece_byte_size * 8;
|
||||||
uint32_t bit_offset = 0;
|
uint32_t bit_offset = 0;
|
||||||
if (!curr_piece_source_value.GetScalar().ExtractBitfield(
|
Scalar &scalar = curr_piece_source_value.GetScalar();
|
||||||
|
if (!scalar.ExtractBitfield(
|
||||||
bit_size, bit_offset)) {
|
bit_size, bit_offset)) {
|
||||||
if (error_ptr)
|
if (error_ptr)
|
||||||
error_ptr->SetErrorStringWithFormat(
|
error_ptr->SetErrorStringWithFormat(
|
||||||
@ -2139,7 +2144,14 @@ bool DWARFExpression::Evaluate(
|
|||||||
.GetByteSize());
|
.GetByteSize());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
curr_piece = curr_piece_source_value;
|
// Create curr_piece with bit_size. By default Scalar
|
||||||
|
// grows to the nearest host integer type.
|
||||||
|
llvm::APInt fail_value(1, 0, false);
|
||||||
|
llvm::APInt ap_int = scalar.UInt128(fail_value);
|
||||||
|
assert(ap_int.getBitWidth() >= bit_size);
|
||||||
|
llvm::ArrayRef<uint64_t> buf{ap_int.getRawData(),
|
||||||
|
ap_int.getNumWords()};
|
||||||
|
curr_piece.GetScalar() = Scalar(llvm::APInt(bit_size, buf));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Value::eValueTypeVector: {
|
case Value::eValueTypeVector: {
|
||||||
@ -2161,7 +2173,7 @@ bool DWARFExpression::Evaluate(
|
|||||||
if (op_piece_offset == 0) {
|
if (op_piece_offset == 0) {
|
||||||
// This is the first piece, we should push it back onto the stack
|
// This is the first piece, we should push it back onto the stack
|
||||||
// so subsequent pieces will be able to access this piece and add
|
// so subsequent pieces will be able to access this piece and add
|
||||||
// to it
|
// to it.
|
||||||
if (pieces.AppendDataToHostBuffer(curr_piece) == 0) {
|
if (pieces.AppendDataToHostBuffer(curr_piece) == 0) {
|
||||||
if (error_ptr)
|
if (error_ptr)
|
||||||
error_ptr->SetErrorString("failed to append piece data");
|
error_ptr->SetErrorString("failed to append piece data");
|
||||||
@ -2169,7 +2181,7 @@ bool DWARFExpression::Evaluate(
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// If this is the second or later piece there should be a value on
|
// If this is the second or later piece there should be a value on
|
||||||
// the stack
|
// the stack.
|
||||||
if (pieces.GetBuffer().GetByteSize() != op_piece_offset) {
|
if (pieces.GetBuffer().GetByteSize() != op_piece_offset) {
|
||||||
if (error_ptr)
|
if (error_ptr)
|
||||||
error_ptr->SetErrorStringWithFormat(
|
error_ptr->SetErrorStringWithFormat(
|
||||||
@ -2185,8 +2197,8 @@ bool DWARFExpression::Evaluate(
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
op_piece_offset += piece_byte_size;
|
|
||||||
}
|
}
|
||||||
|
op_piece_offset += piece_byte_size;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
@ -2298,7 +2298,10 @@ bool MemorySSAWrapperPass::runOnFunction(Function &F) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemorySSAWrapperPass::verifyAnalysis() const { MSSA->verifyMemorySSA(); }
|
void MemorySSAWrapperPass::verifyAnalysis() const {
|
||||||
|
if (VerifyMemorySSA)
|
||||||
|
MSSA->verifyMemorySSA();
|
||||||
|
}
|
||||||
|
|
||||||
void MemorySSAWrapperPass::print(raw_ostream &OS, const Module *M) const {
|
void MemorySSAWrapperPass::print(raw_ostream &OS, const Module *M) const {
|
||||||
MSSA->print(OS);
|
MSSA->print(OS);
|
||||||
|
@ -16510,33 +16510,6 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) {
|
|||||||
CombineTo(ST1, ST1->getChain());
|
CombineTo(ST1, ST1->getChain());
|
||||||
return SDValue();
|
return SDValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
// If ST stores to a subset of preceding store's write set, we may be
|
|
||||||
// able to fold ST's value into the preceding stored value. As we know
|
|
||||||
// the other uses of ST1's chain are unconcerned with ST, this folding
|
|
||||||
// will not affect those nodes.
|
|
||||||
int64_t BitOffset;
|
|
||||||
if (ChainBase.contains(DAG, ChainBitSize, STBase, STBitSize,
|
|
||||||
BitOffset)) {
|
|
||||||
SDValue ChainValue = ST1->getValue();
|
|
||||||
if (auto *C1 = dyn_cast<ConstantSDNode>(ChainValue)) {
|
|
||||||
if (auto *C = dyn_cast<ConstantSDNode>(Value)) {
|
|
||||||
APInt Val = C1->getAPIntValue();
|
|
||||||
APInt InsertVal = C->getAPIntValue().zextOrTrunc(STBitSize);
|
|
||||||
// FIXME: Handle Big-endian mode.
|
|
||||||
if (!DAG.getDataLayout().isBigEndian()) {
|
|
||||||
Val.insertBits(InsertVal, BitOffset);
|
|
||||||
SDValue NewSDVal =
|
|
||||||
DAG.getConstant(Val, SDLoc(C), ChainValue.getValueType(),
|
|
||||||
C1->isTargetOpcode(), C1->isOpaque());
|
|
||||||
SDNode *NewST1 = DAG.UpdateNodeOperands(
|
|
||||||
ST1, ST1->getChain(), NewSDVal, ST1->getOperand(2),
|
|
||||||
ST1->getOperand(3));
|
|
||||||
return CombineTo(ST, SDValue(NewST1, 0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // End ST subset of ST1 case.
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1233,7 +1233,6 @@ bool DAGTypeLegalizer::PromoteIntegerOperand(SDNode *N, unsigned OpNo) {
|
|||||||
LLVM_DEBUG(dbgs() << "Promote integer operand: "; N->dump(&DAG);
|
LLVM_DEBUG(dbgs() << "Promote integer operand: "; N->dump(&DAG);
|
||||||
dbgs() << "\n");
|
dbgs() << "\n");
|
||||||
SDValue Res = SDValue();
|
SDValue Res = SDValue();
|
||||||
|
|
||||||
if (CustomLowerNode(N, N->getOperand(OpNo).getValueType(), false)) {
|
if (CustomLowerNode(N, N->getOperand(OpNo).getValueType(), false)) {
|
||||||
LLVM_DEBUG(dbgs() << "Node has been custom lowered, done\n");
|
LLVM_DEBUG(dbgs() << "Node has been custom lowered, done\n");
|
||||||
return false;
|
return false;
|
||||||
@ -1330,10 +1329,17 @@ bool DAGTypeLegalizer::PromoteIntegerOperand(SDNode *N, unsigned OpNo) {
|
|||||||
if (Res.getNode() == N)
|
if (Res.getNode() == N)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
|
const bool IsStrictFp = N->isStrictFPOpcode();
|
||||||
|
assert(Res.getValueType() == N->getValueType(0) &&
|
||||||
|
N->getNumValues() == (IsStrictFp ? 2 : 1) &&
|
||||||
"Invalid operand expansion");
|
"Invalid operand expansion");
|
||||||
|
LLVM_DEBUG(dbgs() << "Replacing: "; N->dump(&DAG); dbgs() << " with: ";
|
||||||
|
Res.dump());
|
||||||
|
|
||||||
ReplaceValueWith(SDValue(N, 0), Res);
|
ReplaceValueWith(SDValue(N, 0), Res);
|
||||||
|
if (IsStrictFp)
|
||||||
|
ReplaceValueWith(SDValue(N, 1), SDValue(Res.getNode(), 1));
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,6 +211,12 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
|
|||||||
setOperationAction(ISD::SETCC, MVT::f16, Custom);
|
setOperationAction(ISD::SETCC, MVT::f16, Custom);
|
||||||
setOperationAction(ISD::SETCC, MVT::f32, Custom);
|
setOperationAction(ISD::SETCC, MVT::f32, Custom);
|
||||||
setOperationAction(ISD::SETCC, MVT::f64, Custom);
|
setOperationAction(ISD::SETCC, MVT::f64, Custom);
|
||||||
|
setOperationAction(ISD::STRICT_FSETCC, MVT::f16, Custom);
|
||||||
|
setOperationAction(ISD::STRICT_FSETCC, MVT::f32, Custom);
|
||||||
|
setOperationAction(ISD::STRICT_FSETCC, MVT::f64, Custom);
|
||||||
|
setOperationAction(ISD::STRICT_FSETCCS, MVT::f16, Custom);
|
||||||
|
setOperationAction(ISD::STRICT_FSETCCS, MVT::f32, Custom);
|
||||||
|
setOperationAction(ISD::STRICT_FSETCCS, MVT::f64, Custom);
|
||||||
setOperationAction(ISD::BITREVERSE, MVT::i32, Legal);
|
setOperationAction(ISD::BITREVERSE, MVT::i32, Legal);
|
||||||
setOperationAction(ISD::BITREVERSE, MVT::i64, Legal);
|
setOperationAction(ISD::BITREVERSE, MVT::i64, Legal);
|
||||||
setOperationAction(ISD::BRCOND, MVT::Other, Expand);
|
setOperationAction(ISD::BRCOND, MVT::Other, Expand);
|
||||||
@ -266,6 +272,8 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
|
|||||||
setOperationAction(ISD::FSUB, MVT::f128, Custom);
|
setOperationAction(ISD::FSUB, MVT::f128, Custom);
|
||||||
setOperationAction(ISD::FTRUNC, MVT::f128, Expand);
|
setOperationAction(ISD::FTRUNC, MVT::f128, Expand);
|
||||||
setOperationAction(ISD::SETCC, MVT::f128, Custom);
|
setOperationAction(ISD::SETCC, MVT::f128, Custom);
|
||||||
|
setOperationAction(ISD::STRICT_FSETCC, MVT::f128, Custom);
|
||||||
|
setOperationAction(ISD::STRICT_FSETCCS, MVT::f128, Custom);
|
||||||
setOperationAction(ISD::BR_CC, MVT::f128, Custom);
|
setOperationAction(ISD::BR_CC, MVT::f128, Custom);
|
||||||
setOperationAction(ISD::SELECT, MVT::f128, Custom);
|
setOperationAction(ISD::SELECT, MVT::f128, Custom);
|
||||||
setOperationAction(ISD::SELECT_CC, MVT::f128, Custom);
|
setOperationAction(ISD::SELECT_CC, MVT::f128, Custom);
|
||||||
@ -276,17 +284,31 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
|
|||||||
setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
|
setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
|
||||||
setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom);
|
setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom);
|
||||||
setOperationAction(ISD::FP_TO_SINT, MVT::i128, Custom);
|
setOperationAction(ISD::FP_TO_SINT, MVT::i128, Custom);
|
||||||
|
setOperationAction(ISD::STRICT_FP_TO_SINT, MVT::i32, Custom);
|
||||||
|
setOperationAction(ISD::STRICT_FP_TO_SINT, MVT::i64, Custom);
|
||||||
|
setOperationAction(ISD::STRICT_FP_TO_SINT, MVT::i128, Custom);
|
||||||
setOperationAction(ISD::FP_TO_UINT, MVT::i32, Custom);
|
setOperationAction(ISD::FP_TO_UINT, MVT::i32, Custom);
|
||||||
setOperationAction(ISD::FP_TO_UINT, MVT::i64, Custom);
|
setOperationAction(ISD::FP_TO_UINT, MVT::i64, Custom);
|
||||||
setOperationAction(ISD::FP_TO_UINT, MVT::i128, Custom);
|
setOperationAction(ISD::FP_TO_UINT, MVT::i128, Custom);
|
||||||
|
setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::i32, Custom);
|
||||||
|
setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::i64, Custom);
|
||||||
|
setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::i128, Custom);
|
||||||
setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom);
|
setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom);
|
||||||
setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom);
|
setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom);
|
||||||
setOperationAction(ISD::SINT_TO_FP, MVT::i128, Custom);
|
setOperationAction(ISD::SINT_TO_FP, MVT::i128, Custom);
|
||||||
|
setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::i32, Custom);
|
||||||
|
setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::i64, Custom);
|
||||||
|
setOperationAction(ISD::STRICT_SINT_TO_FP, MVT::i128, Custom);
|
||||||
setOperationAction(ISD::UINT_TO_FP, MVT::i32, Custom);
|
setOperationAction(ISD::UINT_TO_FP, MVT::i32, Custom);
|
||||||
setOperationAction(ISD::UINT_TO_FP, MVT::i64, Custom);
|
setOperationAction(ISD::UINT_TO_FP, MVT::i64, Custom);
|
||||||
setOperationAction(ISD::UINT_TO_FP, MVT::i128, Custom);
|
setOperationAction(ISD::UINT_TO_FP, MVT::i128, Custom);
|
||||||
|
setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::i32, Custom);
|
||||||
|
setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::i64, Custom);
|
||||||
|
setOperationAction(ISD::STRICT_UINT_TO_FP, MVT::i128, Custom);
|
||||||
setOperationAction(ISD::FP_ROUND, MVT::f32, Custom);
|
setOperationAction(ISD::FP_ROUND, MVT::f32, Custom);
|
||||||
setOperationAction(ISD::FP_ROUND, MVT::f64, Custom);
|
setOperationAction(ISD::FP_ROUND, MVT::f64, Custom);
|
||||||
|
setOperationAction(ISD::STRICT_FP_ROUND, MVT::f32, Custom);
|
||||||
|
setOperationAction(ISD::STRICT_FP_ROUND, MVT::f64, Custom);
|
||||||
|
|
||||||
// Variable arguments.
|
// Variable arguments.
|
||||||
setOperationAction(ISD::VASTART, MVT::Other, Custom);
|
setOperationAction(ISD::VASTART, MVT::Other, Custom);
|
||||||
@ -1235,6 +1257,8 @@ const char *AArch64TargetLowering::getTargetNodeName(unsigned Opcode) const {
|
|||||||
case AArch64ISD::CCMN: return "AArch64ISD::CCMN";
|
case AArch64ISD::CCMN: return "AArch64ISD::CCMN";
|
||||||
case AArch64ISD::FCCMP: return "AArch64ISD::FCCMP";
|
case AArch64ISD::FCCMP: return "AArch64ISD::FCCMP";
|
||||||
case AArch64ISD::FCMP: return "AArch64ISD::FCMP";
|
case AArch64ISD::FCMP: return "AArch64ISD::FCMP";
|
||||||
|
case AArch64ISD::STRICT_FCMP: return "AArch64ISD::STRICT_FCMP";
|
||||||
|
case AArch64ISD::STRICT_FCMPE: return "AArch64ISD::STRICT_FCMPE";
|
||||||
case AArch64ISD::DUP: return "AArch64ISD::DUP";
|
case AArch64ISD::DUP: return "AArch64ISD::DUP";
|
||||||
case AArch64ISD::DUPLANE8: return "AArch64ISD::DUPLANE8";
|
case AArch64ISD::DUPLANE8: return "AArch64ISD::DUPLANE8";
|
||||||
case AArch64ISD::DUPLANE16: return "AArch64ISD::DUPLANE16";
|
case AArch64ISD::DUPLANE16: return "AArch64ISD::DUPLANE16";
|
||||||
@ -1668,6 +1692,17 @@ static bool isCMN(SDValue Op, ISD::CondCode CC) {
|
|||||||
(CC == ISD::SETEQ || CC == ISD::SETNE);
|
(CC == ISD::SETEQ || CC == ISD::SETNE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static SDValue emitStrictFPComparison(SDValue LHS, SDValue RHS, const SDLoc &dl,
|
||||||
|
SelectionDAG &DAG, SDValue Chain,
|
||||||
|
bool IsSignaling) {
|
||||||
|
EVT VT = LHS.getValueType();
|
||||||
|
assert(VT != MVT::f128);
|
||||||
|
assert(VT != MVT::f16 && "Lowering of strict fp16 not yet implemented");
|
||||||
|
unsigned Opcode =
|
||||||
|
IsSignaling ? AArch64ISD::STRICT_FCMPE : AArch64ISD::STRICT_FCMP;
|
||||||
|
return DAG.getNode(Opcode, dl, {VT, MVT::Other}, {Chain, LHS, RHS});
|
||||||
|
}
|
||||||
|
|
||||||
static SDValue emitComparison(SDValue LHS, SDValue RHS, ISD::CondCode CC,
|
static SDValue emitComparison(SDValue LHS, SDValue RHS, ISD::CondCode CC,
|
||||||
const SDLoc &dl, SelectionDAG &DAG) {
|
const SDLoc &dl, SelectionDAG &DAG) {
|
||||||
EVT VT = LHS.getValueType();
|
EVT VT = LHS.getValueType();
|
||||||
@ -2284,9 +2319,16 @@ getAArch64XALUOOp(AArch64CC::CondCode &CC, SDValue Op, SelectionDAG &DAG) {
|
|||||||
|
|
||||||
SDValue AArch64TargetLowering::LowerF128Call(SDValue Op, SelectionDAG &DAG,
|
SDValue AArch64TargetLowering::LowerF128Call(SDValue Op, SelectionDAG &DAG,
|
||||||
RTLIB::Libcall Call) const {
|
RTLIB::Libcall Call) const {
|
||||||
SmallVector<SDValue, 2> Ops(Op->op_begin(), Op->op_end());
|
bool IsStrict = Op->isStrictFPOpcode();
|
||||||
|
unsigned Offset = IsStrict ? 1 : 0;
|
||||||
|
SDValue Chain = IsStrict ? Op.getOperand(0) : SDValue();
|
||||||
|
SmallVector<SDValue, 2> Ops(Op->op_begin() + Offset, Op->op_end());
|
||||||
MakeLibCallOptions CallOptions;
|
MakeLibCallOptions CallOptions;
|
||||||
return makeLibCall(DAG, Call, MVT::f128, Ops, CallOptions, SDLoc(Op)).first;
|
SDValue Result;
|
||||||
|
SDLoc dl(Op);
|
||||||
|
std::tie(Result, Chain) = makeLibCall(DAG, Call, Op.getValueType(), Ops,
|
||||||
|
CallOptions, dl, Chain);
|
||||||
|
return IsStrict ? DAG.getMergeValues({Result, Chain}, dl) : Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if the given Op is the overflow flag result of an overflow
|
// Returns true if the given Op is the overflow flag result of an overflow
|
||||||
@ -2483,21 +2525,26 @@ SDValue AArch64TargetLowering::LowerFP_EXTEND(SDValue Op,
|
|||||||
|
|
||||||
SDValue AArch64TargetLowering::LowerFP_ROUND(SDValue Op,
|
SDValue AArch64TargetLowering::LowerFP_ROUND(SDValue Op,
|
||||||
SelectionDAG &DAG) const {
|
SelectionDAG &DAG) const {
|
||||||
if (Op.getOperand(0).getValueType() != MVT::f128) {
|
bool IsStrict = Op->isStrictFPOpcode();
|
||||||
|
SDValue SrcVal = Op.getOperand(IsStrict ? 1 : 0);
|
||||||
|
if (SrcVal.getValueType() != MVT::f128) {
|
||||||
// It's legal except when f128 is involved
|
// It's legal except when f128 is involved
|
||||||
return Op;
|
return Op;
|
||||||
}
|
}
|
||||||
|
|
||||||
RTLIB::Libcall LC;
|
RTLIB::Libcall LC;
|
||||||
LC = RTLIB::getFPROUND(Op.getOperand(0).getValueType(), Op.getValueType());
|
LC = RTLIB::getFPROUND(SrcVal.getValueType(), Op.getValueType());
|
||||||
|
|
||||||
// FP_ROUND node has a second operand indicating whether it is known to be
|
// FP_ROUND node has a second operand indicating whether it is known to be
|
||||||
// precise. That doesn't take part in the LibCall so we can't directly use
|
// precise. That doesn't take part in the LibCall so we can't directly use
|
||||||
// LowerF128Call.
|
// LowerF128Call.
|
||||||
SDValue SrcVal = Op.getOperand(0);
|
|
||||||
MakeLibCallOptions CallOptions;
|
MakeLibCallOptions CallOptions;
|
||||||
return makeLibCall(DAG, LC, Op.getValueType(), SrcVal, CallOptions,
|
SDValue Chain = IsStrict ? Op.getOperand(0) : SDValue();
|
||||||
SDLoc(Op)).first;
|
SDValue Result;
|
||||||
|
SDLoc dl(Op);
|
||||||
|
std::tie(Result, Chain) = makeLibCall(DAG, LC, Op.getValueType(), SrcVal,
|
||||||
|
CallOptions, dl, Chain);
|
||||||
|
return IsStrict ? DAG.getMergeValues({Result, Chain}, dl) : Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDValue AArch64TargetLowering::LowerVectorFP_TO_INT(SDValue Op,
|
SDValue AArch64TargetLowering::LowerVectorFP_TO_INT(SDValue Op,
|
||||||
@ -2542,32 +2589,34 @@ SDValue AArch64TargetLowering::LowerVectorFP_TO_INT(SDValue Op,
|
|||||||
|
|
||||||
SDValue AArch64TargetLowering::LowerFP_TO_INT(SDValue Op,
|
SDValue AArch64TargetLowering::LowerFP_TO_INT(SDValue Op,
|
||||||
SelectionDAG &DAG) const {
|
SelectionDAG &DAG) const {
|
||||||
if (Op.getOperand(0).getValueType().isVector())
|
bool IsStrict = Op->isStrictFPOpcode();
|
||||||
|
SDValue SrcVal = Op.getOperand(IsStrict ? 1 : 0);
|
||||||
|
|
||||||
|
if (SrcVal.getValueType().isVector())
|
||||||
return LowerVectorFP_TO_INT(Op, DAG);
|
return LowerVectorFP_TO_INT(Op, DAG);
|
||||||
|
|
||||||
// f16 conversions are promoted to f32 when full fp16 is not supported.
|
// f16 conversions are promoted to f32 when full fp16 is not supported.
|
||||||
if (Op.getOperand(0).getValueType() == MVT::f16 &&
|
if (SrcVal.getValueType() == MVT::f16 && !Subtarget->hasFullFP16()) {
|
||||||
!Subtarget->hasFullFP16()) {
|
assert(!IsStrict && "Lowering of strict fp16 not yet implemented");
|
||||||
SDLoc dl(Op);
|
SDLoc dl(Op);
|
||||||
return DAG.getNode(
|
return DAG.getNode(
|
||||||
Op.getOpcode(), dl, Op.getValueType(),
|
Op.getOpcode(), dl, Op.getValueType(),
|
||||||
DAG.getNode(ISD::FP_EXTEND, dl, MVT::f32, Op.getOperand(0)));
|
DAG.getNode(ISD::FP_EXTEND, dl, MVT::f32, SrcVal));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Op.getOperand(0).getValueType() != MVT::f128) {
|
if (SrcVal.getValueType() != MVT::f128) {
|
||||||
// It's legal except when f128 is involved
|
// It's legal except when f128 is involved
|
||||||
return Op;
|
return Op;
|
||||||
}
|
}
|
||||||
|
|
||||||
RTLIB::Libcall LC;
|
RTLIB::Libcall LC;
|
||||||
if (Op.getOpcode() == ISD::FP_TO_SINT)
|
if (Op.getOpcode() == ISD::FP_TO_SINT ||
|
||||||
LC = RTLIB::getFPTOSINT(Op.getOperand(0).getValueType(), Op.getValueType());
|
Op.getOpcode() == ISD::STRICT_FP_TO_SINT)
|
||||||
|
LC = RTLIB::getFPTOSINT(SrcVal.getValueType(), Op.getValueType());
|
||||||
else
|
else
|
||||||
LC = RTLIB::getFPTOUINT(Op.getOperand(0).getValueType(), Op.getValueType());
|
LC = RTLIB::getFPTOUINT(SrcVal.getValueType(), Op.getValueType());
|
||||||
|
|
||||||
SmallVector<SDValue, 2> Ops(Op->op_begin(), Op->op_end());
|
return LowerF128Call(Op, DAG, LC);
|
||||||
MakeLibCallOptions CallOptions;
|
|
||||||
return makeLibCall(DAG, LC, Op.getValueType(), Ops, CallOptions, SDLoc(Op)).first;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDValue LowerVectorINT_TO_FP(SDValue Op, SelectionDAG &DAG) {
|
static SDValue LowerVectorINT_TO_FP(SDValue Op, SelectionDAG &DAG) {
|
||||||
@ -2603,18 +2652,22 @@ SDValue AArch64TargetLowering::LowerINT_TO_FP(SDValue Op,
|
|||||||
if (Op.getValueType().isVector())
|
if (Op.getValueType().isVector())
|
||||||
return LowerVectorINT_TO_FP(Op, DAG);
|
return LowerVectorINT_TO_FP(Op, DAG);
|
||||||
|
|
||||||
|
bool IsStrict = Op->isStrictFPOpcode();
|
||||||
|
SDValue SrcVal = Op.getOperand(IsStrict ? 1 : 0);
|
||||||
|
|
||||||
// f16 conversions are promoted to f32 when full fp16 is not supported.
|
// f16 conversions are promoted to f32 when full fp16 is not supported.
|
||||||
if (Op.getValueType() == MVT::f16 &&
|
if (Op.getValueType() == MVT::f16 &&
|
||||||
!Subtarget->hasFullFP16()) {
|
!Subtarget->hasFullFP16()) {
|
||||||
|
assert(!IsStrict && "Lowering of strict fp16 not yet implemented");
|
||||||
SDLoc dl(Op);
|
SDLoc dl(Op);
|
||||||
return DAG.getNode(
|
return DAG.getNode(
|
||||||
ISD::FP_ROUND, dl, MVT::f16,
|
ISD::FP_ROUND, dl, MVT::f16,
|
||||||
DAG.getNode(Op.getOpcode(), dl, MVT::f32, Op.getOperand(0)),
|
DAG.getNode(Op.getOpcode(), dl, MVT::f32, SrcVal),
|
||||||
DAG.getIntPtrConstant(0, dl));
|
DAG.getIntPtrConstant(0, dl));
|
||||||
}
|
}
|
||||||
|
|
||||||
// i128 conversions are libcalls.
|
// i128 conversions are libcalls.
|
||||||
if (Op.getOperand(0).getValueType() == MVT::i128)
|
if (SrcVal.getValueType() == MVT::i128)
|
||||||
return SDValue();
|
return SDValue();
|
||||||
|
|
||||||
// Other conversions are legal, unless it's to the completely software-based
|
// Other conversions are legal, unless it's to the completely software-based
|
||||||
@ -2623,10 +2676,11 @@ SDValue AArch64TargetLowering::LowerINT_TO_FP(SDValue Op,
|
|||||||
return Op;
|
return Op;
|
||||||
|
|
||||||
RTLIB::Libcall LC;
|
RTLIB::Libcall LC;
|
||||||
if (Op.getOpcode() == ISD::SINT_TO_FP)
|
if (Op.getOpcode() == ISD::SINT_TO_FP ||
|
||||||
LC = RTLIB::getSINTTOFP(Op.getOperand(0).getValueType(), Op.getValueType());
|
Op.getOpcode() == ISD::STRICT_SINT_TO_FP)
|
||||||
|
LC = RTLIB::getSINTTOFP(SrcVal.getValueType(), Op.getValueType());
|
||||||
else
|
else
|
||||||
LC = RTLIB::getUINTTOFP(Op.getOperand(0).getValueType(), Op.getValueType());
|
LC = RTLIB::getUINTTOFP(SrcVal.getValueType(), Op.getValueType());
|
||||||
|
|
||||||
return LowerF128Call(Op, DAG, LC);
|
return LowerF128Call(Op, DAG, LC);
|
||||||
}
|
}
|
||||||
@ -3104,6 +3158,8 @@ SDValue AArch64TargetLowering::LowerOperation(SDValue Op,
|
|||||||
case ISD::GlobalTLSAddress:
|
case ISD::GlobalTLSAddress:
|
||||||
return LowerGlobalTLSAddress(Op, DAG);
|
return LowerGlobalTLSAddress(Op, DAG);
|
||||||
case ISD::SETCC:
|
case ISD::SETCC:
|
||||||
|
case ISD::STRICT_FSETCC:
|
||||||
|
case ISD::STRICT_FSETCCS:
|
||||||
return LowerSETCC(Op, DAG);
|
return LowerSETCC(Op, DAG);
|
||||||
case ISD::BR_CC:
|
case ISD::BR_CC:
|
||||||
return LowerBR_CC(Op, DAG);
|
return LowerBR_CC(Op, DAG);
|
||||||
@ -3146,6 +3202,7 @@ SDValue AArch64TargetLowering::LowerOperation(SDValue Op,
|
|||||||
case ISD::FDIV:
|
case ISD::FDIV:
|
||||||
return LowerF128Call(Op, DAG, RTLIB::DIV_F128);
|
return LowerF128Call(Op, DAG, RTLIB::DIV_F128);
|
||||||
case ISD::FP_ROUND:
|
case ISD::FP_ROUND:
|
||||||
|
case ISD::STRICT_FP_ROUND:
|
||||||
return LowerFP_ROUND(Op, DAG);
|
return LowerFP_ROUND(Op, DAG);
|
||||||
case ISD::FP_EXTEND:
|
case ISD::FP_EXTEND:
|
||||||
return LowerFP_EXTEND(Op, DAG);
|
return LowerFP_EXTEND(Op, DAG);
|
||||||
@ -3190,9 +3247,13 @@ SDValue AArch64TargetLowering::LowerOperation(SDValue Op,
|
|||||||
return LowerPREFETCH(Op, DAG);
|
return LowerPREFETCH(Op, DAG);
|
||||||
case ISD::SINT_TO_FP:
|
case ISD::SINT_TO_FP:
|
||||||
case ISD::UINT_TO_FP:
|
case ISD::UINT_TO_FP:
|
||||||
|
case ISD::STRICT_SINT_TO_FP:
|
||||||
|
case ISD::STRICT_UINT_TO_FP:
|
||||||
return LowerINT_TO_FP(Op, DAG);
|
return LowerINT_TO_FP(Op, DAG);
|
||||||
case ISD::FP_TO_SINT:
|
case ISD::FP_TO_SINT:
|
||||||
case ISD::FP_TO_UINT:
|
case ISD::FP_TO_UINT:
|
||||||
|
case ISD::STRICT_FP_TO_SINT:
|
||||||
|
case ISD::STRICT_FP_TO_UINT:
|
||||||
return LowerFP_TO_INT(Op, DAG);
|
return LowerFP_TO_INT(Op, DAG);
|
||||||
case ISD::FSINCOS:
|
case ISD::FSINCOS:
|
||||||
return LowerFSINCOS(Op, DAG);
|
return LowerFSINCOS(Op, DAG);
|
||||||
@ -5154,9 +5215,15 @@ SDValue AArch64TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const {
|
|||||||
if (Op.getValueType().isVector())
|
if (Op.getValueType().isVector())
|
||||||
return LowerVSETCC(Op, DAG);
|
return LowerVSETCC(Op, DAG);
|
||||||
|
|
||||||
SDValue LHS = Op.getOperand(0);
|
bool IsStrict = Op->isStrictFPOpcode();
|
||||||
SDValue RHS = Op.getOperand(1);
|
bool IsSignaling = Op.getOpcode() == ISD::STRICT_FSETCCS;
|
||||||
ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(2))->get();
|
unsigned OpNo = IsStrict ? 1 : 0;
|
||||||
|
SDValue Chain;
|
||||||
|
if (IsStrict)
|
||||||
|
Chain = Op.getOperand(0);
|
||||||
|
SDValue LHS = Op.getOperand(OpNo + 0);
|
||||||
|
SDValue RHS = Op.getOperand(OpNo + 1);
|
||||||
|
ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(OpNo + 2))->get();
|
||||||
SDLoc dl(Op);
|
SDLoc dl(Op);
|
||||||
|
|
||||||
// We chose ZeroOrOneBooleanContents, so use zero and one.
|
// We chose ZeroOrOneBooleanContents, so use zero and one.
|
||||||
@ -5167,13 +5234,14 @@ SDValue AArch64TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const {
|
|||||||
// Handle f128 first, since one possible outcome is a normal integer
|
// Handle f128 first, since one possible outcome is a normal integer
|
||||||
// comparison which gets picked up by the next if statement.
|
// comparison which gets picked up by the next if statement.
|
||||||
if (LHS.getValueType() == MVT::f128) {
|
if (LHS.getValueType() == MVT::f128) {
|
||||||
softenSetCCOperands(DAG, MVT::f128, LHS, RHS, CC, dl, LHS, RHS);
|
softenSetCCOperands(DAG, MVT::f128, LHS, RHS, CC, dl, LHS, RHS, Chain,
|
||||||
|
IsSignaling);
|
||||||
|
|
||||||
// If softenSetCCOperands returned a scalar, use it.
|
// If softenSetCCOperands returned a scalar, use it.
|
||||||
if (!RHS.getNode()) {
|
if (!RHS.getNode()) {
|
||||||
assert(LHS.getValueType() == Op.getValueType() &&
|
assert(LHS.getValueType() == Op.getValueType() &&
|
||||||
"Unexpected setcc expansion!");
|
"Unexpected setcc expansion!");
|
||||||
return LHS;
|
return IsStrict ? DAG.getMergeValues({LHS, Chain}, dl) : LHS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5185,7 +5253,8 @@ SDValue AArch64TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const {
|
|||||||
// Note that we inverted the condition above, so we reverse the order of
|
// Note that we inverted the condition above, so we reverse the order of
|
||||||
// the true and false operands here. This will allow the setcc to be
|
// the true and false operands here. This will allow the setcc to be
|
||||||
// matched to a single CSINC instruction.
|
// matched to a single CSINC instruction.
|
||||||
return DAG.getNode(AArch64ISD::CSEL, dl, VT, FVal, TVal, CCVal, Cmp);
|
SDValue Res = DAG.getNode(AArch64ISD::CSEL, dl, VT, FVal, TVal, CCVal, Cmp);
|
||||||
|
return IsStrict ? DAG.getMergeValues({Res, Chain}, dl) : Res;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now we know we're dealing with FP values.
|
// Now we know we're dealing with FP values.
|
||||||
@ -5194,10 +5263,15 @@ SDValue AArch64TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const {
|
|||||||
|
|
||||||
// If that fails, we'll need to perform an FCMP + CSEL sequence. Go ahead
|
// If that fails, we'll need to perform an FCMP + CSEL sequence. Go ahead
|
||||||
// and do the comparison.
|
// and do the comparison.
|
||||||
SDValue Cmp = emitComparison(LHS, RHS, CC, dl, DAG);
|
SDValue Cmp;
|
||||||
|
if (IsStrict)
|
||||||
|
Cmp = emitStrictFPComparison(LHS, RHS, dl, DAG, Chain, IsSignaling);
|
||||||
|
else
|
||||||
|
Cmp = emitComparison(LHS, RHS, CC, dl, DAG);
|
||||||
|
|
||||||
AArch64CC::CondCode CC1, CC2;
|
AArch64CC::CondCode CC1, CC2;
|
||||||
changeFPCCToAArch64CC(CC, CC1, CC2);
|
changeFPCCToAArch64CC(CC, CC1, CC2);
|
||||||
|
SDValue Res;
|
||||||
if (CC2 == AArch64CC::AL) {
|
if (CC2 == AArch64CC::AL) {
|
||||||
changeFPCCToAArch64CC(ISD::getSetCCInverse(CC, LHS.getValueType()), CC1,
|
changeFPCCToAArch64CC(ISD::getSetCCInverse(CC, LHS.getValueType()), CC1,
|
||||||
CC2);
|
CC2);
|
||||||
@ -5206,7 +5280,7 @@ SDValue AArch64TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const {
|
|||||||
// Note that we inverted the condition above, so we reverse the order of
|
// Note that we inverted the condition above, so we reverse the order of
|
||||||
// the true and false operands here. This will allow the setcc to be
|
// the true and false operands here. This will allow the setcc to be
|
||||||
// matched to a single CSINC instruction.
|
// matched to a single CSINC instruction.
|
||||||
return DAG.getNode(AArch64ISD::CSEL, dl, VT, FVal, TVal, CC1Val, Cmp);
|
Res = DAG.getNode(AArch64ISD::CSEL, dl, VT, FVal, TVal, CC1Val, Cmp);
|
||||||
} else {
|
} else {
|
||||||
// Unfortunately, the mapping of LLVM FP CC's onto AArch64 CC's isn't
|
// Unfortunately, the mapping of LLVM FP CC's onto AArch64 CC's isn't
|
||||||
// totally clean. Some of them require two CSELs to implement. As is in
|
// totally clean. Some of them require two CSELs to implement. As is in
|
||||||
@ -5219,8 +5293,9 @@ SDValue AArch64TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const {
|
|||||||
DAG.getNode(AArch64ISD::CSEL, dl, VT, TVal, FVal, CC1Val, Cmp);
|
DAG.getNode(AArch64ISD::CSEL, dl, VT, TVal, FVal, CC1Val, Cmp);
|
||||||
|
|
||||||
SDValue CC2Val = DAG.getConstant(CC2, dl, MVT::i32);
|
SDValue CC2Val = DAG.getConstant(CC2, dl, MVT::i32);
|
||||||
return DAG.getNode(AArch64ISD::CSEL, dl, VT, TVal, CS1, CC2Val, Cmp);
|
Res = DAG.getNode(AArch64ISD::CSEL, dl, VT, TVal, CS1, CC2Val, Cmp);
|
||||||
}
|
}
|
||||||
|
return IsStrict ? DAG.getMergeValues({Res, Cmp.getValue(1)}, dl) : Res;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDValue AArch64TargetLowering::LowerSELECT_CC(ISD::CondCode CC, SDValue LHS,
|
SDValue AArch64TargetLowering::LowerSELECT_CC(ISD::CondCode CC, SDValue LHS,
|
||||||
|
@ -241,6 +241,10 @@ enum NodeType : unsigned {
|
|||||||
SST1_SXTW_SCALED,
|
SST1_SXTW_SCALED,
|
||||||
SST1_IMM,
|
SST1_IMM,
|
||||||
|
|
||||||
|
// Strict (exception-raising) floating point comparison
|
||||||
|
STRICT_FCMP = ISD::FIRST_TARGET_STRICTFP_OPCODE,
|
||||||
|
STRICT_FCMPE,
|
||||||
|
|
||||||
// NEON Load/Store with post-increment base updates
|
// NEON Load/Store with post-increment base updates
|
||||||
LD2post = ISD::FIRST_TARGET_MEMORY_OPCODE,
|
LD2post = ISD::FIRST_TARGET_MEMORY_OPCODE,
|
||||||
LD3post,
|
LD3post,
|
||||||
|
@ -4702,11 +4702,11 @@ class BaseFPConversion<bits<2> type, bits<2> opcode, RegisterClass dstType,
|
|||||||
multiclass FPConversion<string asm> {
|
multiclass FPConversion<string asm> {
|
||||||
// Double-precision to Half-precision
|
// Double-precision to Half-precision
|
||||||
def HDr : BaseFPConversion<0b01, 0b11, FPR16, FPR64, asm,
|
def HDr : BaseFPConversion<0b01, 0b11, FPR16, FPR64, asm,
|
||||||
[(set FPR16:$Rd, (fpround FPR64:$Rn))]>;
|
[(set FPR16:$Rd, (any_fpround FPR64:$Rn))]>;
|
||||||
|
|
||||||
// Double-precision to Single-precision
|
// Double-precision to Single-precision
|
||||||
def SDr : BaseFPConversion<0b01, 0b00, FPR32, FPR64, asm,
|
def SDr : BaseFPConversion<0b01, 0b00, FPR32, FPR64, asm,
|
||||||
[(set FPR32:$Rd, (fpround FPR64:$Rn))]>;
|
[(set FPR32:$Rd, (any_fpround FPR64:$Rn))]>;
|
||||||
|
|
||||||
// Half-precision to Double-precision
|
// Half-precision to Double-precision
|
||||||
def DHr : BaseFPConversion<0b11, 0b01, FPR64, FPR16, asm,
|
def DHr : BaseFPConversion<0b11, 0b01, FPR64, FPR16, asm,
|
||||||
@ -4722,7 +4722,7 @@ multiclass FPConversion<string asm> {
|
|||||||
|
|
||||||
// Single-precision to Half-precision
|
// Single-precision to Half-precision
|
||||||
def HSr : BaseFPConversion<0b00, 0b11, FPR16, FPR32, asm,
|
def HSr : BaseFPConversion<0b00, 0b11, FPR16, FPR32, asm,
|
||||||
[(set FPR16:$Rd, (fpround FPR32:$Rn))]>;
|
[(set FPR16:$Rd, (any_fpround FPR32:$Rn))]>;
|
||||||
}
|
}
|
||||||
|
|
||||||
//---
|
//---
|
||||||
|
@ -419,7 +419,14 @@ def AArch64fccmp : SDNode<"AArch64ISD::FCCMP", SDT_AArch64FCCMP>;
|
|||||||
|
|
||||||
def AArch64threadpointer : SDNode<"AArch64ISD::THREAD_POINTER", SDTPtrLeaf>;
|
def AArch64threadpointer : SDNode<"AArch64ISD::THREAD_POINTER", SDTPtrLeaf>;
|
||||||
|
|
||||||
def AArch64fcmp : SDNode<"AArch64ISD::FCMP", SDT_AArch64FCmp>;
|
def AArch64fcmp : SDNode<"AArch64ISD::FCMP", SDT_AArch64FCmp>;
|
||||||
|
def AArch64strict_fcmp : SDNode<"AArch64ISD::STRICT_FCMP", SDT_AArch64FCmp,
|
||||||
|
[SDNPHasChain]>;
|
||||||
|
def AArch64strict_fcmpe : SDNode<"AArch64ISD::STRICT_FCMPE", SDT_AArch64FCmp,
|
||||||
|
[SDNPHasChain]>;
|
||||||
|
def AArch64any_fcmp : PatFrags<(ops node:$lhs, node:$rhs),
|
||||||
|
[(AArch64strict_fcmp node:$lhs, node:$rhs),
|
||||||
|
(AArch64fcmp node:$lhs, node:$rhs)]>;
|
||||||
|
|
||||||
def AArch64dup : SDNode<"AArch64ISD::DUP", SDT_AArch64Dup>;
|
def AArch64dup : SDNode<"AArch64ISD::DUP", SDT_AArch64Dup>;
|
||||||
def AArch64duplane8 : SDNode<"AArch64ISD::DUPLANE8", SDT_AArch64DupLane>;
|
def AArch64duplane8 : SDNode<"AArch64ISD::DUPLANE8", SDT_AArch64DupLane>;
|
||||||
@ -3300,10 +3307,10 @@ defm FCVTNS : FPToIntegerUnscaled<0b00, 0b000, "fcvtns", int_aarch64_neon_fcvtns
|
|||||||
defm FCVTNU : FPToIntegerUnscaled<0b00, 0b001, "fcvtnu", int_aarch64_neon_fcvtnu>;
|
defm FCVTNU : FPToIntegerUnscaled<0b00, 0b001, "fcvtnu", int_aarch64_neon_fcvtnu>;
|
||||||
defm FCVTPS : FPToIntegerUnscaled<0b01, 0b000, "fcvtps", int_aarch64_neon_fcvtps>;
|
defm FCVTPS : FPToIntegerUnscaled<0b01, 0b000, "fcvtps", int_aarch64_neon_fcvtps>;
|
||||||
defm FCVTPU : FPToIntegerUnscaled<0b01, 0b001, "fcvtpu", int_aarch64_neon_fcvtpu>;
|
defm FCVTPU : FPToIntegerUnscaled<0b01, 0b001, "fcvtpu", int_aarch64_neon_fcvtpu>;
|
||||||
defm FCVTZS : FPToIntegerUnscaled<0b11, 0b000, "fcvtzs", fp_to_sint>;
|
defm FCVTZS : FPToIntegerUnscaled<0b11, 0b000, "fcvtzs", any_fp_to_sint>;
|
||||||
defm FCVTZU : FPToIntegerUnscaled<0b11, 0b001, "fcvtzu", fp_to_uint>;
|
defm FCVTZU : FPToIntegerUnscaled<0b11, 0b001, "fcvtzu", any_fp_to_uint>;
|
||||||
defm FCVTZS : FPToIntegerScaled<0b11, 0b000, "fcvtzs", fp_to_sint>;
|
defm FCVTZS : FPToIntegerScaled<0b11, 0b000, "fcvtzs", any_fp_to_sint>;
|
||||||
defm FCVTZU : FPToIntegerScaled<0b11, 0b001, "fcvtzu", fp_to_uint>;
|
defm FCVTZU : FPToIntegerScaled<0b11, 0b001, "fcvtzu", any_fp_to_uint>;
|
||||||
|
|
||||||
multiclass FPToIntegerIntPats<Intrinsic round, string INST> {
|
multiclass FPToIntegerIntPats<Intrinsic round, string INST> {
|
||||||
def : Pat<(i32 (round f16:$Rn)), (!cast<Instruction>(INST # UWHr) $Rn)>;
|
def : Pat<(i32 (round f16:$Rn)), (!cast<Instruction>(INST # UWHr) $Rn)>;
|
||||||
@ -3375,8 +3382,8 @@ def : Pat<(i64 (llround f64:$Rn)),
|
|||||||
// Scaled integer to floating point conversion instructions.
|
// Scaled integer to floating point conversion instructions.
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
defm SCVTF : IntegerToFP<0, "scvtf", sint_to_fp>;
|
defm SCVTF : IntegerToFP<0, "scvtf", any_sint_to_fp>;
|
||||||
defm UCVTF : IntegerToFP<1, "ucvtf", uint_to_fp>;
|
defm UCVTF : IntegerToFP<1, "ucvtf", any_uint_to_fp>;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Unscaled integer to floating point conversion instruction.
|
// Unscaled integer to floating point conversion instruction.
|
||||||
@ -3541,8 +3548,8 @@ def : Pat<(f64 (fma FPR64:$Rn, (fneg FPR64:$Rm), (fneg FPR64:$Ra))),
|
|||||||
// Floating point comparison instructions.
|
// Floating point comparison instructions.
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
defm FCMPE : FPComparison<1, "fcmpe">;
|
defm FCMPE : FPComparison<1, "fcmpe", AArch64strict_fcmpe>;
|
||||||
defm FCMP : FPComparison<0, "fcmp", AArch64fcmp>;
|
defm FCMP : FPComparison<0, "fcmp", AArch64any_fcmp>;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Floating point conditional comparison instructions.
|
// Floating point conditional comparison instructions.
|
||||||
|
@ -244,11 +244,6 @@ static raw_ostream& operator<<(raw_ostream &OS, const DstUnused &Un) {
|
|||||||
return OS;
|
return OS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static raw_ostream& operator<<(raw_ostream &OS, const SDWAOperand &Operand) {
|
|
||||||
Operand.print(OS);
|
|
||||||
return OS;
|
|
||||||
}
|
|
||||||
|
|
||||||
LLVM_DUMP_METHOD
|
LLVM_DUMP_METHOD
|
||||||
void SDWASrcOperand::print(raw_ostream& OS) const {
|
void SDWASrcOperand::print(raw_ostream& OS) const {
|
||||||
OS << "SDWA src: " << *getTargetOperand()
|
OS << "SDWA src: " << *getTargetOperand()
|
||||||
@ -850,6 +845,13 @@ SIPeepholeSDWA::matchSDWAOperand(MachineInstr &MI) {
|
|||||||
return std::unique_ptr<SDWAOperand>(nullptr);
|
return std::unique_ptr<SDWAOperand>(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined(NDEBUG)
|
||||||
|
static raw_ostream& operator<<(raw_ostream &OS, const SDWAOperand &Operand) {
|
||||||
|
Operand.print(OS);
|
||||||
|
return OS;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void SIPeepholeSDWA::matchSDWAOperands(MachineBasicBlock &MBB) {
|
void SIPeepholeSDWA::matchSDWAOperands(MachineBasicBlock &MBB) {
|
||||||
for (MachineInstr &MI : MBB) {
|
for (MachineInstr &MI : MBB) {
|
||||||
if (auto Operand = matchSDWAOperand(MI)) {
|
if (auto Operand = matchSDWAOperand(MI)) {
|
||||||
|
@ -1354,6 +1354,14 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM,
|
|||||||
setOperationAction(ISD::FP16_TO_FP, MVT::f32, Expand);
|
setOperationAction(ISD::FP16_TO_FP, MVT::f32, Expand);
|
||||||
setOperationAction(ISD::FP_TO_FP16, MVT::f32, Expand);
|
setOperationAction(ISD::FP_TO_FP16, MVT::f32, Expand);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Strict floating-point comparisons need custom lowering.
|
||||||
|
setOperationAction(ISD::STRICT_FSETCC, MVT::f16, Custom);
|
||||||
|
setOperationAction(ISD::STRICT_FSETCCS, MVT::f16, Custom);
|
||||||
|
setOperationAction(ISD::STRICT_FSETCC, MVT::f32, Custom);
|
||||||
|
setOperationAction(ISD::STRICT_FSETCCS, MVT::f32, Custom);
|
||||||
|
setOperationAction(ISD::STRICT_FSETCC, MVT::f64, Custom);
|
||||||
|
setOperationAction(ISD::STRICT_FSETCCS, MVT::f64, Custom);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use __sincos_stret if available.
|
// Use __sincos_stret if available.
|
||||||
@ -1552,7 +1560,9 @@ const char *ARMTargetLowering::getTargetNodeName(unsigned Opcode) const {
|
|||||||
case ARMISD::CMN: return "ARMISD::CMN";
|
case ARMISD::CMN: return "ARMISD::CMN";
|
||||||
case ARMISD::CMPZ: return "ARMISD::CMPZ";
|
case ARMISD::CMPZ: return "ARMISD::CMPZ";
|
||||||
case ARMISD::CMPFP: return "ARMISD::CMPFP";
|
case ARMISD::CMPFP: return "ARMISD::CMPFP";
|
||||||
|
case ARMISD::CMPFPE: return "ARMISD::CMPFPE";
|
||||||
case ARMISD::CMPFPw0: return "ARMISD::CMPFPw0";
|
case ARMISD::CMPFPw0: return "ARMISD::CMPFPw0";
|
||||||
|
case ARMISD::CMPFPEw0: return "ARMISD::CMPFPEw0";
|
||||||
case ARMISD::BCC_i64: return "ARMISD::BCC_i64";
|
case ARMISD::BCC_i64: return "ARMISD::BCC_i64";
|
||||||
case ARMISD::FMSTAT: return "ARMISD::FMSTAT";
|
case ARMISD::FMSTAT: return "ARMISD::FMSTAT";
|
||||||
|
|
||||||
@ -4344,13 +4354,16 @@ SDValue ARMTargetLowering::getARMCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,
|
|||||||
|
|
||||||
/// Returns a appropriate VFP CMP (fcmp{s|d}+fmstat) for the given operands.
|
/// Returns a appropriate VFP CMP (fcmp{s|d}+fmstat) for the given operands.
|
||||||
SDValue ARMTargetLowering::getVFPCmp(SDValue LHS, SDValue RHS,
|
SDValue ARMTargetLowering::getVFPCmp(SDValue LHS, SDValue RHS,
|
||||||
SelectionDAG &DAG, const SDLoc &dl) const {
|
SelectionDAG &DAG, const SDLoc &dl,
|
||||||
|
bool Signaling) const {
|
||||||
assert(Subtarget->hasFP64() || RHS.getValueType() != MVT::f64);
|
assert(Subtarget->hasFP64() || RHS.getValueType() != MVT::f64);
|
||||||
SDValue Cmp;
|
SDValue Cmp;
|
||||||
if (!isFloatingPointZero(RHS))
|
if (!isFloatingPointZero(RHS))
|
||||||
Cmp = DAG.getNode(ARMISD::CMPFP, dl, MVT::Glue, LHS, RHS);
|
Cmp = DAG.getNode(Signaling ? ARMISD::CMPFPE : ARMISD::CMPFP,
|
||||||
|
dl, MVT::Glue, LHS, RHS);
|
||||||
else
|
else
|
||||||
Cmp = DAG.getNode(ARMISD::CMPFPw0, dl, MVT::Glue, LHS);
|
Cmp = DAG.getNode(Signaling ? ARMISD::CMPFPEw0 : ARMISD::CMPFPw0,
|
||||||
|
dl, MVT::Glue, LHS);
|
||||||
return DAG.getNode(ARMISD::FMSTAT, dl, MVT::Glue, Cmp);
|
return DAG.getNode(ARMISD::FMSTAT, dl, MVT::Glue, Cmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5408,7 +5421,12 @@ SDValue ARMTargetLowering::LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG) const {
|
|||||||
|
|
||||||
// FIXME: Remove this when we have strict fp instruction selection patterns
|
// FIXME: Remove this when we have strict fp instruction selection patterns
|
||||||
if (IsStrict) {
|
if (IsStrict) {
|
||||||
DAG.mutateStrictFPToFP(Op.getNode());
|
SDLoc Loc(Op);
|
||||||
|
SDValue Result =
|
||||||
|
DAG.getNode(Op.getOpcode() == ISD::STRICT_FP_TO_SINT ? ISD::FP_TO_SINT
|
||||||
|
: ISD::FP_TO_UINT,
|
||||||
|
Loc, Op.getValueType(), SrcVal);
|
||||||
|
return DAG.getMergeValues({Result, Op.getOperand(0)}, Loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Op;
|
return Op;
|
||||||
@ -9222,6 +9240,51 @@ static void ReplaceCMP_SWAP_64Results(SDNode *N,
|
|||||||
Results.push_back(SDValue(CmpSwap, 2));
|
Results.push_back(SDValue(CmpSwap, 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SDValue ARMTargetLowering::LowerFSETCC(SDValue Op, SelectionDAG &DAG) const {
|
||||||
|
SDLoc dl(Op);
|
||||||
|
EVT VT = Op.getValueType();
|
||||||
|
SDValue Chain = Op.getOperand(0);
|
||||||
|
SDValue LHS = Op.getOperand(1);
|
||||||
|
SDValue RHS = Op.getOperand(2);
|
||||||
|
ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(3))->get();
|
||||||
|
bool IsSignaling = Op.getOpcode() == ISD::STRICT_FSETCCS;
|
||||||
|
|
||||||
|
// If we don't have instructions of this float type then soften to a libcall
|
||||||
|
// and use SETCC instead.
|
||||||
|
if (isUnsupportedFloatingType(LHS.getValueType())) {
|
||||||
|
DAG.getTargetLoweringInfo().softenSetCCOperands(
|
||||||
|
DAG, LHS.getValueType(), LHS, RHS, CC, dl, LHS, RHS, Chain, IsSignaling);
|
||||||
|
if (!RHS.getNode()) {
|
||||||
|
RHS = DAG.getConstant(0, dl, LHS.getValueType());
|
||||||
|
CC = ISD::SETNE;
|
||||||
|
}
|
||||||
|
SDValue Result = DAG.getNode(ISD::SETCC, dl, VT, LHS, RHS,
|
||||||
|
DAG.getCondCode(CC));
|
||||||
|
return DAG.getMergeValues({Result, Chain}, dl);
|
||||||
|
}
|
||||||
|
|
||||||
|
ARMCC::CondCodes CondCode, CondCode2;
|
||||||
|
FPCCToARMCC(CC, CondCode, CondCode2);
|
||||||
|
|
||||||
|
// FIXME: Chain is not handled correctly here. Currently the FPSCR is implicit
|
||||||
|
// in CMPFP and CMPFPE, but instead it should be made explicit by these
|
||||||
|
// instructions using a chain instead of glue. This would also fix the problem
|
||||||
|
// here (and also in LowerSELECT_CC) where we generate two comparisons when
|
||||||
|
// CondCode2 != AL.
|
||||||
|
SDValue True = DAG.getConstant(1, dl, VT);
|
||||||
|
SDValue False = DAG.getConstant(0, dl, VT);
|
||||||
|
SDValue ARMcc = DAG.getConstant(CondCode, dl, MVT::i32);
|
||||||
|
SDValue CCR = DAG.getRegister(ARM::CPSR, MVT::i32);
|
||||||
|
SDValue Cmp = getVFPCmp(LHS, RHS, DAG, dl, IsSignaling);
|
||||||
|
SDValue Result = getCMOV(dl, VT, False, True, ARMcc, CCR, Cmp, DAG);
|
||||||
|
if (CondCode2 != ARMCC::AL) {
|
||||||
|
ARMcc = DAG.getConstant(CondCode2, dl, MVT::i32);
|
||||||
|
Cmp = getVFPCmp(LHS, RHS, DAG, dl, IsSignaling);
|
||||||
|
Result = getCMOV(dl, VT, Result, True, ARMcc, CCR, Cmp, DAG);
|
||||||
|
}
|
||||||
|
return DAG.getMergeValues({Result, Chain}, dl);
|
||||||
|
}
|
||||||
|
|
||||||
SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
|
SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
|
||||||
LLVM_DEBUG(dbgs() << "Lowering node: "; Op.dump());
|
LLVM_DEBUG(dbgs() << "Lowering node: "; Op.dump());
|
||||||
switch (Op.getOpcode()) {
|
switch (Op.getOpcode()) {
|
||||||
@ -9315,6 +9378,8 @@ SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
|
|||||||
case ISD::FP_ROUND: return LowerFP_ROUND(Op, DAG);
|
case ISD::FP_ROUND: return LowerFP_ROUND(Op, DAG);
|
||||||
case ISD::STRICT_FP_EXTEND:
|
case ISD::STRICT_FP_EXTEND:
|
||||||
case ISD::FP_EXTEND: return LowerFP_EXTEND(Op, DAG);
|
case ISD::FP_EXTEND: return LowerFP_EXTEND(Op, DAG);
|
||||||
|
case ISD::STRICT_FSETCC:
|
||||||
|
case ISD::STRICT_FSETCCS: return LowerFSETCC(Op, DAG);
|
||||||
case ARMISD::WIN__DBZCHK: return SDValue();
|
case ARMISD::WIN__DBZCHK: return SDValue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -16320,6 +16385,18 @@ SDValue ARMTargetLowering::LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const {
|
|||||||
assert(!(DstSz == 32 && Subtarget->hasFP16()) &&
|
assert(!(DstSz == 32 && Subtarget->hasFP16()) &&
|
||||||
"With FP16, 16 to 32 conversion is legal!");
|
"With FP16, 16 to 32 conversion is legal!");
|
||||||
|
|
||||||
|
// Converting from 32 -> 64 is valid if we have FP64.
|
||||||
|
if (SrcSz == 32 && DstSz == 64 && Subtarget->hasFP64()) {
|
||||||
|
// FIXME: Remove this when we have strict fp instruction selection patterns
|
||||||
|
if (IsStrict) {
|
||||||
|
SDLoc Loc(Op);
|
||||||
|
SDValue Result = DAG.getNode(ISD::FP_EXTEND,
|
||||||
|
Loc, Op.getValueType(), SrcVal);
|
||||||
|
return DAG.getMergeValues({Result, Op.getOperand(0)}, Loc);
|
||||||
|
}
|
||||||
|
return Op;
|
||||||
|
}
|
||||||
|
|
||||||
// Either we are converting from 16 -> 64, without FP16 and/or
|
// Either we are converting from 16 -> 64, without FP16 and/or
|
||||||
// FP.double-precision or without Armv8-fp. So we must do it in two
|
// FP.double-precision or without Armv8-fp. So we must do it in two
|
||||||
// steps.
|
// steps.
|
||||||
@ -16815,7 +16892,7 @@ bool ARMTargetLowering::isCheapToSpeculateCtlz() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool ARMTargetLowering::shouldExpandShift(SelectionDAG &DAG, SDNode *N) const {
|
bool ARMTargetLowering::shouldExpandShift(SelectionDAG &DAG, SDNode *N) const {
|
||||||
return !Subtarget->hasMinSize();
|
return !Subtarget->hasMinSize() || Subtarget->isTargetWindows();
|
||||||
}
|
}
|
||||||
|
|
||||||
Value *ARMTargetLowering::emitLoadLinked(IRBuilder<> &Builder, Value *Addr,
|
Value *ARMTargetLowering::emitLoadLinked(IRBuilder<> &Builder, Value *Addr,
|
||||||
|
@ -84,7 +84,9 @@ class VectorType;
|
|||||||
CMN, // ARM CMN instructions.
|
CMN, // ARM CMN instructions.
|
||||||
CMPZ, // ARM compare that sets only Z flag.
|
CMPZ, // ARM compare that sets only Z flag.
|
||||||
CMPFP, // ARM VFP compare instruction, sets FPSCR.
|
CMPFP, // ARM VFP compare instruction, sets FPSCR.
|
||||||
|
CMPFPE, // ARM VFP signalling compare instruction, sets FPSCR.
|
||||||
CMPFPw0, // ARM VFP compare against zero instruction, sets FPSCR.
|
CMPFPw0, // ARM VFP compare against zero instruction, sets FPSCR.
|
||||||
|
CMPFPEw0, // ARM VFP signalling compare against zero instruction, sets FPSCR.
|
||||||
FMSTAT, // ARM fmstat instruction.
|
FMSTAT, // ARM fmstat instruction.
|
||||||
|
|
||||||
CMOV, // ARM conditional move instructions.
|
CMOV, // ARM conditional move instructions.
|
||||||
@ -729,6 +731,7 @@ class VectorType;
|
|||||||
SDValue LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const;
|
SDValue LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const;
|
||||||
SDValue LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG) const;
|
SDValue LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG) const;
|
||||||
SDValue LowerINT_TO_FP(SDValue Op, SelectionDAG &DAG) const;
|
SDValue LowerINT_TO_FP(SDValue Op, SelectionDAG &DAG) const;
|
||||||
|
SDValue LowerFSETCC(SDValue Op, SelectionDAG &DAG) const;
|
||||||
void lowerABS(SDNode *N, SmallVectorImpl<SDValue> &Results,
|
void lowerABS(SDNode *N, SmallVectorImpl<SDValue> &Results,
|
||||||
SelectionDAG &DAG) const;
|
SelectionDAG &DAG) const;
|
||||||
|
|
||||||
@ -817,7 +820,7 @@ class VectorType;
|
|||||||
SDValue getARMCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,
|
SDValue getARMCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,
|
||||||
SDValue &ARMcc, SelectionDAG &DAG, const SDLoc &dl) const;
|
SDValue &ARMcc, SelectionDAG &DAG, const SDLoc &dl) const;
|
||||||
SDValue getVFPCmp(SDValue LHS, SDValue RHS, SelectionDAG &DAG,
|
SDValue getVFPCmp(SDValue LHS, SDValue RHS, SelectionDAG &DAG,
|
||||||
const SDLoc &dl) const;
|
const SDLoc &dl, bool Signaling = false) const;
|
||||||
SDValue duplicateCmp(SDValue Cmp, SelectionDAG &DAG) const;
|
SDValue duplicateCmp(SDValue Cmp, SelectionDAG &DAG) const;
|
||||||
|
|
||||||
SDValue OptimizeVFPBrcond(SDValue Op, SelectionDAG &DAG) const;
|
SDValue OptimizeVFPBrcond(SDValue Op, SelectionDAG &DAG) const;
|
||||||
|
@ -21,6 +21,8 @@ def SDT_VMOVSR : SDTypeProfile<1, 1, [SDTCisVT<0, f32>, SDTCisVT<1, i32>]>;
|
|||||||
def arm_fmstat : SDNode<"ARMISD::FMSTAT", SDTNone, [SDNPInGlue, SDNPOutGlue]>;
|
def arm_fmstat : SDNode<"ARMISD::FMSTAT", SDTNone, [SDNPInGlue, SDNPOutGlue]>;
|
||||||
def arm_cmpfp : SDNode<"ARMISD::CMPFP", SDT_ARMCmp, [SDNPOutGlue]>;
|
def arm_cmpfp : SDNode<"ARMISD::CMPFP", SDT_ARMCmp, [SDNPOutGlue]>;
|
||||||
def arm_cmpfp0 : SDNode<"ARMISD::CMPFPw0", SDT_CMPFP0, [SDNPOutGlue]>;
|
def arm_cmpfp0 : SDNode<"ARMISD::CMPFPw0", SDT_CMPFP0, [SDNPOutGlue]>;
|
||||||
|
def arm_cmpfpe : SDNode<"ARMISD::CMPFPE", SDT_ARMCmp, [SDNPOutGlue]>;
|
||||||
|
def arm_cmpfpe0: SDNode<"ARMISD::CMPFPEw0",SDT_CMPFP0, [SDNPOutGlue]>;
|
||||||
def arm_fmdrr : SDNode<"ARMISD::VMOVDRR", SDT_VMOVDRR>;
|
def arm_fmdrr : SDNode<"ARMISD::VMOVDRR", SDT_VMOVDRR>;
|
||||||
def arm_fmrrd : SDNode<"ARMISD::VMOVRRD", SDT_VMOVRRD>;
|
def arm_fmrrd : SDNode<"ARMISD::VMOVRRD", SDT_VMOVRRD>;
|
||||||
def arm_vmovsr : SDNode<"ARMISD::VMOVSR", SDT_VMOVSR>;
|
def arm_vmovsr : SDNode<"ARMISD::VMOVSR", SDT_VMOVSR>;
|
||||||
@ -548,12 +550,12 @@ let Defs = [FPSCR_NZCV] in {
|
|||||||
def VCMPED : ADuI<0b11101, 0b11, 0b0100, 0b11, 0,
|
def VCMPED : ADuI<0b11101, 0b11, 0b0100, 0b11, 0,
|
||||||
(outs), (ins DPR:$Dd, DPR:$Dm),
|
(outs), (ins DPR:$Dd, DPR:$Dm),
|
||||||
IIC_fpCMP64, "vcmpe", ".f64\t$Dd, $Dm",
|
IIC_fpCMP64, "vcmpe", ".f64\t$Dd, $Dm",
|
||||||
[/* For disassembly only; pattern left blank */]>;
|
[(arm_cmpfpe DPR:$Dd, (f64 DPR:$Dm))]>;
|
||||||
|
|
||||||
def VCMPES : ASuI<0b11101, 0b11, 0b0100, 0b11, 0,
|
def VCMPES : ASuI<0b11101, 0b11, 0b0100, 0b11, 0,
|
||||||
(outs), (ins SPR:$Sd, SPR:$Sm),
|
(outs), (ins SPR:$Sd, SPR:$Sm),
|
||||||
IIC_fpCMP32, "vcmpe", ".f32\t$Sd, $Sm",
|
IIC_fpCMP32, "vcmpe", ".f32\t$Sd, $Sm",
|
||||||
[/* For disassembly only; pattern left blank */]> {
|
[(arm_cmpfpe SPR:$Sd, SPR:$Sm)]> {
|
||||||
// Some single precision VFP instructions may be executed on both NEON and
|
// Some single precision VFP instructions may be executed on both NEON and
|
||||||
// VFP pipelines on A8.
|
// VFP pipelines on A8.
|
||||||
let D = VFPNeonA8Domain;
|
let D = VFPNeonA8Domain;
|
||||||
@ -562,7 +564,7 @@ def VCMPES : ASuI<0b11101, 0b11, 0b0100, 0b11, 0,
|
|||||||
def VCMPEH : AHuI<0b11101, 0b11, 0b0100, 0b11, 0,
|
def VCMPEH : AHuI<0b11101, 0b11, 0b0100, 0b11, 0,
|
||||||
(outs), (ins HPR:$Sd, HPR:$Sm),
|
(outs), (ins HPR:$Sd, HPR:$Sm),
|
||||||
IIC_fpCMP16, "vcmpe", ".f16\t$Sd, $Sm",
|
IIC_fpCMP16, "vcmpe", ".f16\t$Sd, $Sm",
|
||||||
[/* For disassembly only; pattern left blank */]>;
|
[(arm_cmpfpe HPR:$Sd, HPR:$Sm)]>;
|
||||||
|
|
||||||
def VCMPD : ADuI<0b11101, 0b11, 0b0100, 0b01, 0,
|
def VCMPD : ADuI<0b11101, 0b11, 0b0100, 0b01, 0,
|
||||||
(outs), (ins DPR:$Dd, DPR:$Dm),
|
(outs), (ins DPR:$Dd, DPR:$Dm),
|
||||||
@ -611,7 +613,7 @@ let Defs = [FPSCR_NZCV] in {
|
|||||||
def VCMPEZD : ADuI<0b11101, 0b11, 0b0101, 0b11, 0,
|
def VCMPEZD : ADuI<0b11101, 0b11, 0b0101, 0b11, 0,
|
||||||
(outs), (ins DPR:$Dd),
|
(outs), (ins DPR:$Dd),
|
||||||
IIC_fpCMP64, "vcmpe", ".f64\t$Dd, #0",
|
IIC_fpCMP64, "vcmpe", ".f64\t$Dd, #0",
|
||||||
[/* For disassembly only; pattern left blank */]> {
|
[(arm_cmpfpe0 (f64 DPR:$Dd))]> {
|
||||||
let Inst{3-0} = 0b0000;
|
let Inst{3-0} = 0b0000;
|
||||||
let Inst{5} = 0;
|
let Inst{5} = 0;
|
||||||
}
|
}
|
||||||
@ -619,7 +621,7 @@ def VCMPEZD : ADuI<0b11101, 0b11, 0b0101, 0b11, 0,
|
|||||||
def VCMPEZS : ASuI<0b11101, 0b11, 0b0101, 0b11, 0,
|
def VCMPEZS : ASuI<0b11101, 0b11, 0b0101, 0b11, 0,
|
||||||
(outs), (ins SPR:$Sd),
|
(outs), (ins SPR:$Sd),
|
||||||
IIC_fpCMP32, "vcmpe", ".f32\t$Sd, #0",
|
IIC_fpCMP32, "vcmpe", ".f32\t$Sd, #0",
|
||||||
[/* For disassembly only; pattern left blank */]> {
|
[(arm_cmpfpe0 SPR:$Sd)]> {
|
||||||
let Inst{3-0} = 0b0000;
|
let Inst{3-0} = 0b0000;
|
||||||
let Inst{5} = 0;
|
let Inst{5} = 0;
|
||||||
|
|
||||||
@ -631,7 +633,7 @@ def VCMPEZS : ASuI<0b11101, 0b11, 0b0101, 0b11, 0,
|
|||||||
def VCMPEZH : AHuI<0b11101, 0b11, 0b0101, 0b11, 0,
|
def VCMPEZH : AHuI<0b11101, 0b11, 0b0101, 0b11, 0,
|
||||||
(outs), (ins HPR:$Sd),
|
(outs), (ins HPR:$Sd),
|
||||||
IIC_fpCMP16, "vcmpe", ".f16\t$Sd, #0",
|
IIC_fpCMP16, "vcmpe", ".f16\t$Sd, #0",
|
||||||
[/* For disassembly only; pattern left blank */]> {
|
[(arm_cmpfpe0 HPR:$Sd)]> {
|
||||||
let Inst{3-0} = 0b0000;
|
let Inst{3-0} = 0b0000;
|
||||||
let Inst{5} = 0;
|
let Inst{5} = 0;
|
||||||
}
|
}
|
||||||
|
@ -156,13 +156,6 @@ const uint32_t *
|
|||||||
RISCVRegisterInfo::getCallPreservedMask(const MachineFunction & MF,
|
RISCVRegisterInfo::getCallPreservedMask(const MachineFunction & MF,
|
||||||
CallingConv::ID /*CC*/) const {
|
CallingConv::ID /*CC*/) const {
|
||||||
auto &Subtarget = MF.getSubtarget<RISCVSubtarget>();
|
auto &Subtarget = MF.getSubtarget<RISCVSubtarget>();
|
||||||
if (MF.getFunction().hasFnAttribute("interrupt")) {
|
|
||||||
if (Subtarget.hasStdExtD())
|
|
||||||
return CSR_XLEN_F64_Interrupt_RegMask;
|
|
||||||
if (Subtarget.hasStdExtF())
|
|
||||||
return CSR_XLEN_F32_Interrupt_RegMask;
|
|
||||||
return CSR_Interrupt_RegMask;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (Subtarget.getTargetABI()) {
|
switch (Subtarget.getTargetABI()) {
|
||||||
default:
|
default:
|
||||||
|
@ -364,12 +364,13 @@ bool X86CmovConverterPass::collectCmovCandidates(
|
|||||||
/// \param TrueOpDepth depth cost of CMOV true value operand.
|
/// \param TrueOpDepth depth cost of CMOV true value operand.
|
||||||
/// \param FalseOpDepth depth cost of CMOV false value operand.
|
/// \param FalseOpDepth depth cost of CMOV false value operand.
|
||||||
static unsigned getDepthOfOptCmov(unsigned TrueOpDepth, unsigned FalseOpDepth) {
|
static unsigned getDepthOfOptCmov(unsigned TrueOpDepth, unsigned FalseOpDepth) {
|
||||||
//===--------------------------------------------------------------------===//
|
// The depth of the result after branch conversion is
|
||||||
// With no info about branch weight, we assume 50% for each value operand.
|
// TrueOpDepth * TrueOpProbability + FalseOpDepth * FalseOpProbability.
|
||||||
// Thus, depth of optimized CMOV instruction is the rounded up average of
|
// As we have no info about branch weight, we assume 75% for one and 25% for
|
||||||
// its True-Operand-Value-Depth and False-Operand-Value-Depth.
|
// the other, and pick the result with the largest resulting depth.
|
||||||
//===--------------------------------------------------------------------===//
|
return std::max(
|
||||||
return (TrueOpDepth + FalseOpDepth + 1) / 2;
|
divideCeil(TrueOpDepth * 3 + FalseOpDepth, 4),
|
||||||
|
divideCeil(FalseOpDepth * 3 + TrueOpDepth, 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool X86CmovConverterPass::checkForProfitableCmovCandidates(
|
bool X86CmovConverterPass::checkForProfitableCmovCandidates(
|
||||||
|
@ -3494,7 +3494,8 @@ foldShiftIntoShiftInAnotherHandOfAndInICmp(ICmpInst &I, const SimplifyQuery SQ,
|
|||||||
Instruction *NarrowestShift = XShift;
|
Instruction *NarrowestShift = XShift;
|
||||||
|
|
||||||
Type *WidestTy = WidestShift->getType();
|
Type *WidestTy = WidestShift->getType();
|
||||||
assert(NarrowestShift->getType() == I.getOperand(0)->getType() &&
|
Type *NarrowestTy = NarrowestShift->getType();
|
||||||
|
assert(NarrowestTy == I.getOperand(0)->getType() &&
|
||||||
"We did not look past any shifts while matching XShift though.");
|
"We did not look past any shifts while matching XShift though.");
|
||||||
bool HadTrunc = WidestTy != I.getOperand(0)->getType();
|
bool HadTrunc = WidestTy != I.getOperand(0)->getType();
|
||||||
|
|
||||||
@ -3533,6 +3534,23 @@ foldShiftIntoShiftInAnotherHandOfAndInICmp(ICmpInst &I, const SimplifyQuery SQ,
|
|||||||
if (XShAmt->getType() != YShAmt->getType())
|
if (XShAmt->getType() != YShAmt->getType())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
// As input, we have the following pattern:
|
||||||
|
// icmp eq/ne (and ((x shift Q), (y oppositeshift K))), 0
|
||||||
|
// We want to rewrite that as:
|
||||||
|
// icmp eq/ne (and (x shift (Q+K)), y), 0 iff (Q+K) u< bitwidth(x)
|
||||||
|
// While we know that originally (Q+K) would not overflow
|
||||||
|
// (because 2 * (N-1) u<= iN -1), we have looked past extensions of
|
||||||
|
// shift amounts. so it may now overflow in smaller bitwidth.
|
||||||
|
// To ensure that does not happen, we need to ensure that the total maximal
|
||||||
|
// shift amount is still representable in that smaller bit width.
|
||||||
|
unsigned MaximalPossibleTotalShiftAmount =
|
||||||
|
(WidestTy->getScalarSizeInBits() - 1) +
|
||||||
|
(NarrowestTy->getScalarSizeInBits() - 1);
|
||||||
|
APInt MaximalRepresentableShiftAmount =
|
||||||
|
APInt::getAllOnesValue(XShAmt->getType()->getScalarSizeInBits());
|
||||||
|
if (MaximalRepresentableShiftAmount.ult(MaximalPossibleTotalShiftAmount))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
// Can we fold (XShAmt+YShAmt) ?
|
// Can we fold (XShAmt+YShAmt) ?
|
||||||
auto *NewShAmt = dyn_cast_or_null<Constant>(
|
auto *NewShAmt = dyn_cast_or_null<Constant>(
|
||||||
SimplifyAddInst(XShAmt, YShAmt, /*isNSW=*/false,
|
SimplifyAddInst(XShAmt, YShAmt, /*isNSW=*/false,
|
||||||
|
@ -23,8 +23,11 @@ using namespace PatternMatch;
|
|||||||
// Given pattern:
|
// Given pattern:
|
||||||
// (x shiftopcode Q) shiftopcode K
|
// (x shiftopcode Q) shiftopcode K
|
||||||
// we should rewrite it as
|
// we should rewrite it as
|
||||||
// x shiftopcode (Q+K) iff (Q+K) u< bitwidth(x)
|
// x shiftopcode (Q+K) iff (Q+K) u< bitwidth(x) and
|
||||||
// This is valid for any shift, but they must be identical.
|
//
|
||||||
|
// This is valid for any shift, but they must be identical, and we must be
|
||||||
|
// careful in case we have (zext(Q)+zext(K)) and look past extensions,
|
||||||
|
// (Q+K) must not overflow or else (Q+K) u< bitwidth(x) is bogus.
|
||||||
//
|
//
|
||||||
// AnalyzeForSignBitExtraction indicates that we will only analyze whether this
|
// AnalyzeForSignBitExtraction indicates that we will only analyze whether this
|
||||||
// pattern has any 2 right-shifts that sum to 1 less than original bit width.
|
// pattern has any 2 right-shifts that sum to 1 less than original bit width.
|
||||||
@ -58,6 +61,23 @@ Value *InstCombiner::reassociateShiftAmtsOfTwoSameDirectionShifts(
|
|||||||
if (ShAmt0->getType() != ShAmt1->getType())
|
if (ShAmt0->getType() != ShAmt1->getType())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
// As input, we have the following pattern:
|
||||||
|
// Sh0 (Sh1 X, Q), K
|
||||||
|
// We want to rewrite that as:
|
||||||
|
// Sh x, (Q+K) iff (Q+K) u< bitwidth(x)
|
||||||
|
// While we know that originally (Q+K) would not overflow
|
||||||
|
// (because 2 * (N-1) u<= iN -1), we have looked past extensions of
|
||||||
|
// shift amounts. so it may now overflow in smaller bitwidth.
|
||||||
|
// To ensure that does not happen, we need to ensure that the total maximal
|
||||||
|
// shift amount is still representable in that smaller bit width.
|
||||||
|
unsigned MaximalPossibleTotalShiftAmount =
|
||||||
|
(Sh0->getType()->getScalarSizeInBits() - 1) +
|
||||||
|
(Sh1->getType()->getScalarSizeInBits() - 1);
|
||||||
|
APInt MaximalRepresentableShiftAmount =
|
||||||
|
APInt::getAllOnesValue(ShAmt0->getType()->getScalarSizeInBits());
|
||||||
|
if (MaximalRepresentableShiftAmount.ult(MaximalPossibleTotalShiftAmount))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
// We are only looking for signbit extraction if we have two right shifts.
|
// We are only looking for signbit extraction if we have two right shifts.
|
||||||
bool HadTwoRightShifts = match(Sh0, m_Shr(m_Value(), m_Value())) &&
|
bool HadTwoRightShifts = match(Sh0, m_Shr(m_Value(), m_Value())) &&
|
||||||
match(Sh1, m_Shr(m_Value(), m_Value()));
|
match(Sh1, m_Shr(m_Value(), m_Value()));
|
||||||
|
@ -790,41 +790,6 @@ class ControlFlowHoister {
|
|||||||
};
|
};
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
/// Return true if we know how to rewrite all uses of the given alloca after
|
|
||||||
/// hoisting it out of the loop. The main concerns are a) potential captures
|
|
||||||
/// and b) invariant.start markers which don't capture, but are no longer
|
|
||||||
/// valid w/o a corresponding invariant.end.
|
|
||||||
static bool canRewriteUsesOfAlloca(AllocaInst &AI) {
|
|
||||||
// TODO: This looks a lot like capture tracking, but we need to remove any
|
|
||||||
// invariant starts if we extend the lifetime of the alloca by hoisting it.
|
|
||||||
// We should probably refactor capture tracking into a form which allows us
|
|
||||||
// to reuse the relevant bits and remove the duplicated logic here.
|
|
||||||
|
|
||||||
SmallVector<Use *, 16> Worklist;
|
|
||||||
for (Use &U : AI.uses())
|
|
||||||
Worklist.push_back(&U);
|
|
||||||
|
|
||||||
unsigned NumUsesExplored = 0;
|
|
||||||
while (!Worklist.empty()) {
|
|
||||||
Use *U = Worklist.pop_back_val();
|
|
||||||
Instruction *I = cast<Instruction>(U->getUser());
|
|
||||||
NumUsesExplored++;
|
|
||||||
if (NumUsesExplored > DefaultMaxUsesToExplore)
|
|
||||||
return false;
|
|
||||||
// Non capturing, terminating uses
|
|
||||||
if (isa<LoadInst>(I) ||
|
|
||||||
(isa<StoreInst>(I) && U->getOperandNo() == 1))
|
|
||||||
continue;
|
|
||||||
// Non capturing, non-terminating
|
|
||||||
if (!isa<BitCastInst>(I) && !isa<GetElementPtrInst>(I))
|
|
||||||
return false;
|
|
||||||
for (Use &U : I->uses())
|
|
||||||
Worklist.push_back(&U);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Walk the specified region of the CFG (defined by all blocks dominated by
|
/// Walk the specified region of the CFG (defined by all blocks dominated by
|
||||||
/// the specified block, and that are in the current loop) in depth first
|
/// the specified block, and that are in the current loop) in depth first
|
||||||
/// order w.r.t the DominatorTree. This allows us to visit definitions before
|
/// order w.r.t the DominatorTree. This allows us to visit definitions before
|
||||||
@ -945,16 +910,6 @@ bool llvm::hoistRegion(DomTreeNode *N, AliasAnalysis *AA, LoopInfo *LI,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isa<AllocaInst>(&I) &&
|
|
||||||
SafetyInfo->isGuaranteedToExecute(I, DT, CurLoop) &&
|
|
||||||
canRewriteUsesOfAlloca(cast<AllocaInst>(I))) {
|
|
||||||
hoist(I, DT, CurLoop, CFH.getOrCreateHoistedBlock(BB), SafetyInfo,
|
|
||||||
MSSAU, SE, ORE);
|
|
||||||
HoistedInstructions.push_back(&I);
|
|
||||||
Changed = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PHINode *PN = dyn_cast<PHINode>(&I)) {
|
if (PHINode *PN = dyn_cast<PHINode>(&I)) {
|
||||||
if (CFH.canHoistPHI(PN)) {
|
if (CFH.canHoistPHI(PN)) {
|
||||||
// Redirect incoming blocks first to ensure that we create hoisted
|
// Redirect incoming blocks first to ensure that we create hoisted
|
||||||
@ -1537,7 +1492,8 @@ static bool canSplitPredecessors(PHINode *PN, LoopSafetyInfo *SafetyInfo) {
|
|||||||
return false;
|
return false;
|
||||||
for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) {
|
for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) {
|
||||||
BasicBlock *BBPred = *PI;
|
BasicBlock *BBPred = *PI;
|
||||||
if (isa<IndirectBrInst>(BBPred->getTerminator()))
|
if (isa<IndirectBrInst>(BBPred->getTerminator()) ||
|
||||||
|
isa<CallBrInst>(BBPred->getTerminator()))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -81,10 +81,8 @@ class LoopRotateLegacyPass : public LoopPass {
|
|||||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||||
AU.addRequired<AssumptionCacheTracker>();
|
AU.addRequired<AssumptionCacheTracker>();
|
||||||
AU.addRequired<TargetTransformInfoWrapperPass>();
|
AU.addRequired<TargetTransformInfoWrapperPass>();
|
||||||
if (EnableMSSALoopDependency) {
|
if (EnableMSSALoopDependency)
|
||||||
AU.addRequired<MemorySSAWrapperPass>();
|
|
||||||
AU.addPreserved<MemorySSAWrapperPass>();
|
AU.addPreserved<MemorySSAWrapperPass>();
|
||||||
}
|
|
||||||
getLoopAnalysisUsage(AU);
|
getLoopAnalysisUsage(AU);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,8 +99,11 @@ class LoopRotateLegacyPass : public LoopPass {
|
|||||||
const SimplifyQuery SQ = getBestSimplifyQuery(*this, F);
|
const SimplifyQuery SQ = getBestSimplifyQuery(*this, F);
|
||||||
Optional<MemorySSAUpdater> MSSAU;
|
Optional<MemorySSAUpdater> MSSAU;
|
||||||
if (EnableMSSALoopDependency) {
|
if (EnableMSSALoopDependency) {
|
||||||
MemorySSA *MSSA = &getAnalysis<MemorySSAWrapperPass>().getMSSA();
|
// Not requiring MemorySSA and getting it only if available will split
|
||||||
MSSAU = MemorySSAUpdater(MSSA);
|
// the loop pass pipeline when LoopRotate is being run first.
|
||||||
|
auto *MSSAA = getAnalysisIfAvailable<MemorySSAWrapperPass>();
|
||||||
|
if (MSSAA)
|
||||||
|
MSSAU = MemorySSAUpdater(&MSSAA->getMSSA());
|
||||||
}
|
}
|
||||||
return LoopRotation(L, LI, TTI, AC, &DT, &SE,
|
return LoopRotation(L, LI, TTI, AC, &DT, &SE,
|
||||||
MSSAU.hasValue() ? MSSAU.getPointer() : nullptr, SQ,
|
MSSAU.hasValue() ? MSSAU.getPointer() : nullptr, SQ,
|
||||||
|
@ -505,7 +505,8 @@ llvm::SplitAllCriticalEdges(Function &F,
|
|||||||
unsigned NumBroken = 0;
|
unsigned NumBroken = 0;
|
||||||
for (BasicBlock &BB : F) {
|
for (BasicBlock &BB : F) {
|
||||||
Instruction *TI = BB.getTerminator();
|
Instruction *TI = BB.getTerminator();
|
||||||
if (TI->getNumSuccessors() > 1 && !isa<IndirectBrInst>(TI))
|
if (TI->getNumSuccessors() > 1 && !isa<IndirectBrInst>(TI) &&
|
||||||
|
!isa<CallBrInst>(TI))
|
||||||
for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i)
|
for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i)
|
||||||
if (SplitCriticalEdge(TI, i, Options))
|
if (SplitCriticalEdge(TI, i, Options))
|
||||||
++NumBroken;
|
++NumBroken;
|
||||||
|
@ -832,13 +832,12 @@ class BoUpSLP {
|
|||||||
|
|
||||||
// Extracts from consecutive indexes of the same vector better score as
|
// Extracts from consecutive indexes of the same vector better score as
|
||||||
// the extracts could be optimized away.
|
// the extracts could be optimized away.
|
||||||
auto *Ex1 = dyn_cast<ExtractElementInst>(V1);
|
Value *EV;
|
||||||
auto *Ex2 = dyn_cast<ExtractElementInst>(V2);
|
ConstantInt *Ex1Idx, *Ex2Idx;
|
||||||
if (Ex1 && Ex2 && Ex1->getVectorOperand() == Ex2->getVectorOperand() &&
|
if (match(V1, m_ExtractElement(m_Value(EV), m_ConstantInt(Ex1Idx))) &&
|
||||||
cast<ConstantInt>(Ex1->getIndexOperand())->getZExtValue() + 1 ==
|
match(V2, m_ExtractElement(m_Deferred(EV), m_ConstantInt(Ex2Idx))) &&
|
||||||
cast<ConstantInt>(Ex2->getIndexOperand())->getZExtValue()) {
|
Ex1Idx->getZExtValue() + 1 == Ex2Idx->getZExtValue())
|
||||||
return VLOperands::ScoreConsecutiveExtracts;
|
return VLOperands::ScoreConsecutiveExtracts;
|
||||||
}
|
|
||||||
|
|
||||||
auto *I1 = dyn_cast<Instruction>(V1);
|
auto *I1 = dyn_cast<Instruction>(V1);
|
||||||
auto *I2 = dyn_cast<Instruction>(V2);
|
auto *I2 = dyn_cast<Instruction>(V2);
|
||||||
|
@ -53,14 +53,14 @@ void DfaEmitter::addTransition(state_type From, state_type To, action_type A) {
|
|||||||
++NumNfaTransitions;
|
++NumNfaTransitions;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DfaEmitter::visitDfaState(DfaState DS) {
|
void DfaEmitter::visitDfaState(const DfaState &DS) {
|
||||||
// For every possible action...
|
// For every possible action...
|
||||||
auto FromId = DfaStates.idFor(DS);
|
auto FromId = DfaStates.idFor(DS);
|
||||||
for (action_type A : Actions) {
|
for (action_type A : Actions) {
|
||||||
DfaState NewStates;
|
DfaState NewStates;
|
||||||
DfaTransitionInfo TI;
|
DfaTransitionInfo TI;
|
||||||
// For every represented state, word pair in the original NFA...
|
// For every represented state, word pair in the original NFA...
|
||||||
for (state_type &FromState : DS) {
|
for (state_type FromState : DS) {
|
||||||
// If this action is possible from this state add the transitioned-to
|
// If this action is possible from this state add the transitioned-to
|
||||||
// states to NewStates.
|
// states to NewStates.
|
||||||
auto I = NfaTransitions.find({FromState, A});
|
auto I = NfaTransitions.find({FromState, A});
|
||||||
@ -90,8 +90,11 @@ void DfaEmitter::constructDfa() {
|
|||||||
|
|
||||||
// Note that UniqueVector starts indices at 1, not zero.
|
// Note that UniqueVector starts indices at 1, not zero.
|
||||||
unsigned DfaStateId = 1;
|
unsigned DfaStateId = 1;
|
||||||
while (DfaStateId <= DfaStates.size())
|
while (DfaStateId <= DfaStates.size()) {
|
||||||
visitDfaState(DfaStates[DfaStateId++]);
|
DfaState S = DfaStates[DfaStateId];
|
||||||
|
visitDfaState(S);
|
||||||
|
DfaStateId++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DfaEmitter::emit(StringRef Name, raw_ostream &OS) {
|
void DfaEmitter::emit(StringRef Name, raw_ostream &OS) {
|
||||||
|
@ -99,7 +99,7 @@ class DfaEmitter {
|
|||||||
void constructDfa();
|
void constructDfa();
|
||||||
/// Visit a single DFA state and construct all possible transitions to new DFA
|
/// Visit a single DFA state and construct all possible transitions to new DFA
|
||||||
/// states.
|
/// states.
|
||||||
void visitDfaState(DfaState DS);
|
void visitDfaState(const DfaState &DS);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace llvm
|
} // namespace llvm
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
// $FreeBSD$
|
// $FreeBSD$
|
||||||
|
|
||||||
#define LLVM_REVISION "llvmorg-10.0.0-rc2-0-g90c78073f73"
|
#define LLVM_REVISION "llvmorg-10.0.0-rc2-70-ge5cb70267e7"
|
||||||
#define LLVM_REPOSITORY "git@github.com:llvm/llvm-project.git"
|
#define LLVM_REPOSITORY "git@github.com:llvm/llvm-project.git"
|
||||||
|
|
||||||
#define CLANG_REVISION "llvmorg-10.0.0-rc2-0-g90c78073f73"
|
#define CLANG_REVISION "llvmorg-10.0.0-rc2-70-ge5cb70267e7"
|
||||||
#define CLANG_REPOSITORY "git@github.com:llvm/llvm-project.git"
|
#define CLANG_REPOSITORY "git@github.com:llvm/llvm-project.git"
|
||||||
|
|
||||||
// <Upstream revision at import>-<Local identifier in __FreeBSD_version style>
|
// <Upstream revision at import>-<Local identifier in __FreeBSD_version style>
|
||||||
#define LLD_REVISION "llvmorg-10.0.0-rc2-0-g90c78073f73-1300007"
|
#define LLD_REVISION "llvmorg-10.0.0-rc2-70-ge5cb70267e7-1300007"
|
||||||
#define LLD_REPOSITORY "FreeBSD"
|
#define LLD_REPOSITORY "FreeBSD"
|
||||||
|
|
||||||
#define LLDB_REVISION "llvmorg-10.0.0-rc2-0-g90c78073f73"
|
#define LLDB_REVISION "llvmorg-10.0.0-rc2-70-ge5cb70267e7"
|
||||||
#define LLDB_REPOSITORY "git@github.com:llvm/llvm-project.git"
|
#define LLDB_REPOSITORY "git@github.com:llvm/llvm-project.git"
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
/* $FreeBSD$ */
|
/* $FreeBSD$ */
|
||||||
#define LLVM_REVISION "llvmorg-10.0.0-rc2-0-g90c78073f73"
|
#define LLVM_REVISION "llvmorg-10.0.0-rc2-70-ge5cb70267e7"
|
||||||
#define LLVM_REPOSITORY "git@github.com:llvm/llvm-project.git"
|
#define LLVM_REPOSITORY "git@github.com:llvm/llvm-project.git"
|
||||||
|
Loading…
Reference in New Issue
Block a user