@@ -5155,7 +5155,46 @@ 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+ const auto *Attr =
5161+ mdconst::extract_or_null<ConstantInt>(M->getModuleFlag (ModAttr));
5162+ return Attr && Attr->getZExtValue ();
5163+ }
5164+
5165+ // Copy an attribute from module to the function if exists.
5166+ // First value of the pair is used when the module attribute is not zero
5167+ // the second otherwise.
5168+ static void
5169+ CopyModuleAttributeToFunction (Function &F, StringRef FnAttrName,
5170+ StringRef ModAttrName,
5171+ std::pair<StringRef, StringRef> Values) {
5172+ if (F.hasFnAttribute (FnAttrName))
5173+ return ;
5174+ F.addFnAttr (FnAttrName, isModuleAttributeSet (F.getParent (), ModAttrName)
5175+ ? Values.first
5176+ : Values.second );
5177+ }
5178+
5179+ // Copy a boolean attribute from module to the function if exists.
5180+ // Module attribute treated false if zero otherwise true.
5181+ static void CopyModuleAttributeToFunction (Function &F, StringRef AttrName) {
5182+ CopyModuleAttributeToFunction (
5183+ F, AttrName, AttrName,
5184+ std::make_pair<StringRef, StringRef>(" true" , " false" ));
5185+ }
5186+
5187+ // Copy an attribute from module to the function if exists.
5188+ // First value of the pair is used when the module attribute is not zero
5189+ // the second otherwise.
5190+ static void
5191+ CopyModuleAttributeToFunction (Function &F, StringRef AttrName,
5192+ std::pair<StringRef, StringRef> Values) {
5193+ CopyModuleAttributeToFunction (F, AttrName, AttrName, Values);
5194+ }
5195+
5196+ void llvm::UpgradeFunctionAttributes (Function &F,
5197+ bool ModuleMetadataIsMaterialized) {
51595198 // If a function definition doesn't have the strictfp attribute,
51605199 // convert any callsite strictfp attributes to nobuiltin.
51615200 if (!F.isDeclaration () && !F.hasFnAttribute (Attribute::StrictFP)) {
@@ -5167,6 +5206,37 @@ void llvm::UpgradeFunctionAttributes(Function &F) {
51675206 F.removeRetAttrs (AttributeFuncs::typeIncompatible (F.getReturnType ()));
51685207 for (auto &Arg : F.args ())
51695208 Arg.removeAttrs (AttributeFuncs::typeIncompatible (Arg.getType ()));
5209+
5210+ if (!ModuleMetadataIsMaterialized)
5211+ return ;
5212+ if (F.isDeclaration ())
5213+ return ;
5214+ Module *M = F.getParent ();
5215+ if (!M)
5216+ return ;
5217+
5218+ Triple T (M->getTargetTriple ());
5219+ // Convert module level attributes to function level attributes because
5220+ // after merging modules the attributes might change and would have different
5221+ // effect on the functions as the original module would have.
5222+ if (T.isThumb () || T.isARM () || T.isAArch64 ()) {
5223+ if (!F.hasFnAttribute (" sign-return-address" )) {
5224+ StringRef SignType = " none" ;
5225+ if (isModuleAttributeSet (M, " sign-return-address" ))
5226+ SignType = " non-leaf" ;
5227+
5228+ if (isModuleAttributeSet (M, " sign-return-address-all" ))
5229+ SignType = " all" ;
5230+
5231+ F.addFnAttr (" sign-return-address" , SignType);
5232+ }
5233+ CopyModuleAttributeToFunction (F, " branch-target-enforcement" );
5234+ CopyModuleAttributeToFunction (F, " branch-protection-pauth-lr" );
5235+ CopyModuleAttributeToFunction (F, " guarded-control-stack" );
5236+ CopyModuleAttributeToFunction (
5237+ F, " sign-return-address-key" ,
5238+ std::make_pair<StringRef, StringRef>(" b_key" , " a_key" ));
5239+ }
51705240}
51715241
51725242static bool isOldLoopArgument (Metadata *MD) {
0 commit comments