@@ -5155,7 +5155,39 @@ struct StrictFPUpgradeVisitor : public InstVisitor<StrictFPUpgradeVisitor> {
5155
5155
};
5156
5156
} // namespace
5157
5157
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) {
5159
5191
// If a function definition doesn't have the strictfp attribute,
5160
5192
// convert any callsite strictfp attributes to nobuiltin.
5161
5193
if (!F.isDeclaration () && !F.hasFnAttribute (Attribute::StrictFP)) {
@@ -5167,6 +5199,41 @@ void llvm::UpgradeFunctionAttributes(Function &F) {
5167
5199
F.removeRetAttrs (AttributeFuncs::typeIncompatible (F.getReturnType ()));
5168
5200
for (auto &Arg : F.args ())
5169
5201
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
+ }
5170
5237
}
5171
5238
5172
5239
static bool isOldLoopArgument (Metadata *MD) {
0 commit comments