1 ; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=corei7 | FileCheck %s 2 3 ; Check that DAGCombiner correctly folds the following pairs of shuffles 4 ; using the following rules: 5 ; 1. shuffle(shuffle(x, y), undef) -> x 6 ; 2. shuffle(shuffle(x, y), undef) -> y 7 ; 3. shuffle(shuffle(x, y), undef) -> shuffle(x, undef) 8 ; 4. shuffle(shuffle(x, y), undef) -> shuffle(undef, y) 9 ; 10 ; Rules 3. and 4. are used only if the resulting shuffle mask is legal. 11 12 define <4 x i32> @test1(<4 x i32> %A, <4 x i32> %B) { 13 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 0, i32 4, i32 3, i32 1> 14 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 4, i32 0, i32 3> 15 ret <4 x i32> %2 16 } 17 ; CHECK-LABEL: test1 18 ; Mask: [3,0,0,1] 19 ; CHECK: pshufd $67 20 ; CHECK-NEXT: ret 21 22 23 define <4 x i32> @test2(<4 x i32> %A, <4 x i32> %B) { 24 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 0, i32 5, i32 2, i32 3> 25 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 4, i32 0, i32 3> 26 ret <4 x i32> %2 27 } 28 ; CHECK-LABEL: test2 29 ; Mask: [2,0,0,3] 30 ; CHECK: pshufd $-62 31 ; CHECK-NEXT: ret 32 33 34 define <4 x i32> @test3(<4 x i32> %A, <4 x i32> %B) { 35 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 0, i32 6, i32 2, i32 3> 36 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 4, i32 0, i32 3> 37 ret <4 x i32> %2 38 } 39 ; CHECK-LABEL: test3 40 ; Mask: [2,0,0,3] 41 ; CHECK: pshufd $-62 42 ; CHECK-NEXT: ret 43 44 45 define <4 x i32> @test4(<4 x i32> %A, <4 x i32> %B) { 46 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 0, i32 4, i32 7, i32 1> 47 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 4, i32 4, i32 0, i32 3> 48 ret <4 x i32> %2 49 } 50 ; CHECK-LABEL: test4 51 ; Mask: [0,0,0,1] 52 ; CHECK: pshufd $64 53 ; CHECK-NEXT: ret 54 55 56 define <4 x i32> @test5(<4 x i32> %A, <4 x i32> %B) { 57 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 5, i32 5, i32 2, i32 3> 58 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 4, i32 4, i32 3> 59 ret <4 x i32> %2 60 } 61 ; CHECK-LABEL: test5 62 ; Mask: [1,1] 63 ; CHECK: movhlps 64 ; CHECK-NEXT: ret 65 66 67 define <4 x i32> @test6(<4 x i32> %A, <4 x i32> %B) { 68 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 0, i32 6, i32 2, i32 4> 69 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 2, i32 4, i32 0, i32 4> 70 ret <4 x i32> %2 71 } 72 ; CHECK-LABEL: test6 73 ; Mask: [2,0,0,0] 74 ; CHECK: pshufd $2 75 ; CHECK-NEXT: ret 76 77 78 define <4 x i32> @test7(<4 x i32> %A, <4 x i32> %B) { 79 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 0, i32 5, i32 2, i32 7> 80 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 0, i32 2, i32 0, i32 2> 81 ret <4 x i32> %2 82 } 83 ; CHECK-LABEL: test7 84 ; Mask: [0,2,0,2] 85 ; CHECK: pshufd $-120 86 ; CHECK-NEXT: ret 87 88 89 define <4 x i32> @test8(<4 x i32> %A, <4 x i32> %B) { 90 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 4, i32 1, i32 6, i32 3> 91 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 1, i32 4, i32 3, i32 4> 92 ret <4 x i32> %2 93 } 94 ; CHECK-LABEL: test8 95 ; Mask: [1,0,3,0] 96 ; CHECK: pshufd $49 97 ; CHECK-NEXT: ret 98 99 100 define <4 x i32> @test9(<4 x i32> %A, <4 x i32> %B) { 101 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 1, i32 3, i32 2, i32 5> 102 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 0, i32 1, i32 4, i32 2> 103 ret <4 x i32> %2 104 } 105 ; CHECK-LABEL: test9 106 ; Mask: [1,3,0,2] 107 ; CHECK: pshufd $-115 108 ; CHECK-NEXT: ret 109 110 111 define <4 x i32> @test10(<4 x i32> %A, <4 x i32> %B) { 112 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 1, i32 1, i32 5, i32 5> 113 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 0, i32 4, i32 1, i32 4> 114 ret <4 x i32> %2 115 } 116 ; CHECK-LABEL: test10 117 ; Mask: [1,0,1,0] 118 ; CHECK: pshufd $17 119 ; CHECK-NEXT: ret 120 121 122 define <4 x i32> @test11(<4 x i32> %A, <4 x i32> %B) { 123 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 1, i32 2, i32 5, i32 4> 124 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 0, i32 4, i32 1, i32 0> 125 ret <4 x i32> %2 126 } 127 ; CHECK-LABEL: test11 128 ; Mask: [1,0,2,1] 129 ; CHECK: pshufd $97 130 ; CHECK-NEXT: ret 131 132 133 define <4 x i32> @test12(<4 x i32> %A, <4 x i32> %B) { 134 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 0, i32 0, i32 2, i32 4> 135 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 1, i32 4, i32 0, i32 4> 136 ret <4 x i32> %2 137 } 138 ; CHECK-LABEL: test12 139 ; Mask: [0,0,0,0] 140 ; CHECK: pshufd $0 141 ; CHECK-NEXT: ret 142 143 144 ; The following pair of shuffles is folded into vector %A. 145 define <4 x i32> @test13(<4 x i32> %A, <4 x i32> %B) { 146 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 1, i32 4, i32 2, i32 6> 147 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 4, i32 0, i32 2, i32 4> 148 ret <4 x i32> %2 149 } 150 ; CHECK-LABEL: test13 151 ; CHECK-NOT: pshufd 152 ; CHECK: ret 153 154 155 ; The following pair of shuffles is folded into vector %B. 156 define <4 x i32> @test14(<4 x i32> %A, <4 x i32> %B) { 157 %1 = shufflevector <4 x i32> %A, <4 x i32> %B, <4 x i32> <i32 0, i32 6, i32 2, i32 4> 158 %2 = shufflevector <4 x i32> %1, <4 x i32> undef, <4 x i32> <i32 3, i32 4, i32 1, i32 4> 159 ret <4 x i32> %2 160 } 161 ; CHECK-LABEL: test14 162 ; CHECK-NOT: pshufd 163 ; CHECK: ret 164 165