@@ -5155,7 +5155,51 @@ struct StrictFPUpgradeVisitor : public InstVisitor<StrictFPUpgradeVisitor> {
51555155};
51565156} // namespace
51575157
5158- void llvm::UpgradeFunctionAttributes (Function &F) {
5158+ // Check if the module attribute is present and not zero.
5159+ static bool isModuleAttributeSet (const Module *M, const StringRef &ModAttr) {
5160+ if (const auto *Attr =
5161+ mdconst::extract_or_null<ConstantInt>(M->getModuleFlag (ModAttr)))
5162+ if (Attr->getZExtValue ())
5163+ return true ;
5164+ return false ;
5165+ }
5166+
5167+ // Copy an attribute from module to the function if exists.
5168+ // First value of the pair is used when the module attribute is not zero
5169+ // the second otherwise.
5170+ static void
5171+ CopyModuleAttributeToFunction (Function &F, StringRef FnAttrName,
5172+ StringRef ModAttrName,
5173+ std::pair<StringRef, StringRef> Values) {
5174+ Module *M = F.getParent ();
5175+ assert (M && " Missing module" );
5176+ if (F.hasFnAttribute (FnAttrName))
5177+ return ;
5178+ if (isModuleAttributeSet (M, ModAttrName))
5179+ F.addFnAttr (FnAttrName, Values.first );
5180+ else
5181+ F.addFnAttr (FnAttrName, Values.second );
5182+ }
5183+
5184+ // Copy a boolean attribute from module to the function if exists.
5185+ // Module attribute treated false if zero otherwise true.
5186+ static void CopyModuleAttributeToFunction (Function &F, StringRef AttrName) {
5187+ CopyModuleAttributeToFunction (
5188+ F, AttrName, AttrName,
5189+ std::make_pair<StringRef, StringRef>(" true" , " false" ));
5190+ }
5191+
5192+ // Copy an attribute from module to the function if exists.
5193+ // First value of the pair is used when the module attribute is not zero
5194+ // the second otherwise.
5195+ static void
5196+ CopyModuleAttributeToFunction (Function &F, StringRef AttrName,
5197+ std::pair<StringRef, StringRef> Values) {
5198+ CopyModuleAttributeToFunction (F, AttrName, AttrName, Values);
5199+ }
5200+
5201+ void llvm::UpgradeFunctionAttributes (Function &F,
5202+ bool ModuleMetadataIsMaterialized) {
51595203 // If a function definition doesn't have the strictfp attribute,
51605204 // convert any callsite strictfp attributes to nobuiltin.
51615205 if (!F.isDeclaration () && !F.hasFnAttribute (Attribute::StrictFP)) {
@@ -5167,6 +5211,37 @@ void llvm::UpgradeFunctionAttributes(Function &F) {
51675211 F.removeRetAttrs (AttributeFuncs::typeIncompatible (F.getReturnType ()));
51685212 for (auto &Arg : F.args ())
51695213 Arg.removeAttrs (AttributeFuncs::typeIncompatible (Arg.getType ()));
5214+
5215+ if (!ModuleMetadataIsMaterialized)
5216+ return ;
5217+ if (F.isDeclaration ())
5218+ return ;
5219+ Module *M = F.getParent ();
5220+ if (!M)
5221+ return ;
5222+
5223+ Triple T (M->getTargetTriple ());
5224+ // Convert module level attributes to function level attributes because
5225+ // after merging modules the attributes might change and would have different
5226+ // effect on the functions as the original module would have.
5227+ if (T.isThumb () || T.isARM () || T.isAArch64 ()) {
5228+ if (!F.hasFnAttribute (" sign-return-address" )) {
5229+ StringRef SignType = " none" ;
5230+ if (isModuleAttributeSet (M, " sign-return-address" ))
5231+ SignType = " non-leaf" ;
5232+
5233+ if (isModuleAttributeSet (M, " sign-return-address-all" ))
5234+ SignType = " all" ;
5235+
5236+ F.addFnAttr (" sign-return-address" , SignType);
5237+ }
5238+ CopyModuleAttributeToFunction (F, " branch-target-enforcement" );
5239+ CopyModuleAttributeToFunction (F, " branch-protection-pauth-lr" );
5240+ CopyModuleAttributeToFunction (F, " guarded-control-stack" );
5241+ CopyModuleAttributeToFunction (
5242+ F, " sign-return-address-key" ,
5243+ std::make_pair<StringRef, StringRef>(" b_key" , " a_key" ));
5244+ }
51705245}
51715246
51725247static bool isOldLoopArgument (Metadata *MD) {
0 commit comments