1; RUN: opt -S -function-attrs < %s -enable-new-pm=0 | FileCheck %s
2
3declare void @f_readonly() readonly
4declare void @f_readnone() readnone
5declare void @f_writeonly() writeonly
6
7define void @test_0(i32* %x) {
8; FunctionAttrs must not infer readonly / readnone for %x
9
10; CHECK-LABEL: define void @test_0(i32* %x) #3 {
11 entry:
12 ; CHECK: call void @f_readonly() [ "foo"(i32* %x) ]
13  call void @f_readonly() [ "foo"(i32* %x) ]
14  ret void
15}
16
17define void @test_1(i32* %x) {
18; FunctionAttrs must not infer readonly / readnone for %x
19
20; CHECK-LABEL: define void @test_1(i32* %x) #4 {
21 entry:
22 ; CHECK: call void @f_readnone() [ "foo"(i32* %x) ]
23  call void @f_readnone() [ "foo"(i32* %x) ]
24  ret void
25}
26
27define void @test_2(i32* %x) {
28; FunctionAttrs must not infer writeonly
29
30; CHECK-LABEL: define void @test_2(i32* %x) {
31 entry:
32 ; CHECK: call void @f_writeonly() [ "foo"(i32* %x) ]
33  call void @f_writeonly() [ "foo"(i32* %x) ]
34  ret void
35}
36
37define void @test_3(i32* %x) {
38; The "deopt" operand bundle does not capture or write to %x.
39
40; CHECK-LABEL: define void @test_3(i32* nocapture readonly %x)
41 entry:
42  call void @f_readonly() [ "deopt"(i32* %x) ]
43  ret void
44}
45
46; CHECK: attributes #0 = { nofree readonly }
47; CHECK: attributes #1 = { nofree nosync readnone }
48; CHECK: attributes #2 = { writeonly }
49; CHECK: attributes #3 = { nofree }
50; CHECK: attributes #4 = { nofree nosync }
51