Skip to content

Commit 5c8d7bc

Browse files
[InferAttrs] Mark errnomem-setting libcalls as such
Mark C standard library functions that set `errno` as such, as included in the POSIX specification.
1 parent 3adea2c commit 5c8d7bc

File tree

5 files changed

+364
-130
lines changed

5 files changed

+364
-130
lines changed

llvm/include/llvm/IR/Function.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,22 @@ class LLVM_ABI Function : public GlobalObject, public ilist_node<Function> {
586586
bool onlyAccessesInaccessibleMemOrArgMem() const;
587587
void setOnlyAccessesInaccessibleMemOrArgMem();
588588

589+
/// Determine if the function may only access memory that is
590+
/// either pointed to by its arguments or errno memory.
591+
bool onlyAccessesArgMemOrErrnoMem() const;
592+
void setOnlyAccessesArgMemOrErrnoMem(ModRefInfo ArgMR);
593+
594+
/// Determine if the function may only access memory that is
595+
/// either inaccessible from the IR or errno memory.
596+
bool onlyAccessesInaccessibleMemOrErrnoMem() const;
597+
void setOnlyAccessesInaccessibleMemOrErrnoMem();
598+
599+
/// Determine if the function may only access memory that is
600+
/// either inaccessible from the IR, pointed to by its arguments, or errno
601+
/// memory.
602+
bool onlyAccessesInaccessibleMemOrArgMemOrErrnoMem() const;
603+
void setOnlyAccessesInaccessibleMemOrArgMemOrErrnoMem(ModRefInfo ArgMR);
604+
589605
/// Determine if the function cannot return.
590606
bool doesNotReturn() const {
591607
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 ArgMR = ModRefInfo::ModRef,
188+
ModRefInfo OtherMR = ModRefInfo::ModRef) {
189+
MemoryEffectsBase FRMB = none();
190+
FRMB.setModRef(Location::ArgMem, ArgMR);
191+
FRMB.setModRef(Location::ErrnoMem, OtherMR);
192+
FRMB.setModRef(Location::InaccessibleMem, OtherMR);
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: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -932,6 +932,39 @@ void Function::setOnlyAccessesInaccessibleMemOrArgMem() {
932932
MemoryEffects::inaccessibleOrArgMemOnly());
933933
}
934934

935+
/// Determine if the function may only access memory that is
936+
/// either pointed to by its arguments or errno memory.
937+
bool Function::onlyAccessesArgMemOrErrnoMem() const {
938+
return getMemoryEffects().onlyAccessesArgumentOrErrnoMem();
939+
}
940+
void Function::setOnlyAccessesArgMemOrErrnoMem(ModRefInfo ArgMR) {
941+
setMemoryEffects(getMemoryEffects() & MemoryEffects::argumentOrErrnoMemOnly(
942+
ArgMR, ModRefInfo::ModRef));
943+
}
944+
945+
/// Determine if the function may only access memory that is
946+
/// either inaccessible from the IR or errno memory.
947+
bool Function::onlyAccessesInaccessibleMemOrErrnoMem() const {
948+
return getMemoryEffects().onlyAccessesInaccessibleOrErrnoMem();
949+
}
950+
void Function::setOnlyAccessesInaccessibleMemOrErrnoMem() {
951+
setMemoryEffects(getMemoryEffects() &
952+
MemoryEffects::inaccessibleOrErrnoMemOnly());
953+
}
954+
955+
/// Determine if the function may only access memory that is
956+
/// either inaccessible from the IR, pointed to by its arguments or errno
957+
/// memory.
958+
bool Function::onlyAccessesInaccessibleMemOrArgMemOrErrnoMem() const {
959+
return getMemoryEffects().onlyAccessesInaccessibleOrArgOrErrnoMem();
960+
}
961+
void Function::setOnlyAccessesInaccessibleMemOrArgMemOrErrnoMem(
962+
ModRefInfo ArgMR) {
963+
setMemoryEffects(getMemoryEffects() &
964+
MemoryEffects::inaccessibleOrArgOrErrnoMemOnly(
965+
ArgMR, ModRefInfo::ModRef));
966+
}
967+
935968
bool Function::isTargetIntrinsic() const {
936969
return Intrinsic::isTargetIntrinsic(IntID);
937970
}

0 commit comments

Comments
 (0)