Skip to content

Commit 7c38ee2

Browse files
authored
[FunctionAttrs][IR] Fix memory attr inference for volatile mem intrinsics (#122926)
Per LangRef volatile operations can read and write inaccessible memory: > any volatile operation can read and/or modify state which is not > accessible via a regular load or store in this module Model this by adding inaccessible memory effects in getMemoryEffects() if the operation is volatile. In the future, we should model volatile using operand bundles instead. Fixes #120932.
1 parent 5238f06 commit 7c38ee2

File tree

4 files changed

+12
-4
lines changed

4 files changed

+12
-4
lines changed

llvm/lib/Analysis/BasicAliasAnalysis.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -839,6 +839,10 @@ MemoryEffects BasicAAResult::getMemoryEffects(const CallBase *Call,
839839
FuncME |= MemoryEffects::readOnly();
840840
if (Call->hasClobberingOperandBundles())
841841
FuncME |= MemoryEffects::writeOnly();
842+
if (Call->isVolatile()) {
843+
// Volatile operations also access inaccessible memory.
844+
FuncME |= MemoryEffects::inaccessibleMemOnly();
845+
}
842846
Min &= FuncME;
843847
}
844848

llvm/lib/IR/Instructions.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -643,6 +643,10 @@ MemoryEffects CallBase::getMemoryEffects() const {
643643
if (hasClobberingOperandBundles())
644644
FnME |= MemoryEffects::writeOnly();
645645
}
646+
if (isVolatile()) {
647+
// Volatile operations also access inaccessible memory.
648+
FnME |= MemoryEffects::inaccessibleMemOnly();
649+
}
646650
ME &= FnME;
647651
}
648652
return ME;

llvm/test/Transforms/FunctionAttrs/initializes.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,7 @@ define void @memset_neg(ptr %p) {
443443
}
444444

445445
define void @memset_volatile(ptr %p) {
446-
; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: write)
446+
; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: write, inaccessiblemem: readwrite)
447447
; CHECK-LABEL: define void @memset_volatile(
448448
; CHECK-SAME: ptr writeonly [[P:%.*]]) #[[ATTR5:[0-9]+]] {
449449
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr [[P]], i8 2, i64 9, i1 true)
@@ -478,7 +478,7 @@ define void @memcpy(ptr %p, ptr %p2) {
478478
}
479479

480480
define void @memcpy_volatile(ptr %p, ptr %p2) {
481-
; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite)
481+
; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite)
482482
; CHECK-LABEL: define void @memcpy_volatile(
483483
; CHECK-SAME: ptr writeonly [[P:%.*]], ptr readonly [[P2:%.*]]) #[[ATTR6:[0-9]+]] {
484484
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[P]], ptr [[P2]], i64 9, i1 true)
@@ -541,7 +541,7 @@ define void @memmove(ptr %p, ptr %p2) {
541541
}
542542

543543
define void @memmove_volatile(ptr %p, ptr %p2) {
544-
; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite)
544+
; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite)
545545
; CHECK-LABEL: define void @memmove_volatile(
546546
; CHECK-SAME: ptr writeonly [[P:%.*]], ptr readonly [[P2:%.*]]) #[[ATTR6]] {
547547
; CHECK-NEXT: call void @llvm.memmove.p0.p0.i64(ptr [[P]], ptr [[P2]], i64 9, i1 true)

llvm/test/Transforms/FunctionAttrs/nosync.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ declare void @llvm.memset(ptr %dest, i8 %val, i32 %len, i1 %isvolatile)
236236

237237
; negative, checking volatile intrinsics.
238238
define i32 @memcpy_volatile(ptr %ptr1, ptr %ptr2) {
239-
; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite)
239+
; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite)
240240
; CHECK-LABEL: @memcpy_volatile(
241241
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr [[PTR1:%.*]], ptr [[PTR2:%.*]], i32 8, i1 true)
242242
; CHECK-NEXT: ret i32 4

0 commit comments

Comments
 (0)