[llvm] [RFC][Draft] Extend MemoryEffects to Support Target-Specific Memory L… (PR #148650)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 15 05:46:06 PDT 2025
https://github.com/CarolineConcatto updated https://github.com/llvm/llvm-project/pull/148650
>From d568c2bc9f421cd37b8b1e123deba4b792b4e66e Mon Sep 17 00:00:00 2001
From: CarolineConcatto <caroline.concatto at arm.com>
Date: Tue, 1 Jul 2025 11:48:55 +0000
Subject: [PATCH 1/2] [RFC][Draft] Extend MemoryEffects to Support
Target-Specific Memory Locations
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This patch introduces preliminary support for additional memory locations,
such as FPMR and ZA, needed to model AArch64 architectural registers as
memory dependencies.
Currently, these locations are not yet target-specific. The goal is to enable
the compiler to express read/write effects on these resources.
What This Patch Does:
Adds two new memory locations: FPMR and ZA, intended to represent
AArch64-specific inaccessible memory types.
Current Limitations:
These new locations are not yet target-specific in the type-safe sense,
they are globally visible and hardcoded.
There is no mechanism yet to associate a memory location with its
corresponding target (e.g., AArch64 vs RISCV).
No changes are made yet to bitcode serialization, parser support, or alias
analysis behavior.
This patch is not functionally complete — it is a structural prototype to
solicit feedback on the direction and I would like some suggestion on
how to proceed.
---
llvm/include/llvm/AsmParser/LLParser.h | 1 +
llvm/include/llvm/AsmParser/LLToken.h | 4 +
llvm/include/llvm/IR/Intrinsics.td | 11 +++
llvm/include/llvm/IR/IntrinsicsAArch64.td | 1 -
llvm/include/llvm/Support/ModRef.h | 24 ++++-
llvm/include/llvm/TableGen/Record.h | 3 +
llvm/lib/AsmParser/LLLexer.cpp | 4 +
llvm/lib/AsmParser/LLParser.cpp | 94 ++++++++++++++++---
llvm/lib/IR/Attributes.cpp | 13 +++
llvm/lib/Support/ModRef.cpp | 9 ++
llvm/lib/TableGen/Record.cpp | 15 +++
llvm/test/Assembler/memory-attribute.ll | 21 +++++
llvm/test/Bitcode/attributes.ll | 44 +++++++++
llvm/test/TableGen/intrinsic-attrs-fp8.td | 24 +++++
llvm/unittests/Support/ModRefTest.cpp | 2 +-
.../TableGen/Basic/CodeGenIntrinsics.cpp | 8 +-
16 files changed, 261 insertions(+), 17 deletions(-)
create mode 100644 llvm/test/TableGen/intrinsic-attrs-fp8.td
diff --git a/llvm/include/llvm/AsmParser/LLParser.h b/llvm/include/llvm/AsmParser/LLParser.h
index c01de4a289a69..ee7f133961031 100644
--- a/llvm/include/llvm/AsmParser/LLParser.h
+++ b/llvm/include/llvm/AsmParser/LLParser.h
@@ -295,6 +295,7 @@ namespace llvm {
};
bool parseEnumAttribute(Attribute::AttrKind Attr, AttrBuilder &B,
bool InAttrGroup);
+ bool parseInaccessibleMemLocation(IRMemLocation &MemLoc);
bool parseOptionalParamOrReturnAttrs(AttrBuilder &B, bool IsParam);
bool parseOptionalParamAttrs(AttrBuilder &B) {
return parseOptionalParamOrReturnAttrs(B, true);
diff --git a/llvm/include/llvm/AsmParser/LLToken.h b/llvm/include/llvm/AsmParser/LLToken.h
index c7e4bdf3ff811..68920af75c667 100644
--- a/llvm/include/llvm/AsmParser/LLToken.h
+++ b/llvm/include/llvm/AsmParser/LLToken.h
@@ -202,11 +202,15 @@ enum Kind {
kw_readwrite,
kw_argmem,
kw_inaccessiblemem,
+ kw_fpmr,
+ kw_za,
kw_errnomem,
// Legacy attributes:
kw_argmemonly,
kw_inaccessiblememonly,
+ kw_inaccessiblereadmemonly,
+ kw_inaccessiblewritememonly,
kw_inaccessiblemem_or_argmemonly,
kw_nocapture,
diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td
index bd6f94ac1286c..ad1b0b462be37 100644
--- a/llvm/include/llvm/IR/Intrinsics.td
+++ b/llvm/include/llvm/IR/Intrinsics.td
@@ -49,6 +49,17 @@ def IntrArgMemOnly : IntrinsicProperty;
// accessible by the module being compiled. This is a weaker form of IntrNoMem.
def IntrInaccessibleMemOnly : IntrinsicProperty;
+
+
+class IntrinsicMemoryLocation;
+// This should be added in the Target, but once in IntrinsicsAArch64.td
+// It complains error: "Variable not defined: 'AArch64_FPMR'"
+def AArch64_FPMR : IntrinsicMemoryLocation;
+def AArch64_ZA: IntrinsicMemoryLocation;
+// IntrInaccessible{Read|Write}MemOnly needs to set Location
+class IntrInaccessibleReadMemOnly<IntrinsicMemoryLocation idx> : IntrinsicProperty{IntrinsicMemoryLocation Loc=idx;}
+class IntrInaccessibleWriteMemOnly<IntrinsicMemoryLocation idx> : IntrinsicProperty{IntrinsicMemoryLocation Loc=idx;}
+
// IntrInaccessibleMemOrArgMemOnly -- This intrinsic only accesses memory that
// its pointer-typed arguments point to or memory that is not accessible
// by the module being compiled. This is a weaker form of IntrArgMemOnly.
diff --git a/llvm/include/llvm/IR/IntrinsicsAArch64.td b/llvm/include/llvm/IR/IntrinsicsAArch64.td
index ca6e2128812f7..5e0b5915d77fa 100644
--- a/llvm/include/llvm/IR/IntrinsicsAArch64.td
+++ b/llvm/include/llvm/IR/IntrinsicsAArch64.td
@@ -9,7 +9,6 @@
// This file defines all of the AARCH64-specific intrinsics.
//
//===----------------------------------------------------------------------===//
-
let TargetPrefix = "aarch64" in {
def int_aarch64_ldxr : Intrinsic<[llvm_i64_ty], [llvm_anyptr_ty],
diff --git a/llvm/include/llvm/Support/ModRef.h b/llvm/include/llvm/Support/ModRef.h
index 71f3b5bcb9c2b..8459876bf34a6 100644
--- a/llvm/include/llvm/Support/ModRef.h
+++ b/llvm/include/llvm/Support/ModRef.h
@@ -56,6 +56,11 @@ enum class ModRefInfo : uint8_t {
/// Debug print ModRefInfo.
LLVM_ABI raw_ostream &operator<<(raw_ostream &OS, ModRefInfo MR);
+enum class InaccessibleTargetMemLocation {
+ AARCH64_FPMR = 3,
+ AARCH64_ZA = 4,
+};
+
/// The locations at which a function might access memory.
enum class IRMemLocation {
/// Access to memory via argument pointers.
@@ -65,7 +70,7 @@ enum class IRMemLocation {
/// Errno memory.
ErrnoMem = 2,
/// Any other memory.
- Other = 3,
+ Other = 5,
/// Helpers to iterate all locations in the MemoryEffectsBase class.
First = ArgMem,
@@ -142,6 +147,18 @@ template <typename LocationEnum> class MemoryEffectsBase {
return MemoryEffectsBase(Location::InaccessibleMem, MR);
}
+ /// Create MemoryEffectsBase that can only read inaccessible memory.
+ static MemoryEffectsBase
+ inaccessibleReadMemOnly(Location Loc = Location::InaccessibleMem) {
+ return MemoryEffectsBase(Loc, ModRefInfo::Ref);
+ }
+
+ /// Create MemoryEffectsBase that can only write inaccessible memory.
+ static MemoryEffectsBase
+ inaccessibleWriteMemOnly(Location Loc = Location::InaccessibleMem) {
+ return MemoryEffectsBase(Loc, ModRefInfo::Mod);
+ }
+
/// Create MemoryEffectsBase that can only access errno memory.
static MemoryEffectsBase errnoMemOnly(ModRefInfo MR = ModRefInfo::ModRef) {
return MemoryEffectsBase(Location::ErrnoMem, MR);
@@ -178,6 +195,11 @@ template <typename LocationEnum> class MemoryEffectsBase {
return MemoryEffectsBase(Data);
}
+ bool isTargetMemLoc(IRMemLocation Loc) {
+ return static_cast<unsigned>(Loc) >
+ static_cast<unsigned>(Location::ErrnoMem);
+ }
+
/// Convert MemoryEffectsBase into an encoded integer value (used by memory
/// attribute).
uint32_t toIntValue() const {
diff --git a/llvm/include/llvm/TableGen/Record.h b/llvm/include/llvm/TableGen/Record.h
index a2b86eb8e7cad..5aeb331c49c9b 100644
--- a/llvm/include/llvm/TableGen/Record.h
+++ b/llvm/include/llvm/TableGen/Record.h
@@ -25,6 +25,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/ModRef.h"
#include "llvm/Support/SMLoc.h"
#include "llvm/Support/Timer.h"
#include "llvm/Support/TrailingObjects.h"
@@ -1961,6 +1962,8 @@ class Record {
/// value is not the right type.
int64_t getValueAsInt(StringRef FieldName) const;
+ llvm::IRMemLocation getLocationTypeAsInt(StringRef FieldName) const;
+
/// This method looks up the specified field and returns its value as an Dag,
/// throwing an exception if the field does not exist or if the value is not
/// the right type.
diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp
index ce813e1d7b1c4..d7ac109d3a7bf 100644
--- a/llvm/lib/AsmParser/LLLexer.cpp
+++ b/llvm/lib/AsmParser/LLLexer.cpp
@@ -701,10 +701,14 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(write);
KEYWORD(readwrite);
KEYWORD(argmem);
+ KEYWORD(fpmr);
+ KEYWORD(za);
KEYWORD(inaccessiblemem);
KEYWORD(errnomem);
KEYWORD(argmemonly);
KEYWORD(inaccessiblememonly);
+ KEYWORD(inaccessiblewritememonly);
+ KEYWORD(inaccessiblereadmemonly);
KEYWORD(inaccessiblemem_or_argmemonly);
KEYWORD(nocapture);
KEYWORD(address_is_null);
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index b7f6950f679ef..fcc53829e60fa 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -1666,6 +1666,48 @@ static bool upgradeMemoryAttr(MemoryEffects &ME, lltok::Kind Kind) {
}
}
+static std::optional<MemoryEffects::Location> keywordToLoc(lltok::Kind Tok) {
+ switch (Tok) {
+ case lltok::kw_argmem:
+ return IRMemLocation::ArgMem;
+ case lltok::kw_inaccessiblemem:
+ return IRMemLocation::InaccessibleMem;
+ case lltok::kw_errnomem:
+ return IRMemLocation::ErrnoMem;
+ case lltok::kw_fpmr:
+ return static_cast<IRMemLocation>(
+ llvm::InaccessibleTargetMemLocation::AARCH64_FPMR);
+ case lltok::kw_za:
+ return static_cast<IRMemLocation>(
+ llvm::InaccessibleTargetMemLocation::AARCH64_ZA);
+ default:
+ return std::nullopt;
+ }
+}
+
+bool LLParser::parseInaccessibleMemLocation(IRMemLocation &MemLoc) {
+ // It does not have location
+ if (Lex.getKind() != llvm::lltok::lparen)
+ return false;
+
+ Lex.Lex(); // eat '('
+
+ std::optional<IRMemLocation> LocOpt = keywordToLoc(Lex.getKind());
+ if (!LocOpt)
+ return tokError("invalid memory location keyword");
+
+ MemLoc = *LocOpt;
+
+ Lex.Lex(); // eat the keyword (e.g., 'fpmr', 'za')
+
+ if (Lex.getKind() != llvm::lltok::rparen)
+ return tokError("expected ')' after memory location");
+
+ Lex.Lex(); // eat ')'
+
+ return true; // success
+}
+
/// parseFnAttributeValuePairs
/// ::= <attr> | <attr> '=' <value>
bool LLParser::parseFnAttributeValuePairs(AttrBuilder &B,
@@ -1676,6 +1718,11 @@ bool LLParser::parseFnAttributeValuePairs(AttrBuilder &B,
B.clear();
MemoryEffects ME = MemoryEffects::unknown();
+ // Memory effects can span multiple locations, so we initialize a base
+ // MemoryEffects object once with default state, and then incrementally
+ // populate or combine effects for individual locations. This avoids
+ // rebuilding the full Data structure on each addition.
+ bool FirstME = true;
while (true) {
lltok::Kind Token = Lex.getKind();
if (Token == lltok::rbrace)
@@ -1712,6 +1759,36 @@ bool LLParser::parseFnAttributeValuePairs(AttrBuilder &B,
continue;
}
+ if (Token == lltok::kw_inaccessiblereadmemonly) {
+ Lex.Lex(); // eat the keyword
+
+ IRMemLocation MemLoc;
+ if (parseInaccessibleMemLocation(MemLoc)) {
+ if (!FirstME)
+ ME = ME.getWithModRef(MemLoc, ModRefInfo::Ref);
+ else
+ ME &= MemoryEffects::inaccessibleReadMemOnly(MemLoc);
+ } else
+ ME = MemoryEffects::inaccessibleReadMemOnly();
+ FirstME = false;
+ continue;
+ }
+
+ if (Token == lltok::kw_inaccessiblewritememonly) {
+ Lex.Lex(); // eat the keyword
+
+ IRMemLocation MemLoc;
+ if (parseInaccessibleMemLocation(MemLoc)) {
+ if (!FirstME)
+ ME = ME.getWithModRef(MemLoc, ModRefInfo::Mod);
+ else
+ ME &= MemoryEffects::inaccessibleWriteMemOnly(MemLoc);
+ } else
+ ME &= MemoryEffects::inaccessibleWriteMemOnly();
+ FirstME = false;
+ continue;
+ }
+
Attribute::AttrKind Attr = tokenToAttribute(Token);
if (Attr == Attribute::None) {
if (!InAttrGrp)
@@ -2510,19 +2587,6 @@ bool LLParser::parseAllocKind(AllocFnKind &Kind) {
return false;
}
-static std::optional<MemoryEffects::Location> keywordToLoc(lltok::Kind Tok) {
- switch (Tok) {
- case lltok::kw_argmem:
- return IRMemLocation::ArgMem;
- case lltok::kw_inaccessiblemem:
- return IRMemLocation::InaccessibleMem;
- case lltok::kw_errnomem:
- return IRMemLocation::ErrnoMem;
- default:
- return std::nullopt;
- }
-}
-
static std::optional<ModRefInfo> keywordToModRef(lltok::Kind Tok) {
switch (Tok) {
case lltok::kw_none:
@@ -2533,6 +2597,10 @@ static std::optional<ModRefInfo> keywordToModRef(lltok::Kind Tok) {
return ModRefInfo::Mod;
case lltok::kw_readwrite:
return ModRefInfo::ModRef;
+ case lltok::kw_inaccessiblewritememonly:
+ return ModRefInfo::Mod;
+ case lltok::kw_inaccessiblereadmemonly:
+ return ModRefInfo::Ref;
default:
return std::nullopt;
}
diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp
index d1fbcb9e893a7..5d5f207350f89 100644
--- a/llvm/lib/IR/Attributes.cpp
+++ b/llvm/lib/IR/Attributes.cpp
@@ -640,6 +640,10 @@ std::string Attribute::getAsString(bool InAttrGrp) const {
if (MR == OtherMR)
continue;
+ // Dont want to print Target Location if NoModRef
+ if (ME.isTargetMemLoc(Loc) && (MR == ModRefInfo::NoModRef))
+ continue;
+
if (!First)
OS << ", ";
First = false;
@@ -656,6 +660,15 @@ std::string Attribute::getAsString(bool InAttrGrp) const {
break;
case IRMemLocation::Other:
llvm_unreachable("This is represented as the default access kind");
+ default: {
+ InaccessibleTargetMemLocation TargetLoc =
+ static_cast<InaccessibleTargetMemLocation>(Loc);
+ if (TargetLoc == InaccessibleTargetMemLocation::AARCH64_FPMR)
+ OS << "fpmr: ";
+ if (TargetLoc == InaccessibleTargetMemLocation::AARCH64_ZA)
+ OS << "za: ";
+ break;
+ }
}
OS << getModRefStr(MR);
}
diff --git a/llvm/lib/Support/ModRef.cpp b/llvm/lib/Support/ModRef.cpp
index 2bb9bc945bd2e..82ae2b3acf831 100644
--- a/llvm/lib/Support/ModRef.cpp
+++ b/llvm/lib/Support/ModRef.cpp
@@ -49,6 +49,15 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, MemoryEffects ME) {
case IRMemLocation::Other:
OS << "Other: ";
break;
+ default: {
+ InaccessibleTargetMemLocation TargetLoc =
+ static_cast<InaccessibleTargetMemLocation>(Loc);
+ if (TargetLoc == InaccessibleTargetMemLocation::AARCH64_FPMR)
+ OS << "FPMR: ";
+ if (TargetLoc == InaccessibleTargetMemLocation::AARCH64_ZA)
+ OS << "ZA: ";
+ break;
+ }
}
OS << ME.getModRef(Loc);
});
diff --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp
index 1f3e5dc68f1d6..b3ff26a57755c 100644
--- a/llvm/lib/TableGen/Record.cpp
+++ b/llvm/lib/TableGen/Record.cpp
@@ -3102,6 +3102,21 @@ Record::getValueAsListOfDefs(StringRef FieldName) const {
return Defs;
}
+llvm::IRMemLocation Record::getLocationTypeAsInt(StringRef FieldName) const {
+ const Record *LocRec = getValueAsDef(FieldName);
+ StringRef Name = LocRec->getName();
+ if (Name == "AArch64_FPMR")
+ return static_cast<IRMemLocation>(
+ llvm::InaccessibleTargetMemLocation::AARCH64_FPMR);
+ else if (Name == "ZA")
+ return static_cast<IRMemLocation>(
+ llvm::InaccessibleTargetMemLocation::AARCH64_ZA);
+ else if (Name == "InaccessibleMem")
+ return llvm::IRMemLocation::InaccessibleMem;
+ else
+ PrintFatalError(getLoc(), "unknown IRMemLocation: " + Name);
+}
+
int64_t Record::getValueAsInt(StringRef FieldName) const {
const RecordVal *R = getValue(FieldName);
if (!R || !R->getValue())
diff --git a/llvm/test/Assembler/memory-attribute.ll b/llvm/test/Assembler/memory-attribute.ll
index effd4ce7c4548..473468810768b 100644
--- a/llvm/test/Assembler/memory-attribute.ll
+++ b/llvm/test/Assembler/memory-attribute.ll
@@ -78,3 +78,24 @@ declare void @fn_argmem_read_inaccessiblemem_write()
; CHECK: @fn_argmem_read_inaccessiblemem_write_reordered()
declare void @fn_argmem_read_inaccessiblemem_write_reordered()
memory(inaccessiblemem: write, argmem: read)
+
+; CHECK: Function Attrs: memory(za: write)
+; CHECK: @fn_argmem_read_inaccessiblemem_write_za()
+declare void @fn_argmem_read_inaccessiblemem_write_za()
+ memory(za: inaccessiblewritememonly)
+
+; CHECK: Function Attrs: memory(za: read)
+; CHECK: @fn_argmem_read_inaccessiblemem_read_za()
+declare void @fn_argmem_read_inaccessiblemem_read_za()
+ memory(za: inaccessiblereadmemonly)
+
+; CHECK: Function Attrs: memory(fpmr: write)
+; CHECK: @fn_argmem_read_inaccessiblemem_write_fpmr()
+declare void @fn_argmem_read_inaccessiblemem_write_fpmr()
+ memory(fpmr: inaccessiblewritememonly)
+
+; CHECK: Function Attrs: memory(fpmr: read)
+; CHECK: @fn_argmem_read_inaccessiblemem_read_fpmr()
+declare void @fn_argmem_read_inaccessiblemem_read_fpmr()
+ memory(fpmr: inaccessiblereadmemonly)
+
diff --git a/llvm/test/Bitcode/attributes.ll b/llvm/test/Bitcode/attributes.ll
index 8c1a76365e1b4..89ea5eb302029 100644
--- a/llvm/test/Bitcode/attributes.ll
+++ b/llvm/test/Bitcode/attributes.ll
@@ -286,6 +286,7 @@ define void @f48() inaccessiblememonly {
define void @f49() inaccessiblemem_or_argmemonly {
ret void
}
+
; CHECK: define void @f50(ptr swiftself %0)
define void @f50(ptr swiftself %0)
{
@@ -572,6 +573,42 @@ define void @dead_on_return(ptr dead_on_return %p) {
ret void
}
+; CHECK: define void @fpmr_write() [[ATTR59:#.*]] {
+define void @fpmr_write() inaccessiblewritememonly(fpmr) {
+ ret void
+}
+
+; CHECK: define void @fpmr_read() [[ATTR60:#.*]] {
+define void @fpmr_read() inaccessiblereadmemonly(fpmr) {
+ ret void
+}
+
+; CHECK: define void @za_write() [[ATTR61:#.*]] {
+define void @za_write() inaccessiblewritememonly(za) {
+ ret void
+}
+
+; CHECK: define void @za_read() [[ATTR62:#.*]] {
+define void @za_read() inaccessiblereadmemonly(za) {
+ ret void
+}
+
+; CHECK: define void @read_inaccessible() [[ATTR63:#.*]] {
+define void @read_inaccessible() inaccessiblereadmemonly {
+ ret void
+}
+
+; CHECK: define void @write_inaccessible() [[ATTR64:#.*]] {
+define void @write_inaccessible() inaccessiblewritememonly {
+ ret void
+}
+
+; CHECK: define void @za_read_write_fpmr() [[ATTR65:#.*]] {
+define void @za_read_write_fpmr() inaccessiblereadmemonly(za) inaccessiblewritememonly(fpmr) {
+ ret void
+}
+
+
; CHECK: attributes #0 = { noreturn }
; CHECK: attributes #1 = { nounwind }
; CHECK: attributes #2 = { memory(none) }
@@ -631,4 +668,11 @@ define void @dead_on_return(ptr dead_on_return %p) {
; CHECK: attributes [[SKIPPROFILE]] = { skipprofile }
; CHECK: attributes [[OPTDEBUG]] = { optdebug }
; CHECK: attributes [[NODIVERGENCESOURCE]] = { nodivergencesource }
+; CHECK: attributes [[ATTR59]] = { memory(fpmr: write) }
+; CHECK: attributes [[ATTR60]] = { memory(fpmr: read) }
+; CHECK: attributes [[ATTR61]] = { memory(za: write) }
+; CHECK: attributes [[ATTR62]] = { memory(za: read) }
+; CHECK: attributes [[ATTR63]] = { memory(inaccessiblemem: read) }
+; CHECK: attributes [[ATTR64]] = { memory(inaccessiblemem: write) }
+; CHECK: attributes [[ATTR65]] = { memory(fpmr: write, za: read) }
; CHECK: attributes #[[NOBUILTIN]] = { nobuiltin }
diff --git a/llvm/test/TableGen/intrinsic-attrs-fp8.td b/llvm/test/TableGen/intrinsic-attrs-fp8.td
new file mode 100644
index 0000000000000..53ff1dfe2b807
--- /dev/null
+++ b/llvm/test/TableGen/intrinsic-attrs-fp8.td
@@ -0,0 +1,24 @@
+// RUN: llvm-tblgen -gen-intrinsic-impl -I %p/../../include -DTEST_INTRINSICS_SUPPRESS_DEFS %s | FileCheck %s
+
+include "llvm/IR/Intrinsics.td"
+
+def int_aarch64_set_fpmr_2 : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [IntrInaccessibleWriteMemOnly<AArch64_FPMR>]>;
+
+// CHECK: static constexpr unsigned IntrinsicNameOffsetTable[] = {
+// CHECK-NEXT: 1, // not_intrinsic
+// CHECK-NEXT: 15, // llvm.aarch64.set.fpmr.2
+
+
+// CHECK: static AttributeSet getIntrinsicFnAttributeSet(LLVMContext &C, unsigned ID) {
+// CHECK-NEXT: switch (ID) {
+// CHECK-NEXT: default: llvm_unreachable("Invalid attribute set number");
+// CHECK-NEXT: case 0:
+// CHECK-NEXT: return AttributeSet::get(C, {
+// CHECK-NEXT: Attribute::get(C, Attribute::NoUnwind),
+// CHECK-NEXT: Attribute::get(C, Attribute::NoCallback),
+// CHECK-NEXT: Attribute::get(C, Attribute::NoSync),
+// CHECK-NEXT: Attribute::get(C, Attribute::NoFree),
+// CHECK-NEXT: Attribute::get(C, Attribute::WillReturn),
+// CHECK-NEXT: // ArgMem: NoModRef, InaccessibleMem: NoModRef, ErrnoMem: NoModRef, FPMR: Mod, ZA: NoModRef, Other: NoModRef
+// CHECK-NEXT: Attribute::getWithMemoryEffects(C, MemoryEffects::createFromIntValue(128)),
+// CHECK-NEXT: });
diff --git a/llvm/unittests/Support/ModRefTest.cpp b/llvm/unittests/Support/ModRefTest.cpp
index 9c13908da44bb..cbdf752978555 100644
--- a/llvm/unittests/Support/ModRefTest.cpp
+++ b/llvm/unittests/Support/ModRefTest.cpp
@@ -21,7 +21,7 @@ TEST(ModRefTest, PrintMemoryEffects) {
raw_string_ostream OS(S);
OS << MemoryEffects::none();
EXPECT_EQ(S, "ArgMem: NoModRef, InaccessibleMem: NoModRef, ErrnoMem: "
- "NoModRef, Other: NoModRef");
+ "NoModRef, FPMR: NoModRef, ZA: NoModRef, Other: NoModRef");
}
} // namespace
diff --git a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
index bc42efa3b2e9c..f53915642ac6d 100644
--- a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
+++ b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
@@ -374,7 +374,13 @@ void CodeGenIntrinsic::setProperty(const Record *R) {
ME &= MemoryEffects::argMemOnly();
else if (R->getName() == "IntrInaccessibleMemOnly")
ME &= MemoryEffects::inaccessibleMemOnly();
- else if (R->getName() == "IntrInaccessibleMemOrArgMemOnly")
+ else if (R->isSubClassOf("IntrInaccessibleReadMemOnly")) {
+ llvm::IRMemLocation Loc = R->getLocationTypeAsInt("Loc");
+ ME &= MemoryEffects::inaccessibleWriteMemOnly(Loc);
+ } else if (R->isSubClassOf("IntrInaccessibleWriteMemOnly")) {
+ llvm::IRMemLocation Loc = R->getLocationTypeAsInt("Loc");
+ ME &= MemoryEffects::inaccessibleWriteMemOnly(Loc);
+ } else if (R->getName() == "IntrInaccessibleMemOrArgMemOnly")
ME &= MemoryEffects::inaccessibleOrArgMemOnly();
else if (R->getName() == "Commutative")
isCommutative = true;
>From 7512b21ad6eeaaa67edcfa876d15001de9f12c0f Mon Sep 17 00:00:00 2001
From: CarolineConcatto <caroline.concatto at arm.com>
Date: Tue, 15 Jul 2025 10:56:25 +0000
Subject: [PATCH 2/2] Address review comments about tests and names
This patch is removing the keyworkd and token inaccessibleWrite and
inaccessibleRead. It is using Read and Write to set the Target Memory
Location.
Adding "aarch64" in front of the target specific memory locations
---
llvm/include/llvm/AsmParser/LLToken.h | 6 +-
llvm/include/llvm/Support/ModRef.h | 12 ----
llvm/lib/AsmParser/LLLexer.cpp | 6 +-
llvm/lib/AsmParser/LLParser.cpp | 66 +------------------
llvm/lib/IR/Attributes.cpp | 4 +-
llvm/lib/Support/ModRef.cpp | 4 +-
llvm/lib/TableGen/Record.cpp | 2 +-
llvm/test/Assembler/memory-attribute.ll | 44 +++++++------
llvm/test/Bitcode/attributes.ll | 8 ---
llvm/test/TableGen/intrinsic-attrs-fp8.td | 46 ++++++++++---
llvm/unittests/Support/ModRefTest.cpp | 3 +-
.../TableGen/Basic/CodeGenIntrinsics.cpp | 4 +-
12 files changed, 77 insertions(+), 128 deletions(-)
diff --git a/llvm/include/llvm/AsmParser/LLToken.h b/llvm/include/llvm/AsmParser/LLToken.h
index 68920af75c667..c08eb99c1f5b2 100644
--- a/llvm/include/llvm/AsmParser/LLToken.h
+++ b/llvm/include/llvm/AsmParser/LLToken.h
@@ -202,15 +202,13 @@ enum Kind {
kw_readwrite,
kw_argmem,
kw_inaccessiblemem,
- kw_fpmr,
- kw_za,
+ kw_aarch64_fpmr,
+ kw_aarch64_za,
kw_errnomem,
// Legacy attributes:
kw_argmemonly,
kw_inaccessiblememonly,
- kw_inaccessiblereadmemonly,
- kw_inaccessiblewritememonly,
kw_inaccessiblemem_or_argmemonly,
kw_nocapture,
diff --git a/llvm/include/llvm/Support/ModRef.h b/llvm/include/llvm/Support/ModRef.h
index 8459876bf34a6..329218900f8ca 100644
--- a/llvm/include/llvm/Support/ModRef.h
+++ b/llvm/include/llvm/Support/ModRef.h
@@ -147,18 +147,6 @@ template <typename LocationEnum> class MemoryEffectsBase {
return MemoryEffectsBase(Location::InaccessibleMem, MR);
}
- /// Create MemoryEffectsBase that can only read inaccessible memory.
- static MemoryEffectsBase
- inaccessibleReadMemOnly(Location Loc = Location::InaccessibleMem) {
- return MemoryEffectsBase(Loc, ModRefInfo::Ref);
- }
-
- /// Create MemoryEffectsBase that can only write inaccessible memory.
- static MemoryEffectsBase
- inaccessibleWriteMemOnly(Location Loc = Location::InaccessibleMem) {
- return MemoryEffectsBase(Loc, ModRefInfo::Mod);
- }
-
/// Create MemoryEffectsBase that can only access errno memory.
static MemoryEffectsBase errnoMemOnly(ModRefInfo MR = ModRefInfo::ModRef) {
return MemoryEffectsBase(Location::ErrnoMem, MR);
diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp
index d7ac109d3a7bf..c086f9f9585a2 100644
--- a/llvm/lib/AsmParser/LLLexer.cpp
+++ b/llvm/lib/AsmParser/LLLexer.cpp
@@ -701,14 +701,12 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(write);
KEYWORD(readwrite);
KEYWORD(argmem);
- KEYWORD(fpmr);
- KEYWORD(za);
+ KEYWORD(aarch64_fpmr);
+ KEYWORD(aarch64_za);
KEYWORD(inaccessiblemem);
KEYWORD(errnomem);
KEYWORD(argmemonly);
KEYWORD(inaccessiblememonly);
- KEYWORD(inaccessiblewritememonly);
- KEYWORD(inaccessiblereadmemonly);
KEYWORD(inaccessiblemem_or_argmemonly);
KEYWORD(nocapture);
KEYWORD(address_is_null);
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index fcc53829e60fa..abde2993bb048 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -1674,10 +1674,10 @@ static std::optional<MemoryEffects::Location> keywordToLoc(lltok::Kind Tok) {
return IRMemLocation::InaccessibleMem;
case lltok::kw_errnomem:
return IRMemLocation::ErrnoMem;
- case lltok::kw_fpmr:
+ case lltok::kw_aarch64_fpmr:
return static_cast<IRMemLocation>(
llvm::InaccessibleTargetMemLocation::AARCH64_FPMR);
- case lltok::kw_za:
+ case lltok::kw_aarch64_za:
return static_cast<IRMemLocation>(
llvm::InaccessibleTargetMemLocation::AARCH64_ZA);
default:
@@ -1685,29 +1685,6 @@ static std::optional<MemoryEffects::Location> keywordToLoc(lltok::Kind Tok) {
}
}
-bool LLParser::parseInaccessibleMemLocation(IRMemLocation &MemLoc) {
- // It does not have location
- if (Lex.getKind() != llvm::lltok::lparen)
- return false;
-
- Lex.Lex(); // eat '('
-
- std::optional<IRMemLocation> LocOpt = keywordToLoc(Lex.getKind());
- if (!LocOpt)
- return tokError("invalid memory location keyword");
-
- MemLoc = *LocOpt;
-
- Lex.Lex(); // eat the keyword (e.g., 'fpmr', 'za')
-
- if (Lex.getKind() != llvm::lltok::rparen)
- return tokError("expected ')' after memory location");
-
- Lex.Lex(); // eat ')'
-
- return true; // success
-}
-
/// parseFnAttributeValuePairs
/// ::= <attr> | <attr> '=' <value>
bool LLParser::parseFnAttributeValuePairs(AttrBuilder &B,
@@ -1718,11 +1695,6 @@ bool LLParser::parseFnAttributeValuePairs(AttrBuilder &B,
B.clear();
MemoryEffects ME = MemoryEffects::unknown();
- // Memory effects can span multiple locations, so we initialize a base
- // MemoryEffects object once with default state, and then incrementally
- // populate or combine effects for individual locations. This avoids
- // rebuilding the full Data structure on each addition.
- bool FirstME = true;
while (true) {
lltok::Kind Token = Lex.getKind();
if (Token == lltok::rbrace)
@@ -1759,36 +1731,6 @@ bool LLParser::parseFnAttributeValuePairs(AttrBuilder &B,
continue;
}
- if (Token == lltok::kw_inaccessiblereadmemonly) {
- Lex.Lex(); // eat the keyword
-
- IRMemLocation MemLoc;
- if (parseInaccessibleMemLocation(MemLoc)) {
- if (!FirstME)
- ME = ME.getWithModRef(MemLoc, ModRefInfo::Ref);
- else
- ME &= MemoryEffects::inaccessibleReadMemOnly(MemLoc);
- } else
- ME = MemoryEffects::inaccessibleReadMemOnly();
- FirstME = false;
- continue;
- }
-
- if (Token == lltok::kw_inaccessiblewritememonly) {
- Lex.Lex(); // eat the keyword
-
- IRMemLocation MemLoc;
- if (parseInaccessibleMemLocation(MemLoc)) {
- if (!FirstME)
- ME = ME.getWithModRef(MemLoc, ModRefInfo::Mod);
- else
- ME &= MemoryEffects::inaccessibleWriteMemOnly(MemLoc);
- } else
- ME &= MemoryEffects::inaccessibleWriteMemOnly();
- FirstME = false;
- continue;
- }
-
Attribute::AttrKind Attr = tokenToAttribute(Token);
if (Attr == Attribute::None) {
if (!InAttrGrp)
@@ -2597,10 +2539,6 @@ static std::optional<ModRefInfo> keywordToModRef(lltok::Kind Tok) {
return ModRefInfo::Mod;
case lltok::kw_readwrite:
return ModRefInfo::ModRef;
- case lltok::kw_inaccessiblewritememonly:
- return ModRefInfo::Mod;
- case lltok::kw_inaccessiblereadmemonly:
- return ModRefInfo::Ref;
default:
return std::nullopt;
}
diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp
index 5d5f207350f89..37e9d7c5c74db 100644
--- a/llvm/lib/IR/Attributes.cpp
+++ b/llvm/lib/IR/Attributes.cpp
@@ -664,9 +664,9 @@ std::string Attribute::getAsString(bool InAttrGrp) const {
InaccessibleTargetMemLocation TargetLoc =
static_cast<InaccessibleTargetMemLocation>(Loc);
if (TargetLoc == InaccessibleTargetMemLocation::AARCH64_FPMR)
- OS << "fpmr: ";
+ OS << "aarch64_fpmr: ";
if (TargetLoc == InaccessibleTargetMemLocation::AARCH64_ZA)
- OS << "za: ";
+ OS << "aarch64_za: ";
break;
}
}
diff --git a/llvm/lib/Support/ModRef.cpp b/llvm/lib/Support/ModRef.cpp
index 82ae2b3acf831..dc0dafdbe7e49 100644
--- a/llvm/lib/Support/ModRef.cpp
+++ b/llvm/lib/Support/ModRef.cpp
@@ -53,9 +53,9 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, MemoryEffects ME) {
InaccessibleTargetMemLocation TargetLoc =
static_cast<InaccessibleTargetMemLocation>(Loc);
if (TargetLoc == InaccessibleTargetMemLocation::AARCH64_FPMR)
- OS << "FPMR: ";
+ OS << "AARCH64_FPMR: ";
if (TargetLoc == InaccessibleTargetMemLocation::AARCH64_ZA)
- OS << "ZA: ";
+ OS << "AARCH64_ZA: ";
break;
}
}
diff --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp
index b3ff26a57755c..d114358266737 100644
--- a/llvm/lib/TableGen/Record.cpp
+++ b/llvm/lib/TableGen/Record.cpp
@@ -3108,7 +3108,7 @@ llvm::IRMemLocation Record::getLocationTypeAsInt(StringRef FieldName) const {
if (Name == "AArch64_FPMR")
return static_cast<IRMemLocation>(
llvm::InaccessibleTargetMemLocation::AARCH64_FPMR);
- else if (Name == "ZA")
+ else if (Name == "AArch64_ZA")
return static_cast<IRMemLocation>(
llvm::InaccessibleTargetMemLocation::AARCH64_ZA);
else if (Name == "InaccessibleMem")
diff --git a/llvm/test/Assembler/memory-attribute.ll b/llvm/test/Assembler/memory-attribute.ll
index 473468810768b..42f9b9f87e8b0 100644
--- a/llvm/test/Assembler/memory-attribute.ll
+++ b/llvm/test/Assembler/memory-attribute.ll
@@ -79,23 +79,27 @@ declare void @fn_argmem_read_inaccessiblemem_write()
declare void @fn_argmem_read_inaccessiblemem_write_reordered()
memory(inaccessiblemem: write, argmem: read)
-; CHECK: Function Attrs: memory(za: write)
-; CHECK: @fn_argmem_read_inaccessiblemem_write_za()
-declare void @fn_argmem_read_inaccessiblemem_write_za()
- memory(za: inaccessiblewritememonly)
-
-; CHECK: Function Attrs: memory(za: read)
-; CHECK: @fn_argmem_read_inaccessiblemem_read_za()
-declare void @fn_argmem_read_inaccessiblemem_read_za()
- memory(za: inaccessiblereadmemonly)
-
-; CHECK: Function Attrs: memory(fpmr: write)
-; CHECK: @fn_argmem_read_inaccessiblemem_write_fpmr()
-declare void @fn_argmem_read_inaccessiblemem_write_fpmr()
- memory(fpmr: inaccessiblewritememonly)
-
-; CHECK: Function Attrs: memory(fpmr: read)
-; CHECK: @fn_argmem_read_inaccessiblemem_read_fpmr()
-declare void @fn_argmem_read_inaccessiblemem_read_fpmr()
- memory(fpmr: inaccessiblereadmemonly)
-
+; CHECK: Function Attrs: memory(aarch64_za: write)
+; CHECK: @fn_inaccessiblemem_write_aarch64_za()
+declare void @fn_inaccessiblemem_write_aarch64_za()
+ memory(aarch64_za: write)
+
+; CHECK: Function Attrs: memory(aarch64_za: read)
+; CHECK: @fn_inaccessiblemem_read_aarch64_za()
+declare void @fn_inaccessiblemem_read_aarch64_za()
+ memory(aarch64_za: read)
+
+; CHECK: Function Attrs: memory(aarch64_fpmr: write)
+; CHECK: @fn_inaccessiblemem_write_aarch64_fpmr()
+declare void @fn_inaccessiblemem_write_aarch64_fpmr()
+ memory(aarch64_fpmr: write)
+
+; CHECK: Function Attrs: memory(aarch64_fpmr: read)
+; CHECK: @fn_inaccessiblemem_read_aarch64_fpmr()
+declare void @fn_inaccessiblemem_read_aarch64_fpmr()
+ memory(aarch64_fpmr: read)
+
+; CHECK: Function Attrs: memory(aarch64_fpmr: read, aarch64_za: write)
+; CHECK: @fn_inaccessiblemem_read_aarch64_fpmr_write_aarch64_za()
+declare void @fn_inaccessiblemem_read_aarch64_fpmr_write_aarch64_za()
+ memory(aarch64_fpmr: read, aarch64_za: write)
diff --git a/llvm/test/Bitcode/attributes.ll b/llvm/test/Bitcode/attributes.ll
index 89ea5eb302029..2c4b7d63e1ceb 100644
--- a/llvm/test/Bitcode/attributes.ll
+++ b/llvm/test/Bitcode/attributes.ll
@@ -608,7 +608,6 @@ define void @za_read_write_fpmr() inaccessiblereadmemonly(za) inaccessiblewritem
ret void
}
-
; CHECK: attributes #0 = { noreturn }
; CHECK: attributes #1 = { nounwind }
; CHECK: attributes #2 = { memory(none) }
@@ -668,11 +667,4 @@ define void @za_read_write_fpmr() inaccessiblereadmemonly(za) inaccessiblewritem
; CHECK: attributes [[SKIPPROFILE]] = { skipprofile }
; CHECK: attributes [[OPTDEBUG]] = { optdebug }
; CHECK: attributes [[NODIVERGENCESOURCE]] = { nodivergencesource }
-; CHECK: attributes [[ATTR59]] = { memory(fpmr: write) }
-; CHECK: attributes [[ATTR60]] = { memory(fpmr: read) }
-; CHECK: attributes [[ATTR61]] = { memory(za: write) }
-; CHECK: attributes [[ATTR62]] = { memory(za: read) }
-; CHECK: attributes [[ATTR63]] = { memory(inaccessiblemem: read) }
-; CHECK: attributes [[ATTR64]] = { memory(inaccessiblemem: write) }
-; CHECK: attributes [[ATTR65]] = { memory(fpmr: write, za: read) }
; CHECK: attributes #[[NOBUILTIN]] = { nobuiltin }
diff --git a/llvm/test/TableGen/intrinsic-attrs-fp8.td b/llvm/test/TableGen/intrinsic-attrs-fp8.td
index 53ff1dfe2b807..76d4ec6058f87 100644
--- a/llvm/test/TableGen/intrinsic-attrs-fp8.td
+++ b/llvm/test/TableGen/intrinsic-attrs-fp8.td
@@ -4,14 +4,19 @@ include "llvm/IR/Intrinsics.td"
def int_aarch64_set_fpmr_2 : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [IntrInaccessibleWriteMemOnly<AArch64_FPMR>]>;
-// CHECK: static constexpr unsigned IntrinsicNameOffsetTable[] = {
-// CHECK-NEXT: 1, // not_intrinsic
-// CHECK-NEXT: 15, // llvm.aarch64.set.fpmr.2
+def int_aarch64_get_za_2 : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [IntrInaccessibleReadMemOnly<AArch64_ZA>]>;
+def int_aarch64_get_fpmr_set_za : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [IntrInaccessibleReadMemOnly<AArch64_FPMR>, IntrInaccessibleWriteMemOnly<AArch64_ZA>]>;
-// CHECK: static AttributeSet getIntrinsicFnAttributeSet(LLVMContext &C, unsigned ID) {
-// CHECK-NEXT: switch (ID) {
-// CHECK-NEXT: default: llvm_unreachable("Invalid attribute set number");
+// CHECK: static constexpr unsigned IntrinsicNameOffsetTable[] = {
+// CHECK-NEXT: 1, // not_intrinsic
+// CHECK-NEXT: 15, // llvm.aarch64.get.fpmr.set.za
+// CHECK-NEXT: 44, // llvm.aarch64.get.za.2
+// CHECK-NEXT: 66, // llvm.aarch64.set.fpmr.2
+
+// CHECK: static AttributeSet getIntrinsicFnAttributeSet(LLVMContext &C, unsigned ID) {
+// CHECK-NEXT: switch (ID) {
+// CHECK-NEXT: default: llvm_unreachable("Invalid attribute set number");
// CHECK-NEXT: case 0:
// CHECK-NEXT: return AttributeSet::get(C, {
// CHECK-NEXT: Attribute::get(C, Attribute::NoUnwind),
@@ -19,6 +24,31 @@ def int_aarch64_set_fpmr_2 : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [IntrIna
// CHECK-NEXT: Attribute::get(C, Attribute::NoSync),
// CHECK-NEXT: Attribute::get(C, Attribute::NoFree),
// CHECK-NEXT: Attribute::get(C, Attribute::WillReturn),
-// CHECK-NEXT: // ArgMem: NoModRef, InaccessibleMem: NoModRef, ErrnoMem: NoModRef, FPMR: Mod, ZA: NoModRef, Other: NoModRef
-// CHECK-NEXT: Attribute::getWithMemoryEffects(C, MemoryEffects::createFromIntValue(128)),
+// CHECK-NEXT: // ArgMem: ModRef, InaccessibleMem: ModRef, ErrnoMem: ModRef, AARCH64_FPMR: Ref, AARCH64_ZA: Mod, Other: ModRef
+// CHECK-NEXT: Attribute::getWithMemoryEffects(C, MemoryEffects::createFromIntValue(3711)),
+// CHECK-NEXT: });
+// CHECK-NEXT: case 1:
+// CHECK-NEXT: return AttributeSet::get(C, {
+// CHECK-NEXT: Attribute::get(C, Attribute::NoUnwind),
+// CHECK-NEXT: Attribute::get(C, Attribute::NoCallback),
+// CHECK-NEXT: Attribute::get(C, Attribute::NoSync),
+// CHECK-NEXT: Attribute::get(C, Attribute::NoFree),
+// CHECK-NEXT: Attribute::get(C, Attribute::WillReturn),
+// CHECK-NEXT: // ArgMem: ModRef, InaccessibleMem: ModRef, ErrnoMem: ModRef, AARCH64_FPMR: ModRef, AARCH64_ZA: Ref, Other: ModRef
+// CHECK-NEXT: Attribute::getWithMemoryEffects(C, MemoryEffects::createFromIntValue(3583)),
// CHECK-NEXT: });
+// CHECK-NEXT: case 2:
+// CHECK-NEXT: return AttributeSet::get(C, {
+// CHECK-NEXT: Attribute::get(C, Attribute::NoUnwind),
+// CHECK-NEXT: Attribute::get(C, Attribute::NoCallback),
+// CHECK-NEXT: Attribute::get(C, Attribute::NoSync),
+// CHECK-NEXT: Attribute::get(C, Attribute::NoFree),
+// CHECK-NEXT: Attribute::get(C, Attribute::WillReturn),
+// CHECK-NEXT: // ArgMem: ModRef, InaccessibleMem: ModRef, ErrnoMem: ModRef, AARCH64_FPMR: Mod, AARCH64_ZA: ModRef, Other: ModRef
+// CHECK-NEXT: Attribute::getWithMemoryEffects(C, MemoryEffects::createFromIntValue(4031)),
+
+// CHECK: static constexpr uint16_t IntrinsicsToAttributesMap[] = {
+// CHECK-NEXT: 0 << 8 | 0, // llvm.aarch64.get.fpmr.set.za
+// CHECK-NEXT: 1 << 8 | 0, // llvm.aarch64.get.za.2
+// CHECK-NEXT: 2 << 8 | 0, // llvm.aarch64.set.fpmr.2
+// CHECK-NEXT:};
diff --git a/llvm/unittests/Support/ModRefTest.cpp b/llvm/unittests/Support/ModRefTest.cpp
index cbdf752978555..7aa473ad20336 100644
--- a/llvm/unittests/Support/ModRefTest.cpp
+++ b/llvm/unittests/Support/ModRefTest.cpp
@@ -21,7 +21,8 @@ TEST(ModRefTest, PrintMemoryEffects) {
raw_string_ostream OS(S);
OS << MemoryEffects::none();
EXPECT_EQ(S, "ArgMem: NoModRef, InaccessibleMem: NoModRef, ErrnoMem: "
- "NoModRef, FPMR: NoModRef, ZA: NoModRef, Other: NoModRef");
+ "NoModRef, AARCH64_FPMR: NoModRef, AARCH64_ZA: NoModRef, Other: "
+ "NoModRef");
}
} // namespace
diff --git a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
index f53915642ac6d..ad6a5344e4b7c 100644
--- a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
+++ b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
@@ -376,10 +376,10 @@ void CodeGenIntrinsic::setProperty(const Record *R) {
ME &= MemoryEffects::inaccessibleMemOnly();
else if (R->isSubClassOf("IntrInaccessibleReadMemOnly")) {
llvm::IRMemLocation Loc = R->getLocationTypeAsInt("Loc");
- ME &= MemoryEffects::inaccessibleWriteMemOnly(Loc);
+ ME = ME.getWithModRef(Loc, ModRefInfo::Ref);
} else if (R->isSubClassOf("IntrInaccessibleWriteMemOnly")) {
llvm::IRMemLocation Loc = R->getLocationTypeAsInt("Loc");
- ME &= MemoryEffects::inaccessibleWriteMemOnly(Loc);
+ ME = ME.getWithModRef(Loc, ModRefInfo::Mod);
} else if (R->getName() == "IntrInaccessibleMemOrArgMemOnly")
ME &= MemoryEffects::inaccessibleOrArgMemOnly();
else if (R->getName() == "Commutative")
More information about the llvm-commits
mailing list