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 116 117 118 119 120 121 122 123 124 125 126 127 128 129
|
; 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
; writeonly w/o nocapture is not enough
; CHECK: define void @direct2(i8* %p)
define void @direct2(i8* %p) {
call void @direct2_callee(i8* %p)
; read back from global, read through pointer...
ret void
}
; CHECK: define void @direct2b(i8* nocapture writeonly %p)
define void @direct2b(i8* %p) {
call void @direct2_callee(i8* nocapture %p)
ret void
}
declare void @direct3_callee(i8* nocapture writeonly %p)
; CHECK: define void @direct3(i8* nocapture writeonly %p)
define void @direct3(i8* %p) {
call void @direct3_callee(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)
ret void
}
; CHECK: define void @fptr_test2(i8* nocapture writeonly %p, void (i8*)* nocapture readonly %f)
define void @fptr_test2(i8* %p, void (i8*)* %f) {
call void %f(i8* nocapture writeonly %p)
ret void
}
; CHECK: define void @fptr_test3(i8* nocapture writeonly %p, void (i8*)* nocapture readonly %f)
define void @fptr_test3(i8* %p, void (i8*)* %f) {
call void %f(i8* nocapture %p) writeonly
ret void
}
; CHECK: attributes #0 = { {{.*}}readnone{{.*}} }
; CHECK: attributes #1 = { {{.*}}readonly{{.*}} }
; CHECK: attributes #2 = { {{.*}}writeonly{{.*}} }
|