mirror of
https://github.com/RPCSX/llvm.git
synced 2024-12-12 06:06:19 +00:00
e9afeb0bd1
convert one test to use this. This is a particularly significant milestone because it required a working per-function AA framework which can be queried over each function from within a CGSCC transform pass (and additionally a module analysis to be accessible). This is essentially *the* point of the entire pass manager rewrite. A CGSCC transform is able to query for multiple different function's analysis results. It works. The whole thing appears to actually work and accomplish the original goal. While we were able to hack function attrs and basic-aa to "work" in the old pass manager, this port doesn't use any of that, it directly leverages the new fundamental functionality. For this to work, the CGSCC framework also has to support SCC-based behavior analysis, etc. The only part of the CGSCC pass infrastructure not sorted out at this point are the updates in the face of inlining and running function passes that mutate the call graph. The changes are pretty boring and boiler-plate. Most of the work was factored into more focused preperatory patches. But this is what wires it all together. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@261203 91177308-0d34-0410-b5e6-96231b3b80d8
107 lines
3.0 KiB
LLVM
107 lines
3.0 KiB
LLVM
; RUN: opt < %s -functionattrs -S | FileCheck %s
|
|
; RUN: opt < %s -aa-pipeline=basic-aa -passes='require<targetlibinfo>,cgscc(function-attrs)' -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
|
|
}
|
|
|
|
; CHECK: define void @test7_1(i32* inalloca nocapture %a)
|
|
; inalloca parameters are always considered written
|
|
define void @test7_1(i32* inalloca %a) {
|
|
ret void
|
|
}
|
|
|
|
; CHECK: define i32* @test8_1(i32* readnone %p)
|
|
define i32* @test8_1(i32* %p) {
|
|
entry:
|
|
ret i32* %p
|
|
}
|
|
|
|
; CHECK: define void @test8_2(i32* %p)
|
|
define void @test8_2(i32* %p) {
|
|
entry:
|
|
%call = call i32* @test8_1(i32* %p)
|
|
store i32 10, i32* %call, align 4
|
|
ret void
|
|
}
|
|
|
|
; CHECK: declare void @llvm.masked.scatter
|
|
declare void @llvm.masked.scatter.v4i32(<4 x i32>%val, <4 x i32*>, i32, <4 x i1>)
|
|
|
|
; CHECK-NOT: readnone
|
|
; CHECK-NOT: readonly
|
|
; CHECK: define void @test9
|
|
define void @test9(<4 x i32*> %ptrs, <4 x i32>%val) {
|
|
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>)
|
|
ret void
|
|
}
|
|
|
|
; CHECK: declare <4 x i32> @llvm.masked.gather
|
|
declare <4 x i32> @llvm.masked.gather.v4i32(<4 x i32*>, i32, <4 x i1>, <4 x i32>)
|
|
; CHECK: readonly
|
|
; CHECK: define <4 x i32> @test10
|
|
define <4 x i32> @test10(<4 x i32*> %ptrs) {
|
|
%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)
|
|
ret <4 x i32> %res
|
|
}
|
|
|
|
; CHECK: declare <4 x i32> @test11_1
|
|
declare <4 x i32> @test11_1(<4 x i32*>) argmemonly nounwind readonly
|
|
; CHECK: readonly
|
|
; CHECK-NOT: readnone
|
|
; CHECK: define <4 x i32> @test11_2
|
|
define <4 x i32> @test11_2(<4 x i32*> %ptrs) {
|
|
%res = call <4 x i32> @test11_1(<4 x i32*> %ptrs)
|
|
ret <4 x i32> %res
|
|
}
|
|
|
|
declare <4 x i32> @test12_1(<4 x i32*>) argmemonly nounwind
|
|
; CHECK-NOT: readnone
|
|
; CHECK: define <4 x i32> @test12_2
|
|
define <4 x i32> @test12_2(<4 x i32*> %ptrs) {
|
|
%res = call <4 x i32> @test12_1(<4 x i32*> %ptrs)
|
|
ret <4 x i32> %res
|
|
}
|