X86: Resolve a long standing FIXME and properly isel pextr[bw].
[oota-llvm.git] / test / CodeGen / X86 / widen_load-2.ll
1 ; RUN: llc < %s -o - -mcpu=generic -march=x86-64 -mattr=+sse4.2 | FileCheck %s
2
3 ; Test based on pr5626 to load/store
4 ;
5
6 %i32vec3 = type <3 x i32>
7 ; CHECK: add3i32
8 define void @add3i32(%i32vec3*  sret %ret, %i32vec3* %ap, %i32vec3* %bp)  {
9 ; CHECK: movdqa
10 ; CHECK: paddd
11 ; CHECK: pextrd
12 ; CHECK: movq
13         %a = load %i32vec3* %ap, align 16
14         %b = load %i32vec3* %bp, align 16
15         %x = add %i32vec3 %a, %b
16         store %i32vec3 %x, %i32vec3* %ret, align 16
17         ret void
18 }
19
20 ; CHECK: add3i32_2
21 define void @add3i32_2(%i32vec3*  sret %ret, %i32vec3* %ap, %i32vec3* %bp)  {
22 ; CHECK: movq
23 ; CHECK: pinsrd
24 ; CHECK: movq
25 ; CHECK: pinsrd
26 ; CHECK: paddd
27 ; CHECK: pextrd
28 ; CHECK: movq
29         %a = load %i32vec3* %ap, align 8
30         %b = load %i32vec3* %bp, align 8
31         %x = add %i32vec3 %a, %b
32         store %i32vec3 %x, %i32vec3* %ret, align 8
33         ret void
34 }
35
36 %i32vec7 = type <7 x i32>
37 ; CHECK: add7i32
38 define void @add7i32(%i32vec7*  sret %ret, %i32vec7* %ap, %i32vec7* %bp)  {
39 ; CHECK: movdqa
40 ; CHECK: movdqa
41 ; CHECK: paddd
42 ; CHECK: paddd
43 ; CHECK: pextrd
44 ; CHECK: movq
45 ; CHECK: movdqa
46         %a = load %i32vec7* %ap, align 16
47         %b = load %i32vec7* %bp, align 16
48         %x = add %i32vec7 %a, %b
49         store %i32vec7 %x, %i32vec7* %ret, align 16
50         ret void
51 }
52
53 ; CHECK: add12i32
54 %i32vec12 = type <12 x i32>
55 define void @add12i32(%i32vec12*  sret %ret, %i32vec12* %ap, %i32vec12* %bp)  {
56 ; CHECK: movdqa
57 ; CHECK: movdqa
58 ; CHECK: movdqa
59 ; CHECK: paddd
60 ; CHECK: paddd
61 ; CHECK: paddd
62 ; CHECK: movdqa
63 ; CHECK: movdqa
64 ; CHECK: movdqa
65         %a = load %i32vec12* %ap, align 16
66         %b = load %i32vec12* %bp, align 16
67         %x = add %i32vec12 %a, %b
68         store %i32vec12 %x, %i32vec12* %ret, align 16
69         ret void
70 }
71
72
73 ; CHECK: add3i16
74 %i16vec3 = type <3 x i16>
75 define void @add3i16(%i16vec3* nocapture sret %ret, %i16vec3* %ap, %i16vec3* %bp) nounwind {
76 ; CHECK: paddd
77 ; CHECK: ret
78         %a = load %i16vec3* %ap, align 16
79         %b = load %i16vec3* %bp, align 16
80         %x = add %i16vec3 %a, %b
81         store %i16vec3 %x, %i16vec3* %ret, align 16
82         ret void
83 }
84
85 ; CHECK: add4i16
86 %i16vec4 = type <4 x i16>
87 define void @add4i16(%i16vec4* nocapture sret %ret, %i16vec4* %ap, %i16vec4* %bp) nounwind {
88 ; CHECK: paddd
89 ; CHECK: movq
90         %a = load %i16vec4* %ap, align 16
91         %b = load %i16vec4* %bp, align 16
92         %x = add %i16vec4 %a, %b
93         store %i16vec4 %x, %i16vec4* %ret, align 16
94         ret void
95 }
96
97 ; CHECK: add12i16
98 %i16vec12 = type <12 x i16>
99 define void @add12i16(%i16vec12* nocapture sret %ret, %i16vec12* %ap, %i16vec12* %bp) nounwind {
100 ; CHECK: movdqa
101 ; CHECK: movdqa
102 ; CHECK: paddw
103 ; CHECK: paddw
104 ; CHECK: movq
105 ; CHECK: movdqa
106         %a = load %i16vec12* %ap, align 16
107         %b = load %i16vec12* %bp, align 16
108         %x = add %i16vec12 %a, %b
109         store %i16vec12 %x, %i16vec12* %ret, align 16
110         ret void
111 }
112
113 ; CHECK: add18i16
114 %i16vec18 = type <18 x i16>
115 define void @add18i16(%i16vec18* nocapture sret %ret, %i16vec18* %ap, %i16vec18* %bp) nounwind {
116 ; CHECK: movdqa
117 ; CHECK: movdqa
118 ; CHECK: movdqa
119 ; CHECK: paddw
120 ; CHECK: paddw
121 ; CHECK: paddw
122 ; CHECK: movd
123 ; CHECK: movdqa
124 ; CHECK: movdqa
125         %a = load %i16vec18* %ap, align 16
126         %b = load %i16vec18* %bp, align 16
127         %x = add %i16vec18 %a, %b
128         store %i16vec18 %x, %i16vec18* %ret, align 16
129         ret void
130 }
131
132
133 ; CHECK: add3i8
134 %i8vec3 = type <3 x i8>
135 define void @add3i8(%i8vec3* nocapture sret %ret, %i8vec3* %ap, %i8vec3* %bp) nounwind {
136 ; CHECK: paddd
137 ; CHECK: ret
138         %a = load %i8vec3* %ap, align 16
139         %b = load %i8vec3* %bp, align 16
140         %x = add %i8vec3 %a, %b
141         store %i8vec3 %x, %i8vec3* %ret, align 16
142         ret void
143 }
144
145 ; CHECK-LABEL: add31i8:
146 %i8vec31 = type <31 x i8>
147 define void @add31i8(%i8vec31* nocapture sret %ret, %i8vec31* %ap, %i8vec31* %bp) nounwind {
148 ; CHECK: movdqa
149 ; CHECK: movdqa
150 ; CHECK: paddb
151 ; CHECK: paddb
152 ; CHECK: pextrb
153 ; CHECK: pextrw
154 ; CHECK: movq
155 ; CHECK: ret
156         %a = load %i8vec31* %ap, align 16
157         %b = load %i8vec31* %bp, align 16
158         %x = add %i8vec31 %a, %b
159         store %i8vec31 %x, %i8vec31* %ret, align 16
160         ret void
161 }
162
163
164 ; CHECK: rot
165 %i8vec3pack = type { <3 x i8>, i8 }
166 define %i8vec3pack  @rot() nounwind {
167 ; CHECK: pmovzxbd {{-?[0-9]+}}(%rsp), {{%xmm[0-9]}}
168 entry:
169   %X = alloca %i8vec3pack, align 4
170   %rot = alloca %i8vec3pack, align 4
171   %result = alloca %i8vec3pack, align 4
172   %storetmp = bitcast %i8vec3pack* %X to <3 x i8>*
173   store <3 x i8> <i8 -98, i8 -98, i8 -98>, <3 x i8>* %storetmp
174   %storetmp1 = bitcast %i8vec3pack* %rot to <3 x i8>*
175   store <3 x i8> <i8 1, i8 1, i8 1>, <3 x i8>* %storetmp1
176   %tmp = load %i8vec3pack* %X
177   %extractVec = extractvalue %i8vec3pack %tmp, 0
178   %tmp2 = load %i8vec3pack* %rot
179   %extractVec3 = extractvalue %i8vec3pack %tmp2, 0
180   %shr = lshr <3 x i8> %extractVec, %extractVec3
181   %storetmp4 = bitcast %i8vec3pack* %result to <3 x i8>*
182   store <3 x i8> %shr, <3 x i8>* %storetmp4
183   %tmp5 = load %i8vec3pack* %result
184   ret %i8vec3pack %tmp5
185 }
186