Skip to content

Commit c13ebc1

Browse files
[InferAttrs] Mark errnomem-writing libcalls as such
Mark C standard library functions that set `errno` as such, as included in the POSIX specification.
1 parent 9e82ee5 commit c13ebc1

File tree

5 files changed

+511
-274
lines changed

5 files changed

+511
-274
lines changed

llvm/include/llvm/IR/Function.h

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,7 @@ class LLVM_ABI Function : public GlobalObject, public ilist_node<Function> {
571571
bool onlyWritesMemory() const;
572572
void setOnlyWritesMemory();
573573

574-
/// Determine if the call can access memmory only using pointers based
574+
/// Determine if the call can access memory only using pointers based
575575
/// on its arguments.
576576
bool onlyAccessesArgMemory() const;
577577
void setOnlyAccessesArgMemory();
@@ -581,11 +581,32 @@ class LLVM_ABI Function : public GlobalObject, public ilist_node<Function> {
581581
bool onlyAccessesInaccessibleMemory() const;
582582
void setOnlyAccessesInaccessibleMemory();
583583

584+
/// Determine if the call can access only errno memory.
585+
bool onlyAccessesErrnoMemory() const;
586+
void setOnlyAccessesErrnoMemory();
587+
584588
/// Determine if the function may only access memory that is
585589
/// either inaccessible from the IR or pointed to by its arguments.
586590
bool onlyAccessesInaccessibleMemOrArgMem() const;
587591
void setOnlyAccessesInaccessibleMemOrArgMem();
588592

593+
/// Determine if the function may only access memory that is
594+
/// either pointed to by its arguments or errno memory.
595+
bool onlyAccessesArgMemOrErrnoMem() const;
596+
void setOnlyAccessesArgMemOrErrnoMem(ModRefInfo ArgMR);
597+
598+
/// Determine if the function may only access memory that is
599+
/// either inaccessible from the IR or errno memory.
600+
bool onlyAccessesInaccessibleMemOrErrnoMem() const;
601+
void setOnlyAccessesInaccessibleMemOrErrnoMem();
602+
603+
/// Determine if the function may only access memory that is
604+
/// either inaccessible from the IR, pointed to by its arguments, or errno
605+
/// memory.
606+
bool onlyAccessesInaccessibleMemOrArgMemOrErrnoMem() const;
607+
void setOnlyAccessesInaccessibleMemOrArgMemOrErrnoMem(
608+
ModRefInfo InaccessibleMR, ModRefInfo ArgMR, ModRefInfo ErrnoMR);
609+
589610
/// Determine if the function cannot return.
590611
bool doesNotReturn() const {
591612
return hasFnAttribute(Attribute::NoReturn);

llvm/include/llvm/Support/ModRef.h

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,38 @@ template <typename LocationEnum> class MemoryEffectsBase {
161161
return FRMB;
162162
}
163163

164+
/// Create MemoryEffectsBase that can only access argument or errno memory.
165+
static MemoryEffectsBase
166+
argumentOrErrnoMemOnly(ModRefInfo ArgMR = ModRefInfo::ModRef,
167+
ModRefInfo OtherMR = ModRefInfo::ModRef) {
168+
MemoryEffectsBase FRMB = none();
169+
FRMB.setModRef(Location::ArgMem, ArgMR);
170+
FRMB.setModRef(Location::ErrnoMem, OtherMR);
171+
return FRMB;
172+
}
173+
174+
/// Create MemoryEffectsBase that can only access inaccessible or errno
175+
/// memory.
176+
static MemoryEffectsBase
177+
inaccessibleOrErrnoMemOnly(ModRefInfo MR = ModRefInfo::ModRef) {
178+
MemoryEffectsBase FRMB = none();
179+
FRMB.setModRef(Location::ErrnoMem, MR);
180+
FRMB.setModRef(Location::InaccessibleMem, MR);
181+
return FRMB;
182+
}
183+
184+
/// Create MemoryEffectsBase that can only access inaccessible, argument or
185+
/// errno memory.
186+
static MemoryEffectsBase
187+
inaccessibleOrArgOrErrnoMemOnly(ModRefInfo InaccessibleMR, ModRefInfo ArgMR,
188+
ModRefInfo ErrnoMR) {
189+
MemoryEffectsBase FRMB = none();
190+
FRMB.setModRef(Location::ArgMem, ArgMR);
191+
FRMB.setModRef(Location::ErrnoMem, ErrnoMR);
192+
FRMB.setModRef(Location::InaccessibleMem, InaccessibleMR);
193+
return FRMB;
194+
}
195+
164196
/// Create MemoryEffectsBase from an encoded integer value (used by memory
165197
/// attribute).
166198
static MemoryEffectsBase createFromIntValue(uint32_t Data) {
@@ -237,6 +269,30 @@ template <typename LocationEnum> class MemoryEffectsBase {
237269
.doesNotAccessMemory();
238270
}
239271

272+
/// Whether this function only (at most) accesses argument and errno memory.
273+
bool onlyAccessesArgumentOrErrnoMem() const {
274+
return getWithoutLoc(Location::ArgMem)
275+
.getWithoutLoc(Location::ErrnoMem)
276+
.doesNotAccessMemory();
277+
}
278+
279+
/// Whether this function only (at most) accesses inaccessible and errno
280+
/// memory.
281+
bool onlyAccessesInaccessibleOrErrnoMem() const {
282+
return getWithoutLoc(Location::InaccessibleMem)
283+
.getWithoutLoc(Location::ErrnoMem)
284+
.doesNotAccessMemory();
285+
}
286+
287+
/// Whether this function only (at most) accesses inaccessible, argument and
288+
/// errno memory.
289+
bool onlyAccessesInaccessibleOrArgOrErrnoMem() const {
290+
return getWithoutLoc(Location::InaccessibleMem)
291+
.getWithoutLoc(Location::ArgMem)
292+
.getWithoutLoc(Location::ErrnoMem)
293+
.doesNotAccessMemory();
294+
}
295+
240296
/// Intersect with other MemoryEffectsBase.
241297
MemoryEffectsBase operator&(MemoryEffectsBase Other) const {
242298
return MemoryEffectsBase(Data & Other.Data);

llvm/lib/IR/Function.cpp

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -904,7 +904,7 @@ void Function::setOnlyWritesMemory() {
904904
setMemoryEffects(getMemoryEffects() & MemoryEffects::writeOnly());
905905
}
906906

907-
/// Determine if the call can access memmory only using pointers based
907+
/// Determine if the call can access memory only using pointers based
908908
/// on its arguments.
909909
bool Function::onlyAccessesArgMemory() const {
910910
return getMemoryEffects().onlyAccessesArgPointees();
@@ -922,6 +922,14 @@ void Function::setOnlyAccessesInaccessibleMemory() {
922922
setMemoryEffects(getMemoryEffects() & MemoryEffects::inaccessibleMemOnly());
923923
}
924924

925+
/// Determine if the call can access only errno memory.
926+
bool Function::onlyAccessesErrnoMemory() const {
927+
return getMemoryEffects().onlyAccessesErrnoMem();
928+
}
929+
void Function::setOnlyAccessesErrnoMemory() {
930+
setMemoryEffects(getMemoryEffects() & MemoryEffects::errnoMemOnly());
931+
}
932+
925933
/// Determine if the function may only access memory that is
926934
/// either inaccessible from the IR or pointed to by its arguments.
927935
bool Function::onlyAccessesInaccessibleMemOrArgMem() const {
@@ -932,6 +940,39 @@ void Function::setOnlyAccessesInaccessibleMemOrArgMem() {
932940
MemoryEffects::inaccessibleOrArgMemOnly());
933941
}
934942

943+
/// Determine if the function may only access memory that is
944+
/// either pointed to by its arguments or errno memory.
945+
bool Function::onlyAccessesArgMemOrErrnoMem() const {
946+
return getMemoryEffects().onlyAccessesArgumentOrErrnoMem();
947+
}
948+
void Function::setOnlyAccessesArgMemOrErrnoMem(ModRefInfo ArgMR) {
949+
setMemoryEffects(getMemoryEffects() &
950+
MemoryEffects::argumentOrErrnoMemOnly(ArgMR));
951+
}
952+
953+
/// Determine if the function may only access memory that is
954+
/// either inaccessible from the IR or errno memory.
955+
bool Function::onlyAccessesInaccessibleMemOrErrnoMem() const {
956+
return getMemoryEffects().onlyAccessesInaccessibleOrErrnoMem();
957+
}
958+
void Function::setOnlyAccessesInaccessibleMemOrErrnoMem() {
959+
setMemoryEffects(getMemoryEffects() &
960+
MemoryEffects::inaccessibleOrErrnoMemOnly());
961+
}
962+
963+
/// Determine if the function may only access memory that is
964+
/// either inaccessible from the IR, pointed to by its arguments or errno
965+
/// memory.
966+
bool Function::onlyAccessesInaccessibleMemOrArgMemOrErrnoMem() const {
967+
return getMemoryEffects().onlyAccessesInaccessibleOrArgOrErrnoMem();
968+
}
969+
void Function::setOnlyAccessesInaccessibleMemOrArgMemOrErrnoMem(
970+
ModRefInfo InaccessibleMR, ModRefInfo ArgMR, ModRefInfo ErrnoMR) {
971+
setMemoryEffects(getMemoryEffects() &
972+
MemoryEffects::inaccessibleOrArgOrErrnoMemOnly(
973+
InaccessibleMR, ArgMR, ErrnoMR));
974+
}
975+
935976
bool Function::isTargetIntrinsic() const {
936977
return Intrinsic::isTargetIntrinsic(IntID);
937978
}

0 commit comments

Comments
 (0)