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 13 define <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 24 define <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 36 define <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 48 define <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 59 define <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 70 define <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 81 define <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