diff options
| author | Philip Reames <listmail@philipreames.com> | 2022-01-18 12:08:02 -0800 |
|---|---|---|
| committer | Philip Reames <listmail@philipreames.com> | 2022-01-18 12:08:14 -0800 |
| commit | 7ac65f6b2e961d3eda547b50eefdab8a04d819fd (patch) | |
| tree | 2b11af42dc7569408fe4fe666f77229aab345812 | |
| parent | bf366bd9dfe4abcb7b54a66c1006173462900348 (diff) | |
[tests] Add coverage of writeonly attribute and operand bundle intersection
| -rw-r--r-- | llvm/test/Feature/OperandBundles/function-attrs.ll | 25 | ||||
| -rw-r--r-- | llvm/test/Transforms/DeadStoreElimination/trivial-dse-calls.ll | 14 | ||||
| -rw-r--r-- | llvm/test/Transforms/FunctionAttrs/writeonly.ll | 6 |
3 files changed, 40 insertions, 5 deletions
diff --git a/llvm/test/Feature/OperandBundles/function-attrs.ll b/llvm/test/Feature/OperandBundles/function-attrs.ll index 4a27425e922b..a27daef5fca3 100644 --- a/llvm/test/Feature/OperandBundles/function-attrs.ll +++ b/llvm/test/Feature/OperandBundles/function-attrs.ll @@ -2,11 +2,12 @@ declare void @f_readonly() readonly declare void @f_readnone() readnone +declare void @f_writeonly() writeonly define void @test_0(i32* %x) { ; FunctionAttrs must not infer readonly / readnone for %x -; CHECK-LABEL: define void @test_0(i32* %x) #2 { +; CHECK-LABEL: define void @test_0(i32* %x) #3 { entry: ; CHECK: call void @f_readonly() [ "foo"(i32* %x) ] call void @f_readonly() [ "foo"(i32* %x) ] @@ -16,21 +17,35 @@ define void @test_0(i32* %x) { define void @test_1(i32* %x) { ; FunctionAttrs must not infer readonly / readnone for %x -; CHECK-LABEL: define void @test_1(i32* %x) #3 { +; CHECK-LABEL: define void @test_1(i32* %x) #4 { entry: ; CHECK: call void @f_readnone() [ "foo"(i32* %x) ] call void @f_readnone() [ "foo"(i32* %x) ] ret void } +; FIXME: We are incorectly inferring writeonly on the function define void @test_2(i32* %x) { +; FunctionAttrs must not infer writeonly + +; CHECK-LABEL: define void @test_2(i32* %x) #2 { + entry: + ; CHECK: call void @f_writeonly() [ "foo"(i32* %x) ] + call void @f_writeonly() [ "foo"(i32* %x) ] + ret void +} + +define void @test_3(i32* %x) { ; The "deopt" operand bundle does not capture or write to %x. -; CHECK-LABEL: define void @test_2(i32* nocapture readonly %x) +; CHECK-LABEL: define void @test_3(i32* nocapture readonly %x) entry: call void @f_readonly() [ "deopt"(i32* %x) ] ret void } -; CHECK: attributes #2 = { nofree } -; CHECK: attributes #3 = { nofree nosync } +; CHECK: attributes #0 = { nofree readonly } +; CHECK: attributes #1 = { nofree nosync readnone } +; CHECK: attributes #2 = { writeonly } +; CHECK: attributes #3 = { nofree } +; CHECK: attributes #4 = { nofree nosync } diff --git a/llvm/test/Transforms/DeadStoreElimination/trivial-dse-calls.ll b/llvm/test/Transforms/DeadStoreElimination/trivial-dse-calls.ll index 1966559f5d39..d58178288444 100644 --- a/llvm/test/Transforms/DeadStoreElimination/trivial-dse-calls.ll +++ b/llvm/test/Transforms/DeadStoreElimination/trivial-dse-calls.ll @@ -193,6 +193,20 @@ define i32 @test_neg_captured_before() { ret i32 %res } +; Callee might be dead, but op bundle has unknown semantics and thus isn't. +define void @test_new_op_bundle() { +; CHECK-LABEL: @test_new_op_bundle( +; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 +; CHECK-NEXT: [[BITCAST:%.*]] = bitcast i32* [[A]] to i8* +; CHECK-NEXT: call void @f(i8* nocapture writeonly [[BITCAST]]) #[[ATTR1]] [ "unknown"(i8* [[BITCAST]]) ] +; CHECK-NEXT: ret void +; + %a = alloca i32, align 4 + %bitcast = bitcast i32* %a to i8* + call void @f(i8* writeonly nocapture %bitcast) argmemonly nounwind willreturn ["unknown" (i8* %bitcast)] + ret void +} + ; Show that reading from unrelated memory is okay define void @test_unreleated_read() { ; CHECK-LABEL: @test_unreleated_read( diff --git a/llvm/test/Transforms/FunctionAttrs/writeonly.ll b/llvm/test/Transforms/FunctionAttrs/writeonly.ll index 5094d6914929..e3aa04d4de2c 100644 --- a/llvm/test/Transforms/FunctionAttrs/writeonly.ll +++ b/llvm/test/Transforms/FunctionAttrs/writeonly.ll @@ -100,6 +100,12 @@ define void @direct3(i8* %p) { ret void } +; CHECK: define void @direct3b(i8* %p) +define void @direct3b(i8* %p) { + call void @direct3_callee(i8* %p) ["may-read-and-capture"(i8* %p)] + ret void +} + ; CHECK: define void @fptr_test1(i8* %p, void (i8*)* nocapture readonly %f) define void @fptr_test1(i8* %p, void (i8*)* %f) { call void %f(i8* %p) |
