02e084bf1129bb0403677c4596cee130a8683fa4
[oota-llvm.git] / test / Transforms / SROA / vector-promotion.ll
1 ; RUN: opt < %s -sroa -S | FileCheck %s
2 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n8:16:32:64"
3
4 %S1 = type { i64, [42 x float] }
5
6 define i32 @test1(<4 x i32> %x, <4 x i32> %y) {
7 ; CHECK: @test1
8 entry:
9         %a = alloca [2 x <4 x i32>]
10 ; CHECK-NOT: alloca
11
12   %a.x = getelementptr inbounds [2 x <4 x i32>]* %a, i64 0, i64 0
13   store <4 x i32> %x, <4 x i32>* %a.x
14   %a.y = getelementptr inbounds [2 x <4 x i32>]* %a, i64 0, i64 1
15   store <4 x i32> %y, <4 x i32>* %a.y
16 ; CHECK-NOT: store
17
18   %a.tmp1 = getelementptr inbounds [2 x <4 x i32>]* %a, i64 0, i64 0, i64 2
19   %tmp1 = load i32* %a.tmp1
20   %a.tmp2 = getelementptr inbounds [2 x <4 x i32>]* %a, i64 0, i64 1, i64 3
21   %tmp2 = load i32* %a.tmp2
22   %a.tmp3 = getelementptr inbounds [2 x <4 x i32>]* %a, i64 0, i64 1, i64 0
23   %tmp3 = load i32* %a.tmp3
24 ; CHECK-NOT: load
25 ; CHECK:      extractelement <4 x i32> %x, i32 2
26 ; CHECK-NEXT: extractelement <4 x i32> %y, i32 3
27 ; CHECK-NEXT: extractelement <4 x i32> %y, i32 0
28
29   %tmp4 = add i32 %tmp1, %tmp2
30   %tmp5 = add i32 %tmp3, %tmp4
31   ret i32 %tmp5
32 ; CHECK-NEXT: add
33 ; CHECK-NEXT: add
34 ; CHECK-NEXT: ret
35 }
36
37 define i32 @test2(<4 x i32> %x, <4 x i32> %y) {
38 ; CHECK: @test2
39 ; FIXME: This should be handled!
40 entry:
41         %a = alloca [2 x <4 x i32>]
42 ; CHECK: alloca <4 x i32>
43
44   %a.x = getelementptr inbounds [2 x <4 x i32>]* %a, i64 0, i64 0
45   store <4 x i32> %x, <4 x i32>* %a.x
46   %a.y = getelementptr inbounds [2 x <4 x i32>]* %a, i64 0, i64 1
47   store <4 x i32> %y, <4 x i32>* %a.y
48
49   %a.tmp1 = getelementptr inbounds [2 x <4 x i32>]* %a, i64 0, i64 0, i64 2
50   %tmp1 = load i32* %a.tmp1
51   %a.tmp2 = getelementptr inbounds [2 x <4 x i32>]* %a, i64 0, i64 1, i64 3
52   %tmp2 = load i32* %a.tmp2
53   %a.tmp3 = getelementptr inbounds [2 x <4 x i32>]* %a, i64 0, i64 1, i64 0
54   %a.tmp3.cast = bitcast i32* %a.tmp3 to <2 x i32>*
55   %tmp3.vec = load <2 x i32>* %a.tmp3.cast
56   %tmp3 = extractelement <2 x i32> %tmp3.vec, i32 0
57
58   %tmp4 = add i32 %tmp1, %tmp2
59   %tmp5 = add i32 %tmp3, %tmp4
60   ret i32 %tmp5
61 }
62
63 define i32 @test3(<4 x i32> %x, <4 x i32> %y) {
64 ; CHECK: @test3
65 entry:
66         %a = alloca [2 x <4 x i32>]
67 ; CHECK-NOT: alloca
68
69   %a.x = getelementptr inbounds [2 x <4 x i32>]* %a, i64 0, i64 0
70   store <4 x i32> %x, <4 x i32>* %a.x
71   %a.y = getelementptr inbounds [2 x <4 x i32>]* %a, i64 0, i64 1
72   store <4 x i32> %y, <4 x i32>* %a.y
73 ; CHECK-NOT: store
74
75   %a.y.cast = bitcast <4 x i32>* %a.y to i8*
76   call void @llvm.memset.p0i8.i32(i8* %a.y.cast, i8 0, i32 16, i32 1, i1 false)
77 ; CHECK-NOT: memset
78
79   %a.tmp1 = getelementptr inbounds [2 x <4 x i32>]* %a, i64 0, i64 0, i64 2
80   %a.tmp1.cast = bitcast i32* %a.tmp1 to i8*
81   call void @llvm.memset.p0i8.i32(i8* %a.tmp1.cast, i8 -1, i32 4, i32 1, i1 false)
82   %tmp1 = load i32* %a.tmp1
83   %a.tmp2 = getelementptr inbounds [2 x <4 x i32>]* %a, i64 0, i64 1, i64 3
84   %tmp2 = load i32* %a.tmp2
85   %a.tmp3 = getelementptr inbounds [2 x <4 x i32>]* %a, i64 0, i64 1, i64 0
86   %tmp3 = load i32* %a.tmp3
87 ; CHECK-NOT: load
88 ; CHECK:      %[[insert:.*]] = insertelement <4 x i32> %x, i32 -1, i32 2
89 ; CHECK-NEXT: extractelement <4 x i32> %[[insert]], i32 2
90 ; CHECK-NEXT: extractelement <4 x i32> zeroinitializer, i32 3
91 ; CHECK-NEXT: extractelement <4 x i32> zeroinitializer, i32 0
92
93   %tmp4 = add i32 %tmp1, %tmp2
94   %tmp5 = add i32 %tmp3, %tmp4
95   ret i32 %tmp5
96 ; CHECK-NEXT: add
97 ; CHECK-NEXT: add
98 ; CHECK-NEXT: ret
99 }
100
101 define i32 @test4(<4 x i32> %x, <4 x i32> %y, <4 x i32>* %z) {
102 ; CHECK: @test4
103 entry:
104         %a = alloca [2 x <4 x i32>]
105 ; CHECK-NOT: alloca
106
107   %a.x = getelementptr inbounds [2 x <4 x i32>]* %a, i64 0, i64 0
108   store <4 x i32> %x, <4 x i32>* %a.x
109   %a.y = getelementptr inbounds [2 x <4 x i32>]* %a, i64 0, i64 1
110   store <4 x i32> %y, <4 x i32>* %a.y
111 ; CHECK-NOT: store
112
113   %a.y.cast = bitcast <4 x i32>* %a.y to i8*
114   %z.cast = bitcast <4 x i32>* %z to i8*
115   call void @llvm.memcpy.p0i8.p0i8.i32(i8* %a.y.cast, i8* %z.cast, i32 16, i32 1, i1 false)
116 ; CHECK-NOT: memcpy
117
118   %a.tmp1 = getelementptr inbounds [2 x <4 x i32>]* %a, i64 0, i64 0, i64 2
119   %a.tmp1.cast = bitcast i32* %a.tmp1 to i8*
120   %z.tmp1 = getelementptr inbounds <4 x i32>* %z, i64 0, i64 2
121   %z.tmp1.cast = bitcast i32* %z.tmp1 to i8*
122   call void @llvm.memcpy.p0i8.p0i8.i32(i8* %a.tmp1.cast, i8* %z.tmp1.cast, i32 4, i32 1, i1 false)
123   %tmp1 = load i32* %a.tmp1
124   %a.tmp2 = getelementptr inbounds [2 x <4 x i32>]* %a, i64 0, i64 1, i64 3
125   %tmp2 = load i32* %a.tmp2
126   %a.tmp3 = getelementptr inbounds [2 x <4 x i32>]* %a, i64 0, i64 1, i64 0
127   %tmp3 = load i32* %a.tmp3
128 ; CHECK-NOT: memcpy
129 ; CHECK:      %[[load:.*]] = load <4 x i32>* %z
130 ; CHECK-NEXT: %[[gep:.*]] = getelementptr inbounds <4 x i32>* %z, i64 0, i64 2
131 ; CHECK-NEXT: %[[element_load:.*]] = load i32* %[[gep]]
132 ; CHECK-NEXT: %[[insert:.*]] = insertelement <4 x i32> %x, i32 %[[element_load]], i32 2
133 ; CHECK-NEXT: extractelement <4 x i32> %[[insert]], i32 2
134 ; CHECK-NEXT: extractelement <4 x i32> %[[load]], i32 3
135 ; CHECK-NEXT: extractelement <4 x i32> %[[load]], i32 0
136
137   %tmp4 = add i32 %tmp1, %tmp2
138   %tmp5 = add i32 %tmp3, %tmp4
139   ret i32 %tmp5
140 ; CHECK-NEXT: add
141 ; CHECK-NEXT: add
142 ; CHECK-NEXT: ret
143 }
144
145 define i32 @test5(<4 x i32> %x, <4 x i32> %y, <4 x i32>* %z) {
146 ; CHECK: @test5
147 ; The same as the above, but with reversed source and destination for the
148 ; element memcpy, and a self copy.
149 entry:
150         %a = alloca [2 x <4 x i32>]
151 ; CHECK-NOT: alloca
152
153   %a.x = getelementptr inbounds [2 x <4 x i32>]* %a, i64 0, i64 0
154   store <4 x i32> %x, <4 x i32>* %a.x
155   %a.y = getelementptr inbounds [2 x <4 x i32>]* %a, i64 0, i64 1
156   store <4 x i32> %y, <4 x i32>* %a.y
157 ; CHECK-NOT: store
158
159   %a.y.cast = bitcast <4 x i32>* %a.y to i8*
160   %a.x.cast = bitcast <4 x i32>* %a.x to i8*
161   call void @llvm.memcpy.p0i8.p0i8.i32(i8* %a.x.cast, i8* %a.y.cast, i32 16, i32 1, i1 false)
162 ; CHECK-NOT: memcpy
163
164   %a.tmp1 = getelementptr inbounds [2 x <4 x i32>]* %a, i64 0, i64 0, i64 2
165   %a.tmp1.cast = bitcast i32* %a.tmp1 to i8*
166   %z.tmp1 = getelementptr inbounds <4 x i32>* %z, i64 0, i64 2
167   %z.tmp1.cast = bitcast i32* %z.tmp1 to i8*
168   call void @llvm.memcpy.p0i8.p0i8.i32(i8* %z.tmp1.cast, i8* %a.tmp1.cast, i32 4, i32 1, i1 false)
169   %tmp1 = load i32* %a.tmp1
170   %a.tmp2 = getelementptr inbounds [2 x <4 x i32>]* %a, i64 0, i64 1, i64 3
171   %tmp2 = load i32* %a.tmp2
172   %a.tmp3 = getelementptr inbounds [2 x <4 x i32>]* %a, i64 0, i64 1, i64 0
173   %tmp3 = load i32* %a.tmp3
174 ; CHECK-NOT: memcpy
175 ; CHECK:      %[[gep:.*]] = getelementptr inbounds <4 x i32>* %z, i64 0, i64 2
176 ; CHECK-NEXT: %[[extract:.*]] = extractelement <4 x i32> %y, i32 2
177 ; CHECK-NEXT: store i32 %[[extract]], i32* %[[gep]]
178 ; CHECK-NEXT: extractelement <4 x i32> %y, i32 2
179 ; CHECK-NEXT: extractelement <4 x i32> %y, i32 3
180 ; CHECK-NEXT: extractelement <4 x i32> %y, i32 0
181
182   %tmp4 = add i32 %tmp1, %tmp2
183   %tmp5 = add i32 %tmp3, %tmp4
184   ret i32 %tmp5
185 ; CHECK-NEXT: add
186 ; CHECK-NEXT: add
187 ; CHECK-NEXT: ret
188 }
189
190 declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind
191 declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) nounwind
192
193 define i64 @test6(<4 x i64> %x, <4 x i64> %y, i64 %n) {
194 ; CHECK: @test6
195 ; The old scalarrepl pass would wrongly drop the store to the second alloca.
196 ; PR13254
197   %tmp = alloca { <4 x i64>, <4 x i64> }
198   %p0 = getelementptr inbounds { <4 x i64>, <4 x i64> }* %tmp, i32 0, i32 0
199   store <4 x i64> %x, <4 x i64>* %p0
200 ; CHECK: store <4 x i64> %x,
201   %p1 = getelementptr inbounds { <4 x i64>, <4 x i64> }* %tmp, i32 0, i32 1
202   store <4 x i64> %y, <4 x i64>* %p1
203 ; CHECK: store <4 x i64> %y,
204   %addr = getelementptr inbounds { <4 x i64>, <4 x i64> }* %tmp, i32 0, i32 0, i64 %n
205   %res = load i64* %addr, align 4
206   ret i64 %res
207 }
208
209 define i32 @PR14212() {
210 ; CHECK: @PR14212
211 ; This caused a crash when "splitting" the load of the i32 in order to promote
212 ; the store of <3 x i8> properly. Heavily reduced from an OpenCL test case.
213 entry:
214   %retval = alloca <3 x i8>, align 4
215 ; CHECK-NOT: alloca
216
217   store <3 x i8> undef, <3 x i8>* %retval, align 4
218   %cast = bitcast <3 x i8>* %retval to i32*
219   %load = load i32* %cast, align 4
220   ret i32 %load
221 ; CHECK: ret i32
222 }