xref: /llvm-project/llvm/test/Transforms/VectorCombine/X86/shuffle-of-casts.ll (revision 611401c11594871aa5c7692cd17a7f12b6fbe660)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
2; RUN: opt < %s -passes=vector-combine -S -mtriple=x86_64-- -mattr=sse2 | FileCheck %s --check-prefixes=CHECK,SSE
3; RUN: opt < %s -passes=vector-combine -S -mtriple=x86_64-- -mattr=avx2 | FileCheck %s --check-prefixes=CHECK,AVX
4
5; standard vector concatenations
6
7define <16 x i32> @concat_zext_v8i16_v16i32(<8 x i16> %a0, <8 x i16> %a1) {
8; CHECK-LABEL: define <16 x i32> @concat_zext_v8i16_v16i32(
9; CHECK-SAME: <8 x i16> [[A0:%.*]], <8 x i16> [[A1:%.*]]) #[[ATTR0:[0-9]+]] {
10; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <8 x i16> [[A0]], <8 x i16> [[A1]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
11; CHECK-NEXT:    [[R:%.*]] = zext <16 x i16> [[TMP1]] to <16 x i32>
12; CHECK-NEXT:    ret <16 x i32> [[R]]
13;
14  %x0 = zext <8 x i16> %a0 to <8 x i32>
15  %x1 = zext <8 x i16> %a1 to <8 x i32>
16  %r = shufflevector <8 x i32> %x0, <8 x i32> %x1, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
17  ret <16 x i32> %r
18}
19
20define <16 x i32> @concat_zext_nneg_v8i16_v16i32(<8 x i16> %a0, <8 x i16> %a1) {
21; CHECK-LABEL: define <16 x i32> @concat_zext_nneg_v8i16_v16i32(
22; CHECK-SAME: <8 x i16> [[A0:%.*]], <8 x i16> [[A1:%.*]]) #[[ATTR0]] {
23; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <8 x i16> [[A0]], <8 x i16> [[A1]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
24; CHECK-NEXT:    [[R:%.*]] = zext nneg <16 x i16> [[TMP1]] to <16 x i32>
25; CHECK-NEXT:    ret <16 x i32> [[R]]
26;
27  %x0 = zext nneg <8 x i16> %a0 to <8 x i32>
28  %x1 = zext nneg <8 x i16> %a1 to <8 x i32>
29  %r = shufflevector <8 x i32> %x0, <8 x i32> %x1, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
30  ret <16 x i32> %r
31}
32
33define <16 x i32> @concat_sext_zext_nneg_v8i16_v8i32(<8 x i16> %a0, <8 x i16> %a1) {
34; SSE-LABEL: define <16 x i32> @concat_sext_zext_nneg_v8i16_v8i32(
35; SSE-SAME: <8 x i16> [[A0:%.*]], <8 x i16> [[A1:%.*]]) #[[ATTR0]] {
36; SSE-NEXT:    [[X0:%.*]] = sext <8 x i16> [[A0]] to <8 x i32>
37; SSE-NEXT:    [[X1:%.*]] = zext nneg <8 x i16> [[A1]] to <8 x i32>
38; SSE-NEXT:    [[R:%.*]] = shufflevector <8 x i32> [[X0]], <8 x i32> [[X1]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
39; SSE-NEXT:    ret <16 x i32> [[R]]
40;
41; AVX-LABEL: define <16 x i32> @concat_sext_zext_nneg_v8i16_v8i32(
42; AVX-SAME: <8 x i16> [[A0:%.*]], <8 x i16> [[A1:%.*]]) #[[ATTR0]] {
43; AVX-NEXT:    [[TMP1:%.*]] = shufflevector <8 x i16> [[A0]], <8 x i16> [[A1]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
44; AVX-NEXT:    [[R:%.*]] = sext <16 x i16> [[TMP1]] to <16 x i32>
45; AVX-NEXT:    ret <16 x i32> [[R]]
46;
47  %x0 = sext <8 x i16> %a0 to <8 x i32>
48  %x1 = zext nneg <8 x i16> %a1 to <8 x i32>
49  %r = shufflevector <8 x i32> %x0, <8 x i32> %x1, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
50  ret <16 x i32> %r
51}
52
53define <16 x i32> @concat_sext_v8i16_v16i32(<8 x i16> %a0, <8 x i16> %a1) {
54; CHECK-LABEL: define <16 x i32> @concat_sext_v8i16_v16i32(
55; CHECK-SAME: <8 x i16> [[A0:%.*]], <8 x i16> [[A1:%.*]]) #[[ATTR0]] {
56; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <8 x i16> [[A0]], <8 x i16> [[A1]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
57; CHECK-NEXT:    [[R:%.*]] = sext <16 x i16> [[TMP1]] to <16 x i32>
58; CHECK-NEXT:    ret <16 x i32> [[R]]
59;
60  %x0 = sext <8 x i16> %a0 to <8 x i32>
61  %x1 = sext <8 x i16> %a1 to <8 x i32>
62  %r = shufflevector <8 x i32> %x0, <8 x i32> %x1, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
63  ret <16 x i32> %r
64}
65
66define <8 x i32> @concat_sext_v4i1_v8i32(<4 x i1> %a0, <4 x i1> %a1) {
67; SSE-LABEL: define <8 x i32> @concat_sext_v4i1_v8i32(
68; SSE-SAME: <4 x i1> [[A0:%.*]], <4 x i1> [[A1:%.*]]) #[[ATTR0]] {
69; SSE-NEXT:    [[X0:%.*]] = sext <4 x i1> [[A0]] to <4 x i32>
70; SSE-NEXT:    [[X1:%.*]] = sext <4 x i1> [[A1]] to <4 x i32>
71; SSE-NEXT:    [[R:%.*]] = shufflevector <4 x i32> [[X0]], <4 x i32> [[X1]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
72; SSE-NEXT:    ret <8 x i32> [[R]]
73;
74; AVX-LABEL: define <8 x i32> @concat_sext_v4i1_v8i32(
75; AVX-SAME: <4 x i1> [[A0:%.*]], <4 x i1> [[A1:%.*]]) #[[ATTR0]] {
76; AVX-NEXT:    [[TMP1:%.*]] = shufflevector <4 x i1> [[A0]], <4 x i1> [[A1]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
77; AVX-NEXT:    [[R:%.*]] = sext <8 x i1> [[TMP1]] to <8 x i32>
78; AVX-NEXT:    ret <8 x i32> [[R]]
79;
80  %x0 = sext <4 x i1> %a0 to <4 x i32>
81  %x1 = sext <4 x i1> %a1 to <4 x i32>
82  %r = shufflevector <4 x i32> %x0, <4 x i32> %x1, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
83  ret <8 x i32> %r
84}
85
86define <8 x i16> @concat_trunc_v4i32_v8i16(<4 x i32> %a0, <4 x i32> %a1) {
87; CHECK-LABEL: define <8 x i16> @concat_trunc_v4i32_v8i16(
88; CHECK-SAME: <4 x i32> [[A0:%.*]], <4 x i32> [[A1:%.*]]) #[[ATTR0]] {
89; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x i32> [[A0]], <4 x i32> [[A1]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
90; CHECK-NEXT:    [[R:%.*]] = trunc <8 x i32> [[TMP1]] to <8 x i16>
91; CHECK-NEXT:    ret <8 x i16> [[R]]
92;
93  %x0 = trunc <4 x i32> %a0 to <4 x i16>
94  %x1 = trunc <4 x i32> %a1 to <4 x i16>
95  %r = shufflevector <4 x i16> %x0, <4 x i16> %x1, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
96  ret <8 x i16> %r
97}
98
99define <8 x ptr> @concat_inttoptr_v4i32_v8iptr(<4 x i32> %a0, <4 x i32> %a1) {
100; SSE-LABEL: define <8 x ptr> @concat_inttoptr_v4i32_v8iptr(
101; SSE-SAME: <4 x i32> [[A0:%.*]], <4 x i32> [[A1:%.*]]) #[[ATTR0]] {
102; SSE-NEXT:    [[TMP1:%.*]] = shufflevector <4 x i32> [[A0]], <4 x i32> [[A1]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
103; SSE-NEXT:    [[R:%.*]] = inttoptr <8 x i32> [[TMP1]] to <8 x ptr>
104; SSE-NEXT:    ret <8 x ptr> [[R]]
105;
106; AVX-LABEL: define <8 x ptr> @concat_inttoptr_v4i32_v8iptr(
107; AVX-SAME: <4 x i32> [[A0:%.*]], <4 x i32> [[A1:%.*]]) #[[ATTR0]] {
108; AVX-NEXT:    [[X0:%.*]] = inttoptr <4 x i32> [[A0]] to <4 x ptr>
109; AVX-NEXT:    [[X1:%.*]] = inttoptr <4 x i32> [[A1]] to <4 x ptr>
110; AVX-NEXT:    [[R:%.*]] = shufflevector <4 x ptr> [[X0]], <4 x ptr> [[X1]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
111; AVX-NEXT:    ret <8 x ptr> [[R]]
112;
113  %x0 = inttoptr <4 x i32> %a0 to <4 x ptr>
114  %x1 = inttoptr <4 x i32> %a1 to <4 x ptr>
115  %r = shufflevector <4 x ptr> %x0, <4 x ptr> %x1, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
116  ret <8 x ptr> %r
117}
118
119define <16 x i64> @concat_ptrtoint_v8i16_v16i32(<8 x ptr> %a0, <8 x ptr> %a1) {
120; CHECK-LABEL: define <16 x i64> @concat_ptrtoint_v8i16_v16i32(
121; CHECK-SAME: <8 x ptr> [[A0:%.*]], <8 x ptr> [[A1:%.*]]) #[[ATTR0]] {
122; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <8 x ptr> [[A0]], <8 x ptr> [[A1]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
123; CHECK-NEXT:    [[R:%.*]] = ptrtoint <16 x ptr> [[TMP1]] to <16 x i64>
124; CHECK-NEXT:    ret <16 x i64> [[R]]
125;
126  %x0 = ptrtoint <8 x ptr> %a0 to <8 x i64>
127  %x1 = ptrtoint <8 x ptr> %a1 to <8 x i64>
128  %r = shufflevector <8 x i64> %x0, <8 x i64> %x1, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
129  ret <16 x i64> %r
130}
131
132define <8 x double> @concat_fpext_v4f32_v8f64(<4 x float> %a0, <4 x float> %a1) {
133; SSE-LABEL: define <8 x double> @concat_fpext_v4f32_v8f64(
134; SSE-SAME: <4 x float> [[A0:%.*]], <4 x float> [[A1:%.*]]) #[[ATTR0]] {
135; SSE-NEXT:    [[TMP1:%.*]] = shufflevector <4 x float> [[A0]], <4 x float> [[A1]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
136; SSE-NEXT:    [[R:%.*]] = fpext <8 x float> [[TMP1]] to <8 x double>
137; SSE-NEXT:    ret <8 x double> [[R]]
138;
139; AVX-LABEL: define <8 x double> @concat_fpext_v4f32_v8f64(
140; AVX-SAME: <4 x float> [[A0:%.*]], <4 x float> [[A1:%.*]]) #[[ATTR0]] {
141; AVX-NEXT:    [[X0:%.*]] = fpext <4 x float> [[A0]] to <4 x double>
142; AVX-NEXT:    [[X1:%.*]] = fpext <4 x float> [[A1]] to <4 x double>
143; AVX-NEXT:    [[R:%.*]] = shufflevector <4 x double> [[X0]], <4 x double> [[X1]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
144; AVX-NEXT:    ret <8 x double> [[R]]
145;
146  %x0 = fpext <4 x float> %a0 to <4 x double>
147  %x1 = fpext <4 x float> %a1 to <4 x double>
148  %r = shufflevector <4 x double> %x0, <4 x double> %x1, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
149  ret <8 x double> %r
150}
151
152define <16 x float> @concat_fptrunc_v8f64_v16f32(<8 x double> %a0, <8 x double> %a1) {
153; CHECK-LABEL: define <16 x float> @concat_fptrunc_v8f64_v16f32(
154; CHECK-SAME: <8 x double> [[A0:%.*]], <8 x double> [[A1:%.*]]) #[[ATTR0]] {
155; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <8 x double> [[A0]], <8 x double> [[A1]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
156; CHECK-NEXT:    [[R:%.*]] = fptrunc <16 x double> [[TMP1]] to <16 x float>
157; CHECK-NEXT:    ret <16 x float> [[R]]
158;
159  %x0 = fptrunc <8 x double> %a0 to <8 x float>
160  %x1 = fptrunc <8 x double> %a1 to <8 x float>
161  %r = shufflevector <8 x float> %x0, <8 x float> %x1, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
162  ret <16 x float> %r
163}
164
165; commuted vector concatenation
166
167define <16 x i32> @rconcat_sext_v8i16_v16i32(<8 x i16> %a0, <8 x i16> %a1) {
168; SSE-LABEL: define <16 x i32> @rconcat_sext_v8i16_v16i32(
169; SSE-SAME: <8 x i16> [[A0:%.*]], <8 x i16> [[A1:%.*]]) #[[ATTR0]] {
170; SSE-NEXT:    [[TMP1:%.*]] = shufflevector <8 x i16> [[A1]], <8 x i16> [[A0]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
171; SSE-NEXT:    [[R:%.*]] = sext <16 x i16> [[TMP1]] to <16 x i32>
172; SSE-NEXT:    ret <16 x i32> [[R]]
173;
174; AVX-LABEL: define <16 x i32> @rconcat_sext_v8i16_v16i32(
175; AVX-SAME: <8 x i16> [[A0:%.*]], <8 x i16> [[A1:%.*]]) #[[ATTR0]] {
176; AVX-NEXT:    [[TMP1:%.*]] = shufflevector <8 x i16> [[A0]], <8 x i16> [[A1]], <16 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
177; AVX-NEXT:    [[R:%.*]] = sext <16 x i16> [[TMP1]] to <16 x i32>
178; AVX-NEXT:    ret <16 x i32> [[R]]
179;
180  %x0 = sext <8 x i16> %a0 to <8 x i32>
181  %x1 = sext <8 x i16> %a1 to <8 x i32>
182  %r = shufflevector <8 x i32> %x0, <8 x i32> %x1, <16 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
183  ret <16 x i32> %r
184}
185
186; interleaved shuffle
187
188define <8 x double> @interleave_fpext_v4f32_v8f64(<4 x float> %a0, <4 x float> %a1) {
189; CHECK-LABEL: define <8 x double> @interleave_fpext_v4f32_v8f64(
190; CHECK-SAME: <4 x float> [[A0:%.*]], <4 x float> [[A1:%.*]]) #[[ATTR0]] {
191; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x float> [[A0]], <4 x float> [[A1]], <8 x i32> <i32 0, i32 4, i32 1, i32 5, i32 2, i32 6, i32 3, i32 7>
192; CHECK-NEXT:    [[R:%.*]] = fpext <8 x float> [[TMP1]] to <8 x double>
193; CHECK-NEXT:    ret <8 x double> [[R]]
194;
195  %x0 = fpext <4 x float> %a0 to <4 x double>
196  %x1 = fpext <4 x float> %a1 to <4 x double>
197  %r = shufflevector <4 x double> %x0, <4 x double> %x1, <8 x i32> <i32 0, i32 4, i32 1, i32 5, i32 2, i32 6, i32 3, i32 7>
198  ret <8 x double> %r
199}
200
201; bitcasts (same element count)
202
203define <8 x float> @concat_bitcast_v4i32_v8f32(<4 x i32> %a0, <4 x i32> %a1) {
204; CHECK-LABEL: define <8 x float> @concat_bitcast_v4i32_v8f32(
205; CHECK-SAME: <4 x i32> [[A0:%.*]], <4 x i32> [[A1:%.*]]) #[[ATTR0]] {
206; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x i32> [[A0]], <4 x i32> [[A1]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
207; CHECK-NEXT:    [[R:%.*]] = bitcast <8 x i32> [[TMP1]] to <8 x float>
208; CHECK-NEXT:    ret <8 x float> [[R]]
209;
210  %x0 = bitcast <4 x i32> %a0 to <4 x float>
211  %x1 = bitcast <4 x i32> %a1 to <4 x float>
212  %r = shufflevector <4 x float> %x0, <4 x float> %x1, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
213  ret <8 x float> %r
214}
215
216; bitcasts (lower element count)
217
218define <4 x double> @concat_bitcast_v8i16_v4f64(<8 x i16> %a0, <8 x i16> %a1) {
219; CHECK-LABEL: define <4 x double> @concat_bitcast_v8i16_v4f64(
220; CHECK-SAME: <8 x i16> [[A0:%.*]], <8 x i16> [[A1:%.*]]) #[[ATTR0]] {
221; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <8 x i16> [[A0]], <8 x i16> [[A1]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
222; CHECK-NEXT:    [[R:%.*]] = bitcast <16 x i16> [[TMP1]] to <4 x double>
223; CHECK-NEXT:    ret <4 x double> [[R]]
224;
225  %x0 = bitcast <8 x i16> %a0 to <2 x double>
226  %x1 = bitcast <8 x i16> %a1 to <2 x double>
227  %r = shufflevector <2 x double> %x0, <2 x double> %x1, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
228  ret <4 x double> %r
229}
230
231; bitcasts (higher element count)
232
233define <16 x i16> @concat_bitcast_v4i32_v16i16(<4 x i32> %a0, <4 x i32> %a1) {
234; CHECK-LABEL: define <16 x i16> @concat_bitcast_v4i32_v16i16(
235; CHECK-SAME: <4 x i32> [[A0:%.*]], <4 x i32> [[A1:%.*]]) #[[ATTR0]] {
236; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x i32> [[A0]], <4 x i32> [[A1]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
237; CHECK-NEXT:    [[R:%.*]] = bitcast <8 x i32> [[TMP1]] to <16 x i16>
238; CHECK-NEXT:    ret <16 x i16> [[R]]
239;
240  %x0 = bitcast <4 x i32> %a0 to <8 x i16>
241  %x1 = bitcast <4 x i32> %a1 to <8 x i16>
242  %r = shufflevector <8 x i16> %x0, <8 x i16> %x1, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
243  ret <16 x i16> %r
244}
245
246; multiuse - ensure cost of any duplicated casts are worth it
247
248define <8 x i16> @concat_trunc_v4i32_v8i16_multiuse(<4 x i32> %a0, <4 x i32> %a1, ptr %a2) {
249; CHECK-LABEL: define <8 x i16> @concat_trunc_v4i32_v8i16_multiuse(
250; CHECK-SAME: <4 x i32> [[A0:%.*]], <4 x i32> [[A1:%.*]], ptr [[A2:%.*]]) #[[ATTR0]] {
251; CHECK-NEXT:    [[X0:%.*]] = trunc <4 x i32> [[A0]] to <4 x i16>
252; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x i32> [[A0]], <4 x i32> [[A1]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
253; CHECK-NEXT:    [[R:%.*]] = trunc <8 x i32> [[TMP1]] to <8 x i16>
254; CHECK-NEXT:    store <4 x i16> [[X0]], ptr [[A2]], align 8
255; CHECK-NEXT:    ret <8 x i16> [[R]]
256;
257  %x0 = trunc <4 x i32> %a0 to <4 x i16>
258  %x1 = trunc <4 x i32> %a1 to <4 x i16>
259  %r = shufflevector <4 x i16> %x0, <4 x i16> %x1, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
260  store <4 x i16> %x0, ptr %a2
261  ret <8 x i16> %r
262}
263
264; negative - multiuse - ensure cost of any duplicated casts are worth it
265
266define <16 x i8> @concat_trunc_v8i64_v16i8_multiuse(<8 x i64> %a0, <8 x i64> %a1, ptr %a2) {
267; CHECK-LABEL: define <16 x i8> @concat_trunc_v8i64_v16i8_multiuse(
268; CHECK-SAME: <8 x i64> [[A0:%.*]], <8 x i64> [[A1:%.*]], ptr [[A2:%.*]]) #[[ATTR0]] {
269; CHECK-NEXT:    [[X0:%.*]] = trunc <8 x i64> [[A0]] to <8 x i8>
270; CHECK-NEXT:    [[X1:%.*]] = trunc <8 x i64> [[A1]] to <8 x i8>
271; CHECK-NEXT:    [[R:%.*]] = shufflevector <8 x i8> [[X0]], <8 x i8> [[X1]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 4, i32 15>
272; CHECK-NEXT:    store <8 x i8> [[X0]], ptr [[A2]], align 8
273; CHECK-NEXT:    ret <16 x i8> [[R]]
274;
275  %x0 = trunc <8 x i64> %a0 to <8 x i8>
276  %x1 = trunc <8 x i64> %a1 to <8 x i8>
277  %r = shufflevector <8 x i8> %x0, <8 x i8> %x1, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 4, i32 15>
278  store <8 x i8> %x0, ptr %a2
279  ret <16 x i8> %r
280}
281
282; negative - bitcasts (unscalable higher element count)
283
284define <16 x i16> @revpair_bitcast_v4i32_v16i16(<4 x i32> %a0, <4 x i32> %a1) {
285; CHECK-LABEL: define <16 x i16> @revpair_bitcast_v4i32_v16i16(
286; CHECK-SAME: <4 x i32> [[A0:%.*]], <4 x i32> [[A1:%.*]]) #[[ATTR0]] {
287; CHECK-NEXT:    [[X0:%.*]] = bitcast <4 x i32> [[A0]] to <8 x i16>
288; CHECK-NEXT:    [[X1:%.*]] = bitcast <4 x i32> [[A1]] to <8 x i16>
289; CHECK-NEXT:    [[R:%.*]] = shufflevector <8 x i16> [[X0]], <8 x i16> [[X1]], <16 x i32> <i32 1, i32 0, i32 3, i32 3, i32 5, i32 4, i32 7, i32 6, i32 9, i32 8, i32 11, i32 10, i32 13, i32 12, i32 15, i32 14>
290; CHECK-NEXT:    ret <16 x i16> [[R]]
291;
292  %x0 = bitcast <4 x i32> %a0 to <8 x i16>
293  %x1 = bitcast <4 x i32> %a1 to <8 x i16>
294  %r = shufflevector <8 x i16> %x0, <8 x i16> %x1, <16 x i32> <i32 1, i32 0, i32 3, i32 3, i32 5, i32 4, i32 7, i32 6, i32 9, i32 8, i32 11, i32 10, i32 13, i32 12, i32 15, i32 14>
295  ret <16 x i16> %r
296}
297
298; negative - bitcasts (unscalable element counts)
299
300define <4 x i32> @shuffle_bitcast_v32i40_v4i32(<32 x i40> %a0, <32 x i40> %a1) {
301; CHECK-LABEL: define <4 x i32> @shuffle_bitcast_v32i40_v4i32(
302; CHECK-SAME: <32 x i40> [[A0:%.*]], <32 x i40> [[A1:%.*]]) #[[ATTR0]] {
303; CHECK-NEXT:    [[X0:%.*]] = bitcast <32 x i40> [[A0]] to <40 x i32>
304; CHECK-NEXT:    [[X1:%.*]] = bitcast <32 x i40> [[A1]] to <40 x i32>
305; CHECK-NEXT:    [[R:%.*]] = shufflevector <40 x i32> [[X0]], <40 x i32> [[X1]], <4 x i32> <i32 0, i32 42, i32 poison, i32 poison>
306; CHECK-NEXT:    ret <4 x i32> [[R]]
307;
308  %x0 = bitcast <32 x i40> %a0 to <40 x i32>
309  %x1 = bitcast <32 x i40> %a1 to <40 x i32>
310  %r = shufflevector <40 x i32> %x0, <40 x i32> %x1, <4 x i32> <i32 0, i32 42, i32 poison, i32 poison>
311  ret <4 x i32> %r
312}
313
314; negative - src type mismatch
315
316define <8 x i32> @concat_sext_v4i8_v4i16_v8i32(<4 x i8> %a0, <4 x i16> %a1) {
317; CHECK-LABEL: define <8 x i32> @concat_sext_v4i8_v4i16_v8i32(
318; CHECK-SAME: <4 x i8> [[A0:%.*]], <4 x i16> [[A1:%.*]]) #[[ATTR0]] {
319; CHECK-NEXT:    [[X0:%.*]] = sext <4 x i8> [[A0]] to <4 x i32>
320; CHECK-NEXT:    [[X1:%.*]] = sext <4 x i16> [[A1]] to <4 x i32>
321; CHECK-NEXT:    [[R:%.*]] = shufflevector <4 x i32> [[X0]], <4 x i32> [[X1]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
322; CHECK-NEXT:    ret <8 x i32> [[R]]
323;
324  %x0 = sext <4 x i8> %a0 to <4 x i32>
325  %x1 = sext <4 x i16> %a1 to <4 x i32>
326  %r = shufflevector <4 x i32> %x0, <4 x i32> %x1, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
327  ret <8 x i32> %r
328}
329
330; negative - castop mismatch
331
332define <16 x i32> @concat_sext_zext_v8i16_v16i32(<8 x i16> %a0, <8 x i16> %a1) {
333; CHECK-LABEL: define <16 x i32> @concat_sext_zext_v8i16_v16i32(
334; CHECK-SAME: <8 x i16> [[A0:%.*]], <8 x i16> [[A1:%.*]]) #[[ATTR0]] {
335; CHECK-NEXT:    [[X0:%.*]] = sext <8 x i16> [[A0]] to <8 x i32>
336; CHECK-NEXT:    [[X1:%.*]] = zext <8 x i16> [[A1]] to <8 x i32>
337; CHECK-NEXT:    [[R:%.*]] = shufflevector <8 x i32> [[X0]], <8 x i32> [[X1]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
338; CHECK-NEXT:    ret <16 x i32> [[R]]
339;
340  %x0 = sext <8 x i16> %a0 to <8 x i32>
341  %x1 = zext <8 x i16> %a1 to <8 x i32>
342  %r = shufflevector <8 x i32> %x0, <8 x i32> %x1, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
343  ret <16 x i32> %r
344}
345