1; RUN: llc < %s -march=x86-64 -mtriple=x86_64-unknown-linux-gnu -mcpu=core-avx2 | FileCheck %s
2
3; Test that we correctly fold a shuffle that performs a swizzle of another
4; shuffle node according to the rule
5;  shuffle (shuffle (x, undef, M0), undef, M1) -> shuffle(x, undef, M2)
6;
7; We only do this if the resulting mask is legal to avoid introducing an
8; illegal shuffle that is expanded into a sub-optimal sequence of instructions
9; during lowering stage.
10
11; Check that we produce a single vector permute / shuffle in all cases.
12
13define <8 x i32> @swizzle_1(<8 x i32> %v) {
14  %1 = shufflevector <8 x i32> %v, <8 x i32> undef, <8 x i32> <i32 3, i32 1, i32 2, i32 0, i32 7, i32 5, i32 6, i32 4>
15  %2 = shufflevector <8 x i32> %1, <8 x i32> undef, <8 x i32> <i32 1, i32 0, i32 2, i32 3, i32 7, i32 5, i32 6, i32 4>
16  ret <8 x i32> %2
17}
18; CHECK-LABEL: swizzle_1
19; CHECK: vpermd
20; CHECK-NOT: vpermd
21; CHECK: ret
22
23
24define <8 x i32> @swizzle_2(<8 x i32> %v) {
25  %1 = shufflevector <8 x i32> %v, <8 x i32> undef, <8 x i32> <i32 6, i32 7, i32 4, i32 5, i32 0, i32 1, i32 2, i32 3>
26  %2 = shufflevector <8 x i32> %1, <8 x i32> undef, <8 x i32> <i32 6, i32 7, i32 4, i32 5, i32 0, i32 1, i32 2, i32 3>
27  ret <8 x i32> %2
28}
29; CHECK-LABEL: swizzle_2
30; CHECK: vpshufd $78
31; CHECK-NOT: vpermd
32; CHECK-NOT: vpshufd
33; CHECK: ret
34
35
36define <8 x i32> @swizzle_3(<8 x i32> %v) {
37  %1 = shufflevector <8 x i32> %v, <8 x i32> undef, <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 2, i32 3, i32 0, i32 1>
38  %2 = shufflevector <8 x i32> %1, <8 x i32> undef, <8 x i32> <i32 4, i32 5, i32 6, i32 7, i32 2, i32 3, i32 0, i32 1>
39  ret <8 x i32> %2
40}
41; CHECK-LABEL: swizzle_3
42; CHECK: vpshufd $78
43; CHECK-NOT: vpermd
44; CHECK-NOT: vpshufd
45; CHECK: ret
46
47
48define <8 x i32> @swizzle_4(<8 x i32> %v) {
49  %1 = shufflevector <8 x i32> %v, <8 x i32> undef, <8 x i32> <i32 4, i32 7, i32 5, i32 6, i32 3, i32 2, i32 0, i32 1>
50  %2 = shufflevector <8 x i32> %1, <8 x i32> undef, <8 x i32> <i32 4, i32 7, i32 5, i32 6, i32 3, i32 2, i32 0, i32 1>
51  ret <8 x i32> %2
52}
53; CHECK-LABEL: swizzle_4
54; CHECK: vpermd
55; CHECK-NOT: vpermd
56; CHECK: ret
57
58
59define <8 x i32> @swizzle_5(<8 x i32> %v) {
60  %1 = shufflevector <8 x i32> %v, <8 x i32> undef, <8 x i32> <i32 7, i32 4, i32 6, i32 5, i32 0, i32 2, i32 1, i32 3>
61  %2 = shufflevector <8 x i32> %1, <8 x i32> undef, <8 x i32> <i32 7, i32 4, i32 6, i32 5, i32 0, i32 2, i32 1, i32 3>
62  ret <8 x i32> %2
63}
64; CHECK-LABEL: swizzle_5
65; CHECK: vpermd
66; CHECK-NOT: vpermd
67; CHECK: ret
68
69
70define <8 x i32> @swizzle_6(<8 x i32> %v) {
71  %1 = shufflevector <8 x i32> %v, <8 x i32> undef, <8 x i32> <i32 2, i32 1, i32 3, i32 0, i32 4, i32 7, i32 6, i32 5>
72  %2 = shufflevector <8 x i32> %1, <8 x i32> undef, <8 x i32> <i32 2, i32 1, i32 3, i32 0, i32 4, i32 7, i32 6, i32 5>
73  ret <8 x i32> %2
74}
75; CHECK-LABEL: swizzle_6
76; CHECK: vpermd
77; CHECK-NOT: vpermd
78; CHECK: ret
79
80
81define <8 x i32> @swizzle_7(<8 x i32> %v) {
82  %1 = shufflevector <8 x i32> %v, <8 x i32> undef, <8 x i32> <i32 0, i32 3, i32 1, i32 2, i32 5, i32 4, i32 6, i32 7>
83  %2 = shufflevector <8 x i32> %1, <8 x i32> undef, <8 x i32> <i32 0, i32 3, i32 1, i32 2, i32 5, i32 4, i32 6, i32 7>
84  ret <8 x i32> %2
85}
86; CHECK-LABEL: swizzle_7
87; CHECK: vpermd
88; CHECK-NOT: vpermd
89; CHECK: ret
90
91
92