[Mlir-commits] [llvm] [mlir] [IR][ModRef] Introduce `errno` memory location (PR #120783)
Antonio Frighetto
llvmlistbot at llvm.org
Tue Feb 11 10:28:17 PST 2025
https://github.com/antoniofrighetto updated https://github.com/llvm/llvm-project/pull/120783
>From 3adea2ccfa68f94e8080bc55fb3a2ff2bac111f4 Mon Sep 17 00:00:00 2001
From: Antonio Frighetto <me at antoniofrighetto.com>
Date: Mon, 10 Feb 2025 15:30:35 +0100
Subject: [PATCH] [IR][ModRef] Introduce `errno` memory location
Model C/C++ `errno` macro by adding a corresponding `errno`
memory location kind to the IR. Preliminary work to separate
`errno` writes from other memory accesses, to the benefit of
alias analyses and optimization correctness.
Previous discussion: https://discourse.llvm.org/t/rfc-modelling-errno-memory-effects/82972.
---
llvm/docs/LangRef.rst | 7 +++--
llvm/include/llvm/AsmParser/LLToken.h | 1 +
llvm/include/llvm/Support/ModRef.h | 19 ++++++++++++-
llvm/lib/AsmParser/LLLexer.cpp | 1 +
llvm/lib/AsmParser/LLParser.cpp | 4 ++-
llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 25 ++++++++++++++----
llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 11 ++++++--
llvm/lib/IR/Attributes.cpp | 3 +++
llvm/lib/Support/ModRef.cpp | 3 +++
llvm/lib/Transforms/IPO/FunctionAttrs.cpp | 4 +++
llvm/lib/Transforms/IPO/SCCP.cpp | 6 +++--
.../test/Assembler/memory-attribute-errors.ll | 6 ++---
llvm/test/Assembler/memory-attribute.ll | 12 +++++++++
.../Inputs/memory-attribute-upgrade.bc | Bin 0 -> 1736 bytes
llvm/test/Bitcode/memory-attribute-upgrade.ll | 7 +++++
llvm/unittests/Support/ModRefTest.cpp | 4 +--
mlir/test/Target/LLVMIR/llvmir.mlir | 10 +++----
17 files changed, 100 insertions(+), 23 deletions(-)
create mode 100644 llvm/test/Bitcode/Inputs/memory-attribute-upgrade.bc
create mode 100644 llvm/test/Bitcode/memory-attribute-upgrade.ll
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 5cdb19fa03fc7..099e119f78363 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -2046,8 +2046,8 @@ For example:
This attribute specifies the possible memory effects of the call-site or
function. It allows specifying the possible access kinds (``none``,
``read``, ``write``, or ``readwrite``) for the possible memory location
- kinds (``argmem``, ``inaccessiblemem``, as well as a default). It is best
- understood by example:
+ kinds (``argmem``, ``inaccessiblemem``, ``errnomem``, as well as a default).
+ It is best understood by example:
- ``memory(none)``: Does not access any memory.
- ``memory(read)``: May read (but not write) any memory.
@@ -2056,6 +2056,8 @@ For example:
- ``memory(argmem: read)``: May only read argument memory.
- ``memory(argmem: read, inaccessiblemem: write)``: May only read argument
memory and only write inaccessible memory.
+ - ``memory(argmem: read, errnomem: write)``: May only read argument memory
+ and only write errno.
- ``memory(read, argmem: readwrite)``: May read any memory (default mode)
and additionally write argument memory.
- ``memory(readwrite, argmem: none)``: May access any memory apart from
@@ -2085,6 +2087,7 @@ For example:
allocator function may return newly accessible memory while only
accessing inaccessible memory itself). Inaccessible memory is often used
to model control dependencies of intrinsics.
+ - ``errnomem``: This refers to accesses to the ``errno`` variable.
- The default access kind (specified without a location prefix) applies to
all locations that haven't been specified explicitly, including those that
don't currently have a dedicated location kind (e.g. accesses to globals
diff --git a/llvm/include/llvm/AsmParser/LLToken.h b/llvm/include/llvm/AsmParser/LLToken.h
index 4a431383e0a1c..a53d471f70271 100644
--- a/llvm/include/llvm/AsmParser/LLToken.h
+++ b/llvm/include/llvm/AsmParser/LLToken.h
@@ -201,6 +201,7 @@ enum Kind {
kw_readwrite,
kw_argmem,
kw_inaccessiblemem,
+ kw_errnomem,
// Legacy attributes:
kw_argmemonly,
diff --git a/llvm/include/llvm/Support/ModRef.h b/llvm/include/llvm/Support/ModRef.h
index a8ce9a8e6e69c..be416fe0cd66d 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,16 @@ 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 default memory.
+ static MemoryEffectsBase defaultMemOnly(ModRefInfo MR = ModRefInfo::ModRef) {
+ return MemoryEffectsBase(Location::Other, MR);
+ }
+
/// Create MemoryEffectsBase that can only access inaccessible or argument
/// memory.
static MemoryEffectsBase
@@ -212,6 +224,11 @@ template <typename LocationEnum> class MemoryEffectsBase {
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 {
diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp
index 438824f84e2d0..c867a68518e4d 100644
--- a/llvm/lib/AsmParser/LLLexer.cpp
+++ b/llvm/lib/AsmParser/LLLexer.cpp
@@ -701,6 +701,7 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(readwrite);
KEYWORD(argmem);
KEYWORD(inaccessiblemem);
+ KEYWORD(errnomem);
KEYWORD(argmemonly);
KEYWORD(inaccessiblememonly);
KEYWORD(inaccessiblemem_or_argmemonly);
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index ad52a9f493eae..0817851bd408a 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -2497,6 +2497,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;
}
@@ -2545,7 +2547,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 1a09e80c4fbb2..e13f7d3fc47bf 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -1937,8 +1937,7 @@ static void addRawAttributeValue(AttrBuilder &B, uint64_t Val) {
}
/// This fills an AttrBuilder object with the LLVM attributes that have
-/// been decoded from the given integer. This function must stay in sync with
-/// 'encodeLLVMAttributesForBitcode'.
+/// been decoded from the given integer.
static void decodeLLVMAttributesForBitcode(AttrBuilder &B,
uint64_t EncodedAttrs,
uint64_t AttrIdx) {
@@ -2398,9 +2397,25 @@ Error BitcodeReader::parseAttributeGroupBlock() {
B.addUWTableAttr(UWTableKind(Record[++i]));
else if (Kind == Attribute::AllocKind)
B.addAllocKindAttr(static_cast<AllocFnKind>(Record[++i]));
- else if (Kind == Attribute::Memory)
- B.addMemoryAttr(MemoryEffects::createFromIntValue(Record[++i]));
- else if (Kind == Attribute::Captures)
+ else if (Kind == Attribute::Memory) {
+ uint64_t EncodedME = Record[++i];
+ const uint8_t Version = (EncodedME >> 56);
+ auto ME = MemoryEffects::createFromIntValue(EncodedME &
+ 0x00FFFFFFFFFFFFFFULL);
+ if (Version < 1) {
+ // Errno memory location was previously encompassed into default
+ // memory. Ensure this is taken into account while reconstructing
+ // the memory attribute prior to its introduction.
+ ModRefInfo OldOtherMR = ME.getModRef(IRMemLocation::ErrnoMem);
+ ME = MemoryEffects::inaccessibleMemOnly(
+ ME.getModRef(IRMemLocation::InaccessibleMem)) |
+ MemoryEffects::argMemOnly(
+ ME.getModRef(IRMemLocation::ArgMem)) |
+ MemoryEffects::errnoMemOnly(OldOtherMR) |
+ MemoryEffects::defaultMemOnly(OldOtherMR);
+ }
+ B.addMemoryAttr(ME);
+ } else if (Kind == Attribute::Captures)
B.addCapturesAttr(CaptureInfo::createFromIntValue(Record[++i]));
else if (Kind == Attribute::NoFPClass)
B.addNoFPClassAttr(
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
index 7ca63c2c7251d..450b8066540e5 100644
--- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -977,8 +977,15 @@ void ModuleBitcodeWriter::writeAttributeGroupTable() {
Record.push_back(getAttrKindEncoding(Attr.getKindAsEnum()));
} else if (Attr.isIntAttribute()) {
Record.push_back(1);
- Record.push_back(getAttrKindEncoding(Attr.getKindAsEnum()));
- Record.push_back(Attr.getValueAsInt());
+ Attribute::AttrKind Kind = Attr.getKindAsEnum();
+ Record.push_back(getAttrKindEncoding(Kind));
+ if (Kind == Attribute::Memory) {
+ // Version field for upgrading old memory effects.
+ const uint64_t Version = 1;
+ Record.push_back((Version << 56) | Attr.getValueAsInt());
+ } else {
+ Record.push_back(Attr.getValueAsInt());
+ }
} else if (Attr.isStringAttribute()) {
StringRef Kind = Attr.getKindAsString();
StringRef Val = Attr.getValueAsString();
diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp
index ef0591ef31744..8da1dfe914818 100644
--- a/llvm/lib/IR/Attributes.cpp
+++ b/llvm/lib/IR/Attributes.cpp
@@ -647,6 +647,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/Support/ModRef.cpp b/llvm/lib/Support/ModRef.cpp
index d3b3dd11171f1..2bb9bc945bd2e 100644
--- a/llvm/lib/Support/ModRef.cpp
+++ b/llvm/lib/Support/ModRef.cpp
@@ -43,6 +43,9 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, MemoryEffects ME) {
case IRMemLocation::InaccessibleMem:
OS << "InaccessibleMem: ";
break;
+ case IRMemLocation::ErrnoMem:
+ OS << "ErrnoMem: ";
+ break;
case IRMemLocation::Other:
OS << "Other: ";
break;
diff --git a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
index cf56f67e4de3f..415df169b88fc 100644
--- a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
+++ b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
@@ -132,6 +132,7 @@ static void addLocAccess(MemoryEffects &ME, const MemoryLocation &Loc,
// If it's not an identified object, it might be an argument.
if (!isIdentifiedObject(UO))
ME |= MemoryEffects::argMemOnly(MR);
+ ME |= MemoryEffects(IRMemLocation::ErrnoMem, MR);
ME |= MemoryEffects(IRMemLocation::Other, MR);
}
@@ -210,6 +211,9 @@ checkFunctionMemoryAccess(Function &F, bool ThisBody, AAResults &AAR,
if (isa<PseudoProbeInst>(I))
continue;
+ // Merge callee's memory effects into caller's ones, including
+ // inaccessible and errno memory, but excluding argument memory, which is
+ // handled separately.
ME |= CallME.getWithoutLoc(IRMemLocation::ArgMem);
// If the call accesses captured memory (currently part of "other") and
diff --git a/llvm/lib/Transforms/IPO/SCCP.cpp b/llvm/lib/Transforms/IPO/SCCP.cpp
index 2afcdf09af016..639e3039108a7 100644
--- a/llvm/lib/Transforms/IPO/SCCP.cpp
+++ b/llvm/lib/Transforms/IPO/SCCP.cpp
@@ -191,8 +191,10 @@ static bool runIPSCCP(
if (ME == MemoryEffects::unknown())
return AL;
- ME |= MemoryEffects(IRMemLocation::Other,
- ME.getModRef(IRMemLocation::ArgMem));
+ ModRefInfo ArgMemMR = ME.getModRef(IRMemLocation::ArgMem);
+ ME |= MemoryEffects(IRMemLocation::ErrnoMem, ArgMemMR);
+ ME |= MemoryEffects(IRMemLocation::Other, ArgMemMR);
+
return AL.addFnAttribute(
F.getContext(),
Attribute::getWithMemoryEffects(F.getContext(), ME));
diff --git a/llvm/test/Assembler/memory-attribute-errors.ll b/llvm/test/Assembler/memory-attribute-errors.ll
index 1fba90362e79b..2eed11d9465d5 100644
--- a/llvm/test/Assembler/memory-attribute-errors.ll
+++ b/llvm/test/Assembler/memory-attribute-errors.ll
@@ -12,16 +12,16 @@
; MISSING-ARGS: error: expected '('
declare void @fn() memory
;--- empty.ll
-; EMPTY: error: expected memory location (argmem, inaccessiblemem) or access kind (none, read, write, readwrite)
+; EMPTY: error: expected memory location (argmem, inaccessiblemem, errnomem) or access kind (none, read, write, readwrite)
declare void @fn() memory()
;--- unterminated.ll
; UNTERMINATED: error: unterminated memory attribute
declare void @fn() memory(read
;--- invalid-kind.ll
-; INVALID-KIND: error: expected memory location (argmem, inaccessiblemem) or access kind (none, read, write, readwrite)
+; INVALID-KIND: error: expected memory location (argmem, inaccessiblemem, errnomem) or access kind (none, read, write, readwrite)
declare void @fn() memory(foo)
;--- other.ll
-; OTHER: error: expected memory location (argmem, inaccessiblemem) or access kind (none, read, write, readwrite)
+; OTHER: error: expected memory location (argmem, inaccessiblemem, errnomem) or access kind (none, read, write, readwrite)
declare void @fn() memory(other: read)
;--- missing-colon.ll
; MISSING-COLON: error: expected ':' after location
diff --git a/llvm/test/Assembler/memory-attribute.ll b/llvm/test/Assembler/memory-attribute.ll
index 2f7d3980eb378..effd4ce7c4548 100644
--- a/llvm/test/Assembler/memory-attribute.ll
+++ b/llvm/test/Assembler/memory-attribute.ll
@@ -40,6 +40,18 @@ declare void @fn_inaccessiblemem_write() memory(inaccessiblemem: write)
; CHECK: @fn_inaccessiblemem_readwrite()
declare void @fn_inaccessiblemem_readwrite() memory(inaccessiblemem: readwrite)
+; CHECK: Function Attrs: memory(errnomem: read)
+; CHECK: @fn_errnomem_read()
+declare void @fn_errnomem_read() memory(errnomem: read)
+
+; CHECK: Function Attrs: memory(errnomem: write)
+; CHECK: @fn_errnomem_write()
+declare void @fn_errnomem_write() memory(errnomem: write)
+
+; CHECK: Function Attrs: memory(errnomem: readwrite)
+; CHECK: @fn_errnomem_readwrite()
+declare void @fn_errnomem_readwrite() memory(errnomem: readwrite)
+
; CHECK: Function Attrs: memory(read, argmem: readwrite)
; CHECK: @fn_read_argmem_readwrite()
declare void @fn_read_argmem_readwrite() memory(read, argmem: readwrite)
diff --git a/llvm/test/Bitcode/Inputs/memory-attribute-upgrade.bc b/llvm/test/Bitcode/Inputs/memory-attribute-upgrade.bc
new file mode 100644
index 0000000000000000000000000000000000000000..52a38d27b10327243e1b7ba34f2e7762a8ebf722
GIT binary patch
literal 1736
zcmYjRZ%h+s7=MpKuVTGB6t&g6+nu1{gMW at 9(Asusdv4av#p+zbk{Mc{1vX^`I{vx1
zmUbT7`k|VB=m$(-Gt2x23m^DE7TW7v)y6TiEF>eO9e>0Pl}xsnXtq69)a*^}eeQYR
z=Xu`e`8|Ie;`DrNIYK1}p(d?R`PRGNeSP-n#L3;6%A=T}1o2vgE at B96F5*!U$mrq2
zLlu|pnd0MW%3!*JMYMZMG<vr9i>9FVwIaur&5jnzP;S)d-Yhj3hMfL1UvYG+6s7D}
zidr(7 at p4XleTch>84QsIB6gWS8XFz_vPduEx3}vJ(db@^ITFYq^cjaxDZI7ES4 at 5D
z7`#cHhAq~aayd&k?Gta5I1KwVrMs{yhd>F(f(V_`Aq1|X-Jj?Fg(Xezxa$`AXUab{
zo0=Ha{R4lWXwKQU)Rm`|Q!;em49Fh`Jr&SxgKh_RLUU;ohM_k|P1#o4rDz;shaHJw
zcFJ^hxaX;c;&g83_BKEP at Yq<>YVGy9lL*;f9H7}C{|;*_q6$U}r;5z!d|422FNNxC
zO<|iSiBNDq1&0du1~#G9mz{`3H|;xiqgYI7;A|XxyA8BP6Qt95+E<QQheTsUjyi&P
ze;?kR=+rJF@&QGx2Z<W3gH0uwJEOEuC at F}AcV|`BjA)Ijtl7S3z>i<h;Qda?@5cxH
zs-8Z{&q?}h8L=88@&ef*kPB<Xnv1BR(#$+h&+<&l!}^5J%u`|WjA)urS*F64h{~K@
zEAMgR7uxXpHmM8tpyZE9emCAzh4(xu0kge9sZk?!>ZGoO)Sn3Lf4D|G%n^T06RU!%
zDKknhj?&q}KIfrt at pL-G-14Y@iHW9+Xi60JN!b_|jYBGPTs{PkJ{vUutTK<u+8^2_
ze}mNJ4+q-tKDQLmNr4ebf9GxTAtL{D5sNWm!A9meVils`s+hSXo3gWad3r9y&gJOE
zJo7uo`gEs^W8#tFusQ3hd>)8f>g~h(5~ohA$4CVM_I>u2hhE{C`6P1 at V-<&aX3e8M
z^J&<amCa+K6##jbvMh?`Az<a`_oWc2)C>M- at PR74D-n8cfg)C?i6s~DSg1(ewX=))
zowIpn9vpD$&0}HfM0j^ZHbzBLR<=wgO&J+tv}BzVof;gx>I48AB>k^9h*dZFAg5mA
z$R&YX;>f>UL<dDI2n4W?bL#s!V$nrB5h{LL_0XvhGn?PJ$}`J6lja%7;0phWkGpD~
z60MUeQ#@?SHcUbGA=m-%(<$}(CH?Jt#3O;s=ZO0@^8N_CB4euVZ*YjEF#)BbARL&1
zRE8pUQ%(lxtdOa!Ej_~A8f9{Jc0Nh_Dw_o&ujH2mBTItFhd<Kc-A<`-MEW=gy5n)o
z5|u4+**GH}fpW?MVp=D^-Qi)u)jLV%bg0~SqE#Rsapa?%`jLxVS4<I0IrTC}=4T+-
zuWaF-HoRXW=}+&Pl+93w*F<9$FjSdhVM|tJ0WjlA8>8#cGY5cfF72v<TEqt${0WF(
zaosc{4=&R;Mz^fkl~#ebH*&n=@PeDT=YrB97nK4c at 41Nev0w=AuPRh_p9EP^^4j1Z
zmW>mb`C8Z-my14tCZXr@^c+VodX#-7#HKv-%qX4NNQNhgk?Rlu#1kYo4{d-_@}m(T
zn1w=@Ath$00O-$*%B=YQ6AS}2P&{k77B&w<1E{PcVGA at vOjbsYhl4wy+lrGzb}Y#0
zH0klYZDSnyC=1+d$S8AgTd}<`TNJ%?8A7r;LKROxSBs1(YK1ZOLa&qCn1cp_+7rS4
zD5|m at 0ttl9g0U)~TUGID#a3&;+Z|~1bo4j&cC`n*jh?R7^WO7~U0zSi%NvFH|3yKv
z*>mok*Sn$hVaK`t=e#1Tu!ib`!a<?6J;2on)h6#@lefv&T-#D#4P147wV|o5<#0`X
ab8TI-Q0=X&Z8Fwdx&tlk9j_`*!uk*B0#z~q
literal 0
HcmV?d00001
diff --git a/llvm/test/Bitcode/memory-attribute-upgrade.ll b/llvm/test/Bitcode/memory-attribute-upgrade.ll
new file mode 100644
index 0000000000000..915b62a88935d
--- /dev/null
+++ b/llvm/test/Bitcode/memory-attribute-upgrade.ll
@@ -0,0 +1,7 @@
+; RUN: llvm-dis < %S/Inputs/memory-attribute-upgrade.bc | FileCheck %s
+
+; CHECK: ; Function Attrs: memory(write, argmem: read)
+; CHECK-NEXT: define void @test_any_write_argmem_read(ptr %p)
+
+; CHECK: ; Function Attrs: memory(read, argmem: readwrite, inaccessiblemem: none)
+; CHECK-NEXT: define void @test_any_read_argmem_readwrite(ptr %p)
diff --git a/llvm/unittests/Support/ModRefTest.cpp b/llvm/unittests/Support/ModRefTest.cpp
index 35107e50b32db..9c13908da44bb 100644
--- a/llvm/unittests/Support/ModRefTest.cpp
+++ b/llvm/unittests/Support/ModRefTest.cpp
@@ -7,7 +7,6 @@
//===----------------------------------------------------------------------===//
#include "llvm/Support/ModRef.h"
-#include "llvm/ADT/SmallString.h"
#include "llvm/Support/raw_ostream.h"
#include "gtest/gtest.h"
#include <string>
@@ -21,7 +20,8 @@ TEST(ModRefTest, PrintMemoryEffects) {
std::string S;
raw_string_ostream OS(S);
OS << MemoryEffects::none();
- EXPECT_EQ(S, "ArgMem: NoModRef, InaccessibleMem: NoModRef, Other: NoModRef");
+ EXPECT_EQ(S, "ArgMem: NoModRef, InaccessibleMem: NoModRef, ErrnoMem: "
+ "NoModRef, Other: NoModRef");
}
} // namespace
diff --git a/mlir/test/Target/LLVMIR/llvmir.mlir b/mlir/test/Target/LLVMIR/llvmir.mlir
index 52aa69f4c481f..91cfb04e3b440 100644
--- a/mlir/test/Target/LLVMIR/llvmir.mlir
+++ b/mlir/test/Target/LLVMIR/llvmir.mlir
@@ -2347,7 +2347,7 @@ llvm.func @readonly_function(%arg0: !llvm.ptr {llvm.readonly})
llvm.func @arg_mem_none_func() attributes {
memory_effects = #llvm.memory_effects<other = readwrite, argMem = none, inaccessibleMem = readwrite>}
-// CHECK: attributes #[[ATTR]] = { memory(readwrite, argmem: none) }
+// CHECK: attributes #[[ATTR]] = { memory(readwrite, argmem: none, errnomem: none) }
// -----
@@ -2355,7 +2355,7 @@ llvm.func @arg_mem_none_func() attributes {
llvm.func @readwrite_func() attributes {
memory_effects = #llvm.memory_effects<other = readwrite, argMem = readwrite, inaccessibleMem = readwrite>}
-// CHECK: attributes #[[ATTR]] = { memory(readwrite) }
+// CHECK: attributes #[[ATTR]] = { memory(readwrite, errnomem: none) }
// -----
@@ -2613,11 +2613,11 @@ llvm.func @mem_effects_call() {
// CHECK: #[[ATTRS_0]]
// CHECK-SAME: memory(none)
// CHECK: #[[ATTRS_1]]
-// CHECK-SAME: memory(read, argmem: none, inaccessiblemem: write)
+// CHECK-SAME: memory(read, argmem: none, inaccessiblemem: write, errnomem: none)
// CHECK: #[[ATTRS_2]]
-// CHECK-SAME: memory(read, inaccessiblemem: write)
+// CHECK-SAME: memory(read, inaccessiblemem: write, errnomem: none)
// CHECK: #[[ATTRS_3]]
-// CHECK-SAME: memory(readwrite, argmem: read)
+// CHECK-SAME: memory(readwrite, argmem: read, errnomem: none)
// -----
More information about the Mlir-commits
mailing list