llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-mlir Author: Antonio Frighetto (antoniofrighetto) <details> <summary>Changes</summary> Mark C standard library functions that set `errno` as such, as included in the POSIX specification. Likewise, while deducing function attributes, determine whether a memory access affects errno memory (this possibly should leverage Loc.TBAAErrno in upcoming PR). Rebased on: #<!-- -->120783. --- Patch is 109.86 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/124742.diff 29 Files Affected: - (modified) clang/test/CodeGen/sanitize-metadata-nosanitize.c (+9-9) - (modified) clang/test/CodeGenOpenCL/convergent.cl (+1-1) - (modified) llvm/include/llvm/AsmParser/LLToken.h (+4) - (modified) llvm/include/llvm/Bitcode/LLVMBitCodes.h (+3) - (modified) llvm/include/llvm/IR/Function.h (+15) - (modified) llvm/include/llvm/IR/InstrTypes.h (+15) - (modified) llvm/include/llvm/Support/ModRef.h (+56-1) - (modified) llvm/lib/AsmParser/LLLexer.cpp (+4) - (modified) llvm/lib/AsmParser/LLParser.cpp (+12-1) - (modified) llvm/lib/Bitcode/Reader/BitcodeReader.cpp (+28) - (modified) llvm/lib/IR/Attributes.cpp (+3) - (modified) llvm/lib/IR/Function.cpp (+29) - (modified) llvm/lib/IR/Instructions.cpp (+29) - (modified) llvm/lib/Support/ModRef.cpp (+3) - (modified) llvm/lib/Transforms/IPO/FunctionAttrs.cpp (+12) - (modified) llvm/lib/Transforms/Utils/BuildLibCalls.cpp (+82-16) - (modified) llvm/test/Assembler/memory-attribute-errors.ll (+3-3) - (modified) llvm/test/Assembler/memory-attribute.ll (+12) - (modified) llvm/test/Transforms/FunctionAttrs/argmemonly.ll (+11-11) - (modified) llvm/test/Transforms/FunctionAttrs/nocapture.ll (+15-15) - (modified) llvm/test/Transforms/FunctionAttrs/read-write-scc.ll (+2-2) - (modified) llvm/test/Transforms/FunctionAttrs/readattrs.ll (+1-1) - (modified) llvm/test/Transforms/FunctionAttrs/writeonly.ll (+2-2) - (modified) llvm/test/Transforms/InferFunctionAttrs/annotate.ll (+96-93) - (modified) llvm/test/Transforms/InferFunctionAttrs/norecurse_debug.ll (+1-1) - (modified) llvm/test/Transforms/LowerTypeTests/cfi-nounwind-direct-call.ll (+1-1) - (modified) llvm/test/Transforms/SCCP/ipscp-drop-argmemonly.ll (+6-6) - (modified) llvm/unittests/Support/ModRefTest.cpp (+2-2) - (modified) mlir/test/Target/LLVMIR/llvmir.mlir (+5-5) ``````````diff diff --git a/clang/test/CodeGen/sanitize-metadata-nosanitize.c b/clang/test/CodeGen/sanitize-metadata-nosanitize.c index fd2fdce31b52fb..77dc7d9d492ecc 100644 --- a/clang/test/CodeGen/sanitize-metadata-nosanitize.c +++ b/clang/test/CodeGen/sanitize-metadata-nosanitize.c @@ -10,7 +10,7 @@ // CHECK: @llvm.global_ctors = appending global [2 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 2, ptr @__sanitizer_metadata_covered2.module_ctor, ptr @__sanitizer_metadata_covered2.module_ctor }, { i32, ptr, ptr } { i32 2, ptr @__sanitizer_metadata_atomics2.module_ctor, ptr @__sanitizer_metadata_atomics2.module_ctor }] // CHECK: @llvm.global_dtors = appending global [2 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 2, ptr @__sanitizer_metadata_covered2.module_dtor, ptr @__sanitizer_metadata_covered2.module_dtor }, { i32, ptr, ptr } { i32 2, ptr @__sanitizer_metadata_atomics2.module_dtor, ptr @__sanitizer_metadata_atomics2.module_dtor }] //. -// CHECK: Function Attrs: mustprogress nofree noinline norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none) +// CHECK: Function Attrs: mustprogress nofree noinline norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none, errnomem: none) // CHECK-LABEL: define dso_local void @escape // CHECK-SAME: (ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] !pcsections [[META2:![0-9]+]] { // CHECK-NEXT: entry: @@ -21,7 +21,7 @@ __attribute__((noinline, not_tail_called)) void escape(const volatile void *p) { sink = p; } -// CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none) +// CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none, errnomem: none) // CHECK-LABEL: define dso_local i32 @normal_function // CHECK-SAME: (ptr noundef [[X:%.*]], ptr nocapture noundef readonly [[Y:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] !pcsections [[META4:![0-9]+]] { // CHECK-NEXT: entry: @@ -38,7 +38,7 @@ int normal_function(int *x, int *y) { return *y; } -// CHECK: Function Attrs: disable_sanitizer_instrumentation mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none) +// CHECK: Function Attrs: disable_sanitizer_instrumentation mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none, errnomem: none) // CHECK-LABEL: define dso_local i32 @test_disable_sanitize_instrumentation // CHECK-SAME: (ptr noundef [[X:%.*]], ptr nocapture noundef readonly [[Y:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] { // CHECK-NEXT: entry: @@ -55,7 +55,7 @@ __attribute__((disable_sanitizer_instrumentation)) int test_disable_sanitize_ins return *y; } -// CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none) +// CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none, errnomem: none) // CHECK-LABEL: define dso_local i32 @test_no_sanitize_thread // CHECK-SAME: (ptr noundef [[X:%.*]], ptr nocapture noundef readonly [[Y:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] !pcsections [[META14:![0-9]+]] { // CHECK-NEXT: entry: @@ -72,7 +72,7 @@ __attribute__((no_sanitize("thread"))) int test_no_sanitize_thread(int *x, int * return *y; } -// CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none) +// CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none, errnomem: none) // CHECK-LABEL: define dso_local i32 @test_no_sanitize_all // CHECK-SAME: (ptr noundef [[X:%.*]], ptr nocapture noundef readonly [[Y:%.*]]) local_unnamed_addr #[[ATTR3]] !pcsections [[META14]] { // CHECK-NEXT: entry: @@ -89,10 +89,10 @@ __attribute__((no_sanitize("all"))) int test_no_sanitize_all(int *x, int *y) { return *y; } //. -// CHECK: attributes #[[ATTR0]] = { mustprogress nofree noinline norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none) "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" } -// CHECK: attributes #[[ATTR1]] = { mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none) "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" } -// CHECK: attributes #[[ATTR2]] = { disable_sanitizer_instrumentation mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none) "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" } -// CHECK: attributes #[[ATTR3]] = { mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none) "min-legal-vector-width"="0" "no-trapping-math"="true" "no_sanitize_thread" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" } +// CHECK: attributes #[[ATTR0]] = { mustprogress nofree noinline norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none, errnomem: 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, errnomem: 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, errnomem: 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, errnomem: 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 123adba7b40d2c..d64915205aabf6 100644 --- a/clang/test/CodeGenOpenCL/convergent.cl +++ b/clang/test/CodeGenOpenCL/convergent.cl @@ -133,7 +133,7 @@ kernel void assume_convergent_asm() __asm__ volatile("s_barrier"); } -// CHECK: attributes #0 = { nofree noinline norecurse nounwind " +// CHECK: attributes #0 = { nofree noinline norecurse nounwind memory(readwrite, errnomem: 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 7b47bc88ddb25f..e36ebcb0f13b08 100644 --- a/llvm/include/llvm/AsmParser/LLToken.h +++ b/llvm/include/llvm/AsmParser/LLToken.h @@ -201,11 +201,15 @@ enum Kind { kw_readwrite, kw_argmem, kw_inaccessiblemem, + kw_errnomem, // Legacy memory attributes: kw_argmemonly, kw_inaccessiblememonly, kw_inaccessiblemem_or_argmemonly, + kw_inaccessiblemem_or_errnomemonly, + kw_inaccessiblemem_or_argmem_or_errnomemonly, + kw_errnomemonly, // Captures attribute: kw_address, diff --git a/llvm/include/llvm/Bitcode/LLVMBitCodes.h b/llvm/include/llvm/Bitcode/LLVMBitCodes.h index 9eb38c3e448291..4d4911932fb181 100644 --- a/llvm/include/llvm/Bitcode/LLVMBitCodes.h +++ b/llvm/include/llvm/Bitcode/LLVMBitCodes.h @@ -789,6 +789,9 @@ enum AttributeKindCodes { ATTR_KIND_NO_DIVERGENCE_SOURCE = 100, ATTR_KIND_SANITIZE_TYPE = 101, ATTR_KIND_CAPTURES = 102, + ATTR_KIND_ERRNOMEMONLY = 103, + ATTR_KIND_INACCESSIBLEMEM_OR_ERRNOMEMONLY = 104, + ATTR_KIND_INACCESSIBLEMEM_OR_ARGMEM_OR_ERRNOMEMONLY = 105, }; enum ComdatSelectionKindCodes { diff --git a/llvm/include/llvm/IR/Function.h b/llvm/include/llvm/IR/Function.h index e7afcbd31420c1..847b8367743234 100644 --- a/llvm/include/llvm/IR/Function.h +++ b/llvm/include/llvm/IR/Function.h @@ -575,11 +575,26 @@ class LLVM_ABI Function : public GlobalObject, public ilist_node<Function> { bool onlyAccessesInaccessibleMemory() const; void setOnlyAccessesInaccessibleMemory(); + /// Determine if the function may only access errno memory. + bool onlyAccessesErrnoMemory() const; + void setOnlyAccessesErrnoMemory(); + /// Determine if the function may only access memory that is /// either inaccessible from the IR or pointed to by its arguments. bool onlyAccessesInaccessibleMemOrArgMem() const; void setOnlyAccessesInaccessibleMemOrArgMem(); + /// Determine if the function may only access memory that is + /// either inaccessible from the IR or errno memory. + bool onlyAccessesInaccessibleMemOrErrnoMem() const; + void setOnlyAccessesInaccessibleMemOrErrnoMem(); + + /// Determine if the function may only access memory that is + /// either inaccessible from the IR, pointed to by its arguments, or errno + /// memory. + bool onlyAccessesInaccessibleMemOrArgMemOrErrnoMem() const; + void setOnlyAccessesInaccessibleMemOrArgMemOrErrnoMem(); + /// Determine if the function cannot return. bool doesNotReturn() const { return hasFnAttribute(Attribute::NoReturn); diff --git a/llvm/include/llvm/IR/InstrTypes.h b/llvm/include/llvm/IR/InstrTypes.h index 47ddc7555594c5..5ef72e09292f3a 100644 --- a/llvm/include/llvm/IR/InstrTypes.h +++ b/llvm/include/llvm/IR/InstrTypes.h @@ -1909,11 +1909,26 @@ class CallBase : public Instruction { bool onlyAccessesInaccessibleMemory() const; void setOnlyAccessesInaccessibleMemory(); + /// Determine if the function may only access errno memory. + bool onlyAccessesErrnoMemory() const; + void setOnlyAccessesErrnoMemory(); + /// Determine if the function may only access memory that is /// either inaccessible from the IR or pointed to by its arguments. bool onlyAccessesInaccessibleMemOrArgMem() const; void setOnlyAccessesInaccessibleMemOrArgMem(); + /// Determine if the function may only access memory that is + /// either inaccessible from the IR or errno memory. + bool onlyAccessesInaccessibleMemOrErrnoMem() const; + void setOnlyAccessesInaccessibleMemOrErrnoMem(); + + /// Determine if the function may only access memory that is + /// either inaccessible from the IR, pointed to by its arguments, or errno + /// memory. + bool onlyAccessesInaccessibleMemOrArgMemOrErrnoMem() const; + void setOnlyAccessesInaccessibleMemOrArgMemOrErrnoMem(); + /// Determine if the call cannot return. bool doesNotReturn() const { return hasFnAttr(Attribute::NoReturn); } void setDoesNotReturn() { addFnAttr(Attribute::NoReturn); } diff --git a/llvm/include/llvm/Support/ModRef.h b/llvm/include/llvm/Support/ModRef.h index 9ecdab71ec8ca6..aa4ce8295c77a7 100644 --- a/llvm/include/llvm/Support/ModRef.h +++ b/llvm/include/llvm/Support/ModRef.h @@ -61,8 +61,10 @@ enum class IRMemLocation { ArgMem = 0, /// Memory that is inaccessible via LLVM IR. InaccessibleMem = 1, + /// Errno memory. + ErrnoMem = 2, /// Any other memory. - Other = 2, + Other = 3, /// Helpers to iterate all locations in the MemoryEffectsBase class. First = ArgMem, @@ -139,6 +141,11 @@ template <typename LocationEnum> class MemoryEffectsBase { return MemoryEffectsBase(Location::InaccessibleMem, MR); } + /// Create MemoryEffectsBase that can only access errno memory. + static MemoryEffectsBase errnoMemOnly(ModRefInfo MR = ModRefInfo::ModRef) { + return MemoryEffectsBase(Location::ErrnoMem, MR); + } + /// Create MemoryEffectsBase that can only access inaccessible or argument /// memory. static MemoryEffectsBase @@ -149,6 +156,27 @@ template <typename LocationEnum> class MemoryEffectsBase { return FRMB; } + /// Create MemoryEffectsBase that can only access inaccessible or errno + /// memory. + static MemoryEffectsBase + inaccessibleOrErrnoMemOnly(ModRefInfo MR = ModRefInfo::ModRef) { + MemoryEffectsBase FRMB = none(); + FRMB.setModRef(Location::ErrnoMem, MR); + FRMB.setModRef(Location::InaccessibleMem, MR); + return FRMB; + } + + /// Create MemoryEffectsBase that can only access inaccessible, argument or + /// errno memory. + static MemoryEffectsBase + inaccessibleOrArgOrErrnoMemOnly(ModRefInfo MR = ModRefInfo::ModRef) { + MemoryEffectsBase FRMB = none(); + FRMB.setModRef(Location::ArgMem, MR); + FRMB.setModRef(Location::ErrnoMem, MR); + FRMB.setModRef(Location::InaccessibleMem, MR); + return FRMB; + } + /// Create MemoryEffectsBase from an encoded integer value (used by memory /// attribute). static MemoryEffectsBase createFromIntValue(uint32_t Data) { @@ -207,11 +235,21 @@ template <typename LocationEnum> class MemoryEffectsBase { return isModOrRefSet(getModRef(Location::ArgMem)); } + /// Whether this function may access errno memory. + bool doesAccessErrnoMem() const { + return isModOrRefSet(getModRef(Location::ErrnoMem)); + } + /// Whether this function only (at most) accesses inaccessible memory. bool onlyAccessesInaccessibleMem() const { return getWithoutLoc(Location::InaccessibleMem).doesNotAccessMemory(); } + /// Whether this function only (at most) accesses errno memory. + bool onlyAccessesErrnoMem() const { + return getWithoutLoc(Location::ErrnoMem).doesNotAccessMemory(); + } + /// Whether this function only (at most) accesses argument and inaccessible /// memory. bool onlyAccessesInaccessibleOrArgMem() const { @@ -220,6 +258,23 @@ template <typename LocationEnum> class MemoryEffectsBase { .doesNotAccessMemory(); } + /// Whether this function only (at most) accesses inaccessible and errno + /// memory. + bool onlyAccessesInaccessibleOrErrnoMem() const { + return getWithoutLoc(Location::InaccessibleMem) + .getWithoutLoc(Location::ErrnoMem) + .doesNotAccessMemory(); + } + + /// Whether this function only (at most) accesses inaccessible, argument and + /// errno memory. + bool onlyAccessesInaccessibleOrArgOrErrnoMem() const { + return getWithoutLoc(Location::InaccessibleMem) + .getWithoutLoc(Location::ArgMem) + .getWithoutLoc(Location::ErrnoMem) + .doesNotAccessMemory(); + } + /// Intersect with other MemoryEffectsBase. MemoryEffectsBase operator&(MemoryEffectsBase Other) const { return MemoryEffectsBase(Data & Other.Data); diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp index 5ea507c009bdc6..7fcdd5d6f0df9c 100644 --- a/llvm/lib/AsmParser/LLLexer.cpp +++ b/llvm/lib/AsmParser/LLLexer.cpp @@ -701,9 +701,13 @@ lltok::Kind LLLexer::LexIdentifier() { KEYWORD(readwrite); KEYWORD(argmem); KEYWORD(inaccessiblemem); + KEYWORD(errnomem); KEYWORD(argmemonly); KEYWORD(inaccessiblememonly); + KEYWORD(errnomemonly); KEYWORD(inaccessiblemem_or_argmemonly); + KEYWORD(inaccessiblemem_or_errnomemonly); + KEYWORD(inaccessiblemem_or_argmem_or_errnomemonly); KEYWORD(address_is_null); KEYWORD(address); KEYWORD(provenance); diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index fa0079bac435c1..55b352a44d8838 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -1670,9 +1670,18 @@ static bool upgradeMemoryAttr(MemoryEffects &ME, lltok::Kind Kind) { case lltok::kw_inaccessiblememonly: ME &= MemoryEffects::inaccessibleMemOnly(); return true; + case lltok::kw_errnomemonly: + ME &= MemoryEffects::errnoMemOnly(); + return true; case lltok::kw_inaccessiblemem_or_argmemonly: ME &= MemoryEffects::inaccessibleOrArgMemOnly(); return true; + case lltok::kw_inaccessiblemem_or_errnomemonly: + ME &= MemoryEffects::inaccessibleOrErrnoMemOnly(); + return true; + case lltok::kw_inaccessiblemem_or_argmem_or_errnomemonly: + ME &= MemoryEffects::inaccessibleOrArgOrErrnoMemOnly(); + return true; default: return false; } @@ -2490,6 +2499,8 @@ static std::optional<MemoryEffects::Location> keywordToLoc(lltok::Kind Tok) { return IRMemLocation::ArgMem; case lltok::kw_inaccessiblemem: return IRMemLocation::InaccessibleMem; + case lltok::kw_errnomem: + return IRMemLocation::ErrnoMem; default: return std::nullopt; } @@ -2538,7 +2549,7 @@ std::optional<MemoryEffects> LLParser::parseMemoryAttr() { std::optional<ModRefInfo> MR = keywordToModRef(Lex.getKind()); if (!MR) { if (!Loc) - tokError("expected memory location (argmem, inaccessiblemem) " + tokError("expected memory location (argmem, inaccessiblemem, errnomem) " "or access kind (none, read, write, readwrite)"); else tokError("expected access kind (none, read, write, readwrite)"); diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 551dfd4af88bb2..8165002e9d7204 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -1910,6 +1910,10 @@ static uint64_t getRawAttributeMask(Attribute::AttrKind Val) { return 1ULL << 62; case Attribute::NoFree: return 1ULL << 63; + // 7ULL << 36 is ErrnoMemOnly, which is upgraded separately. + // 7ULL << 37 is InaccessibleMemOrErrnoMemOnly, which is upgraded separately. + // 7ULL << 38 is InaccessibleMemOrArgOrErrnoMemOnly, which is upgraded + // separately. default: // Other attributes are not supported in the raw format, // as we ran out of space. @@ -1982,6 +1986,21 @@ static void decodeLLVMAttributesForBitcode(AttrBuilder &B, Attrs &= ~(1ULL << 53); ME &= MemoryEffects::writeOnly(); } + if (Attrs & (7ULL << 36)) { + // ErrnoMemOnly + Attrs &= ~(7ULL << 36); + ME &= MemoryEffects::errnoMemOnly(); + } + if (Attrs & (7ULL << 37)) { + // InaccessibleMemOrErrnoMemOnly + Attrs &= ~(7ULL << 37); + ME &= MemoryEffects::inaccessibleOrErrnoMemOnly(); + } + if (Attrs & (7ULL << 38)) { + // InaccessibleMemOrArgOrErrnoMemOnly + Attrs &= ~(7ULL << 38); + ME &= MemoryEffects::inaccessibleOrArgOrErrnoMemOnly(); + } if (ME != MemoryEffects::unknown()) B.addMemoryAttr(ME); } @@ -2289,9 +2308,18 @@ static bool upgradeOldMemoryAttribute(MemoryEffects &ME, uint64_t EncodedKind) { case bitc::ATTR_KIND_INACCESSIBLEMEM_ONLY: ME &= MemoryEffects::inaccessibleMemOnly(); return true; + case bitc::ATTR_KIND_ERRNOMEMONLY: + ME &= MemoryEffects::errnoMemOnly(); + return true; case bitc::ATTR_KIND_INACCESSIBLEMEM_OR_ARGMEMONLY: ME &= MemoryEffects::inaccessibleOrArgMemOnly(); return true; + case bitc::ATTR_KIND_INACCESSIBLEMEM_OR_ERRNOMEMONLY: + ME &= MemoryEffects::inaccessibleOrErrnoMemOnly(); + return true; + case bitc::ATTR_KIND_INACCESSIBLEMEM_OR_ARGMEM_OR_ERRNOMEMONLY: + ME &= MemoryEffects::inaccessibleOrArgOrErrnoMemOnly(); + return true; default: return false; } diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp index ceb31856283c9a..0ead5a26ce5bd3 100644 --- a/llvm/lib/IR/Attributes.cpp +++ b/llvm/lib/IR/Attributes.cpp @@ -643,6 +643,9 @@ std::string Attribute::getAsString(bool InAttrGrp) const { case IRMemLocation::InaccessibleMem: OS << "inaccessiblemem: "; break; + case IRMemLocation::ErrnoMem: + OS << "errnomem: "; + break; case IRMemLocation::Other: llvm_unreachable("This is represented as the default access kind"); } diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp index 9c5dd5aeb92e97..e4c64bcf9bc5d0 100644 --- a/llvm/lib/IR/Function.cpp +++ b/llvm/lib/IR/Function.cpp @@ -922,6 +922,... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/124742 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits