Index: llvm/lib/IR/Instructions.cpp =================================================================== --- llvm/lib/IR/Instructions.cpp +++ llvm/lib/IR/Instructions.cpp @@ -344,9 +344,25 @@ if (Attrs.hasParamAttr(ArgNo, Kind)) return true; - if (const Function *F = getCalledFunction()) - return F->getAttributes().hasParamAttr(ArgNo, Kind); - return false; + + const Function *F = getCalledFunction(); + if (!F) + return false; + + if (!F->getAttributes().hasParamAttr(ArgNo, Kind)) + return false; + + // Take into account mod/ref by operand bundles. + switch (Kind) { + case Attribute::ReadNone: + return !hasReadingOperandBundles() && !hasClobberingOperandBundles(); + case Attribute::ReadOnly: + return !hasClobberingOperandBundles(); + case Attribute::WriteOnly: + return !hasReadingOperandBundles(); + default: + return true; + } } bool CallBase::hasFnAttrOnCalledFunction(Attribute::AttrKind Kind) const { Index: llvm/test/Transforms/FunctionAttrs/readattrs.ll =================================================================== --- llvm/test/Transforms/FunctionAttrs/readattrs.ll +++ llvm/test/Transforms/FunctionAttrs/readattrs.ll @@ -326,9 +326,10 @@ declare void @readnone_param(ptr nocapture readnone %p) declare void @readonly_param(ptr nocapture readonly %p) +; FIXME: While this can't be readnone, this could be readonly. define void @op_bundle_readnone_deopt(ptr %p) { ; CHECK-LABEL: define {{[^@]+}}@op_bundle_readnone_deopt -; CHECK-SAME: (ptr nocapture readnone [[P:%.*]]) { +; CHECK-SAME: (ptr nocapture [[P:%.*]]) { ; CHECK-NEXT: call void @readnone_param(ptr [[P]]) [ "deopt"() ] ; CHECK-NEXT: ret void ; @@ -338,7 +339,7 @@ define void @op_bundle_readnone_unknown(ptr %p) { ; CHECK-LABEL: define {{[^@]+}}@op_bundle_readnone_unknown -; CHECK-SAME: (ptr nocapture readnone [[P:%.*]]) { +; CHECK-SAME: (ptr nocapture [[P:%.*]]) { ; CHECK-NEXT: call void @readnone_param(ptr [[P]]) [ "unknown"() ] ; CHECK-NEXT: ret void ; @@ -358,7 +359,7 @@ define void @op_bundle_readonly_unknown(ptr %p) { ; CHECK-LABEL: define {{[^@]+}}@op_bundle_readonly_unknown -; CHECK-SAME: (ptr nocapture readonly [[P:%.*]]) { +; CHECK-SAME: (ptr nocapture [[P:%.*]]) { ; CHECK-NEXT: call void @readonly_param(ptr [[P]]) [ "unknown"() ] ; CHECK-NEXT: ret void ; Index: llvm/test/Transforms/FunctionAttrs/writeonly.ll =================================================================== --- llvm/test/Transforms/FunctionAttrs/writeonly.ll +++ llvm/test/Transforms/FunctionAttrs/writeonly.ll @@ -180,7 +180,7 @@ define void @direct3c(ptr %p) { ; CHECK-LABEL: define {{[^@]+}}@direct3c -; CHECK-SAME: (ptr nocapture writeonly [[P:%.*]]) { +; CHECK-SAME: (ptr nocapture [[P:%.*]]) { ; CHECK-NEXT: call void @direct3_callee(ptr [[P]]) [ "may-read"() ] ; CHECK-NEXT: ret void ;