1; RUN: llc < %s -march=x86-64 -mattr=+sse2,+sse3 | FileCheck %s -check-prefix=CHECK -check-prefix=SSE3 2; RUN: llc < %s -march=x86-64 -mattr=+sse2,+sse3,+ssse3 | FileCheck %s -check-prefix=CHECK -check-prefix=SSSE3 3; RUN: llc < %s -march=x86-64 -mcpu=corei7-avx | FileCheck %s -check-prefix=CHECK -check-prefix=AVX 4; RUN: llc < %s -march=x86-64 -mcpu=core-avx2 | FileCheck %s -check-prefix=CHECK -check-prefix=AVX2 5 6 7 8define <4 x float> @hadd_ps_test1(<4 x float> %A, <4 x float> %B) { 9 %vecext = extractelement <4 x float> %A, i32 0 10 %vecext1 = extractelement <4 x float> %A, i32 1 11 %add = fadd float %vecext, %vecext1 12 %vecinit = insertelement <4 x float> undef, float %add, i32 0 13 %vecext2 = extractelement <4 x float> %A, i32 2 14 %vecext3 = extractelement <4 x float> %A, i32 3 15 %add4 = fadd float %vecext2, %vecext3 16 %vecinit5 = insertelement <4 x float> %vecinit, float %add4, i32 1 17 %vecext6 = extractelement <4 x float> %B, i32 0 18 %vecext7 = extractelement <4 x float> %B, i32 1 19 %add8 = fadd float %vecext6, %vecext7 20 %vecinit9 = insertelement <4 x float> %vecinit5, float %add8, i32 2 21 %vecext10 = extractelement <4 x float> %B, i32 2 22 %vecext11 = extractelement <4 x float> %B, i32 3 23 %add12 = fadd float %vecext10, %vecext11 24 %vecinit13 = insertelement <4 x float> %vecinit9, float %add12, i32 3 25 ret <4 x float> %vecinit13 26} 27; CHECK-LABEL: hadd_ps_test1 28; CHECK: haddps 29; CHECK-NEXT: ret 30 31 32define <4 x float> @hadd_ps_test2(<4 x float> %A, <4 x float> %B) { 33 %vecext = extractelement <4 x float> %A, i32 2 34 %vecext1 = extractelement <4 x float> %A, i32 3 35 %add = fadd float %vecext, %vecext1 36 %vecinit = insertelement <4 x float> undef, float %add, i32 1 37 %vecext2 = extractelement <4 x float> %A, i32 0 38 %vecext3 = extractelement <4 x float> %A, i32 1 39 %add4 = fadd float %vecext2, %vecext3 40 %vecinit5 = insertelement <4 x float> %vecinit, float %add4, i32 0 41 %vecext6 = extractelement <4 x float> %B, i32 2 42 %vecext7 = extractelement <4 x float> %B, i32 3 43 %add8 = fadd float %vecext6, %vecext7 44 %vecinit9 = insertelement <4 x float> %vecinit5, float %add8, i32 3 45 %vecext10 = extractelement <4 x float> %B, i32 0 46 %vecext11 = extractelement <4 x float> %B, i32 1 47 %add12 = fadd float %vecext10, %vecext11 48 %vecinit13 = insertelement <4 x float> %vecinit9, float %add12, i32 2 49 ret <4 x float> %vecinit13 50} 51; CHECK-LABEL: hadd_ps_test2 52; CHECK: haddps 53; CHECK-NEXT: ret 54 55 56define <4 x float> @hsub_ps_test1(<4 x float> %A, <4 x float> %B) { 57 %vecext = extractelement <4 x float> %A, i32 0 58 %vecext1 = extractelement <4 x float> %A, i32 1 59 %sub = fsub float %vecext, %vecext1 60 %vecinit = insertelement <4 x float> undef, float %sub, i32 0 61 %vecext2 = extractelement <4 x float> %A, i32 2 62 %vecext3 = extractelement <4 x float> %A, i32 3 63 %sub4 = fsub float %vecext2, %vecext3 64 %vecinit5 = insertelement <4 x float> %vecinit, float %sub4, i32 1 65 %vecext6 = extractelement <4 x float> %B, i32 0 66 %vecext7 = extractelement <4 x float> %B, i32 1 67 %sub8 = fsub float %vecext6, %vecext7 68 %vecinit9 = insertelement <4 x float> %vecinit5, float %sub8, i32 2 69 %vecext10 = extractelement <4 x float> %B, i32 2 70 %vecext11 = extractelement <4 x float> %B, i32 3 71 %sub12 = fsub float %vecext10, %vecext11 72 %vecinit13 = insertelement <4 x float> %vecinit9, float %sub12, i32 3 73 ret <4 x float> %vecinit13 74} 75; CHECK-LABEL: hsub_ps_test1 76; CHECK: hsubps 77; CHECK-NEXT: ret 78 79 80define <4 x float> @hsub_ps_test2(<4 x float> %A, <4 x float> %B) { 81 %vecext = extractelement <4 x float> %A, i32 2 82 %vecext1 = extractelement <4 x float> %A, i32 3 83 %sub = fsub float %vecext, %vecext1 84 %vecinit = insertelement <4 x float> undef, float %sub, i32 1 85 %vecext2 = extractelement <4 x float> %A, i32 0 86 %vecext3 = extractelement <4 x float> %A, i32 1 87 %sub4 = fsub float %vecext2, %vecext3 88 %vecinit5 = insertelement <4 x float> %vecinit, float %sub4, i32 0 89 %vecext6 = extractelement <4 x float> %B, i32 2 90 %vecext7 = extractelement <4 x float> %B, i32 3 91 %sub8 = fsub float %vecext6, %vecext7 92 %vecinit9 = insertelement <4 x float> %vecinit5, float %sub8, i32 3 93 %vecext10 = extractelement <4 x float> %B, i32 0 94 %vecext11 = extractelement <4 x float> %B, i32 1 95 %sub12 = fsub float %vecext10, %vecext11 96 %vecinit13 = insertelement <4 x float> %vecinit9, float %sub12, i32 2 97 ret <4 x float> %vecinit13 98} 99; CHECK-LABEL: hsub_ps_test2 100; CHECK: hsubps 101; CHECK-NEXT: ret 102 103 104define <4 x i32> @phadd_d_test1(<4 x i32> %A, <4 x i32> %B) { 105 %vecext = extractelement <4 x i32> %A, i32 0 106 %vecext1 = extractelement <4 x i32> %A, i32 1 107 %add = add i32 %vecext, %vecext1 108 %vecinit = insertelement <4 x i32> undef, i32 %add, i32 0 109 %vecext2 = extractelement <4 x i32> %A, i32 2 110 %vecext3 = extractelement <4 x i32> %A, i32 3 111 %add4 = add i32 %vecext2, %vecext3 112 %vecinit5 = insertelement <4 x i32> %vecinit, i32 %add4, i32 1 113 %vecext6 = extractelement <4 x i32> %B, i32 0 114 %vecext7 = extractelement <4 x i32> %B, i32 1 115 %add8 = add i32 %vecext6, %vecext7 116 %vecinit9 = insertelement <4 x i32> %vecinit5, i32 %add8, i32 2 117 %vecext10 = extractelement <4 x i32> %B, i32 2 118 %vecext11 = extractelement <4 x i32> %B, i32 3 119 %add12 = add i32 %vecext10, %vecext11 120 %vecinit13 = insertelement <4 x i32> %vecinit9, i32 %add12, i32 3 121 ret <4 x i32> %vecinit13 122} 123; CHECK-LABEL: phadd_d_test1 124; SSE3-NOT: phaddd 125; SSSE3: phaddd 126; AVX: vphaddd 127; AVX2 vphaddd 128; CHECK: ret 129 130 131define <4 x i32> @phadd_d_test2(<4 x i32> %A, <4 x i32> %B) { 132 %vecext = extractelement <4 x i32> %A, i32 2 133 %vecext1 = extractelement <4 x i32> %A, i32 3 134 %add = add i32 %vecext, %vecext1 135 %vecinit = insertelement <4 x i32> undef, i32 %add, i32 1 136 %vecext2 = extractelement <4 x i32> %A, i32 0 137 %vecext3 = extractelement <4 x i32> %A, i32 1 138 %add4 = add i32 %vecext2, %vecext3 139 %vecinit5 = insertelement <4 x i32> %vecinit, i32 %add4, i32 0 140 %vecext6 = extractelement <4 x i32> %B, i32 3 141 %vecext7 = extractelement <4 x i32> %B, i32 2 142 %add8 = add i32 %vecext6, %vecext7 143 %vecinit9 = insertelement <4 x i32> %vecinit5, i32 %add8, i32 3 144 %vecext10 = extractelement <4 x i32> %B, i32 1 145 %vecext11 = extractelement <4 x i32> %B, i32 0 146 %add12 = add i32 %vecext10, %vecext11 147 %vecinit13 = insertelement <4 x i32> %vecinit9, i32 %add12, i32 2 148 ret <4 x i32> %vecinit13 149} 150; CHECK-LABEL: phadd_d_test2 151; SSE3-NOT: phaddd 152; SSSE3: phaddd 153; AVX: vphaddd 154; AVX2 vphaddd 155; CHECK: ret 156 157 158define <4 x i32> @phsub_d_test1(<4 x i32> %A, <4 x i32> %B) { 159 %vecext = extractelement <4 x i32> %A, i32 0 160 %vecext1 = extractelement <4 x i32> %A, i32 1 161 %sub = sub i32 %vecext, %vecext1 162 %vecinit = insertelement <4 x i32> undef, i32 %sub, i32 0 163 %vecext2 = extractelement <4 x i32> %A, i32 2 164 %vecext3 = extractelement <4 x i32> %A, i32 3 165 %sub4 = sub i32 %vecext2, %vecext3 166 %vecinit5 = insertelement <4 x i32> %vecinit, i32 %sub4, i32 1 167 %vecext6 = extractelement <4 x i32> %B, i32 0 168 %vecext7 = extractelement <4 x i32> %B, i32 1 169 %sub8 = sub i32 %vecext6, %vecext7 170 %vecinit9 = insertelement <4 x i32> %vecinit5, i32 %sub8, i32 2 171 %vecext10 = extractelement <4 x i32> %B, i32 2 172 %vecext11 = extractelement <4 x i32> %B, i32 3 173 %sub12 = sub i32 %vecext10, %vecext11 174 %vecinit13 = insertelement <4 x i32> %vecinit9, i32 %sub12, i32 3 175 ret <4 x i32> %vecinit13 176} 177; CHECK-LABEL: phsub_d_test1 178; SSE3-NOT: phsubd 179; SSSE3: phsubd 180; AVX: vphsubd 181; AVX2 vphsubd 182; CHECK: ret 183 184 185define <4 x i32> @phsub_d_test2(<4 x i32> %A, <4 x i32> %B) { 186 %vecext = extractelement <4 x i32> %A, i32 2 187 %vecext1 = extractelement <4 x i32> %A, i32 3 188 %sub = sub i32 %vecext, %vecext1 189 %vecinit = insertelement <4 x i32> undef, i32 %sub, i32 1 190 %vecext2 = extractelement <4 x i32> %A, i32 0 191 %vecext3 = extractelement <4 x i32> %A, i32 1 192 %sub4 = sub i32 %vecext2, %vecext3 193 %vecinit5 = insertelement <4 x i32> %vecinit, i32 %sub4, i32 0 194 %vecext6 = extractelement <4 x i32> %B, i32 2 195 %vecext7 = extractelement <4 x i32> %B, i32 3 196 %sub8 = sub i32 %vecext6, %vecext7 197 %vecinit9 = insertelement <4 x i32> %vecinit5, i32 %sub8, i32 3 198 %vecext10 = extractelement <4 x i32> %B, i32 0 199 %vecext11 = extractelement <4 x i32> %B, i32 1 200 %sub12 = sub i32 %vecext10, %vecext11 201 %vecinit13 = insertelement <4 x i32> %vecinit9, i32 %sub12, i32 2 202 ret <4 x i32> %vecinit13 203} 204; CHECK-LABEL: phsub_d_test2 205; SSE3-NOT: phsubd 206; SSSE3: phsubd 207; AVX: vphsubd 208; AVX2 vphsubd 209; CHECK: ret 210 211 212define <2 x double> @hadd_pd_test1(<2 x double> %A, <2 x double> %B) { 213 %vecext = extractelement <2 x double> %A, i32 0 214 %vecext1 = extractelement <2 x double> %A, i32 1 215 %add = fadd double %vecext, %vecext1 216 %vecinit = insertelement <2 x double> undef, double %add, i32 0 217 %vecext2 = extractelement <2 x double> %B, i32 0 218 %vecext3 = extractelement <2 x double> %B, i32 1 219 %add2 = fadd double %vecext2, %vecext3 220 %vecinit2 = insertelement <2 x double> %vecinit, double %add2, i32 1 221 ret <2 x double> %vecinit2 222} 223; CHECK-LABEL: hadd_pd_test1 224; CHECK: haddpd 225; CHECK-NEXT: ret 226 227 228define <2 x double> @hadd_pd_test2(<2 x double> %A, <2 x double> %B) { 229 %vecext = extractelement <2 x double> %A, i32 1 230 %vecext1 = extractelement <2 x double> %A, i32 0 231 %add = fadd double %vecext, %vecext1 232 %vecinit = insertelement <2 x double> undef, double %add, i32 0 233 %vecext2 = extractelement <2 x double> %B, i32 1 234 %vecext3 = extractelement <2 x double> %B, i32 0 235 %add2 = fadd double %vecext2, %vecext3 236 %vecinit2 = insertelement <2 x double> %vecinit, double %add2, i32 1 237 ret <2 x double> %vecinit2 238} 239; CHECK-LABEL: hadd_pd_test2 240; CHECK: haddpd 241; CHECK-NEXT: ret 242 243 244define <2 x double> @hsub_pd_test1(<2 x double> %A, <2 x double> %B) { 245 %vecext = extractelement <2 x double> %A, i32 0 246 %vecext1 = extractelement <2 x double> %A, i32 1 247 %sub = fsub double %vecext, %vecext1 248 %vecinit = insertelement <2 x double> undef, double %sub, i32 0 249 %vecext2 = extractelement <2 x double> %B, i32 0 250 %vecext3 = extractelement <2 x double> %B, i32 1 251 %sub2 = fsub double %vecext2, %vecext3 252 %vecinit2 = insertelement <2 x double> %vecinit, double %sub2, i32 1 253 ret <2 x double> %vecinit2 254} 255; CHECK-LABEL: hsub_pd_test1 256; CHECK: hsubpd 257; CHECK-NEXT: ret 258 259 260define <2 x double> @hsub_pd_test2(<2 x double> %A, <2 x double> %B) { 261 %vecext = extractelement <2 x double> %B, i32 0 262 %vecext1 = extractelement <2 x double> %B, i32 1 263 %sub = fsub double %vecext, %vecext1 264 %vecinit = insertelement <2 x double> undef, double %sub, i32 1 265 %vecext2 = extractelement <2 x double> %A, i32 0 266 %vecext3 = extractelement <2 x double> %A, i32 1 267 %sub2 = fsub double %vecext2, %vecext3 268 %vecinit2 = insertelement <2 x double> %vecinit, double %sub2, i32 0 269 ret <2 x double> %vecinit2 270} 271; CHECK-LABEL: hsub_pd_test2 272; CHECK: hsubpd 273; CHECK-NEXT: ret 274 275 276define <4 x double> @avx_vhadd_pd_test(<4 x double> %A, <4 x double> %B) { 277 %vecext = extractelement <4 x double> %A, i32 0 278 %vecext1 = extractelement <4 x double> %A, i32 1 279 %add = fadd double %vecext, %vecext1 280 %vecinit = insertelement <4 x double> undef, double %add, i32 0 281 %vecext2 = extractelement <4 x double> %A, i32 2 282 %vecext3 = extractelement <4 x double> %A, i32 3 283 %add4 = fadd double %vecext2, %vecext3 284 %vecinit5 = insertelement <4 x double> %vecinit, double %add4, i32 1 285 %vecext6 = extractelement <4 x double> %B, i32 0 286 %vecext7 = extractelement <4 x double> %B, i32 1 287 %add8 = fadd double %vecext6, %vecext7 288 %vecinit9 = insertelement <4 x double> %vecinit5, double %add8, i32 2 289 %vecext10 = extractelement <4 x double> %B, i32 2 290 %vecext11 = extractelement <4 x double> %B, i32 3 291 %add12 = fadd double %vecext10, %vecext11 292 %vecinit13 = insertelement <4 x double> %vecinit9, double %add12, i32 3 293 ret <4 x double> %vecinit13 294} 295; CHECK-LABEL: avx_vhadd_pd_test 296; SSE3: haddpd 297; SSE3-NEXT: haddpd 298; SSSE3: haddpd 299; SSSE3: haddpd 300; AVX: vhaddpd 301; AVX: vhaddpd 302; AVX2: vhaddpd 303; AVX2: vhaddpd 304; CHECK: ret 305 306 307define <4 x double> @avx_vhsub_pd_test(<4 x double> %A, <4 x double> %B) { 308 %vecext = extractelement <4 x double> %A, i32 0 309 %vecext1 = extractelement <4 x double> %A, i32 1 310 %sub = fsub double %vecext, %vecext1 311 %vecinit = insertelement <4 x double> undef, double %sub, i32 0 312 %vecext2 = extractelement <4 x double> %A, i32 2 313 %vecext3 = extractelement <4 x double> %A, i32 3 314 %sub4 = fsub double %vecext2, %vecext3 315 %vecinit5 = insertelement <4 x double> %vecinit, double %sub4, i32 1 316 %vecext6 = extractelement <4 x double> %B, i32 0 317 %vecext7 = extractelement <4 x double> %B, i32 1 318 %sub8 = fsub double %vecext6, %vecext7 319 %vecinit9 = insertelement <4 x double> %vecinit5, double %sub8, i32 2 320 %vecext10 = extractelement <4 x double> %B, i32 2 321 %vecext11 = extractelement <4 x double> %B, i32 3 322 %sub12 = fsub double %vecext10, %vecext11 323 %vecinit13 = insertelement <4 x double> %vecinit9, double %sub12, i32 3 324 ret <4 x double> %vecinit13 325} 326; CHECK-LABEL: avx_vhsub_pd_test 327; SSE3: hsubpd 328; SSE3-NEXT: hsubpd 329; SSSE3: hsubpd 330; SSSE3-NEXT: hsubpd 331; AVX: vhsubpd 332; AVX: vhsubpd 333; AVX2: vhsubpd 334; AVX2: vhsubpd 335; CHECK: ret 336 337 338define <8 x i32> @avx2_vphadd_d_test(<8 x i32> %A, <8 x i32> %B) { 339 %vecext = extractelement <8 x i32> %A, i32 0 340 %vecext1 = extractelement <8 x i32> %A, i32 1 341 %add = add i32 %vecext, %vecext1 342 %vecinit = insertelement <8 x i32> undef, i32 %add, i32 0 343 %vecext2 = extractelement <8 x i32> %A, i32 2 344 %vecext3 = extractelement <8 x i32> %A, i32 3 345 %add4 = add i32 %vecext2, %vecext3 346 %vecinit5 = insertelement <8 x i32> %vecinit, i32 %add4, i32 1 347 %vecext6 = extractelement <8 x i32> %A, i32 4 348 %vecext7 = extractelement <8 x i32> %A, i32 5 349 %add8 = add i32 %vecext6, %vecext7 350 %vecinit9 = insertelement <8 x i32> %vecinit5, i32 %add8, i32 2 351 %vecext10 = extractelement <8 x i32> %A, i32 6 352 %vecext11 = extractelement <8 x i32> %A, i32 7 353 %add12 = add i32 %vecext10, %vecext11 354 %vecinit13 = insertelement <8 x i32> %vecinit9, i32 %add12, i32 3 355 %vecext14 = extractelement <8 x i32> %B, i32 0 356 %vecext15 = extractelement <8 x i32> %B, i32 1 357 %add16 = add i32 %vecext14, %vecext15 358 %vecinit17 = insertelement <8 x i32> %vecinit13, i32 %add16, i32 4 359 %vecext18 = extractelement <8 x i32> %B, i32 2 360 %vecext19 = extractelement <8 x i32> %B, i32 3 361 %add20 = add i32 %vecext18, %vecext19 362 %vecinit21 = insertelement <8 x i32> %vecinit17, i32 %add20, i32 5 363 %vecext22 = extractelement <8 x i32> %B, i32 4 364 %vecext23 = extractelement <8 x i32> %B, i32 5 365 %add24 = add i32 %vecext22, %vecext23 366 %vecinit25 = insertelement <8 x i32> %vecinit21, i32 %add24, i32 6 367 %vecext26 = extractelement <8 x i32> %B, i32 6 368 %vecext27 = extractelement <8 x i32> %B, i32 7 369 %add28 = add i32 %vecext26, %vecext27 370 %vecinit29 = insertelement <8 x i32> %vecinit25, i32 %add28, i32 7 371 ret <8 x i32> %vecinit29 372} 373; CHECK-LABEL: avx2_vphadd_d_test 374; SSE3-NOT: phaddd 375; SSSE3: phaddd 376; SSSE3-NEXT: phaddd 377; AVX: vphaddd 378; AVX: vphaddd 379; AVX2: vphaddd 380; AVX2: vphaddd 381; CHECK: ret 382 383define <16 x i16> @avx2_vphadd_w_test(<16 x i16> %a, <16 x i16> %b) { 384 %vecext = extractelement <16 x i16> %a, i32 0 385 %vecext1 = extractelement <16 x i16> %a, i32 1 386 %add = add i16 %vecext, %vecext1 387 %vecinit = insertelement <16 x i16> undef, i16 %add, i32 0 388 %vecext4 = extractelement <16 x i16> %a, i32 2 389 %vecext6 = extractelement <16 x i16> %a, i32 3 390 %add8 = add i16 %vecext4, %vecext6 391 %vecinit10 = insertelement <16 x i16> %vecinit, i16 %add8, i32 1 392 %vecext11 = extractelement <16 x i16> %a, i32 4 393 %vecext13 = extractelement <16 x i16> %a, i32 5 394 %add15 = add i16 %vecext11, %vecext13 395 %vecinit17 = insertelement <16 x i16> %vecinit10, i16 %add15, i32 2 396 %vecext18 = extractelement <16 x i16> %a, i32 6 397 %vecext20 = extractelement <16 x i16> %a, i32 7 398 %add22 = add i16 %vecext18, %vecext20 399 %vecinit24 = insertelement <16 x i16> %vecinit17, i16 %add22, i32 3 400 %vecext25 = extractelement <16 x i16> %a, i32 8 401 %vecext27 = extractelement <16 x i16> %a, i32 9 402 %add29 = add i16 %vecext25, %vecext27 403 %vecinit31 = insertelement <16 x i16> %vecinit24, i16 %add29, i32 4 404 %vecext32 = extractelement <16 x i16> %a, i32 10 405 %vecext34 = extractelement <16 x i16> %a, i32 11 406 %add36 = add i16 %vecext32, %vecext34 407 %vecinit38 = insertelement <16 x i16> %vecinit31, i16 %add36, i32 5 408 %vecext39 = extractelement <16 x i16> %a, i32 12 409 %vecext41 = extractelement <16 x i16> %a, i32 13 410 %add43 = add i16 %vecext39, %vecext41 411 %vecinit45 = insertelement <16 x i16> %vecinit38, i16 %add43, i32 6 412 %vecext46 = extractelement <16 x i16> %a, i32 14 413 %vecext48 = extractelement <16 x i16> %a, i32 15 414 %add50 = add i16 %vecext46, %vecext48 415 %vecinit52 = insertelement <16 x i16> %vecinit45, i16 %add50, i32 7 416 %vecext53 = extractelement <16 x i16> %b, i32 0 417 %vecext55 = extractelement <16 x i16> %b, i32 1 418 %add57 = add i16 %vecext53, %vecext55 419 %vecinit59 = insertelement <16 x i16> %vecinit52, i16 %add57, i32 8 420 %vecext60 = extractelement <16 x i16> %b, i32 2 421 %vecext62 = extractelement <16 x i16> %b, i32 3 422 %add64 = add i16 %vecext60, %vecext62 423 %vecinit66 = insertelement <16 x i16> %vecinit59, i16 %add64, i32 9 424 %vecext67 = extractelement <16 x i16> %b, i32 4 425 %vecext69 = extractelement <16 x i16> %b, i32 5 426 %add71 = add i16 %vecext67, %vecext69 427 %vecinit73 = insertelement <16 x i16> %vecinit66, i16 %add71, i32 10 428 %vecext74 = extractelement <16 x i16> %b, i32 6 429 %vecext76 = extractelement <16 x i16> %b, i32 7 430 %add78 = add i16 %vecext74, %vecext76 431 %vecinit80 = insertelement <16 x i16> %vecinit73, i16 %add78, i32 11 432 %vecext81 = extractelement <16 x i16> %b, i32 8 433 %vecext83 = extractelement <16 x i16> %b, i32 9 434 %add85 = add i16 %vecext81, %vecext83 435 %vecinit87 = insertelement <16 x i16> %vecinit80, i16 %add85, i32 12 436 %vecext88 = extractelement <16 x i16> %b, i32 10 437 %vecext90 = extractelement <16 x i16> %b, i32 11 438 %add92 = add i16 %vecext88, %vecext90 439 %vecinit94 = insertelement <16 x i16> %vecinit87, i16 %add92, i32 13 440 %vecext95 = extractelement <16 x i16> %b, i32 12 441 %vecext97 = extractelement <16 x i16> %b, i32 13 442 %add99 = add i16 %vecext95, %vecext97 443 %vecinit101 = insertelement <16 x i16> %vecinit94, i16 %add99, i32 14 444 %vecext102 = extractelement <16 x i16> %b, i32 14 445 %vecext104 = extractelement <16 x i16> %b, i32 15 446 %add106 = add i16 %vecext102, %vecext104 447 %vecinit108 = insertelement <16 x i16> %vecinit101, i16 %add106, i32 15 448 ret <16 x i16> %vecinit108 449} 450; CHECK-LABEL: avx2_vphadd_w_test 451; SSE3-NOT: phaddw 452; SSSE3: phaddw 453; SSSE3-NEXT: phaddw 454; AVX: vphaddw 455; AVX: vphaddw 456; AVX2: vphaddw 457; AVX2: vphaddw 458; CHECK: ret 459 460 461; Verify that we don't select horizontal subs in the following functions. 462 463define <4 x i32> @not_a_hsub_1(<4 x i32> %A, <4 x i32> %B) { 464 %vecext = extractelement <4 x i32> %A, i32 0 465 %vecext1 = extractelement <4 x i32> %A, i32 1 466 %sub = sub i32 %vecext, %vecext1 467 %vecinit = insertelement <4 x i32> undef, i32 %sub, i32 0 468 %vecext2 = extractelement <4 x i32> %A, i32 2 469 %vecext3 = extractelement <4 x i32> %A, i32 3 470 %sub4 = sub i32 %vecext2, %vecext3 471 %vecinit5 = insertelement <4 x i32> %vecinit, i32 %sub4, i32 1 472 %vecext6 = extractelement <4 x i32> %B, i32 1 473 %vecext7 = extractelement <4 x i32> %B, i32 0 474 %sub8 = sub i32 %vecext6, %vecext7 475 %vecinit9 = insertelement <4 x i32> %vecinit5, i32 %sub8, i32 2 476 %vecext10 = extractelement <4 x i32> %B, i32 3 477 %vecext11 = extractelement <4 x i32> %B, i32 2 478 %sub12 = sub i32 %vecext10, %vecext11 479 %vecinit13 = insertelement <4 x i32> %vecinit9, i32 %sub12, i32 3 480 ret <4 x i32> %vecinit13 481} 482; CHECK-LABEL: not_a_hsub_1 483; CHECK-NOT: phsubd 484; CHECK: ret 485 486 487define <4 x float> @not_a_hsub_2(<4 x float> %A, <4 x float> %B) { 488 %vecext = extractelement <4 x float> %A, i32 2 489 %vecext1 = extractelement <4 x float> %A, i32 3 490 %sub = fsub float %vecext, %vecext1 491 %vecinit = insertelement <4 x float> undef, float %sub, i32 1 492 %vecext2 = extractelement <4 x float> %A, i32 0 493 %vecext3 = extractelement <4 x float> %A, i32 1 494 %sub4 = fsub float %vecext2, %vecext3 495 %vecinit5 = insertelement <4 x float> %vecinit, float %sub4, i32 0 496 %vecext6 = extractelement <4 x float> %B, i32 3 497 %vecext7 = extractelement <4 x float> %B, i32 2 498 %sub8 = fsub float %vecext6, %vecext7 499 %vecinit9 = insertelement <4 x float> %vecinit5, float %sub8, i32 3 500 %vecext10 = extractelement <4 x float> %B, i32 0 501 %vecext11 = extractelement <4 x float> %B, i32 1 502 %sub12 = fsub float %vecext10, %vecext11 503 %vecinit13 = insertelement <4 x float> %vecinit9, float %sub12, i32 2 504 ret <4 x float> %vecinit13 505} 506; CHECK-LABEL: not_a_hsub_2 507; CHECK-NOT: hsubps 508; CHECK: ret 509 510 511define <2 x double> @not_a_hsub_3(<2 x double> %A, <2 x double> %B) { 512 %vecext = extractelement <2 x double> %B, i32 0 513 %vecext1 = extractelement <2 x double> %B, i32 1 514 %sub = fsub double %vecext, %vecext1 515 %vecinit = insertelement <2 x double> undef, double %sub, i32 1 516 %vecext2 = extractelement <2 x double> %A, i32 1 517 %vecext3 = extractelement <2 x double> %A, i32 0 518 %sub2 = fsub double %vecext2, %vecext3 519 %vecinit2 = insertelement <2 x double> %vecinit, double %sub2, i32 0 520 ret <2 x double> %vecinit2 521} 522; CHECK-LABEL: not_a_hsub_3 523; CHECK-NOT: hsubpd 524; CHECK: ret 525 526 527; Test AVX horizontal add/sub of packed single/double precision 528; floating point values from 256-bit vectors. 529 530define <8 x float> @avx_vhadd_ps(<8 x float> %a, <8 x float> %b) { 531 %vecext = extractelement <8 x float> %a, i32 0 532 %vecext1 = extractelement <8 x float> %a, i32 1 533 %add = fadd float %vecext, %vecext1 534 %vecinit = insertelement <8 x float> undef, float %add, i32 0 535 %vecext2 = extractelement <8 x float> %a, i32 2 536 %vecext3 = extractelement <8 x float> %a, i32 3 537 %add4 = fadd float %vecext2, %vecext3 538 %vecinit5 = insertelement <8 x float> %vecinit, float %add4, i32 1 539 %vecext6 = extractelement <8 x float> %b, i32 0 540 %vecext7 = extractelement <8 x float> %b, i32 1 541 %add8 = fadd float %vecext6, %vecext7 542 %vecinit9 = insertelement <8 x float> %vecinit5, float %add8, i32 2 543 %vecext10 = extractelement <8 x float> %b, i32 2 544 %vecext11 = extractelement <8 x float> %b, i32 3 545 %add12 = fadd float %vecext10, %vecext11 546 %vecinit13 = insertelement <8 x float> %vecinit9, float %add12, i32 3 547 %vecext14 = extractelement <8 x float> %a, i32 4 548 %vecext15 = extractelement <8 x float> %a, i32 5 549 %add16 = fadd float %vecext14, %vecext15 550 %vecinit17 = insertelement <8 x float> %vecinit13, float %add16, i32 4 551 %vecext18 = extractelement <8 x float> %a, i32 6 552 %vecext19 = extractelement <8 x float> %a, i32 7 553 %add20 = fadd float %vecext18, %vecext19 554 %vecinit21 = insertelement <8 x float> %vecinit17, float %add20, i32 5 555 %vecext22 = extractelement <8 x float> %b, i32 4 556 %vecext23 = extractelement <8 x float> %b, i32 5 557 %add24 = fadd float %vecext22, %vecext23 558 %vecinit25 = insertelement <8 x float> %vecinit21, float %add24, i32 6 559 %vecext26 = extractelement <8 x float> %b, i32 6 560 %vecext27 = extractelement <8 x float> %b, i32 7 561 %add28 = fadd float %vecext26, %vecext27 562 %vecinit29 = insertelement <8 x float> %vecinit25, float %add28, i32 7 563 ret <8 x float> %vecinit29 564} 565; CHECK-LABEL: avx_vhadd_ps 566; SSE3: haddps 567; SSE3-NEXT: haddps 568; SSSE3: haddps 569; SSSE3-NEXT: haddps 570; AVX: vhaddps 571; AVX2: vhaddps 572; CHECK: ret 573 574 575define <8 x float> @avx_vhsub_ps(<8 x float> %a, <8 x float> %b) { 576 %vecext = extractelement <8 x float> %a, i32 0 577 %vecext1 = extractelement <8 x float> %a, i32 1 578 %sub = fsub float %vecext, %vecext1 579 %vecinit = insertelement <8 x float> undef, float %sub, i32 0 580 %vecext2 = extractelement <8 x float> %a, i32 2 581 %vecext3 = extractelement <8 x float> %a, i32 3 582 %sub4 = fsub float %vecext2, %vecext3 583 %vecinit5 = insertelement <8 x float> %vecinit, float %sub4, i32 1 584 %vecext6 = extractelement <8 x float> %b, i32 0 585 %vecext7 = extractelement <8 x float> %b, i32 1 586 %sub8 = fsub float %vecext6, %vecext7 587 %vecinit9 = insertelement <8 x float> %vecinit5, float %sub8, i32 2 588 %vecext10 = extractelement <8 x float> %b, i32 2 589 %vecext11 = extractelement <8 x float> %b, i32 3 590 %sub12 = fsub float %vecext10, %vecext11 591 %vecinit13 = insertelement <8 x float> %vecinit9, float %sub12, i32 3 592 %vecext14 = extractelement <8 x float> %a, i32 4 593 %vecext15 = extractelement <8 x float> %a, i32 5 594 %sub16 = fsub float %vecext14, %vecext15 595 %vecinit17 = insertelement <8 x float> %vecinit13, float %sub16, i32 4 596 %vecext18 = extractelement <8 x float> %a, i32 6 597 %vecext19 = extractelement <8 x float> %a, i32 7 598 %sub20 = fsub float %vecext18, %vecext19 599 %vecinit21 = insertelement <8 x float> %vecinit17, float %sub20, i32 5 600 %vecext22 = extractelement <8 x float> %b, i32 4 601 %vecext23 = extractelement <8 x float> %b, i32 5 602 %sub24 = fsub float %vecext22, %vecext23 603 %vecinit25 = insertelement <8 x float> %vecinit21, float %sub24, i32 6 604 %vecext26 = extractelement <8 x float> %b, i32 6 605 %vecext27 = extractelement <8 x float> %b, i32 7 606 %sub28 = fsub float %vecext26, %vecext27 607 %vecinit29 = insertelement <8 x float> %vecinit25, float %sub28, i32 7 608 ret <8 x float> %vecinit29 609} 610; CHECK-LABEL: avx_vhsub_ps 611; SSE3: hsubps 612; SSE3-NEXT: hsubps 613; SSSE3: hsubps 614; SSSE3-NEXT: hsubps 615; AVX: vhsubps 616; AVX2: vhsubps 617; CHECK: ret 618 619 620define <4 x double> @avx_hadd_pd(<4 x double> %a, <4 x double> %b) { 621 %vecext = extractelement <4 x double> %a, i32 0 622 %vecext1 = extractelement <4 x double> %a, i32 1 623 %add = fadd double %vecext, %vecext1 624 %vecinit = insertelement <4 x double> undef, double %add, i32 0 625 %vecext2 = extractelement <4 x double> %b, i32 0 626 %vecext3 = extractelement <4 x double> %b, i32 1 627 %add4 = fadd double %vecext2, %vecext3 628 %vecinit5 = insertelement <4 x double> %vecinit, double %add4, i32 1 629 %vecext6 = extractelement <4 x double> %a, i32 2 630 %vecext7 = extractelement <4 x double> %a, i32 3 631 %add8 = fadd double %vecext6, %vecext7 632 %vecinit9 = insertelement <4 x double> %vecinit5, double %add8, i32 2 633 %vecext10 = extractelement <4 x double> %b, i32 2 634 %vecext11 = extractelement <4 x double> %b, i32 3 635 %add12 = fadd double %vecext10, %vecext11 636 %vecinit13 = insertelement <4 x double> %vecinit9, double %add12, i32 3 637 ret <4 x double> %vecinit13 638} 639; CHECK-LABEL: avx_hadd_pd 640; SSE3: haddpd 641; SSE3-NEXT: haddpd 642; SSSE3: haddpd 643; SSSE3-NEXT: haddpd 644; AVX: vhaddpd 645; AVX2: vhaddpd 646; CHECK: ret 647 648 649define <4 x double> @avx_hsub_pd(<4 x double> %a, <4 x double> %b) { 650 %vecext = extractelement <4 x double> %a, i32 0 651 %vecext1 = extractelement <4 x double> %a, i32 1 652 %sub = fsub double %vecext, %vecext1 653 %vecinit = insertelement <4 x double> undef, double %sub, i32 0 654 %vecext2 = extractelement <4 x double> %b, i32 0 655 %vecext3 = extractelement <4 x double> %b, i32 1 656 %sub4 = fsub double %vecext2, %vecext3 657 %vecinit5 = insertelement <4 x double> %vecinit, double %sub4, i32 1 658 %vecext6 = extractelement <4 x double> %a, i32 2 659 %vecext7 = extractelement <4 x double> %a, i32 3 660 %sub8 = fsub double %vecext6, %vecext7 661 %vecinit9 = insertelement <4 x double> %vecinit5, double %sub8, i32 2 662 %vecext10 = extractelement <4 x double> %b, i32 2 663 %vecext11 = extractelement <4 x double> %b, i32 3 664 %sub12 = fsub double %vecext10, %vecext11 665 %vecinit13 = insertelement <4 x double> %vecinit9, double %sub12, i32 3 666 ret <4 x double> %vecinit13 667} 668; CHECK-LABEL: avx_hsub_pd 669; SSE3: hsubpd 670; SSE3-NEXT: hsubpd 671; SSSE3: hsubpd 672; SSSE3-NEXT: hsubpd 673; AVX: vhsubpd 674; AVX2: vhsubpd 675; CHECK: ret 676 677 678; Test AVX2 horizontal add of packed integer values from 256-bit vectors. 679 680define <8 x i32> @avx2_hadd_d(<8 x i32> %a, <8 x i32> %b) { 681 %vecext = extractelement <8 x i32> %a, i32 0 682 %vecext1 = extractelement <8 x i32> %a, i32 1 683 %add = add i32 %vecext, %vecext1 684 %vecinit = insertelement <8 x i32> undef, i32 %add, i32 0 685 %vecext2 = extractelement <8 x i32> %a, i32 2 686 %vecext3 = extractelement <8 x i32> %a, i32 3 687 %add4 = add i32 %vecext2, %vecext3 688 %vecinit5 = insertelement <8 x i32> %vecinit, i32 %add4, i32 1 689 %vecext6 = extractelement <8 x i32> %b, i32 0 690 %vecext7 = extractelement <8 x i32> %b, i32 1 691 %add8 = add i32 %vecext6, %vecext7 692 %vecinit9 = insertelement <8 x i32> %vecinit5, i32 %add8, i32 2 693 %vecext10 = extractelement <8 x i32> %b, i32 2 694 %vecext11 = extractelement <8 x i32> %b, i32 3 695 %add12 = add i32 %vecext10, %vecext11 696 %vecinit13 = insertelement <8 x i32> %vecinit9, i32 %add12, i32 3 697 %vecext14 = extractelement <8 x i32> %a, i32 4 698 %vecext15 = extractelement <8 x i32> %a, i32 5 699 %add16 = add i32 %vecext14, %vecext15 700 %vecinit17 = insertelement <8 x i32> %vecinit13, i32 %add16, i32 4 701 %vecext18 = extractelement <8 x i32> %a, i32 6 702 %vecext19 = extractelement <8 x i32> %a, i32 7 703 %add20 = add i32 %vecext18, %vecext19 704 %vecinit21 = insertelement <8 x i32> %vecinit17, i32 %add20, i32 5 705 %vecext22 = extractelement <8 x i32> %b, i32 4 706 %vecext23 = extractelement <8 x i32> %b, i32 5 707 %add24 = add i32 %vecext22, %vecext23 708 %vecinit25 = insertelement <8 x i32> %vecinit21, i32 %add24, i32 6 709 %vecext26 = extractelement <8 x i32> %b, i32 6 710 %vecext27 = extractelement <8 x i32> %b, i32 7 711 %add28 = add i32 %vecext26, %vecext27 712 %vecinit29 = insertelement <8 x i32> %vecinit25, i32 %add28, i32 7 713 ret <8 x i32> %vecinit29 714} 715; CHECK-LABEL: avx2_hadd_d 716; SSE3-NOT: phaddd 717; SSSE3: phaddd 718; SSSE3-NEXT: phaddd 719; AVX: vphaddd 720; AVX: vphaddd 721; AVX2: vphaddd 722; AVX2-NOT: vphaddd 723; CHECK: ret 724 725 726define <16 x i16> @avx2_hadd_w(<16 x i16> %a, <16 x i16> %b) { 727 %vecext = extractelement <16 x i16> %a, i32 0 728 %vecext1 = extractelement <16 x i16> %a, i32 1 729 %add = add i16 %vecext, %vecext1 730 %vecinit = insertelement <16 x i16> undef, i16 %add, i32 0 731 %vecext4 = extractelement <16 x i16> %a, i32 2 732 %vecext6 = extractelement <16 x i16> %a, i32 3 733 %add8 = add i16 %vecext4, %vecext6 734 %vecinit10 = insertelement <16 x i16> %vecinit, i16 %add8, i32 1 735 %vecext11 = extractelement <16 x i16> %a, i32 4 736 %vecext13 = extractelement <16 x i16> %a, i32 5 737 %add15 = add i16 %vecext11, %vecext13 738 %vecinit17 = insertelement <16 x i16> %vecinit10, i16 %add15, i32 2 739 %vecext18 = extractelement <16 x i16> %a, i32 6 740 %vecext20 = extractelement <16 x i16> %a, i32 7 741 %add22 = add i16 %vecext18, %vecext20 742 %vecinit24 = insertelement <16 x i16> %vecinit17, i16 %add22, i32 3 743 %vecext25 = extractelement <16 x i16> %a, i32 8 744 %vecext27 = extractelement <16 x i16> %a, i32 9 745 %add29 = add i16 %vecext25, %vecext27 746 %vecinit31 = insertelement <16 x i16> %vecinit24, i16 %add29, i32 8 747 %vecext32 = extractelement <16 x i16> %a, i32 10 748 %vecext34 = extractelement <16 x i16> %a, i32 11 749 %add36 = add i16 %vecext32, %vecext34 750 %vecinit38 = insertelement <16 x i16> %vecinit31, i16 %add36, i32 9 751 %vecext39 = extractelement <16 x i16> %a, i32 12 752 %vecext41 = extractelement <16 x i16> %a, i32 13 753 %add43 = add i16 %vecext39, %vecext41 754 %vecinit45 = insertelement <16 x i16> %vecinit38, i16 %add43, i32 10 755 %vecext46 = extractelement <16 x i16> %a, i32 14 756 %vecext48 = extractelement <16 x i16> %a, i32 15 757 %add50 = add i16 %vecext46, %vecext48 758 %vecinit52 = insertelement <16 x i16> %vecinit45, i16 %add50, i32 11 759 %vecext53 = extractelement <16 x i16> %b, i32 0 760 %vecext55 = extractelement <16 x i16> %b, i32 1 761 %add57 = add i16 %vecext53, %vecext55 762 %vecinit59 = insertelement <16 x i16> %vecinit52, i16 %add57, i32 4 763 %vecext60 = extractelement <16 x i16> %b, i32 2 764 %vecext62 = extractelement <16 x i16> %b, i32 3 765 %add64 = add i16 %vecext60, %vecext62 766 %vecinit66 = insertelement <16 x i16> %vecinit59, i16 %add64, i32 5 767 %vecext67 = extractelement <16 x i16> %b, i32 4 768 %vecext69 = extractelement <16 x i16> %b, i32 5 769 %add71 = add i16 %vecext67, %vecext69 770 %vecinit73 = insertelement <16 x i16> %vecinit66, i16 %add71, i32 6 771 %vecext74 = extractelement <16 x i16> %b, i32 6 772 %vecext76 = extractelement <16 x i16> %b, i32 7 773 %add78 = add i16 %vecext74, %vecext76 774 %vecinit80 = insertelement <16 x i16> %vecinit73, i16 %add78, i32 7 775 %vecext81 = extractelement <16 x i16> %b, i32 8 776 %vecext83 = extractelement <16 x i16> %b, i32 9 777 %add85 = add i16 %vecext81, %vecext83 778 %vecinit87 = insertelement <16 x i16> %vecinit80, i16 %add85, i32 12 779 %vecext88 = extractelement <16 x i16> %b, i32 10 780 %vecext90 = extractelement <16 x i16> %b, i32 11 781 %add92 = add i16 %vecext88, %vecext90 782 %vecinit94 = insertelement <16 x i16> %vecinit87, i16 %add92, i32 13 783 %vecext95 = extractelement <16 x i16> %b, i32 12 784 %vecext97 = extractelement <16 x i16> %b, i32 13 785 %add99 = add i16 %vecext95, %vecext97 786 %vecinit101 = insertelement <16 x i16> %vecinit94, i16 %add99, i32 14 787 %vecext102 = extractelement <16 x i16> %b, i32 14 788 %vecext104 = extractelement <16 x i16> %b, i32 15 789 %add106 = add i16 %vecext102, %vecext104 790 %vecinit108 = insertelement <16 x i16> %vecinit101, i16 %add106, i32 15 791 ret <16 x i16> %vecinit108 792} 793; CHECK-LABEL: avx2_hadd_w 794; SSE3-NOT: phaddw 795; SSSE3: phaddw 796; SSSE3-NEXT: phaddw 797; AVX: vphaddw 798; AVX: vphaddw 799; AVX2: vphaddw 800; AVX2-NOT: vphaddw 801; CHECK: ret 802 803