Fix incorrect inference of writeonly despite reading operand bundle

If we have a writeonly function called from a callsite with a potentially reading operand bundle, we can not conclude the callsite is writeonly.

The changed test is the only one I've been able to demonstrate a current miscompile on, but an incorrect result here could show up in a bunch of subtle ways.  For instance, this issue caused several spurious test changes when combined with D117591.
This commit is contained in:
Philip Reames 2022-01-18 12:08:40 -08:00
parent d3b756c51c
commit 43907d608a
2 changed files with 6 additions and 4 deletions

View File

@ -2087,8 +2087,8 @@ public:
/// Is the function attribute S disallowed by some operand bundle on /// Is the function attribute S disallowed by some operand bundle on
/// this operand bundle user? /// this operand bundle user?
bool isFnAttrDisallowedByOpBundle(StringRef S) const { bool isFnAttrDisallowedByOpBundle(StringRef S) const {
// Operand bundles only possibly disallow readnone, readonly and argmemonly // Operand bundles only possibly disallow memory access attributes. All
// attributes. All String attributes are fine. // String attributes are fine.
return false; return false;
} }
@ -2113,6 +2113,9 @@ public:
case Attribute::ReadOnly: case Attribute::ReadOnly:
return hasClobberingOperandBundles(); return hasClobberingOperandBundles();
case Attribute::WriteOnly:
return hasReadingOperandBundles();
} }
llvm_unreachable("switch has a default case!"); llvm_unreachable("switch has a default case!");

View File

@ -24,11 +24,10 @@ define void @test_1(i32* %x) {
ret void ret void
} }
; FIXME: We are incorectly inferring writeonly on the function
define void @test_2(i32* %x) { define void @test_2(i32* %x) {
; FunctionAttrs must not infer writeonly ; FunctionAttrs must not infer writeonly
; CHECK-LABEL: define void @test_2(i32* %x) #2 { ; CHECK-LABEL: define void @test_2(i32* %x) {
entry: entry:
; CHECK: call void @f_writeonly() [ "foo"(i32* %x) ] ; CHECK: call void @f_writeonly() [ "foo"(i32* %x) ]
call void @f_writeonly() [ "foo"(i32* %x) ] call void @f_writeonly() [ "foo"(i32* %x) ]