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