Index: clang/include/clang/Basic/TargetInfo.h =================================================================== --- clang/include/clang/Basic/TargetInfo.h +++ clang/include/clang/Basic/TargetInfo.h @@ -928,8 +928,20 @@ return false; } - /// \brief Identify whether this taret supports multiversioning of functions, - /// which requires support for cpu_supports and cpu_is functionality. + /// \brief Determine if ReqFeature is enabled given the features populated in + /// FeatureMap. Targets may override this to provide custom handling of + /// required features. Function returns None when the feature does not need + /// special handling by the target, or true/false to indicate whether the + /// feature is enabled. + virtual Optional + hasRequiredFeature(const llvm::StringMap FeatureMap, + const StringRef ReqFeature) const { + return None; + } + + /// \brief Identify whether this taret supports multiversioning of + /// functions, which requires support for cpu_supports and cpu_is + /// functionality. virtual bool supportsMultiVersioning() const { return false; } // \brief Validate the contents of the __builtin_cpu_supports(const char*) Index: clang/lib/CodeGen/CodeGenFunction.cpp =================================================================== --- clang/lib/CodeGen/CodeGenFunction.cpp +++ clang/lib/CodeGen/CodeGenFunction.cpp @@ -2262,6 +2262,16 @@ Feature.split(OrFeatures, "|"); return std::any_of(OrFeatures.begin(), OrFeatures.end(), [&](StringRef Feature) { + // Check if the target wants to handle the feature. + if (Optional HasFeature = + CGM.getTarget().hasRequiredFeature( + CallerFeatureMap, Feature)) { + if (*HasFeature == false) + FirstMissing = Feature.str(); + return *HasFeature; + } + // Otherwise just look for the feature + // presence/absence in the CallerFeatureMap. if (!CallerFeatureMap.lookup(Feature)) { FirstMissing = Feature.str(); return false;