@@ -5155,7 +5155,39 @@ struct StrictFPUpgradeVisitor : public InstVisitor<StrictFPUpgradeVisitor> {
51555155};
51565156} // namespace
51575157
5158- void llvm::UpgradeFunctionAttributes (Function &F) {
5158+ static void
5159+ CopyModuleAttributeToFunction (Function &F, StringRef FnAttrName,
5160+ StringRef ModAttrName,
5161+ std::pair<StringRef, StringRef> Values) {
5162+ Module *M = F.getParent ();
5163+ if (!M)
5164+ return ;
5165+ if (F.hasFnAttribute (FnAttrName))
5166+ return ;
5167+ if (const auto *MAttr = mdconst::extract_or_null<ConstantInt>(
5168+ M->getModuleFlag (ModAttrName))) {
5169+ if (MAttr->getZExtValue ()) {
5170+ F.addFnAttr (FnAttrName, Values.first );
5171+ return ;
5172+ }
5173+ }
5174+ F.addFnAttr (FnAttrName, Values.second );
5175+ }
5176+
5177+ static void CopyModuleAttributeToFunction (Function &F, StringRef AttrName) {
5178+ CopyModuleAttributeToFunction (
5179+ F, AttrName, AttrName,
5180+ std::make_pair<StringRef, StringRef>(" true" , " false" ));
5181+ }
5182+
5183+ static void
5184+ CopyModuleAttributeToFunction (Function &F, StringRef AttrName,
5185+ std::pair<StringRef, StringRef> Values) {
5186+ CopyModuleAttributeToFunction (F, AttrName, AttrName, Values);
5187+ }
5188+
5189+ void llvm::UpgradeFunctionAttributes (Function &F,
5190+ bool ModuleMetadataIsMaterialized) {
51595191 // If a function definition doesn't have the strictfp attribute,
51605192 // convert any callsite strictfp attributes to nobuiltin.
51615193 if (!F.isDeclaration () && !F.hasFnAttribute (Attribute::StrictFP)) {
@@ -5167,6 +5199,41 @@ void llvm::UpgradeFunctionAttributes(Function &F) {
51675199 F.removeRetAttrs (AttributeFuncs::typeIncompatible (F.getReturnType ()));
51685200 for (auto &Arg : F.args ())
51695201 Arg.removeAttrs (AttributeFuncs::typeIncompatible (Arg.getType ()));
5202+
5203+ if (!ModuleMetadataIsMaterialized)
5204+ return ;
5205+ if (F.isDeclaration ())
5206+ return ;
5207+ Module *M = F.getParent ();
5208+ if (!M)
5209+ return ;
5210+
5211+ Triple T (M->getTargetTriple ());
5212+ // Convert module level attributes to function level attributes because
5213+ // after merging modules the attributes might change and would have different
5214+ // effect on the functions as the original module would have.
5215+ if (T.isThumb () || T.isARM () || T.isAArch64 ()) {
5216+ if (!F.hasFnAttribute (" sign-return-address" )) {
5217+ StringRef SignType = " none" ;
5218+ if (const auto *Sign = mdconst::extract_or_null<ConstantInt>(
5219+ M->getModuleFlag (" sign-return-address" )))
5220+ if (Sign->getZExtValue ())
5221+ SignType = " non-leaf" ;
5222+
5223+ if (const auto *SignAll = mdconst::extract_or_null<ConstantInt>(
5224+ M->getModuleFlag (" sign-return-address-all" )))
5225+ if (SignAll->getZExtValue ())
5226+ SignType = " all" ;
5227+
5228+ F.addFnAttr (" sign-return-address" , SignType);
5229+ }
5230+ CopyModuleAttributeToFunction (F, " branch-target-enforcement" );
5231+ CopyModuleAttributeToFunction (F, " branch-protection-pauth-lr" );
5232+ CopyModuleAttributeToFunction (F, " guarded-control-stack" );
5233+ CopyModuleAttributeToFunction (
5234+ F, " sign-return-address-key" ,
5235+ std::make_pair<StringRef, StringRef>(" b_key" , " a_key" ));
5236+ }
51705237}
51715238
51725239static bool isOldLoopArgument (Metadata *MD) {
0 commit comments