1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -instcombine -S | FileCheck %s 3 4define <4 x float> @test1(<4 x float> %v1) { 5; CHECK-LABEL: @test1( 6; CHECK-NEXT: ret <4 x float> %v1 7; 8 %v2 = shufflevector <4 x float> %v1, <4 x float> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3> 9 ret <4 x float> %v2 10} 11 12define <4 x float> @test2(<4 x float> %v1) { 13; CHECK-LABEL: @test2( 14; CHECK-NEXT: ret <4 x float> %v1 15; 16 %v2 = shufflevector <4 x float> %v1, <4 x float> %v1, <4 x i32> <i32 0, i32 5, i32 2, i32 7> 17 ret <4 x float> %v2 18} 19 20define float @test3(<4 x float> %A, <4 x float> %B, float %f) { 21; CHECK-LABEL: @test3( 22; CHECK-NEXT: ret float %f 23; 24 %C = insertelement <4 x float> %A, float %f, i32 0 25 %D = shufflevector <4 x float> %C, <4 x float> %B, <4 x i32> <i32 5, i32 0, i32 2, i32 7> 26 %E = extractelement <4 x float> %D, i32 1 27 ret float %E 28} 29 30define i32 @test4(<4 x i32> %X) { 31; CHECK-LABEL: @test4( 32; CHECK-NEXT: [[TMP34:%.*]] = extractelement <4 x i32> %X, i32 0 33; CHECK-NEXT: ret i32 [[TMP34]] 34; 35 %tmp152.i53899.i = shufflevector <4 x i32> %X, <4 x i32> undef, <4 x i32> zeroinitializer 36 %tmp34 = extractelement <4 x i32> %tmp152.i53899.i, i32 0 37 ret i32 %tmp34 38} 39 40define i32 @test5(<4 x i32> %X) { 41; CHECK-LABEL: @test5( 42; CHECK-NEXT: [[TMP34:%.*]] = extractelement <4 x i32> %X, i32 3 43; CHECK-NEXT: ret i32 [[TMP34]] 44; 45 %tmp152.i53899.i = shufflevector <4 x i32> %X, <4 x i32> undef, <4 x i32> <i32 3, i32 2, i32 undef, i32 undef> 46 %tmp34 = extractelement <4 x i32> %tmp152.i53899.i, i32 0 47 ret i32 %tmp34 48} 49 50define float @test6(<4 x float> %X) { 51; CHECK-LABEL: @test6( 52; CHECK-NEXT: [[TMP34:%.*]] = extractelement <4 x float> %X, i32 0 53; CHECK-NEXT: ret float [[TMP34]] 54; 55 %X1 = bitcast <4 x float> %X to <4 x i32> 56 %tmp152.i53899.i = shufflevector <4 x i32> %X1, <4 x i32> undef, <4 x i32> zeroinitializer 57 %tmp152.i53900.i = bitcast <4 x i32> %tmp152.i53899.i to <4 x float> 58 %tmp34 = extractelement <4 x float> %tmp152.i53900.i, i32 0 59 ret float %tmp34 60} 61 62define <4 x float> @test7(<4 x float> %tmp45.i) { 63; CHECK-LABEL: @test7( 64; CHECK-NEXT: ret <4 x float> %tmp45.i 65; 66 %tmp1642.i = shufflevector <4 x float> %tmp45.i, <4 x float> undef, <4 x i32> < i32 0, i32 1, i32 6, i32 7 > 67 ret <4 x float> %tmp1642.i 68} 69 70; This should turn into a single shuffle. 71define <4 x float> @test8(<4 x float> %tmp, <4 x float> %tmp1) { 72; CHECK-LABEL: @test8( 73; CHECK-NEXT: [[TMP134:%.*]] = shufflevector <4 x float> %tmp, <4 x float> %tmp1, <4 x i32> <i32 1, i32 undef, i32 3, i32 4> 74; CHECK-NEXT: ret <4 x float> [[TMP134]] 75; 76 %tmp4 = extractelement <4 x float> %tmp, i32 1 77 %tmp2 = extractelement <4 x float> %tmp, i32 3 78 %tmp1.upgrd.1 = extractelement <4 x float> %tmp1, i32 0 79 %tmp128 = insertelement <4 x float> undef, float %tmp4, i32 0 80 %tmp130 = insertelement <4 x float> %tmp128, float undef, i32 1 81 %tmp132 = insertelement <4 x float> %tmp130, float %tmp2, i32 2 82 %tmp134 = insertelement <4 x float> %tmp132, float %tmp1.upgrd.1, i32 3 83 ret <4 x float> %tmp134 84} 85 86; Test fold of two shuffles where the first shuffle vectors inputs are a 87; different length then the second. 88define <4 x i8> @test9(<16 x i8> %tmp6) nounwind { 89; CHECK-LABEL: @test9( 90; CHECK-NEXT: [[TMP9:%.*]] = shufflevector <16 x i8> %tmp6, <16 x i8> undef, <4 x i32> <i32 13, i32 9, i32 4, i32 13> 91; CHECK-NEXT: ret <4 x i8> [[TMP9]] 92; 93 %tmp7 = shufflevector <16 x i8> %tmp6, <16 x i8> undef, <4 x i32> < i32 13, i32 9, i32 4, i32 13 > ; <<4 x i8>> [#uses=1] 94 %tmp9 = shufflevector <4 x i8> %tmp7, <4 x i8> undef, <4 x i32> < i32 3, i32 1, i32 2, i32 0 > ; <<4 x i8>> [#uses=1] 95 ret <4 x i8> %tmp9 96} 97 98; Same as test9, but make sure that "undef" mask values are not confused with 99; mask values of 2*N, where N is the mask length. These shuffles should not 100; be folded (because [8,9,4,8] may not be a mask supported by the target). 101define <4 x i8> @test9a(<16 x i8> %tmp6) nounwind { 102; CHECK-LABEL: @test9a( 103; CHECK-NEXT: [[TMP7:%.*]] = shufflevector <16 x i8> %tmp6, <16 x i8> undef, <4 x i32> <i32 undef, i32 9, i32 4, i32 8> 104; CHECK-NEXT: [[TMP9:%.*]] = shufflevector <4 x i8> [[TMP7]], <4 x i8> undef, <4 x i32> <i32 3, i32 1, i32 2, i32 undef> 105; CHECK-NEXT: ret <4 x i8> [[TMP9]] 106; 107 %tmp7 = shufflevector <16 x i8> %tmp6, <16 x i8> undef, <4 x i32> < i32 undef, i32 9, i32 4, i32 8 > ; <<4 x i8>> [#uses=1] 108 %tmp9 = shufflevector <4 x i8> %tmp7, <4 x i8> undef, <4 x i32> < i32 3, i32 1, i32 2, i32 0 > ; <<4 x i8>> [#uses=1] 109 ret <4 x i8> %tmp9 110} 111 112; Test fold of two shuffles where the first shuffle vectors inputs are a 113; different length then the second. 114define <4 x i8> @test9b(<4 x i8> %tmp6, <4 x i8> %tmp7) nounwind { 115; CHECK-LABEL: @test9b( 116; CHECK-NEXT: [[TMP9:%.*]] = shufflevector <4 x i8> %tmp6, <4 x i8> %tmp7, <4 x i32> <i32 0, i32 1, i32 4, i32 5> 117; CHECK-NEXT: ret <4 x i8> [[TMP9]] 118; 119 %tmp1 = shufflevector <4 x i8> %tmp6, <4 x i8> %tmp7, <8 x i32> <i32 0, i32 1, i32 4, i32 5, i32 4, i32 5, i32 2, i32 3> ; <<4 x i8>> [#uses=1] 120 %tmp9 = shufflevector <8 x i8> %tmp1, <8 x i8> undef, <4 x i32> <i32 0, i32 1, i32 4, i32 5> ; <<4 x i8>> [#uses=1] 121 ret <4 x i8> %tmp9 122} 123 124; Redundant vector splats should be removed. Radar 8597790. 125define <4 x i32> @test10(<4 x i32> %tmp5) nounwind { 126; CHECK-LABEL: @test10( 127; CHECK-NEXT: [[TMP7:%.*]] = shufflevector <4 x i32> %tmp5, <4 x i32> undef, <4 x i32> <i32 1, i32 1, i32 1, i32 1> 128; CHECK-NEXT: ret <4 x i32> [[TMP7]] 129; 130 %tmp6 = shufflevector <4 x i32> %tmp5, <4 x i32> undef, <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef> 131 %tmp7 = shufflevector <4 x i32> %tmp6, <4 x i32> undef, <4 x i32> zeroinitializer 132 ret <4 x i32> %tmp7 133} 134 135; Test fold of two shuffles where the two shufflevector inputs's op1 are 136; the same 137define <8 x i8> @test11(<16 x i8> %tmp6) nounwind { 138; CHECK-LABEL: @test11( 139; CHECK-NEXT: [[TMP3:%.*]] = shufflevector <16 x i8> %tmp6, <16 x i8> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> 140; CHECK-NEXT: ret <8 x i8> [[TMP3]] 141; 142 %tmp1 = shufflevector <16 x i8> %tmp6, <16 x i8> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3> ; <<4 x i8>> [#uses=1] 143 %tmp2 = shufflevector <16 x i8> %tmp6, <16 x i8> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 7> ; <<4 x i8>> [#uses=1] 144 %tmp3 = shufflevector <4 x i8> %tmp1, <4 x i8> %tmp2, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> ; <<8 x i8>> [#uses=1] 145 ret <8 x i8> %tmp3 146} 147 148; Test fold of two shuffles where the first shufflevector's inputs are 149; the same as the second 150define <8 x i8> @test12(<8 x i8> %tmp6, <8 x i8> %tmp2) nounwind { 151; CHECK-LABEL: @test12( 152; CHECK-NEXT: [[TMP3:%.*]] = shufflevector <8 x i8> %tmp6, <8 x i8> %tmp2, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 9, i32 8, i32 11, i32 12> 153; CHECK-NEXT: ret <8 x i8> [[TMP3]] 154; 155 %tmp1 = shufflevector <8 x i8> %tmp6, <8 x i8> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 5, i32 4, i32 undef, i32 7> ; <<8 x i8>> [#uses=1] 156 %tmp3 = shufflevector <8 x i8> %tmp1, <8 x i8> %tmp2, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 9, i32 8, i32 11, i32 12> ; <<8 x i8>> [#uses=1] 157 ret <8 x i8> %tmp3 158} 159 160; Test fold of two shuffles where the first shufflevector's inputs are 161; the same as the second 162define <8 x i8> @test12a(<8 x i8> %tmp6, <8 x i8> %tmp2) nounwind { 163; CHECK-LABEL: @test12a( 164; CHECK-NEXT: [[TMP3:%.*]] = shufflevector <8 x i8> %tmp2, <8 x i8> %tmp6, <8 x i32> <i32 0, i32 3, i32 1, i32 4, i32 8, i32 9, i32 10, i32 11> 165; CHECK-NEXT: ret <8 x i8> [[TMP3]] 166; 167 %tmp1 = shufflevector <8 x i8> %tmp6, <8 x i8> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 5, i32 4, i32 undef, i32 7> ; <<8 x i8>> [#uses=1] 168 %tmp3 = shufflevector <8 x i8> %tmp2, <8 x i8> %tmp1, <8 x i32> <i32 0, i32 3, i32 1, i32 4, i32 8, i32 9, i32 10, i32 11> ; <<8 x i8>> [#uses=1] 169 ret <8 x i8> %tmp3 170} 171 172define <2 x i8> @test13a(i8 %x1, i8 %x2) { 173; CHECK-LABEL: @test13a( 174; CHECK-NEXT: [[TMP1:%.*]] = insertelement <2 x i8> undef, i8 %x1, i32 1 175; CHECK-NEXT: [[TMP2:%.*]] = insertelement <2 x i8> [[TMP1]], i8 %x2, i32 0 176; CHECK-NEXT: [[TMP3:%.*]] = add <2 x i8> [[TMP2]], <i8 7, i8 5> 177; CHECK-NEXT: ret <2 x i8> [[TMP3]] 178; 179 %A = insertelement <2 x i8> undef, i8 %x1, i32 0 180 %B = insertelement <2 x i8> %A, i8 %x2, i32 1 181 %C = add <2 x i8> %B, <i8 5, i8 7> 182 %D = shufflevector <2 x i8> %C, <2 x i8> undef, <2 x i32> <i32 1, i32 0> 183 ret <2 x i8> %D 184} 185 186define <2 x i8> @test13b(i8 %x) { 187; CHECK-LABEL: @test13b( 188; CHECK-NEXT: [[TMP1:%.*]] = insertelement <2 x i8> undef, i8 %x, i32 1 189; CHECK-NEXT: ret <2 x i8> [[TMP1]] 190; 191 %A = insertelement <2 x i8> undef, i8 %x, i32 0 192 %B = shufflevector <2 x i8> %A, <2 x i8> undef, <2 x i32> <i32 undef, i32 0> 193 ret <2 x i8> %B 194} 195 196define <2 x i8> @test13c(i8 %x1, i8 %x2) { 197; CHECK-LABEL: @test13c( 198; CHECK-NEXT: [[TMP1:%.*]] = insertelement <2 x i8> undef, i8 %x1, i32 0 199; CHECK-NEXT: [[TMP2:%.*]] = insertelement <2 x i8> [[TMP1]], i8 %x2, i32 1 200; CHECK-NEXT: ret <2 x i8> [[TMP2]] 201; 202 %A = insertelement <4 x i8> undef, i8 %x1, i32 0 203 %B = insertelement <4 x i8> %A, i8 %x2, i32 2 204 %C = shufflevector <4 x i8> %B, <4 x i8> undef, <2 x i32> <i32 0, i32 2> 205 ret <2 x i8> %C 206} 207 208define void @test14(i16 %conv10) { 209; CHECK-LABEL: @test14( 210; CHECK-NEXT: store <4 x i16> <i16 undef, i16 undef, i16 undef, i16 23>, <4 x i16>* undef, align 8 211; CHECK-NEXT: ret void 212; 213 %tmp = alloca <4 x i16>, align 8 214 %vecinit6 = insertelement <4 x i16> undef, i16 23, i32 3 215 store <4 x i16> %vecinit6, <4 x i16>* undef 216 %tmp1 = load <4 x i16>, <4 x i16>* undef 217 %vecinit11 = insertelement <4 x i16> undef, i16 %conv10, i32 3 218 %div = udiv <4 x i16> %tmp1, %vecinit11 219 store <4 x i16> %div, <4 x i16>* %tmp 220 %tmp4 = load <4 x i16>, <4 x i16>* %tmp 221 %tmp5 = shufflevector <4 x i16> %tmp4, <4 x i16> undef, <2 x i32> <i32 2, i32 0> 222 %cmp = icmp ule <2 x i16> %tmp5, undef 223 %sext = sext <2 x i1> %cmp to <2 x i16> 224 ret void 225} 226 227; Check that sequences of insert/extract element are 228; collapsed into valid shuffle instruction with correct shuffle indexes. 229 230define <4 x float> @test15a(<4 x float> %LHS, <4 x float> %RHS) { 231; CHECK-LABEL: @test15a( 232; CHECK-NEXT: [[TMP4:%.*]] = shufflevector <4 x float> %LHS, <4 x float> %RHS, <4 x i32> <i32 4, i32 0, i32 6, i32 6> 233; CHECK-NEXT: ret <4 x float> [[TMP4]] 234; 235 %tmp1 = extractelement <4 x float> %LHS, i32 0 236 %tmp2 = insertelement <4 x float> %RHS, float %tmp1, i32 1 237 %tmp3 = extractelement <4 x float> %RHS, i32 2 238 %tmp4 = insertelement <4 x float> %tmp2, float %tmp3, i32 3 239 ret <4 x float> %tmp4 240} 241 242define <4 x float> @test15b(<4 x float> %LHS, <4 x float> %RHS) { 243; CHECK-LABEL: @test15b( 244; CHECK-NEXT: [[TMP5:%.*]] = shufflevector <4 x float> %LHS, <4 x float> %RHS, <4 x i32> <i32 4, i32 3, i32 6, i32 6> 245; CHECK-NEXT: ret <4 x float> [[TMP5]] 246; 247 %tmp0 = extractelement <4 x float> %LHS, i32 3 248 %tmp1 = insertelement <4 x float> %RHS, float %tmp0, i32 0 249 %tmp2 = extractelement <4 x float> %tmp1, i32 0 250 %tmp3 = insertelement <4 x float> %RHS, float %tmp2, i32 1 251 %tmp4 = extractelement <4 x float> %RHS, i32 2 252 %tmp5 = insertelement <4 x float> %tmp3, float %tmp4, i32 3 253 ret <4 x float> %tmp5 254} 255 256define <1 x i32> @test16a(i32 %ele) { 257; CHECK-LABEL: @test16a( 258; CHECK-NEXT: ret <1 x i32> <i32 2> 259; 260 %tmp0 = insertelement <2 x i32> <i32 1, i32 undef>, i32 %ele, i32 1 261 %tmp1 = shl <2 x i32> %tmp0, <i32 1, i32 1> 262 %tmp2 = shufflevector <2 x i32> %tmp1, <2 x i32> undef, <1 x i32> <i32 0> 263 ret <1 x i32> %tmp2 264} 265 266define <4 x i8> @test16b(i8 %ele) { 267; CHECK-LABEL: @test16b( 268; CHECK-NEXT: ret <4 x i8> <i8 2, i8 2, i8 2, i8 2> 269; 270 %tmp0 = insertelement <8 x i8> <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 undef, i8 1>, i8 %ele, i32 6 271 %tmp1 = shl <8 x i8> %tmp0, <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1> 272 %tmp2 = shufflevector <8 x i8> %tmp1, <8 x i8> undef, <4 x i32> <i32 1, i32 2, i32 3, i32 4> 273 ret <4 x i8> %tmp2 274} 275 276; If composition of two shuffles is identity, shuffles can be removed. 277define <4 x i32> @shuffle_17ident(<4 x i32> %v) nounwind uwtable { 278; CHECK-LABEL: @shuffle_17ident( 279; CHECK-NEXT: ret <4 x i32> %v 280; 281 %shuffle = shufflevector <4 x i32> %v, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0> 282 %shuffle2 = shufflevector <4 x i32> %shuffle, <4 x i32> zeroinitializer, <4 x i32> <i32 3, i32 0, i32 1, i32 2> 283 ret <4 x i32> %shuffle2 284} 285 286; swizzle can be put after operation 287define <4 x i32> @shuffle_17and(<4 x i32> %v1, <4 x i32> %v2) nounwind uwtable { 288; CHECK-LABEL: @shuffle_17and( 289; CHECK-NEXT: [[TMP1:%.*]] = and <4 x i32> %v1, %v2 290; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> undef, <4 x i32> <i32 1, i32 2, i32 3, i32 0> 291; CHECK-NEXT: ret <4 x i32> [[TMP2]] 292; 293 %t1 = shufflevector <4 x i32> %v1, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0> 294 %t2 = shufflevector <4 x i32> %v2, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0> 295 %r = and <4 x i32> %t1, %t2 296 ret <4 x i32> %r 297} 298 299define <4 x i32> @shuffle_17add(<4 x i32> %v1, <4 x i32> %v2) nounwind uwtable { 300; CHECK-LABEL: @shuffle_17add( 301; CHECK-NEXT: [[TMP1:%.*]] = add <4 x i32> %v1, %v2 302; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> undef, <4 x i32> <i32 1, i32 2, i32 3, i32 0> 303; CHECK-NEXT: ret <4 x i32> [[TMP2]] 304; 305 %t1 = shufflevector <4 x i32> %v1, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0> 306 %t2 = shufflevector <4 x i32> %v2, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0> 307 %r = add <4 x i32> %t1, %t2 308 ret <4 x i32> %r 309} 310 311define <4 x i32> @shuffle_17addnsw(<4 x i32> %v1, <4 x i32> %v2) nounwind uwtable { 312; CHECK-LABEL: @shuffle_17addnsw( 313; CHECK-NEXT: [[TMP1:%.*]] = add nsw <4 x i32> %v1, %v2 314; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> undef, <4 x i32> <i32 1, i32 2, i32 3, i32 0> 315; CHECK-NEXT: ret <4 x i32> [[TMP2]] 316; 317 %t1 = shufflevector <4 x i32> %v1, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0> 318 %t2 = shufflevector <4 x i32> %v2, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0> 319 %r = add nsw <4 x i32> %t1, %t2 320 ret <4 x i32> %r 321} 322 323define <4 x i32> @shuffle_17addnuw(<4 x i32> %v1, <4 x i32> %v2) nounwind uwtable { 324; CHECK-LABEL: @shuffle_17addnuw( 325; CHECK-NEXT: [[TMP1:%.*]] = add nuw <4 x i32> %v1, %v2 326; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> undef, <4 x i32> <i32 1, i32 2, i32 3, i32 0> 327; CHECK-NEXT: ret <4 x i32> [[TMP2]] 328; 329 %t1 = shufflevector <4 x i32> %v1, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0> 330 %t2 = shufflevector <4 x i32> %v2, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0> 331 %r = add nuw <4 x i32> %t1, %t2 332 ret <4 x i32> %r 333} 334 335define <4 x float> @shuffle_17fsub_fast(<4 x float> %v1, <4 x float> %v2) nounwind uwtable { 336; CHECK-LABEL: @shuffle_17fsub_fast( 337; CHECK-NEXT: [[TMP1:%.*]] = fsub fast <4 x float> %v1, %v2 338; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <4 x float> [[TMP1]], <4 x float> undef, <4 x i32> <i32 1, i32 2, i32 3, i32 0> 339; CHECK-NEXT: ret <4 x float> [[TMP2]] 340; 341 %t1 = shufflevector <4 x float> %v1, <4 x float> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0> 342 %t2 = shufflevector <4 x float> %v2, <4 x float> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0> 343 %r = fsub fast <4 x float> %t1, %t2 344 ret <4 x float> %r 345} 346 347define <4 x i32> @shuffle_17addconst(<4 x i32> %v1, <4 x i32> %v2) { 348; CHECK-LABEL: @shuffle_17addconst( 349; CHECK-NEXT: [[TMP1:%.*]] = add <4 x i32> %v1, <i32 4, i32 1, i32 2, i32 3> 350; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> undef, <4 x i32> <i32 1, i32 2, i32 3, i32 0> 351; CHECK-NEXT: ret <4 x i32> [[TMP2]] 352; 353 %t1 = shufflevector <4 x i32> %v1, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 2, i32 3, i32 0> 354 %r = add <4 x i32> %t1, <i32 1, i32 2, i32 3, i32 4> 355 ret <4 x i32> %r 356} 357 358define <4 x i32> @shuffle_17add2(<4 x i32> %v) { 359; CHECK-LABEL: @shuffle_17add2( 360; CHECK-NEXT: [[TMP1:%.*]] = shl <4 x i32> %v, <i32 1, i32 1, i32 1, i32 1> 361; CHECK-NEXT: ret <4 x i32> [[TMP1]] 362; 363 %t1 = shufflevector <4 x i32> %v, <4 x i32> zeroinitializer, <4 x i32> <i32 3, i32 2, i32 1, i32 0> 364 %t2 = add <4 x i32> %t1, %t1 365 %r = shufflevector <4 x i32> %t2, <4 x i32> zeroinitializer, <4 x i32> <i32 3, i32 2, i32 1, i32 0> 366 ret <4 x i32> %r 367} 368 369define <4 x i32> @shuffle_17mulsplat(<4 x i32> %v) { 370; CHECK-LABEL: @shuffle_17mulsplat( 371; CHECK-NEXT: [[TMP1:%.*]] = mul <4 x i32> %v, %v 372; CHECK-NEXT: [[S2:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> undef, <4 x i32> zeroinitializer 373; CHECK-NEXT: ret <4 x i32> [[S2]] 374; 375 %s1 = shufflevector <4 x i32> %v, <4 x i32> zeroinitializer, <4 x i32> zeroinitializer 376 %m1 = mul <4 x i32> %s1, %s1 377 %s2 = shufflevector <4 x i32> %m1, <4 x i32> zeroinitializer, <4 x i32> <i32 1, i32 1, i32 1, i32 1> 378 ret <4 x i32> %s2 379} 380 381; Do not reorder shuffle and binop if LHS of shuffles are of different size 382define <2 x i32> @pr19717(<4 x i32> %in0, <2 x i32> %in1) { 383; CHECK-LABEL: @pr19717( 384; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <4 x i32> %in0, <4 x i32> undef, <2 x i32> zeroinitializer 385; CHECK-NEXT: [[SHUFFLE4:%.*]] = shufflevector <2 x i32> %in1, <2 x i32> undef, <2 x i32> zeroinitializer 386; CHECK-NEXT: [[MUL:%.*]] = mul <2 x i32> [[SHUFFLE]], [[SHUFFLE4]] 387; CHECK-NEXT: ret <2 x i32> [[MUL]] 388; 389 %shuffle = shufflevector <4 x i32> %in0, <4 x i32> %in0, <2 x i32> zeroinitializer 390 %shuffle4 = shufflevector <2 x i32> %in1, <2 x i32> %in1, <2 x i32> zeroinitializer 391 %mul = mul <2 x i32> %shuffle, %shuffle4 392 ret <2 x i32> %mul 393} 394 395define <4 x i16> @pr19717a(<8 x i16> %in0, <8 x i16> %in1) { 396; CHECK-LABEL: @pr19717a( 397; CHECK-NEXT: [[TMP1:%.*]] = mul <8 x i16> %in0, %in1 398; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <8 x i16> [[TMP1]], <8 x i16> undef, <4 x i32> <i32 5, i32 5, i32 5, i32 5> 399; CHECK-NEXT: ret <4 x i16> [[TMP2]] 400; 401 %shuffle = shufflevector <8 x i16> %in0, <8 x i16> %in0, <4 x i32> <i32 5, i32 5, i32 5, i32 5> 402 %shuffle1 = shufflevector <8 x i16> %in1, <8 x i16> %in1, <4 x i32> <i32 5, i32 5, i32 5, i32 5> 403 %mul = mul <4 x i16> %shuffle, %shuffle1 404 ret <4 x i16> %mul 405} 406 407define <8 x i8> @pr19730(<16 x i8> %in0) { 408; CHECK-LABEL: @pr19730( 409; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <16 x i8> %in0, <16 x i8> undef, <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0> 410; CHECK-NEXT: [[SHUFFLE1:%.*]] = shufflevector <8 x i8> [[SHUFFLE]], <8 x i8> undef, <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0> 411; CHECK-NEXT: ret <8 x i8> [[SHUFFLE1]] 412; 413 %shuffle = shufflevector <16 x i8> %in0, <16 x i8> undef, <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0> 414 %shuffle1 = shufflevector <8 x i8> %shuffle, <8 x i8> undef, <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0> 415 ret <8 x i8> %shuffle1 416} 417 418define i32 @pr19737(<4 x i32> %in0) { 419; CHECK-LABEL: @pr19737( 420; CHECK-NEXT: [[RV_LHS:%.*]] = extractelement <4 x i32> %in0, i32 0 421; CHECK-NEXT: ret i32 [[RV_LHS]] 422; 423 %shuffle.i = shufflevector <4 x i32> zeroinitializer, <4 x i32> %in0, <4 x i32> <i32 0, i32 4, i32 2, i32 6> 424 %neg.i = xor <4 x i32> %shuffle.i, <i32 -1, i32 -1, i32 -1, i32 -1> 425 %and.i = and <4 x i32> %in0, %neg.i 426 %rv = extractelement <4 x i32> %and.i, i32 0 427 ret i32 %rv 428} 429 430; In PR20059 ( http://llvm.org/pr20059 ), shufflevector operations are reordered/removed 431; for an srem operation. This is not a valid optimization because it may cause a trap 432; on div-by-zero. 433 434define <4 x i32> @pr20059(<4 x i32> %p1, <4 x i32> %p2) { 435; CHECK-LABEL: @pr20059( 436; CHECK-NEXT: [[SPLAT1:%.*]] = shufflevector <4 x i32> %p1, <4 x i32> undef, <4 x i32> zeroinitializer 437; CHECK-NEXT: [[SPLAT2:%.*]] = shufflevector <4 x i32> %p2, <4 x i32> undef, <4 x i32> zeroinitializer 438; CHECK-NEXT: [[RETVAL:%.*]] = srem <4 x i32> [[SPLAT1]], [[SPLAT2]] 439; CHECK-NEXT: ret <4 x i32> [[RETVAL]] 440; 441 %splat1 = shufflevector <4 x i32> %p1, <4 x i32> undef, <4 x i32> zeroinitializer 442 %splat2 = shufflevector <4 x i32> %p2, <4 x i32> undef, <4 x i32> zeroinitializer 443 %retval = srem <4 x i32> %splat1, %splat2 444 ret <4 x i32> %retval 445} 446 447define <4 x i32> @pr20114(<4 x i32> %__mask) { 448; CHECK-LABEL: @pr20114( 449; CHECK-NEXT: [[MASK01_I:%.*]] = shufflevector <4 x i32> %__mask, <4 x i32> undef, <4 x i32> <i32 0, i32 0, i32 1, i32 1> 450; CHECK-NEXT: [[MASKED_NEW_I_I_I:%.*]] = and <4 x i32> [[MASK01_I]], bitcast (<2 x i64> <i64 ptrtoint (<4 x i32> (<4 x i32>)* @pr20114 to i64), i64 ptrtoint (<4 x i32> (<4 x i32>)* @pr20114 to i64)> to <4 x i32>) 451; CHECK-NEXT: ret <4 x i32> [[MASKED_NEW_I_I_I]] 452; 453 %mask01.i = shufflevector <4 x i32> %__mask, <4 x i32> undef, <4 x i32> <i32 0, i32 0, i32 1, i32 1> 454 %masked_new.i.i.i = and <4 x i32> bitcast (<2 x i64> <i64 ptrtoint (<4 x i32> (<4 x i32>)* @pr20114 to i64), i64 ptrtoint (<4 x i32> (<4 x i32>)* @pr20114 to i64)> to <4 x i32>), %mask01.i 455 ret <4 x i32> %masked_new.i.i.i 456} 457 458define <2 x i32*> @pr23113(<4 x i32*> %A) { 459; CHECK-LABEL: @pr23113( 460; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <4 x i32*> %A, <4 x i32*> undef, <2 x i32> <i32 0, i32 1> 461; CHECK-NEXT: ret <2 x i32*> [[TMP1]] 462; 463 %1 = shufflevector <4 x i32*> %A, <4 x i32*> undef, <2 x i32> <i32 0, i32 1> 464 ret <2 x i32*> %1 465} 466