@@ -5169,6 +5169,72 @@ void llvm::UpgradeFunctionAttributes(Function &F) {
5169
5169
Arg.removeAttrs (AttributeFuncs::typeIncompatible (Arg.getType ()));
5170
5170
}
5171
5171
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
+
5172
5238
static bool isOldLoopArgument (Metadata *MD) {
5173
5239
auto *T = dyn_cast_or_null<MDTuple>(MD);
5174
5240
if (!T)
0 commit comments