1 ; RUN: opt < %s -functionattrs -S | FileCheck %s 2 @x = global i32 0 3 4 declare void @test1_1(i8* %x1_1, i8* readonly %y1_1, ...) 5 6 ; CHECK: define void @test1_2(i8* %x1_2, i8* readonly %y1_2, i8* %z1_2) 7 define void @test1_2(i8* %x1_2, i8* %y1_2, i8* %z1_2) { 8 call void (i8*, i8*, ...) @test1_1(i8* %x1_2, i8* %y1_2, i8* %z1_2) 9 store i32 0, i32* @x 10 ret void 11 } 12 13 ; CHECK: define i8* @test2(i8* readnone %p) 14 define i8* @test2(i8* %p) { 15 store i32 0, i32* @x 16 ret i8* %p 17 } 18 19 ; CHECK: define i1 @test3(i8* readnone %p, i8* readnone %q) 20 define i1 @test3(i8* %p, i8* %q) { 21 %A = icmp ult i8* %p, %q 22 ret i1 %A 23 } 24 25 declare void @test4_1(i8* nocapture) readonly 26 27 ; CHECK: define void @test4_2(i8* nocapture readonly %p) 28 define void @test4_2(i8* %p) { 29 call void @test4_1(i8* %p) 30 ret void 31 } 32 33 ; CHECK: define void @test5(i8** nocapture %p, i8* %q) 34 ; Missed optz'n: we could make %q readnone, but don't break test6! 35 define void @test5(i8** %p, i8* %q) { 36 store i8* %q, i8** %p 37 ret void 38 } 39 40 declare void @test6_1() 41 ; CHECK: define void @test6_2(i8** nocapture %p, i8* %q) 42 ; This is not a missed optz'n. 43 define void @test6_2(i8** %p, i8* %q) { 44 store i8* %q, i8** %p 45 call void @test6_1() 46 ret void 47 } 48 49 ; CHECK: define void @test7_1(i32* inalloca nocapture %a) 50 ; inalloca parameters are always considered written 51 define void @test7_1(i32* inalloca %a) { 52 ret void 53 } 54 55 ; CHECK: define i32* @test8_1(i32* readnone %p) 56 define i32* @test8_1(i32* %p) { 57 entry: 58 ret i32* %p 59 } 60 61 ; CHECK: define void @test8_2(i32* %p) 62 define void @test8_2(i32* %p) { 63 entry: 64 %call = call i32* @test8_1(i32* %p) 65 store i32 10, i32* %call, align 4 66 ret void 67 } 68 69 ; CHECK: declare void @llvm.masked.scatter 70 declare void @llvm.masked.scatter.v4i32(<4 x i32>%val, <4 x i32*>, i32, <4 x i1>) 71 72 ; CHECK-NOT: readnone 73 ; CHECK-NOT: readonly 74 ; CHECK: define void @test9 75 define void @test9(<4 x i32*> %ptrs, <4 x i32>%val) { 76 call void @llvm.masked.scatter.v4i32(<4 x i32>%val, <4 x i32*> %ptrs, i32 4, <4 x i1><i1 true, i1 false, i1 true, i1 false>) 77 ret void 78 } 79 80 ; CHECK: declare <4 x i32> @llvm.masked.gather 81 declare <4 x i32> @llvm.masked.gather.v4i32(<4 x i32*>, i32, <4 x i1>, <4 x i32>) 82 ; CHECK: readonly 83 ; CHECK: define <4 x i32> @test10 84 define <4 x i32> @test10(<4 x i32*> %ptrs) { 85 %res = call <4 x i32> @llvm.masked.gather.v4i32(<4 x i32*> %ptrs, i32 4, <4 x i1><i1 true, i1 false, i1 true, i1 false>, <4 x i32>undef) 86 ret <4 x i32> %res 87 } 88 89 ; CHECK: declare <4 x i32> @test11_1 90 declare <4 x i32> @test11_1(<4 x i32*>) argmemonly nounwind readonly 91 ; CHECK: readonly 92 ; CHECK-NOT: readnone 93 ; CHECK: define <4 x i32> @test11_2 94 define <4 x i32> @test11_2(<4 x i32*> %ptrs) { 95 %res = call <4 x i32> @test11_1(<4 x i32*> %ptrs) 96 ret <4 x i32> %res 97 } 98 99 declare <4 x i32> @test12_1(<4 x i32*>) argmemonly nounwind 100 ; CHECK-NOT: readnone 101 ; CHECK: define <4 x i32> @test12_2 102 define <4 x i32> @test12_2(<4 x i32*> %ptrs) { 103 %res = call <4 x i32> @test12_1(<4 x i32*> %ptrs) 104 ret <4 x i32> %res 105 } 106