mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-24 21:42:54 +02:00
3a1d9fe91a
most of the inliner test cases. The inliner involves a bunch of interesting code and tends to be where most of the issues I've seen experimenting with the new PM lie. All of these test cases pass, but I'd like to keep some more thorough coverage here so doing a fairly blanket enabling. There are a handful of interesting tests I've not enabled yet because they're focused on the always inliner, or on functionality that doesn't (yet) exist in the inliner. llvm-svn: 290592
131 lines
4.0 KiB
LLVM
131 lines
4.0 KiB
LLVM
; RUN: opt < %s -inline -S | FileCheck %s
|
|
; RUN: opt < %s -passes='cgscc(inline)' -S | FileCheck %s
|
|
|
|
; Inlining a byval struct should cause an explicit copy into an alloca.
|
|
|
|
%struct.ss = type { i32, i64 }
|
|
@.str = internal constant [10 x i8] c"%d, %lld\0A\00" ; <[10 x i8]*> [#uses=1]
|
|
|
|
define internal void @f(%struct.ss* byval %b) nounwind {
|
|
entry:
|
|
%tmp = getelementptr %struct.ss, %struct.ss* %b, i32 0, i32 0 ; <i32*> [#uses=2]
|
|
%tmp1 = load i32, i32* %tmp, align 4 ; <i32> [#uses=1]
|
|
%tmp2 = add i32 %tmp1, 1 ; <i32> [#uses=1]
|
|
store i32 %tmp2, i32* %tmp, align 4
|
|
ret void
|
|
}
|
|
|
|
declare i32 @printf(i8*, ...) nounwind
|
|
|
|
define i32 @test1() nounwind {
|
|
entry:
|
|
%S = alloca %struct.ss ; <%struct.ss*> [#uses=4]
|
|
%tmp1 = getelementptr %struct.ss, %struct.ss* %S, i32 0, i32 0 ; <i32*> [#uses=1]
|
|
store i32 1, i32* %tmp1, align 8
|
|
%tmp4 = getelementptr %struct.ss, %struct.ss* %S, i32 0, i32 1 ; <i64*> [#uses=1]
|
|
store i64 2, i64* %tmp4, align 4
|
|
call void @f( %struct.ss* byval %S ) nounwind
|
|
ret i32 0
|
|
; CHECK: @test1()
|
|
; CHECK: %S1 = alloca %struct.ss
|
|
; CHECK: %S = alloca %struct.ss
|
|
; CHECK: call void @llvm.memcpy
|
|
; CHECK: ret i32 0
|
|
}
|
|
|
|
; Inlining a byval struct should NOT cause an explicit copy
|
|
; into an alloca if the function is readonly
|
|
|
|
define internal i32 @f2(%struct.ss* byval %b) nounwind readonly {
|
|
entry:
|
|
%tmp = getelementptr %struct.ss, %struct.ss* %b, i32 0, i32 0 ; <i32*> [#uses=2]
|
|
%tmp1 = load i32, i32* %tmp, align 4 ; <i32> [#uses=1]
|
|
%tmp2 = add i32 %tmp1, 1 ; <i32> [#uses=1]
|
|
ret i32 %tmp2
|
|
}
|
|
|
|
define i32 @test2() nounwind {
|
|
entry:
|
|
%S = alloca %struct.ss ; <%struct.ss*> [#uses=4]
|
|
%tmp1 = getelementptr %struct.ss, %struct.ss* %S, i32 0, i32 0 ; <i32*> [#uses=1]
|
|
store i32 1, i32* %tmp1, align 8
|
|
%tmp4 = getelementptr %struct.ss, %struct.ss* %S, i32 0, i32 1 ; <i64*> [#uses=1]
|
|
store i64 2, i64* %tmp4, align 4
|
|
%X = call i32 @f2( %struct.ss* byval %S ) nounwind
|
|
ret i32 %X
|
|
; CHECK: @test2()
|
|
; CHECK: %S = alloca %struct.ss
|
|
; CHECK-NOT: call void @llvm.memcpy
|
|
; CHECK: ret i32
|
|
}
|
|
|
|
|
|
; Inlining a byval with an explicit alignment needs to use *at least* that
|
|
; alignment on the generated alloca.
|
|
; PR8769
|
|
declare void @g3(%struct.ss* %p)
|
|
|
|
define internal void @f3(%struct.ss* byval align 64 %b) nounwind {
|
|
call void @g3(%struct.ss* %b) ;; Could make alignment assumptions!
|
|
ret void
|
|
}
|
|
|
|
define void @test3() nounwind {
|
|
entry:
|
|
%S = alloca %struct.ss, align 1 ;; May not be aligned.
|
|
call void @f3( %struct.ss* byval align 64 %S) nounwind
|
|
ret void
|
|
; CHECK: @test3()
|
|
; CHECK: %S1 = alloca %struct.ss, align 64
|
|
; CHECK: %S = alloca %struct.ss
|
|
; CHECK: call void @llvm.memcpy
|
|
; CHECK: call void @g3(%struct.ss* %S1)
|
|
; CHECK: ret void
|
|
}
|
|
|
|
|
|
; Inlining a byval struct should NOT cause an explicit copy
|
|
; into an alloca if the function is readonly, but should increase an alloca's
|
|
; alignment to satisfy an explicit alignment request.
|
|
|
|
define internal i32 @f4(%struct.ss* byval align 64 %b) nounwind readonly {
|
|
call void @g3(%struct.ss* %b)
|
|
ret i32 4
|
|
}
|
|
|
|
define i32 @test4() nounwind {
|
|
entry:
|
|
%S = alloca %struct.ss, align 2 ; <%struct.ss*> [#uses=4]
|
|
%X = call i32 @f4( %struct.ss* byval align 64 %S ) nounwind
|
|
ret i32 %X
|
|
; CHECK: @test4()
|
|
; CHECK: %S = alloca %struct.ss, align 64
|
|
; CHECK-NOT: call void @llvm.memcpy
|
|
; CHECK: call void @g3
|
|
; CHECK: ret i32 4
|
|
}
|
|
|
|
%struct.S0 = type { i32 }
|
|
|
|
@b = global %struct.S0 { i32 1 }, align 4
|
|
@a = common global i32 0, align 4
|
|
|
|
define internal void @f5(%struct.S0* byval nocapture readonly align 4 %p) {
|
|
entry:
|
|
store i32 0, i32* getelementptr inbounds (%struct.S0, %struct.S0* @b, i64 0, i32 0), align 4
|
|
%f2 = getelementptr inbounds %struct.S0, %struct.S0* %p, i64 0, i32 0
|
|
%0 = load i32, i32* %f2, align 4
|
|
store i32 %0, i32* @a, align 4
|
|
ret void
|
|
}
|
|
|
|
define i32 @test5() {
|
|
entry:
|
|
tail call void @f5(%struct.S0* byval align 4 @b)
|
|
%0 = load i32, i32* @a, align 4
|
|
ret i32 %0
|
|
; CHECK: @test5()
|
|
; CHECK: store i32 0, i32* getelementptr inbounds (%struct.S0, %struct.S0* @b, i64 0, i32 0), align 4
|
|
; CHECK-NOT: load i32, i32* getelementptr inbounds (%struct.S0, %struct.S0* @b, i64 0, i32 0), align 4
|
|
}
|