[clang] [llvm] [mlir] [LLVM] Improve IR parsing and printing for target memory locations (PR #176968)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Jan 26 01:46:40 PST 2026
https://github.com/CarolineConcatto updated https://github.com/llvm/llvm-project/pull/176968
>From 3705eeb0605261f7946c744c273a27782fca1550 Mon Sep 17 00:00:00 2001
From: CarolineConcatto <caroline.concatto at arm.com>
Date: Wed, 3 Dec 2025 14:06:37 +0000
Subject: [PATCH 1/2] [LLVM] Improve IR parsing and printing for target memory
locations
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This patch adds support for specifying all target memory locations using a
single IR spellings such as:
```
memory(target_mem: read)
```
This form is not supported in TableGen, but it is now accepted by the IR parser.
When the parser encounters target_mem, it expands it to all target-memory
locations (e.g., target_mem0, target_mem1, …).
Printing behavior
When all target-memory locations share the same ModRef value, the printer
now collapses them into a single entry:
```
memory(target_mem: read)
```
Otherwise, each target memory location is printed separately.
Rejected IR:
memory(target_mem0: write, target_mem: read)
This is invalid because the default access kind for the target memory group
must appear first.
---
.../CodeGen/sanitize-metadata-nosanitize.c | 18 ++++----
clang/test/CodeGenOpenCL/convergent.cl | 2 +-
llvm/include/llvm/AsmParser/LLToken.h | 1 +
llvm/include/llvm/Support/ModRef.h | 22 +++++++++
llvm/lib/AsmParser/LLLexer.cpp | 1 +
llvm/lib/AsmParser/LLParser.cpp | 46 ++++++++++++++-----
llvm/lib/IR/Attributes.cpp | 14 +++++-
llvm/test/Assembler/memory-attribute.ll | 17 ++++++-
llvm/test/Bitcode/memory-attribute-upgrade.ll | 4 +-
.../Transforms/FunctionAttrs/argmemonly.ll | 22 ++++-----
.../Transforms/FunctionAttrs/nocapture.ll | 38 +++++++--------
.../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 | 10 ++--
mlir/test/Target/LLVMIR/llvmir.mlir | 10 ++--
18 files changed, 147 insertions(+), 72 deletions(-)
diff --git a/clang/test/CodeGen/sanitize-metadata-nosanitize.c b/clang/test/CodeGen/sanitize-metadata-nosanitize.c
index 74b5c9b03754f..db5121d37462f 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, target_mem0: none, target_mem1: none)
+// CHECK: Function Attrs: mustprogress nofree noinline norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none, target_mem: 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, target_mem0: none, target_mem1: none)
+// CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none, target_mem: 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, target_mem0: none, target_mem1: none)
+// CHECK: Function Attrs: disable_sanitizer_instrumentation mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none, target_mem: 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, target_mem0: none, target_mem1: none)
+// CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none, target_mem: 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, target_mem0: none, target_mem1: none)
+// CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none, target_mem: 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, 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 #[[ATTR0]] = { mustprogress nofree noinline norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none, target_mem: 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_mem: 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_mem: 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_mem: 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/clang/test/CodeGenOpenCL/convergent.cl b/clang/test/CodeGenOpenCL/convergent.cl
index 99d9ee74e669b..867c7c35a7dea 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 memory(readwrite, target_mem0: none, target_mem1: none) "
+// CHECK: attributes #0 = { nofree noinline norecurse nounwind memory(readwrite, target_mem: none) "
// CHECK: attributes #1 = { {{[^}]*}}convergent{{[^}]*}} }
// CHECK: attributes #2 = { {{[^}]*}}convergent{{[^}]*}} }
// CHECK: attributes #3 = { {{[^}]*}}convergent noduplicate{{[^}]*}} }
diff --git a/llvm/include/llvm/AsmParser/LLToken.h b/llvm/include/llvm/AsmParser/LLToken.h
index 24f84cfa09e34..89cdc5a39c11b 100644
--- a/llvm/include/llvm/AsmParser/LLToken.h
+++ b/llvm/include/llvm/AsmParser/LLToken.h
@@ -206,6 +206,7 @@ enum Kind {
kw_readwrite,
kw_argmem,
kw_inaccessiblemem,
+ kw_target_mem,
kw_target_mem0,
kw_target_mem1,
kw_errnomem,
diff --git a/llvm/include/llvm/Support/ModRef.h b/llvm/include/llvm/Support/ModRef.h
index 34f116e478966..7506f1d808ff4 100644
--- a/llvm/include/llvm/Support/ModRef.h
+++ b/llvm/include/llvm/Support/ModRef.h
@@ -240,6 +240,28 @@ template <typename LocationEnum> class MemoryEffectsBase {
return getWithoutLoc(Location::InaccessibleMem).doesNotAccessMemory();
}
+ bool isTargetMemLoc(IRMemLocation Loc) {
+ return static_cast<unsigned>(Loc) >=
+ static_cast<unsigned>(Location::FirstTarget);
+ }
+
+ // We need to check if target memory is the same for all locations.
+ // So it behaves the same as default read/write, but for Target
+ // locations only
+ bool targetMemSameForAll() {
+ std::optional<ModRefInfo> First;
+ for (unsigned ILoc = static_cast<unsigned>(IRMemLocation::FirstTarget);
+ ILoc <= static_cast<unsigned>(IRMemLocation::Last); ++ILoc) {
+ const auto Loc = static_cast<IRMemLocation>(ILoc);
+ ModRefInfo MR = getModRef(Loc);
+ if (!First)
+ First = MR;
+ else if (*First != MR)
+ return false;
+ }
+ return true;
+ }
+
/// Whether this function only (at most) accesses errno memory.
bool onlyAccessesErrnoMem() const {
return getWithoutLoc(Location::ErrnoMem).doesNotAccessMemory();
diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp
index 4e7e31da09a52..774ae040101a7 100644
--- a/llvm/lib/AsmParser/LLLexer.cpp
+++ b/llvm/lib/AsmParser/LLLexer.cpp
@@ -709,6 +709,7 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(argmem);
KEYWORD(target_mem0);
KEYWORD(target_mem1);
+ KEYWORD(target_mem);
KEYWORD(inaccessiblemem);
KEYWORD(errnomem);
KEYWORD(argmemonly);
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index 068b52fcf0995..273a59bdd3cd2 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -2568,18 +2568,30 @@ bool LLParser::parseAllocKind(AllocFnKind &Kind) {
return false;
}
-static std::optional<MemoryEffects::Location> keywordToLoc(lltok::Kind Tok) {
+static std::optional<SmallVector<MemoryEffects::Location, 2>>
+keywordToLoc(lltok::Kind Tok) {
+ using Loc = IRMemLocation;
+
switch (Tok) {
case lltok::kw_argmem:
- return IRMemLocation::ArgMem;
+ return SmallVector<Loc, 2>{Loc::ArgMem};
+
case lltok::kw_inaccessiblemem:
- return IRMemLocation::InaccessibleMem;
+ return SmallVector<Loc, 2>{Loc::InaccessibleMem};
+
case lltok::kw_errnomem:
- return IRMemLocation::ErrnoMem;
+ return SmallVector<Loc, 2>{Loc::ErrnoMem};
+
case lltok::kw_target_mem0:
- return IRMemLocation::TargetMem0;
+ return SmallVector<Loc, 2>{Loc::TargetMem0};
+
case lltok::kw_target_mem1:
- return IRMemLocation::TargetMem1;
+ return SmallVector<Loc, 2>{Loc::TargetMem1};
+
+ // In the case this represent all target memories
+ case lltok::kw_target_mem:
+ return SmallVector<Loc, 2>{Loc::TargetMem0, Loc::TargetMem1};
+
default:
return std::nullopt;
}
@@ -2615,9 +2627,11 @@ std::optional<MemoryEffects> LLParser::parseMemoryAttr() {
}
bool SeenLoc = false;
+ bool SeenTargetLoc = false;
do {
- std::optional<IRMemLocation> Loc = keywordToLoc(Lex.getKind());
- if (Loc) {
+ std::optional<SmallVector<IRMemLocation, 2>> Locs =
+ keywordToLoc(Lex.getKind());
+ if (Locs) {
Lex.Lex();
if (!EatIfPresent(lltok::colon)) {
tokError("expected ':' after location");
@@ -2627,7 +2641,7 @@ std::optional<MemoryEffects> LLParser::parseMemoryAttr() {
std::optional<ModRefInfo> MR = keywordToModRef(Lex.getKind());
if (!MR) {
- if (!Loc)
+ if (!Locs)
tokError("expected memory location (argmem, inaccessiblemem, errnomem) "
"or access kind (none, read, write, readwrite)");
else
@@ -2636,9 +2650,19 @@ std::optional<MemoryEffects> LLParser::parseMemoryAttr() {
}
Lex.Lex();
- if (Loc) {
+ if (Locs) {
SeenLoc = true;
- ME = ME.getWithModRef(*Loc, *MR);
+ for (IRMemLocation Loc : *Locs) {
+ ME = ME.getWithModRef(Loc, *MR);
+ SeenTargetLoc = (ME.isTargetMemLoc(Loc) && Locs->size() == 1)
+ ? true
+ : SeenTargetLoc;
+ }
+ if ((Locs->size() > 1) && SeenTargetLoc) {
+ tokError("target memory default access kind must be specified first");
+ return std::nullopt;
+ }
+
} else {
if (SeenLoc) {
tokError("default access kind must be specified first");
diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp
index 726a3d8dd906f..293c31465d7cb 100644
--- a/llvm/lib/IR/Attributes.cpp
+++ b/llvm/lib/IR/Attributes.cpp
@@ -653,15 +653,27 @@ std::string Attribute::getAsString(bool InAttrGrp) const {
OS << getModRefStr(OtherMR);
}
+ bool TargetPrintedForAll = false;
+ bool TargetMemSameForAll = ME.targetMemSameForAll();
for (auto Loc : MemoryEffects::locations()) {
ModRefInfo MR = ME.getModRef(Loc);
if (MR == OtherMR)
continue;
- if (!First)
+ if (!First && !TargetPrintedForAll)
OS << ", ";
First = false;
+ if (ME.isTargetMemLoc(Loc) && TargetMemSameForAll) {
+ if (!TargetPrintedForAll) {
+ OS << "target_mem: ";
+ OS << getModRefStr(MR);
+ TargetPrintedForAll = true;
+ }
+ // Only works while target memories are last to be listed in Location
+ continue;
+ }
+
switch (Loc) {
case IRMemLocation::ArgMem:
OS << "argmem: ";
diff --git a/llvm/test/Assembler/memory-attribute.ll b/llvm/test/Assembler/memory-attribute.ll
index 4c86f8df0e6c1..fd98384d90405 100644
--- a/llvm/test/Assembler/memory-attribute.ll
+++ b/llvm/test/Assembler/memory-attribute.ll
@@ -109,7 +109,7 @@ declare void @fn_read_target_mem0_write_mem_target1()
declare void @fn_inaccessiblemem_write_new()
memory(inaccessiblemem: write)
-; CHECK: Function Attrs: memory(inaccessiblemem: read, target_mem0: read, target_mem1: read)
+; CHECK: Function Attrs: memory(inaccessiblemem: read, target_mem: read)
; CHECK: @fn_inaccessiblemem_target_mem0_1read()
declare void @fn_inaccessiblemem_target_mem0_1read()
memory(inaccessiblemem: read, target_mem0: read, target_mem1: read)
@@ -133,3 +133,18 @@ declare void @fn_write_inaccessiblemem_write_target_mem0_read()
; CHECK: @fn_write_target_mem0_readwrite()
declare void @fn_write_target_mem0_readwrite()
memory(write, target_mem0: read)
+
+; CHECK: Function Attrs: memory(target_mem: read)
+; CHECK: @fn_write_target_mem
+declare void @fn_write_target_mem()
+ memory(target_mem: read)
+
+; CHECK: Function Attrs: memory(target_mem0: write, target_mem1: read)
+; CHECK: @fn_write_target_mem_read_write
+declare void @fn_write_target_mem_read_write()
+ memory(target_mem: read, target_mem0:write)
+
+; CHECK: Function Attrs: memory(readwrite, target_mem: read)
+; CHECK: @fn_all_readwrite
+declare void @fn_all_readwrite()
+ memory(readwrite, target_mem: read)
diff --git a/llvm/test/Bitcode/memory-attribute-upgrade.ll b/llvm/test/Bitcode/memory-attribute-upgrade.ll
index 334a344b96f7f..2d8eb12eaccf7 100644
--- a/llvm/test/Bitcode/memory-attribute-upgrade.ll
+++ b/llvm/test/Bitcode/memory-attribute-upgrade.ll
@@ -1,7 +1,7 @@
; RUN: llvm-dis < %S/Inputs/memory-attribute-upgrade.bc | FileCheck %s
-; CHECK: ; Function Attrs: memory(write, argmem: read, target_mem0: none, target_mem1: none)
+; CHECK: ; Function Attrs: memory(write, argmem: read, target_mem: none)
; CHECK-NEXT: define void @test_any_write_argmem_read(ptr %p)
-; CHECK: ; Function Attrs: memory(read, argmem: readwrite, inaccessiblemem: none, target_mem0: none, target_mem1: none)
+; CHECK: ; Function Attrs: memory(read, argmem: readwrite, inaccessiblemem: none, target_mem: none)
; CHECK-NEXT: define void @test_any_read_argmem_readwrite(ptr %p)
diff --git a/llvm/test/Transforms/FunctionAttrs/argmemonly.ll b/llvm/test/Transforms/FunctionAttrs/argmemonly.ll
index 4ff36c0dbdc3f..a821a21ecb496 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, target_mem0: none, target_mem1: none)
+; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(read, argmem: none, inaccessiblemem: none, target_mem: 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, target_mem0: none, target_mem1: none)
+; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(read, inaccessiblemem: none, target_mem: 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, target_mem0: none, target_mem1: none)
+; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none, target_mem: 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, target_mem0: none, target_mem1: none)
+; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(readwrite, inaccessiblemem: none, target_mem: 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, target_mem0: none, target_mem1: none)
+; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(readwrite, inaccessiblemem: none, target_mem: 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, target_mem0: none, target_mem1: none)
+; FNATTRS: Function Attrs: nofree nosync nounwind memory(read, inaccessiblemem: none, target_mem: 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, target_mem0: none, target_mem1: none)
+; FNATTRS: Function Attrs: nofree nosync nounwind memory(readwrite, inaccessiblemem: none, target_mem: 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, target_mem0: none, target_mem1: none)
+; FNATTRS: Function Attrs: nofree nosync nounwind memory(read, inaccessiblemem: none, target_mem: 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, target_mem0: none, target_mem1: none)
+; FNATTRS: Function Attrs: nofree nosync nounwind memory(read, inaccessiblemem: none, target_mem: 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, target_mem0: none, target_mem1: none)
+; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(read, inaccessiblemem: none, target_mem: 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, target_mem0: none, target_mem1: none)
+; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(read, inaccessiblemem: none, target_mem: 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 b5b14f571d47d..421ef601d0b85 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, target_mem0: none, target_mem1: none)
+; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none, target_mem: 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, target_mem0: none, target_mem1: none)
+; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write, inaccessiblemem: none, target_mem: 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, target_mem0: none, target_mem1: none)
+; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(read, argmem: none, inaccessiblemem: none, target_mem: 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, target_mem0: none, target_mem1: none)
+; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(read, inaccessiblemem: none, target_mem: 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, target_mem0: none, target_mem1: none)
+; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(readwrite, inaccessiblemem: none, target_mem: 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, target_mem0: none, target_mem1: none)
+; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(readwrite, inaccessiblemem: none, target_mem: 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, target_mem0: none, target_mem1: none)
+; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(readwrite, inaccessiblemem: none, target_mem: 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, target_mem0: none, target_mem1: none)
+; FNATTRS: Function Attrs: nofree nosync nounwind memory(write, argmem: none, inaccessiblemem: none, target_mem: 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, target_mem0: none, target_mem1: none)
+; FNATTRS: Function Attrs: nofree nosync nounwind memory(write, argmem: none, inaccessiblemem: none, target_mem: 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, target_mem0: none, target_mem1: none)
+; FNATTRS: Function Attrs: nofree nosync nounwind memory(write, argmem: none, inaccessiblemem: none, target_mem: 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, target_mem0: none, target_mem1: none)
+; FNATTRS: Function Attrs: nofree nosync nounwind memory(write, argmem: none, inaccessiblemem: none, target_mem: 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, target_mem0: none, target_mem1: none)
+; FNATTRS: Function Attrs: nofree nosync nounwind memory(write, argmem: none, inaccessiblemem: none, target_mem: 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, target_mem0: none, target_mem1: none)
+; FNATTRS: Function Attrs: nofree nosync nounwind memory(write, argmem: none, inaccessiblemem: none, target_mem: 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:%.*]]
@@ -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, target_mem0: none, target_mem1: none)
+; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: readwrite, target_mem: 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]])
@@ -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, target_mem0: none, target_mem1: none)
+; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none, target_mem: 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, target_mem0: none, target_mem1: none)
+; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none, target_mem: 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, target_mem0: none, target_mem1: none)
+; FNATTRS: Function Attrs: nofree nosync nounwind memory(write, argmem: none, inaccessiblemem: none, target_mem: 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, target_mem0: none, target_mem1: none)
+; FNATTRS: Function Attrs: nofree nosync nounwind memory(write, argmem: read, inaccessiblemem: none, target_mem: 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, target_mem0: none, target_mem1: none)
+; FNATTRS: Function Attrs: nofree nosync nounwind memory(write, argmem: read, inaccessiblemem: none, target_mem: 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 1fc0084203fca..36baf6be754c9 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, target_mem0: none, target_mem1: none)
+; CHECK: Function Attrs: nofree nosync nounwind memory(readwrite, argmem: none, inaccessiblemem: none, target_mem: 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, target_mem0: none, target_mem1: none)
+; CHECK: Function Attrs: nofree nosync nounwind memory(readwrite, argmem: none, inaccessiblemem: none, target_mem: 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 8fc72a1ab90b9..ce56e436ce075 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, target_mem0: none, target_mem1: none)
+; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none, target_mem: 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 05ecb12c710ee..e00ed9e0f2293 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, target_mem0: none, target_mem1: none)
+; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none, target_mem: 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, target_mem0: none, target_mem1: none)
+; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(readwrite, argmem: read, inaccessiblemem: none, target_mem: 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 89a09406e5f1d..0a0fdc0d4d42a 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, target_mem0: none, target_mem1: none) }
+; CHECK: attributes #0 = { mustprogress nofree norecurse nosync nounwind willreturn memory(readwrite, argmem: write, inaccessiblemem: none, target_mem: 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 89c32fab54a4c..7d36014fb2d0a 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, target_mem0: none, target_mem1: none)
+; CHECK: Function Attrs: minsize mustprogress nofree norecurse nosync nounwind optsize willreturn memory(write, argmem: none, inaccessiblemem: none, target_mem: 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 6a64dc3cddd39..4e7597e930207 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, target_mem0: none, target_mem1: none)
+; CHECK: Function Attrs: nounwind memory(readwrite, inaccessiblemem: none, target_mem: none)
; CHECK-LABEL: @ptrarg.1(
; CHECK-NEXT: store i32 10, ptr @g, align 4
; CHECK-NEXT: ret void
@@ -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, target_mem0: none, target_mem1: none)
+; CHECK: Function Attrs: nounwind memory(readwrite, target_mem: none)
; CHECK-LABEL: @ptrarg.3(
; 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, target_mem0: none, target_mem1: none)
+; CHECK: Function Attrs: nounwind memory(readwrite, inaccessiblemem: none, target_mem: none)
; CHECK-LABEL: @ptrarg.5(
; CHECK-NEXT: store i32 10, ptr @g, align 4
; CHECK-NEXT: ret void
@@ -163,9 +163,9 @@ define i32 @caller.6.cs.attributes(i32 %n) {
}
;.
-; CHECK: attributes #[[ATTR0]] = { nounwind memory(readwrite, inaccessiblemem: none, target_mem0: none, target_mem1: none) }
+; CHECK: attributes #[[ATTR0]] = { nounwind memory(readwrite, inaccessiblemem: none, target_mem: none) }
; CHECK: attributes #[[ATTR1:[0-9]+]] = { nounwind memory(argmem: readwrite) }
-; CHECK: attributes #[[ATTR2]] = { nounwind memory(readwrite, target_mem0: none, target_mem1: none) }
+; CHECK: attributes #[[ATTR2]] = { nounwind memory(readwrite, target_mem: none) }
; CHECK: attributes #[[ATTR3:[0-9]+]] = { nounwind memory(argmem: readwrite, inaccessiblemem: readwrite) }
; CHECK: attributes #[[ATTR4]] = { nounwind }
;.
diff --git a/mlir/test/Target/LLVMIR/llvmir.mlir b/mlir/test/Target/LLVMIR/llvmir.mlir
index 819a514bc8b7e..0d58bb6108696 100644
--- a/mlir/test/Target/LLVMIR/llvmir.mlir
+++ b/mlir/test/Target/LLVMIR/llvmir.mlir
@@ -2376,7 +2376,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, errnoMem = none, targetMem0 = none, targetMem1 = none>}
-// CHECK: attributes #[[ATTR]] = { memory(readwrite, argmem: none, errnomem: none, target_mem0: none, target_mem1: none) }
+// CHECK: attributes #[[ATTR]] = { memory(readwrite, argmem: none, errnomem: none, target_mem: none) }
// -----
@@ -2384,7 +2384,7 @@ llvm.func @arg_mem_none_func() attributes {
llvm.func @readwrite_func() attributes {
memory_effects = #llvm.memory_effects<other = readwrite, argMem = readwrite, inaccessibleMem = readwrite, errnoMem = none, targetMem0 = none, targetMem1 = none>}
-// CHECK: attributes #[[ATTR]] = { memory(readwrite, errnomem: none, target_mem0: none, target_mem1: none) }
+// CHECK: attributes #[[ATTR]] = { memory(readwrite, errnomem: none, target_mem: none) }
// -----
@@ -2737,11 +2737,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, target_mem0: none, target_mem1: none)
+// CHECK-SAME: memory(read, argmem: none, inaccessiblemem: write, errnomem: none, target_mem: none)
// CHECK: #[[ATTRS_2]]
-// CHECK-SAME: memory(read, inaccessiblemem: write, errnomem: none, target_mem0: none, target_mem1: none)
+// CHECK-SAME: memory(read, inaccessiblemem: write, errnomem: none, target_mem: none)
// CHECK: #[[ATTRS_3]]
-// CHECK-SAME: memory(readwrite, argmem: read, errnomem: none, target_mem0: none, target_mem1: none)
+// CHECK-SAME: memory(readwrite, argmem: read, errnomem: none, target_mem: none)
// -----
>From e8caa19cbbc6208abe0d97c3a3fee4ef56957af2 Mon Sep 17 00:00:00 2001
From: CarolineConcatto <caroline.concatto at arm.com>
Date: Fri, 23 Jan 2026 17:32:15 +0000
Subject: [PATCH 2/2] Address comments
---
llvm/include/llvm/Support/ModRef.h | 16 ++++----
llvm/lib/AsmParser/LLParser.cpp | 41 ++++++++++---------
llvm/lib/IR/Attributes.cpp | 5 +--
.../GlobalOpt/disable-globals-aa.ll | 8 ++--
4 files changed, 35 insertions(+), 35 deletions(-)
diff --git a/llvm/include/llvm/Support/ModRef.h b/llvm/include/llvm/Support/ModRef.h
index 7506f1d808ff4..7b637c78a2b9c 100644
--- a/llvm/include/llvm/Support/ModRef.h
+++ b/llvm/include/llvm/Support/ModRef.h
@@ -240,23 +240,21 @@ template <typename LocationEnum> class MemoryEffectsBase {
return getWithoutLoc(Location::InaccessibleMem).doesNotAccessMemory();
}
- bool isTargetMemLoc(IRMemLocation Loc) {
+ bool isTargetMemLoc(IRMemLocation Loc) const {
return static_cast<unsigned>(Loc) >=
static_cast<unsigned>(Location::FirstTarget);
}
- // We need to check if target memory is the same for all locations.
- // So it behaves the same as default read/write, but for Target
+ // Whether the target memory locations are all the same.
+ // So it behaves as the default read/write, but for Target
// locations only
- bool targetMemSameForAll() {
- std::optional<ModRefInfo> First;
- for (unsigned ILoc = static_cast<unsigned>(IRMemLocation::FirstTarget);
+ bool isTargetMemLocSameForAll() const {
+ ModRefInfo First = getModRef(IRMemLocation::FirstTarget);
+ for (unsigned ILoc = static_cast<unsigned>(IRMemLocation::FirstTarget) + 1;
ILoc <= static_cast<unsigned>(IRMemLocation::Last); ++ILoc) {
const auto Loc = static_cast<IRMemLocation>(ILoc);
ModRefInfo MR = getModRef(Loc);
- if (!First)
- First = MR;
- else if (*First != MR)
+ if (First != MR)
return false;
}
return true;
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index 273a59bdd3cd2..9cb9adf2c9c21 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -2568,32 +2568,37 @@ bool LLParser::parseAllocKind(AllocFnKind &Kind) {
return false;
}
-static std::optional<SmallVector<MemoryEffects::Location, 2>>
-keywordToLoc(lltok::Kind Tok) {
+static ArrayRef<IRMemLocation> keywordToLoc(lltok::Kind Tok) {
using Loc = IRMemLocation;
+ static constexpr Loc ArgMem[] = {Loc::ArgMem};
+ static constexpr Loc InaccessibleMem[] = {Loc::InaccessibleMem};
+ static constexpr Loc ErrnoMem[] = {Loc::ErrnoMem};
+ static constexpr Loc TargetMem0[] = {Loc::TargetMem0};
+ static constexpr Loc TargetMem1[] = {Loc::TargetMem1};
+ static constexpr Loc TargetMem[] = {Loc::TargetMem0, Loc::TargetMem1};
switch (Tok) {
case lltok::kw_argmem:
- return SmallVector<Loc, 2>{Loc::ArgMem};
+ return ArgMem;
case lltok::kw_inaccessiblemem:
- return SmallVector<Loc, 2>{Loc::InaccessibleMem};
+ return InaccessibleMem;
case lltok::kw_errnomem:
- return SmallVector<Loc, 2>{Loc::ErrnoMem};
+ return ErrnoMem;
case lltok::kw_target_mem0:
- return SmallVector<Loc, 2>{Loc::TargetMem0};
+ return TargetMem0;
case lltok::kw_target_mem1:
- return SmallVector<Loc, 2>{Loc::TargetMem1};
+ return TargetMem1;
// In the case this represent all target memories
case lltok::kw_target_mem:
- return SmallVector<Loc, 2>{Loc::TargetMem0, Loc::TargetMem1};
+ return TargetMem;
default:
- return std::nullopt;
+ return {};
}
}
@@ -2629,9 +2634,8 @@ std::optional<MemoryEffects> LLParser::parseMemoryAttr() {
bool SeenLoc = false;
bool SeenTargetLoc = false;
do {
- std::optional<SmallVector<IRMemLocation, 2>> Locs =
- keywordToLoc(Lex.getKind());
- if (Locs) {
+ llvm::ArrayRef<llvm::IRMemLocation> Locs = keywordToLoc(Lex.getKind());
+ if (!Locs.empty()) {
Lex.Lex();
if (!EatIfPresent(lltok::colon)) {
tokError("expected ':' after location");
@@ -2641,7 +2645,7 @@ std::optional<MemoryEffects> LLParser::parseMemoryAttr() {
std::optional<ModRefInfo> MR = keywordToModRef(Lex.getKind());
if (!MR) {
- if (!Locs)
+ if (Locs.empty())
tokError("expected memory location (argmem, inaccessiblemem, errnomem) "
"or access kind (none, read, write, readwrite)");
else
@@ -2650,15 +2654,14 @@ std::optional<MemoryEffects> LLParser::parseMemoryAttr() {
}
Lex.Lex();
- if (Locs) {
+ if (!Locs.empty()) {
SeenLoc = true;
- for (IRMemLocation Loc : *Locs) {
+ for (const llvm::IRMemLocation &Loc : Locs) {
ME = ME.getWithModRef(Loc, *MR);
- SeenTargetLoc = (ME.isTargetMemLoc(Loc) && Locs->size() == 1)
- ? true
- : SeenTargetLoc;
+ if (ME.isTargetMemLoc(Loc) && Locs.size() == 1)
+ SeenTargetLoc = true;
}
- if ((Locs->size() > 1) && SeenTargetLoc) {
+ if (Locs.size() > 1 && SeenTargetLoc) {
tokError("target memory default access kind must be specified first");
return std::nullopt;
}
diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp
index 293c31465d7cb..399dea4b11124 100644
--- a/llvm/lib/IR/Attributes.cpp
+++ b/llvm/lib/IR/Attributes.cpp
@@ -654,7 +654,6 @@ std::string Attribute::getAsString(bool InAttrGrp) const {
}
bool TargetPrintedForAll = false;
- bool TargetMemSameForAll = ME.targetMemSameForAll();
for (auto Loc : MemoryEffects::locations()) {
ModRefInfo MR = ME.getModRef(Loc);
if (MR == OtherMR)
@@ -664,13 +663,13 @@ std::string Attribute::getAsString(bool InAttrGrp) const {
OS << ", ";
First = false;
- if (ME.isTargetMemLoc(Loc) && TargetMemSameForAll) {
+ if (ME.isTargetMemLoc(Loc) && ME.isTargetMemLocSameForAll()) {
if (!TargetPrintedForAll) {
OS << "target_mem: ";
OS << getModRefStr(MR);
TargetPrintedForAll = true;
}
- // Only works while target memories are last to be listed in Location
+ // Only works when target memories are last to be listed in Location.
continue;
}
diff --git a/llvm/test/Transforms/GlobalOpt/disable-globals-aa.ll b/llvm/test/Transforms/GlobalOpt/disable-globals-aa.ll
index ce1a3d39d764e..df620416154d7 100644
--- a/llvm/test/Transforms/GlobalOpt/disable-globals-aa.ll
+++ b/llvm/test/Transforms/GlobalOpt/disable-globals-aa.ll
@@ -44,11 +44,11 @@ define i8 @dummy() !prof !0 {
!0 = !{!"function_entry_count", i32 10}
;.
-; WITHGLOBALSAA: attributes #[[ATTR0:[0-9]+]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(write, inaccessiblemem: none, target_mem0: none, target_mem1: none) }
-; WITHGLOBALSAA: attributes #[[ATTR1:[0-9]+]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(read, argmem: none, inaccessiblemem: none, target_mem0: none, target_mem1: none) }
+; WITHGLOBALSAA: attributes #[[ATTR0:[0-9]+]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(write, inaccessiblemem: none, target_mem: none) }
+; WITHGLOBALSAA: attributes #[[ATTR1:[0-9]+]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(read, argmem: none, inaccessiblemem: none, target_mem: none) }
;.
-; NOGLOBALSAA: attributes #[[ATTR0:[0-9]+]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none, target_mem0: none, target_mem1: none) }
-; NOGLOBALSAA: attributes #[[ATTR1:[0-9]+]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(read, argmem: none, inaccessiblemem: none, target_mem0: none, target_mem1: none) }
+; NOGLOBALSAA: attributes #[[ATTR0:[0-9]+]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none, target_mem: none) }
+; NOGLOBALSAA: attributes #[[ATTR1:[0-9]+]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(read, argmem: none, inaccessiblemem: none, target_mem: none) }
;.
; WITHGLOBALSAA: [[META0:![0-9]+]] = !{!"function_entry_count", i32 10}
; WITHGLOBALSAA: [[PROF1]] = !{!"unknown", !"globalopt"}
More information about the cfe-commits
mailing list