1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-24 21:42:54 +02:00
llvm-mirror/test/Transforms/Inline/byval.ll
Chandler Carruth 3a1d9fe91a [PM] Turn on the new PM's inliner in addition to the current one for
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
2016-12-27 07:18:43 +00:00

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
}