diff options
author | Nick Lewycky <nicholas@mxc.ca> | 2013-07-06 00:29:58 +0000 |
---|---|---|
committer | Nick Lewycky <nicholas@mxc.ca> | 2013-07-06 00:29:58 +0000 |
commit | c2ec0725cedceb851858c3991fbdd36ee9ac85dd (patch) | |
tree | 841ddf4ab15a0d446543803d7124a7716619cb04 /llvm/test/Transforms/FunctionAttrs | |
parent | e8545dde7be8fe78e64bf4d9578c25368243c274 (diff) | |
download | bcm5719-llvm-c2ec0725cedceb851858c3991fbdd36ee9ac85dd.tar.gz bcm5719-llvm-c2ec0725cedceb851858c3991fbdd36ee9ac85dd.zip |
Extend 'readonly' and 'readnone' to work on function arguments as well as
functions. Make the function attributes pass add it to known library functions
and when it can deduce it.
llvm-svn: 185735
Diffstat (limited to 'llvm/test/Transforms/FunctionAttrs')
6 files changed, 72 insertions, 14 deletions
diff --git a/llvm/test/Transforms/FunctionAttrs/2009-01-02-LocalStores.ll b/llvm/test/Transforms/FunctionAttrs/2009-01-02-LocalStores.ll index f38c03acca3..0cf1cb7c638 100644 --- a/llvm/test/Transforms/FunctionAttrs/2009-01-02-LocalStores.ll +++ b/llvm/test/Transforms/FunctionAttrs/2009-01-02-LocalStores.ll @@ -1,14 +1,23 @@ -; RUN: opt < %s -functionattrs -S | not grep "nocapture *%%q" -; RUN: opt < %s -functionattrs -S | grep "nocapture *%%p" +; RUN: opt < %s -functionattrs -S | FileCheck %s +; CHECK: define i32* @a(i32** nocapture readonly %p) define i32* @a(i32** %p) { %tmp = load i32** %p ret i32* %tmp } +; CHECK: define i32* @b(i32* %q) define i32* @b(i32 *%q) { %mem = alloca i32* store i32* %q, i32** %mem %tmp = call i32* @a(i32** %mem) ret i32* %tmp } + +; CHECK: define i32* @c(i32* readnone %r) +@g = global i32 0 +define i32* @c(i32 *%r) { + %a = icmp eq i32* %r, null + store i32 1, i32* @g + ret i32* %r +} diff --git a/llvm/test/Transforms/FunctionAttrs/2009-01-04-Annotate.ll b/llvm/test/Transforms/FunctionAttrs/2009-01-04-Annotate.ll index d414b73524f..fa06cc718a9 100644 --- a/llvm/test/Transforms/FunctionAttrs/2009-01-04-Annotate.ll +++ b/llvm/test/Transforms/FunctionAttrs/2009-01-04-Annotate.ll @@ -1,6 +1,6 @@ ; RUN: opt < %s -functionattrs -S | FileCheck %s -; CHECK: declare noalias i8* @fopen(i8* nocapture, i8* nocapture) #0 +; CHECK: declare noalias i8* @fopen(i8* nocapture readonly, i8* nocapture readonly) #0 declare i8* @fopen(i8*, i8*) ; CHECK: declare i8 @strlen(i8* nocapture) #1 diff --git a/llvm/test/Transforms/FunctionAttrs/annotate-1.ll b/llvm/test/Transforms/FunctionAttrs/annotate-1.ll index ca78212f349..adb7bce57f8 100644 --- a/llvm/test/Transforms/FunctionAttrs/annotate-1.ll +++ b/llvm/test/Transforms/FunctionAttrs/annotate-1.ll @@ -2,7 +2,7 @@ ; RUN: opt < %s -mtriple=x86_64-apple-macosx10.8.0 -functionattrs -S | FileCheck -check-prefix=POSIX %s declare i8* @fopen(i8*, i8*) -; CHECK: declare noalias i8* @fopen(i8* nocapture, i8* nocapture) [[G0:#[0-9]]] +; CHECK: declare noalias i8* @fopen(i8* nocapture readonly, i8* nocapture readonly) [[G0:#[0-9]]] declare i8 @strlen(i8*) ; CHECK: declare i8 @strlen(i8* nocapture) [[G1:#[0-9]]] diff --git a/llvm/test/Transforms/FunctionAttrs/atomic.ll b/llvm/test/Transforms/FunctionAttrs/atomic.ll index 027ee0fd06a..d5a8db7d53b 100644 --- a/llvm/test/Transforms/FunctionAttrs/atomic.ll +++ b/llvm/test/Transforms/FunctionAttrs/atomic.ll @@ -13,7 +13,7 @@ entry: ; A function with an Acquire load is not readonly. define i32 @test2(i32* %x) uwtable ssp { -; CHECK: define i32 @test2(i32* nocapture %x) #1 { +; CHECK: define i32 @test2(i32* nocapture readonly %x) #1 { entry: %r = load atomic i32* %x seq_cst, align 4 ret i32 %r diff --git a/llvm/test/Transforms/FunctionAttrs/nocapture.ll b/llvm/test/Transforms/FunctionAttrs/nocapture.ll index 3027acd35c7..110bd03dac7 100644 --- a/llvm/test/Transforms/FunctionAttrs/nocapture.ll +++ b/llvm/test/Transforms/FunctionAttrs/nocapture.ll @@ -1,12 +1,13 @@ ; RUN: opt < %s -functionattrs -S | FileCheck %s @g = global i32* null ; <i32**> [#uses=1] -; CHECK: define i32* @c1(i32* %q) +; CHECK: define i32* @c1(i32* readnone %q) define i32* @c1(i32* %q) { ret i32* %q } ; CHECK: define void @c2(i32* %q) +; It would also be acceptable to mark %q as readnone. Update @c3 too. define void @c2(i32* %q) { store i32* %q, i32** @g ret void @@ -45,7 +46,7 @@ define i1 @c5(i32* %q, i32 %bitno) { declare void @throw_if_bit_set(i8*, i8) readonly -; CHECK: define i1 @c6(i8* %q, i8 %bit) +; CHECK: define i1 @c6(i8* readonly %q, i8 %bit) define i1 @c6(i8* %q, i8 %bit) { invoke void @throw_if_bit_set(i8* %q, i8 %bit) to label %ret0 unwind label %ret1 @@ -67,7 +68,7 @@ define i1* @lookup_bit(i32* %q, i32 %bitno) readnone nounwind { ret i1* %lookup } -; CHECK: define i1 @c7(i32* %q, i32 %bitno) +; CHECK: define i1 @c7(i32* readnone %q, i32 %bitno) define i1 @c7(i32* %q, i32 %bitno) { %ptr = call i1* @lookup_bit(i32* %q, i32 %bitno) %val = load i1* %ptr @@ -103,7 +104,7 @@ define void @nc3(void ()* %p) { } declare void @external(i8*) readonly nounwind -; CHECK: define void @nc4(i8* nocapture %p) +; CHECK: define void @nc4(i8* nocapture readonly %p) define void @nc4(i8* %p) { call void @external(i8* %p) ret void @@ -116,28 +117,29 @@ define void @nc5(void (i8*)* %f, i8* %p) { ret void } -; CHECK: define void @test1_1(i8* nocapture %x1_1, i8* %y1_1) +; CHECK: define void @test1_1(i8* nocapture readnone %x1_1, i8* %y1_1) +; It would be acceptable to add readnone to %y1_1 and %y1_2. define void @test1_1(i8* %x1_1, i8* %y1_1) { call i8* @test1_2(i8* %x1_1, i8* %y1_1) store i32* null, i32** @g ret void } -; CHECK: define i8* @test1_2(i8* nocapture %x1_2, i8* %y1_2) +; CHECK: define i8* @test1_2(i8* nocapture readnone %x1_2, i8* %y1_2) define i8* @test1_2(i8* %x1_2, i8* %y1_2) { call void @test1_1(i8* %x1_2, i8* %y1_2) store i32* null, i32** @g ret i8* %y1_2 } -; CHECK: define void @test2(i8* nocapture %x2) +; CHECK: define void @test2(i8* nocapture readnone %x2) define void @test2(i8* %x2) { call void @test2(i8* %x2) store i32* null, i32** @g ret void } -; CHECK: define void @test3(i8* nocapture %x3, i8* nocapture %y3, i8* nocapture %z3) +; CHECK: define void @test3(i8* nocapture readnone %x3, i8* nocapture readnone %y3, i8* nocapture readnone %z3) define void @test3(i8* %x3, i8* %y3, i8* %z3) { call void @test3(i8* %z3, i8* %y3, i8* %x3) store i32* null, i32** @g @@ -151,7 +153,7 @@ define void @test4_1(i8* %x4_1) { ret void } -; CHECK: define i8* @test4_2(i8* nocapture %x4_2, i8* %y4_2, i8* nocapture %z4_2) +; CHECK: define i8* @test4_2(i8* nocapture readnone %x4_2, i8* readnone %y4_2, i8* nocapture readnone %z4_2) define i8* @test4_2(i8* %x4_2, i8* %y4_2, i8* %z4_2) { call void @test4_1(i8* null) store i32* null, i32** @g diff --git a/llvm/test/Transforms/FunctionAttrs/readattrs.ll b/llvm/test/Transforms/FunctionAttrs/readattrs.ll new file mode 100644 index 00000000000..0842f566d12 --- /dev/null +++ b/llvm/test/Transforms/FunctionAttrs/readattrs.ll @@ -0,0 +1,47 @@ +; RUN: opt < %s -functionattrs -S | FileCheck %s +@x = global i32 0 + +declare void @test1_1(i8* %x1_1, i8* readonly %y1_1, ...) + +; CHECK: define void @test1_2(i8* %x1_2, i8* readonly %y1_2, i8* %z1_2) +define void @test1_2(i8* %x1_2, i8* %y1_2, i8* %z1_2) { + call void (i8*, i8*, ...)* @test1_1(i8* %x1_2, i8* %y1_2, i8* %z1_2) + store i32 0, i32* @x + ret void +} + +; CHECK: define i8* @test2(i8* readnone %p) +define i8* @test2(i8* %p) { + store i32 0, i32* @x + ret i8* %p +} + +; CHECK: define i1 @test3(i8* readnone %p, i8* readnone %q) +define i1 @test3(i8* %p, i8* %q) { + %A = icmp ult i8* %p, %q + ret i1 %A +} + +declare void @test4_1(i8* nocapture) readonly + +; CHECK: define void @test4_2(i8* nocapture readonly %p) +define void @test4_2(i8* %p) { + call void @test4_1(i8* %p) + ret void +} + +; CHECK: define void @test5(i8** nocapture %p, i8* %q) +; Missed optz'n: we could make %q readnone, but don't break test6! +define void @test5(i8** %p, i8* %q) { + store i8* %q, i8** %p + ret void +} + +declare void @test6_1() +; CHECK: define void @test6_2(i8** nocapture %p, i8* %q) +; This is not a missed optz'n. +define void @test6_2(i8** %p, i8* %q) { + store i8* %q, i8** %p + call void @test6_1() + ret void +} |