From d568c2bc9f421cd37b8b1e123deba4b792b4e66e Mon Sep 17 00:00:00 2001 From: CarolineConcatto Date: Tue, 1 Jul 2025 11:48:55 +0000 Subject: [PATCH 01/10] [RFC][Draft] Extend MemoryEffects to Support Target-Specific Memory Locations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch introduces preliminary support for additional memory locations, such as FPMR and ZA, needed to model AArch64 architectural registers as memory dependencies. Currently, these locations are not yet target-specific. The goal is to enable the compiler to express read/write effects on these resources. What This Patch Does: Adds two new memory locations: FPMR and ZA, intended to represent AArch64-specific inaccessible memory types. Current Limitations: These new locations are not yet target-specific in the type-safe sense, they are globally visible and hardcoded. There is no mechanism yet to associate a memory location with its corresponding target (e.g., AArch64 vs RISCV). No changes are made yet to bitcode serialization, parser support, or alias analysis behavior. This patch is not functionally complete — it is a structural prototype to solicit feedback on the direction and I would like some suggestion on how to proceed. --- llvm/include/llvm/AsmParser/LLParser.h | 1 + llvm/include/llvm/AsmParser/LLToken.h | 4 + llvm/include/llvm/IR/Intrinsics.td | 11 +++ llvm/include/llvm/IR/IntrinsicsAArch64.td | 1 - llvm/include/llvm/Support/ModRef.h | 24 ++++- llvm/include/llvm/TableGen/Record.h | 3 + llvm/lib/AsmParser/LLLexer.cpp | 4 + llvm/lib/AsmParser/LLParser.cpp | 94 ++++++++++++++++--- llvm/lib/IR/Attributes.cpp | 13 +++ llvm/lib/Support/ModRef.cpp | 9 ++ llvm/lib/TableGen/Record.cpp | 15 +++ llvm/test/Assembler/memory-attribute.ll | 21 +++++ llvm/test/Bitcode/attributes.ll | 44 +++++++++ llvm/test/TableGen/intrinsic-attrs-fp8.td | 24 +++++ llvm/unittests/Support/ModRefTest.cpp | 2 +- .../TableGen/Basic/CodeGenIntrinsics.cpp | 8 +- 16 files changed, 261 insertions(+), 17 deletions(-) create mode 100644 llvm/test/TableGen/intrinsic-attrs-fp8.td diff --git a/llvm/include/llvm/AsmParser/LLParser.h b/llvm/include/llvm/AsmParser/LLParser.h index c01de4a289a69..ee7f133961031 100644 --- a/llvm/include/llvm/AsmParser/LLParser.h +++ b/llvm/include/llvm/AsmParser/LLParser.h @@ -295,6 +295,7 @@ namespace llvm { }; bool parseEnumAttribute(Attribute::AttrKind Attr, AttrBuilder &B, bool InAttrGroup); + bool parseInaccessibleMemLocation(IRMemLocation &MemLoc); bool parseOptionalParamOrReturnAttrs(AttrBuilder &B, bool IsParam); bool parseOptionalParamAttrs(AttrBuilder &B) { return parseOptionalParamOrReturnAttrs(B, true); diff --git a/llvm/include/llvm/AsmParser/LLToken.h b/llvm/include/llvm/AsmParser/LLToken.h index c7e4bdf3ff811..68920af75c667 100644 --- a/llvm/include/llvm/AsmParser/LLToken.h +++ b/llvm/include/llvm/AsmParser/LLToken.h @@ -202,11 +202,15 @@ enum Kind { kw_readwrite, kw_argmem, kw_inaccessiblemem, + kw_fpmr, + kw_za, kw_errnomem, // Legacy attributes: kw_argmemonly, kw_inaccessiblememonly, + kw_inaccessiblereadmemonly, + kw_inaccessiblewritememonly, kw_inaccessiblemem_or_argmemonly, kw_nocapture, diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td index bd6f94ac1286c..ad1b0b462be37 100644 --- a/llvm/include/llvm/IR/Intrinsics.td +++ b/llvm/include/llvm/IR/Intrinsics.td @@ -49,6 +49,17 @@ def IntrArgMemOnly : IntrinsicProperty; // accessible by the module being compiled. This is a weaker form of IntrNoMem. def IntrInaccessibleMemOnly : IntrinsicProperty; + + +class IntrinsicMemoryLocation; +// This should be added in the Target, but once in IntrinsicsAArch64.td +// It complains error: "Variable not defined: 'AArch64_FPMR'" +def AArch64_FPMR : IntrinsicMemoryLocation; +def AArch64_ZA: IntrinsicMemoryLocation; +// IntrInaccessible{Read|Write}MemOnly needs to set Location +class IntrInaccessibleReadMemOnly : IntrinsicProperty{IntrinsicMemoryLocation Loc=idx;} +class IntrInaccessibleWriteMemOnly : IntrinsicProperty{IntrinsicMemoryLocation Loc=idx;} + // IntrInaccessibleMemOrArgMemOnly -- This intrinsic only accesses memory that // its pointer-typed arguments point to or memory that is not accessible // by the module being compiled. This is a weaker form of IntrArgMemOnly. diff --git a/llvm/include/llvm/IR/IntrinsicsAArch64.td b/llvm/include/llvm/IR/IntrinsicsAArch64.td index ca6e2128812f7..5e0b5915d77fa 100644 --- a/llvm/include/llvm/IR/IntrinsicsAArch64.td +++ b/llvm/include/llvm/IR/IntrinsicsAArch64.td @@ -9,7 +9,6 @@ // This file defines all of the AARCH64-specific intrinsics. // //===----------------------------------------------------------------------===// - let TargetPrefix = "aarch64" in { def int_aarch64_ldxr : Intrinsic<[llvm_i64_ty], [llvm_anyptr_ty], diff --git a/llvm/include/llvm/Support/ModRef.h b/llvm/include/llvm/Support/ModRef.h index 71f3b5bcb9c2b..8459876bf34a6 100644 --- a/llvm/include/llvm/Support/ModRef.h +++ b/llvm/include/llvm/Support/ModRef.h @@ -56,6 +56,11 @@ enum class ModRefInfo : uint8_t { /// Debug print ModRefInfo. LLVM_ABI raw_ostream &operator<<(raw_ostream &OS, ModRefInfo MR); +enum class InaccessibleTargetMemLocation { + AARCH64_FPMR = 3, + AARCH64_ZA = 4, +}; + /// The locations at which a function might access memory. enum class IRMemLocation { /// Access to memory via argument pointers. @@ -65,7 +70,7 @@ enum class IRMemLocation { /// Errno memory. ErrnoMem = 2, /// Any other memory. - Other = 3, + Other = 5, /// Helpers to iterate all locations in the MemoryEffectsBase class. First = ArgMem, @@ -142,6 +147,18 @@ template 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 class MemoryEffectsBase { return MemoryEffectsBase(Data); } + bool isTargetMemLoc(IRMemLocation Loc) { + return static_cast(Loc) > + static_cast(Location::ErrnoMem); + } + /// Convert MemoryEffectsBase into an encoded integer value (used by memory /// attribute). uint32_t toIntValue() const { diff --git a/llvm/include/llvm/TableGen/Record.h b/llvm/include/llvm/TableGen/Record.h index a2b86eb8e7cad..5aeb331c49c9b 100644 --- a/llvm/include/llvm/TableGen/Record.h +++ b/llvm/include/llvm/TableGen/Record.h @@ -25,6 +25,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/ModRef.h" #include "llvm/Support/SMLoc.h" #include "llvm/Support/Timer.h" #include "llvm/Support/TrailingObjects.h" @@ -1961,6 +1962,8 @@ class Record { /// value is not the right type. int64_t getValueAsInt(StringRef FieldName) const; + llvm::IRMemLocation getLocationTypeAsInt(StringRef FieldName) const; + /// This method looks up the specified field and returns its value as an Dag, /// throwing an exception if the field does not exist or if the value is not /// the right type. diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp index ce813e1d7b1c4..d7ac109d3a7bf 100644 --- a/llvm/lib/AsmParser/LLLexer.cpp +++ b/llvm/lib/AsmParser/LLLexer.cpp @@ -701,10 +701,14 @@ lltok::Kind LLLexer::LexIdentifier() { KEYWORD(write); KEYWORD(readwrite); KEYWORD(argmem); + KEYWORD(fpmr); + KEYWORD(za); KEYWORD(inaccessiblemem); KEYWORD(errnomem); KEYWORD(argmemonly); KEYWORD(inaccessiblememonly); + KEYWORD(inaccessiblewritememonly); + KEYWORD(inaccessiblereadmemonly); KEYWORD(inaccessiblemem_or_argmemonly); KEYWORD(nocapture); KEYWORD(address_is_null); diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index b7f6950f679ef..fcc53829e60fa 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -1666,6 +1666,48 @@ static bool upgradeMemoryAttr(MemoryEffects &ME, lltok::Kind Kind) { } } +static std::optional 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( + llvm::InaccessibleTargetMemLocation::AARCH64_FPMR); + case lltok::kw_za: + return static_cast( + 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 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 /// ::= | '=' bool LLParser::parseFnAttributeValuePairs(AttrBuilder &B, @@ -1676,6 +1718,11 @@ bool LLParser::parseFnAttributeValuePairs(AttrBuilder &B, B.clear(); MemoryEffects ME = MemoryEffects::unknown(); + // Memory effects can span multiple locations, so we initialize a base + // MemoryEffects object once with default state, and then incrementally + // populate or combine effects for individual locations. This avoids + // rebuilding the full Data structure on each addition. + bool FirstME = true; while (true) { lltok::Kind Token = Lex.getKind(); if (Token == lltok::rbrace) @@ -1712,6 +1759,36 @@ bool LLParser::parseFnAttributeValuePairs(AttrBuilder &B, continue; } + if (Token == lltok::kw_inaccessiblereadmemonly) { + Lex.Lex(); // eat the keyword + + IRMemLocation MemLoc; + if (parseInaccessibleMemLocation(MemLoc)) { + if (!FirstME) + ME = ME.getWithModRef(MemLoc, ModRefInfo::Ref); + else + ME &= MemoryEffects::inaccessibleReadMemOnly(MemLoc); + } else + ME = MemoryEffects::inaccessibleReadMemOnly(); + FirstME = false; + continue; + } + + if (Token == lltok::kw_inaccessiblewritememonly) { + Lex.Lex(); // eat the keyword + + IRMemLocation MemLoc; + if (parseInaccessibleMemLocation(MemLoc)) { + if (!FirstME) + ME = ME.getWithModRef(MemLoc, ModRefInfo::Mod); + else + ME &= MemoryEffects::inaccessibleWriteMemOnly(MemLoc); + } else + ME &= MemoryEffects::inaccessibleWriteMemOnly(); + FirstME = false; + continue; + } + Attribute::AttrKind Attr = tokenToAttribute(Token); if (Attr == Attribute::None) { if (!InAttrGrp) @@ -2510,19 +2587,6 @@ bool LLParser::parseAllocKind(AllocFnKind &Kind) { return false; } -static std::optional 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 keywordToModRef(lltok::Kind Tok) { switch (Tok) { case lltok::kw_none: @@ -2533,6 +2597,10 @@ static std::optional keywordToModRef(lltok::Kind Tok) { return ModRefInfo::Mod; case lltok::kw_readwrite: return ModRefInfo::ModRef; + case lltok::kw_inaccessiblewritememonly: + return ModRefInfo::Mod; + case lltok::kw_inaccessiblereadmemonly: + return ModRefInfo::Ref; default: return std::nullopt; } diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp index d1fbcb9e893a7..5d5f207350f89 100644 --- a/llvm/lib/IR/Attributes.cpp +++ b/llvm/lib/IR/Attributes.cpp @@ -640,6 +640,10 @@ std::string Attribute::getAsString(bool InAttrGrp) const { if (MR == OtherMR) continue; + // Dont want to print Target Location if NoModRef + if (ME.isTargetMemLoc(Loc) && (MR == ModRefInfo::NoModRef)) + continue; + if (!First) OS << ", "; First = false; @@ -656,6 +660,15 @@ std::string Attribute::getAsString(bool InAttrGrp) const { break; case IRMemLocation::Other: llvm_unreachable("This is represented as the default access kind"); + default: { + InaccessibleTargetMemLocation TargetLoc = + static_cast(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(Loc); + if (TargetLoc == InaccessibleTargetMemLocation::AARCH64_FPMR) + OS << "FPMR: "; + if (TargetLoc == InaccessibleTargetMemLocation::AARCH64_ZA) + OS << "ZA: "; + break; + } } OS << ME.getModRef(Loc); }); diff --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp index 1f3e5dc68f1d6..b3ff26a57755c 100644 --- a/llvm/lib/TableGen/Record.cpp +++ b/llvm/lib/TableGen/Record.cpp @@ -3102,6 +3102,21 @@ Record::getValueAsListOfDefs(StringRef FieldName) const { return Defs; } +llvm::IRMemLocation Record::getLocationTypeAsInt(StringRef FieldName) const { + const Record *LocRec = getValueAsDef(FieldName); + StringRef Name = LocRec->getName(); + if (Name == "AArch64_FPMR") + return static_cast( + llvm::InaccessibleTargetMemLocation::AARCH64_FPMR); + else if (Name == "ZA") + return static_cast( + llvm::InaccessibleTargetMemLocation::AARCH64_ZA); + else if (Name == "InaccessibleMem") + return llvm::IRMemLocation::InaccessibleMem; + else + PrintFatalError(getLoc(), "unknown IRMemLocation: " + Name); +} + int64_t Record::getValueAsInt(StringRef FieldName) const { const RecordVal *R = getValue(FieldName); if (!R || !R->getValue()) diff --git a/llvm/test/Assembler/memory-attribute.ll b/llvm/test/Assembler/memory-attribute.ll index effd4ce7c4548..473468810768b 100644 --- a/llvm/test/Assembler/memory-attribute.ll +++ b/llvm/test/Assembler/memory-attribute.ll @@ -78,3 +78,24 @@ declare void @fn_argmem_read_inaccessiblemem_write() ; CHECK: @fn_argmem_read_inaccessiblemem_write_reordered() declare void @fn_argmem_read_inaccessiblemem_write_reordered() memory(inaccessiblemem: write, argmem: read) + +; CHECK: Function Attrs: memory(za: write) +; CHECK: @fn_argmem_read_inaccessiblemem_write_za() +declare void @fn_argmem_read_inaccessiblemem_write_za() + memory(za: inaccessiblewritememonly) + +; CHECK: Function Attrs: memory(za: read) +; CHECK: @fn_argmem_read_inaccessiblemem_read_za() +declare void @fn_argmem_read_inaccessiblemem_read_za() + memory(za: inaccessiblereadmemonly) + +; CHECK: Function Attrs: memory(fpmr: write) +; CHECK: @fn_argmem_read_inaccessiblemem_write_fpmr() +declare void @fn_argmem_read_inaccessiblemem_write_fpmr() + memory(fpmr: inaccessiblewritememonly) + +; CHECK: Function Attrs: memory(fpmr: read) +; CHECK: @fn_argmem_read_inaccessiblemem_read_fpmr() +declare void @fn_argmem_read_inaccessiblemem_read_fpmr() + memory(fpmr: inaccessiblereadmemonly) + diff --git a/llvm/test/Bitcode/attributes.ll b/llvm/test/Bitcode/attributes.ll index 8c1a76365e1b4..89ea5eb302029 100644 --- a/llvm/test/Bitcode/attributes.ll +++ b/llvm/test/Bitcode/attributes.ll @@ -286,6 +286,7 @@ define void @f48() inaccessiblememonly { define void @f49() inaccessiblemem_or_argmemonly { ret void } + ; CHECK: define void @f50(ptr swiftself %0) define void @f50(ptr swiftself %0) { @@ -572,6 +573,42 @@ define void @dead_on_return(ptr dead_on_return %p) { ret void } +; CHECK: define void @fpmr_write() [[ATTR59:#.*]] { +define void @fpmr_write() inaccessiblewritememonly(fpmr) { + ret void +} + +; CHECK: define void @fpmr_read() [[ATTR60:#.*]] { +define void @fpmr_read() inaccessiblereadmemonly(fpmr) { + ret void +} + +; CHECK: define void @za_write() [[ATTR61:#.*]] { +define void @za_write() inaccessiblewritememonly(za) { + ret void +} + +; CHECK: define void @za_read() [[ATTR62:#.*]] { +define void @za_read() inaccessiblereadmemonly(za) { + ret void +} + +; CHECK: define void @read_inaccessible() [[ATTR63:#.*]] { +define void @read_inaccessible() inaccessiblereadmemonly { + ret void +} + +; CHECK: define void @write_inaccessible() [[ATTR64:#.*]] { +define void @write_inaccessible() inaccessiblewritememonly { + ret void +} + +; CHECK: define void @za_read_write_fpmr() [[ATTR65:#.*]] { +define void @za_read_write_fpmr() inaccessiblereadmemonly(za) inaccessiblewritememonly(fpmr) { + ret void +} + + ; CHECK: attributes #0 = { noreturn } ; CHECK: attributes #1 = { nounwind } ; CHECK: attributes #2 = { memory(none) } @@ -631,4 +668,11 @@ define void @dead_on_return(ptr dead_on_return %p) { ; CHECK: attributes [[SKIPPROFILE]] = { skipprofile } ; CHECK: attributes [[OPTDEBUG]] = { optdebug } ; CHECK: attributes [[NODIVERGENCESOURCE]] = { nodivergencesource } +; CHECK: attributes [[ATTR59]] = { memory(fpmr: write) } +; CHECK: attributes [[ATTR60]] = { memory(fpmr: read) } +; CHECK: attributes [[ATTR61]] = { memory(za: write) } +; CHECK: attributes [[ATTR62]] = { memory(za: read) } +; CHECK: attributes [[ATTR63]] = { memory(inaccessiblemem: read) } +; CHECK: attributes [[ATTR64]] = { memory(inaccessiblemem: write) } +; CHECK: attributes [[ATTR65]] = { memory(fpmr: write, za: read) } ; CHECK: attributes #[[NOBUILTIN]] = { nobuiltin } diff --git a/llvm/test/TableGen/intrinsic-attrs-fp8.td b/llvm/test/TableGen/intrinsic-attrs-fp8.td new file mode 100644 index 0000000000000..53ff1dfe2b807 --- /dev/null +++ b/llvm/test/TableGen/intrinsic-attrs-fp8.td @@ -0,0 +1,24 @@ +// RUN: llvm-tblgen -gen-intrinsic-impl -I %p/../../include -DTEST_INTRINSICS_SUPPRESS_DEFS %s | FileCheck %s + +include "llvm/IR/Intrinsics.td" + +def int_aarch64_set_fpmr_2 : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [IntrInaccessibleWriteMemOnly]>; + +// CHECK: static constexpr unsigned IntrinsicNameOffsetTable[] = { +// CHECK-NEXT: 1, // not_intrinsic +// CHECK-NEXT: 15, // llvm.aarch64.set.fpmr.2 + + +// CHECK: static AttributeSet getIntrinsicFnAttributeSet(LLVMContext &C, unsigned ID) { +// CHECK-NEXT: switch (ID) { +// CHECK-NEXT: default: llvm_unreachable("Invalid attribute set number"); +// CHECK-NEXT: case 0: +// CHECK-NEXT: return AttributeSet::get(C, { +// CHECK-NEXT: Attribute::get(C, Attribute::NoUnwind), +// CHECK-NEXT: Attribute::get(C, Attribute::NoCallback), +// CHECK-NEXT: Attribute::get(C, Attribute::NoSync), +// CHECK-NEXT: Attribute::get(C, Attribute::NoFree), +// CHECK-NEXT: Attribute::get(C, Attribute::WillReturn), +// CHECK-NEXT: // ArgMem: NoModRef, InaccessibleMem: NoModRef, ErrnoMem: NoModRef, FPMR: Mod, ZA: NoModRef, Other: NoModRef +// CHECK-NEXT: Attribute::getWithMemoryEffects(C, MemoryEffects::createFromIntValue(128)), +// CHECK-NEXT: }); diff --git a/llvm/unittests/Support/ModRefTest.cpp b/llvm/unittests/Support/ModRefTest.cpp index 9c13908da44bb..cbdf752978555 100644 --- a/llvm/unittests/Support/ModRefTest.cpp +++ b/llvm/unittests/Support/ModRefTest.cpp @@ -21,7 +21,7 @@ TEST(ModRefTest, PrintMemoryEffects) { raw_string_ostream OS(S); OS << MemoryEffects::none(); EXPECT_EQ(S, "ArgMem: NoModRef, InaccessibleMem: NoModRef, ErrnoMem: " - "NoModRef, Other: NoModRef"); + "NoModRef, FPMR: NoModRef, ZA: NoModRef, Other: NoModRef"); } } // namespace diff --git a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp index bc42efa3b2e9c..f53915642ac6d 100644 --- a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp +++ b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp @@ -374,7 +374,13 @@ void CodeGenIntrinsic::setProperty(const Record *R) { ME &= MemoryEffects::argMemOnly(); else if (R->getName() == "IntrInaccessibleMemOnly") ME &= MemoryEffects::inaccessibleMemOnly(); - else if (R->getName() == "IntrInaccessibleMemOrArgMemOnly") + else if (R->isSubClassOf("IntrInaccessibleReadMemOnly")) { + llvm::IRMemLocation Loc = R->getLocationTypeAsInt("Loc"); + ME &= MemoryEffects::inaccessibleWriteMemOnly(Loc); + } else if (R->isSubClassOf("IntrInaccessibleWriteMemOnly")) { + llvm::IRMemLocation Loc = R->getLocationTypeAsInt("Loc"); + ME &= MemoryEffects::inaccessibleWriteMemOnly(Loc); + } else if (R->getName() == "IntrInaccessibleMemOrArgMemOnly") ME &= MemoryEffects::inaccessibleOrArgMemOnly(); else if (R->getName() == "Commutative") isCommutative = true; From 13c7470bde9de343862f3b2252be3b6532341061 Mon Sep 17 00:00:00 2001 From: CarolineConcatto Date: Tue, 15 Jul 2025 10:56:25 +0000 Subject: [PATCH 02/10] 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 68920af75c667..c08eb99c1f5b2 100644 --- a/llvm/include/llvm/AsmParser/LLToken.h +++ b/llvm/include/llvm/AsmParser/LLToken.h @@ -202,15 +202,13 @@ enum Kind { kw_readwrite, kw_argmem, kw_inaccessiblemem, - kw_fpmr, - kw_za, + kw_aarch64_fpmr, + kw_aarch64_za, kw_errnomem, // Legacy attributes: kw_argmemonly, kw_inaccessiblememonly, - kw_inaccessiblereadmemonly, - kw_inaccessiblewritememonly, kw_inaccessiblemem_or_argmemonly, kw_nocapture, diff --git a/llvm/include/llvm/IR/IntrinsicsAArch64.td b/llvm/include/llvm/IR/IntrinsicsAArch64.td index 5e0b5915d77fa..ca6e2128812f7 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 class MemoryEffectsBase { return MemoryEffectsBase(Location::InaccessibleMem, MR); } - /// Create MemoryEffectsBase that can only read inaccessible memory. - static MemoryEffectsBase - inaccessibleReadMemOnly(Location Loc = Location::InaccessibleMem) { - return MemoryEffectsBase(Loc, ModRefInfo::Ref); - } - - /// Create MemoryEffectsBase that can only write inaccessible memory. - static MemoryEffectsBase - inaccessibleWriteMemOnly(Location Loc = Location::InaccessibleMem) { - return MemoryEffectsBase(Loc, ModRefInfo::Mod); - } - /// Create MemoryEffectsBase that can only access errno memory. static MemoryEffectsBase errnoMemOnly(ModRefInfo MR = ModRefInfo::ModRef) { return MemoryEffectsBase(Location::ErrnoMem, MR); diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp index d7ac109d3a7bf..c086f9f9585a2 100644 --- a/llvm/lib/AsmParser/LLLexer.cpp +++ b/llvm/lib/AsmParser/LLLexer.cpp @@ -701,14 +701,12 @@ lltok::Kind LLLexer::LexIdentifier() { KEYWORD(write); KEYWORD(readwrite); KEYWORD(argmem); - KEYWORD(fpmr); - KEYWORD(za); + KEYWORD(aarch64_fpmr); + KEYWORD(aarch64_za); KEYWORD(inaccessiblemem); KEYWORD(errnomem); KEYWORD(argmemonly); KEYWORD(inaccessiblememonly); - KEYWORD(inaccessiblewritememonly); - KEYWORD(inaccessiblereadmemonly); KEYWORD(inaccessiblemem_or_argmemonly); KEYWORD(nocapture); KEYWORD(address_is_null); diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index fcc53829e60fa..abde2993bb048 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -1674,10 +1674,10 @@ static std::optional 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( llvm::InaccessibleTargetMemLocation::AARCH64_FPMR); - case lltok::kw_za: + case lltok::kw_aarch64_za: return static_cast( llvm::InaccessibleTargetMemLocation::AARCH64_ZA); default: @@ -1685,29 +1685,6 @@ static std::optional 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 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 /// ::= | '=' bool LLParser::parseFnAttributeValuePairs(AttrBuilder &B, @@ -1718,11 +1695,6 @@ bool LLParser::parseFnAttributeValuePairs(AttrBuilder &B, B.clear(); MemoryEffects ME = MemoryEffects::unknown(); - // Memory effects can span multiple locations, so we initialize a base - // MemoryEffects object once with default state, and then incrementally - // populate or combine effects for individual locations. This avoids - // rebuilding the full Data structure on each addition. - bool FirstME = true; while (true) { lltok::Kind Token = Lex.getKind(); if (Token == lltok::rbrace) @@ -1759,36 +1731,6 @@ bool LLParser::parseFnAttributeValuePairs(AttrBuilder &B, continue; } - if (Token == lltok::kw_inaccessiblereadmemonly) { - Lex.Lex(); // eat the keyword - - IRMemLocation MemLoc; - if (parseInaccessibleMemLocation(MemLoc)) { - if (!FirstME) - ME = ME.getWithModRef(MemLoc, ModRefInfo::Ref); - else - ME &= MemoryEffects::inaccessibleReadMemOnly(MemLoc); - } else - ME = MemoryEffects::inaccessibleReadMemOnly(); - FirstME = false; - continue; - } - - if (Token == lltok::kw_inaccessiblewritememonly) { - Lex.Lex(); // eat the keyword - - IRMemLocation MemLoc; - if (parseInaccessibleMemLocation(MemLoc)) { - if (!FirstME) - ME = ME.getWithModRef(MemLoc, ModRefInfo::Mod); - else - ME &= MemoryEffects::inaccessibleWriteMemOnly(MemLoc); - } else - ME &= MemoryEffects::inaccessibleWriteMemOnly(); - FirstME = false; - continue; - } - Attribute::AttrKind Attr = tokenToAttribute(Token); if (Attr == Attribute::None) { if (!InAttrGrp) @@ -2597,10 +2539,6 @@ static std::optional keywordToModRef(lltok::Kind Tok) { return ModRefInfo::Mod; case lltok::kw_readwrite: return ModRefInfo::ModRef; - case lltok::kw_inaccessiblewritememonly: - return ModRefInfo::Mod; - case lltok::kw_inaccessiblereadmemonly: - return ModRefInfo::Ref; default: return std::nullopt; } diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp index 5d5f207350f89..37e9d7c5c74db 100644 --- a/llvm/lib/IR/Attributes.cpp +++ b/llvm/lib/IR/Attributes.cpp @@ -664,9 +664,9 @@ std::string Attribute::getAsString(bool InAttrGrp) const { InaccessibleTargetMemLocation TargetLoc = static_cast(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(Loc); if (TargetLoc == InaccessibleTargetMemLocation::AARCH64_FPMR) - OS << "FPMR: "; + OS << "AARCH64_FPMR: "; if (TargetLoc == InaccessibleTargetMemLocation::AARCH64_ZA) - OS << "ZA: "; + OS << "AARCH64_ZA: "; break; } } diff --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp index b3ff26a57755c..d114358266737 100644 --- a/llvm/lib/TableGen/Record.cpp +++ b/llvm/lib/TableGen/Record.cpp @@ -3108,7 +3108,7 @@ llvm::IRMemLocation Record::getLocationTypeAsInt(StringRef FieldName) const { if (Name == "AArch64_FPMR") return static_cast( llvm::InaccessibleTargetMemLocation::AARCH64_FPMR); - else if (Name == "ZA") + else if (Name == "AArch64_ZA") return static_cast( llvm::InaccessibleTargetMemLocation::AARCH64_ZA); else if (Name == "InaccessibleMem") diff --git a/llvm/test/Assembler/memory-attribute.ll b/llvm/test/Assembler/memory-attribute.ll index 473468810768b..42f9b9f87e8b0 100644 --- a/llvm/test/Assembler/memory-attribute.ll +++ b/llvm/test/Assembler/memory-attribute.ll @@ -79,23 +79,27 @@ declare void @fn_argmem_read_inaccessiblemem_write() declare void @fn_argmem_read_inaccessiblemem_write_reordered() memory(inaccessiblemem: write, argmem: read) -; CHECK: Function Attrs: memory(za: write) -; CHECK: @fn_argmem_read_inaccessiblemem_write_za() -declare void @fn_argmem_read_inaccessiblemem_write_za() - memory(za: inaccessiblewritememonly) - -; CHECK: Function Attrs: memory(za: read) -; CHECK: @fn_argmem_read_inaccessiblemem_read_za() -declare void @fn_argmem_read_inaccessiblemem_read_za() - memory(za: inaccessiblereadmemonly) - -; CHECK: Function Attrs: memory(fpmr: write) -; CHECK: @fn_argmem_read_inaccessiblemem_write_fpmr() -declare void @fn_argmem_read_inaccessiblemem_write_fpmr() - memory(fpmr: inaccessiblewritememonly) - -; CHECK: Function Attrs: memory(fpmr: read) -; CHECK: @fn_argmem_read_inaccessiblemem_read_fpmr() -declare void @fn_argmem_read_inaccessiblemem_read_fpmr() - memory(fpmr: inaccessiblereadmemonly) - +; CHECK: Function Attrs: memory(aarch64_za: write) +; CHECK: @fn_inaccessiblemem_write_aarch64_za() +declare void @fn_inaccessiblemem_write_aarch64_za() + memory(aarch64_za: write) + +; CHECK: Function Attrs: memory(aarch64_za: read) +; CHECK: @fn_inaccessiblemem_read_aarch64_za() +declare void @fn_inaccessiblemem_read_aarch64_za() + memory(aarch64_za: read) + +; CHECK: Function Attrs: memory(aarch64_fpmr: write) +; CHECK: @fn_inaccessiblemem_write_aarch64_fpmr() +declare void @fn_inaccessiblemem_write_aarch64_fpmr() + memory(aarch64_fpmr: write) + +; CHECK: Function Attrs: memory(aarch64_fpmr: read) +; CHECK: @fn_inaccessiblemem_read_aarch64_fpmr() +declare void @fn_inaccessiblemem_read_aarch64_fpmr() + memory(aarch64_fpmr: read) + +; CHECK: Function Attrs: memory(aarch64_fpmr: read, aarch64_za: write) +; CHECK: @fn_inaccessiblemem_read_aarch64_fpmr_write_aarch64_za() +declare void @fn_inaccessiblemem_read_aarch64_fpmr_write_aarch64_za() + memory(aarch64_fpmr: read, aarch64_za: write) diff --git a/llvm/test/Bitcode/attributes.ll b/llvm/test/Bitcode/attributes.ll index 89ea5eb302029..8e72e7ade54c1 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) { @@ -573,43 +572,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) } @@ -668,11 +630,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]>; -// 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]>; +def int_aarch64_get_fpmr_set_za : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [IntrInaccessibleReadMemOnly, IntrInaccessibleWriteMemOnly]>; -// CHECK: static AttributeSet getIntrinsicFnAttributeSet(LLVMContext &C, unsigned ID) { -// CHECK-NEXT: switch (ID) { -// CHECK-NEXT: default: llvm_unreachable("Invalid attribute set number"); +// CHECK: static constexpr unsigned IntrinsicNameOffsetTable[] = { +// CHECK-NEXT: 1, // not_intrinsic +// CHECK-NEXT: 15, // llvm.aarch64.get.fpmr.set.za +// CHECK-NEXT: 44, // llvm.aarch64.get.za.2 +// CHECK-NEXT: 66, // llvm.aarch64.set.fpmr.2 + +// CHECK: static AttributeSet getIntrinsicFnAttributeSet(LLVMContext &C, unsigned ID) { +// CHECK-NEXT: switch (ID) { +// CHECK-NEXT: default: llvm_unreachable("Invalid attribute set number"); // CHECK-NEXT: case 0: // CHECK-NEXT: return AttributeSet::get(C, { // CHECK-NEXT: Attribute::get(C, Attribute::NoUnwind), @@ -19,6 +24,31 @@ def int_aarch64_set_fpmr_2 : DefaultAttrsIntrinsic<[], [llvm_i64_ty], [IntrIna // CHECK-NEXT: Attribute::get(C, Attribute::NoSync), // CHECK-NEXT: Attribute::get(C, Attribute::NoFree), // CHECK-NEXT: Attribute::get(C, Attribute::WillReturn), -// CHECK-NEXT: // ArgMem: NoModRef, InaccessibleMem: NoModRef, ErrnoMem: NoModRef, FPMR: Mod, ZA: NoModRef, Other: NoModRef -// CHECK-NEXT: Attribute::getWithMemoryEffects(C, MemoryEffects::createFromIntValue(128)), +// CHECK-NEXT: // ArgMem: ModRef, InaccessibleMem: ModRef, ErrnoMem: ModRef, AARCH64_FPMR: Ref, AARCH64_ZA: Mod, Other: ModRef +// CHECK-NEXT: Attribute::getWithMemoryEffects(C, MemoryEffects::createFromIntValue(3711)), +// CHECK-NEXT: }); +// CHECK-NEXT: case 1: +// CHECK-NEXT: return AttributeSet::get(C, { +// CHECK-NEXT: Attribute::get(C, Attribute::NoUnwind), +// CHECK-NEXT: Attribute::get(C, Attribute::NoCallback), +// CHECK-NEXT: Attribute::get(C, Attribute::NoSync), +// CHECK-NEXT: Attribute::get(C, Attribute::NoFree), +// CHECK-NEXT: Attribute::get(C, Attribute::WillReturn), +// CHECK-NEXT: // ArgMem: ModRef, InaccessibleMem: ModRef, ErrnoMem: ModRef, AARCH64_FPMR: ModRef, AARCH64_ZA: Ref, Other: ModRef +// CHECK-NEXT: Attribute::getWithMemoryEffects(C, MemoryEffects::createFromIntValue(3583)), // CHECK-NEXT: }); +// CHECK-NEXT: case 2: +// CHECK-NEXT: return AttributeSet::get(C, { +// CHECK-NEXT: Attribute::get(C, Attribute::NoUnwind), +// CHECK-NEXT: Attribute::get(C, Attribute::NoCallback), +// CHECK-NEXT: Attribute::get(C, Attribute::NoSync), +// CHECK-NEXT: Attribute::get(C, Attribute::NoFree), +// CHECK-NEXT: Attribute::get(C, Attribute::WillReturn), +// CHECK-NEXT: // ArgMem: ModRef, InaccessibleMem: ModRef, ErrnoMem: ModRef, AARCH64_FPMR: Mod, AARCH64_ZA: ModRef, Other: ModRef +// CHECK-NEXT: Attribute::getWithMemoryEffects(C, MemoryEffects::createFromIntValue(4031)), + +// CHECK: static constexpr uint16_t IntrinsicsToAttributesMap[] = { +// CHECK-NEXT: 0 << 8 | 0, // llvm.aarch64.get.fpmr.set.za +// CHECK-NEXT: 1 << 8 | 0, // llvm.aarch64.get.za.2 +// CHECK-NEXT: 2 << 8 | 0, // llvm.aarch64.set.fpmr.2 +// CHECK-NEXT:}; diff --git a/llvm/unittests/Support/ModRefTest.cpp b/llvm/unittests/Support/ModRefTest.cpp index cbdf752978555..7aa473ad20336 100644 --- a/llvm/unittests/Support/ModRefTest.cpp +++ b/llvm/unittests/Support/ModRefTest.cpp @@ -21,7 +21,8 @@ TEST(ModRefTest, PrintMemoryEffects) { raw_string_ostream OS(S); OS << MemoryEffects::none(); EXPECT_EQ(S, "ArgMem: NoModRef, InaccessibleMem: NoModRef, ErrnoMem: " - "NoModRef, FPMR: NoModRef, ZA: NoModRef, Other: NoModRef"); + "NoModRef, AARCH64_FPMR: NoModRef, AARCH64_ZA: NoModRef, Other: " + "NoModRef"); } } // namespace diff --git a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp index f53915642ac6d..ad6a5344e4b7c 100644 --- a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp +++ b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp @@ -376,10 +376,10 @@ void CodeGenIntrinsic::setProperty(const Record *R) { ME &= MemoryEffects::inaccessibleMemOnly(); else if (R->isSubClassOf("IntrInaccessibleReadMemOnly")) { llvm::IRMemLocation Loc = R->getLocationTypeAsInt("Loc"); - ME &= MemoryEffects::inaccessibleWriteMemOnly(Loc); + ME = ME.getWithModRef(Loc, ModRefInfo::Ref); } else if (R->isSubClassOf("IntrInaccessibleWriteMemOnly")) { llvm::IRMemLocation Loc = R->getLocationTypeAsInt("Loc"); - ME &= MemoryEffects::inaccessibleWriteMemOnly(Loc); + ME = ME.getWithModRef(Loc, ModRefInfo::Mod); } else if (R->getName() == "IntrInaccessibleMemOrArgMemOnly") ME &= MemoryEffects::inaccessibleOrArgMemOnly(); else if (R->getName() == "Commutative") From 1987000f84031613846e0fefd6aafe352e2ac851 Mon Sep 17 00:00:00 2001 From: CarolineConcatto Date: Tue, 15 Jul 2025 13:53:51 +0000 Subject: [PATCH 03/10] 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 ee7f133961031..c01de4a289a69 100644 --- a/llvm/include/llvm/AsmParser/LLParser.h +++ b/llvm/include/llvm/AsmParser/LLParser.h @@ -295,7 +295,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 2dccfa1708a6e732c4bfc49e0ff9903a9788d4f8 Mon Sep 17 00:00:00 2001 From: CarolineConcatto Date: Wed, 16 Jul 2025 17:23:20 +0000 Subject: [PATCH 04/10] 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 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( + llvm::InaccessibleTargetMemLocation::AARCH64_FPMR)) + .getWithoutLoc(static_cast( + 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 ad6a5344e4b7c..eb2d4de7e9320 100644 --- a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp +++ b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp @@ -376,10 +376,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 4366ac79d1a15842ce602f7aa4db190c8c4d392a Mon Sep 17 00:00:00 2001 From: CarolineConcatto Date: Wed, 23 Jul 2025 15:48:49 +0000 Subject: [PATCH 05/10] 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 class MemoryEffectsBase { /// Needed because `Data` may be non-zero by default unless explicitly /// cleared. bool onlyAccessTargetMemoryLocation() { - return getWithoutLoc(static_cast( - llvm::InaccessibleTargetMemLocation::AARCH64_FPMR)) - .getWithoutLoc(static_cast( - llvm::InaccessibleTargetMemLocation::AARCH64_ZA)) - .doesNotAccessMemory(); + MemoryEffectsBase ME = *this; + for (unsigned I = static_cast(LocationEnum::ErrnoMem); + I < static_cast(LocationEnum::Last); I++) + ME = ME.getWithoutLoc(static_cast(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(LocationEnum::ErrnoMem); + I < static_cast(LocationEnum::Last); I++) + FRMB.setModRef(static_cast(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 f43202eea6306..49b822b3ef38e 100644 --- a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp +++ b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp @@ -143,6 +143,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 4c810b2fe936cbf920a97e2449bdc1c87e06288e Mon Sep 17 00:00:00 2001 From: CarolineConcatto Date: Wed, 20 Aug 2025 10:21:49 +0000 Subject: [PATCH 06/10] 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 class MemoryEffectsBase { /// Whether this function only (at most) accesses inaccessible memory. bool onlyAccessesInaccessibleMem() const { - return getWithoutLoc(Location::InaccessibleMem).doesNotAccessMemory(); + return getWithoutLoc(static_cast( + llvm::InaccessibleTargetMemLocation::AARCH64_FPMR)) + .getWithoutLoc(static_cast( + 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 5aeb331c49c9b..75637cff35428 100644 --- a/llvm/include/llvm/TableGen/Record.h +++ b/llvm/include/llvm/TableGen/Record.h @@ -1962,8 +1962,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 d114358266737..1f3e5dc68f1d6 100644 --- a/llvm/lib/TableGen/Record.cpp +++ b/llvm/lib/TableGen/Record.cpp @@ -3102,21 +3102,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( - llvm::InaccessibleTargetMemLocation::AARCH64_FPMR); - else if (Name == "AArch64_ZA") - return static_cast( - llvm::InaccessibleTargetMemLocation::AARCH64_ZA); - else if (Name == "InaccessibleMem") - return llvm::IRMemLocation::InaccessibleMem; - else - PrintFatalError(getLoc(), "unknown IRMemLocation: " + Name); -} - int64_t Record::getValueAsInt(StringRef FieldName) const { const RecordVal *R = getValue(FieldName); if (!R || !R->getValue()) diff --git a/llvm/test/Assembler/memory-attribute.ll b/llvm/test/Assembler/memory-attribute.ll index 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 8e72e7ade54c1..8c1a76365e1b4 100644 --- a/llvm/test/Bitcode/attributes.ll +++ b/llvm/test/Bitcode/attributes.ll @@ -572,6 +572,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 eb2d4de7e9320..892ee5af58c24 100644 --- a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp +++ b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp @@ -375,13 +375,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 @@ -461,6 +461,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( + llvm::InaccessibleTargetMemLocation::AARCH64_FPMR); + else if (Name == "AArch64_ZA") + return static_cast( + 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 676f575b2749d..875b7c02b77b8 100644 --- a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.h +++ b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.h @@ -170,6 +170,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 3a576901cb382c96bb1c5d064d73d19dcc84e4e4 Mon Sep 17 00:00:00 2001 From: CarolineConcatto Date: Wed, 20 Aug 2025 10:55:30 +0000 Subject: [PATCH 07/10] 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 03e37fa36f8d545ac86f3d33a160306d1fc7efad Mon Sep 17 00:00:00 2001 From: CarolineConcatto Date: Thu, 21 Aug 2025 09:15:45 +0000 Subject: [PATCH 08/10] 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 2b500ed58d0d6..6886cd5e16ad6 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 #include #include @@ -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; @@ -457,7 +459,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 class MemoryEffectsBase { /// Whether this function only (at most) accesses inaccessible memory. bool onlyAccessesInaccessibleMem() const { return getWithoutLoc(static_cast( - llvm::InaccessibleTargetMemLocation::AARCH64_FPMR)) + llvm::InaccessibleTargetMemLocation::MEM_TARGET_0)) .getWithoutLoc(static_cast( - 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 657f4230379e8..82518212ea3ef 100644 --- a/llvm/include/llvm/TargetParser/Triple.h +++ b/llvm/include/llvm/TargetParser/Triple.h @@ -322,6 +322,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; @@ -1180,6 +1189,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 abde2993bb048..7d16372a09077 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -1676,10 +1676,10 @@ static std::optional keywordToLoc(lltok::Kind Tok) { return IRMemLocation::ErrnoMem; case lltok::kw_aarch64_fpmr: return static_cast( - llvm::InaccessibleTargetMemLocation::AARCH64_FPMR); + llvm::InaccessibleTargetMemLocation::MEM_TARGET_0); case lltok::kw_aarch64_za: return static_cast( - 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 145ef10f28f35..ad5c342d7be9f 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -2902,7 +2902,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); @@ -3173,7 +3173,7 @@ void AssemblyWriter::printModule(const Module *M) { // Output all attribute groups. if (!Machine.as_empty()) { Out << '\n'; - writeAllAttributeGroups(); + writeAllAttributeGroups(&M->getTargetTriple()); } // Output named metadata. @@ -4126,7 +4126,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); } } @@ -4973,8 +4973,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; } @@ -4997,7 +4998,7 @@ void AssemblyWriter::writeAttributeSet(const AttributeSet &AttrSet, } } -void AssemblyWriter::writeAllAttributeGroups() { +void AssemblyWriter::writeAllAttributeGroups(const Triple *TT) { std::vector> asVec; asVec.resize(Machine.as_size()); @@ -5006,7 +5007,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 37e9d7c5c74db..e28b3c358f47b 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(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(TargetLoc)); + if (TargetLoc == InaccessibleTargetMemLocation::MEM_TARGET_1) + OS << TT->getTargetMemLocName( + static_cast(TargetLoc)); + OS << ": "; break; } } @@ -1219,8 +1222,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 { @@ -1243,7 +1246,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 @@ -1415,12 +1418,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; } @@ -2011,7 +2015,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(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 0584c941d2e6e..73e7c2bd80229 100644 --- a/llvm/lib/TargetParser/Triple.cpp +++ b/llvm/lib/TargetParser/Triple.cpp @@ -2306,6 +2306,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 892ee5af58c24..8201554e05d51 100644 --- a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp +++ b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp @@ -468,10 +468,10 @@ CodeGenIntrinsic::getLocationTypeAsInt(const Record *R, StringRef Name = LocRec->getName(); if (Name == "AArch64_FPMR") return static_cast( - llvm::InaccessibleTargetMemLocation::AARCH64_FPMR); + llvm::InaccessibleTargetMemLocation::MEM_TARGET_0); else if (Name == "AArch64_ZA") return static_cast( - llvm::InaccessibleTargetMemLocation::AARCH64_ZA); + llvm::InaccessibleTargetMemLocation::MEM_TARGET_1); else if (Name == "InaccessibleMem") return llvm::IRMemLocation::InaccessibleMem; else From 213fe2b3eacf1de91990d708bf50552cab9afddc Mon Sep 17 00:00:00 2001 From: CarolineConcatto Date: Thu, 21 Aug 2025 14:59:23 +0000 Subject: [PATCH 09/10] 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(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 11acc4a13ea6f8f069b16a7e5cd3dd143965a6d7 Mon Sep 17 00:00:00 2001 From: CarolineConcatto Date: Thu, 21 Aug 2025 15:06:10 +0000 Subject: [PATCH 10/10] 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