diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -2892,6 +2892,12 @@ let SimpleHandler = 1; } +def AMXPreserve : InheritableAttr, TargetSpecificAttr { + let Spellings = [GCC<"amxpreserve">, Declspec<"amxpreserve">]; + let Documentation = [Undocumented]; + let SimpleHandler = 1; +} + def AnyX86Interrupt : InheritableAttr, TargetSpecificAttr { // NOTE: If you add any additional spellings, ARMInterrupt's, // M68kInterrupt's, MSP430Interrupt's and MipsInterrupt's spellings must match. diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -2116,6 +2116,8 @@ FuncAttrs.addAttribute(llvm::Attribute::NoCfCheck); if (TargetDecl->hasAttr()) FuncAttrs.addAttribute(llvm::Attribute::NoCallback); + if (TargetDecl->hasAttr()) + FuncAttrs.addAttribute(llvm::Attribute::AMXPreserve); HasOptnone = TargetDecl->hasAttr(); if (auto *AllocSize = TargetDecl->getAttr()) { diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -1858,6 +1858,8 @@ // carry an explicit noinline attribute. if (!F->hasFnAttribute(llvm::Attribute::AlwaysInline)) B.addAttribute(llvm::Attribute::NoInline); + } else if (D->hasAttr()) { + B.addAttribute(llvm::Attribute::AMXPreserve); } else { // Otherwise, propagate the inline hint attribute and potentially use its // absence to mark things as noinline. diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -7514,6 +7514,17 @@ return true; } + if (attr.getKind() == ParsedAttr::AT_AMXPreserve) { + if (S.CheckAttrTarget(attr)) + return true; + + // Delay if this is not a function type. + if (!unwrapped.isFunctionType()) + return false; + + return true; + } + if (attr.getKind() == ParsedAttr::AT_AnyX86NoCallerSavedRegisters) { if (S.CheckAttrTarget(attr) || S.CheckAttrNoArgs(attr)) return true;