Skip to content

Commit 31c0e52

Browse files
committed
A readonly operand bundle should not prevent inference of readonly from a readnone callee
A readonly operand bundle disallows inference of readnone from the callee, but it should not prevent us from using the readnone fact on the callee to infer readonly for the callsite. Fixes pr53270. Differential Revision: https://reviews.llvm.org/D117591
1 parent a440b04 commit 31c0e52

File tree

2 files changed

+22
-3
lines changed

2 files changed

+22
-3
lines changed

llvm/include/llvm/IR/InstrTypes.h

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1818,14 +1818,14 @@ class CallBase : public Instruction {
18181818

18191819
/// Determine if the call does not access or only reads memory.
18201820
bool onlyReadsMemory() const {
1821-
return doesNotAccessMemory() || hasFnAttr(Attribute::ReadOnly);
1821+
return hasImpliedFnAttr(Attribute::ReadOnly);
18221822
}
18231823

18241824
void setOnlyReadsMemory() { addFnAttr(Attribute::ReadOnly); }
18251825

18261826
/// Determine if the call does not access or only writes memory.
18271827
bool onlyWritesMemory() const {
1828-
return doesNotAccessMemory() || hasFnAttr(Attribute::WriteOnly);
1828+
return hasImpliedFnAttr(Attribute::WriteOnly);
18291829
}
18301830
void setOnlyWritesMemory() { addFnAttr(Attribute::WriteOnly); }
18311831

@@ -2288,6 +2288,26 @@ class CallBase : public Instruction {
22882288
return hasFnAttrOnCalledFunction(Kind);
22892289
}
22902290

2291+
/// A specialized version of hasFnAttrImpl for when the caller wants to
2292+
/// know if an attribute's semantics are implied, not whether the attribute
2293+
/// is actually present. This distinction only exists when checking whether
2294+
/// something is readonly or writeonly since readnone implies both. The case
2295+
/// which motivates the specialized code is a callee with readnone, and an
2296+
/// operand bundle on the call which disallows readnone but not either
2297+
/// readonly or writeonly.
2298+
bool hasImpliedFnAttr(Attribute::AttrKind Kind) const {
2299+
assert((Kind == Attribute::ReadOnly || Kind == Attribute::WriteOnly) &&
2300+
"use hasFnAttrImpl instead");
2301+
if (Attrs.hasFnAttr(Kind) || Attrs.hasFnAttr(Attribute::ReadNone))
2302+
return true;
2303+
2304+
if (isFnAttrDisallowedByOpBundle(Kind))
2305+
return false;
2306+
2307+
return hasFnAttrOnCalledFunction(Kind) ||
2308+
hasFnAttrOnCalledFunction(Attribute::ReadNone);
2309+
}
2310+
22912311
/// Determine whether the return value has the given attribute. Supports
22922312
/// Attribute::AttrKind and StringRef as \p AttrKind types.
22932313
template <typename AttrKind> bool hasRetAttrImpl(AttrKind Kind) const {

llvm/test/Transforms/InstCombine/trivial-dse-calls.ll

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,6 @@ define void @test_readnone() {
253253

254254
define void @test_readnone_with_deopt() {
255255
; CHECK-LABEL: @test_readnone_with_deopt(
256-
; CHECK-NEXT: call void @removable_readnone() [ "deopt"() ]
257256
; CHECK-NEXT: ret void
258257
;
259258
call void @removable_readnone() [ "deopt"() ]

0 commit comments

Comments
 (0)