[LLVM] Improve IR parsing and printing for target memory locations (#176968)

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.
This commit is contained in:
CarolineConcatto 2026-03-19 17:29:54 +00:00 committed by GitHub
parent 467cf7caed
commit d96722b660
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 151 additions and 78 deletions

View File

@ -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 [[META5:![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 [[META7:![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 [[META13:![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 [[META13]] {
// 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]+]] = !{!"{{.*}}clang version {{.*}}"}

View File

@ -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 norecurse nounwind{{[^}]*}} }
// CHECK: attributes #2 = { convergent nounwind{{[^}]*}} }
// CHECK: attributes #3 = { convergent noduplicate nounwind{{[^}]*}} }

View File

@ -207,6 +207,7 @@ enum Kind {
kw_readwrite,
kw_argmem,
kw_inaccessiblemem,
kw_target_mem,
kw_target_mem0,
kw_target_mem1,
kw_errnomem,

View File

@ -102,7 +102,7 @@ public:
return enum_seq_inclusive(Location::First, Location::Last,
force_iteration_on_noniterable_enum);
}
/// Returns iterator over all target location kinds
static auto targetMemLocations() {
return enum_seq_inclusive(Location::TargetMem0, Location::TargetMem1,
force_iteration_on_noniterable_enum);
@ -275,6 +275,26 @@ public:
return ME.getWithoutLoc(Location::InaccessibleMem).doesNotAccessMemory();
}
/// Whether location is target memory location.
bool isTargetMemLoc(IRMemLocation Loc) const {
for (auto L : targetMemLocations())
if (Loc == L)
return true;
return false;
}
/// Whether the target memory locations are all the same.
/// So it behaves as the default read/write, but for Target
/// locations only.
bool isTargetMemLocSameForAll() const {
ModRefInfo Expected = getModRef(IRMemLocation::TargetMem0);
for (auto Loc : targetMemLocations()) {
if (Expected != getModRef(Loc))
return false;
}
return true;
}
/// Whether this function only (at most) accesses errno memory.
bool onlyAccessesErrnoMem() const {
return getWithoutLoc(Location::ErrnoMem).doesNotAccessMemory();

View File

@ -722,6 +722,7 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(argmem);
KEYWORD(target_mem0);
KEYWORD(target_mem1);
KEYWORD(target_mem);
KEYWORD(inaccessiblemem);
KEYWORD(errnomem);
KEYWORD(argmemonly);

View File

@ -2609,20 +2609,28 @@ bool LLParser::parseAllocKind(AllocFnKind &Kind) {
return false;
}
static std::optional<MemoryEffects::Location> keywordToLoc(lltok::Kind Tok) {
static SmallVector<MemoryEffects::Location, 2> keywordToLoc(lltok::Kind Tok) {
using Loc = IRMemLocation;
switch (Tok) {
case lltok::kw_argmem:
return IRMemLocation::ArgMem;
return {Loc::ArgMem};
case lltok::kw_inaccessiblemem:
return IRMemLocation::InaccessibleMem;
return {Loc::InaccessibleMem};
case lltok::kw_errnomem:
return IRMemLocation::ErrnoMem;
return {Loc::ErrnoMem};
case lltok::kw_target_mem0:
return IRMemLocation::TargetMem0;
return {Loc::TargetMem0};
case lltok::kw_target_mem1:
return IRMemLocation::TargetMem1;
return {Loc::TargetMem1};
case lltok::kw_target_mem: {
SmallVector<MemoryEffects::Location, 2> Targets;
for (auto Loc : MemoryEffects::targetMemLocations())
Targets.push_back(Loc);
return Targets;
}
default:
return std::nullopt;
return {};
}
}
@ -2672,9 +2680,10 @@ std::optional<MemoryEffects> LLParser::parseMemoryAttr() {
}
bool SeenLoc = false;
bool SeenTargetLoc = false;
do {
std::optional<IRMemLocation> Loc = keywordToLoc(Lex.getKind());
if (Loc) {
SmallVector<IRMemLocation, 2> Locs = keywordToLoc(Lex.getKind());
if (!Locs.empty()) {
Lex.Lex();
if (!EatIfPresent(lltok::colon)) {
tokError("expected ':' after location");
@ -2684,7 +2693,7 @@ std::optional<MemoryEffects> LLParser::parseMemoryAttr() {
std::optional<ModRefInfo> MR = keywordToModRef(Lex.getKind());
if (!MR) {
if (!Loc)
if (Locs.empty())
tokError("expected memory location (argmem, inaccessiblemem, errnomem) "
"or access kind (none, read, write, readwrite)");
else
@ -2693,9 +2702,18 @@ std::optional<MemoryEffects> LLParser::parseMemoryAttr() {
}
Lex.Lex();
if (Loc) {
if (!Locs.empty()) {
SeenLoc = true;
ME = ME.getWithModRef(*Loc, *MR);
for (IRMemLocation Loc : Locs) {
ME = ME.getWithModRef(Loc, *MR);
if (ME.isTargetMemLoc(Loc) && Locs.size() == 1)
SeenTargetLoc = true;
}
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");

View File

@ -657,15 +657,29 @@ std::string Attribute::getAsString(bool InAttrGrp) const {
OS << getModRefStr(OtherMR);
}
bool TargetPrintedForAll = false;
for (auto Loc : MemoryEffects::locations()) {
ModRefInfo MR = ME.getModRef(Loc);
if (MR == OtherMR)
continue;
if (!First)
if (!First && !TargetPrintedForAll)
OS << ", ";
First = false;
// isTargetMemLocSameForAll is fine for target location < 3
// If more targets are added it should do something like:
// memory(target_mem:read, target_mem3:none, target_mem5:write).
if (ME.isTargetMemLoc(Loc) && ME.isTargetMemLocSameForAll()) {
if (!TargetPrintedForAll) {
OS << "target_mem: ";
OS << getModRefStr(MR);
TargetPrintedForAll = true;
}
// Only works when target memories are last to be listed in Location.
continue;
}
switch (Loc) {
case IRMemLocation::ArgMem:
OS << "argmem: ";

View File

@ -7,6 +7,7 @@
; RUN: not llvm-as < %t/missing-colon.ll 2>&1 | FileCheck %s --check-prefix=MISSING-COLON
; RUN: not llvm-as < %t/invalid-access-kind.ll 2>&1 | FileCheck %s --check-prefix=INVALID-ACCESS-KIND
; RUN: not llvm-as < %t/default-after-loc.ll 2>&1 | FileCheck %s --check-prefix=DEFAULT-AFTER-LOC
; RUN: not llvm-as < %t/default-after-target-loc.ll 2>&1 | FileCheck %s --check-prefix=DEFAULT-AFTER-TARGET-LOC
;--- missing-args.ll
; MISSING-ARGS: error: expected '('
@ -32,3 +33,6 @@ declare void @fn() memory(argmem: foo)
;--- default-after-loc.ll
; DEFAULT-AFTER-LOC: error: default access kind must be specified first
declare void @fn() memory(argmem: read, write)
;--- default-after-target-loc.ll
; DEFAULT-AFTER-TARGET-LOC: error: target memory default access kind must be specified first
declare void @fn() memory(target_mem0: read, target_mem:write)

View File

@ -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)

View File

@ -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)

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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"}

View File

@ -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

View File

@ -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:

View File

@ -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 }
;.

View File

@ -2394,7 +2394,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) }
// -----
@ -2402,7 +2402,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) }
// -----
@ -3165,11 +3165,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)
// -----