Index: clang/include/clang/Basic/TargetInfo.h =================================================================== --- clang/include/clang/Basic/TargetInfo.h +++ clang/include/clang/Basic/TargetInfo.h @@ -928,8 +928,18 @@ 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. + virtual Optional + hasRequiredFeature(const llvm::StringMap FeatureMap, + const StringRef ReqFeature) const { + return {}; + } + + /// \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,12 @@ Feature.split(OrFeatures, "|"); return std::any_of(OrFeatures.begin(), OrFeatures.end(), [&](StringRef Feature) { + // Check if the target wants to handle the feature. + if (auto OR = CGM.getTarget().hasRequiredFeature( + CallerFeatureMap, Feature)) + return OR.getValue(); + // Otherwise just look for the feature + // presence/absence in the CallerFeatureMap. if (!CallerFeatureMap.lookup(Feature)) { FirstMissing = Feature.str(); return false;