summaryrefslogtreecommitdiff
path: root/llvm/test/Transforms/FunctionAttrs/writeonly.ll
blob: 54d00d355f7afa47835238b79a10f8c29ba84bf2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
; RUN: opt < %s -function-attrs         -S | FileCheck %s
; RUN: opt < %s -passes=function-attrs -S | FileCheck %s

; CHECK: define void @nouses-argworn-funrn(i32* nocapture readnone %.aaa) #0 {
define void @nouses-argworn-funrn(i32* writeonly %.aaa) {
nouses-argworn-funrn_entry:
  ret void
}

; CHECK: define void @nouses-argworn-funro(i32* nocapture readnone %.aaa, i32* nocapture readonly %.bbb) #1 {
define void @nouses-argworn-funro(i32* writeonly %.aaa, i32* %.bbb) {
nouses-argworn-funro_entry:
  %val = load i32 , i32* %.bbb
  ret void
}

%_type_of_d-ccc = type <{ i8*, i8, i8, i8, i8 }>

@d-ccc = internal global %_type_of_d-ccc <{ i8* null, i8 1, i8 13, i8 0, i8 -127 }>, align 8

; CHECK: define void @nouses-argworn-funwo(i32* nocapture readnone %.aaa) #2 {
define void @nouses-argworn-funwo(i32* writeonly %.aaa) {
nouses-argworn-funwo_entry:
  store i8 0, i8* getelementptr inbounds (%_type_of_d-ccc, %_type_of_d-ccc* @d-ccc, i32 0, i32 3)
  ret void
}

; CHECK: define void @test_store(i8* nocapture writeonly %p)
define void @test_store(i8* %p) {
  store i8 0, i8* %p
  ret void
}

@G = external global i8*
; CHECK: define i8 @test_store_capture(i8* %p)
define i8 @test_store_capture(i8* %p) {
  store i8* %p, i8** @G
  %p2 = load i8*, i8** @G
  %v = load i8, i8* %p2
  ret i8 %v
}

; CHECK: define void @test_addressing(i8* nocapture writeonly %p)
define void @test_addressing(i8* %p) {
  %gep = getelementptr i8, i8* %p, i64 8
  %bitcast = bitcast i8* %gep to i32*
  store i32 0, i32* %bitcast
  ret void
}

; CHECK: define void @test_readwrite(i8* nocapture %p)
define void @test_readwrite(i8* %p) {
  %v = load i8, i8* %p
  store i8 %v, i8* %p
  ret void
}

; CHECK: define void @test_volatile(i8* %p)
define void @test_volatile(i8* %p) {
  store volatile i8 0, i8* %p
  ret void
}

; CHECK: define void @test_atomicrmw(i8* nocapture %p)
define void @test_atomicrmw(i8* %p) {
  atomicrmw add i8* %p, i8 0  seq_cst
  ret void
}


declare void @direct1_callee(i8* %p)

; CHECK: define void @direct1(i8* %p)
define void @direct1(i8* %p) {
  call void @direct1_callee(i8* %p)
  ret void
}

declare void @direct2_callee(i8* %p) writeonly

; CHECK: define void @direct2(i8* %p)
define void @direct2(i8* %p) {
  call void @direct2_callee(i8* %p)
  ret void
}

declare void @direct3_callee(i8* writeonly %p)

; CHECK: define void @direct3(i8* %p)
define void @direct3(i8* %p) {
  call void @direct3_callee(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)
  ret void
}

; CHECK: define void @fptr_test2(i8* %p, void (i8*)* nocapture readonly %f)
define void @fptr_test2(i8* %p, void (i8*)* %f) {
  call void %f(i8* writeonly %p)
  ret void
}

; CHECK: define void @fptr_test3(i8* %p, void (i8*)* nocapture readonly %f)
define void @fptr_test3(i8* %p, void (i8*)* %f) {
  call void %f(i8* %p) writeonly
  ret void
}

; CHECK: attributes #0 = { {{.*}}readnone{{.*}} }
; CHECK: attributes #1 = { {{.*}}readonly{{.*}} }
; CHECK: attributes #2 = { {{.*}}writeonly{{.*}} }