@@ -5169,6 +5169,72 @@ void llvm::UpgradeFunctionAttributes(Function &F) {
51695169 Arg.removeAttrs (AttributeFuncs::typeIncompatible (Arg.getType ()));
51705170}
51715171
5172+ // Check if the module attribute is present and not zero.
5173+ static bool isModuleAttributeSet (Module &M, const StringRef &ModAttr) {
5174+ const auto *Attr =
5175+ mdconst::extract_or_null<ConstantInt>(M.getModuleFlag (ModAttr));
5176+ return Attr && Attr->getZExtValue ();
5177+ }
5178+
5179+ // Copy an attribute from module to the function if exists.
5180+ // First value of the pair is used when the module attribute is not zero
5181+ // the second otherwise.
5182+ static void
5183+ CopyModuleAttributeToFunction (Function &F, StringRef FnAttrName,
5184+ StringRef ModAttrName,
5185+ std::pair<StringRef, StringRef> Values) {
5186+ if (F.hasFnAttribute (FnAttrName))
5187+ return ;
5188+ F.addFnAttr (FnAttrName, isModuleAttributeSet (*F.getParent (), ModAttrName)
5189+ ? Values.first
5190+ : Values.second );
5191+ }
5192+
5193+ // Copy a boolean attribute from module to the function if exists.
5194+ // Module attribute treated false if zero otherwise true.
5195+ static void CopyModuleAttributeToFunction (Function &F, StringRef AttrName) {
5196+ CopyModuleAttributeToFunction (
5197+ F, AttrName, AttrName,
5198+ std::make_pair<StringRef, StringRef>(" true" , " false" ));
5199+ }
5200+
5201+ // Copy an attribute from module to the function if exists.
5202+ // First value of the pair is used when the module attribute is not zero
5203+ // the second otherwise.
5204+ static void
5205+ CopyModuleAttributeToFunction (Function &F, StringRef AttrName,
5206+ std::pair<StringRef, StringRef> Values) {
5207+ CopyModuleAttributeToFunction (F, AttrName, AttrName, Values);
5208+ }
5209+
5210+ void llvm::CopyModuleAttrToFunctions (Module &M) {
5211+ Triple T (M.getTargetTriple ());
5212+ if (!T.isThumb () && !T.isARM () && !T.isAArch64 ())
5213+ return ;
5214+
5215+ for (Function &F : M.getFunctionList ()) {
5216+ if (F.isDeclaration ())
5217+ continue ;
5218+
5219+ if (!F.hasFnAttribute (" sign-return-address" )) {
5220+ StringRef SignType = " none" ;
5221+ if (isModuleAttributeSet (M, " sign-return-address" ))
5222+ SignType = " non-leaf" ;
5223+
5224+ if (isModuleAttributeSet (M, " sign-return-address-all" ))
5225+ SignType = " all" ;
5226+
5227+ F.addFnAttr (" sign-return-address" , SignType);
5228+ }
5229+ CopyModuleAttributeToFunction (F, " branch-target-enforcement" );
5230+ CopyModuleAttributeToFunction (F, " branch-protection-pauth-lr" );
5231+ CopyModuleAttributeToFunction (F, " guarded-control-stack" );
5232+ CopyModuleAttributeToFunction (
5233+ F, " sign-return-address-key" ,
5234+ std::make_pair<StringRef, StringRef>(" b_key" , " a_key" ));
5235+ }
5236+ }
5237+
51725238static bool isOldLoopArgument (Metadata *MD) {
51735239 auto *T = dyn_cast_or_null<MDTuple>(MD);
51745240 if (!T)
0 commit comments