blob: ea2bec2cee3fea38367ea20366047d3910f23149 [file] [log] [blame]
Chris Lattner6f3ddbd2010-12-20 07:38:24 +00001; RUN: opt < %s -inline -S | FileCheck %s
Chandler Carruth625038d2016-12-27 07:18:43 +00002; RUN: opt < %s -passes='cgscc(inline)' -S | FileCheck %s
Chris Lattner908117b2008-01-11 06:09:30 +00003
Bjorn Pettersson38514962018-01-10 13:01:18 +00004; The verifier does catch problems with inlining of byval arguments that has a
5; different address space compared to the alloca. But running instcombine
6; after inline used to trigger asserts unless we disallow such inlining.
7; RUN: opt < %s -inline -instcombine -disable-output 2>/dev/null
8
Bjorn Pettersson77f32992018-01-04 18:23:40 +00009target datalayout = "p:32:32-p1:64:64-p2:16:16-n16:32:64"
10
Chris Lattner908117b2008-01-11 06:09:30 +000011; Inlining a byval struct should cause an explicit copy into an alloca.
12
13 %struct.ss = type { i32, i64 }
14@.str = internal constant [10 x i8] c"%d, %lld\0A\00" ; <[10 x i8]*> [#uses=1]
15
16define internal void @f(%struct.ss* byval %b) nounwind {
17entry:
David Blaikie79e6c742015-02-27 19:29:02 +000018 %tmp = getelementptr %struct.ss, %struct.ss* %b, i32 0, i32 0 ; <i32*> [#uses=2]
David Blaikiea79ac142015-02-27 21:17:42 +000019 %tmp1 = load i32, i32* %tmp, align 4 ; <i32> [#uses=1]
Chris Lattner908117b2008-01-11 06:09:30 +000020 %tmp2 = add i32 %tmp1, 1 ; <i32> [#uses=1]
21 store i32 %tmp2, i32* %tmp, align 4
22 ret void
23}
24
25declare i32 @printf(i8*, ...) nounwind
26
Chris Lattnera9a5c592010-12-20 07:39:57 +000027define i32 @test1() nounwind {
Chris Lattner908117b2008-01-11 06:09:30 +000028entry:
29 %S = alloca %struct.ss ; <%struct.ss*> [#uses=4]
David Blaikie79e6c742015-02-27 19:29:02 +000030 %tmp1 = getelementptr %struct.ss, %struct.ss* %S, i32 0, i32 0 ; <i32*> [#uses=1]
Chris Lattner908117b2008-01-11 06:09:30 +000031 store i32 1, i32* %tmp1, align 8
David Blaikie79e6c742015-02-27 19:29:02 +000032 %tmp4 = getelementptr %struct.ss, %struct.ss* %S, i32 0, i32 1 ; <i64*> [#uses=1]
Chris Lattner908117b2008-01-11 06:09:30 +000033 store i64 2, i64* %tmp4, align 4
34 call void @f( %struct.ss* byval %S ) nounwind
35 ret i32 0
David Majnemer120f4a02013-11-03 12:22:13 +000036; CHECK: @test1()
Chris Lattner00997442010-12-20 07:57:41 +000037; CHECK: %S1 = alloca %struct.ss
38; CHECK: %S = alloca %struct.ss
Chris Lattner6f3ddbd2010-12-20 07:38:24 +000039; CHECK: call void @llvm.memcpy
Chris Lattnera9a5c592010-12-20 07:39:57 +000040; CHECK: ret i32 0
41}
42
43; Inlining a byval struct should NOT cause an explicit copy
44; into an alloca if the function is readonly
45
46define internal i32 @f2(%struct.ss* byval %b) nounwind readonly {
47entry:
David Blaikie79e6c742015-02-27 19:29:02 +000048 %tmp = getelementptr %struct.ss, %struct.ss* %b, i32 0, i32 0 ; <i32*> [#uses=2]
David Blaikiea79ac142015-02-27 21:17:42 +000049 %tmp1 = load i32, i32* %tmp, align 4 ; <i32> [#uses=1]
Chris Lattnera9a5c592010-12-20 07:39:57 +000050 %tmp2 = add i32 %tmp1, 1 ; <i32> [#uses=1]
51 ret i32 %tmp2
52}
53
54define i32 @test2() nounwind {
55entry:
56 %S = alloca %struct.ss ; <%struct.ss*> [#uses=4]
David Blaikie79e6c742015-02-27 19:29:02 +000057 %tmp1 = getelementptr %struct.ss, %struct.ss* %S, i32 0, i32 0 ; <i32*> [#uses=1]
Chris Lattnera9a5c592010-12-20 07:39:57 +000058 store i32 1, i32* %tmp1, align 8
David Blaikie79e6c742015-02-27 19:29:02 +000059 %tmp4 = getelementptr %struct.ss, %struct.ss* %S, i32 0, i32 1 ; <i64*> [#uses=1]
Chris Lattnera9a5c592010-12-20 07:39:57 +000060 store i64 2, i64* %tmp4, align 4
61 %X = call i32 @f2( %struct.ss* byval %S ) nounwind
62 ret i32 %X
David Majnemer120f4a02013-11-03 12:22:13 +000063; CHECK: @test2()
Chris Lattnera9a5c592010-12-20 07:39:57 +000064; CHECK: %S = alloca %struct.ss
65; CHECK-NOT: call void @llvm.memcpy
66; CHECK: ret i32
Chris Lattner908117b2008-01-11 06:09:30 +000067}
Chris Lattner73946802010-12-20 07:45:28 +000068
69
70; Inlining a byval with an explicit alignment needs to use *at least* that
71; alignment on the generated alloca.
72; PR8769
73declare void @g3(%struct.ss* %p)
74
75define internal void @f3(%struct.ss* byval align 64 %b) nounwind {
76 call void @g3(%struct.ss* %b) ;; Could make alignment assumptions!
77 ret void
78}
79
80define void @test3() nounwind {
81entry:
82 %S = alloca %struct.ss, align 1 ;; May not be aligned.
83 call void @f3( %struct.ss* byval align 64 %S) nounwind
84 ret void
David Majnemer120f4a02013-11-03 12:22:13 +000085; CHECK: @test3()
Chris Lattner00997442010-12-20 07:57:41 +000086; CHECK: %S1 = alloca %struct.ss, align 64
Chris Lattner73946802010-12-20 07:45:28 +000087; CHECK: %S = alloca %struct.ss
88; CHECK: call void @llvm.memcpy
Chris Lattner00997442010-12-20 07:57:41 +000089; CHECK: call void @g3(%struct.ss* %S1)
Chris Lattner73946802010-12-20 07:45:28 +000090; CHECK: ret void
91}
Chris Lattner0f114952010-12-20 08:10:40 +000092
93
94; Inlining a byval struct should NOT cause an explicit copy
95; into an alloca if the function is readonly, but should increase an alloca's
96; alignment to satisfy an explicit alignment request.
97
98define internal i32 @f4(%struct.ss* byval align 64 %b) nounwind readonly {
99 call void @g3(%struct.ss* %b)
100 ret i32 4
101}
102
103define i32 @test4() nounwind {
104entry:
105 %S = alloca %struct.ss, align 2 ; <%struct.ss*> [#uses=4]
106 %X = call i32 @f4( %struct.ss* byval align 64 %S ) nounwind
107 ret i32 %X
David Majnemer120f4a02013-11-03 12:22:13 +0000108; CHECK: @test4()
Chris Lattner0f114952010-12-20 08:10:40 +0000109; CHECK: %S = alloca %struct.ss, align 64
110; CHECK-NOT: call void @llvm.memcpy
111; CHECK: call void @g3
112; CHECK: ret i32 4
113}
114
David Majnemer120f4a02013-11-03 12:22:13 +0000115%struct.S0 = type { i32 }
Tom Stellardbc7d87f2013-10-24 16:38:33 +0000116
David Majnemer120f4a02013-11-03 12:22:13 +0000117@b = global %struct.S0 { i32 1 }, align 4
118@a = common global i32 0, align 4
119
120define internal void @f5(%struct.S0* byval nocapture readonly align 4 %p) {
Tom Stellardbc7d87f2013-10-24 16:38:33 +0000121entry:
David Blaikief72d05b2015-03-13 18:20:45 +0000122 store i32 0, i32* getelementptr inbounds (%struct.S0, %struct.S0* @b, i64 0, i32 0), align 4
David Blaikie79e6c742015-02-27 19:29:02 +0000123 %f2 = getelementptr inbounds %struct.S0, %struct.S0* %p, i64 0, i32 0
David Blaikiea79ac142015-02-27 21:17:42 +0000124 %0 = load i32, i32* %f2, align 4
David Majnemer120f4a02013-11-03 12:22:13 +0000125 store i32 %0, i32* @a, align 4
126 ret void
Tom Stellardbc7d87f2013-10-24 16:38:33 +0000127}
128
David Majnemer120f4a02013-11-03 12:22:13 +0000129define i32 @test5() {
Tom Stellardbc7d87f2013-10-24 16:38:33 +0000130entry:
David Majnemer120f4a02013-11-03 12:22:13 +0000131 tail call void @f5(%struct.S0* byval align 4 @b)
David Blaikiea79ac142015-02-27 21:17:42 +0000132 %0 = load i32, i32* @a, align 4
David Majnemer120f4a02013-11-03 12:22:13 +0000133 ret i32 %0
134; CHECK: @test5()
David Blaikief72d05b2015-03-13 18:20:45 +0000135; CHECK: store i32 0, i32* getelementptr inbounds (%struct.S0, %struct.S0* @b, i64 0, i32 0), align 4
136; CHECK-NOT: load i32, i32* getelementptr inbounds (%struct.S0, %struct.S0* @b, i64 0, i32 0), align 4
Tom Stellardbc7d87f2013-10-24 16:38:33 +0000137}
Bjorn Pettersson77f32992018-01-04 18:23:40 +0000138
Bjorn Pettersson38514962018-01-10 13:01:18 +0000139; Inlining a byval struct that is in a different address space compared to the
140; alloca address space is at the moment not expected. That would need
141; adjustments inside the inlined function since the address space attribute of
142; the inlined argument changes.
143
Bjorn Pettersson77f32992018-01-04 18:23:40 +0000144%struct.S1 = type { i32 }
145
146@d = addrspace(1) global %struct.S1 { i32 1 }, align 4
147@c = common addrspace(1) global i32 0, align 4
148
149define internal void @f5_as1(%struct.S1 addrspace(1)* byval nocapture readonly align 4 %p) {
150entry:
151 store i32 0, i32 addrspace(1)* getelementptr inbounds (%struct.S1, %struct.S1 addrspace(1)* @d, i64 0, i32 0), align 4
152 %f2 = getelementptr inbounds %struct.S1, %struct.S1 addrspace(1)* %p, i64 0, i32 0
153 %0 = load i32, i32 addrspace(1)* %f2, align 4
154 store i32 %0, i32 addrspace(1)* @c, align 4
155 ret void
156}
157
158define i32 @test5_as1() {
159entry:
160 tail call void @f5_as1(%struct.S1 addrspace(1)* byval align 4 @d)
161 %0 = load i32, i32 addrspace(1)* @c, align 4
162 ret i32 %0
163; CHECK: @test5_as1()
Bjorn Pettersson38514962018-01-10 13:01:18 +0000164; CHECK: call void @f5_as1
Bjorn Pettersson77f32992018-01-04 18:23:40 +0000165}