[clang] [llvm] [mlir] Extend MemoryEffects to Support Target-Specific Memory Locations (PR #148650)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 24 09:20:02 PDT 2025
https://github.com/CarolineConcatto updated https://github.com/llvm/llvm-project/pull/148650
>From 46fe79bd19d88d17b282b8f7d081bf8e5903a9e7 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 01/19] [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 9eb31d7e0a451..9e8e21b331644 100644
--- a/llvm/include/llvm/AsmParser/LLParser.h
+++ b/llvm/include/llvm/AsmParser/LLParser.h
@@ -300,6 +300,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 6de99fe182ad9..4576f983323ec 100644
--- a/llvm/include/llvm/AsmParser/LLToken.h
+++ b/llvm/include/llvm/AsmParser/LLToken.h
@@ -206,11 +206,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 4d59ee8676b9e..71e999861550a 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 b81edc385cd43..87a5e1ffad4b5 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 cb2721aba4f25..f515af3ebf841 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"
@@ -1966,6 +1967,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 7a6c19ece92ac..393e4fbc967c7 100644
--- a/llvm/lib/AsmParser/LLLexer.cpp
+++ b/llvm/lib/AsmParser/LLLexer.cpp
@@ -707,10 +707,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 5164cec33e6f5..0db5e0ab95a33 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -1688,6 +1688,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,
@@ -1698,6 +1740,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)
@@ -1734,6 +1781,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)
@@ -2544,19 +2621,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:
@@ -2567,6 +2631,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 4ac2ebd55dcac..8e3c7265bfbfc 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 afce803f3f568..e207f79646439 100644
--- a/llvm/lib/TableGen/Record.cpp
+++ b/llvm/lib/TableGen/Record.cpp
@@ -3142,6 +3142,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 Init *I = getValueInit(FieldName);
if (const auto *II = dyn_cast<IntInit>(I))
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 aef7810fe2c3b..9af6be3a08848 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)
{
@@ -577,6 +578,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) }
@@ -637,4 +674,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 cd866469792a2..b61e9c7ea200d 100644
--- a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
+++ b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
@@ -377,7 +377,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 0d61d316f0d5f36cda23af7f6ed4b7afaa825272 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 02/19] 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/IR/IntrinsicsAArch64.td | 1 +
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 | 45 -------------
llvm/test/TableGen/intrinsic-attrs-fp8.td | 46 ++++++++++---
llvm/unittests/Support/ModRefTest.cpp | 3 +-
.../TableGen/Basic/CodeGenIntrinsics.cpp | 4 +-
13 files changed, 78 insertions(+), 165 deletions(-)
diff --git a/llvm/include/llvm/AsmParser/LLToken.h b/llvm/include/llvm/AsmParser/LLToken.h
index 4576f983323ec..a3cfa646d1e21 100644
--- a/llvm/include/llvm/AsmParser/LLToken.h
+++ b/llvm/include/llvm/AsmParser/LLToken.h
@@ -206,15 +206,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/IR/IntrinsicsAArch64.td b/llvm/include/llvm/IR/IntrinsicsAArch64.td
index 87a5e1ffad4b5..b81edc385cd43 100644
--- a/llvm/include/llvm/IR/IntrinsicsAArch64.td
+++ b/llvm/include/llvm/IR/IntrinsicsAArch64.td
@@ -9,6 +9,7 @@
// 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 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 393e4fbc967c7..8d34d74a0535f 100644
--- a/llvm/lib/AsmParser/LLLexer.cpp
+++ b/llvm/lib/AsmParser/LLLexer.cpp
@@ -707,14 +707,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 0db5e0ab95a33..01f30b3a10593 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -1696,10 +1696,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:
@@ -1707,29 +1707,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,
@@ -1740,11 +1717,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)
@@ -1781,36 +1753,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)
@@ -2631,10 +2573,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 8e3c7265bfbfc..7a79ebdb243e2 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 e207f79646439..5b45355f7cb6c 100644
--- a/llvm/lib/TableGen/Record.cpp
+++ b/llvm/lib/TableGen/Record.cpp
@@ -3148,7 +3148,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 9af6be3a08848..283aeac6db565 100644
--- a/llvm/test/Bitcode/attributes.ll
+++ b/llvm/test/Bitcode/attributes.ll
@@ -286,7 +286,6 @@ 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)
{
@@ -578,43 +577,6 @@ 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) }
; CHECK: attributes #3 = { memory(read) }
@@ -674,11 +636,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 b61e9c7ea200d..733fe1f44a424 100644
--- a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
+++ b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
@@ -379,10 +379,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")
>From 52133b037551b38446f979c8aaa482142030f256 Mon Sep 17 00:00:00 2001
From: CarolineConcatto <caroline.concatto at arm.com>
Date: Tue, 15 Jul 2025 13:53:51 +0000
Subject: [PATCH 03/19] Remove old function header that doesn't exist
---
llvm/include/llvm/AsmParser/LLParser.h | 1 -
1 file changed, 1 deletion(-)
diff --git a/llvm/include/llvm/AsmParser/LLParser.h b/llvm/include/llvm/AsmParser/LLParser.h
index 9e8e21b331644..9eb31d7e0a451 100644
--- a/llvm/include/llvm/AsmParser/LLParser.h
+++ b/llvm/include/llvm/AsmParser/LLParser.h
@@ -300,7 +300,6 @@ 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);
>From b94a65ed23d93cda2d455951eeeaa1a3dde25c33 Mon Sep 17 00:00:00 2001
From: CarolineConcatto <caroline.concatto at arm.com>
Date: Wed, 16 Jul 2025 17:23:20 +0000
Subject: [PATCH 04/19] Fix test when target memory locations are combined
---
llvm/include/llvm/Support/ModRef.h | 24 +++++++++++++++++++
llvm/test/TableGen/intrinsic-attrs-fp8.td | 12 +++++-----
.../TableGen/Basic/CodeGenIntrinsics.cpp | 10 ++++++--
3 files changed, 38 insertions(+), 8 deletions(-)
diff --git a/llvm/include/llvm/Support/ModRef.h b/llvm/include/llvm/Support/ModRef.h
index 329218900f8ca..26c11c223bd0b 100644
--- a/llvm/include/llvm/Support/ModRef.h
+++ b/llvm/include/llvm/Support/ModRef.h
@@ -157,6 +157,30 @@ template <typename LocationEnum> class MemoryEffectsBase {
return MemoryEffectsBase(Location::Other, 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);
+ }
+
+ /// Checks if only target-specific memory locations are set.
+ /// Ignores standard locations like ArgMem or InaccessibleMem.
+ /// Needed because `Data` may be non-zero by default unless explicitly
+ /// cleared.
+ bool onlyAccessTargetMemoryLocation() {
+ return getWithoutLoc(static_cast<IRMemLocation>(
+ llvm::InaccessibleTargetMemLocation::AARCH64_FPMR))
+ .getWithoutLoc(static_cast<IRMemLocation>(
+ llvm::InaccessibleTargetMemLocation::AARCH64_ZA))
+ .doesNotAccessMemory();
+ }
+
/// Create MemoryEffectsBase that can only access inaccessible or argument
/// memory.
static MemoryEffectsBase
diff --git a/llvm/test/TableGen/intrinsic-attrs-fp8.td b/llvm/test/TableGen/intrinsic-attrs-fp8.td
index 76d4ec6058f87..5aaba44edcc45 100644
--- a/llvm/test/TableGen/intrinsic-attrs-fp8.td
+++ b/llvm/test/TableGen/intrinsic-attrs-fp8.td
@@ -24,8 +24,8 @@ def int_aarch64_get_fpmr_set_za : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [In
// 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: Ref, AARCH64_ZA: Mod, Other: ModRef
-// CHECK-NEXT: Attribute::getWithMemoryEffects(C, MemoryEffects::createFromIntValue(3711)),
+// CHECK-NEXT: // ArgMem: NoModRef, InaccessibleMem: NoModRef, ErrnoMem: NoModRef, AARCH64_FPMR: Ref, AARCH64_ZA: Mod, Other: NoModRef
+// CHECK-NEXT: Attribute::getWithMemoryEffects(C, MemoryEffects::createFromIntValue(576)),
// CHECK-NEXT: });
// CHECK-NEXT: case 1:
// CHECK-NEXT: return AttributeSet::get(C, {
@@ -34,8 +34,8 @@ def int_aarch64_get_fpmr_set_za : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [In
// 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: // ArgMem: NoModRef, InaccessibleMem: NoModRef, ErrnoMem: NoModRef, AARCH64_FPMR: NoModRef, AARCH64_ZA: Ref, Other: NoModRef
+// CHECK-NEXT: Attribute::getWithMemoryEffects(C, MemoryEffects::createFromIntValue(256)),
// CHECK-NEXT: });
// CHECK-NEXT: case 2:
// CHECK-NEXT: return AttributeSet::get(C, {
@@ -44,8 +44,8 @@ def int_aarch64_get_fpmr_set_za : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [In
// 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-NEXT: // ArgMem: NoModRef, InaccessibleMem: NoModRef, ErrnoMem: NoModRef, AARCH64_FPMR: Mod, AARCH64_ZA: NoModRef, Other: NoModRef
+// CHECK-NEXT: Attribute::getWithMemoryEffects(C, MemoryEffects::createFromIntValue(128)),
// CHECK: static constexpr uint16_t IntrinsicsToAttributesMap[] = {
// CHECK-NEXT: 0 << 8 | 0, // llvm.aarch64.get.fpmr.set.za
diff --git a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
index 733fe1f44a424..f3ab40a20cc92 100644
--- a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
+++ b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
@@ -379,10 +379,16 @@ void CodeGenIntrinsic::setProperty(const Record *R) {
ME &= MemoryEffects::inaccessibleMemOnly();
else if (R->isSubClassOf("IntrInaccessibleReadMemOnly")) {
llvm::IRMemLocation Loc = R->getLocationTypeAsInt("Loc");
- ME = ME.getWithModRef(Loc, ModRefInfo::Ref);
+ if (ME.onlyAccessTargetMemoryLocation())
+ ME = ME.getWithModRef(Loc, ModRefInfo::Ref);
+ else
+ ME &= MemoryEffects::inaccessibleReadMemOnly(Loc);
} else if (R->isSubClassOf("IntrInaccessibleWriteMemOnly")) {
llvm::IRMemLocation Loc = R->getLocationTypeAsInt("Loc");
- ME = ME.getWithModRef(Loc, ModRefInfo::Mod);
+ if (ME.onlyAccessTargetMemoryLocation())
+ ME = ME.getWithModRef(Loc, ModRefInfo::Mod);
+ else
+ ME &= MemoryEffects::inaccessibleWriteMemOnly(Loc);
} else if (R->getName() == "IntrInaccessibleMemOrArgMemOnly")
ME &= MemoryEffects::inaccessibleOrArgMemOnly();
else if (R->getName() == "Commutative")
>From 66e3b38eadb27fe02ceff33a75e02b55175a214e Mon Sep 17 00:00:00 2001
From: CarolineConcatto <caroline.concatto at arm.com>
Date: Wed, 23 Jul 2025 15:48:49 +0000
Subject: [PATCH 05/19] Fix codegen for opencl tests
---
llvm/include/llvm/Support/ModRef.h | 20 +++++++++++++++-----
llvm/lib/Transforms/IPO/FunctionAttrs.cpp | 3 +++
2 files changed, 18 insertions(+), 5 deletions(-)
diff --git a/llvm/include/llvm/Support/ModRef.h b/llvm/include/llvm/Support/ModRef.h
index 26c11c223bd0b..0de2b02e4e05a 100644
--- a/llvm/include/llvm/Support/ModRef.h
+++ b/llvm/include/llvm/Support/ModRef.h
@@ -174,11 +174,21 @@ template <typename LocationEnum> class MemoryEffectsBase {
/// Needed because `Data` may be non-zero by default unless explicitly
/// cleared.
bool onlyAccessTargetMemoryLocation() {
- return getWithoutLoc(static_cast<IRMemLocation>(
- llvm::InaccessibleTargetMemLocation::AARCH64_FPMR))
- .getWithoutLoc(static_cast<IRMemLocation>(
- llvm::InaccessibleTargetMemLocation::AARCH64_ZA))
- .doesNotAccessMemory();
+ MemoryEffectsBase ME = *this;
+ for (unsigned I = static_cast<int>(LocationEnum::ErrnoMem);
+ I < static_cast<int>(LocationEnum::Last); I++)
+ ME = ME.getWithoutLoc(static_cast<IRMemLocation>(I));
+ return ME.doesNotAccessMemory();
+ }
+
+ /// Create MemoryEffectsBase that can only access Target Memory Locations
+ static MemoryEffectsBase
+ setTargetMemLocationModRef(ModRefInfo MR = ModRefInfo::NoModRef) {
+ MemoryEffectsBase FRMB = none();
+ for (unsigned I = static_cast<int>(LocationEnum::ErrnoMem);
+ I < static_cast<int>(LocationEnum::Last); I++)
+ FRMB.setModRef(static_cast<Location>(I), MR);
+ return FRMB;
}
/// Create MemoryEffectsBase that can only access inaccessible or argument
diff --git a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
index 50130da01c7ba..8bd6463f48299 100644
--- a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
+++ b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
@@ -142,6 +142,9 @@ static void addLocAccess(MemoryEffects &ME, const MemoryLocation &Loc,
ME |= MemoryEffects::argMemOnly(MR);
ME |= MemoryEffects(IRMemLocation::ErrnoMem, MR);
ME |= MemoryEffects(IRMemLocation::Other, MR);
+ // Should also set the other Target Memory Locations as MR.
+ // To compares with MemoryEffects::unknown() in addMemoryAttrs
+ ME |= MemoryEffects::setTargetMemLocationModRef(MR);
}
static void addArgLocs(MemoryEffects &ME, const CallBase *Call,
>From f386e962e8631f669bd94b9cb10c762ac29f0eb5 Mon Sep 17 00:00:00 2001
From: CarolineConcatto <caroline.concatto at arm.com>
Date: Wed, 20 Aug 2025 10:21:49 +0000
Subject: [PATCH 06/19] Address review comments
---
llvm/include/llvm/Support/ModRef.h | 7 ++++++-
llvm/include/llvm/TableGen/Record.h | 2 --
llvm/lib/TableGen/Record.cpp | 15 -------------
llvm/test/Assembler/memory-attribute.ll | 5 +++++
llvm/test/Bitcode/attributes.ll | 1 +
.../TableGen/Basic/CodeGenIntrinsics.cpp | 21 +++++++++++++++++--
llvm/utils/TableGen/Basic/CodeGenIntrinsics.h | 3 +++
7 files changed, 34 insertions(+), 20 deletions(-)
diff --git a/llvm/include/llvm/Support/ModRef.h b/llvm/include/llvm/Support/ModRef.h
index 0de2b02e4e05a..8bf3a71846220 100644
--- a/llvm/include/llvm/Support/ModRef.h
+++ b/llvm/include/llvm/Support/ModRef.h
@@ -276,7 +276,12 @@ template <typename LocationEnum> class MemoryEffectsBase {
/// Whether this function only (at most) accesses inaccessible memory.
bool onlyAccessesInaccessibleMem() const {
- return getWithoutLoc(Location::InaccessibleMem).doesNotAccessMemory();
+ return getWithoutLoc(static_cast<IRMemLocation>(
+ llvm::InaccessibleTargetMemLocation::AARCH64_FPMR))
+ .getWithoutLoc(static_cast<IRMemLocation>(
+ llvm::InaccessibleTargetMemLocation::AARCH64_ZA))
+ .getWithoutLoc(Location::InaccessibleMem)
+ .doesNotAccessMemory();
}
/// Whether this function only (at most) accesses errno memory.
diff --git a/llvm/include/llvm/TableGen/Record.h b/llvm/include/llvm/TableGen/Record.h
index f515af3ebf841..215e142279d59 100644
--- a/llvm/include/llvm/TableGen/Record.h
+++ b/llvm/include/llvm/TableGen/Record.h
@@ -1967,8 +1967,6 @@ 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/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp
index 5b45355f7cb6c..afce803f3f568 100644
--- a/llvm/lib/TableGen/Record.cpp
+++ b/llvm/lib/TableGen/Record.cpp
@@ -3142,21 +3142,6 @@ 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 == "AArch64_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 Init *I = getValueInit(FieldName);
if (const auto *II = dyn_cast<IntInit>(I))
diff --git a/llvm/test/Assembler/memory-attribute.ll b/llvm/test/Assembler/memory-attribute.ll
index 42f9b9f87e8b0..18abb5d5bfe37 100644
--- a/llvm/test/Assembler/memory-attribute.ll
+++ b/llvm/test/Assembler/memory-attribute.ll
@@ -103,3 +103,8 @@ declare void @fn_inaccessiblemem_read_aarch64_fpmr()
; 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)
+
+; CHECK: Function Attrs: memory(aarch64_fpmr: read, aarch64_za: write)
+; CHECK: @fn_inaccessiblemem_read_aarch64_fpmr_write_aarch64_za()
+declare void @fn_inaccessiblemem_read_argmem__write_inacessiblemem()
+ memory(argmem: read, inacessiblemem: write)
diff --git a/llvm/test/Bitcode/attributes.ll b/llvm/test/Bitcode/attributes.ll
index 283aeac6db565..aef7810fe2c3b 100644
--- a/llvm/test/Bitcode/attributes.ll
+++ b/llvm/test/Bitcode/attributes.ll
@@ -577,6 +577,7 @@ define void @dead_on_return(ptr dead_on_return %p) {
ret void
}
+; CHECK: attributes #0 = { noreturn }
; CHECK: attributes #1 = { nounwind }
; CHECK: attributes #2 = { memory(none) }
; CHECK: attributes #3 = { memory(read) }
diff --git a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
index f3ab40a20cc92..2780344ee0127 100644
--- a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
+++ b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
@@ -378,13 +378,13 @@ void CodeGenIntrinsic::setProperty(const Record *R) {
else if (R->getName() == "IntrInaccessibleMemOnly")
ME &= MemoryEffects::inaccessibleMemOnly();
else if (R->isSubClassOf("IntrInaccessibleReadMemOnly")) {
- llvm::IRMemLocation Loc = R->getLocationTypeAsInt("Loc");
+ llvm::IRMemLocation Loc = getLocationTypeAsInt(R, "Loc");
if (ME.onlyAccessTargetMemoryLocation())
ME = ME.getWithModRef(Loc, ModRefInfo::Ref);
else
ME &= MemoryEffects::inaccessibleReadMemOnly(Loc);
} else if (R->isSubClassOf("IntrInaccessibleWriteMemOnly")) {
- llvm::IRMemLocation Loc = R->getLocationTypeAsInt("Loc");
+ llvm::IRMemLocation Loc = getLocationTypeAsInt(R, "Loc");
if (ME.onlyAccessTargetMemoryLocation())
ME = ME.getWithModRef(Loc, ModRefInfo::Mod);
else
@@ -464,6 +464,23 @@ void CodeGenIntrinsic::setProperty(const Record *R) {
}
}
+llvm::IRMemLocation
+CodeGenIntrinsic::getLocationTypeAsInt(const Record *R,
+ StringRef FieldName) const {
+ const Record *LocRec = R->getValueAsDef(FieldName);
+ StringRef Name = LocRec->getName();
+ if (Name == "AArch64_FPMR")
+ return static_cast<IRMemLocation>(
+ llvm::InaccessibleTargetMemLocation::AARCH64_FPMR);
+ else if (Name == "AArch64_ZA")
+ return static_cast<IRMemLocation>(
+ llvm::InaccessibleTargetMemLocation::AARCH64_ZA);
+ else if (Name == "InaccessibleMem")
+ return llvm::IRMemLocation::InaccessibleMem;
+ else
+ PrintFatalError(R->getLoc(), "unknown IRMemLocation: " + Name);
+}
+
bool CodeGenIntrinsic::isParamAPointer(unsigned ParamIdx) const {
if (ParamIdx >= IS.ParamTys.size())
return false;
diff --git a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.h b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.h
index 2e86149514f46..e4c2347704cb9 100644
--- a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.h
+++ b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.h
@@ -167,6 +167,9 @@ struct CodeGenIntrinsic {
bool isParamImmArg(unsigned ParamIdx) const;
+ llvm::IRMemLocation getLocationTypeAsInt(const Record *R,
+ StringRef FieldName) const;
+
CodeGenIntrinsic(const Record *R, const CodeGenIntrinsicContext &Ctx);
};
>From 2e898b1d38b47213f5e754cc4755148ac9a903c8 Mon Sep 17 00:00:00 2001
From: CarolineConcatto <caroline.concatto at arm.com>
Date: Wed, 20 Aug 2025 10:55:30 +0000
Subject: [PATCH 07/19] Remove unwanted changes from the test
memory-attribute.ll
---
llvm/test/Assembler/memory-attribute.ll | 5 -----
1 file changed, 5 deletions(-)
diff --git a/llvm/test/Assembler/memory-attribute.ll b/llvm/test/Assembler/memory-attribute.ll
index 18abb5d5bfe37..42f9b9f87e8b0 100644
--- a/llvm/test/Assembler/memory-attribute.ll
+++ b/llvm/test/Assembler/memory-attribute.ll
@@ -103,8 +103,3 @@ declare void @fn_inaccessiblemem_read_aarch64_fpmr()
; 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)
-
-; CHECK: Function Attrs: memory(aarch64_fpmr: read, aarch64_za: write)
-; CHECK: @fn_inaccessiblemem_read_aarch64_fpmr_write_aarch64_za()
-declare void @fn_inaccessiblemem_read_argmem__write_inacessiblemem()
- memory(argmem: read, inacessiblemem: write)
>From 3a7bc26a54f9be4a3544d6cb96aeb2ee102bc326 Mon Sep 17 00:00:00 2001
From: CarolineConcatto <caroline.concatto at arm.com>
Date: Thu, 21 Aug 2025 09:15:45 +0000
Subject: [PATCH 08/19] Make target memory locations generic; resolve meaning
via Triple
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This patch replaces target‑specific memory location names in IR
printing/parsing with generic target memory kinds whose meaning is determined
by the module’s target triple.
Replace the target specific names by generic target memory kinds
(e.g. mem_target_0, mem_target_1), and make their user‑facing names
triple‑dependent.
Plumb the Triple into attribute so textual IR reflects the correct per‑target
names.
To print a meaningful name each target needs to add a keyword->kind
mapping so textual forms remain readable and round‑trip correctly.
---
llvm/include/llvm/IR/Attributes.h | 7 ++--
llvm/include/llvm/Support/ModRef.h | 8 ++---
llvm/include/llvm/TargetParser/Triple.h | 14 ++++++++
llvm/lib/AsmParser/LLParser.cpp | 4 +--
llvm/lib/IR/AsmWriter.cpp | 13 +++----
llvm/lib/IR/AttributeImpl.h | 3 +-
llvm/lib/IR/Attributes.cpp | 26 ++++++++------
llvm/lib/Support/ModRef.cpp | 4 +--
llvm/lib/TargetParser/Triple.cpp | 25 +++++++++++++
.../Assembler/aarch64-memory-attribute.ll | 35 +++++++++++++++++++
llvm/test/Assembler/memory-attribute.ll | 10 +++---
.../TableGen/Basic/CodeGenIntrinsics.cpp | 4 +--
12 files changed, 118 insertions(+), 35 deletions(-)
create mode 100644 llvm/test/Assembler/aarch64-memory-attribute.ll
diff --git a/llvm/include/llvm/IR/Attributes.h b/llvm/include/llvm/IR/Attributes.h
index e734466ce20e0..2af8bb4d58c35 100644
--- a/llvm/include/llvm/IR/Attributes.h
+++ b/llvm/include/llvm/IR/Attributes.h
@@ -25,6 +25,7 @@
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ModRef.h"
#include "llvm/Support/PointerLikeTypeTraits.h"
+#include "llvm/TargetParser/Triple.h"
#include <cassert>
#include <cstdint>
#include <optional>
@@ -314,7 +315,8 @@ class Attribute {
/// The Attribute is converted to a string of equivalent mnemonic. This
/// is, presumably, for writing out the mnemonics for the assembly writer.
- LLVM_ABI std::string getAsString(bool InAttrGrp = false) const;
+ LLVM_ABI std::string getAsString(const Triple *TT = nullptr,
+ bool InAttrGrp = false) const;
/// Return true if this attribute belongs to the LLVMContext.
LLVM_ABI bool hasParentContext(LLVMContext &C) const;
@@ -461,7 +463,8 @@ class AttributeSet {
LLVM_ABI MemoryEffects getMemoryEffects() const;
LLVM_ABI CaptureInfo getCaptureInfo() const;
LLVM_ABI FPClassTest getNoFPClass() const;
- LLVM_ABI std::string getAsString(bool InAttrGrp = false) const;
+ LLVM_ABI std::string getAsString(const Triple *TT = nullptr,
+ bool InAttrGrp = false) const;
/// Return true if this attribute set belongs to the LLVMContext.
LLVM_ABI bool hasParentContext(LLVMContext &C) const;
diff --git a/llvm/include/llvm/Support/ModRef.h b/llvm/include/llvm/Support/ModRef.h
index 8bf3a71846220..bcbdd5492a076 100644
--- a/llvm/include/llvm/Support/ModRef.h
+++ b/llvm/include/llvm/Support/ModRef.h
@@ -57,8 +57,8 @@ enum class ModRefInfo : uint8_t {
LLVM_ABI raw_ostream &operator<<(raw_ostream &OS, ModRefInfo MR);
enum class InaccessibleTargetMemLocation {
- AARCH64_FPMR = 3,
- AARCH64_ZA = 4,
+ MEM_TARGET_0 = 3,
+ MEM_TARGET_1 = 4,
};
/// The locations at which a function might access memory.
@@ -277,9 +277,9 @@ template <typename LocationEnum> class MemoryEffectsBase {
/// Whether this function only (at most) accesses inaccessible memory.
bool onlyAccessesInaccessibleMem() const {
return getWithoutLoc(static_cast<IRMemLocation>(
- llvm::InaccessibleTargetMemLocation::AARCH64_FPMR))
+ llvm::InaccessibleTargetMemLocation::MEM_TARGET_0))
.getWithoutLoc(static_cast<IRMemLocation>(
- llvm::InaccessibleTargetMemLocation::AARCH64_ZA))
+ llvm::InaccessibleTargetMemLocation::MEM_TARGET_1))
.getWithoutLoc(Location::InaccessibleMem)
.doesNotAccessMemory();
}
diff --git a/llvm/include/llvm/TargetParser/Triple.h b/llvm/include/llvm/TargetParser/Triple.h
index 0e82dd212f34d..9d6d69d646a1f 100644
--- a/llvm/include/llvm/TargetParser/Triple.h
+++ b/llvm/include/llvm/TargetParser/Triple.h
@@ -329,6 +329,15 @@ class Triple {
XCOFF,
};
+ // This should be a copy from enum class InaccessibleTargetMemLocation
+ // in ModRef.h
+ enum class InaccessibleTargetMemLocation : uint8_t {
+ MEM_TARGET_0 = 3,
+ MEM_TARGET_1 = 4,
+ // Reserve more if/when needed
+ Last
+ };
+
private:
std::string Data;
@@ -1200,6 +1209,11 @@ class Triple {
/// Tests if the environment supports dllimport/export annotations.
bool hasDLLImportExport() const { return isOSWindows() || isPS(); }
+ StringRef
+ aarch64GetTargetMemLocName(InaccessibleTargetMemLocation Kind) const;
+
+ StringRef getTargetMemLocName(InaccessibleTargetMemLocation Kind) const;
+
/// @}
/// @name Mutators
/// @{
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index 01f30b3a10593..de6986d63f65d 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -1698,10 +1698,10 @@ static std::optional<MemoryEffects::Location> keywordToLoc(lltok::Kind Tok) {
return IRMemLocation::ErrnoMem;
case lltok::kw_aarch64_fpmr:
return static_cast<IRMemLocation>(
- llvm::InaccessibleTargetMemLocation::AARCH64_FPMR);
+ llvm::InaccessibleTargetMemLocation::MEM_TARGET_0);
case lltok::kw_aarch64_za:
return static_cast<IRMemLocation>(
- llvm::InaccessibleTargetMemLocation::AARCH64_ZA);
+ llvm::InaccessibleTargetMemLocation::MEM_TARGET_1);
default:
return std::nullopt;
}
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index 488b078ab6caf..f88c868feb2c5 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -2887,7 +2887,7 @@ class AssemblyWriter {
void writeMDNode(unsigned Slot, const MDNode *Node);
void writeAttribute(const Attribute &Attr, bool InAttrGroup = false);
void writeAttributeSet(const AttributeSet &AttrSet, bool InAttrGroup = false);
- void writeAllAttributeGroups();
+ void writeAllAttributeGroups(const Triple *TT = nullptr);
void printTypeIdentities();
void printGlobal(const GlobalVariable *GV);
@@ -3146,7 +3146,7 @@ void AssemblyWriter::printModule(const Module *M) {
// Output all attribute groups.
if (!Machine.as_empty()) {
Out << '\n';
- writeAllAttributeGroups();
+ writeAllAttributeGroups(&M->getTargetTriple());
}
// Output named metadata.
@@ -4095,7 +4095,7 @@ void AssemblyWriter::printFunction(const Function *F) {
for (const Attribute &Attr : AS) {
if (!Attr.isStringAttribute()) {
if (!AttrStr.empty()) AttrStr += ' ';
- AttrStr += Attr.getAsString();
+ AttrStr += Attr.getAsString(&F->getParent()->getTargetTriple(), false);
}
}
@@ -4939,8 +4939,9 @@ void AssemblyWriter::printMDNodeBody(const MDNode *Node) {
}
void AssemblyWriter::writeAttribute(const Attribute &Attr, bool InAttrGroup) {
+ llvm::Triple *TT;
if (!Attr.isTypeAttribute()) {
- Out << Attr.getAsString(InAttrGroup);
+ Out << Attr.getAsString(TT, InAttrGroup);
return;
}
@@ -4961,7 +4962,7 @@ void AssemblyWriter::writeAttributeSet(const AttributeSet &AttrSet,
}
}
-void AssemblyWriter::writeAllAttributeGroups() {
+void AssemblyWriter::writeAllAttributeGroups(const Triple *TT) {
std::vector<std::pair<AttributeSet, unsigned>> asVec;
asVec.resize(Machine.as_size());
@@ -4970,7 +4971,7 @@ void AssemblyWriter::writeAllAttributeGroups() {
for (const auto &I : asVec)
Out << "attributes #" << I.second << " = { "
- << I.first.getAsString(true) << " }\n";
+ << I.first.getAsString(TT, true) << " }\n";
}
void AssemblyWriter::printUseListOrder(const Value *V,
diff --git a/llvm/lib/IR/AttributeImpl.h b/llvm/lib/IR/AttributeImpl.h
index 707c8205ee1f9..6abb6e3f184ad 100644
--- a/llvm/lib/IR/AttributeImpl.h
+++ b/llvm/lib/IR/AttributeImpl.h
@@ -342,7 +342,8 @@ class AttributeSetNode final
MemoryEffects getMemoryEffects() const;
CaptureInfo getCaptureInfo() const;
FPClassTest getNoFPClass() const;
- std::string getAsString(bool InAttrGrp) const;
+ std::string getAsString(const Triple *TT = nullptr,
+ bool InAttrGrp = false) const;
Type *getAttributeType(Attribute::AttrKind Kind) const;
using iterator = const Attribute *;
diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp
index 7a79ebdb243e2..efca310cc8887 100644
--- a/llvm/lib/IR/Attributes.cpp
+++ b/llvm/lib/IR/Attributes.cpp
@@ -533,7 +533,7 @@ static const char *getModRefStr(ModRefInfo MR) {
llvm_unreachable("Invalid ModRefInfo");
}
-std::string Attribute::getAsString(bool InAttrGrp) const {
+std::string Attribute::getAsString(const Triple *TT, bool InAttrGrp) const {
if (!pImpl) return {};
if (isEnumAttribute())
@@ -663,10 +663,13 @@ std::string Attribute::getAsString(bool InAttrGrp) const {
default: {
InaccessibleTargetMemLocation TargetLoc =
static_cast<InaccessibleTargetMemLocation>(Loc);
- if (TargetLoc == InaccessibleTargetMemLocation::AARCH64_FPMR)
- OS << "aarch64_fpmr: ";
- if (TargetLoc == InaccessibleTargetMemLocation::AARCH64_ZA)
- OS << "aarch64_za: ";
+ if (TargetLoc == InaccessibleTargetMemLocation::MEM_TARGET_0)
+ OS << TT->getTargetMemLocName(
+ static_cast<Triple::InaccessibleTargetMemLocation>(TargetLoc));
+ if (TargetLoc == InaccessibleTargetMemLocation::MEM_TARGET_1)
+ OS << TT->getTargetMemLocName(
+ static_cast<Triple::InaccessibleTargetMemLocation>(TargetLoc));
+ OS << ": ";
break;
}
}
@@ -1232,8 +1235,8 @@ FPClassTest AttributeSet::getNoFPClass() const {
return SetNode ? SetNode->getNoFPClass() : fcNone;
}
-std::string AttributeSet::getAsString(bool InAttrGrp) const {
- return SetNode ? SetNode->getAsString(InAttrGrp) : "";
+std::string AttributeSet::getAsString(const Triple *TT, bool InAttrGrp) const {
+ return SetNode ? SetNode->getAsString(TT, InAttrGrp) : "";
}
bool AttributeSet::hasParentContext(LLVMContext &C) const {
@@ -1256,7 +1259,7 @@ AttributeSet::iterator AttributeSet::end() const {
LLVM_DUMP_METHOD void AttributeSet::dump() const {
dbgs() << "AS =\n";
dbgs() << " { ";
- dbgs() << getAsString(true) << " }\n";
+ dbgs() << getAsString(nullptr, true) << " }\n";
}
#endif
@@ -1428,12 +1431,13 @@ FPClassTest AttributeSetNode::getNoFPClass() const {
return fcNone;
}
-std::string AttributeSetNode::getAsString(bool InAttrGrp) const {
+std::string AttributeSetNode::getAsString(const Triple *TT,
+ bool InAttrGrp) const {
std::string Str;
for (iterator I = begin(), E = end(); I != E; ++I) {
if (I != begin())
Str += ' ';
- Str += I->getAsString(InAttrGrp);
+ Str += I->getAsString(TT, InAttrGrp);
}
return Str;
}
@@ -2024,7 +2028,7 @@ MemoryEffects AttributeList::getMemoryEffects() const {
}
std::string AttributeList::getAsString(unsigned Index, bool InAttrGrp) const {
- return getAttributes(Index).getAsString(InAttrGrp);
+ return getAttributes(Index).getAsString(nullptr, InAttrGrp);
}
AttributeSet AttributeList::getAttributes(unsigned Index) const {
diff --git a/llvm/lib/Support/ModRef.cpp b/llvm/lib/Support/ModRef.cpp
index dc0dafdbe7e49..f73224afba866 100644
--- a/llvm/lib/Support/ModRef.cpp
+++ b/llvm/lib/Support/ModRef.cpp
@@ -52,9 +52,9 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, MemoryEffects ME) {
default: {
InaccessibleTargetMemLocation TargetLoc =
static_cast<InaccessibleTargetMemLocation>(Loc);
- if (TargetLoc == InaccessibleTargetMemLocation::AARCH64_FPMR)
+ if (TargetLoc == InaccessibleTargetMemLocation::MEM_TARGET_0)
OS << "AARCH64_FPMR: ";
- if (TargetLoc == InaccessibleTargetMemLocation::AARCH64_ZA)
+ if (TargetLoc == InaccessibleTargetMemLocation::MEM_TARGET_1)
OS << "AARCH64_ZA: ";
break;
}
diff --git a/llvm/lib/TargetParser/Triple.cpp b/llvm/lib/TargetParser/Triple.cpp
index 11ba9ee32f66a..c367341637cbe 100644
--- a/llvm/lib/TargetParser/Triple.cpp
+++ b/llvm/lib/TargetParser/Triple.cpp
@@ -2361,6 +2361,31 @@ ExceptionHandling Triple::getDefaultExceptionHandling() const {
return ExceptionHandling::None;
}
+StringRef Triple::aarch64GetTargetMemLocName(
+ Triple::InaccessibleTargetMemLocation Kind) const {
+ switch (Kind) {
+ case InaccessibleTargetMemLocation::MEM_TARGET_0:
+ return "aarch64_fprm";
+ case InaccessibleTargetMemLocation::MEM_TARGET_1:
+ return "aarch64_za";
+ }
+}
+
+StringRef
+Triple::getTargetMemLocName(InaccessibleTargetMemLocation Kind) const {
+
+ if (isAArch64())
+ return aarch64GetTargetMemLocName(Kind);
+
+ switch (Kind) {
+ case InaccessibleTargetMemLocation::MEM_TARGET_0:
+ return "mem_target_0";
+ case InaccessibleTargetMemLocation::MEM_TARGET_1:
+ return "mem_target_1";
+ }
+ return "unkown";
+}
+
// HLSL triple environment orders are relied on in the front end
static_assert(Triple::Vertex - Triple::Pixel == 1,
"incorrect HLSL stage order");
diff --git a/llvm/test/Assembler/aarch64-memory-attribute.ll b/llvm/test/Assembler/aarch64-memory-attribute.ll
new file mode 100644
index 0000000000000..48f05ec9dec8a
--- /dev/null
+++ b/llvm/test/Assembler/aarch64-memory-attribute.ll
@@ -0,0 +1,35 @@
+; RUN: llvm-as < %s | llvm-dis | FileCheck %s
+
+target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
+target triple = "aarch64"
+
+; CHECK: Function Attrs: memory(aarch64_za: write)
+; CHECK: @fn_inaccessiblemem_write_aarch64_za() [[ATTR0:#.*]]
+declare void @fn_inaccessiblemem_write_aarch64_za()
+ memory(aarch64_za: write)
+
+; CHECK: Function Attrs: memory(aarch64_za: read)
+; CHECK: @fn_inaccessiblemem_read_aarch64_za() [[ATTR1:#.*]]
+declare void @fn_inaccessiblemem_read_aarch64_za()
+ memory(aarch64_za: read)
+
+; CHECK: Function Attrs: memory(aarch64_fprm: write)
+; CHECK: @fn_inaccessiblemem_write_aarch64_fpmr() [[ATTR2:#.*]]
+declare void @fn_inaccessiblemem_write_aarch64_fpmr()
+ memory(aarch64_fpmr: write)
+
+; CHECK: ; Function Attrs: memory(aarch64_fprm: read)
+; CHECK: @fn_inaccessiblemem_read_aarch64_fpmr() [[ATTR3:#.*]]
+declare void @fn_inaccessiblemem_read_aarch64_fpmr()
+ memory(aarch64_fpmr: read)
+
+; CHECK: Function Attrs: memory(aarch64_fprm: read, aarch64_za: write)
+; CHECK: @fn_inaccessiblemem_read_aarch64_fpmr_write_aarch64_za() [[ATTR4:#.*]]
+declare void @fn_inaccessiblemem_read_aarch64_fpmr_write_aarch64_za()
+ memory(aarch64_fpmr: read, aarch64_za: write)
+
+; CHECK: attributes [[ATTR0]] = { memory(aarch64_za: write) }
+; CHECK: attributes [[ATTR1]] = { memory(aarch64_za: read) }
+; CHECK: attributes [[ATTR2]] = { memory(aarch64_fprm: write) }
+; CHECK: attributes [[ATTR3]] = { memory(aarch64_fprm: read) }
+; CHECK: attributes [[ATTR4]] = { memory(aarch64_fprm: read, aarch64_za: write) }
diff --git a/llvm/test/Assembler/memory-attribute.ll b/llvm/test/Assembler/memory-attribute.ll
index 42f9b9f87e8b0..a12a826dc97fe 100644
--- a/llvm/test/Assembler/memory-attribute.ll
+++ b/llvm/test/Assembler/memory-attribute.ll
@@ -79,27 +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(aarch64_za: write)
+; CHECK: Function Attrs: memory(mem_target_1: 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: Function Attrs: memory(mem_target_1: 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: Function Attrs: memory(mem_target_0: 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: Function Attrs: memory(mem_target_0: 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: Function Attrs: memory(mem_target_0: read, mem_target_1: 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/utils/TableGen/Basic/CodeGenIntrinsics.cpp b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
index 2780344ee0127..652f00d15385c 100644
--- a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
+++ b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
@@ -471,10 +471,10 @@ CodeGenIntrinsic::getLocationTypeAsInt(const Record *R,
StringRef Name = LocRec->getName();
if (Name == "AArch64_FPMR")
return static_cast<IRMemLocation>(
- llvm::InaccessibleTargetMemLocation::AARCH64_FPMR);
+ llvm::InaccessibleTargetMemLocation::MEM_TARGET_0);
else if (Name == "AArch64_ZA")
return static_cast<IRMemLocation>(
- llvm::InaccessibleTargetMemLocation::AARCH64_ZA);
+ llvm::InaccessibleTargetMemLocation::MEM_TARGET_1);
else if (Name == "InaccessibleMem")
return llvm::IRMemLocation::InaccessibleMem;
else
>From 8ddc872a90bf7205ae5a6815b5874a4e81bd7566 Mon Sep 17 00:00:00 2001
From: CarolineConcatto <caroline.concatto at arm.com>
Date: Thu, 21 Aug 2025 14:59:23 +0000
Subject: [PATCH 09/19] Change ModRef.cpp to use generic memory target name
---
llvm/lib/Support/ModRef.cpp | 4 ++--
llvm/test/TableGen/intrinsic-attrs-fp8.td | 6 +++---
llvm/unittests/Support/ModRefTest.cpp | 2 +-
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/llvm/lib/Support/ModRef.cpp b/llvm/lib/Support/ModRef.cpp
index f73224afba866..f78a135d1d698 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::MEM_TARGET_0)
- OS << "AARCH64_FPMR: ";
+ OS << "MEM_TARGET_0: ";
if (TargetLoc == InaccessibleTargetMemLocation::MEM_TARGET_1)
- OS << "AARCH64_ZA: ";
+ OS << "MEM_TARGET_1: ";
break;
}
}
diff --git a/llvm/test/TableGen/intrinsic-attrs-fp8.td b/llvm/test/TableGen/intrinsic-attrs-fp8.td
index 5aaba44edcc45..ba2fd0eb07b61 100644
--- a/llvm/test/TableGen/intrinsic-attrs-fp8.td
+++ b/llvm/test/TableGen/intrinsic-attrs-fp8.td
@@ -24,7 +24,7 @@ def int_aarch64_get_fpmr_set_za : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [In
// 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, AARCH64_FPMR: Ref, AARCH64_ZA: Mod, Other: NoModRef
+// CHECK-NEXT: // ArgMem: NoModRef, InaccessibleMem: NoModRef, ErrnoMem: NoModRef, MEM_TARGET_0: Ref, MEM_TARGET_1: Mod, Other: NoModRef
// CHECK-NEXT: Attribute::getWithMemoryEffects(C, MemoryEffects::createFromIntValue(576)),
// CHECK-NEXT: });
// CHECK-NEXT: case 1:
@@ -34,7 +34,7 @@ def int_aarch64_get_fpmr_set_za : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [In
// 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, AARCH64_FPMR: NoModRef, AARCH64_ZA: Ref, Other: NoModRef
+// CHECK-NEXT: // ArgMem: NoModRef, InaccessibleMem: NoModRef, ErrnoMem: NoModRef, MEM_TARGET_0: NoModRef, MEM_TARGET_1: Ref, Other: NoModRef
// CHECK-NEXT: Attribute::getWithMemoryEffects(C, MemoryEffects::createFromIntValue(256)),
// CHECK-NEXT: });
// CHECK-NEXT: case 2:
@@ -44,7 +44,7 @@ def int_aarch64_get_fpmr_set_za : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [In
// 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, AARCH64_FPMR: Mod, AARCH64_ZA: NoModRef, Other: NoModRef
+// CHECK-NEXT: // ArgMem: NoModRef, InaccessibleMem: NoModRef, ErrnoMem: NoModRef, MEM_TARGET_0: Mod, MEM_TARGET_1: NoModRef, Other: NoModRef
// CHECK-NEXT: Attribute::getWithMemoryEffects(C, MemoryEffects::createFromIntValue(128)),
// CHECK: static constexpr uint16_t IntrinsicsToAttributesMap[] = {
diff --git a/llvm/unittests/Support/ModRefTest.cpp b/llvm/unittests/Support/ModRefTest.cpp
index 7aa473ad20336..9bcb4bb6901b4 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, AARCH64_FPMR: NoModRef, AARCH64_ZA: NoModRef, Other: "
+ "NoModRef, MEM_TARGET_0: NoModRef, MEM_TARGET_1: NoModRef, Other: "
"NoModRef");
}
>From 6d7fa02cbeab8fea1310388e46f00d29131d4266 Mon Sep 17 00:00:00 2001
From: CarolineConcatto <caroline.concatto at arm.com>
Date: Thu, 21 Aug 2025 15:06:10 +0000
Subject: [PATCH 10/19] Fix clang format
---
llvm/unittests/Support/ModRefTest.cpp | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/llvm/unittests/Support/ModRefTest.cpp b/llvm/unittests/Support/ModRefTest.cpp
index 9bcb4bb6901b4..3fd8a5fee5c6b 100644
--- a/llvm/unittests/Support/ModRefTest.cpp
+++ b/llvm/unittests/Support/ModRefTest.cpp
@@ -20,9 +20,10 @@ TEST(ModRefTest, PrintMemoryEffects) {
std::string S;
raw_string_ostream OS(S);
OS << MemoryEffects::none();
- EXPECT_EQ(S, "ArgMem: NoModRef, InaccessibleMem: NoModRef, ErrnoMem: "
- "NoModRef, MEM_TARGET_0: NoModRef, MEM_TARGET_1: NoModRef, Other: "
- "NoModRef");
+ EXPECT_EQ(S,
+ "ArgMem: NoModRef, InaccessibleMem: NoModRef, ErrnoMem: "
+ "NoModRef, MEM_TARGET_0: NoModRef, MEM_TARGET_1: NoModRef, Other: "
+ "NoModRef");
}
} // namespace
>From d2ca3e9d31305db5ed721dca88e6d8ccd0029eb0 Mon Sep 17 00:00:00 2001
From: CarolineConcatto <caroline.concatto at arm.com>
Date: Wed, 17 Sep 2025 12:44:53 +0000
Subject: [PATCH 11/19] Remove Target Triple interface for Target Memory
---
llvm/include/llvm/IR/Attributes.h | 7 +--
llvm/include/llvm/Support/ModRef.h | 8 ++--
llvm/include/llvm/TargetParser/Triple.h | 14 ------
llvm/lib/AsmParser/LLParser.cpp | 4 +-
llvm/lib/IR/AsmWriter.cpp | 15 +++---
llvm/lib/IR/AttributeImpl.h | 3 +-
llvm/lib/IR/Attributes.cpp | 25 +++++-----
llvm/lib/Support/ModRef.cpp | 8 ++--
llvm/lib/TargetParser/Triple.cpp | 25 ----------
.../Assembler/aarch64-memory-attribute.ll | 20 ++++----
llvm/test/Assembler/memory-attribute.ll | 48 +++++++++----------
llvm/test/TableGen/intrinsic-attrs-fp8.td | 6 +--
llvm/unittests/Support/ModRefTest.cpp | 7 ++-
.../TableGen/Basic/CodeGenIntrinsics.cpp | 4 +-
14 files changed, 73 insertions(+), 121 deletions(-)
diff --git a/llvm/include/llvm/IR/Attributes.h b/llvm/include/llvm/IR/Attributes.h
index 2af8bb4d58c35..e734466ce20e0 100644
--- a/llvm/include/llvm/IR/Attributes.h
+++ b/llvm/include/llvm/IR/Attributes.h
@@ -25,7 +25,6 @@
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ModRef.h"
#include "llvm/Support/PointerLikeTypeTraits.h"
-#include "llvm/TargetParser/Triple.h"
#include <cassert>
#include <cstdint>
#include <optional>
@@ -315,8 +314,7 @@ class Attribute {
/// The Attribute is converted to a string of equivalent mnemonic. This
/// is, presumably, for writing out the mnemonics for the assembly writer.
- LLVM_ABI std::string getAsString(const Triple *TT = nullptr,
- bool InAttrGrp = false) const;
+ LLVM_ABI std::string getAsString(bool InAttrGrp = false) const;
/// Return true if this attribute belongs to the LLVMContext.
LLVM_ABI bool hasParentContext(LLVMContext &C) const;
@@ -463,8 +461,7 @@ class AttributeSet {
LLVM_ABI MemoryEffects getMemoryEffects() const;
LLVM_ABI CaptureInfo getCaptureInfo() const;
LLVM_ABI FPClassTest getNoFPClass() const;
- LLVM_ABI std::string getAsString(const Triple *TT = nullptr,
- bool InAttrGrp = false) const;
+ LLVM_ABI std::string getAsString(bool InAttrGrp = false) const;
/// Return true if this attribute set belongs to the LLVMContext.
LLVM_ABI bool hasParentContext(LLVMContext &C) const;
diff --git a/llvm/include/llvm/Support/ModRef.h b/llvm/include/llvm/Support/ModRef.h
index bcbdd5492a076..9266980d635f7 100644
--- a/llvm/include/llvm/Support/ModRef.h
+++ b/llvm/include/llvm/Support/ModRef.h
@@ -57,8 +57,8 @@ enum class ModRefInfo : uint8_t {
LLVM_ABI raw_ostream &operator<<(raw_ostream &OS, ModRefInfo MR);
enum class InaccessibleTargetMemLocation {
- MEM_TARGET_0 = 3,
- MEM_TARGET_1 = 4,
+ TargetMem0 = 3,
+ TargetMem1 = 4,
};
/// The locations at which a function might access memory.
@@ -277,9 +277,9 @@ template <typename LocationEnum> class MemoryEffectsBase {
/// Whether this function only (at most) accesses inaccessible memory.
bool onlyAccessesInaccessibleMem() const {
return getWithoutLoc(static_cast<IRMemLocation>(
- llvm::InaccessibleTargetMemLocation::MEM_TARGET_0))
+ llvm::InaccessibleTargetMemLocation::TargetMem0))
.getWithoutLoc(static_cast<IRMemLocation>(
- llvm::InaccessibleTargetMemLocation::MEM_TARGET_1))
+ llvm::InaccessibleTargetMemLocation::TargetMem1))
.getWithoutLoc(Location::InaccessibleMem)
.doesNotAccessMemory();
}
diff --git a/llvm/include/llvm/TargetParser/Triple.h b/llvm/include/llvm/TargetParser/Triple.h
index 9d6d69d646a1f..0e82dd212f34d 100644
--- a/llvm/include/llvm/TargetParser/Triple.h
+++ b/llvm/include/llvm/TargetParser/Triple.h
@@ -329,15 +329,6 @@ class Triple {
XCOFF,
};
- // This should be a copy from enum class InaccessibleTargetMemLocation
- // in ModRef.h
- enum class InaccessibleTargetMemLocation : uint8_t {
- MEM_TARGET_0 = 3,
- MEM_TARGET_1 = 4,
- // Reserve more if/when needed
- Last
- };
-
private:
std::string Data;
@@ -1209,11 +1200,6 @@ class Triple {
/// Tests if the environment supports dllimport/export annotations.
bool hasDLLImportExport() const { return isOSWindows() || isPS(); }
- StringRef
- aarch64GetTargetMemLocName(InaccessibleTargetMemLocation Kind) const;
-
- StringRef getTargetMemLocName(InaccessibleTargetMemLocation Kind) const;
-
/// @}
/// @name Mutators
/// @{
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index de6986d63f65d..2fb2b1bfcf9f0 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -1698,10 +1698,10 @@ static std::optional<MemoryEffects::Location> keywordToLoc(lltok::Kind Tok) {
return IRMemLocation::ErrnoMem;
case lltok::kw_aarch64_fpmr:
return static_cast<IRMemLocation>(
- llvm::InaccessibleTargetMemLocation::MEM_TARGET_0);
+ llvm::InaccessibleTargetMemLocation::TargetMem0);
case lltok::kw_aarch64_za:
return static_cast<IRMemLocation>(
- llvm::InaccessibleTargetMemLocation::MEM_TARGET_1);
+ llvm::InaccessibleTargetMemLocation::TargetMem1);
default:
return std::nullopt;
}
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index f88c868feb2c5..58f8dbec34a48 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -2887,7 +2887,7 @@ class AssemblyWriter {
void writeMDNode(unsigned Slot, const MDNode *Node);
void writeAttribute(const Attribute &Attr, bool InAttrGroup = false);
void writeAttributeSet(const AttributeSet &AttrSet, bool InAttrGroup = false);
- void writeAllAttributeGroups(const Triple *TT = nullptr);
+ void writeAllAttributeGroups();
void printTypeIdentities();
void printGlobal(const GlobalVariable *GV);
@@ -3146,7 +3146,7 @@ void AssemblyWriter::printModule(const Module *M) {
// Output all attribute groups.
if (!Machine.as_empty()) {
Out << '\n';
- writeAllAttributeGroups(&M->getTargetTriple());
+ writeAllAttributeGroups();
}
// Output named metadata.
@@ -4095,7 +4095,7 @@ void AssemblyWriter::printFunction(const Function *F) {
for (const Attribute &Attr : AS) {
if (!Attr.isStringAttribute()) {
if (!AttrStr.empty()) AttrStr += ' ';
- AttrStr += Attr.getAsString(&F->getParent()->getTargetTriple(), false);
+ AttrStr += Attr.getAsString();
}
}
@@ -4939,9 +4939,8 @@ void AssemblyWriter::printMDNodeBody(const MDNode *Node) {
}
void AssemblyWriter::writeAttribute(const Attribute &Attr, bool InAttrGroup) {
- llvm::Triple *TT;
if (!Attr.isTypeAttribute()) {
- Out << Attr.getAsString(TT, InAttrGroup);
+ Out << Attr.getAsString(InAttrGroup);
return;
}
@@ -4962,7 +4961,7 @@ void AssemblyWriter::writeAttributeSet(const AttributeSet &AttrSet,
}
}
-void AssemblyWriter::writeAllAttributeGroups(const Triple *TT) {
+void AssemblyWriter::writeAllAttributeGroups() {
std::vector<std::pair<AttributeSet, unsigned>> asVec;
asVec.resize(Machine.as_size());
@@ -4970,8 +4969,8 @@ void AssemblyWriter::writeAllAttributeGroups(const Triple *TT) {
asVec[I.second] = I;
for (const auto &I : asVec)
- Out << "attributes #" << I.second << " = { "
- << I.first.getAsString(TT, true) << " }\n";
+ Out << "attributes #" << I.second << " = { " << I.first.getAsString(true)
+ << " }\n";
}
void AssemblyWriter::printUseListOrder(const Value *V,
diff --git a/llvm/lib/IR/AttributeImpl.h b/llvm/lib/IR/AttributeImpl.h
index 6abb6e3f184ad..707c8205ee1f9 100644
--- a/llvm/lib/IR/AttributeImpl.h
+++ b/llvm/lib/IR/AttributeImpl.h
@@ -342,8 +342,7 @@ class AttributeSetNode final
MemoryEffects getMemoryEffects() const;
CaptureInfo getCaptureInfo() const;
FPClassTest getNoFPClass() const;
- std::string getAsString(const Triple *TT = nullptr,
- bool InAttrGrp = false) const;
+ std::string getAsString(bool InAttrGrp) const;
Type *getAttributeType(Attribute::AttrKind Kind) const;
using iterator = const Attribute *;
diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp
index efca310cc8887..e9e2c00b3d486 100644
--- a/llvm/lib/IR/Attributes.cpp
+++ b/llvm/lib/IR/Attributes.cpp
@@ -533,7 +533,7 @@ static const char *getModRefStr(ModRefInfo MR) {
llvm_unreachable("Invalid ModRefInfo");
}
-std::string Attribute::getAsString(const Triple *TT, bool InAttrGrp) const {
+std::string Attribute::getAsString(bool InAttrGrp) const {
if (!pImpl) return {};
if (isEnumAttribute())
@@ -663,12 +663,10 @@ std::string Attribute::getAsString(const Triple *TT, bool InAttrGrp) const {
default: {
InaccessibleTargetMemLocation TargetLoc =
static_cast<InaccessibleTargetMemLocation>(Loc);
- if (TargetLoc == InaccessibleTargetMemLocation::MEM_TARGET_0)
- OS << TT->getTargetMemLocName(
- static_cast<Triple::InaccessibleTargetMemLocation>(TargetLoc));
- if (TargetLoc == InaccessibleTargetMemLocation::MEM_TARGET_1)
- OS << TT->getTargetMemLocName(
- static_cast<Triple::InaccessibleTargetMemLocation>(TargetLoc));
+ if (TargetLoc == InaccessibleTargetMemLocation::TargetMem0)
+ OS << "target_mem0 ";
+ if (TargetLoc == InaccessibleTargetMemLocation::TargetMem1)
+ OS << "target_mem1 ";
OS << ": ";
break;
}
@@ -1235,8 +1233,8 @@ FPClassTest AttributeSet::getNoFPClass() const {
return SetNode ? SetNode->getNoFPClass() : fcNone;
}
-std::string AttributeSet::getAsString(const Triple *TT, bool InAttrGrp) const {
- return SetNode ? SetNode->getAsString(TT, InAttrGrp) : "";
+std::string AttributeSet::getAsString(bool InAttrGrp) const {
+ return SetNode ? SetNode->getAsString(InAttrGrp) : "";
}
bool AttributeSet::hasParentContext(LLVMContext &C) const {
@@ -1259,7 +1257,7 @@ AttributeSet::iterator AttributeSet::end() const {
LLVM_DUMP_METHOD void AttributeSet::dump() const {
dbgs() << "AS =\n";
dbgs() << " { ";
- dbgs() << getAsString(nullptr, true) << " }\n";
+ dbgs() << getAsString(true) << " }\n";
}
#endif
@@ -1431,13 +1429,12 @@ FPClassTest AttributeSetNode::getNoFPClass() const {
return fcNone;
}
-std::string AttributeSetNode::getAsString(const Triple *TT,
- bool InAttrGrp) const {
+std::string AttributeSetNode::getAsString(bool InAttrGrp) const {
std::string Str;
for (iterator I = begin(), E = end(); I != E; ++I) {
if (I != begin())
Str += ' ';
- Str += I->getAsString(TT, InAttrGrp);
+ Str += I->getAsString(InAttrGrp);
}
return Str;
}
@@ -2028,7 +2025,7 @@ MemoryEffects AttributeList::getMemoryEffects() const {
}
std::string AttributeList::getAsString(unsigned Index, bool InAttrGrp) const {
- return getAttributes(Index).getAsString(nullptr, InAttrGrp);
+ return getAttributes(Index).getAsString(InAttrGrp);
}
AttributeSet AttributeList::getAttributes(unsigned Index) const {
diff --git a/llvm/lib/Support/ModRef.cpp b/llvm/lib/Support/ModRef.cpp
index f78a135d1d698..c5f757359a3c0 100644
--- a/llvm/lib/Support/ModRef.cpp
+++ b/llvm/lib/Support/ModRef.cpp
@@ -52,10 +52,10 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, MemoryEffects ME) {
default: {
InaccessibleTargetMemLocation TargetLoc =
static_cast<InaccessibleTargetMemLocation>(Loc);
- if (TargetLoc == InaccessibleTargetMemLocation::MEM_TARGET_0)
- OS << "MEM_TARGET_0: ";
- if (TargetLoc == InaccessibleTargetMemLocation::MEM_TARGET_1)
- OS << "MEM_TARGET_1: ";
+ if (TargetLoc == InaccessibleTargetMemLocation::TargetMem0)
+ OS << "TargetMem0: ";
+ if (TargetLoc == InaccessibleTargetMemLocation::TargetMem1)
+ OS << "TargetMem1: ";
break;
}
}
diff --git a/llvm/lib/TargetParser/Triple.cpp b/llvm/lib/TargetParser/Triple.cpp
index c367341637cbe..11ba9ee32f66a 100644
--- a/llvm/lib/TargetParser/Triple.cpp
+++ b/llvm/lib/TargetParser/Triple.cpp
@@ -2361,31 +2361,6 @@ ExceptionHandling Triple::getDefaultExceptionHandling() const {
return ExceptionHandling::None;
}
-StringRef Triple::aarch64GetTargetMemLocName(
- Triple::InaccessibleTargetMemLocation Kind) const {
- switch (Kind) {
- case InaccessibleTargetMemLocation::MEM_TARGET_0:
- return "aarch64_fprm";
- case InaccessibleTargetMemLocation::MEM_TARGET_1:
- return "aarch64_za";
- }
-}
-
-StringRef
-Triple::getTargetMemLocName(InaccessibleTargetMemLocation Kind) const {
-
- if (isAArch64())
- return aarch64GetTargetMemLocName(Kind);
-
- switch (Kind) {
- case InaccessibleTargetMemLocation::MEM_TARGET_0:
- return "mem_target_0";
- case InaccessibleTargetMemLocation::MEM_TARGET_1:
- return "mem_target_1";
- }
- return "unkown";
-}
-
// HLSL triple environment orders are relied on in the front end
static_assert(Triple::Vertex - Triple::Pixel == 1,
"incorrect HLSL stage order");
diff --git a/llvm/test/Assembler/aarch64-memory-attribute.ll b/llvm/test/Assembler/aarch64-memory-attribute.ll
index 48f05ec9dec8a..1eec7b765d555 100644
--- a/llvm/test/Assembler/aarch64-memory-attribute.ll
+++ b/llvm/test/Assembler/aarch64-memory-attribute.ll
@@ -3,33 +3,33 @@
target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
target triple = "aarch64"
-; CHECK: Function Attrs: memory(aarch64_za: write)
+; CHECK: Function Attrs: memory(target_mem1 : write)
; CHECK: @fn_inaccessiblemem_write_aarch64_za() [[ATTR0:#.*]]
declare void @fn_inaccessiblemem_write_aarch64_za()
memory(aarch64_za: write)
-; CHECK: Function Attrs: memory(aarch64_za: read)
+; CHECK: Function Attrs: memory(target_mem1 : read)
; CHECK: @fn_inaccessiblemem_read_aarch64_za() [[ATTR1:#.*]]
declare void @fn_inaccessiblemem_read_aarch64_za()
memory(aarch64_za: read)
-; CHECK: Function Attrs: memory(aarch64_fprm: write)
+; CHECK: Function Attrs: memory(target_mem0 : write)
; CHECK: @fn_inaccessiblemem_write_aarch64_fpmr() [[ATTR2:#.*]]
declare void @fn_inaccessiblemem_write_aarch64_fpmr()
memory(aarch64_fpmr: write)
-; CHECK: ; Function Attrs: memory(aarch64_fprm: read)
+; CHECK: ; Function Attrs: memory(target_mem0 : read)
; CHECK: @fn_inaccessiblemem_read_aarch64_fpmr() [[ATTR3:#.*]]
declare void @fn_inaccessiblemem_read_aarch64_fpmr()
memory(aarch64_fpmr: read)
-; CHECK: Function Attrs: memory(aarch64_fprm: read, aarch64_za: write)
+; CHECK: Function Attrs: memory(target_mem0 : read, target_mem1 : write)
; CHECK: @fn_inaccessiblemem_read_aarch64_fpmr_write_aarch64_za() [[ATTR4:#.*]]
declare void @fn_inaccessiblemem_read_aarch64_fpmr_write_aarch64_za()
memory(aarch64_fpmr: read, aarch64_za: write)
-; CHECK: attributes [[ATTR0]] = { memory(aarch64_za: write) }
-; CHECK: attributes [[ATTR1]] = { memory(aarch64_za: read) }
-; CHECK: attributes [[ATTR2]] = { memory(aarch64_fprm: write) }
-; CHECK: attributes [[ATTR3]] = { memory(aarch64_fprm: read) }
-; CHECK: attributes [[ATTR4]] = { memory(aarch64_fprm: read, aarch64_za: write) }
+; CHECK: attributes [[ATTR0]] = { memory(target_mem1 : write) }
+; CHECK: attributes [[ATTR1]] = { memory(target_mem1 : read) }
+; CHECK: attributes [[ATTR2]] = { memory(target_mem0 : write) }
+; CHECK: attributes [[ATTR3]] = { memory(target_mem0 : read) }
+; CHECK: attributes [[ATTR4]] = { memory(target_mem0 : read, target_mem1 : write) }
diff --git a/llvm/test/Assembler/memory-attribute.ll b/llvm/test/Assembler/memory-attribute.ll
index a12a826dc97fe..d9bd504a763a2 100644
--- a/llvm/test/Assembler/memory-attribute.ll
+++ b/llvm/test/Assembler/memory-attribute.ll
@@ -79,27 +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(mem_target_1: write)
-; CHECK: @fn_inaccessiblemem_write_aarch64_za()
-declare void @fn_inaccessiblemem_write_aarch64_za()
- memory(aarch64_za: write)
-
-; CHECK: Function Attrs: memory(mem_target_1: read)
-; CHECK: @fn_inaccessiblemem_read_aarch64_za()
-declare void @fn_inaccessiblemem_read_aarch64_za()
- memory(aarch64_za: read)
-
-; CHECK: Function Attrs: memory(mem_target_0: write)
-; CHECK: @fn_inaccessiblemem_write_aarch64_fpmr()
-declare void @fn_inaccessiblemem_write_aarch64_fpmr()
- memory(aarch64_fpmr: write)
-
-; CHECK: Function Attrs: memory(mem_target_0: read)
-; CHECK: @fn_inaccessiblemem_read_aarch64_fpmr()
-declare void @fn_inaccessiblemem_read_aarch64_fpmr()
- memory(aarch64_fpmr: read)
-
-; CHECK: Function Attrs: memory(mem_target_0: read, mem_target_1: 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)
+; CHECK: Function Attrs: memory(target_mem1 : write)
+; CHECK: @fn_inaccessiblemem_write_mem_target1()
+declare void @fn_inaccessiblemem_write_mem_target1()
+ memory(aarch64_za : write)
+
+; CHECK: Function Attrs: memory(target_mem1 : read)
+; CHECK: @fn_inaccessiblemem_read_mem_target1()
+declare void @fn_inaccessiblemem_read_mem_target1()
+ memory(aarch64_za : read)
+
+; CHECK: Function Attrs: memory(target_mem0 : write)
+; CHECK: @fn_inaccessiblemem_write_target_mem0()
+declare void @fn_inaccessiblemem_write_target_mem0()
+ memory(aarch64_fpmr : write)
+
+; CHECK: Function Attrs: memory(target_mem0 : read)
+; CHECK: @fn_inaccessiblemem_read_target_mem0()
+declare void @fn_inaccessiblemem_read_target_mem0()
+ memory(aarch64_fpmr : read)
+
+; CHECK: Function Attrs: memory(target_mem0 : read, target_mem1 : write)
+; CHECK: @fn_inaccessiblemem_read_target_mem0_write_mem_target1()
+declare void @fn_inaccessiblemem_read_target_mem0_write_mem_target1()
+ memory(aarch64_fpmr : read, aarch64_za : write)
diff --git a/llvm/test/TableGen/intrinsic-attrs-fp8.td b/llvm/test/TableGen/intrinsic-attrs-fp8.td
index ba2fd0eb07b61..6a92f3fa624e0 100644
--- a/llvm/test/TableGen/intrinsic-attrs-fp8.td
+++ b/llvm/test/TableGen/intrinsic-attrs-fp8.td
@@ -24,7 +24,7 @@ def int_aarch64_get_fpmr_set_za : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [In
// 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, MEM_TARGET_0: Ref, MEM_TARGET_1: Mod, Other: NoModRef
+// CHECK-NEXT: // ArgMem: NoModRef, InaccessibleMem: NoModRef, ErrnoMem: NoModRef, TargetMem0: Ref, TargetMem1: Mod, Other: NoModRef
// CHECK-NEXT: Attribute::getWithMemoryEffects(C, MemoryEffects::createFromIntValue(576)),
// CHECK-NEXT: });
// CHECK-NEXT: case 1:
@@ -34,7 +34,7 @@ def int_aarch64_get_fpmr_set_za : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [In
// 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, MEM_TARGET_0: NoModRef, MEM_TARGET_1: Ref, Other: NoModRef
+// CHECK-NEXT: // ArgMem: NoModRef, InaccessibleMem: NoModRef, ErrnoMem: NoModRef, TargetMem0: NoModRef, TargetMem1: Ref, Other: NoModRef
// CHECK-NEXT: Attribute::getWithMemoryEffects(C, MemoryEffects::createFromIntValue(256)),
// CHECK-NEXT: });
// CHECK-NEXT: case 2:
@@ -44,7 +44,7 @@ def int_aarch64_get_fpmr_set_za : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [In
// 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, MEM_TARGET_0: Mod, MEM_TARGET_1: NoModRef, Other: NoModRef
+// CHECK-NEXT: // ArgMem: NoModRef, InaccessibleMem: NoModRef, ErrnoMem: NoModRef, TargetMem0: Mod, TargetMem1: NoModRef, Other: NoModRef
// CHECK-NEXT: Attribute::getWithMemoryEffects(C, MemoryEffects::createFromIntValue(128)),
// CHECK: static constexpr uint16_t IntrinsicsToAttributesMap[] = {
diff --git a/llvm/unittests/Support/ModRefTest.cpp b/llvm/unittests/Support/ModRefTest.cpp
index 3fd8a5fee5c6b..36c926d9e2945 100644
--- a/llvm/unittests/Support/ModRefTest.cpp
+++ b/llvm/unittests/Support/ModRefTest.cpp
@@ -20,10 +20,9 @@ TEST(ModRefTest, PrintMemoryEffects) {
std::string S;
raw_string_ostream OS(S);
OS << MemoryEffects::none();
- EXPECT_EQ(S,
- "ArgMem: NoModRef, InaccessibleMem: NoModRef, ErrnoMem: "
- "NoModRef, MEM_TARGET_0: NoModRef, MEM_TARGET_1: NoModRef, Other: "
- "NoModRef");
+ EXPECT_EQ(S, "ArgMem: NoModRef, InaccessibleMem: NoModRef, ErrnoMem: "
+ "NoModRef, TargetMem0: NoModRef, TargetMem1: NoModRef, Other: "
+ "NoModRef");
}
} // namespace
diff --git a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
index 652f00d15385c..b8446f55f36f0 100644
--- a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
+++ b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
@@ -471,10 +471,10 @@ CodeGenIntrinsic::getLocationTypeAsInt(const Record *R,
StringRef Name = LocRec->getName();
if (Name == "AArch64_FPMR")
return static_cast<IRMemLocation>(
- llvm::InaccessibleTargetMemLocation::MEM_TARGET_0);
+ llvm::InaccessibleTargetMemLocation::TargetMem0);
else if (Name == "AArch64_ZA")
return static_cast<IRMemLocation>(
- llvm::InaccessibleTargetMemLocation::MEM_TARGET_1);
+ llvm::InaccessibleTargetMemLocation::TargetMem1);
else if (Name == "InaccessibleMem")
return llvm::IRMemLocation::InaccessibleMem;
else
>From c609105d240fdc71c08287259a8ea24d2f2c16c0 Mon Sep 17 00:00:00 2001
From: CarolineConcatto <caroline.concatto at arm.com>
Date: Tue, 23 Sep 2025 11:57:30 +0000
Subject: [PATCH 12/19] Remove all Target specific tokens and definitions
It also fix this warning:
ModRef.cpp:52:5: error: default label in switch which covers all enumeration values [-Werror,-Wcovered-switch-default]
---
llvm/include/llvm/AsmParser/LLToken.h | 4 +-
llvm/include/llvm/IR/Intrinsics.td | 5 +-
llvm/lib/AsmParser/LLLexer.cpp | 4 +-
llvm/lib/AsmParser/LLParser.cpp | 4 +-
llvm/lib/IR/Attributes.cpp | 22 +++++---
llvm/lib/Support/ModRef.cpp | 15 +++---
.../Assembler/aarch64-memory-attribute.ll | 50 +++++++++----------
llvm/test/Assembler/memory-attribute.ll | 20 ++++----
llvm/test/TableGen/intrinsic-attrs-fp8.td | 12 ++---
.../TableGen/Basic/CodeGenIntrinsics.cpp | 4 +-
10 files changed, 72 insertions(+), 68 deletions(-)
diff --git a/llvm/include/llvm/AsmParser/LLToken.h b/llvm/include/llvm/AsmParser/LLToken.h
index a3cfa646d1e21..24f84cfa09e34 100644
--- a/llvm/include/llvm/AsmParser/LLToken.h
+++ b/llvm/include/llvm/AsmParser/LLToken.h
@@ -206,8 +206,8 @@ enum Kind {
kw_readwrite,
kw_argmem,
kw_inaccessiblemem,
- kw_aarch64_fpmr,
- kw_aarch64_za,
+ kw_target_mem0,
+ kw_target_mem1,
kw_errnomem,
// Legacy attributes:
diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td
index 71e999861550a..7c98cb3232e17 100644
--- a/llvm/include/llvm/IR/Intrinsics.td
+++ b/llvm/include/llvm/IR/Intrinsics.td
@@ -53,9 +53,8 @@ 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;
+def TargetMem0 : IntrinsicMemoryLocation;
+def TargetMem1 : 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;}
diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp
index 8d34d74a0535f..ebca344ae7b93 100644
--- a/llvm/lib/AsmParser/LLLexer.cpp
+++ b/llvm/lib/AsmParser/LLLexer.cpp
@@ -707,8 +707,8 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(write);
KEYWORD(readwrite);
KEYWORD(argmem);
- KEYWORD(aarch64_fpmr);
- KEYWORD(aarch64_za);
+ KEYWORD(target_mem0);
+ KEYWORD(target_mem1);
KEYWORD(inaccessiblemem);
KEYWORD(errnomem);
KEYWORD(argmemonly);
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index 2fb2b1bfcf9f0..e893a657a2851 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -1696,10 +1696,10 @@ static std::optional<MemoryEffects::Location> keywordToLoc(lltok::Kind Tok) {
return IRMemLocation::InaccessibleMem;
case lltok::kw_errnomem:
return IRMemLocation::ErrnoMem;
- case lltok::kw_aarch64_fpmr:
+ case lltok::kw_target_mem0:
return static_cast<IRMemLocation>(
llvm::InaccessibleTargetMemLocation::TargetMem0);
- case lltok::kw_aarch64_za:
+ case lltok::kw_target_mem1:
return static_cast<IRMemLocation>(
llvm::InaccessibleTargetMemLocation::TargetMem1);
default:
diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp
index e9e2c00b3d486..5b4071b544ebe 100644
--- a/llvm/lib/IR/Attributes.cpp
+++ b/llvm/lib/IR/Attributes.cpp
@@ -660,17 +660,23 @@ 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::TargetMem0)
- OS << "target_mem0 ";
- if (TargetLoc == InaccessibleTargetMemLocation::TargetMem1)
- OS << "target_mem1 ";
- OS << ": ";
break;
}
+ // Target Memory locations are not IRMemLocation.
+ // It is breaking buildbots when it treats warning as error
+ if (static_cast<int>(Loc) > static_cast<int>(IRMemLocation::ErrnoMem)) {
+ InaccessibleTargetMemLocation TargetMemLoc =
+ static_cast<InaccessibleTargetMemLocation>(Loc);
+ switch (TargetMemLoc) {
+ case InaccessibleTargetMemLocation::TargetMem0:
+ OS << "target_mem0: ";
+ break;
+ case InaccessibleTargetMemLocation::TargetMem1:
+ OS << "target_mem1: ";
+ break;
+ }
}
+
OS << getModRefStr(MR);
}
OS << ")";
diff --git a/llvm/lib/Support/ModRef.cpp b/llvm/lib/Support/ModRef.cpp
index c5f757359a3c0..daefae2f59dbf 100644
--- a/llvm/lib/Support/ModRef.cpp
+++ b/llvm/lib/Support/ModRef.cpp
@@ -49,15 +49,14 @@ 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::TargetMem0)
- OS << "TargetMem0: ";
- if (TargetLoc == InaccessibleTargetMemLocation::TargetMem1)
- OS << "TargetMem1: ";
+ case static_cast<IRMemLocation>(
+ static_cast<int>(InaccessibleTargetMemLocation::TargetMem0)):
+ OS << "TargetMem0: ";
+ break;
+ case static_cast<IRMemLocation>(
+ static_cast<int>(InaccessibleTargetMemLocation::TargetMem1)):
+ OS << "TargetMem1: ";
break;
- }
}
OS << ME.getModRef(Loc);
});
diff --git a/llvm/test/Assembler/aarch64-memory-attribute.ll b/llvm/test/Assembler/aarch64-memory-attribute.ll
index 1eec7b765d555..d19b49cdac142 100644
--- a/llvm/test/Assembler/aarch64-memory-attribute.ll
+++ b/llvm/test/Assembler/aarch64-memory-attribute.ll
@@ -3,33 +3,33 @@
target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
target triple = "aarch64"
-; CHECK: Function Attrs: memory(target_mem1 : write)
-; CHECK: @fn_inaccessiblemem_write_aarch64_za() [[ATTR0:#.*]]
-declare void @fn_inaccessiblemem_write_aarch64_za()
- memory(aarch64_za: write)
+; CHECK: Function Attrs: memory(target_mem1: write)
+; CHECK: @fn_inaccessiblemem_write_target_mem1() [[ATTR0:#.*]]
+declare void @fn_inaccessiblemem_write_target_mem1()
+ memory(target_mem1: write)
-; CHECK: Function Attrs: memory(target_mem1 : read)
-; CHECK: @fn_inaccessiblemem_read_aarch64_za() [[ATTR1:#.*]]
-declare void @fn_inaccessiblemem_read_aarch64_za()
- memory(aarch64_za: read)
+; CHECK: Function Attrs: memory(target_mem1: read)
+; CHECK: @fn_inaccessiblemem_read_target_mem1() [[ATTR1:#.*]]
+declare void @fn_inaccessiblemem_read_target_mem1()
+ memory(target_mem1: read)
-; CHECK: Function Attrs: memory(target_mem0 : write)
-; CHECK: @fn_inaccessiblemem_write_aarch64_fpmr() [[ATTR2:#.*]]
-declare void @fn_inaccessiblemem_write_aarch64_fpmr()
- memory(aarch64_fpmr: write)
+; CHECK: Function Attrs: memory(target_mem0: write)
+; CHECK: @fn_inaccessiblemem_write_target_mem0() [[ATTR2:#.*]]
+declare void @fn_inaccessiblemem_write_target_mem0()
+ memory(target_mem0: write)
-; CHECK: ; Function Attrs: memory(target_mem0 : read)
-; CHECK: @fn_inaccessiblemem_read_aarch64_fpmr() [[ATTR3:#.*]]
-declare void @fn_inaccessiblemem_read_aarch64_fpmr()
- memory(aarch64_fpmr: read)
+; CHECK: ; Function Attrs: memory(target_mem0: read)
+; CHECK: @fn_inaccessiblemem_read_target_mem0() [[ATTR3:#.*]]
+declare void @fn_inaccessiblemem_read_target_mem0()
+ memory(target_mem0: read)
-; CHECK: Function Attrs: memory(target_mem0 : read, target_mem1 : write)
-; CHECK: @fn_inaccessiblemem_read_aarch64_fpmr_write_aarch64_za() [[ATTR4:#.*]]
-declare void @fn_inaccessiblemem_read_aarch64_fpmr_write_aarch64_za()
- memory(aarch64_fpmr: read, aarch64_za: write)
+; CHECK: Function Attrs: memory(target_mem0: read, target_mem1: write)
+; CHECK: @fn_inaccessiblemem_read_target_mem0_write_target_mem1() [[ATTR4:#.*]]
+declare void @fn_inaccessiblemem_read_target_mem0_write_target_mem1()
+ memory(target_mem0: read, target_mem1: write)
-; CHECK: attributes [[ATTR0]] = { memory(target_mem1 : write) }
-; CHECK: attributes [[ATTR1]] = { memory(target_mem1 : read) }
-; CHECK: attributes [[ATTR2]] = { memory(target_mem0 : write) }
-; CHECK: attributes [[ATTR3]] = { memory(target_mem0 : read) }
-; CHECK: attributes [[ATTR4]] = { memory(target_mem0 : read, target_mem1 : write) }
+; CHECK: attributes [[ATTR0]] = { memory(target_mem1: write) }
+; CHECK: attributes [[ATTR1]] = { memory(target_mem1: read) }
+; CHECK: attributes [[ATTR2]] = { memory(target_mem0: write) }
+; CHECK: attributes [[ATTR3]] = { memory(target_mem0: read) }
+; CHECK: attributes [[ATTR4]] = { memory(target_mem0: read, target_mem1: write) }
diff --git a/llvm/test/Assembler/memory-attribute.ll b/llvm/test/Assembler/memory-attribute.ll
index d9bd504a763a2..98eb2d88b2b52 100644
--- a/llvm/test/Assembler/memory-attribute.ll
+++ b/llvm/test/Assembler/memory-attribute.ll
@@ -79,27 +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(target_mem1 : write)
+; CHECK: Function Attrs: memory(target_mem1: write)
; CHECK: @fn_inaccessiblemem_write_mem_target1()
declare void @fn_inaccessiblemem_write_mem_target1()
- memory(aarch64_za : write)
+ memory(target_mem1: write)
-; CHECK: Function Attrs: memory(target_mem1 : read)
+; CHECK: Function Attrs: memory(target_mem1: read)
; CHECK: @fn_inaccessiblemem_read_mem_target1()
declare void @fn_inaccessiblemem_read_mem_target1()
- memory(aarch64_za : read)
+ memory(target_mem1: read)
-; CHECK: Function Attrs: memory(target_mem0 : write)
+; CHECK: Function Attrs: memory(target_mem0: write)
; CHECK: @fn_inaccessiblemem_write_target_mem0()
declare void @fn_inaccessiblemem_write_target_mem0()
- memory(aarch64_fpmr : write)
+ memory(target_mem0: write)
-; CHECK: Function Attrs: memory(target_mem0 : read)
+; CHECK: Function Attrs: memory(target_mem0: read)
; CHECK: @fn_inaccessiblemem_read_target_mem0()
declare void @fn_inaccessiblemem_read_target_mem0()
- memory(aarch64_fpmr : read)
+ memory(target_mem0: read)
-; CHECK: Function Attrs: memory(target_mem0 : read, target_mem1 : write)
+; CHECK: Function Attrs: memory(target_mem0: read, target_mem1: write)
; CHECK: @fn_inaccessiblemem_read_target_mem0_write_mem_target1()
declare void @fn_inaccessiblemem_read_target_mem0_write_mem_target1()
- memory(aarch64_fpmr : read, aarch64_za : write)
+ memory(target_mem0: read, target_mem1: write)
diff --git a/llvm/test/TableGen/intrinsic-attrs-fp8.td b/llvm/test/TableGen/intrinsic-attrs-fp8.td
index 6a92f3fa624e0..3395e56c100a8 100644
--- a/llvm/test/TableGen/intrinsic-attrs-fp8.td
+++ b/llvm/test/TableGen/intrinsic-attrs-fp8.td
@@ -2,11 +2,11 @@
include "llvm/IR/Intrinsics.td"
-def int_aarch64_set_fpmr_2 : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [IntrInaccessibleWriteMemOnly<AArch64_FPMR>]>;
+def int_aarch64_set_fpmr_2 : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [IntrInaccessibleWriteMemOnly<TargetMem0>]>;
-def int_aarch64_get_za_2 : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [IntrInaccessibleReadMemOnly<AArch64_ZA>]>;
+def int_aarch64_get_za_2 : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [IntrInaccessibleReadMemOnly<TargetMem1>]>;
-def int_aarch64_get_fpmr_set_za : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [IntrInaccessibleReadMemOnly<AArch64_FPMR>, IntrInaccessibleWriteMemOnly<AArch64_ZA>]>;
+def int_aarch64_get_fpmr_set_za : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [IntrInaccessibleReadMemOnly<TargetMem0>, IntrInaccessibleWriteMemOnly<TargetMem1>]>;
// CHECK: static constexpr unsigned IntrinsicNameOffsetTable[] = {
// CHECK-NEXT: 1, // not_intrinsic
@@ -48,7 +48,7 @@ def int_aarch64_get_fpmr_set_za : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [In
// CHECK-NEXT: Attribute::getWithMemoryEffects(C, MemoryEffects::createFromIntValue(128)),
// 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: 0 << 1 | 0, // llvm.aarch64.get.fpmr.set.za
+// CHECK-NEXT: 1 << 1 | 0, // llvm.aarch64.get.za.2
+// CHECK-NEXT: 2 << 1 | 0, // llvm.aarch64.set.fpmr.2
// CHECK-NEXT:};
diff --git a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
index b8446f55f36f0..7ab0c68b5fea1 100644
--- a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
+++ b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
@@ -469,10 +469,10 @@ CodeGenIntrinsic::getLocationTypeAsInt(const Record *R,
StringRef FieldName) const {
const Record *LocRec = R->getValueAsDef(FieldName);
StringRef Name = LocRec->getName();
- if (Name == "AArch64_FPMR")
+ if (Name == "TargetMem0")
return static_cast<IRMemLocation>(
llvm::InaccessibleTargetMemLocation::TargetMem0);
- else if (Name == "AArch64_ZA")
+ else if (Name == "TargetMem1")
return static_cast<IRMemLocation>(
llvm::InaccessibleTargetMemLocation::TargetMem1);
else if (Name == "InaccessibleMem")
>From 25b15b604ba199e4a9889c89a135c66fbbf6d68c Mon Sep 17 00:00:00 2001
From: CarolineConcatto <caroline.concatto at arm.com>
Date: Tue, 30 Sep 2025 15:02:36 +0000
Subject: [PATCH 13/19] Address review comments
---
llvm/include/llvm/Support/ModRef.h | 30 ++++++++--------
llvm/include/llvm/TableGen/Record.h | 1 -
llvm/lib/AsmParser/LLParser.cpp | 36 +++++++++----------
llvm/lib/IR/AsmWriter.cpp | 4 +--
llvm/lib/IR/Attributes.cpp | 20 ++++-------
llvm/lib/Support/ModRef.cpp | 6 ++--
llvm/lib/Transforms/IPO/FunctionAttrs.cpp | 3 +-
.../Assembler/aarch64-memory-attribute.ll | 35 ------------------
llvm/test/Assembler/memory-attribute.ll | 28 +++++++--------
llvm/test/TableGen/intrinsic-attrs-fp8.td | 12 +++----
llvm/unittests/Support/ModRefTest.cpp | 2 +-
.../TableGen/Basic/CodeGenIntrinsics.cpp | 6 ++--
12 files changed, 66 insertions(+), 117 deletions(-)
delete mode 100644 llvm/test/Assembler/aarch64-memory-attribute.ll
diff --git a/llvm/include/llvm/Support/ModRef.h b/llvm/include/llvm/Support/ModRef.h
index 9266980d635f7..b15d4f77804cd 100644
--- a/llvm/include/llvm/Support/ModRef.h
+++ b/llvm/include/llvm/Support/ModRef.h
@@ -56,11 +56,6 @@ enum class ModRefInfo : uint8_t {
/// Debug print ModRefInfo.
LLVM_ABI raw_ostream &operator<<(raw_ostream &OS, ModRefInfo MR);
-enum class InaccessibleTargetMemLocation {
- TargetMem0 = 3,
- TargetMem1 = 4,
-};
-
/// The locations at which a function might access memory.
enum class IRMemLocation {
/// Access to memory via argument pointers.
@@ -70,11 +65,16 @@ enum class IRMemLocation {
/// Errno memory.
ErrnoMem = 2,
/// Any other memory.
- Other = 5,
+ Other = 3,
+ /// Target Memory Location
+ /// Used by a target to represent target specif memory regions
+ TargetMem0 = 4,
+ TargetMem1 = 5,
/// Helpers to iterate all locations in the MemoryEffectsBase class.
First = ArgMem,
- Last = Other,
+ Last = TargetMem1,
+ FirstTarget = TargetMem0,
};
template <typename LocationEnum> class MemoryEffectsBase {
@@ -175,8 +175,8 @@ template <typename LocationEnum> class MemoryEffectsBase {
/// cleared.
bool onlyAccessTargetMemoryLocation() {
MemoryEffectsBase ME = *this;
- for (unsigned I = static_cast<int>(LocationEnum::ErrnoMem);
- I < static_cast<int>(LocationEnum::Last); I++)
+ for (unsigned I = static_cast<int>(LocationEnum::FirstTarget);
+ I <= static_cast<int>(LocationEnum::Last); I++)
ME = ME.getWithoutLoc(static_cast<IRMemLocation>(I));
return ME.doesNotAccessMemory();
}
@@ -185,7 +185,7 @@ template <typename LocationEnum> class MemoryEffectsBase {
static MemoryEffectsBase
setTargetMemLocationModRef(ModRefInfo MR = ModRefInfo::NoModRef) {
MemoryEffectsBase FRMB = none();
- for (unsigned I = static_cast<int>(LocationEnum::ErrnoMem);
+ for (unsigned I = static_cast<int>(LocationEnum::FirstTarget);
I < static_cast<int>(LocationEnum::Last); I++)
FRMB.setModRef(static_cast<Location>(I), MR);
return FRMB;
@@ -218,8 +218,8 @@ template <typename LocationEnum> class MemoryEffectsBase {
}
bool isTargetMemLoc(IRMemLocation Loc) {
- return static_cast<unsigned>(Loc) >
- static_cast<unsigned>(Location::ErrnoMem);
+ return static_cast<unsigned>(Loc) >=
+ static_cast<unsigned>(Location::FirstTarget);
}
/// Convert MemoryEffectsBase into an encoded integer value (used by memory
@@ -276,10 +276,8 @@ template <typename LocationEnum> class MemoryEffectsBase {
/// Whether this function only (at most) accesses inaccessible memory.
bool onlyAccessesInaccessibleMem() const {
- return getWithoutLoc(static_cast<IRMemLocation>(
- llvm::InaccessibleTargetMemLocation::TargetMem0))
- .getWithoutLoc(static_cast<IRMemLocation>(
- llvm::InaccessibleTargetMemLocation::TargetMem1))
+ return getWithoutLoc(IRMemLocation::TargetMem0)
+ .getWithoutLoc(IRMemLocation::TargetMem1)
.getWithoutLoc(Location::InaccessibleMem)
.doesNotAccessMemory();
}
diff --git a/llvm/include/llvm/TableGen/Record.h b/llvm/include/llvm/TableGen/Record.h
index 215e142279d59..cb2721aba4f25 100644
--- a/llvm/include/llvm/TableGen/Record.h
+++ b/llvm/include/llvm/TableGen/Record.h
@@ -25,7 +25,6 @@
#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"
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index e893a657a2851..bdc2d4b8da649 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -1688,25 +1688,6 @@ 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_target_mem0:
- return static_cast<IRMemLocation>(
- llvm::InaccessibleTargetMemLocation::TargetMem0);
- case lltok::kw_target_mem1:
- return static_cast<IRMemLocation>(
- llvm::InaccessibleTargetMemLocation::TargetMem1);
- default:
- return std::nullopt;
- }
-}
-
/// parseFnAttributeValuePairs
/// ::= <attr> | <attr> '=' <value>
bool LLParser::parseFnAttributeValuePairs(AttrBuilder &B,
@@ -2563,6 +2544,23 @@ 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;
+ case lltok::kw_target_mem0:
+ return IRMemLocation::TargetMem0;
+ case lltok::kw_target_mem1:
+ return IRMemLocation::TargetMem1;
+ default:
+ return std::nullopt;
+ }
+}
+
static std::optional<ModRefInfo> keywordToModRef(lltok::Kind Tok) {
switch (Tok) {
case lltok::kw_none:
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index 58f8dbec34a48..58c2ff500c859 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -4969,8 +4969,8 @@ void AssemblyWriter::writeAllAttributeGroups() {
asVec[I.second] = I;
for (const auto &I : asVec)
- Out << "attributes #" << I.second << " = { " << I.first.getAsString(true)
- << " }\n";
+ Out << "attributes #" << I.second << " = { "
+ << I.first.getAsString(true) << " }\n";
}
void AssemblyWriter::printUseListOrder(const Value *V,
diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp
index 5b4071b544ebe..55871c7ad5bef 100644
--- a/llvm/lib/IR/Attributes.cpp
+++ b/llvm/lib/IR/Attributes.cpp
@@ -661,20 +661,12 @@ std::string Attribute::getAsString(bool InAttrGrp) const {
case IRMemLocation::Other:
llvm_unreachable("This is represented as the default access kind");
break;
- }
- // Target Memory locations are not IRMemLocation.
- // It is breaking buildbots when it treats warning as error
- if (static_cast<int>(Loc) > static_cast<int>(IRMemLocation::ErrnoMem)) {
- InaccessibleTargetMemLocation TargetMemLoc =
- static_cast<InaccessibleTargetMemLocation>(Loc);
- switch (TargetMemLoc) {
- case InaccessibleTargetMemLocation::TargetMem0:
- OS << "target_mem0: ";
- break;
- case InaccessibleTargetMemLocation::TargetMem1:
- OS << "target_mem1: ";
- break;
- }
+ case IRMemLocation::TargetMem0:
+ OS << "target_mem0: ";
+ break;
+ case IRMemLocation::TargetMem1:
+ OS << "target_mem1: ";
+ break;
}
OS << getModRefStr(MR);
diff --git a/llvm/lib/Support/ModRef.cpp b/llvm/lib/Support/ModRef.cpp
index daefae2f59dbf..1083c72902c0b 100644
--- a/llvm/lib/Support/ModRef.cpp
+++ b/llvm/lib/Support/ModRef.cpp
@@ -49,12 +49,10 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, MemoryEffects ME) {
case IRMemLocation::Other:
OS << "Other: ";
break;
- case static_cast<IRMemLocation>(
- static_cast<int>(InaccessibleTargetMemLocation::TargetMem0)):
+ case IRMemLocation::TargetMem0:
OS << "TargetMem0: ";
break;
- case static_cast<IRMemLocation>(
- static_cast<int>(InaccessibleTargetMemLocation::TargetMem1)):
+ case IRMemLocation::TargetMem1:
OS << "TargetMem1: ";
break;
}
diff --git a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
index 8bd6463f48299..bbb104b8631be 100644
--- a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
+++ b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
@@ -144,7 +144,8 @@ static void addLocAccess(MemoryEffects &ME, const MemoryLocation &Loc,
ME |= MemoryEffects(IRMemLocation::Other, MR);
// Should also set the other Target Memory Locations as MR.
// To compares with MemoryEffects::unknown() in addMemoryAttrs
- ME |= MemoryEffects::setTargetMemLocationModRef(MR);
+ ME |= MemoryEffects(IRMemLocation::TargetMem0, MR);
+ ME |= MemoryEffects(IRMemLocation::TargetMem1, MR);;
}
static void addArgLocs(MemoryEffects &ME, const CallBase *Call,
diff --git a/llvm/test/Assembler/aarch64-memory-attribute.ll b/llvm/test/Assembler/aarch64-memory-attribute.ll
deleted file mode 100644
index d19b49cdac142..0000000000000
--- a/llvm/test/Assembler/aarch64-memory-attribute.ll
+++ /dev/null
@@ -1,35 +0,0 @@
-; RUN: llvm-as < %s | llvm-dis | FileCheck %s
-
-target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
-target triple = "aarch64"
-
-; CHECK: Function Attrs: memory(target_mem1: write)
-; CHECK: @fn_inaccessiblemem_write_target_mem1() [[ATTR0:#.*]]
-declare void @fn_inaccessiblemem_write_target_mem1()
- memory(target_mem1: write)
-
-; CHECK: Function Attrs: memory(target_mem1: read)
-; CHECK: @fn_inaccessiblemem_read_target_mem1() [[ATTR1:#.*]]
-declare void @fn_inaccessiblemem_read_target_mem1()
- memory(target_mem1: read)
-
-; CHECK: Function Attrs: memory(target_mem0: write)
-; CHECK: @fn_inaccessiblemem_write_target_mem0() [[ATTR2:#.*]]
-declare void @fn_inaccessiblemem_write_target_mem0()
- memory(target_mem0: write)
-
-; CHECK: ; Function Attrs: memory(target_mem0: read)
-; CHECK: @fn_inaccessiblemem_read_target_mem0() [[ATTR3:#.*]]
-declare void @fn_inaccessiblemem_read_target_mem0()
- memory(target_mem0: read)
-
-; CHECK: Function Attrs: memory(target_mem0: read, target_mem1: write)
-; CHECK: @fn_inaccessiblemem_read_target_mem0_write_target_mem1() [[ATTR4:#.*]]
-declare void @fn_inaccessiblemem_read_target_mem0_write_target_mem1()
- memory(target_mem0: read, target_mem1: write)
-
-; CHECK: attributes [[ATTR0]] = { memory(target_mem1: write) }
-; CHECK: attributes [[ATTR1]] = { memory(target_mem1: read) }
-; CHECK: attributes [[ATTR2]] = { memory(target_mem0: write) }
-; CHECK: attributes [[ATTR3]] = { memory(target_mem0: read) }
-; CHECK: attributes [[ATTR4]] = { memory(target_mem0: read, target_mem1: write) }
diff --git a/llvm/test/Assembler/memory-attribute.ll b/llvm/test/Assembler/memory-attribute.ll
index 98eb2d88b2b52..63435722c03af 100644
--- a/llvm/test/Assembler/memory-attribute.ll
+++ b/llvm/test/Assembler/memory-attribute.ll
@@ -79,26 +79,26 @@ declare void @fn_argmem_read_inaccessiblemem_write()
declare void @fn_argmem_read_inaccessiblemem_write_reordered()
memory(inaccessiblemem: write, argmem: read)
-; CHECK: Function Attrs: memory(target_mem1: write)
-; CHECK: @fn_inaccessiblemem_write_mem_target1()
-declare void @fn_inaccessiblemem_write_mem_target1()
- memory(target_mem1: write)
-
-; CHECK: Function Attrs: memory(target_mem1: read)
-; CHECK: @fn_inaccessiblemem_read_mem_target1()
-declare void @fn_inaccessiblemem_read_mem_target1()
- memory(target_mem1: read)
-
; CHECK: Function Attrs: memory(target_mem0: write)
-; CHECK: @fn_inaccessiblemem_write_target_mem0()
-declare void @fn_inaccessiblemem_write_target_mem0()
+; CHECK: @fn_inaccessiblemem_write_mem_target0()
+declare void @fn_inaccessiblemem_write_mem_target0()
memory(target_mem0: write)
; CHECK: Function Attrs: memory(target_mem0: read)
-; CHECK: @fn_inaccessiblemem_read_target_mem0()
-declare void @fn_inaccessiblemem_read_target_mem0()
+; CHECK: @fn_inaccessiblemem_read_mem_target0()
+declare void @fn_inaccessiblemem_read_mem_target0()
memory(target_mem0: read)
+; CHECK: Function Attrs: memory(target_mem1: write)
+; CHECK: @fn_inaccessiblemem_write_target_mem1()
+declare void @fn_inaccessiblemem_write_target_mem1()
+ memory(target_mem1: write)
+
+; CHECK: Function Attrs: memory(target_mem1: read)
+; CHECK: @fn_inaccessiblemem_read_target_mem1()
+declare void @fn_inaccessiblemem_read_target_mem1()
+ memory(target_mem1: read)
+
; CHECK: Function Attrs: memory(target_mem0: read, target_mem1: write)
; CHECK: @fn_inaccessiblemem_read_target_mem0_write_mem_target1()
declare void @fn_inaccessiblemem_read_target_mem0_write_mem_target1()
diff --git a/llvm/test/TableGen/intrinsic-attrs-fp8.td b/llvm/test/TableGen/intrinsic-attrs-fp8.td
index 3395e56c100a8..ff9193c4983be 100644
--- a/llvm/test/TableGen/intrinsic-attrs-fp8.td
+++ b/llvm/test/TableGen/intrinsic-attrs-fp8.td
@@ -24,8 +24,8 @@ def int_aarch64_get_fpmr_set_za : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [In
// 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, TargetMem0: Ref, TargetMem1: Mod, Other: NoModRef
-// CHECK-NEXT: Attribute::getWithMemoryEffects(C, MemoryEffects::createFromIntValue(576)),
+// CHECK-NEXT: // ArgMem: NoModRef, InaccessibleMem: NoModRef, ErrnoMem: NoModRef, Other: NoModRef, TargetMem0: Ref, TargetMem1: Mod
+// CHECK-NEXT: Attribute::getWithMemoryEffects(C, MemoryEffects::createFromIntValue(2304)),
// CHECK-NEXT: });
// CHECK-NEXT: case 1:
// CHECK-NEXT: return AttributeSet::get(C, {
@@ -34,8 +34,8 @@ def int_aarch64_get_fpmr_set_za : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [In
// 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, TargetMem0: NoModRef, TargetMem1: Ref, Other: NoModRef
-// CHECK-NEXT: Attribute::getWithMemoryEffects(C, MemoryEffects::createFromIntValue(256)),
+// CHECK-NEXT: // ArgMem: NoModRef, InaccessibleMem: NoModRef, ErrnoMem: NoModRef, Other: NoModRef, TargetMem0: NoModRef, TargetMem1: Ref
+// CHECK-NEXT: Attribute::getWithMemoryEffects(C, MemoryEffects::createFromIntValue(1024)),
// CHECK-NEXT: });
// CHECK-NEXT: case 2:
// CHECK-NEXT: return AttributeSet::get(C, {
@@ -44,8 +44,8 @@ def int_aarch64_get_fpmr_set_za : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [In
// 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, TargetMem0: Mod, TargetMem1: NoModRef, Other: NoModRef
-// CHECK-NEXT: Attribute::getWithMemoryEffects(C, MemoryEffects::createFromIntValue(128)),
+// CHECK-NEXT: // ArgMem: NoModRef, InaccessibleMem: NoModRef, ErrnoMem: NoModRef, Other: NoModRef, TargetMem0: Mod, TargetMem1: NoModRef
+// CHECK-NEXT: Attribute::getWithMemoryEffects(C, MemoryEffects::createFromIntValue(512)),
// CHECK: static constexpr uint16_t IntrinsicsToAttributesMap[] = {
// CHECK-NEXT: 0 << 1 | 0, // llvm.aarch64.get.fpmr.set.za
diff --git a/llvm/unittests/Support/ModRefTest.cpp b/llvm/unittests/Support/ModRefTest.cpp
index 36c926d9e2945..9001fefa20277 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, TargetMem0: NoModRef, TargetMem1: NoModRef, Other: "
+ "NoModRef, Other: NoModRef, TargetMem0: NoModRef, TargetMem1: "
"NoModRef");
}
diff --git a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
index 7ab0c68b5fea1..719bb82242c4c 100644
--- a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
+++ b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
@@ -470,11 +470,9 @@ CodeGenIntrinsic::getLocationTypeAsInt(const Record *R,
const Record *LocRec = R->getValueAsDef(FieldName);
StringRef Name = LocRec->getName();
if (Name == "TargetMem0")
- return static_cast<IRMemLocation>(
- llvm::InaccessibleTargetMemLocation::TargetMem0);
+ return IRMemLocation::TargetMem0;
else if (Name == "TargetMem1")
- return static_cast<IRMemLocation>(
- llvm::InaccessibleTargetMemLocation::TargetMem1);
+ return IRMemLocation::TargetMem1;
else if (Name == "InaccessibleMem")
return llvm::IRMemLocation::InaccessibleMem;
else
>From 8f87c376c3f17f1e5e7f752df932286b0b7a4278 Mon Sep 17 00:00:00 2001
From: CarolineConcatto <caroline.concatto at arm.com>
Date: Fri, 3 Oct 2025 08:32:55 +0000
Subject: [PATCH 14/19] Address comments in FunctionAttrs.cpp
---
llvm/include/llvm/Support/ModRef.h | 2 +-
llvm/lib/Transforms/IPO/FunctionAttrs.cpp | 13 +--
llvm/test/TableGen/intrinsic-attrs-fp8.td | 3 +-
.../Transforms/FunctionAttrs/initializes.ll | 87 +++++++++++++++++++
4 files changed, 97 insertions(+), 8 deletions(-)
diff --git a/llvm/include/llvm/Support/ModRef.h b/llvm/include/llvm/Support/ModRef.h
index b15d4f77804cd..ef2733c2ff1e2 100644
--- a/llvm/include/llvm/Support/ModRef.h
+++ b/llvm/include/llvm/Support/ModRef.h
@@ -186,7 +186,7 @@ template <typename LocationEnum> class MemoryEffectsBase {
setTargetMemLocationModRef(ModRefInfo MR = ModRefInfo::NoModRef) {
MemoryEffectsBase FRMB = none();
for (unsigned I = static_cast<int>(LocationEnum::FirstTarget);
- I < static_cast<int>(LocationEnum::Last); I++)
+ I <= static_cast<int>(LocationEnum::Last); I++)
FRMB.setModRef(static_cast<Location>(I), MR);
return FRMB;
}
diff --git a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
index bbb104b8631be..f8b0096b46332 100644
--- a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
+++ b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
@@ -142,10 +142,6 @@ static void addLocAccess(MemoryEffects &ME, const MemoryLocation &Loc,
ME |= MemoryEffects::argMemOnly(MR);
ME |= MemoryEffects(IRMemLocation::ErrnoMem, MR);
ME |= MemoryEffects(IRMemLocation::Other, MR);
- // Should also set the other Target Memory Locations as MR.
- // To compares with MemoryEffects::unknown() in addMemoryAttrs
- ME |= MemoryEffects(IRMemLocation::TargetMem0, MR);
- ME |= MemoryEffects(IRMemLocation::TargetMem1, MR);;
}
static void addArgLocs(MemoryEffects &ME, const CallBase *Call,
@@ -289,8 +285,15 @@ static void addMemoryAttrs(const SCCNodeSet &SCCNodes, AARGetterT &&AARGetter,
checkFunctionMemoryAccess(*F, F->hasExactDefinition(), AAR, SCCNodes);
ME |= FnME;
RecursiveArgME |= FnRecursiveArgME;
+ // If no Target Memory location is specified, default to ModRef.
+ // This preserves the same behavior as before Target Memory was introduced,
+ // since Target Memory is never set at this point.
+ MemoryEffects METarget = ME;
+ if (ME.getModRef(IRMemLocation::TargetMem0) == ModRefInfo::NoModRef and
+ ME.getModRef(IRMemLocation::TargetMem1) == ModRefInfo::NoModRef)
+ METarget |= ME.setTargetMemLocationModRef(ModRefInfo::ModRef);
// Reached bottom of the lattice, we will not be able to improve the result.
- if (ME == MemoryEffects::unknown())
+ if (ME == MemoryEffects::unknown() or METarget == MemoryEffects::unknown())
return;
}
diff --git a/llvm/test/TableGen/intrinsic-attrs-fp8.td b/llvm/test/TableGen/intrinsic-attrs-fp8.td
index ff9193c4983be..4a00ed2c71ed6 100644
--- a/llvm/test/TableGen/intrinsic-attrs-fp8.td
+++ b/llvm/test/TableGen/intrinsic-attrs-fp8.td
@@ -47,8 +47,7 @@ def int_aarch64_get_fpmr_set_za : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [In
// CHECK-NEXT: // ArgMem: NoModRef, InaccessibleMem: NoModRef, ErrnoMem: NoModRef, Other: NoModRef, TargetMem0: Mod, TargetMem1: NoModRef
// CHECK-NEXT: Attribute::getWithMemoryEffects(C, MemoryEffects::createFromIntValue(512)),
-// CHECK: static constexpr uint16_t IntrinsicsToAttributesMap[] = {
-// CHECK-NEXT: 0 << 1 | 0, // llvm.aarch64.get.fpmr.set.za
+// CHECK: 0 << 1 | 0, // llvm.aarch64.get.fpmr.set.za
// CHECK-NEXT: 1 << 1 | 0, // llvm.aarch64.get.za.2
// CHECK-NEXT: 2 << 1 | 0, // llvm.aarch64.set.fpmr.2
// CHECK-NEXT:};
diff --git a/llvm/test/Transforms/FunctionAttrs/initializes.ll b/llvm/test/Transforms/FunctionAttrs/initializes.ll
index 193d0fd589884..2434bc70d30f4 100644
--- a/llvm/test/Transforms/FunctionAttrs/initializes.ll
+++ b/llvm/test/Transforms/FunctionAttrs/initializes.ll
@@ -663,3 +663,90 @@ define void @memset_large_offset_nonzero_size(ptr %dst) {
call void @llvm.memset.p0.i64(ptr %offset, i8 0, i64 3, i1 false)
ret void
}
+
+
+; Check Target Memory Location keeps the attributes correct with volatile
+
+define void @mem_target_f1(ptr %p){
+; CHECK-LABEL: define void @mem_target_f1(
+; CHECK-SAME: ptr readnone captures(address) [[P:%.*]]) {
+; CHECK-NEXT: call void @target0_no_read_write(ptr [[P]])
+; CHECK-NEXT: store volatile i32 0, ptr undef, align 4
+; CHECK-NEXT: ret void
+;
+ call void @target0_no_read_write(ptr %p)
+ store volatile i32 0, ptr undef, align 4
+ ret void
+}
+
+define void @mem_target_f2(ptr %p){
+; CHECK-LABEL: define void @mem_target_f2(
+; CHECK-SAME: ptr [[P:%.*]]) {
+; CHECK-NEXT: call void @targets_read_write(ptr [[P]])
+; CHECK-NEXT: store volatile i32 0, ptr undef, align 4
+; CHECK-NEXT: ret void
+;
+ call void @targets_read_write(ptr %p)
+ store volatile i32 0, ptr undef, align 4
+ ret void
+}
+
+define void @mem_target_f3(ptr %p){
+; CHECK: Function Attrs: memory(readwrite)
+; CHECK-LABEL: define void @mem_target_f3(
+; CHECK-SAME: ptr [[P:%.*]]) #[[ATTR7:[0-9]+]] {
+; CHECK-NEXT: call void @target_read_or_write(ptr [[P]])
+; CHECK-NEXT: store volatile i32 0, ptr undef, align 4
+; CHECK-NEXT: ret void
+;
+ call void @target_read_or_write(ptr %p)
+ store volatile i32 0, ptr undef, align 4
+ ret void
+}
+
+
+; Without volatile
+
+; Check Target Memory Location keeps the attributes correct with volatile
+define void @mem_target_f4(ptr %p){
+; CHECK: Function Attrs: memory(write, inaccessiblemem: none)
+; CHECK-LABEL: define void @mem_target_f4(
+; CHECK-SAME: ptr readnone captures(address) [[P:%.*]]) #[[ATTR8:[0-9]+]] {
+; CHECK-NEXT: call void @target0_no_read_write(ptr [[P]])
+; CHECK-NEXT: store i32 0, ptr undef, align 4
+; CHECK-NEXT: ret void
+;
+ call void @target0_no_read_write(ptr %p)
+ store i32 0, ptr undef, align 4
+ ret void
+}
+
+define void @mem_target_f5(ptr %p){
+; CHECK: Function Attrs: memory(write, inaccessiblemem: none, target_mem0: readwrite, target_mem1: readwrite)
+; CHECK-LABEL: define void @mem_target_f5(
+; CHECK-SAME: ptr [[P:%.*]]) #[[ATTR9:[0-9]+]] {
+; CHECK-NEXT: call void @targets_read_write(ptr [[P]])
+; CHECK-NEXT: store i32 0, ptr undef, align 4
+; CHECK-NEXT: ret void
+;
+ call void @targets_read_write(ptr %p)
+ store i32 0, ptr undef, align 4
+ ret void
+}
+
+define void @mem_target_f6(ptr %p){
+; CHECK: Function Attrs: memory(write, inaccessiblemem: none, target_mem1: readwrite)
+; CHECK-LABEL: define void @mem_target_f6(
+; CHECK-SAME: ptr [[P:%.*]]) #[[ATTR10:[0-9]+]] {
+; CHECK-NEXT: call void @target_read_or_write(ptr [[P]])
+; CHECK-NEXT: store i32 0, ptr undef, align 4
+; CHECK-NEXT: ret void
+;
+ call void @target_read_or_write(ptr %p)
+ store i32 0, ptr undef, align 4
+ ret void
+}
+
+declare void @target0_no_read_write(ptr) memory(target_mem0: none, target_mem1: none);
+declare void @targets_read_write(ptr %p)memory(target_mem0: readwrite, target_mem1: readwrite);
+declare void @target_read_or_write(ptr) memory(target_mem0: none, target_mem1: readwrite);
>From 231bc7c9d9e99aa8a1862edb472a6b4cf6022c5f Mon Sep 17 00:00:00 2001
From: CarolineConcatto <caroline.concatto at arm.com>
Date: Mon, 6 Oct 2025 12:23:27 +0000
Subject: [PATCH 15/19] Address review comments
---
llvm/include/llvm/IR/Intrinsics.td | 2 +-
llvm/include/llvm/Support/ModRef.h | 3 +-
llvm/lib/IR/AsmWriter.cpp | 2 +-
llvm/lib/IR/Attributes.cpp | 7 +++--
...s-fp8.td => target-mem-intrinsic-attrs.td} | 17 ++++-------
.../TableGen/Basic/CodeGenIntrinsics.cpp | 29 +++++++++++--------
llvm/utils/TableGen/Basic/CodeGenIntrinsics.h | 4 +--
7 files changed, 33 insertions(+), 31 deletions(-)
rename llvm/test/TableGen/{intrinsic-attrs-fp8.td => target-mem-intrinsic-attrs.td} (76%)
diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td
index 7c98cb3232e17..982394bd56339 100644
--- a/llvm/include/llvm/IR/Intrinsics.td
+++ b/llvm/include/llvm/IR/Intrinsics.td
@@ -52,7 +52,7 @@ def IntrInaccessibleMemOnly : IntrinsicProperty;
class IntrinsicMemoryLocation;
-// This should be added in the Target, but once in IntrinsicsAArch64.td
+// These are used to represent Generic Memory Location.
def TargetMem0 : IntrinsicMemoryLocation;
def TargetMem1 : IntrinsicMemoryLocation;
// IntrInaccessible{Read|Write}MemOnly needs to set Location
diff --git a/llvm/include/llvm/Support/ModRef.h b/llvm/include/llvm/Support/ModRef.h
index ef2733c2ff1e2..46de1c55cfd84 100644
--- a/llvm/include/llvm/Support/ModRef.h
+++ b/llvm/include/llvm/Support/ModRef.h
@@ -73,8 +73,9 @@ enum class IRMemLocation {
/// Helpers to iterate all locations in the MemoryEffectsBase class.
First = ArgMem,
- Last = TargetMem1,
FirstTarget = TargetMem0,
+ // TargetMem IDs must be at the end of the list.
+ Last = TargetMem1,
};
template <typename LocationEnum> class MemoryEffectsBase {
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index 58c2ff500c859..488b078ab6caf 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -4970,7 +4970,7 @@ void AssemblyWriter::writeAllAttributeGroups() {
for (const auto &I : asVec)
Out << "attributes #" << I.second << " = { "
- << I.first.getAsString(true) << " }\n";
+ << I.first.getAsString(true) << " }\n";
}
void AssemblyWriter::printUseListOrder(const Value *V,
diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp
index 55871c7ad5bef..5fe9036d4aeba 100644
--- a/llvm/lib/IR/Attributes.cpp
+++ b/llvm/lib/IR/Attributes.cpp
@@ -640,7 +640,10 @@ std::string Attribute::getAsString(bool InAttrGrp) const {
if (MR == OtherMR)
continue;
- // Dont want to print Target Location if NoModRef
+ // Dont Print Target Location if MR and target_mems ModRefInfo
+ // are NoModRef.
+ // Printing Inacessiblemem: none implies that target_mems are also
+ // not affected.
if (ME.isTargetMemLoc(Loc) && (MR == ModRefInfo::NoModRef))
continue;
@@ -660,7 +663,6 @@ std::string Attribute::getAsString(bool InAttrGrp) const {
break;
case IRMemLocation::Other:
llvm_unreachable("This is represented as the default access kind");
- break;
case IRMemLocation::TargetMem0:
OS << "target_mem0: ";
break;
@@ -668,7 +670,6 @@ std::string Attribute::getAsString(bool InAttrGrp) const {
OS << "target_mem1: ";
break;
}
-
OS << getModRefStr(MR);
}
OS << ")";
diff --git a/llvm/test/TableGen/intrinsic-attrs-fp8.td b/llvm/test/TableGen/target-mem-intrinsic-attrs.td
similarity index 76%
rename from llvm/test/TableGen/intrinsic-attrs-fp8.td
rename to llvm/test/TableGen/target-mem-intrinsic-attrs.td
index 4a00ed2c71ed6..61fbddd3c88ae 100644
--- a/llvm/test/TableGen/intrinsic-attrs-fp8.td
+++ b/llvm/test/TableGen/target-mem-intrinsic-attrs.td
@@ -2,17 +2,17 @@
include "llvm/IR/Intrinsics.td"
-def int_aarch64_set_fpmr_2 : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [IntrInaccessibleWriteMemOnly<TargetMem0>]>;
+def int_aarch64_set_target_mem0 : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [IntrInaccessibleWriteMemOnly<TargetMem0>]>;
-def int_aarch64_get_za_2 : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [IntrInaccessibleReadMemOnly<TargetMem1>]>;
+def int_aarch64_get_target_mem1 : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [IntrInaccessibleReadMemOnly<TargetMem1>]>;
-def int_aarch64_get_fpmr_set_za : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [IntrInaccessibleReadMemOnly<TargetMem0>, IntrInaccessibleWriteMemOnly<TargetMem1>]>;
+def int_aarch64_get_target_mem0_set_target_mem1 : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [IntrInaccessibleReadMemOnly<TargetMem0>, IntrInaccessibleWriteMemOnly<TargetMem1>]>;
// 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-NEXT: 15, // llvm.aarch64.get.target.mem0.set.target.mem1
+// CHECK-NEXT: 60, // llvm.aarch64.get.target.mem1
+// CHECK-NEXT: 89, // llvm.aarch64.set.target.mem0
// CHECK: static AttributeSet getIntrinsicFnAttributeSet(LLVMContext &C, unsigned ID) {
// CHECK-NEXT: switch (ID) {
@@ -46,8 +46,3 @@ def int_aarch64_get_fpmr_set_za : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [In
// CHECK-NEXT: Attribute::get(C, Attribute::WillReturn),
// CHECK-NEXT: // ArgMem: NoModRef, InaccessibleMem: NoModRef, ErrnoMem: NoModRef, Other: NoModRef, TargetMem0: Mod, TargetMem1: NoModRef
// CHECK-NEXT: Attribute::getWithMemoryEffects(C, MemoryEffects::createFromIntValue(512)),
-
-// CHECK: 0 << 1 | 0, // llvm.aarch64.get.fpmr.set.za
-// CHECK-NEXT: 1 << 1 | 0, // llvm.aarch64.get.za.2
-// CHECK-NEXT: 2 << 1 | 0, // llvm.aarch64.set.fpmr.2
-// CHECK-NEXT:};
diff --git a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
index 719bb82242c4c..d8befb637cb0e 100644
--- a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
+++ b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
@@ -13,6 +13,7 @@
#include "CodeGenIntrinsics.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/TableGen/Error.h"
@@ -378,13 +379,13 @@ void CodeGenIntrinsic::setProperty(const Record *R) {
else if (R->getName() == "IntrInaccessibleMemOnly")
ME &= MemoryEffects::inaccessibleMemOnly();
else if (R->isSubClassOf("IntrInaccessibleReadMemOnly")) {
- llvm::IRMemLocation Loc = getLocationTypeAsInt(R, "Loc");
+ llvm::IRMemLocation Loc = getValueAsIRMemLocation(R, "Loc");
if (ME.onlyAccessTargetMemoryLocation())
ME = ME.getWithModRef(Loc, ModRefInfo::Ref);
else
ME &= MemoryEffects::inaccessibleReadMemOnly(Loc);
} else if (R->isSubClassOf("IntrInaccessibleWriteMemOnly")) {
- llvm::IRMemLocation Loc = getLocationTypeAsInt(R, "Loc");
+ llvm::IRMemLocation Loc = getValueAsIRMemLocation(R, "Loc");
if (ME.onlyAccessTargetMemoryLocation())
ME = ME.getWithModRef(Loc, ModRefInfo::Mod);
else
@@ -465,18 +466,22 @@ void CodeGenIntrinsic::setProperty(const Record *R) {
}
llvm::IRMemLocation
-CodeGenIntrinsic::getLocationTypeAsInt(const Record *R,
- StringRef FieldName) const {
+CodeGenIntrinsic::getValueAsIRMemLocation(const Record *R,
+ StringRef FieldName) const {
const Record *LocRec = R->getValueAsDef(FieldName);
StringRef Name = LocRec->getName();
- if (Name == "TargetMem0")
- return IRMemLocation::TargetMem0;
- else if (Name == "TargetMem1")
- return IRMemLocation::TargetMem1;
- else if (Name == "InaccessibleMem")
- return llvm::IRMemLocation::InaccessibleMem;
- else
- PrintFatalError(R->getLoc(), "unknown IRMemLocation: " + Name);
+
+ IRMemLocation Loc =
+ StringSwitch<IRMemLocation>(Name)
+ .Case("TargetMem0", IRMemLocation::TargetMem0)
+ .Case("TargetMem1", IRMemLocation::TargetMem1)
+ .Case("InaccessibleMem", IRMemLocation::InaccessibleMem)
+ .Default(IRMemLocation::Other); // fallback enum
+
+ if (Loc == IRMemLocation::Other)
+ PrintFatalError(R->getLoc(), "unknown Target IRMemLocation: " + Name);
+
+ return Loc;
}
bool CodeGenIntrinsic::isParamAPointer(unsigned ParamIdx) const {
diff --git a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.h b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.h
index e4c2347704cb9..b72f4dc6b40a8 100644
--- a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.h
+++ b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.h
@@ -167,8 +167,8 @@ struct CodeGenIntrinsic {
bool isParamImmArg(unsigned ParamIdx) const;
- llvm::IRMemLocation getLocationTypeAsInt(const Record *R,
- StringRef FieldName) const;
+ llvm::IRMemLocation getValueAsIRMemLocation(const Record *R,
+ StringRef FieldName) const;
CodeGenIntrinsic(const Record *R, const CodeGenIntrinsicContext &Ctx);
};
>From 85a89f2d315fd41adb10df003838bfa49f528386 Mon Sep 17 00:00:00 2001
From: CarolineConcatto <caroline.concatto at arm.com>
Date: Fri, 10 Oct 2025 17:16:29 +0000
Subject: [PATCH 16/19] Address comments about tablegen
---
llvm/include/llvm/IR/Intrinsics.td | 10 ++++-
.../TableGen/target-mem-intrinsic-attrs.td | 45 +++++++++++++++----
.../TableGen/Basic/CodeGenIntrinsics.cpp | 37 ++++++++-------
llvm/utils/TableGen/Basic/CodeGenIntrinsics.h | 3 +-
.../utils/TableGen/Basic/IntrinsicEmitter.cpp | 4 +-
5 files changed, 67 insertions(+), 32 deletions(-)
diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td
index 982394bd56339..41a9d6a4a6cda 100644
--- a/llvm/include/llvm/IR/Intrinsics.td
+++ b/llvm/include/llvm/IR/Intrinsics.td
@@ -56,8 +56,14 @@ class IntrinsicMemoryLocation;
def TargetMem0 : IntrinsicMemoryLocation;
def TargetMem1 : 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;}
+class IntrRead<list<IntrinsicMemoryLocation> idx> : IntrinsicProperty {
+ list<IntrinsicMemoryLocation> Loc=idx;
+}
+
+class IntrWrite<list<IntrinsicMemoryLocation> idx> : IntrinsicProperty {
+ list<IntrinsicMemoryLocation> Loc=idx;
+}
+
// IntrInaccessibleMemOrArgMemOnly -- This intrinsic only accesses memory that
// its pointer-typed arguments point to or memory that is not accessible
diff --git a/llvm/test/TableGen/target-mem-intrinsic-attrs.td b/llvm/test/TableGen/target-mem-intrinsic-attrs.td
index 61fbddd3c88ae..44accd7af63c4 100644
--- a/llvm/test/TableGen/target-mem-intrinsic-attrs.td
+++ b/llvm/test/TableGen/target-mem-intrinsic-attrs.td
@@ -2,32 +2,49 @@
include "llvm/IR/Intrinsics.td"
-def int_aarch64_set_target_mem0 : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [IntrInaccessibleWriteMemOnly<TargetMem0>]>;
+def int_aarch64_set_target_mem0 : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [IntrWriteMem, IntrWrite<[TargetMem0]>]>;
-def int_aarch64_get_target_mem1 : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [IntrInaccessibleReadMemOnly<TargetMem1>]>;
+def int_aarch64_get_target_mem1 : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [IntrReadMem, IntrRead<[TargetMem1]>]>;
-def int_aarch64_get_target_mem0_set_target_mem1 : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [IntrInaccessibleReadMemOnly<TargetMem0>, IntrInaccessibleWriteMemOnly<TargetMem1>]>;
+def int_aarch64_get_target_mem0_set_target_mem1 : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [IntrRead<[TargetMem0]>, IntrWrite<[TargetMem1]>]>;
+
+def int_aarch64_get_target_mem1_set_target_mem1 : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [IntrRead<[TargetMem1]>, IntrWrite<[TargetMem1]>]>;
+
+def int_aarch64_get_target_mem0_mem1 : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [IntrReadMem, IntrRead<[TargetMem0, TargetMem1]>]>;
// CHECK: static constexpr unsigned IntrinsicNameOffsetTable[] = {
// CHECK-NEXT: 1, // not_intrinsic
-// CHECK-NEXT: 15, // llvm.aarch64.get.target.mem0.set.target.mem1
-// CHECK-NEXT: 60, // llvm.aarch64.get.target.mem1
-// CHECK-NEXT: 89, // llvm.aarch64.set.target.mem0
+// CHECK-NEXT: 15, // llvm.aarch64.get.target.mem0.mem1
+// CHECK-NEXT: 49, // llvm.aarch64.get.target.mem0.set.target.mem1
+// CHECK-NEXT: 94, // llvm.aarch64.get.target.mem1
+// CHECK-NEXT: 123, // llvm.aarch64.get.target.mem1.set.target.mem1
+// CHECK-NEXT: 168, // llvm.aarch64.set.target.mem0
+
// 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: case 0: // llvm.aarch64.get.target.mem0.mem1
// 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, Other: NoModRef, TargetMem0: Ref, TargetMem1: Ref
+// CHECK-NEXT: Attribute::getWithMemoryEffects(C, MemoryEffects::createFromIntValue(1280)),
+// CHECK-NEXT: });
+// CHECK-NEXT: case 1: // llvm.aarch64.get.target.mem0.set.target.mem1
+// 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, Other: NoModRef, TargetMem0: Ref, TargetMem1: Mod
// CHECK-NEXT: Attribute::getWithMemoryEffects(C, MemoryEffects::createFromIntValue(2304)),
// CHECK-NEXT: });
-// CHECK-NEXT: case 1:
+// CHECK-NEXT: case 2: // llvm.aarch64.get.target.mem1
// CHECK-NEXT: return AttributeSet::get(C, {
// CHECK-NEXT: Attribute::get(C, Attribute::NoUnwind),
// CHECK-NEXT: Attribute::get(C, Attribute::NoCallback),
@@ -37,7 +54,17 @@ def int_aarch64_get_target_mem0_set_target_mem1 : DefaultAttrsIntrinsic<[], [l
// CHECK-NEXT: // ArgMem: NoModRef, InaccessibleMem: NoModRef, ErrnoMem: NoModRef, Other: NoModRef, TargetMem0: NoModRef, TargetMem1: Ref
// CHECK-NEXT: Attribute::getWithMemoryEffects(C, MemoryEffects::createFromIntValue(1024)),
// CHECK-NEXT: });
-// CHECK-NEXT: case 2:
+// CHECK-NEXT: case 3: // llvm.aarch64.get.target.mem1.set.target.mem1
+// 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, Other: NoModRef, TargetMem0: NoModRef, TargetMem1: ModRef
+// CHECK-NEXT: Attribute::getWithMemoryEffects(C, MemoryEffects::createFromIntValue(3072)),
+// CHECK-NEXT: });
+// CHECK-NEXT: case 4: // llvm.aarch64.set.target.mem0
// CHECK-NEXT: return AttributeSet::get(C, {
// CHECK-NEXT: Attribute::get(C, Attribute::NoUnwind),
// CHECK-NEXT: Attribute::get(C, Attribute::NoCallback),
diff --git a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
index d8befb637cb0e..a639f96c9c694 100644
--- a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
+++ b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
@@ -378,18 +378,20 @@ void CodeGenIntrinsic::setProperty(const Record *R) {
ME &= MemoryEffects::argMemOnly();
else if (R->getName() == "IntrInaccessibleMemOnly")
ME &= MemoryEffects::inaccessibleMemOnly();
- else if (R->isSubClassOf("IntrInaccessibleReadMemOnly")) {
- llvm::IRMemLocation Loc = getValueAsIRMemLocation(R, "Loc");
- if (ME.onlyAccessTargetMemoryLocation())
- ME = ME.getWithModRef(Loc, ModRefInfo::Ref);
- else
- ME &= MemoryEffects::inaccessibleReadMemOnly(Loc);
- } else if (R->isSubClassOf("IntrInaccessibleWriteMemOnly")) {
- llvm::IRMemLocation Loc = getValueAsIRMemLocation(R, "Loc");
- if (ME.onlyAccessTargetMemoryLocation())
- ME = ME.getWithModRef(Loc, ModRefInfo::Mod);
- else
- ME &= MemoryEffects::inaccessibleWriteMemOnly(Loc);
+ else if (R->isSubClassOf("IntrRead")) {
+ MemoryEffects ReadMask = MemoryEffects::writeOnly();
+ for (const Record *RLoc : R->getValueAsListOfDefs("Loc"))
+ ReadMask = ReadMask.getWithModRef(getValueAsIRMemLocation(RLoc),
+ ModRefInfo::ModRef);
+ ME &= ReadMask;
+
+ } else if (R->isSubClassOf("IntrWrite")) {
+ MemoryEffects WriteMask = MemoryEffects::readOnly();
+ for (const Record *RLoc : R->getValueAsListOfDefs("Loc"))
+ WriteMask = WriteMask.getWithModRef(getValueAsIRMemLocation(RLoc),
+ ModRefInfo::ModRef);
+ ME &= WriteMask;
+
} else if (R->getName() == "IntrInaccessibleMemOrArgMemOnly")
ME &= MemoryEffects::inaccessibleOrArgMemOnly();
else if (R->getName() == "Commutative")
@@ -466,11 +468,8 @@ void CodeGenIntrinsic::setProperty(const Record *R) {
}
llvm::IRMemLocation
-CodeGenIntrinsic::getValueAsIRMemLocation(const Record *R,
- StringRef FieldName) const {
- const Record *LocRec = R->getValueAsDef(FieldName);
- StringRef Name = LocRec->getName();
-
+CodeGenIntrinsic::getValueAsIRMemLocation(const Record *R) const {
+ StringRef Name = R->getName();
IRMemLocation Loc =
StringSwitch<IRMemLocation>(Name)
.Case("TargetMem0", IRMemLocation::TargetMem0)
@@ -482,6 +481,10 @@ CodeGenIntrinsic::getValueAsIRMemLocation(const Record *R,
PrintFatalError(R->getLoc(), "unknown Target IRMemLocation: " + Name);
return Loc;
+ if (Loc == IRMemLocation::Other)
+ PrintFatalError(R->getLoc(), "unknown Target IRMemLocation: " + Name);
+
+ return Loc;
}
bool CodeGenIntrinsic::isParamAPointer(unsigned ParamIdx) const {
diff --git a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.h b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.h
index b72f4dc6b40a8..5e566bae7e588 100644
--- a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.h
+++ b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.h
@@ -167,8 +167,7 @@ struct CodeGenIntrinsic {
bool isParamImmArg(unsigned ParamIdx) const;
- llvm::IRMemLocation getValueAsIRMemLocation(const Record *R,
- StringRef FieldName) const;
+ llvm::IRMemLocation getValueAsIRMemLocation(const Record *R) const;
CodeGenIntrinsic(const Record *R, const CodeGenIntrinsicContext &Ctx);
};
diff --git a/llvm/utils/TableGen/Basic/IntrinsicEmitter.cpp b/llvm/utils/TableGen/Basic/IntrinsicEmitter.cpp
index 75dffb18fca5a..51859a37b3339 100644
--- a/llvm/utils/TableGen/Basic/IntrinsicEmitter.cpp
+++ b/llvm/utils/TableGen/Basic/IntrinsicEmitter.cpp
@@ -574,10 +574,10 @@ static AttributeSet getIntrinsicFnAttributeSet(LLVMContext &C, unsigned ID) {
if (!UniqFnAttributes.try_emplace(&Int, ID).second)
continue;
OS << formatv(R"(
- case {}:
+ case {}: // {}
return AttributeSet::get(C, {{
)",
- ID);
+ ID, Int.Name);
auto addAttribute = [&OS](StringRef Attr) {
OS << formatv(" Attribute::get(C, Attribute::{}),\n", Attr);
};
>From c7b65eb07693c497aa0bad66cef276c08e7995d8 Mon Sep 17 00:00:00 2001
From: CarolineConcatto <caroline.concatto at arm.com>
Date: Fri, 17 Oct 2025 08:15:04 +0000
Subject: [PATCH 17/19] Address review comments
---
clang/test/CodeGenOpenCL/convergent.cl | 2 +-
llvm/include/llvm/IR/Intrinsics.td | 13 +--
llvm/include/llvm/Support/ModRef.h | 22 -----
llvm/lib/IR/Attributes.cpp | 9 +-
llvm/lib/Transforms/IPO/FunctionAttrs.cpp | 10 +--
llvm/test/Assembler/memory-attribute.ll | 35 +++++---
llvm/test/Bitcode/memory-attribute-upgrade.ll | 2 +-
.../TableGen/target-mem-intrinsic-attrs.td | 22 +++--
.../Transforms/FunctionAttrs/initializes.ll | 87 -------------------
.../Transforms/FunctionAttrs/nocapture.ll | 2 +-
.../Transforms/SCCP/ipscp-drop-argmemonly.ll | 4 +-
.../TableGen/Basic/CodeGenIntrinsics.cpp | 12 +--
12 files changed, 59 insertions(+), 161 deletions(-)
diff --git a/clang/test/CodeGenOpenCL/convergent.cl b/clang/test/CodeGenOpenCL/convergent.cl
index 53a35a4f73119..99d9ee74e669b 100644
--- a/clang/test/CodeGenOpenCL/convergent.cl
+++ b/clang/test/CodeGenOpenCL/convergent.cl
@@ -133,7 +133,7 @@ kernel void assume_convergent_asm()
__asm__ volatile("s_barrier");
}
-// CHECK: attributes #0 = { nofree noinline norecurse nounwind "
+// CHECK: attributes #0 = { nofree noinline norecurse nounwind memory(readwrite, target_mem0: none, target_mem1: none) "
// CHECK: attributes #1 = { {{[^}]*}}convergent{{[^}]*}} }
// CHECK: attributes #2 = { {{[^}]*}}convergent{{[^}]*}} }
// CHECK: attributes #3 = { {{[^}]*}}convergent noduplicate{{[^}]*}} }
diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td
index 41a9d6a4a6cda..c3b077aeaf6f5 100644
--- a/llvm/include/llvm/IR/Intrinsics.td
+++ b/llvm/include/llvm/IR/Intrinsics.td
@@ -52,16 +52,19 @@ def IntrInaccessibleMemOnly : IntrinsicProperty;
class IntrinsicMemoryLocation;
-// These are used to represent Generic Memory Location.
+// Tablegen representation of IRMemLocation.
+// TODO: Populate with all IRMemLocation enum values and update
+// getValueAsIRMemLocation accordingly.
+def InaccessibleMem : IntrinsicMemoryLocation;
def TargetMem0 : IntrinsicMemoryLocation;
def TargetMem1 : IntrinsicMemoryLocation;
-// IntrInaccessible{Read|Write}MemOnly needs to set Location
+// The list of IRMemoryLocations that are read from.
class IntrRead<list<IntrinsicMemoryLocation> idx> : IntrinsicProperty {
- list<IntrinsicMemoryLocation> Loc=idx;
+ list<IntrinsicMemoryLocation> MemLoc=idx;
}
-
+// The list of IRMemoryLocations that are write from.
class IntrWrite<list<IntrinsicMemoryLocation> idx> : IntrinsicProperty {
- list<IntrinsicMemoryLocation> Loc=idx;
+ list<IntrinsicMemoryLocation> MemLoc=idx;
}
diff --git a/llvm/include/llvm/Support/ModRef.h b/llvm/include/llvm/Support/ModRef.h
index 46de1c55cfd84..0046a4d7a1bd9 100644
--- a/llvm/include/llvm/Support/ModRef.h
+++ b/llvm/include/llvm/Support/ModRef.h
@@ -158,18 +158,6 @@ template <typename LocationEnum> class MemoryEffectsBase {
return MemoryEffectsBase(Location::Other, 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);
- }
-
/// Checks if only target-specific memory locations are set.
/// Ignores standard locations like ArgMem or InaccessibleMem.
/// Needed because `Data` may be non-zero by default unless explicitly
@@ -182,16 +170,6 @@ template <typename LocationEnum> class MemoryEffectsBase {
return ME.doesNotAccessMemory();
}
- /// Create MemoryEffectsBase that can only access Target Memory Locations
- static MemoryEffectsBase
- setTargetMemLocationModRef(ModRefInfo MR = ModRefInfo::NoModRef) {
- MemoryEffectsBase FRMB = none();
- for (unsigned I = static_cast<int>(LocationEnum::FirstTarget);
- I <= static_cast<int>(LocationEnum::Last); I++)
- FRMB.setModRef(static_cast<Location>(I), MR);
- return FRMB;
- }
-
/// Create MemoryEffectsBase that can only access inaccessible or argument
/// memory.
static MemoryEffectsBase
diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp
index 5fe9036d4aeba..21504784136c5 100644
--- a/llvm/lib/IR/Attributes.cpp
+++ b/llvm/lib/IR/Attributes.cpp
@@ -630,6 +630,7 @@ std::string Attribute::getAsString(bool InAttrGrp) const {
// Print access kind for "other" as the default access kind. This way it
// will apply to any new location kinds that get split out of "other".
ModRefInfo OtherMR = ME.getModRef(IRMemLocation::Other);
+ ModRefInfo InaccessibleMemMR = ME.getModRef(IRMemLocation::InaccessibleMem);
if (OtherMR != ModRefInfo::NoModRef || ME.getModRef() == OtherMR) {
First = false;
OS << getModRefStr(OtherMR);
@@ -640,11 +641,9 @@ std::string Attribute::getAsString(bool InAttrGrp) const {
if (MR == OtherMR)
continue;
- // Dont Print Target Location if MR and target_mems ModRefInfo
- // are NoModRef.
- // Printing Inacessiblemem: none implies that target_mems are also
- // not affected.
- if (ME.isTargetMemLoc(Loc) && (MR == ModRefInfo::NoModRef))
+ // Only prints Target Location if InaccessibleMem and Target_MemX
+ // ModRefInfo is different. Otherwise skpit Target_Mem print
+ if (ME.isTargetMemLoc(Loc) && MR == InaccessibleMemMR)
continue;
if (!First)
diff --git a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
index f8b0096b46332..3a358184c6367 100644
--- a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
+++ b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
@@ -285,15 +285,7 @@ static void addMemoryAttrs(const SCCNodeSet &SCCNodes, AARGetterT &&AARGetter,
checkFunctionMemoryAccess(*F, F->hasExactDefinition(), AAR, SCCNodes);
ME |= FnME;
RecursiveArgME |= FnRecursiveArgME;
- // If no Target Memory location is specified, default to ModRef.
- // This preserves the same behavior as before Target Memory was introduced,
- // since Target Memory is never set at this point.
- MemoryEffects METarget = ME;
- if (ME.getModRef(IRMemLocation::TargetMem0) == ModRefInfo::NoModRef and
- ME.getModRef(IRMemLocation::TargetMem1) == ModRefInfo::NoModRef)
- METarget |= ME.setTargetMemLocationModRef(ModRefInfo::ModRef);
- // Reached bottom of the lattice, we will not be able to improve the result.
- if (ME == MemoryEffects::unknown() or METarget == MemoryEffects::unknown())
+ if (ME == MemoryEffects::unknown())
return;
}
diff --git a/llvm/test/Assembler/memory-attribute.ll b/llvm/test/Assembler/memory-attribute.ll
index 63435722c03af..a4fc433d7dacb 100644
--- a/llvm/test/Assembler/memory-attribute.ll
+++ b/llvm/test/Assembler/memory-attribute.ll
@@ -80,26 +80,41 @@ declare void @fn_argmem_read_inaccessiblemem_write_reordered()
memory(inaccessiblemem: write, argmem: read)
; CHECK: Function Attrs: memory(target_mem0: write)
-; CHECK: @fn_inaccessiblemem_write_mem_target0()
-declare void @fn_inaccessiblemem_write_mem_target0()
+; CHECK: @fn_write_mem_target0()
+declare void @fn_write_mem_target0()
memory(target_mem0: write)
; CHECK: Function Attrs: memory(target_mem0: read)
-; CHECK: @fn_inaccessiblemem_read_mem_target0()
-declare void @fn_inaccessiblemem_read_mem_target0()
+; CHECK: @fn_read_mem_target0()
+declare void @fn_read_mem_target0()
memory(target_mem0: read)
; CHECK: Function Attrs: memory(target_mem1: write)
-; CHECK: @fn_inaccessiblemem_write_target_mem1()
-declare void @fn_inaccessiblemem_write_target_mem1()
+; CHECK: @fn_write_target_mem1()
+declare void @fn_write_target_mem1()
memory(target_mem1: write)
; CHECK: Function Attrs: memory(target_mem1: read)
-; CHECK: @fn_inaccessiblemem_read_target_mem1()
-declare void @fn_inaccessiblemem_read_target_mem1()
+; CHECK: @fn_read_target_mem1()
+declare void @fn_read_target_mem1()
memory(target_mem1: read)
; CHECK: Function Attrs: memory(target_mem0: read, target_mem1: write)
-; CHECK: @fn_inaccessiblemem_read_target_mem0_write_mem_target1()
-declare void @fn_inaccessiblemem_read_target_mem0_write_mem_target1()
+; CHECK: @fn_read_target_mem0_write_mem_target1()
+declare void @fn_read_target_mem0_write_mem_target1()
memory(target_mem0: read, target_mem1: write)
+
+; CHECK: Function Attrs: memory(inaccessiblemem: write)
+; CHECK: @fn_inaccessiblemem_write_new()
+declare void @fn_inaccessiblemem_write_new()
+ memory(inaccessiblemem: write)
+
+; CHECK: Function Attrs: memory(inaccessiblemem: read)
+; CHECK: @fn_inaccessiblemem_target_mem0_1read()
+declare void @fn_inaccessiblemem_target_mem0_1read()
+ memory(inaccessiblemem: read, target_mem0: read, target_mem0: read)
+
+; CHECK: Function Attrs: memory(target_mem0: read)
+; CHECK: @fn_inaccessiblemem_none_target_mem0_read()
+declare void @fn_inaccessiblemem_none_target_mem0_read()
+ memory(inaccessiblemem: none, target_mem0: read)
diff --git a/llvm/test/Bitcode/memory-attribute-upgrade.ll b/llvm/test/Bitcode/memory-attribute-upgrade.ll
index 915b62a88935d..3648697108995 100644
--- a/llvm/test/Bitcode/memory-attribute-upgrade.ll
+++ b/llvm/test/Bitcode/memory-attribute-upgrade.ll
@@ -1,6 +1,6 @@
; RUN: llvm-dis < %S/Inputs/memory-attribute-upgrade.bc | FileCheck %s
-; CHECK: ; Function Attrs: memory(write, argmem: read)
+; CHECK: ; Function Attrs: memory(write, argmem: read, target_mem0: none, target_mem1: none)
; CHECK-NEXT: define void @test_any_write_argmem_read(ptr %p)
; CHECK: ; Function Attrs: memory(read, argmem: readwrite, inaccessiblemem: none)
diff --git a/llvm/test/TableGen/target-mem-intrinsic-attrs.td b/llvm/test/TableGen/target-mem-intrinsic-attrs.td
index 44accd7af63c4..e6c404b9440eb 100644
--- a/llvm/test/TableGen/target-mem-intrinsic-attrs.td
+++ b/llvm/test/TableGen/target-mem-intrinsic-attrs.td
@@ -2,6 +2,8 @@
include "llvm/IR/Intrinsics.td"
+def int_aarch64_set_inaccessible_mem : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [IntrWriteMem, IntrWrite<[InaccessibleMem]>]>;
+
def int_aarch64_set_target_mem0 : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [IntrWriteMem, IntrWrite<[TargetMem0]>]>;
def int_aarch64_get_target_mem1 : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [IntrReadMem, IntrRead<[TargetMem1]>]>;
@@ -12,14 +14,6 @@ def int_aarch64_get_target_mem1_set_target_mem1 : DefaultAttrsIntrinsic<[], [l
def int_aarch64_get_target_mem0_mem1 : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [IntrReadMem, IntrRead<[TargetMem0, TargetMem1]>]>;
-// CHECK: static constexpr unsigned IntrinsicNameOffsetTable[] = {
-// CHECK-NEXT: 1, // not_intrinsic
-// CHECK-NEXT: 15, // llvm.aarch64.get.target.mem0.mem1
-// CHECK-NEXT: 49, // llvm.aarch64.get.target.mem0.set.target.mem1
-// CHECK-NEXT: 94, // llvm.aarch64.get.target.mem1
-// CHECK-NEXT: 123, // llvm.aarch64.get.target.mem1.set.target.mem1
-// CHECK-NEXT: 168, // llvm.aarch64.set.target.mem0
-
// CHECK: static AttributeSet getIntrinsicFnAttributeSet(LLVMContext &C, unsigned ID) {
// CHECK-NEXT: switch (ID) {
@@ -64,7 +58,17 @@ def int_aarch64_get_target_mem0_mem1 : DefaultAttrsIntrinsic<[], [llvm_i64_ty]
// CHECK-NEXT: // ArgMem: NoModRef, InaccessibleMem: NoModRef, ErrnoMem: NoModRef, Other: NoModRef, TargetMem0: NoModRef, TargetMem1: ModRef
// CHECK-NEXT: Attribute::getWithMemoryEffects(C, MemoryEffects::createFromIntValue(3072)),
// CHECK-NEXT: });
-// CHECK-NEXT: case 4: // llvm.aarch64.set.target.mem0
+// CHECK-NEXT: case 4: // llvm.aarch64.set.inaccessible.mem
+// 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: Mod, ErrnoMem: NoModRef, Other: NoModRef, TargetMem0: NoModRef, TargetMem1: NoModRef
+// CHECK-NEXT: Attribute::getWithMemoryEffects(C, MemoryEffects::createFromIntValue(8)),
+// CHECK-NEXT: });
+// CHECK-NEXT: case 5: // llvm.aarch64.set.target.mem0
// CHECK-NEXT: return AttributeSet::get(C, {
// CHECK-NEXT: Attribute::get(C, Attribute::NoUnwind),
// CHECK-NEXT: Attribute::get(C, Attribute::NoCallback),
diff --git a/llvm/test/Transforms/FunctionAttrs/initializes.ll b/llvm/test/Transforms/FunctionAttrs/initializes.ll
index 2434bc70d30f4..193d0fd589884 100644
--- a/llvm/test/Transforms/FunctionAttrs/initializes.ll
+++ b/llvm/test/Transforms/FunctionAttrs/initializes.ll
@@ -663,90 +663,3 @@ define void @memset_large_offset_nonzero_size(ptr %dst) {
call void @llvm.memset.p0.i64(ptr %offset, i8 0, i64 3, i1 false)
ret void
}
-
-
-; Check Target Memory Location keeps the attributes correct with volatile
-
-define void @mem_target_f1(ptr %p){
-; CHECK-LABEL: define void @mem_target_f1(
-; CHECK-SAME: ptr readnone captures(address) [[P:%.*]]) {
-; CHECK-NEXT: call void @target0_no_read_write(ptr [[P]])
-; CHECK-NEXT: store volatile i32 0, ptr undef, align 4
-; CHECK-NEXT: ret void
-;
- call void @target0_no_read_write(ptr %p)
- store volatile i32 0, ptr undef, align 4
- ret void
-}
-
-define void @mem_target_f2(ptr %p){
-; CHECK-LABEL: define void @mem_target_f2(
-; CHECK-SAME: ptr [[P:%.*]]) {
-; CHECK-NEXT: call void @targets_read_write(ptr [[P]])
-; CHECK-NEXT: store volatile i32 0, ptr undef, align 4
-; CHECK-NEXT: ret void
-;
- call void @targets_read_write(ptr %p)
- store volatile i32 0, ptr undef, align 4
- ret void
-}
-
-define void @mem_target_f3(ptr %p){
-; CHECK: Function Attrs: memory(readwrite)
-; CHECK-LABEL: define void @mem_target_f3(
-; CHECK-SAME: ptr [[P:%.*]]) #[[ATTR7:[0-9]+]] {
-; CHECK-NEXT: call void @target_read_or_write(ptr [[P]])
-; CHECK-NEXT: store volatile i32 0, ptr undef, align 4
-; CHECK-NEXT: ret void
-;
- call void @target_read_or_write(ptr %p)
- store volatile i32 0, ptr undef, align 4
- ret void
-}
-
-
-; Without volatile
-
-; Check Target Memory Location keeps the attributes correct with volatile
-define void @mem_target_f4(ptr %p){
-; CHECK: Function Attrs: memory(write, inaccessiblemem: none)
-; CHECK-LABEL: define void @mem_target_f4(
-; CHECK-SAME: ptr readnone captures(address) [[P:%.*]]) #[[ATTR8:[0-9]+]] {
-; CHECK-NEXT: call void @target0_no_read_write(ptr [[P]])
-; CHECK-NEXT: store i32 0, ptr undef, align 4
-; CHECK-NEXT: ret void
-;
- call void @target0_no_read_write(ptr %p)
- store i32 0, ptr undef, align 4
- ret void
-}
-
-define void @mem_target_f5(ptr %p){
-; CHECK: Function Attrs: memory(write, inaccessiblemem: none, target_mem0: readwrite, target_mem1: readwrite)
-; CHECK-LABEL: define void @mem_target_f5(
-; CHECK-SAME: ptr [[P:%.*]]) #[[ATTR9:[0-9]+]] {
-; CHECK-NEXT: call void @targets_read_write(ptr [[P]])
-; CHECK-NEXT: store i32 0, ptr undef, align 4
-; CHECK-NEXT: ret void
-;
- call void @targets_read_write(ptr %p)
- store i32 0, ptr undef, align 4
- ret void
-}
-
-define void @mem_target_f6(ptr %p){
-; CHECK: Function Attrs: memory(write, inaccessiblemem: none, target_mem1: readwrite)
-; CHECK-LABEL: define void @mem_target_f6(
-; CHECK-SAME: ptr [[P:%.*]]) #[[ATTR10:[0-9]+]] {
-; CHECK-NEXT: call void @target_read_or_write(ptr [[P]])
-; CHECK-NEXT: store i32 0, ptr undef, align 4
-; CHECK-NEXT: ret void
-;
- call void @target_read_or_write(ptr %p)
- store i32 0, ptr undef, align 4
- ret void
-}
-
-declare void @target0_no_read_write(ptr) memory(target_mem0: none, target_mem1: none);
-declare void @targets_read_write(ptr %p)memory(target_mem0: readwrite, target_mem1: readwrite);
-declare void @target_read_or_write(ptr) memory(target_mem0: none, target_mem1: readwrite);
diff --git a/llvm/test/Transforms/FunctionAttrs/nocapture.ll b/llvm/test/Transforms/FunctionAttrs/nocapture.ll
index 8113ba65fe422..9b2518e4d12d9 100644
--- a/llvm/test/Transforms/FunctionAttrs/nocapture.ll
+++ b/llvm/test/Transforms/FunctionAttrs/nocapture.ll
@@ -744,7 +744,7 @@ entry:
@g2 = global ptr null
define void @captureLaunder(ptr %p) {
-; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: readwrite)
+; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: readwrite, target_mem0: none, target_mem1: none)
; FNATTRS-LABEL: define void @captureLaunder
; FNATTRS-SAME: (ptr [[P:%.*]]) #[[ATTR16:[0-9]+]] {
; FNATTRS-NEXT: [[B:%.*]] = call ptr @llvm.launder.invariant.group.p0(ptr [[P]])
diff --git a/llvm/test/Transforms/SCCP/ipscp-drop-argmemonly.ll b/llvm/test/Transforms/SCCP/ipscp-drop-argmemonly.ll
index 22726e0cac1f1..b42f3bc7f4479 100644
--- a/llvm/test/Transforms/SCCP/ipscp-drop-argmemonly.ll
+++ b/llvm/test/Transforms/SCCP/ipscp-drop-argmemonly.ll
@@ -62,7 +62,7 @@ define void @caller.2(ptr %ptr) {
; Here the pointer argument %arg will be replaced by a constant. We need to
; drop inaccessiblemem_or_argmemonly.
define internal void @ptrarg.3(ptr %arg, i32 %val) inaccessiblemem_or_argmemonly nounwind {
-; CHECK: Function Attrs: nounwind memory(readwrite)
+; CHECK: Function Attrs: nounwind memory(readwrite, target_mem0: none, target_mem1: none)
; CHECK-LABEL: @ptrarg.3(
; CHECK-NEXT: store i32 10, ptr @g, align 4
; CHECK-NEXT: ret void
@@ -165,7 +165,7 @@ define i32 @caller.6.cs.attributes(i32 %n) {
;.
; CHECK: attributes #[[ATTR0]] = { nounwind memory(readwrite, inaccessiblemem: none) }
; CHECK: attributes #[[ATTR1:[0-9]+]] = { nounwind memory(argmem: readwrite) }
-; CHECK: attributes #[[ATTR2]] = { nounwind memory(readwrite) }
+; CHECK: attributes #[[ATTR2]] = { nounwind memory(readwrite, target_mem0: none, target_mem1: none) }
; CHECK: attributes #[[ATTR3:[0-9]+]] = { nounwind memory(argmem: readwrite, inaccessiblemem: readwrite) }
; CHECK: attributes #[[ATTR4]] = { nounwind }
;.
diff --git a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
index a639f96c9c694..234ee6dd8f5de 100644
--- a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
+++ b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
@@ -380,18 +380,16 @@ void CodeGenIntrinsic::setProperty(const Record *R) {
ME &= MemoryEffects::inaccessibleMemOnly();
else if (R->isSubClassOf("IntrRead")) {
MemoryEffects ReadMask = MemoryEffects::writeOnly();
- for (const Record *RLoc : R->getValueAsListOfDefs("Loc"))
+ for (const Record *RLoc : R->getValueAsListOfDefs("MemLoc"))
ReadMask = ReadMask.getWithModRef(getValueAsIRMemLocation(RLoc),
ModRefInfo::ModRef);
ME &= ReadMask;
-
} else if (R->isSubClassOf("IntrWrite")) {
MemoryEffects WriteMask = MemoryEffects::readOnly();
- for (const Record *RLoc : R->getValueAsListOfDefs("Loc"))
- WriteMask = WriteMask.getWithModRef(getValueAsIRMemLocation(RLoc),
+ for (const Record *WLoc : R->getValueAsListOfDefs("MemLoc"))
+ WriteMask = WriteMask.getWithModRef(getValueAsIRMemLocation(WLoc),
ModRefInfo::ModRef);
ME &= WriteMask;
-
} else if (R->getName() == "IntrInaccessibleMemOrArgMemOnly")
ME &= MemoryEffects::inaccessibleOrArgMemOnly();
else if (R->getName() == "Commutative")
@@ -481,10 +479,6 @@ CodeGenIntrinsic::getValueAsIRMemLocation(const Record *R) const {
PrintFatalError(R->getLoc(), "unknown Target IRMemLocation: " + Name);
return Loc;
- if (Loc == IRMemLocation::Other)
- PrintFatalError(R->getLoc(), "unknown Target IRMemLocation: " + Name);
-
- return Loc;
}
bool CodeGenIntrinsic::isParamAPointer(unsigned ParamIdx) const {
>From 3de8c96b9ca2da317548e993052dc8d6da10820d Mon Sep 17 00:00:00 2001
From: CarolineConcatto <caroline.concatto at arm.com>
Date: Mon, 20 Oct 2025 13:46:16 +0000
Subject: [PATCH 18/19] Remove unwanted changes
---
llvm/include/llvm/Support/ModRef.h | 12 ------------
llvm/lib/Transforms/IPO/FunctionAttrs.cpp | 1 +
2 files changed, 1 insertion(+), 12 deletions(-)
diff --git a/llvm/include/llvm/Support/ModRef.h b/llvm/include/llvm/Support/ModRef.h
index 0046a4d7a1bd9..487af98b1250d 100644
--- a/llvm/include/llvm/Support/ModRef.h
+++ b/llvm/include/llvm/Support/ModRef.h
@@ -158,18 +158,6 @@ template <typename LocationEnum> class MemoryEffectsBase {
return MemoryEffectsBase(Location::Other, MR);
}
- /// Checks if only target-specific memory locations are set.
- /// Ignores standard locations like ArgMem or InaccessibleMem.
- /// Needed because `Data` may be non-zero by default unless explicitly
- /// cleared.
- bool onlyAccessTargetMemoryLocation() {
- MemoryEffectsBase ME = *this;
- for (unsigned I = static_cast<int>(LocationEnum::FirstTarget);
- I <= static_cast<int>(LocationEnum::Last); I++)
- ME = ME.getWithoutLoc(static_cast<IRMemLocation>(I));
- return ME.doesNotAccessMemory();
- }
-
/// Create MemoryEffectsBase that can only access inaccessible or argument
/// memory.
static MemoryEffectsBase
diff --git a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
index 3a358184c6367..50130da01c7ba 100644
--- a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
+++ b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
@@ -285,6 +285,7 @@ static void addMemoryAttrs(const SCCNodeSet &SCCNodes, AARGetterT &&AARGetter,
checkFunctionMemoryAccess(*F, F->hasExactDefinition(), AAR, SCCNodes);
ME |= FnME;
RecursiveArgME |= FnRecursiveArgME;
+ // Reached bottom of the lattice, we will not be able to improve the result.
if (ME == MemoryEffects::unknown())
return;
}
>From 0aed8e425857b82c9d0c6eb44144e52ddfb22c78 Mon Sep 17 00:00:00 2001
From: CarolineConcatto <caroline.concatto at arm.com>
Date: Tue, 21 Oct 2025 13:06:50 +0000
Subject: [PATCH 19/19] Set target_mem when they are not set with
inaccessiblemem
---
.../CodeGen/sanitize-metadata-nosanitize.c | 18 +++++-----
llvm/docs/LangRef.rst | 20 ++++++++++-
llvm/include/llvm/IR/Intrinsics.td | 18 +++++-----
llvm/include/llvm/Support/ModRef.h | 14 +++-----
llvm/lib/IR/Attributes.cpp | 6 ----
llvm/test/Assembler/memory-attribute.ll | 19 ++++++++--
llvm/test/Bitcode/memory-attribute-upgrade.ll | 2 +-
.../TableGen/target-mem-intrinsic-attrs.td | 9 +++--
.../Transforms/FunctionAttrs/argmemonly.ll | 22 ++++++------
.../Transforms/FunctionAttrs/nocapture.ll | 36 +++++++++----------
.../FunctionAttrs/read-write-scc.ll | 4 +--
.../Transforms/FunctionAttrs/readattrs.ll | 2 +-
.../Transforms/FunctionAttrs/writeonly.ll | 4 +--
.../InferFunctionAttrs/norecurse_debug.ll | 2 +-
.../cfi-nounwind-direct-call.ll | 2 +-
.../Transforms/SCCP/ipscp-drop-argmemonly.ll | 6 ++--
.../TableGen/Basic/CodeGenIntrinsics.cpp | 2 +-
mlir/test/Target/LLVMIR/llvmir.mlir | 10 +++---
18 files changed, 109 insertions(+), 87 deletions(-)
diff --git a/clang/test/CodeGen/sanitize-metadata-nosanitize.c b/clang/test/CodeGen/sanitize-metadata-nosanitize.c
index f2672d7f89157..74b5c9b03754f 100644
--- a/clang/test/CodeGen/sanitize-metadata-nosanitize.c
+++ b/clang/test/CodeGen/sanitize-metadata-nosanitize.c
@@ -10,7 +10,7 @@
// CHECK: @llvm.global_ctors = appending global [2 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 2, ptr @__sanitizer_metadata_covered2.module_ctor, ptr @__sanitizer_metadata_covered2.module_ctor }, { i32, ptr, ptr } { i32 2, ptr @__sanitizer_metadata_atomics2.module_ctor, ptr @__sanitizer_metadata_atomics2.module_ctor }]
// CHECK: @llvm.global_dtors = appending global [2 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 2, ptr @__sanitizer_metadata_covered2.module_dtor, ptr @__sanitizer_metadata_covered2.module_dtor }, { i32, ptr, ptr } { i32 2, ptr @__sanitizer_metadata_atomics2.module_dtor, ptr @__sanitizer_metadata_atomics2.module_dtor }]
//.
-// CHECK: Function Attrs: mustprogress nofree noinline norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none)
+// CHECK: Function Attrs: mustprogress nofree noinline norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none, target_mem0: none, target_mem1: none)
// CHECK-LABEL: define dso_local void @escape(
// CHECK-SAME: ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] !pcsections [[META6:![0-9]+]] {
// CHECK-NEXT: [[ENTRY:.*:]]
@@ -21,7 +21,7 @@ __attribute__((noinline, not_tail_called)) void escape(const volatile void *p) {
sink = p;
}
-// CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none)
+// CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none, target_mem0: none, target_mem1: none)
// CHECK-LABEL: define dso_local i32 @normal_function(
// CHECK-SAME: ptr noundef [[X:%.*]], ptr noundef readonly captures(none) [[Y:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] !pcsections [[META8:![0-9]+]] {
// CHECK-NEXT: [[ENTRY:.*:]]
@@ -38,7 +38,7 @@ int normal_function(int *x, int *y) {
return *y;
}
-// CHECK: Function Attrs: disable_sanitizer_instrumentation mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none)
+// CHECK: Function Attrs: disable_sanitizer_instrumentation mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none, target_mem0: none, target_mem1: none)
// CHECK-LABEL: define dso_local i32 @test_disable_sanitize_instrumentation(
// CHECK-SAME: ptr noundef [[X:%.*]], ptr noundef readonly captures(none) [[Y:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
// CHECK-NEXT: [[ENTRY:.*:]]
@@ -55,7 +55,7 @@ __attribute__((disable_sanitizer_instrumentation)) int test_disable_sanitize_ins
return *y;
}
-// CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none)
+// CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none, target_mem0: none, target_mem1: none)
// CHECK-LABEL: define dso_local i32 @test_no_sanitize_thread(
// CHECK-SAME: ptr noundef [[X:%.*]], ptr noundef readonly captures(none) [[Y:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] !pcsections [[META14:![0-9]+]] {
// CHECK-NEXT: [[ENTRY:.*:]]
@@ -72,7 +72,7 @@ __attribute__((no_sanitize("thread"))) int test_no_sanitize_thread(int *x, int *
return *y;
}
-// CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none)
+// CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none, target_mem0: none, target_mem1: none)
// CHECK-LABEL: define dso_local i32 @test_no_sanitize_all(
// CHECK-SAME: ptr noundef [[X:%.*]], ptr noundef readonly captures(none) [[Y:%.*]]) local_unnamed_addr #[[ATTR3]] !pcsections [[META14]] {
// CHECK-NEXT: [[ENTRY:.*:]]
@@ -89,10 +89,10 @@ __attribute__((no_sanitize("all"))) int test_no_sanitize_all(int *x, int *y) {
return *y;
}
//.
-// CHECK: attributes #[[ATTR0]] = { mustprogress nofree noinline norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none) "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" }
-// CHECK: attributes #[[ATTR1]] = { mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none) "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" }
-// CHECK: attributes #[[ATTR2]] = { disable_sanitizer_instrumentation mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none) "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" }
-// CHECK: attributes #[[ATTR3]] = { mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none) "min-legal-vector-width"="0" "no-trapping-math"="true" "no_sanitize_thread" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" }
+// CHECK: attributes #[[ATTR0]] = { mustprogress nofree noinline norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none, target_mem0: none, target_mem1: none) "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" }
+// CHECK: attributes #[[ATTR1]] = { mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none, target_mem0: none, target_mem1: none) "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" }
+// CHECK: attributes #[[ATTR2]] = { disable_sanitizer_instrumentation mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none, target_mem0: none, target_mem1: none) "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" }
+// CHECK: attributes #[[ATTR3]] = { mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none, target_mem0: none, target_mem1: none) "min-legal-vector-width"="0" "no-trapping-math"="true" "no_sanitize_thread" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" }
// CHECK: attributes #[[ATTR4:[0-9]+]] = { nounwind "target-features"="+cx8,+mmx,+sse,+sse2,+x87" }
//.
// CHECK: [[META0:![0-9]+]] = !{i32 1, !"wchar_size", i32 4}
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 1c6823be44dcb..60870ade7bbaa 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -2178,7 +2178,8 @@ For example:
This attribute specifies the possible memory effects of the call-site or
function. It allows specifying the possible access kinds (``none``,
``read``, ``write``, or ``readwrite``) for the possible memory location
- kinds (``argmem``, ``inaccessiblemem``, ``errnomem``, as well as a default).
+ kinds (``argmem``, ``inaccessiblemem``, ``errnomem``, ``target_mem0``,
+ ``target_mem1``, as well as a default).
It is best understood by example:
- ``memory(none)``: Does not access any memory.
@@ -2220,6 +2221,23 @@ For example:
accessing inaccessible memory itself). Inaccessible memory is often used
to model control dependencies of intrinsics.
- ``errnomem``: This refers to accesses to the ``errno`` variable.
+ - ``target_mem0`` and ``target_mem1``: This refers to additional memory
+ locations that are needed by targets to define memory effects on
+ architectural resources that are neither regular argument/global memory
+ nor ``inaccessiblemem``/``errnomem``.
+
+ As with other location kinds, an omitted location inherits the default access
+ (e.g. from ``memory(read)``), and an explicit access like ``target_mem0: none``
+ indicates that location is not affected.
+ **Examples:**
+
+ A call that may read any memory, and additionally writes only the target_mem0 state::
+
+ declare void @foo()
+ ; ...
+ ; Only target_mem0 writes are observable; no writes to regular memory are implied.
+ attributes #0 = { memory(read, target_mem0: write) }
+
- The default access kind (specified without a location prefix) applies to
all locations that haven't been specified explicitly, including those that
don't currently have a dedicated location kind (e.g. accesses to globals
diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td
index c3b077aeaf6f5..3483f9f0d6d19 100644
--- a/llvm/include/llvm/IR/Intrinsics.td
+++ b/llvm/include/llvm/IR/Intrinsics.td
@@ -49,30 +49,30 @@ def IntrArgMemOnly : IntrinsicProperty;
// accessible by the module being compiled. This is a weaker form of IntrNoMem.
def IntrInaccessibleMemOnly : IntrinsicProperty;
+// 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.
+def IntrInaccessibleMemOrArgMemOnly : IntrinsicProperty;
-
-class IntrinsicMemoryLocation;
// Tablegen representation of IRMemLocation.
+class IntrinsicMemoryLocation;
+
// TODO: Populate with all IRMemLocation enum values and update
// getValueAsIRMemLocation accordingly.
def InaccessibleMem : IntrinsicMemoryLocation;
def TargetMem0 : IntrinsicMemoryLocation;
def TargetMem1 : IntrinsicMemoryLocation;
+
// The list of IRMemoryLocations that are read from.
class IntrRead<list<IntrinsicMemoryLocation> idx> : IntrinsicProperty {
list<IntrinsicMemoryLocation> MemLoc=idx;
}
-// The list of IRMemoryLocations that are write from.
+
+// The list of IRMemoryLocations that are write to.
class IntrWrite<list<IntrinsicMemoryLocation> idx> : IntrinsicProperty {
list<IntrinsicMemoryLocation> MemLoc=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.
-def IntrInaccessibleMemOrArgMemOnly : IntrinsicProperty;
-
// Commutative - This intrinsic is commutative: X op Y == Y op X.
def Commutative : IntrinsicProperty;
diff --git a/llvm/include/llvm/Support/ModRef.h b/llvm/include/llvm/Support/ModRef.h
index 487af98b1250d..b964fa5827624 100644
--- a/llvm/include/llvm/Support/ModRef.h
+++ b/llvm/include/llvm/Support/ModRef.h
@@ -66,8 +66,7 @@ enum class IRMemLocation {
ErrnoMem = 2,
/// Any other memory.
Other = 3,
- /// Target Memory Location
- /// Used by a target to represent target specif memory regions
+ /// Represents target specific state.
TargetMem0 = 4,
TargetMem1 = 5,
@@ -184,11 +183,6 @@ template <typename LocationEnum> class MemoryEffectsBase {
return MemoryEffectsBase(Data);
}
- bool isTargetMemLoc(IRMemLocation Loc) {
- return static_cast<unsigned>(Loc) >=
- static_cast<unsigned>(Location::FirstTarget);
- }
-
/// Convert MemoryEffectsBase into an encoded integer value (used by memory
/// attribute).
uint32_t toIntValue() const {
@@ -243,9 +237,9 @@ template <typename LocationEnum> class MemoryEffectsBase {
/// Whether this function only (at most) accesses inaccessible memory.
bool onlyAccessesInaccessibleMem() const {
- return getWithoutLoc(IRMemLocation::TargetMem0)
+ return getWithoutLoc(Location::InaccessibleMem)
+ .getWithoutLoc(IRMemLocation::TargetMem0)
.getWithoutLoc(IRMemLocation::TargetMem1)
- .getWithoutLoc(Location::InaccessibleMem)
.doesNotAccessMemory();
}
@@ -259,6 +253,8 @@ template <typename LocationEnum> class MemoryEffectsBase {
bool onlyAccessesInaccessibleOrArgMem() const {
return getWithoutLoc(Location::InaccessibleMem)
.getWithoutLoc(Location::ArgMem)
+ .getWithoutLoc(Location::TargetMem0)
+ .getWithoutLoc(Location::TargetMem1)
.doesNotAccessMemory();
}
diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp
index 21504784136c5..fe6d3e5edeb09 100644
--- a/llvm/lib/IR/Attributes.cpp
+++ b/llvm/lib/IR/Attributes.cpp
@@ -630,7 +630,6 @@ std::string Attribute::getAsString(bool InAttrGrp) const {
// Print access kind for "other" as the default access kind. This way it
// will apply to any new location kinds that get split out of "other".
ModRefInfo OtherMR = ME.getModRef(IRMemLocation::Other);
- ModRefInfo InaccessibleMemMR = ME.getModRef(IRMemLocation::InaccessibleMem);
if (OtherMR != ModRefInfo::NoModRef || ME.getModRef() == OtherMR) {
First = false;
OS << getModRefStr(OtherMR);
@@ -641,11 +640,6 @@ std::string Attribute::getAsString(bool InAttrGrp) const {
if (MR == OtherMR)
continue;
- // Only prints Target Location if InaccessibleMem and Target_MemX
- // ModRefInfo is different. Otherwise skpit Target_Mem print
- if (ME.isTargetMemLoc(Loc) && MR == InaccessibleMemMR)
- continue;
-
if (!First)
OS << ", ";
First = false;
diff --git a/llvm/test/Assembler/memory-attribute.ll b/llvm/test/Assembler/memory-attribute.ll
index a4fc433d7dacb..4c86f8df0e6c1 100644
--- a/llvm/test/Assembler/memory-attribute.ll
+++ b/llvm/test/Assembler/memory-attribute.ll
@@ -109,12 +109,27 @@ declare void @fn_read_target_mem0_write_mem_target1()
declare void @fn_inaccessiblemem_write_new()
memory(inaccessiblemem: write)
-; CHECK: Function Attrs: memory(inaccessiblemem: read)
+; CHECK: Function Attrs: memory(inaccessiblemem: read, target_mem0: read, target_mem1: read)
; CHECK: @fn_inaccessiblemem_target_mem0_1read()
declare void @fn_inaccessiblemem_target_mem0_1read()
- memory(inaccessiblemem: read, target_mem0: read, target_mem0: read)
+ memory(inaccessiblemem: read, target_mem0: read, target_mem1: read)
; CHECK: Function Attrs: memory(target_mem0: read)
; CHECK: @fn_inaccessiblemem_none_target_mem0_read()
declare void @fn_inaccessiblemem_none_target_mem0_read()
memory(inaccessiblemem: none, target_mem0: read)
+
+; CHECK: Function Attrs: memory(write, inaccessiblemem: read)
+; CHECK: @fn_write_inaccessiblemem_read_target_mem0_write
+declare void @fn_write_inaccessiblemem_read_target_mem0_write()
+ memory(write, inaccessiblemem: read, target_mem0: write)
+
+; CHECK: Function Attrs: memory(write, target_mem0: read)
+; CHECK: @fn_write_inaccessiblemem_write_target_mem0_read()
+declare void @fn_write_inaccessiblemem_write_target_mem0_read()
+ memory(write, inaccessiblemem: write, target_mem0: read)
+
+; CHECK: Function Attrs: memory(write, target_mem0: read)
+; CHECK: @fn_write_target_mem0_readwrite()
+declare void @fn_write_target_mem0_readwrite()
+ memory(write, target_mem0: read)
diff --git a/llvm/test/Bitcode/memory-attribute-upgrade.ll b/llvm/test/Bitcode/memory-attribute-upgrade.ll
index 3648697108995..334a344b96f7f 100644
--- a/llvm/test/Bitcode/memory-attribute-upgrade.ll
+++ b/llvm/test/Bitcode/memory-attribute-upgrade.ll
@@ -3,5 +3,5 @@
; CHECK: ; Function Attrs: memory(write, argmem: read, target_mem0: none, target_mem1: none)
; CHECK-NEXT: define void @test_any_write_argmem_read(ptr %p)
-; CHECK: ; Function Attrs: memory(read, argmem: readwrite, inaccessiblemem: none)
+; CHECK: ; Function Attrs: memory(read, argmem: readwrite, inaccessiblemem: none, target_mem0: none, target_mem1: none)
; CHECK-NEXT: define void @test_any_read_argmem_readwrite(ptr %p)
diff --git a/llvm/test/TableGen/target-mem-intrinsic-attrs.td b/llvm/test/TableGen/target-mem-intrinsic-attrs.td
index e6c404b9440eb..fc9c3321ad9e9 100644
--- a/llvm/test/TableGen/target-mem-intrinsic-attrs.td
+++ b/llvm/test/TableGen/target-mem-intrinsic-attrs.td
@@ -2,18 +2,17 @@
include "llvm/IR/Intrinsics.td"
-def int_aarch64_set_inaccessible_mem : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [IntrWriteMem, IntrWrite<[InaccessibleMem]>]>;
+def int_aarch64_get_target_mem0_mem1 : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [IntrReadMem, IntrRead<[TargetMem0, TargetMem1]>]>;
-def int_aarch64_set_target_mem0 : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [IntrWriteMem, IntrWrite<[TargetMem0]>]>;
+def int_aarch64_get_target_mem0_set_target_mem1 : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [IntrRead<[TargetMem0]>, IntrWrite<[TargetMem1]>]>;
def int_aarch64_get_target_mem1 : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [IntrReadMem, IntrRead<[TargetMem1]>]>;
-def int_aarch64_get_target_mem0_set_target_mem1 : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [IntrRead<[TargetMem0]>, IntrWrite<[TargetMem1]>]>;
-
def int_aarch64_get_target_mem1_set_target_mem1 : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [IntrRead<[TargetMem1]>, IntrWrite<[TargetMem1]>]>;
-def int_aarch64_get_target_mem0_mem1 : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [IntrReadMem, IntrRead<[TargetMem0, TargetMem1]>]>;
+def int_aarch64_set_inaccessible_mem : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [IntrWriteMem, IntrWrite<[InaccessibleMem]>]>;
+def int_aarch64_set_target_mem0 : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [IntrWriteMem, IntrWrite<[TargetMem0]>]>;
// CHECK: static AttributeSet getIntrinsicFnAttributeSet(LLVMContext &C, unsigned ID) {
// CHECK-NEXT: switch (ID) {
diff --git a/llvm/test/Transforms/FunctionAttrs/argmemonly.ll b/llvm/test/Transforms/FunctionAttrs/argmemonly.ll
index 42e0e94c1cee3..4ff36c0dbdc3f 100644
--- a/llvm/test/Transforms/FunctionAttrs/argmemonly.ll
+++ b/llvm/test/Transforms/FunctionAttrs/argmemonly.ll
@@ -56,7 +56,7 @@ entry:
}
define i32 @test_read_global() {
-; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(read, argmem: none, inaccessiblemem: none)
+; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(read, argmem: none, inaccessiblemem: none, target_mem0: none, target_mem1: none)
; FNATTRS-LABEL: define i32 @test_read_global
; FNATTRS-SAME: () #[[ATTR2:[0-9]+]] {
; FNATTRS-NEXT: entry:
@@ -76,7 +76,7 @@ entry:
}
define i32 @test_read_loaded_ptr(ptr %ptr) {
-; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(read, inaccessiblemem: none)
+; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(read, inaccessiblemem: none, target_mem0: none, target_mem1: none)
; FNATTRS-LABEL: define i32 @test_read_loaded_ptr
; FNATTRS-SAME: (ptr readonly captures(none) [[PTR:%.*]]) #[[ATTR3:[0-9]+]] {
; FNATTRS-NEXT: entry:
@@ -119,7 +119,7 @@ entry:
}
define void @test_write_global() {
-; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none)
+; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none, target_mem0: none, target_mem1: none)
; FNATTRS-LABEL: define void @test_write_global
; FNATTRS-SAME: () #[[ATTR5:[0-9]+]] {
; FNATTRS-NEXT: entry:
@@ -243,7 +243,7 @@ declare void @llvm.memcpy.p0.p0.i64(ptr, ptr, i64, i1)
@arr = global [32 x i8] zeroinitializer
define void @test_memcpy_src_global(ptr %dst) {
-; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(readwrite, inaccessiblemem: none)
+; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(readwrite, inaccessiblemem: none, target_mem0: none, target_mem1: none)
; FNATTRS-LABEL: define void @test_memcpy_src_global
; FNATTRS-SAME: (ptr writeonly captures(none) initializes((0, 32)) [[DST:%.*]]) #[[ATTR11:[0-9]+]] {
; FNATTRS-NEXT: entry:
@@ -263,7 +263,7 @@ entry:
}
define void @test_memcpy_dst_global(ptr %src) {
-; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(readwrite, inaccessiblemem: none)
+; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(readwrite, inaccessiblemem: none, target_mem0: none, target_mem1: none)
; FNATTRS-LABEL: define void @test_memcpy_dst_global
; FNATTRS-SAME: (ptr readonly captures(none) [[SRC:%.*]]) #[[ATTR11]] {
; FNATTRS-NEXT: entry:
@@ -388,7 +388,7 @@ define void @test_inaccessibleorargmemonly_readwrite(ptr %arg) {
}
define void @test_recursive_argmem_read(ptr %p) {
-; FNATTRS: Function Attrs: nofree nosync nounwind memory(read, inaccessiblemem: none)
+; FNATTRS: Function Attrs: nofree nosync nounwind memory(read, inaccessiblemem: none, target_mem0: none, target_mem1: none)
; FNATTRS-LABEL: define void @test_recursive_argmem_read
; FNATTRS-SAME: (ptr readonly captures(none) [[P:%.*]]) #[[ATTR16:[0-9]+]] {
; FNATTRS-NEXT: [[PVAL:%.*]] = load ptr, ptr [[P]], align 8
@@ -408,7 +408,7 @@ define void @test_recursive_argmem_read(ptr %p) {
}
define void @test_recursive_argmem_readwrite(ptr %p) {
-; FNATTRS: Function Attrs: nofree nosync nounwind memory(readwrite, inaccessiblemem: none)
+; FNATTRS: Function Attrs: nofree nosync nounwind memory(readwrite, inaccessiblemem: none, target_mem0: none, target_mem1: none)
; FNATTRS-LABEL: define void @test_recursive_argmem_readwrite
; FNATTRS-SAME: (ptr captures(none) [[P:%.*]]) #[[ATTR17:[0-9]+]] {
; FNATTRS-NEXT: [[PVAL:%.*]] = load ptr, ptr [[P]], align 8
@@ -454,7 +454,7 @@ define void @test_recursive_argmem_read_alloca(ptr %p) {
}
define void @test_scc_argmem_read_1(ptr %p) {
-; FNATTRS: Function Attrs: nofree nosync nounwind memory(read, inaccessiblemem: none)
+; FNATTRS: Function Attrs: nofree nosync nounwind memory(read, inaccessiblemem: none, target_mem0: none, target_mem1: none)
; FNATTRS-LABEL: define void @test_scc_argmem_read_1
; FNATTRS-SAME: (ptr readonly captures(none) [[P:%.*]]) #[[ATTR16]] {
; FNATTRS-NEXT: [[PVAL:%.*]] = load ptr, ptr [[P]], align 8
@@ -474,7 +474,7 @@ define void @test_scc_argmem_read_1(ptr %p) {
}
define void @test_scc_argmem_read_2(ptr %p) {
-; FNATTRS: Function Attrs: nofree nosync nounwind memory(read, inaccessiblemem: none)
+; FNATTRS: Function Attrs: nofree nosync nounwind memory(read, inaccessiblemem: none, target_mem0: none, target_mem1: none)
; FNATTRS-LABEL: define void @test_scc_argmem_read_2
; FNATTRS-SAME: (ptr readonly captures(none) [[P:%.*]]) #[[ATTR16]] {
; FNATTRS-NEXT: call void @test_scc_argmem_read_1(ptr [[P]])
@@ -518,7 +518,7 @@ entry:
; FIXME: This could be `memory(argmem: read)`.
define i64 @select_different_obj(i1 %c, ptr %p, ptr %p2) {
-; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(read, inaccessiblemem: none)
+; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(read, inaccessiblemem: none, target_mem0: none, target_mem1: none)
; FNATTRS-LABEL: define i64 @select_different_obj
; FNATTRS-SAME: (i1 [[C:%.*]], ptr readonly captures(none) [[P:%.*]], ptr readonly captures(none) [[P2:%.*]]) #[[ATTR3]] {
; FNATTRS-NEXT: entry:
@@ -580,7 +580,7 @@ join:
; FIXME: This could be `memory(argmem: read)`.
define i64 @phi_different_obj(i1 %c, ptr %p, ptr %p2) {
-; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(read, inaccessiblemem: none)
+; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(read, inaccessiblemem: none, target_mem0: none, target_mem1: none)
; FNATTRS-LABEL: define i64 @phi_different_obj
; FNATTRS-SAME: (i1 [[C:%.*]], ptr readonly captures(none) [[P:%.*]], ptr readonly captures(none) [[P2:%.*]]) #[[ATTR3]] {
; FNATTRS-NEXT: entry:
diff --git a/llvm/test/Transforms/FunctionAttrs/nocapture.ll b/llvm/test/Transforms/FunctionAttrs/nocapture.ll
index 9b2518e4d12d9..b5b14f571d47d 100644
--- a/llvm/test/Transforms/FunctionAttrs/nocapture.ll
+++ b/llvm/test/Transforms/FunctionAttrs/nocapture.ll
@@ -20,7 +20,7 @@ define ptr @c1(ptr %q) {
; It would also be acceptable to mark %q as readnone. Update @c3 too.
define void @c2(ptr %q) {
-; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none)
+; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none, target_mem0: none, target_mem1: none)
; FNATTRS-LABEL: define void @c2
; FNATTRS-SAME: (ptr [[Q:%.*]]) #[[ATTR1:[0-9]+]] {
; FNATTRS-NEXT: store ptr [[Q]], ptr @g, align 8
@@ -37,7 +37,7 @@ define void @c2(ptr %q) {
}
define void @c3(ptr %q) {
-; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write, inaccessiblemem: none)
+; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write, inaccessiblemem: none, target_mem0: none, target_mem1: none)
; FNATTRS-LABEL: define void @c3
; FNATTRS-SAME: (ptr [[Q:%.*]]) #[[ATTR2:[0-9]+]] {
; FNATTRS-NEXT: call void @c2(ptr [[Q]])
@@ -127,7 +127,7 @@ l1:
@lookup_table = global [2 x i1] [ i1 0, i1 1 ]
define i1 @c5(ptr %q, i32 %bitno) {
-; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(read, argmem: none, inaccessiblemem: none)
+; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(read, argmem: none, inaccessiblemem: none, target_mem0: none, target_mem1: none)
; FNATTRS-LABEL: define i1 @c5
; FNATTRS-SAME: (ptr [[Q:%.*]], i32 [[BITNO:%.*]]) #[[ATTR3:[0-9]+]] {
; FNATTRS-NEXT: [[TMP:%.*]] = ptrtoint ptr [[Q]] to i32
@@ -222,7 +222,7 @@ define ptr @lookup_bit(ptr %q, i32 %bitno) readnone nounwind {
}
define i1 @c7(ptr %q, i32 %bitno) {
-; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(read, inaccessiblemem: none)
+; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(read, inaccessiblemem: none, target_mem0: none, target_mem1: none)
; FNATTRS-LABEL: define i1 @c7
; FNATTRS-SAME: (ptr readonly [[Q:%.*]], i32 [[BITNO:%.*]]) #[[ATTR6:[0-9]+]] {
; FNATTRS-NEXT: [[PTR:%.*]] = call ptr @lookup_bit(ptr [[Q]], i32 [[BITNO]])
@@ -243,7 +243,7 @@ define i1 @c7(ptr %q, i32 %bitno) {
define i32 @nc1(ptr %q, ptr %p, i1 %b) {
-; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(readwrite, inaccessiblemem: none)
+; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(readwrite, inaccessiblemem: none, target_mem0: none, target_mem1: none)
; FNATTRS-LABEL: define i32 @nc1
; FNATTRS-SAME: (ptr [[Q:%.*]], ptr captures(none) [[P:%.*]], i1 [[B:%.*]]) #[[ATTR7:[0-9]+]] {
; FNATTRS-NEXT: e:
@@ -284,7 +284,7 @@ l:
}
define i32 @nc1_addrspace(ptr %q, ptr addrspace(1) %p, i1 %b) {
-; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(readwrite, inaccessiblemem: none)
+; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(readwrite, inaccessiblemem: none, target_mem0: none, target_mem1: none)
; FNATTRS-LABEL: define i32 @nc1_addrspace
; FNATTRS-SAME: (ptr [[Q:%.*]], ptr addrspace(1) captures(none) [[P:%.*]], i1 [[B:%.*]]) #[[ATTR7]] {
; FNATTRS-NEXT: e:
@@ -328,7 +328,7 @@ l:
}
define void @nc2(ptr %p, ptr %q) {
-; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(readwrite, inaccessiblemem: none)
+; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(readwrite, inaccessiblemem: none, target_mem0: none, target_mem1: none)
; FNATTRS-LABEL: define void @nc2
; FNATTRS-SAME: (ptr captures(none) [[P:%.*]], ptr [[Q:%.*]]) #[[ATTR7]] {
; FNATTRS-NEXT: [[TMP1:%.*]] = call i32 @nc1(ptr [[Q]], ptr [[P]], i1 false)
@@ -468,7 +468,7 @@ define void @self_readonly_nounwind_willreturn(ptr %p) readonly nounwind willret
; It would be acceptable to add readnone to %y1_1 and %y1_2.
define void @test1_1(ptr %x1_1, ptr %y1_1, i1 %c) {
-; FNATTRS: Function Attrs: nofree nosync nounwind memory(write, argmem: none, inaccessiblemem: none)
+; FNATTRS: Function Attrs: nofree nosync nounwind memory(write, argmem: none, inaccessiblemem: none, target_mem0: none, target_mem1: none)
; FNATTRS-LABEL: define void @test1_1
; FNATTRS-SAME: (ptr readnone captures(none) [[X1_1:%.*]], ptr [[Y1_1:%.*]], i1 [[C:%.*]]) #[[ATTR12:[0-9]+]] {
; FNATTRS-NEXT: [[TMP1:%.*]] = call ptr @test1_2(ptr [[X1_1]], ptr [[Y1_1]], i1 [[C]])
@@ -488,7 +488,7 @@ define void @test1_1(ptr %x1_1, ptr %y1_1, i1 %c) {
}
define ptr @test1_2(ptr %x1_2, ptr %y1_2, i1 %c) {
-; FNATTRS: Function Attrs: nofree nosync nounwind memory(write, argmem: none, inaccessiblemem: none)
+; FNATTRS: Function Attrs: nofree nosync nounwind memory(write, argmem: none, inaccessiblemem: none, target_mem0: none, target_mem1: none)
; FNATTRS-LABEL: define ptr @test1_2
; FNATTRS-SAME: (ptr readnone captures(none) [[X1_2:%.*]], ptr returned [[Y1_2:%.*]], i1 [[C:%.*]]) #[[ATTR12]] {
; FNATTRS-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
@@ -520,7 +520,7 @@ f:
}
define void @test2(ptr %x2) {
-; FNATTRS: Function Attrs: nofree nosync nounwind memory(write, argmem: none, inaccessiblemem: none)
+; FNATTRS: Function Attrs: nofree nosync nounwind memory(write, argmem: none, inaccessiblemem: none, target_mem0: none, target_mem1: none)
; FNATTRS-LABEL: define void @test2
; FNATTRS-SAME: (ptr readnone captures(none) [[X2:%.*]]) #[[ATTR12]] {
; FNATTRS-NEXT: call void @test2(ptr [[X2]])
@@ -540,7 +540,7 @@ define void @test2(ptr %x2) {
}
define void @test3(ptr %x3, ptr %y3, ptr %z3) {
-; FNATTRS: Function Attrs: nofree nosync nounwind memory(write, argmem: none, inaccessiblemem: none)
+; FNATTRS: Function Attrs: nofree nosync nounwind memory(write, argmem: none, inaccessiblemem: none, target_mem0: none, target_mem1: none)
; FNATTRS-LABEL: define void @test3
; FNATTRS-SAME: (ptr readnone captures(none) [[X3:%.*]], ptr readnone captures(none) [[Y3:%.*]], ptr readnone captures(none) [[Z3:%.*]]) #[[ATTR12]] {
; FNATTRS-NEXT: call void @test3(ptr [[Z3]], ptr [[Y3]], ptr [[X3]])
@@ -560,7 +560,7 @@ define void @test3(ptr %x3, ptr %y3, ptr %z3) {
}
define void @test4_1(ptr %x4_1, i1 %c) {
-; FNATTRS: Function Attrs: nofree nosync nounwind memory(write, argmem: none, inaccessiblemem: none)
+; FNATTRS: Function Attrs: nofree nosync nounwind memory(write, argmem: none, inaccessiblemem: none, target_mem0: none, target_mem1: none)
; FNATTRS-LABEL: define void @test4_1
; FNATTRS-SAME: (ptr [[X4_1:%.*]], i1 [[C:%.*]]) #[[ATTR12]] {
; FNATTRS-NEXT: [[TMP1:%.*]] = call ptr @test4_2(ptr [[X4_1]], ptr [[X4_1]], ptr [[X4_1]], i1 [[C]])
@@ -580,7 +580,7 @@ define void @test4_1(ptr %x4_1, i1 %c) {
}
define ptr @test4_2(ptr %x4_2, ptr %y4_2, ptr %z4_2, i1 %c) {
-; FNATTRS: Function Attrs: nofree nosync nounwind memory(write, argmem: none, inaccessiblemem: none)
+; FNATTRS: Function Attrs: nofree nosync nounwind memory(write, argmem: none, inaccessiblemem: none, target_mem0: none, target_mem1: none)
; FNATTRS-LABEL: define ptr @test4_2
; FNATTRS-SAME: (ptr readnone captures(none) [[X4_2:%.*]], ptr readnone returned captures(ret: address, provenance) [[Y4_2:%.*]], ptr readnone captures(none) [[Z4_2:%.*]], i1 [[C:%.*]]) #[[ATTR12]] {
; FNATTRS-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
@@ -788,7 +788,7 @@ entry:
@g3 = global ptr null
define void @captureStrip(ptr %p) {
-; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none)
+; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none, target_mem0: none, target_mem1: none)
; FNATTRS-LABEL: define void @captureStrip
; FNATTRS-SAME: (ptr [[P:%.*]]) #[[ATTR1]] {
; FNATTRS-NEXT: [[B:%.*]] = call ptr @llvm.strip.invariant.group.p0(ptr [[P]])
@@ -1086,7 +1086,7 @@ define i64 @captures_not_ret_only(ptr %p) {
;; Unlike ptrtoint, ptrtoaddr only captures the address
define i64 @captures_ptrtoaddr_stored(ptr %p) {
-; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none)
+; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none, target_mem0: none, target_mem1: none)
; FNATTRS-LABEL: define noundef i64 @captures_ptrtoaddr_stored
; FNATTRS-SAME: (ptr captures(address) [[P:%.*]]) #[[ATTR1]] {
; FNATTRS-NEXT: [[INT:%.*]] = ptrtoaddr ptr [[P]] to i64
@@ -1189,7 +1189,7 @@ define ptr @captures_used_ret(ptr %p) {
; Make sure this is does not produce captures(ret: ...). We need to take the
; return capture components into account when handling argument SCCs.
define ptr @scc_capture_via_ret(i1 %c, ptr %p) {
-; FNATTRS: Function Attrs: nofree nosync nounwind memory(write, argmem: none, inaccessiblemem: none)
+; FNATTRS: Function Attrs: nofree nosync nounwind memory(write, argmem: none, inaccessiblemem: none, target_mem0: none, target_mem1: none)
; FNATTRS-LABEL: define ptr @scc_capture_via_ret
; FNATTRS-SAME: (i1 [[C:%.*]], ptr [[P:%.*]]) #[[ATTR12]] {
; FNATTRS-NEXT: br i1 [[C]], label [[IF:%.*]], label [[ELSE:%.*]]
@@ -1291,7 +1291,7 @@ define void @dont_increase_existing_captures_scc2(ptr %p) {
}
define void @addr_only_scc(ptr %p) {
-; FNATTRS: Function Attrs: nofree nosync nounwind memory(write, argmem: read, inaccessiblemem: none)
+; FNATTRS: Function Attrs: nofree nosync nounwind memory(write, argmem: read, inaccessiblemem: none, target_mem0: none, target_mem1: none)
; FNATTRS-LABEL: define void @addr_only_scc
; FNATTRS-SAME: (ptr readonly captures(address_is_null) [[P:%.*]]) #[[ATTR20:[0-9]+]] {
; FNATTRS-NEXT: [[V:%.*]] = load i8, ptr [[P]], align 1
@@ -1314,7 +1314,7 @@ define void @addr_only_scc(ptr %p) {
}
define void @addr_only_scc2(ptr %p) {
-; FNATTRS: Function Attrs: nofree nosync nounwind memory(write, argmem: read, inaccessiblemem: none)
+; FNATTRS: Function Attrs: nofree nosync nounwind memory(write, argmem: read, inaccessiblemem: none, target_mem0: none, target_mem1: none)
; FNATTRS-LABEL: define void @addr_only_scc2
; FNATTRS-SAME: (ptr readonly captures(address_is_null) [[P:%.*]]) #[[ATTR20]] {
; FNATTRS-NEXT: [[CMP:%.*]] = icmp ne ptr [[P]], null
diff --git a/llvm/test/Transforms/FunctionAttrs/read-write-scc.ll b/llvm/test/Transforms/FunctionAttrs/read-write-scc.ll
index be61990fd6278..1fc0084203fca 100644
--- a/llvm/test/Transforms/FunctionAttrs/read-write-scc.ll
+++ b/llvm/test/Transforms/FunctionAttrs/read-write-scc.ll
@@ -4,7 +4,7 @@
@i = global i32 0
define void @foo() {
-; CHECK: Function Attrs: nofree nosync nounwind memory(readwrite, argmem: none, inaccessiblemem: none)
+; CHECK: Function Attrs: nofree nosync nounwind memory(readwrite, argmem: none, inaccessiblemem: none, target_mem0: none, target_mem1: none)
; CHECK-LABEL: define {{[^@]+}}@foo
; CHECK-SAME: () #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: store i32 1, ptr @i, align 4
@@ -17,7 +17,7 @@ define void @foo() {
}
define void @bar() {
-; CHECK: Function Attrs: nofree nosync nounwind memory(readwrite, argmem: none, inaccessiblemem: none)
+; CHECK: Function Attrs: nofree nosync nounwind memory(readwrite, argmem: none, inaccessiblemem: none, target_mem0: none, target_mem1: none)
; CHECK-LABEL: define {{[^@]+}}@bar
; CHECK-SAME: () #[[ATTR0]] {
; CHECK-NEXT: [[I:%.*]] = load i32, ptr @i, align 4
diff --git a/llvm/test/Transforms/FunctionAttrs/readattrs.ll b/llvm/test/Transforms/FunctionAttrs/readattrs.ll
index 87f64ed3c63bc..8fc72a1ab90b9 100644
--- a/llvm/test/Transforms/FunctionAttrs/readattrs.ll
+++ b/llvm/test/Transforms/FunctionAttrs/readattrs.ll
@@ -33,7 +33,7 @@ define void @test1_2(ptr %x1_2, ptr %y1_2, ptr %z1_2) {
; TODO: Missing with attributor-light: argmem: none, inaccessiblemem: none
define ptr @test2(ptr %p) {
-; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none)
+; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none, target_mem0: none, target_mem1: none)
; FNATTRS-LABEL: define {{[^@]+}}@test2
; FNATTRS-SAME: (ptr readnone returned captures(ret: address, provenance) [[P:%.*]]) #[[ATTR0:[0-9]+]] {
; FNATTRS-NEXT: store i32 0, ptr @x, align 4
diff --git a/llvm/test/Transforms/FunctionAttrs/writeonly.ll b/llvm/test/Transforms/FunctionAttrs/writeonly.ll
index 88c6031613697..05ecb12c710ee 100644
--- a/llvm/test/Transforms/FunctionAttrs/writeonly.ll
+++ b/llvm/test/Transforms/FunctionAttrs/writeonly.ll
@@ -44,7 +44,7 @@ nouses-argworn-funro_entry:
@d-ccc = internal global %_type_of_d-ccc <{ ptr null, i8 1, i8 13, i8 0, i8 -127 }>, align 8
define void @nouses-argworn-funwo(ptr writeonly %.aaa) {
-; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none)
+; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none, target_mem0: none, target_mem1: none)
; FNATTRS-LABEL: define {{[^@]+}}@nouses-argworn-funwo
; FNATTRS-SAME: (ptr readnone captures(none) [[DOTAAA:%.*]]) #[[ATTR2:[0-9]+]] {
; FNATTRS-NEXT: nouses-argworn-funwo_entry:
@@ -82,7 +82,7 @@ define void @test_store(ptr %p) {
@G = external global ptr
define i8 @test_store_capture(ptr %p) {
-; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(readwrite, argmem: read, inaccessiblemem: none)
+; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(readwrite, argmem: read, inaccessiblemem: none, target_mem0: none, target_mem1: none)
; FNATTRS-LABEL: define {{[^@]+}}@test_store_capture
; FNATTRS-SAME: (ptr [[P:%.*]]) #[[ATTR4:[0-9]+]] {
; FNATTRS-NEXT: store ptr [[P]], ptr @G, align 8
diff --git a/llvm/test/Transforms/InferFunctionAttrs/norecurse_debug.ll b/llvm/test/Transforms/InferFunctionAttrs/norecurse_debug.ll
index c8568272d320f..89a09406e5f1d 100644
--- a/llvm/test/Transforms/InferFunctionAttrs/norecurse_debug.ll
+++ b/llvm/test/Transforms/InferFunctionAttrs/norecurse_debug.ll
@@ -52,5 +52,5 @@ attributes #1 = { nounwind readnone speculatable }
!28 = !DILocation(line: 9, column: 18, scope: !2)
!29 = !DILocation(line: 10, column: 1, scope: !2)
-; CHECK: attributes #0 = { mustprogress nofree norecurse nosync nounwind willreturn memory(readwrite, argmem: write, inaccessiblemem: none) }
+; CHECK: attributes #0 = { mustprogress nofree norecurse nosync nounwind willreturn memory(readwrite, argmem: write, inaccessiblemem: none, target_mem0: none, target_mem1: none) }
; CHECK-NOT: foo.coefficient1
diff --git a/llvm/test/Transforms/LowerTypeTests/cfi-nounwind-direct-call.ll b/llvm/test/Transforms/LowerTypeTests/cfi-nounwind-direct-call.ll
index 2795333effd76..89c32fab54a4c 100644
--- a/llvm/test/Transforms/LowerTypeTests/cfi-nounwind-direct-call.ll
+++ b/llvm/test/Transforms/LowerTypeTests/cfi-nounwind-direct-call.ll
@@ -117,7 +117,7 @@ attributes #6 = { noreturn nounwind }
; CHECK-NEXT: ret i32 [[DOT]]
;
;
-; CHECK: Function Attrs: minsize mustprogress nofree norecurse nosync nounwind optsize willreturn memory(write, argmem: none, inaccessiblemem: none)
+; CHECK: Function Attrs: minsize mustprogress nofree norecurse nosync nounwind optsize willreturn memory(write, argmem: none, inaccessiblemem: none, target_mem0: none, target_mem1: none)
; CHECK-LABEL: define dso_local noundef range(i32 0, 2) i32 @_Z10call_catchi
; CHECK-SAME: (i32 noundef [[NUM:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] !type [[META4]] !type [[META5]] !type [[META6]] {
; CHECK-NEXT: entry:
diff --git a/llvm/test/Transforms/SCCP/ipscp-drop-argmemonly.ll b/llvm/test/Transforms/SCCP/ipscp-drop-argmemonly.ll
index b42f3bc7f4479..6a64dc3cddd39 100644
--- a/llvm/test/Transforms/SCCP/ipscp-drop-argmemonly.ll
+++ b/llvm/test/Transforms/SCCP/ipscp-drop-argmemonly.ll
@@ -14,7 +14,7 @@
; CHECK: @[[G:[a-zA-Z0-9_$"\\.-]+]] = internal global i32 0
;.
define internal void @ptrarg.1(ptr %arg, i32 %val) argmemonly nounwind {
-; CHECK: Function Attrs: nounwind memory(readwrite, inaccessiblemem: none)
+; CHECK: Function Attrs: nounwind memory(readwrite, inaccessiblemem: none, target_mem0: none, target_mem1: none)
; CHECK-LABEL: @ptrarg.1(
; CHECK-NEXT: store i32 10, ptr @g, align 4
; CHECK-NEXT: ret void
@@ -110,7 +110,7 @@ define void @caller.4(ptr %ptr) {
; Here the pointer argument %arg will be replaced by a constant. We need to
; drop inaccessiblemem_or_argmemonly.
define internal void @ptrarg.5(ptr %arg, i32 %val) argmemonly inaccessiblemem_or_argmemonly nounwind {
-; CHECK: Function Attrs: nounwind memory(readwrite, inaccessiblemem: none)
+; CHECK: Function Attrs: nounwind memory(readwrite, inaccessiblemem: none, target_mem0: none, target_mem1: none)
; CHECK-LABEL: @ptrarg.5(
; CHECK-NEXT: store i32 10, ptr @g, align 4
; CHECK-NEXT: ret void
@@ -163,7 +163,7 @@ define i32 @caller.6.cs.attributes(i32 %n) {
}
;.
-; CHECK: attributes #[[ATTR0]] = { nounwind memory(readwrite, inaccessiblemem: none) }
+; CHECK: attributes #[[ATTR0]] = { nounwind memory(readwrite, inaccessiblemem: none, target_mem0: none, target_mem1: none) }
; CHECK: attributes #[[ATTR1:[0-9]+]] = { nounwind memory(argmem: readwrite) }
; CHECK: attributes #[[ATTR2]] = { nounwind memory(readwrite, target_mem0: none, target_mem1: none) }
; CHECK: attributes #[[ATTR3:[0-9]+]] = { nounwind memory(argmem: readwrite, inaccessiblemem: readwrite) }
diff --git a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
index 234ee6dd8f5de..62630c08f181b 100644
--- a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
+++ b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
@@ -476,7 +476,7 @@ CodeGenIntrinsic::getValueAsIRMemLocation(const Record *R) const {
.Default(IRMemLocation::Other); // fallback enum
if (Loc == IRMemLocation::Other)
- PrintFatalError(R->getLoc(), "unknown Target IRMemLocation: " + Name);
+ PrintFatalError(R->getLoc(), "unknown IRMemLocation: " + Name);
return Loc;
}
diff --git a/mlir/test/Target/LLVMIR/llvmir.mlir b/mlir/test/Target/LLVMIR/llvmir.mlir
index cc243c86ca902..0e087200b1116 100644
--- a/mlir/test/Target/LLVMIR/llvmir.mlir
+++ b/mlir/test/Target/LLVMIR/llvmir.mlir
@@ -2373,7 +2373,7 @@ llvm.func @readonly_function(%arg0: !llvm.ptr {llvm.readonly})
llvm.func @arg_mem_none_func() attributes {
memory_effects = #llvm.memory_effects<other = readwrite, argMem = none, inaccessibleMem = readwrite>}
-// CHECK: attributes #[[ATTR]] = { memory(readwrite, argmem: none, errnomem: none) }
+// CHECK: attributes #[[ATTR]] = { memory(readwrite, argmem: none, errnomem: none, target_mem0: none, target_mem1: none) }
// -----
@@ -2381,7 +2381,7 @@ llvm.func @arg_mem_none_func() attributes {
llvm.func @readwrite_func() attributes {
memory_effects = #llvm.memory_effects<other = readwrite, argMem = readwrite, inaccessibleMem = readwrite>}
-// CHECK: attributes #[[ATTR]] = { memory(readwrite, errnomem: none) }
+// CHECK: attributes #[[ATTR]] = { memory(readwrite, errnomem: none, target_mem0: none, target_mem1: none) }
// -----
@@ -2734,11 +2734,11 @@ llvm.func @mem_effects_call() {
// CHECK: #[[ATTRS_0]]
// CHECK-SAME: memory(none)
// CHECK: #[[ATTRS_1]]
-// CHECK-SAME: memory(read, argmem: none, inaccessiblemem: write, errnomem: none)
+// CHECK-SAME: memory(read, argmem: none, inaccessiblemem: write, errnomem: none, target_mem0: none, target_mem1: none)
// CHECK: #[[ATTRS_2]]
-// CHECK-SAME: memory(read, inaccessiblemem: write, errnomem: none)
+// CHECK-SAME: memory(read, inaccessiblemem: write, errnomem: none, target_mem0: none, target_mem1: none)
// CHECK: #[[ATTRS_3]]
-// CHECK-SAME: memory(readwrite, argmem: read, errnomem: none)
+// CHECK-SAME: memory(readwrite, argmem: read, errnomem: none, target_mem0: none, target_mem1: none)
// -----
More information about the llvm-commits
mailing list