[llvm] [X86] Remove lowerToAddSubOrFMAddSub vectorization lowering code (PR #211666)

Simon Pilgrim via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 24 00:12:52 PDT 2026


https://github.com/RKSimon updated https://github.com/llvm/llvm-project/pull/211666

>From 8653c8074438f30d9ef896a9f8b616f6db212cc1 Mon Sep 17 00:00:00 2001
From: Simon Pilgrim <llvm-dev at redking.me.uk>
Date: Thu, 23 Jul 2026 22:10:09 +0100
Subject: [PATCH] [X86] Remove lowerToAddSubOrFMAddSub vectorization lowering
 code

Similar to #207406 - the middleend (SLP/VectorCombine/InstCombine) should no longer generate any mixed "addsub" scalar buildvector patterns for the backend.

We can remove the lowerToAddSubOrFMAddSub build vector code path and rely on the combineShuffleToAddSubOrFMAddSub path.

The vector code created by SLP/VectorCombine isn't yet perfect (and I'm still working on improving it), but lowerToAddSubOrFMAddSub is unrelated and of no more use to us.

The CodeGen buildvector tests can be removed - equivalent test coverage is present in Transforms/PhaseOrdering/X86 that generate shuffle patterns that we test for in fmaddsub-combine.ll, fmsubadd-combine.ll and sse3-avx-addsub.ll (and sse3-avx-addsub-2.ll can be deleted).

Fixes #144489
---
 llvm/lib/Target/X86/X86ISelLowering.cpp    | 144 -----
 llvm/test/CodeGen/X86/fmaddsub-combine.ll  | 153 -----
 llvm/test/CodeGen/X86/fmsubadd-combine.ll  | 223 -------
 llvm/test/CodeGen/X86/sse3-avx-addsub-2.ll | 661 ---------------------
 4 files changed, 1181 deletions(-)
 delete mode 100644 llvm/test/CodeGen/X86/sse3-avx-addsub-2.ll

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index a766530a229be..a287904d19c08 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -8716,103 +8716,6 @@ static SDValue LowerBUILD_VECTORvXi1(SDValue Op, const SDLoc &dl,
   return false;
 }
 
-/// Returns true iff \p BV builds a vector with the result equivalent to
-/// the result of ADDSUB/SUBADD operation.
-/// If true is returned then the operands of ADDSUB = Opnd0 +- Opnd1
-/// (SUBADD = Opnd0 -+ Opnd1) operation are written to the parameters
-/// \p Opnd0 and \p Opnd1.
-static bool isAddSubOrSubAdd(const BuildVectorSDNode *BV,
-                             const X86Subtarget &Subtarget, SelectionDAG &DAG,
-                             SDValue &Opnd0, SDValue &Opnd1,
-                             unsigned &NumExtracts, bool &IsSubAdd,
-                             bool &HasAllowContract) {
-  using namespace SDPatternMatch;
-
-  MVT VT = BV->getSimpleValueType(0);
-  if (!Subtarget.hasSSE3() || !VT.isFloatingPoint())
-    return false;
-
-  unsigned NumElts = VT.getVectorNumElements();
-  SDValue InVec0 = DAG.getUNDEF(VT);
-  SDValue InVec1 = DAG.getUNDEF(VT);
-
-  NumExtracts = 0;
-  HasAllowContract = NumElts != 0;
-
-  // Odd-numbered elements in the input build vector are obtained from
-  // adding/subtracting two integer/float elements.
-  // Even-numbered elements in the input build vector are obtained from
-  // subtracting/adding two integer/float elements.
-  unsigned Opc[2] = {0, 0};
-  for (unsigned i = 0, e = NumElts; i != e; ++i) {
-    SDValue Op = BV->getOperand(i);
-
-    // Skip 'undef' values.
-    unsigned Opcode = Op.getOpcode();
-    if (Opcode == ISD::UNDEF)
-      continue;
-
-    // Early exit if we found an unexpected opcode.
-    if (Opcode != ISD::FADD && Opcode != ISD::FSUB)
-      return false;
-
-    SDValue Op0 = Op.getOperand(0);
-    SDValue Op1 = Op.getOperand(1);
-
-    // Try to match the following pattern:
-    // (BINOP (extract_vector_elt A, i), (extract_vector_elt B, i))
-    // Early exit if we cannot match that sequence.
-    if (!sd_match(Op0, m_ExtractElt(m_SpecificVT(VT), m_SpecificInt(i))) ||
-        !sd_match(Op1, m_ExtractElt(m_SpecificVT(VT), m_SpecificInt(i))))
-      return false;
-
-    // We found a valid add/sub node, make sure its the same opcode as previous
-    // elements for this parity.
-    if (Opc[i % 2] != 0 && Opc[i % 2] != Opcode)
-      return false;
-    Opc[i % 2] = Opcode;
-
-    // Update InVec0 and InVec1.
-    if (InVec0.isUndef())
-      InVec0 = Op0.getOperand(0);
-    if (InVec1.isUndef())
-      InVec1 = Op1.getOperand(0);
-
-    // Make sure that operands in input to each add/sub node always
-    // come from a same pair of vectors.
-    if (InVec0 != Op0.getOperand(0)) {
-      if (Opcode == ISD::FSUB)
-        return false;
-
-      // FADD is commutable. Try to commute the operands
-      // and then test again.
-      std::swap(Op0, Op1);
-      if (InVec0 != Op0.getOperand(0))
-        return false;
-    }
-
-    if (InVec1 != Op1.getOperand(0))
-      return false;
-
-    // Increment the number of extractions done.
-    ++NumExtracts;
-    HasAllowContract &= Op->getFlags().hasAllowContract();
-  }
-
-  // Ensure we have found an opcode for both parities and that they are
-  // different. Don't try to fold this build_vector into an ADDSUB/SUBADD if the
-  // inputs are undef.
-  if (!Opc[0] || !Opc[1] || Opc[0] == Opc[1] ||
-      InVec0.isUndef() || InVec1.isUndef())
-    return false;
-
-  IsSubAdd = Opc[0] == ISD::FADD;
-
-  Opnd0 = InVec0;
-  Opnd1 = InVec1;
-  return true;
-}
-
 /// Returns true if is possible to fold MUL and an idiom that has already been
 /// recognized as ADDSUB/SUBADD(\p Opnd0, \p Opnd1) into
 /// FMADDSUB/FMSUBADD(x, y, \p Opnd1). If (and only if) true is returned, the
@@ -8863,51 +8766,6 @@ static bool isFMAddSubOrFMSubAdd(const X86Subtarget &Subtarget, SDValue &Opnd0,
   return true;
 }
 
-/// Try to fold a build_vector that performs an 'addsub' or 'fmaddsub' or
-/// 'fsubadd' operation accordingly to X86ISD::ADDSUB or X86ISD::FMADDSUB or
-/// X86ISD::FMSUBADD node.
-static SDValue lowerToAddSubOrFMAddSub(const BuildVectorSDNode *BV,
-                                       const SDLoc &DL,
-                                       const X86Subtarget &Subtarget,
-                                       SelectionDAG &DAG) {
-  SDValue Opnd0, Opnd1;
-  unsigned NumExtracts;
-  bool IsSubAdd;
-  bool HasAllowContract;
-  if (!isAddSubOrSubAdd(BV, Subtarget, DAG, Opnd0, Opnd1, NumExtracts, IsSubAdd,
-                        HasAllowContract))
-    return SDValue();
-
-  MVT VT = BV->getSimpleValueType(0);
-
-  // Try to generate X86ISD::FMADDSUB node here.
-  SDValue Opnd2;
-  if (isFMAddSubOrFMSubAdd(Subtarget, Opnd0, Opnd1, Opnd2, NumExtracts,
-                           HasAllowContract)) {
-    unsigned Opc = IsSubAdd ? X86ISD::FMSUBADD : X86ISD::FMADDSUB;
-    return DAG.getNode(Opc, DL, VT, Opnd0, Opnd1, Opnd2);
-  }
-
-  // We only support ADDSUB.
-  if (IsSubAdd)
-    return SDValue();
-
-  // There are no known X86 targets with 512-bit ADDSUB instructions!
-  // Convert to blend(fsub,fadd).
-  if (VT.is512BitVector()) {
-    SmallVector<int> Mask;
-    for (int I = 0, E = VT.getVectorNumElements(); I != E; I += 2) {
-        Mask.push_back(I);
-        Mask.push_back(I + E + 1);
-    }
-    SDValue Sub = DAG.getNode(ISD::FSUB, DL, VT, Opnd0, Opnd1);
-    SDValue Add = DAG.getNode(ISD::FADD, DL, VT, Opnd0, Opnd1);
-    return DAG.getVectorShuffle(VT, DL, Sub, Add, Mask);
-  }
-
-  return DAG.getNode(X86ISD::ADDSUB, DL, VT, Opnd0, Opnd1);
-}
-
 static SDValue LowerShift(SDValue Op, const X86Subtarget &Subtarget,
                           SelectionDAG &DAG);
 
@@ -9563,8 +9421,6 @@ X86TargetLowering::LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const {
     }
   }
 
-  if (SDValue AddSub = lowerToAddSubOrFMAddSub(BV, dl, Subtarget, DAG))
-    return AddSub;
   if (SDValue Broadcast = lowerBuildVectorAsBroadcast(BV, dl, Subtarget, DAG))
     return Broadcast;
   if (SDValue BitOp = lowerBuildVectorToBitOp(BV, dl, Subtarget, DAG))
diff --git a/llvm/test/CodeGen/X86/fmaddsub-combine.ll b/llvm/test/CodeGen/X86/fmaddsub-combine.ll
index 54f69f19ff3a1..a5df3a0bbb74e 100644
--- a/llvm/test/CodeGen/X86/fmaddsub-combine.ll
+++ b/llvm/test/CodeGen/X86/fmaddsub-combine.ll
@@ -276,64 +276,6 @@ define <8 x double> @mul_addsub_pd512_partial_avx(<8 x double> %C, <8 x double>
   %vecinsert8 = shufflevector <8 x double> %vecinsert71, <8 x double> %foldExtExtBinop, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 15>
   ret <8 x double> %vecinsert8
 }
-define <8 x double> @buildvector_mul_addsub_pd512(<8 x double> %C, <8 x double> %D, <8 x double> %B) {
-; NOFMA-LABEL: buildvector_mul_addsub_pd512:
-; NOFMA:       # %bb.0: # %bb
-; NOFMA-NEXT:    vmulpd %ymm3, %ymm1, %ymm1
-; NOFMA-NEXT:    vmulpd %ymm2, %ymm0, %ymm0
-; NOFMA-NEXT:    vaddsubpd %ymm4, %ymm0, %ymm0
-; NOFMA-NEXT:    vaddsubpd %ymm5, %ymm1, %ymm1
-; NOFMA-NEXT:    retq
-;
-; FMA3_256-LABEL: buildvector_mul_addsub_pd512:
-; FMA3_256:       # %bb.0: # %bb
-; FMA3_256-NEXT:    vfmaddsub213pd {{.*#+}} ymm0 = (ymm2 * ymm0) +/- ymm4
-; FMA3_256-NEXT:    vfmaddsub213pd {{.*#+}} ymm1 = (ymm3 * ymm1) +/- ymm5
-; FMA3_256-NEXT:    retq
-;
-; FMA3_512-LABEL: buildvector_mul_addsub_pd512:
-; FMA3_512:       # %bb.0: # %bb
-; FMA3_512-NEXT:    vfmaddsub213pd {{.*#+}} zmm0 = (zmm1 * zmm0) +/- zmm2
-; FMA3_512-NEXT:    retq
-;
-; FMA4-LABEL: buildvector_mul_addsub_pd512:
-; FMA4:       # %bb.0: # %bb
-; FMA4-NEXT:    vfmaddsubpd {{.*#+}} ymm0 = (ymm0 * ymm2) +/- ymm4
-; FMA4-NEXT:    vfmaddsubpd {{.*#+}} ymm1 = (ymm1 * ymm3) +/- ymm5
-; FMA4-NEXT:    retq
-bb:
-  %A = fmul contract <8 x double> %C, %D
-  %A0 = extractelement <8 x double> %A, i32 0
-  %B0 = extractelement <8 x double> %B, i32 0
-  %sub0 = fsub contract double %A0, %B0
-  %A2 = extractelement <8 x double> %A, i32 2
-  %B2 = extractelement <8 x double> %B, i32 2
-  %sub2 = fsub contract double %A2, %B2
-  %A4 = extractelement <8 x double> %A, i32 4
-  %B4 = extractelement <8 x double> %B, i32 4
-  %sub4 = fsub contract double %A4, %B4
-  %A6 = extractelement <8 x double> %A, i32 6
-  %B6 = extractelement <8 x double> %B, i32 6
-  %sub6 = fsub contract double %A6, %B6
-  %A1 = extractelement <8 x double> %A, i32 1
-  %B1 = extractelement <8 x double> %B, i32 1
-  %add1 = fadd contract double %A1, %B1
-  %A3 = extractelement <8 x double> %A, i32 3
-  %B3 = extractelement <8 x double> %B, i32 3
-  %add3 = fadd contract double %A3, %B3
-  %A7 = extractelement <8 x double> %A, i32 7
-  %B7 = extractelement <8 x double> %B, i32 7
-  %add7 = fadd contract double %A7, %B7
-  %vecinsert1 = insertelement <8 x double> undef, double %sub0, i32 0
-  %vecinsert2 = insertelement <8 x double> %vecinsert1, double %add1, i32 1
-  %vecinsert3 = insertelement <8 x double> %vecinsert2, double %sub2, i32 2
-  %vecinsert4 = insertelement <8 x double> %vecinsert3, double %add3, i32 3
-  %vecinsert5 = insertelement <8 x double> %vecinsert4, double %sub4, i32 4
-  ; element 5 is undef
-  %vecinsert7 = insertelement <8 x double> %vecinsert5, double %sub6, i32 6
-  %vecinsert8 = insertelement <8 x double> %vecinsert7, double %add7, i32 7
-  ret <8 x double> %vecinsert8
-}
 
 define <16 x float> @mul_addsub_ps512(<16 x float> %A, <16 x float> %B, <16 x float> %C) {
 ; NOFMA-LABEL: mul_addsub_ps512:
@@ -686,98 +628,3 @@ define <16 x float> @mul_addsub_ps512_partial_avx(<16 x float> %C, <16 x float>
   %vecinsert162 = shufflevector <16 x float> %vecinsert141, <16 x float> %i15, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 16, i32 17>
   ret <16 x float> %vecinsert162
 }
-
-define <16 x float> @buildvector_mul_addsub_ps512(<16 x float> %C, <16 x float> %D, <16 x float> %B) {
-; NOFMA-LABEL: buildvector_mul_addsub_ps512:
-; NOFMA:       # %bb.0: # %bb
-; NOFMA-NEXT:    vmulps %ymm3, %ymm1, %ymm1
-; NOFMA-NEXT:    vmulps %ymm2, %ymm0, %ymm0
-; NOFMA-NEXT:    vaddsubps %ymm4, %ymm0, %ymm0
-; NOFMA-NEXT:    vaddsubps %ymm5, %ymm1, %ymm1
-; NOFMA-NEXT:    retq
-;
-; FMA3_256-LABEL: buildvector_mul_addsub_ps512:
-; FMA3_256:       # %bb.0: # %bb
-; FMA3_256-NEXT:    vfmaddsub213ps {{.*#+}} ymm0 = (ymm2 * ymm0) +/- ymm4
-; FMA3_256-NEXT:    vfmaddsub213ps {{.*#+}} ymm1 = (ymm3 * ymm1) +/- ymm5
-; FMA3_256-NEXT:    retq
-;
-; FMA3_512-LABEL: buildvector_mul_addsub_ps512:
-; FMA3_512:       # %bb.0: # %bb
-; FMA3_512-NEXT:    vfmaddsub213ps {{.*#+}} zmm0 = (zmm1 * zmm0) +/- zmm2
-; FMA3_512-NEXT:    retq
-;
-; FMA4-LABEL: buildvector_mul_addsub_ps512:
-; FMA4:       # %bb.0: # %bb
-; FMA4-NEXT:    vfmaddsubps {{.*#+}} ymm0 = (ymm0 * ymm2) +/- ymm4
-; FMA4-NEXT:    vfmaddsubps {{.*#+}} ymm1 = (ymm1 * ymm3) +/- ymm5
-; FMA4-NEXT:    retq
-bb:
-  %A = fmul contract <16 x float> %C, %D
-  %A0 = extractelement <16 x float> %A, i32 0
-  %B0 = extractelement <16 x float> %B, i32 0
-  %sub0 = fsub contract float %A0, %B0
-  %A2 = extractelement <16 x float> %A, i32 2
-  %B2 = extractelement <16 x float> %B, i32 2
-  %sub2 = fsub contract float %A2, %B2
-  %A4 = extractelement <16 x float> %A, i32 4
-  %B4 = extractelement <16 x float> %B, i32 4
-  %sub4 = fsub contract float %A4, %B4
-  %A6 = extractelement <16 x float> %A, i32 6
-  %B6 = extractelement <16 x float> %B, i32 6
-  %sub6 = fsub contract float %A6, %B6
-  %A8 = extractelement <16 x float> %A, i32 8
-  %B8 = extractelement <16 x float> %B, i32 8
-  %sub8 = fsub contract float %A8, %B8
-  %A10 = extractelement <16 x float> %A, i32 10
-  %B10 = extractelement <16 x float> %B, i32 10
-  %sub10 = fsub contract float %A10, %B10
-  %A12 = extractelement <16 x float> %A, i32 12
-  %B12 = extractelement <16 x float> %B, i32 12
-  %sub12 = fsub contract float %A12, %B12
-  %A14 = extractelement <16 x float> %A, i32 14
-  %B14 = extractelement <16 x float> %B, i32 14
-  %sub14 = fsub contract float %A14, %B14
-  %A1 = extractelement <16 x float> %A, i32 1
-  %B1 = extractelement <16 x float> %B, i32 1
-  %add1 = fadd contract float %A1, %B1
-  %A3 = extractelement <16 x float> %A, i32 3
-  %B3 = extractelement <16 x float> %B, i32 3
-  %add3 = fadd contract float %A3, %B3
-  %A5 = extractelement <16 x float> %A, i32 5
-  %B5 = extractelement <16 x float> %B, i32 5
-  %add5 = fadd contract float %A5, %B5
-  %A7 = extractelement <16 x float> %A, i32 7
-  %B7 = extractelement <16 x float> %B, i32 7
-  %add7 = fadd contract float %A7, %B7
-  %A9 = extractelement <16 x float> %A, i32 9
-  %B9 = extractelement <16 x float> %B, i32 9
-  %add9 = fadd contract float %A9, %B9
-  %A11 = extractelement <16 x float> %A, i32 11
-  %B11 = extractelement <16 x float> %B, i32 11
-  %add11 = fadd contract float %A11, %B11
-  %A13 = extractelement <16 x float> %A, i32 13
-  %B13 = extractelement <16 x float> %B, i32 13
-  %add13 = fadd contract float %A13, %B13
-  %A15 = extractelement <16 x float> %A, i32 15
-  %B15 = extractelement <16 x float> %B, i32 15
-  %add15 = fadd contract float %A15, %B15
-  %vecinsert1 = insertelement <16 x float> undef, float %sub0, i32 0
-  %vecinsert2 = insertelement <16 x float> %vecinsert1, float %add1, i32 1
-  %vecinsert3 = insertelement <16 x float> %vecinsert2, float %sub2, i32 2
-  %vecinsert4 = insertelement <16 x float> %vecinsert3, float %add3, i32 3
-  %vecinsert5 = insertelement <16 x float> %vecinsert4, float %sub4, i32 4
-  ; element 5 is undef
-  %vecinsert7 = insertelement <16 x float> %vecinsert5, float %sub6, i32 6
-  %vecinsert8 = insertelement <16 x float> %vecinsert7, float %add7, i32 7
-  %vecinsert9 = insertelement <16 x float> %vecinsert8, float %sub8, i32 8
-  %vecinsert10 = insertelement <16 x float> %vecinsert9, float %add9, i32 9
-  %vecinsert11 = insertelement <16 x float> %vecinsert10, float %sub10, i32 10
-  %vecinsert12 = insertelement <16 x float> %vecinsert11, float %add11, i32 11
-  ; element 12 is undef
-  %vecinsert14 = insertelement <16 x float> %vecinsert12, float %add13, i32 13
-  %vecinsert15 = insertelement <16 x float> %vecinsert14, float %sub14, i32 14
-  %vecinsert16 = insertelement <16 x float> %vecinsert15, float %add15, i32 15
-  ret <16 x float> %vecinsert16
-}
-
diff --git a/llvm/test/CodeGen/X86/fmsubadd-combine.ll b/llvm/test/CodeGen/X86/fmsubadd-combine.ll
index 76847ca449380..8561a6b023c0e 100644
--- a/llvm/test/CodeGen/X86/fmsubadd-combine.ll
+++ b/llvm/test/CodeGen/X86/fmsubadd-combine.ll
@@ -290,85 +290,6 @@ define <8 x double> @mul_subadd_pd512_partial_avx(<8 x double> %C, <8 x double>
   ret <8 x double> %vecinsert8
 }
 
-define <8 x double> @buildvector_mul_subadd_pd512(<8 x double> %C, <8 x double> %D, <8 x double> %B) {
-; NOFMA-LABEL: buildvector_mul_subadd_pd512:
-; NOFMA:       # %bb.0: # %bb
-; NOFMA-NEXT:    vmulpd %ymm3, %ymm1, %ymm1
-; NOFMA-NEXT:    vmulpd %ymm2, %ymm0, %ymm0
-; NOFMA-NEXT:    vaddsd %xmm4, %xmm0, %xmm2
-; NOFMA-NEXT:    vextractf128 $1, %ymm0, %xmm3
-; NOFMA-NEXT:    vextractf128 $1, %ymm4, %xmm6
-; NOFMA-NEXT:    vaddsd %xmm6, %xmm3, %xmm7
-; NOFMA-NEXT:    vaddsd %xmm5, %xmm1, %xmm8
-; NOFMA-NEXT:    vextractf128 $1, %ymm1, %xmm1
-; NOFMA-NEXT:    vextractf128 $1, %ymm5, %xmm5
-; NOFMA-NEXT:    vaddsd %xmm5, %xmm1, %xmm9
-; NOFMA-NEXT:    vshufpd {{.*#+}} xmm0 = xmm0[1,0]
-; NOFMA-NEXT:    vshufpd {{.*#+}} xmm4 = xmm4[1,0]
-; NOFMA-NEXT:    vsubsd %xmm4, %xmm0, %xmm0
-; NOFMA-NEXT:    vunpcklpd {{.*#+}} xmm0 = xmm2[0],xmm0[0]
-; NOFMA-NEXT:    vshufpd {{.*#+}} xmm2 = xmm3[1,0]
-; NOFMA-NEXT:    vshufpd {{.*#+}} xmm3 = xmm6[1,0]
-; NOFMA-NEXT:    vsubsd %xmm3, %xmm2, %xmm2
-; NOFMA-NEXT:    vunpcklpd {{.*#+}} xmm2 = xmm7[0],xmm2[0]
-; NOFMA-NEXT:    vshufpd {{.*#+}} xmm1 = xmm1[1,0]
-; NOFMA-NEXT:    vshufpd {{.*#+}} xmm3 = xmm5[1,0]
-; NOFMA-NEXT:    vsubsd %xmm3, %xmm1, %xmm1
-; NOFMA-NEXT:    vunpcklpd {{.*#+}} xmm1 = xmm9[0],xmm1[0]
-; NOFMA-NEXT:    vinsertf128 $1, %xmm2, %ymm0, %ymm0
-; NOFMA-NEXT:    vinsertf128 $1, %xmm1, %ymm8, %ymm1
-; NOFMA-NEXT:    retq
-;
-; FMA3_256-LABEL: buildvector_mul_subadd_pd512:
-; FMA3_256:       # %bb.0: # %bb
-; FMA3_256-NEXT:    vfmsubadd213pd {{.*#+}} ymm0 = (ymm2 * ymm0) -/+ ymm4
-; FMA3_256-NEXT:    vfmsubadd213pd {{.*#+}} ymm1 = (ymm3 * ymm1) -/+ ymm5
-; FMA3_256-NEXT:    retq
-;
-; FMA3_512-LABEL: buildvector_mul_subadd_pd512:
-; FMA3_512:       # %bb.0: # %bb
-; FMA3_512-NEXT:    vfmsubadd213pd {{.*#+}} zmm0 = (zmm1 * zmm0) -/+ zmm2
-; FMA3_512-NEXT:    retq
-;
-; FMA4-LABEL: buildvector_mul_subadd_pd512:
-; FMA4:       # %bb.0: # %bb
-; FMA4-NEXT:    vfmsubaddpd {{.*#+}} ymm0 = (ymm0 * ymm2) -/+ ymm4
-; FMA4-NEXT:    vfmsubaddpd {{.*#+}} ymm1 = (ymm1 * ymm3) -/+ ymm5
-; FMA4-NEXT:    retq
-bb:
-  %A = fmul contract <8 x double> %C, %D
-  %A0 = extractelement <8 x double> %A, i32 0
-  %B0 = extractelement <8 x double> %B, i32 0
-  %sub0 = fadd contract double %A0, %B0
-  %A2 = extractelement <8 x double> %A, i32 2
-  %B2 = extractelement <8 x double> %B, i32 2
-  %sub2 = fadd contract double %A2, %B2
-  %A4 = extractelement <8 x double> %A, i32 4
-  %B4 = extractelement <8 x double> %B, i32 4
-  %sub4 = fadd contract double %A4, %B4
-  %A6 = extractelement <8 x double> %A, i32 6
-  %B6 = extractelement <8 x double> %B, i32 6
-  %sub6 = fadd contract double %A6, %B6
-  %A1 = extractelement <8 x double> %A, i32 1
-  %B1 = extractelement <8 x double> %B, i32 1
-  %add1 = fsub contract double %A1, %B1
-  %A3 = extractelement <8 x double> %A, i32 3
-  %B3 = extractelement <8 x double> %B, i32 3
-  %add3 = fsub contract double %A3, %B3
-  %A7 = extractelement <8 x double> %A, i32 7
-  %B7 = extractelement <8 x double> %B, i32 7
-  %add7 = fsub contract double %A7, %B7
-  %vecinsert1 = insertelement <8 x double> undef, double %sub0, i32 0
-  %vecinsert2 = insertelement <8 x double> %vecinsert1, double %add1, i32 1
-  %vecinsert3 = insertelement <8 x double> %vecinsert2, double %sub2, i32 2
-  %vecinsert4 = insertelement <8 x double> %vecinsert3, double %add3, i32 3
-  %vecinsert5 = insertelement <8 x double> %vecinsert4, double %sub4, i32 4
-  ; element 5 is undef
-  %vecinsert7 = insertelement <8 x double> %vecinsert5, double %sub6, i32 6
-  %vecinsert8 = insertelement <8 x double> %vecinsert7, double %add7, i32 7
-  ret <8 x double> %vecinsert8
-}
-
 define <16 x float> @mul_subadd_ps512(<16 x float> %A, <16 x float> %B, <16 x float> %C) {
 ; NOFMA-LABEL: mul_subadd_ps512:
 ; NOFMA:       # %bb.0: # %entry
@@ -735,150 +656,6 @@ define <16 x float> @mul_subadd_ps512_partial_avx(<16 x float> %C, <16 x float>
   ret <16 x float> %vecinsert162
 }
 
-define <16 x float> @buildvector_mul_subadd_ps512(<16 x float> %C, <16 x float> %D, <16 x float> %B) {
-; NOFMA-LABEL: buildvector_mul_subadd_ps512:
-; NOFMA:       # %bb.0: # %bb
-; NOFMA-NEXT:    vmulps %ymm3, %ymm1, %ymm1
-; NOFMA-NEXT:    vmulps %ymm2, %ymm0, %ymm0
-; NOFMA-NEXT:    vaddss %xmm4, %xmm0, %xmm2
-; NOFMA-NEXT:    vshufpd {{.*#+}} xmm3 = xmm0[1,0]
-; NOFMA-NEXT:    vshufpd {{.*#+}} xmm6 = xmm4[1,0]
-; NOFMA-NEXT:    vaddss %xmm6, %xmm3, %xmm3
-; NOFMA-NEXT:    vextractf128 $1, %ymm0, %xmm6
-; NOFMA-NEXT:    vextractf128 $1, %ymm4, %xmm7
-; NOFMA-NEXT:    vaddss %xmm7, %xmm6, %xmm8
-; NOFMA-NEXT:    vshufpd {{.*#+}} xmm9 = xmm6[1,0]
-; NOFMA-NEXT:    vshufpd {{.*#+}} xmm10 = xmm7[1,0]
-; NOFMA-NEXT:    vaddss %xmm10, %xmm9, %xmm9
-; NOFMA-NEXT:    vinsertps {{.*#+}} xmm8 = xmm8[0,1],xmm9[0],xmm8[3]
-; NOFMA-NEXT:    vaddss %xmm5, %xmm1, %xmm9
-; NOFMA-NEXT:    vshufpd {{.*#+}} xmm10 = xmm1[1,0]
-; NOFMA-NEXT:    vshufpd {{.*#+}} xmm11 = xmm5[1,0]
-; NOFMA-NEXT:    vaddss %xmm11, %xmm10, %xmm10
-; NOFMA-NEXT:    vextractf128 $1, %ymm1, %xmm11
-; NOFMA-NEXT:    vshufpd {{.*#+}} xmm12 = xmm11[1,0]
-; NOFMA-NEXT:    vextractf128 $1, %ymm5, %xmm13
-; NOFMA-NEXT:    vshufpd {{.*#+}} xmm14 = xmm13[1,0]
-; NOFMA-NEXT:    vaddss %xmm14, %xmm12, %xmm12
-; NOFMA-NEXT:    vmovshdup {{.*#+}} xmm14 = xmm0[1,1,3,3]
-; NOFMA-NEXT:    vmovshdup {{.*#+}} xmm15 = xmm4[1,1,3,3]
-; NOFMA-NEXT:    vsubss %xmm15, %xmm14, %xmm14
-; NOFMA-NEXT:    vinsertps {{.*#+}} xmm2 = xmm2[0],xmm14[0],xmm2[2,3]
-; NOFMA-NEXT:    vinsertps {{.*#+}} xmm2 = xmm2[0,1],xmm3[0],xmm2[3]
-; NOFMA-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[3,3,3,3]
-; NOFMA-NEXT:    vshufps {{.*#+}} xmm3 = xmm4[3,3,3,3]
-; NOFMA-NEXT:    vsubss %xmm3, %xmm0, %xmm0
-; NOFMA-NEXT:    vinsertps {{.*#+}} xmm0 = xmm2[0,1,2],xmm0[0]
-; NOFMA-NEXT:    vshufps {{.*#+}} xmm2 = xmm6[3,3,3,3]
-; NOFMA-NEXT:    vshufps {{.*#+}} xmm3 = xmm7[3,3,3,3]
-; NOFMA-NEXT:    vsubss %xmm3, %xmm2, %xmm2
-; NOFMA-NEXT:    vinsertps {{.*#+}} xmm2 = xmm8[0,1,2],xmm2[0]
-; NOFMA-NEXT:    vmovshdup {{.*#+}} xmm3 = xmm1[1,1,3,3]
-; NOFMA-NEXT:    vmovshdup {{.*#+}} xmm4 = xmm5[1,1,3,3]
-; NOFMA-NEXT:    vsubss %xmm4, %xmm3, %xmm3
-; NOFMA-NEXT:    vinsertps {{.*#+}} xmm3 = xmm9[0],xmm3[0],xmm9[2,3]
-; NOFMA-NEXT:    vinsertps {{.*#+}} xmm3 = xmm3[0,1],xmm10[0],xmm3[3]
-; NOFMA-NEXT:    vshufps {{.*#+}} xmm1 = xmm1[3,3,3,3]
-; NOFMA-NEXT:    vshufps {{.*#+}} xmm4 = xmm5[3,3,3,3]
-; NOFMA-NEXT:    vsubss %xmm4, %xmm1, %xmm1
-; NOFMA-NEXT:    vinsertps {{.*#+}} xmm1 = xmm3[0,1,2],xmm1[0]
-; NOFMA-NEXT:    vmovshdup {{.*#+}} xmm3 = xmm11[1,1,3,3]
-; NOFMA-NEXT:    vmovshdup {{.*#+}} xmm4 = xmm13[1,1,3,3]
-; NOFMA-NEXT:    vsubss %xmm4, %xmm3, %xmm3
-; NOFMA-NEXT:    vshufps {{.*#+}} xmm3 = xmm3[0,0],xmm12[0,0]
-; NOFMA-NEXT:    vshufps {{.*#+}} xmm4 = xmm11[3,3,3,3]
-; NOFMA-NEXT:    vshufps {{.*#+}} xmm5 = xmm13[3,3,3,3]
-; NOFMA-NEXT:    vsubss %xmm5, %xmm4, %xmm4
-; NOFMA-NEXT:    vinsertps {{.*#+}} xmm3 = xmm3[0,1,2],xmm4[0]
-; NOFMA-NEXT:    vinsertf128 $1, %xmm2, %ymm0, %ymm0
-; NOFMA-NEXT:    vinsertf128 $1, %xmm3, %ymm1, %ymm1
-; NOFMA-NEXT:    retq
-;
-; FMA3_256-LABEL: buildvector_mul_subadd_ps512:
-; FMA3_256:       # %bb.0: # %bb
-; FMA3_256-NEXT:    vfmsubadd213ps {{.*#+}} ymm0 = (ymm2 * ymm0) -/+ ymm4
-; FMA3_256-NEXT:    vfmsubadd213ps {{.*#+}} ymm1 = (ymm3 * ymm1) -/+ ymm5
-; FMA3_256-NEXT:    retq
-;
-; FMA3_512-LABEL: buildvector_mul_subadd_ps512:
-; FMA3_512:       # %bb.0: # %bb
-; FMA3_512-NEXT:    vfmsubadd213ps {{.*#+}} zmm0 = (zmm1 * zmm0) -/+ zmm2
-; FMA3_512-NEXT:    retq
-;
-; FMA4-LABEL: buildvector_mul_subadd_ps512:
-; FMA4:       # %bb.0: # %bb
-; FMA4-NEXT:    vfmsubaddps {{.*#+}} ymm0 = (ymm0 * ymm2) -/+ ymm4
-; FMA4-NEXT:    vfmsubaddps {{.*#+}} ymm1 = (ymm1 * ymm3) -/+ ymm5
-; FMA4-NEXT:    retq
-bb:
-  %A = fmul contract <16 x float> %C, %D
-  %A0 = extractelement <16 x float> %A, i32 0
-  %B0 = extractelement <16 x float> %B, i32 0
-  %sub0 = fadd contract float %A0, %B0
-  %A2 = extractelement <16 x float> %A, i32 2
-  %B2 = extractelement <16 x float> %B, i32 2
-  %sub2 = fadd contract float %A2, %B2
-  %A4 = extractelement <16 x float> %A, i32 4
-  %B4 = extractelement <16 x float> %B, i32 4
-  %sub4 = fadd contract float %A4, %B4
-  %A6 = extractelement <16 x float> %A, i32 6
-  %B6 = extractelement <16 x float> %B, i32 6
-  %sub6 = fadd contract float %A6, %B6
-  %A8 = extractelement <16 x float> %A, i32 8
-  %B8 = extractelement <16 x float> %B, i32 8
-  %sub8 = fadd contract float %A8, %B8
-  %A10 = extractelement <16 x float> %A, i32 10
-  %B10 = extractelement <16 x float> %B, i32 10
-  %sub10 = fadd contract float %A10, %B10
-  %A12 = extractelement <16 x float> %A, i32 12
-  %B12 = extractelement <16 x float> %B, i32 12
-  %sub12 = fadd contract float %A12, %B12
-  %A14 = extractelement <16 x float> %A, i32 14
-  %B14 = extractelement <16 x float> %B, i32 14
-  %sub14 = fadd contract float %A14, %B14
-  %A1 = extractelement <16 x float> %A, i32 1
-  %B1 = extractelement <16 x float> %B, i32 1
-  %add1 = fsub contract float %A1, %B1
-  %A3 = extractelement <16 x float> %A, i32 3
-  %B3 = extractelement <16 x float> %B, i32 3
-  %add3 = fsub contract float %A3, %B3
-  %A5 = extractelement <16 x float> %A, i32 5
-  %B5 = extractelement <16 x float> %B, i32 5
-  %add5 = fsub contract float %A5, %B5
-  %A7 = extractelement <16 x float> %A, i32 7
-  %B7 = extractelement <16 x float> %B, i32 7
-  %add7 = fsub contract float %A7, %B7
-  %A9 = extractelement <16 x float> %A, i32 9
-  %B9 = extractelement <16 x float> %B, i32 9
-  %add9 = fsub contract float %A9, %B9
-  %A11 = extractelement <16 x float> %A, i32 11
-  %B11 = extractelement <16 x float> %B, i32 11
-  %add11 = fsub contract float %A11, %B11
-  %A13 = extractelement <16 x float> %A, i32 13
-  %B13 = extractelement <16 x float> %B, i32 13
-  %add13 = fsub contract float %A13, %B13
-  %A15 = extractelement <16 x float> %A, i32 15
-  %B15 = extractelement <16 x float> %B, i32 15
-  %add15 = fsub contract float %A15, %B15
-  %vecinsert1 = insertelement <16 x float> undef, float %sub0, i32 0
-  %vecinsert2 = insertelement <16 x float> %vecinsert1, float %add1, i32 1
-  %vecinsert3 = insertelement <16 x float> %vecinsert2, float %sub2, i32 2
-  %vecinsert4 = insertelement <16 x float> %vecinsert3, float %add3, i32 3
-  %vecinsert5 = insertelement <16 x float> %vecinsert4, float %sub4, i32 4
-  ; element 5 is undef
-  %vecinsert7 = insertelement <16 x float> %vecinsert5, float %sub6, i32 6
-  %vecinsert8 = insertelement <16 x float> %vecinsert7, float %add7, i32 7
-  %vecinsert9 = insertelement <16 x float> %vecinsert8, float %sub8, i32 8
-  %vecinsert10 = insertelement <16 x float> %vecinsert9, float %add9, i32 9
-  %vecinsert11 = insertelement <16 x float> %vecinsert10, float %sub10, i32 10
-  %vecinsert12 = insertelement <16 x float> %vecinsert11, float %add11, i32 11
-  ; element 12 is undef
-  %vecinsert14 = insertelement <16 x float> %vecinsert12, float %add13, i32 13
-  %vecinsert15 = insertelement <16 x float> %vecinsert14, float %sub14, i32 14
-  %vecinsert16 = insertelement <16 x float> %vecinsert15, float %add15, i32 15
-  ret <16 x float> %vecinsert16
-}
-
 ; This should not be matched to fmsubadd because the mul is on the wrong side of the fsub.
 define <2 x double> @mul_subadd_bad_commute(<2 x double> %A, <2 x double> %B, <2 x double> %C) {
 ; CHECK-LABEL: mul_subadd_bad_commute:
diff --git a/llvm/test/CodeGen/X86/sse3-avx-addsub-2.ll b/llvm/test/CodeGen/X86/sse3-avx-addsub-2.ll
deleted file mode 100644
index 1b92331f9ea61..0000000000000
--- a/llvm/test/CodeGen/X86/sse3-avx-addsub-2.ll
+++ /dev/null
@@ -1,661 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
-; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mattr=+sse3 | FileCheck %s --check-prefix=SSE
-; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mattr=+avx | FileCheck %s --check-prefix=AVX --check-prefix=AVX1
-; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mattr=+avx512f | FileCheck %s --check-prefix=AVX --check-prefix=AVX512
-
-; Verify that we correctly generate 'addsub' instructions from
-; a sequence of vector extracts + float add/sub + vector inserts.
-
-define <4 x float> @test_addsub_v4f32(<4 x float> %A, <4 x float> %B) {
-; SSE-LABEL: test_addsub_v4f32:
-; SSE:       # %bb.0:
-; SSE-NEXT:    addsubps %xmm1, %xmm0
-; SSE-NEXT:    retq
-;
-; AVX-LABEL: test_addsub_v4f32:
-; AVX:       # %bb.0:
-; AVX-NEXT:    vaddsubps %xmm1, %xmm0, %xmm0
-; AVX-NEXT:    retq
-  %1 = extractelement <4 x float> %A, i32 0
-  %2 = extractelement <4 x float> %B, i32 0
-  %sub = fsub float %1, %2
-  %3 = extractelement <4 x float> %A, i32 2
-  %4 = extractelement <4 x float> %B, i32 2
-  %sub2 = fsub float %3, %4
-  %5 = extractelement <4 x float> %A, i32 1
-  %6 = extractelement <4 x float> %B, i32 1
-  %add = fadd float %5, %6
-  %7 = extractelement <4 x float> %A, i32 3
-  %8 = extractelement <4 x float> %B, i32 3
-  %add2 = fadd float %7, %8
-  %vecinsert1 = insertelement <4 x float> undef, float %add, i32 1
-  %vecinsert2 = insertelement <4 x float> %vecinsert1, float %add2, i32 3
-  %vecinsert3 = insertelement <4 x float> %vecinsert2, float %sub, i32 0
-  %vecinsert4 = insertelement <4 x float> %vecinsert3, float %sub2, i32 2
-  ret <4 x float> %vecinsert4
-}
-
-define <4 x float> @test_addsub_v4f32_partial_23(<4 x float> %A, <4 x float> %B) {
-; SSE-LABEL: test_addsub_v4f32_partial_23:
-; SSE:       # %bb.0:
-; SSE-NEXT:    addsubps %xmm1, %xmm0
-; SSE-NEXT:    retq
-;
-; AVX-LABEL: test_addsub_v4f32_partial_23:
-; AVX:       # %bb.0:
-; AVX-NEXT:    vaddsubps %xmm1, %xmm0, %xmm0
-; AVX-NEXT:    retq
-  %1 = extractelement <4 x float> %A, i32 2
-  %2 = extractelement <4 x float> %B, i32 2
-  %sub2 = fsub float %1, %2
-  %3 = extractelement <4 x float> %A, i32 3
-  %4 = extractelement <4 x float> %B, i32 3
-  %add2 = fadd float %3, %4
-  %vecinsert1 = insertelement <4 x float> undef, float %sub2, i32 2
-  %vecinsert2 = insertelement <4 x float> %vecinsert1, float %add2, i32 3
-  ret <4 x float> %vecinsert2
-}
-
-define <4 x float> @test_addsub_v4f32_partial_03(<4 x float> %A, <4 x float> %B) {
-; SSE-LABEL: test_addsub_v4f32_partial_03:
-; SSE:       # %bb.0:
-; SSE-NEXT:    addsubps %xmm1, %xmm0
-; SSE-NEXT:    retq
-;
-; AVX-LABEL: test_addsub_v4f32_partial_03:
-; AVX:       # %bb.0:
-; AVX-NEXT:    vaddsubps %xmm1, %xmm0, %xmm0
-; AVX-NEXT:    retq
-  %1 = extractelement <4 x float> %A, i32 0
-  %2 = extractelement <4 x float> %B, i32 0
-  %sub = fsub float %1, %2
-  %3 = extractelement <4 x float> %A, i32 3
-  %4 = extractelement <4 x float> %B, i32 3
-  %add = fadd float %4, %3
-  %vecinsert1 = insertelement <4 x float> undef, float %sub, i32 0
-  %vecinsert2 = insertelement <4 x float> %vecinsert1, float %add, i32 3
-  ret <4 x float> %vecinsert2
-}
-
-define <4 x float> @test_addsub_v4f32_partial_12(<4 x float> %A, <4 x float> %B) {
-; SSE-LABEL: test_addsub_v4f32_partial_12:
-; SSE:       # %bb.0:
-; SSE-NEXT:    addsubps %xmm1, %xmm0
-; SSE-NEXT:    retq
-;
-; AVX-LABEL: test_addsub_v4f32_partial_12:
-; AVX:       # %bb.0:
-; AVX-NEXT:    vaddsubps %xmm1, %xmm0, %xmm0
-; AVX-NEXT:    retq
-  %1 = extractelement <4 x float> %A, i32 2
-  %2 = extractelement <4 x float> %B, i32 2
-  %sub = fsub float %1, %2
-  %3 = extractelement <4 x float> %A, i32 1
-  %4 = extractelement <4 x float> %B, i32 1
-  %add = fadd float %3, %4
-  %vecinsert1 = insertelement <4 x float> undef, float %sub, i32 2
-  %vecinsert2 = insertelement <4 x float> %vecinsert1, float %add, i32 1
-  ret <4 x float> %vecinsert2
-}
-
-define <4 x float> @test_addsub_v4f32_partial_01(<4 x float> %A, <4 x float> %B) {
-; SSE-LABEL: test_addsub_v4f32_partial_01:
-; SSE:       # %bb.0:
-; SSE-NEXT:    addsubps %xmm1, %xmm0
-; SSE-NEXT:    retq
-;
-; AVX-LABEL: test_addsub_v4f32_partial_01:
-; AVX:       # %bb.0:
-; AVX-NEXT:    vaddsubps %xmm1, %xmm0, %xmm0
-; AVX-NEXT:    retq
-  %1 = extractelement <4 x float> %A, i32 0
-  %2 = extractelement <4 x float> %B, i32 0
-  %sub2 = fsub float %1, %2
-  %3 = extractelement <4 x float> %A, i32 1
-  %4 = extractelement <4 x float> %B, i32 1
-  %add2 = fadd float %3, %4
-  %vecinsert1 = insertelement <4 x float> undef, float %sub2, i32 0
-  %vecinsert2 = insertelement <4 x float> %vecinsert1, float %add2, i32 1
-  ret <4 x float> %vecinsert2
-}
-
-define <4 x float> @test_addsub_v4f32_shuffle_1302(<4 x float> %A, <4 x float> %B) {
-; SSE-LABEL: test_addsub_v4f32_shuffle_1302:
-; SSE:       # %bb.0:
-; SSE-NEXT:    addsubps %xmm1, %xmm0
-; SSE-NEXT:    retq
-;
-; AVX-LABEL: test_addsub_v4f32_shuffle_1302:
-; AVX:       # %bb.0:
-; AVX-NEXT:    vaddsubps %xmm1, %xmm0, %xmm0
-; AVX-NEXT:    retq
-  %1 = extractelement <4 x float> %A, i32 0
-  %2 = extractelement <4 x float> %B, i32 0
-  %sub = fsub float %1, %2
-  %3 = extractelement <4 x float> %A, i32 2
-  %4 = extractelement <4 x float> %B, i32 2
-  %sub2 = fsub float %3, %4
-  %5 = extractelement <4 x float> %A, i32 1
-  %6 = extractelement <4 x float> %B, i32 1
-  %add = fadd float %5, %6
-  %7 = extractelement <4 x float> %A, i32 3
-  %8 = extractelement <4 x float> %B, i32 3
-  %add2 = fadd float %7, %8
-  %vecinsert1 = insertelement <4 x float> undef, float %add, i32 1
-  %vecinsert2 = insertelement <4 x float> %vecinsert1, float %add2, i32 3
-  %vecinsert3 = insertelement <4 x float> %vecinsert2, float %sub, i32 0
-  %vecinsert4 = insertelement <4 x float> %vecinsert3, float %sub2, i32 2
-  ret <4 x float> %vecinsert4
-}
-
-define <4 x double> @test_addsub_v4f64(<4 x double> %A, <4 x double> %B) {
-; SSE-LABEL: test_addsub_v4f64:
-; SSE:       # %bb.0:
-; SSE-NEXT:    addsubpd %xmm2, %xmm0
-; SSE-NEXT:    addsubpd %xmm3, %xmm1
-; SSE-NEXT:    retq
-;
-; AVX-LABEL: test_addsub_v4f64:
-; AVX:       # %bb.0:
-; AVX-NEXT:    vaddsubpd %ymm1, %ymm0, %ymm0
-; AVX-NEXT:    retq
-  %1 = extractelement <4 x double> %A, i32 0
-  %2 = extractelement <4 x double> %B, i32 0
-  %sub = fsub double %1, %2
-  %3 = extractelement <4 x double> %A, i32 2
-  %4 = extractelement <4 x double> %B, i32 2
-  %sub2 = fsub double %3, %4
-  %5 = extractelement <4 x double> %A, i32 1
-  %6 = extractelement <4 x double> %B, i32 1
-  %add = fadd double %5, %6
-  %7 = extractelement <4 x double> %A, i32 3
-  %8 = extractelement <4 x double> %B, i32 3
-  %add2 = fadd double %7, %8
-  %vecinsert1 = insertelement <4 x double> undef, double %add, i32 1
-  %vecinsert2 = insertelement <4 x double> %vecinsert1, double %add2, i32 3
-  %vecinsert3 = insertelement <4 x double> %vecinsert2, double %sub, i32 0
-  %vecinsert4 = insertelement <4 x double> %vecinsert3, double %sub2, i32 2
-  ret <4 x double> %vecinsert4
-}
-
-define <2 x double> @test_addsub_v2f64(<2 x double> %A, <2 x double> %B) {
-; SSE-LABEL: test_addsub_v2f64:
-; SSE:       # %bb.0:
-; SSE-NEXT:    addsubpd %xmm1, %xmm0
-; SSE-NEXT:    retq
-;
-; AVX-LABEL: test_addsub_v2f64:
-; AVX:       # %bb.0:
-; AVX-NEXT:    vaddsubpd %xmm1, %xmm0, %xmm0
-; AVX-NEXT:    retq
-  %1 = extractelement <2 x double> %A, i32 0
-  %2 = extractelement <2 x double> %B, i32 0
-  %sub = fsub double %1, %2
-  %3 = extractelement <2 x double> %A, i32 1
-  %4 = extractelement <2 x double> %B, i32 1
-  %add = fadd double %3, %4
-  %vecinsert1 = insertelement <2 x double> undef, double %sub, i32 0
-  %vecinsert2 = insertelement <2 x double> %vecinsert1, double %add, i32 1
-  ret <2 x double> %vecinsert2
-}
-
-define <8 x float> @test_addsub_v8f32(<8 x float> %A, <8 x float> %B) {
-; SSE-LABEL: test_addsub_v8f32:
-; SSE:       # %bb.0:
-; SSE-NEXT:    addsubps %xmm2, %xmm0
-; SSE-NEXT:    addsubps %xmm3, %xmm1
-; SSE-NEXT:    retq
-;
-; AVX-LABEL: test_addsub_v8f32:
-; AVX:       # %bb.0:
-; AVX-NEXT:    vaddsubps %ymm1, %ymm0, %ymm0
-; AVX-NEXT:    retq
-  %1 = extractelement <8 x float> %A, i32 0
-  %2 = extractelement <8 x float> %B, i32 0
-  %sub = fsub float %1, %2
-  %3 = extractelement <8 x float> %A, i32 2
-  %4 = extractelement <8 x float> %B, i32 2
-  %sub2 = fsub float %3, %4
-  %5 = extractelement <8 x float> %A, i32 1
-  %6 = extractelement <8 x float> %B, i32 1
-  %add = fadd float %5, %6
-  %7 = extractelement <8 x float> %A, i32 3
-  %8 = extractelement <8 x float> %B, i32 3
-  %add2 = fadd float %7, %8
-  %9 = extractelement <8 x float> %A, i32 4
-  %10 = extractelement <8 x float> %B, i32 4
-  %sub3 = fsub float %9, %10
-  %11 = extractelement <8 x float> %A, i32 6
-  %12 = extractelement <8 x float> %B, i32 6
-  %sub4 = fsub float %11, %12
-  %13 = extractelement <8 x float> %A, i32 5
-  %14 = extractelement <8 x float> %B, i32 5
-  %add3 = fadd float %13, %14
-  %15 = extractelement <8 x float> %A, i32 7
-  %16 = extractelement <8 x float> %B, i32 7
-  %add4 = fadd float %15, %16
-  %vecinsert1 = insertelement <8 x float> undef, float %add, i32 1
-  %vecinsert2 = insertelement <8 x float> %vecinsert1, float %add2, i32 3
-  %vecinsert3 = insertelement <8 x float> %vecinsert2, float %sub, i32 0
-  %vecinsert4 = insertelement <8 x float> %vecinsert3, float %sub2, i32 2
-  %vecinsert5 = insertelement <8 x float> %vecinsert4, float %add3, i32 5
-  %vecinsert6 = insertelement <8 x float> %vecinsert5, float %add4, i32 7
-  %vecinsert7 = insertelement <8 x float> %vecinsert6, float %sub3, i32 4
-  %vecinsert8 = insertelement <8 x float> %vecinsert7, float %sub4, i32 6
-  ret <8 x float> %vecinsert8
-}
-
-; Verify that we don't generate addsub instruction for the following
-; functions.
-
-define <4 x float> @test10(<4 x float> %A, <4 x float> %B) {
-; SSE-LABEL: test10:
-; SSE:       # %bb.0:
-; SSE-NEXT:    subss %xmm1, %xmm0
-; SSE-NEXT:    retq
-;
-; AVX-LABEL: test10:
-; AVX:       # %bb.0:
-; AVX-NEXT:    vsubss %xmm1, %xmm0, %xmm0
-; AVX-NEXT:    retq
-  %1 = extractelement <4 x float> %A, i32 0
-  %2 = extractelement <4 x float> %B, i32 0
-  %sub = fsub float %1, %2
-  %vecinsert1 = insertelement <4 x float> undef, float %sub, i32 0
-  ret <4 x float> %vecinsert1
-}
-
-define <4 x float> @test11(<4 x float> %A, <4 x float> %B) {
-; SSE-LABEL: test11:
-; SSE:       # %bb.0:
-; SSE-NEXT:    movhlps {{.*#+}} xmm0 = xmm0[1,1]
-; SSE-NEXT:    movhlps {{.*#+}} xmm1 = xmm1[1,1]
-; SSE-NEXT:    subss %xmm1, %xmm0
-; SSE-NEXT:    movddup {{.*#+}} xmm0 = xmm0[0,0]
-; SSE-NEXT:    retq
-;
-; AVX1-LABEL: test11:
-; AVX1:       # %bb.0:
-; AVX1-NEXT:    vshufpd {{.*#+}} xmm0 = xmm0[1,0]
-; AVX1-NEXT:    vshufpd {{.*#+}} xmm1 = xmm1[1,0]
-; AVX1-NEXT:    vsubss %xmm1, %xmm0, %xmm0
-; AVX1-NEXT:    vmovddup {{.*#+}} xmm0 = xmm0[0,0]
-; AVX1-NEXT:    retq
-;
-; AVX512-LABEL: test11:
-; AVX512:       # %bb.0:
-; AVX512-NEXT:    vshufpd {{.*#+}} xmm0 = xmm0[1,0]
-; AVX512-NEXT:    vshufpd {{.*#+}} xmm1 = xmm1[1,0]
-; AVX512-NEXT:    vsubss %xmm1, %xmm0, %xmm0
-; AVX512-NEXT:    vbroadcastss %xmm0, %xmm0
-; AVX512-NEXT:    retq
-  %1 = extractelement <4 x float> %A, i32 2
-  %2 = extractelement <4 x float> %B, i32 2
-  %sub = fsub float %1, %2
-  %vecinsert1 = insertelement <4 x float> undef, float %sub, i32 2
-  ret <4 x float> %vecinsert1
-}
-
-define <4 x float> @test12(<4 x float> %A, <4 x float> %B) {
-; SSE-LABEL: test12:
-; SSE:       # %bb.0:
-; SSE-NEXT:    movshdup {{.*#+}} xmm0 = xmm0[1,1,3,3]
-; SSE-NEXT:    movshdup {{.*#+}} xmm1 = xmm1[1,1,3,3]
-; SSE-NEXT:    addss %xmm0, %xmm1
-; SSE-NEXT:    movsldup {{.*#+}} xmm0 = xmm1[0,0,2,2]
-; SSE-NEXT:    retq
-;
-; AVX1-LABEL: test12:
-; AVX1:       # %bb.0:
-; AVX1-NEXT:    vmovshdup {{.*#+}} xmm0 = xmm0[1,1,3,3]
-; AVX1-NEXT:    vmovshdup {{.*#+}} xmm1 = xmm1[1,1,3,3]
-; AVX1-NEXT:    vaddss %xmm1, %xmm0, %xmm0
-; AVX1-NEXT:    vmovsldup {{.*#+}} xmm0 = xmm0[0,0,2,2]
-; AVX1-NEXT:    retq
-;
-; AVX512-LABEL: test12:
-; AVX512:       # %bb.0:
-; AVX512-NEXT:    vmovshdup {{.*#+}} xmm0 = xmm0[1,1,3,3]
-; AVX512-NEXT:    vmovshdup {{.*#+}} xmm1 = xmm1[1,1,3,3]
-; AVX512-NEXT:    vaddss %xmm1, %xmm0, %xmm0
-; AVX512-NEXT:    vbroadcastss %xmm0, %xmm0
-; AVX512-NEXT:    retq
-  %1 = extractelement <4 x float> %A, i32 1
-  %2 = extractelement <4 x float> %B, i32 1
-  %add = fadd float %1, %2
-  %vecinsert1 = insertelement <4 x float> undef, float %add, i32 1
-  ret <4 x float> %vecinsert1
-}
-
-define <4 x float> @test13(<4 x float> %A, <4 x float> %B) {
-; SSE-LABEL: test13:
-; SSE:       # %bb.0:
-; SSE-NEXT:    shufps {{.*#+}} xmm0 = xmm0[3,3,3,3]
-; SSE-NEXT:    shufps {{.*#+}} xmm1 = xmm1[3,3,3,3]
-; SSE-NEXT:    addss %xmm1, %xmm0
-; SSE-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,0,0,0]
-; SSE-NEXT:    retq
-;
-; AVX1-LABEL: test13:
-; AVX1:       # %bb.0:
-; AVX1-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[3,3,3,3]
-; AVX1-NEXT:    vshufps {{.*#+}} xmm1 = xmm1[3,3,3,3]
-; AVX1-NEXT:    vaddss %xmm1, %xmm0, %xmm0
-; AVX1-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[0,0,0,0]
-; AVX1-NEXT:    retq
-;
-; AVX512-LABEL: test13:
-; AVX512:       # %bb.0:
-; AVX512-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[3,3,3,3]
-; AVX512-NEXT:    vshufps {{.*#+}} xmm1 = xmm1[3,3,3,3]
-; AVX512-NEXT:    vaddss %xmm1, %xmm0, %xmm0
-; AVX512-NEXT:    vbroadcastss %xmm0, %xmm0
-; AVX512-NEXT:    retq
-  %1 = extractelement <4 x float> %A, i32 3
-  %2 = extractelement <4 x float> %B, i32 3
-  %add = fadd float %1, %2
-  %vecinsert1 = insertelement <4 x float> undef, float %add, i32 3
-  ret <4 x float> %vecinsert1
-}
-
-define <4 x float> @test14(<4 x float> %A, <4 x float> %B) {
-; SSE-LABEL: test14:
-; SSE:       # %bb.0:
-; SSE-NEXT:    movaps %xmm0, %xmm2
-; SSE-NEXT:    subss %xmm1, %xmm2
-; SSE-NEXT:    movhlps {{.*#+}} xmm0 = xmm0[1,1]
-; SSE-NEXT:    movhlps {{.*#+}} xmm1 = xmm1[1,1]
-; SSE-NEXT:    subss %xmm1, %xmm0
-; SSE-NEXT:    movlhps {{.*#+}} xmm2 = xmm2[0],xmm0[0]
-; SSE-NEXT:    movaps %xmm2, %xmm0
-; SSE-NEXT:    retq
-;
-; AVX-LABEL: test14:
-; AVX:       # %bb.0:
-; AVX-NEXT:    vsubss %xmm1, %xmm0, %xmm2
-; AVX-NEXT:    vshufpd {{.*#+}} xmm0 = xmm0[1,0]
-; AVX-NEXT:    vshufpd {{.*#+}} xmm1 = xmm1[1,0]
-; AVX-NEXT:    vsubss %xmm1, %xmm0, %xmm0
-; AVX-NEXT:    vinsertps {{.*#+}} xmm0 = xmm2[0,1],xmm0[0],xmm2[3]
-; AVX-NEXT:    retq
-  %1 = extractelement <4 x float> %A, i32 0
-  %2 = extractelement <4 x float> %B, i32 0
-  %sub = fsub float %1, %2
-  %3 = extractelement <4 x float> %A, i32 2
-  %4 = extractelement <4 x float> %B, i32 2
-  %sub2 = fsub float %3, %4
-  %vecinsert1 = insertelement <4 x float> undef, float %sub, i32 0
-  %vecinsert2 = insertelement <4 x float> %vecinsert1, float %sub2, i32 2
-  ret <4 x float> %vecinsert2
-}
-
-define <4 x float> @test15(<4 x float> %A, <4 x float> %B) {
-; SSE-LABEL: test15:
-; SSE:       # %bb.0:
-; SSE-NEXT:    movshdup {{.*#+}} xmm3 = xmm0[1,1,3,3]
-; SSE-NEXT:    movshdup {{.*#+}} xmm2 = xmm1[1,1,3,3]
-; SSE-NEXT:    addss %xmm3, %xmm2
-; SSE-NEXT:    shufps {{.*#+}} xmm0 = xmm0[3,3,3,3]
-; SSE-NEXT:    shufps {{.*#+}} xmm1 = xmm1[3,3,3,3]
-; SSE-NEXT:    addss %xmm0, %xmm1
-; SSE-NEXT:    shufps {{.*#+}} xmm2 = xmm2[0,0],xmm1[0,0]
-; SSE-NEXT:    movaps %xmm2, %xmm0
-; SSE-NEXT:    retq
-;
-; AVX1-LABEL: test15:
-; AVX1:       # %bb.0:
-; AVX1-NEXT:    vmovshdup {{.*#+}} xmm2 = xmm0[1,1,3,3]
-; AVX1-NEXT:    vmovshdup {{.*#+}} xmm3 = xmm1[1,1,3,3]
-; AVX1-NEXT:    vaddss %xmm3, %xmm2, %xmm2
-; AVX1-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[3,3,3,3]
-; AVX1-NEXT:    vshufps {{.*#+}} xmm1 = xmm1[3,3,3,3]
-; AVX1-NEXT:    vaddss %xmm1, %xmm0, %xmm0
-; AVX1-NEXT:    vmovsldup {{.*#+}} xmm1 = xmm2[0,0,2,2]
-; AVX1-NEXT:    vinsertps {{.*#+}} xmm0 = xmm1[0,1,2],xmm0[0]
-; AVX1-NEXT:    retq
-;
-; AVX512-LABEL: test15:
-; AVX512:       # %bb.0:
-; AVX512-NEXT:    vmovshdup {{.*#+}} xmm2 = xmm0[1,1,3,3]
-; AVX512-NEXT:    vmovshdup {{.*#+}} xmm3 = xmm1[1,1,3,3]
-; AVX512-NEXT:    vaddss %xmm3, %xmm2, %xmm2
-; AVX512-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[3,3,3,3]
-; AVX512-NEXT:    vshufps {{.*#+}} xmm1 = xmm1[3,3,3,3]
-; AVX512-NEXT:    vaddss %xmm1, %xmm0, %xmm0
-; AVX512-NEXT:    vbroadcastss %xmm2, %xmm1
-; AVX512-NEXT:    vinsertps {{.*#+}} xmm0 = xmm1[0,1,2],xmm0[0]
-; AVX512-NEXT:    retq
-  %1 = extractelement <4 x float> %A, i32 1
-  %2 = extractelement <4 x float> %B, i32 1
-  %add = fadd float %1, %2
-  %3 = extractelement <4 x float> %A, i32 3
-  %4 = extractelement <4 x float> %B, i32 3
-  %add2 = fadd float %3, %4
-  %vecinsert1 = insertelement <4 x float> undef, float %add, i32 1
-  %vecinsert2 = insertelement <4 x float> %vecinsert1, float %add2, i32 3
-  ret <4 x float> %vecinsert2
-}
-
-define <4 x float> @test16(<4 x float> %A, <4 x float> %B) {
-; SSE-LABEL: test16:
-; SSE:       # %bb.0:
-; SSE-NEXT:    movss {{.*#+}} xmm3 = [4.2E+1,0.0E+0,0.0E+0,0.0E+0]
-; SSE-NEXT:    movaps %xmm0, %xmm2
-; SSE-NEXT:    subss %xmm3, %xmm2
-; SSE-NEXT:    movaps %xmm0, %xmm4
-; SSE-NEXT:    unpckhpd {{.*#+}} xmm4 = xmm4[1],xmm0[1]
-; SSE-NEXT:    movaps %xmm1, %xmm5
-; SSE-NEXT:    unpckhpd {{.*#+}} xmm5 = xmm5[1],xmm1[1]
-; SSE-NEXT:    subss %xmm5, %xmm4
-; SSE-NEXT:    movshdup {{.*#+}} xmm5 = xmm0[1,1,3,3]
-; SSE-NEXT:    addss %xmm3, %xmm5
-; SSE-NEXT:    unpcklps {{.*#+}} xmm2 = xmm2[0],xmm5[0],xmm2[1],xmm5[1]
-; SSE-NEXT:    shufps {{.*#+}} xmm0 = xmm0[3,3,3,3]
-; SSE-NEXT:    shufps {{.*#+}} xmm1 = xmm1[3,3,3,3]
-; SSE-NEXT:    addss %xmm0, %xmm1
-; SSE-NEXT:    unpcklps {{.*#+}} xmm4 = xmm4[0],xmm1[0],xmm4[1],xmm1[1]
-; SSE-NEXT:    movlhps {{.*#+}} xmm2 = xmm2[0],xmm4[0]
-; SSE-NEXT:    movaps %xmm2, %xmm0
-; SSE-NEXT:    retq
-;
-; AVX-LABEL: test16:
-; AVX:       # %bb.0:
-; AVX-NEXT:    vmovss {{.*#+}} xmm2 = [4.2E+1,0.0E+0,0.0E+0,0.0E+0]
-; AVX-NEXT:    vsubss %xmm2, %xmm0, %xmm3
-; AVX-NEXT:    vshufpd {{.*#+}} xmm4 = xmm0[1,0]
-; AVX-NEXT:    vshufpd {{.*#+}} xmm5 = xmm1[1,0]
-; AVX-NEXT:    vsubss %xmm5, %xmm4, %xmm4
-; AVX-NEXT:    vmovshdup {{.*#+}} xmm5 = xmm0[1,1,3,3]
-; AVX-NEXT:    vaddss %xmm2, %xmm5, %xmm2
-; AVX-NEXT:    vinsertps {{.*#+}} xmm2 = xmm3[0],xmm2[0],xmm3[2,3]
-; AVX-NEXT:    vinsertps {{.*#+}} xmm2 = xmm2[0,1],xmm4[0],xmm2[3]
-; AVX-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[3,3,3,3]
-; AVX-NEXT:    vshufps {{.*#+}} xmm1 = xmm1[3,3,3,3]
-; AVX-NEXT:    vaddss %xmm1, %xmm0, %xmm0
-; AVX-NEXT:    vinsertps {{.*#+}} xmm0 = xmm2[0,1,2],xmm0[0]
-; AVX-NEXT:    retq
-  %1 = extractelement <4 x float> %A, i32 0
-  %2 = extractelement <4 x float> %B, i32 0
-  %sub = fsub float %1, 42.0
-  %3 = extractelement <4 x float> %A, i32 2
-  %4 = extractelement <4 x float> %B, i32 2
-  %sub2 = fsub float %3, %4
-  %5 = extractelement <4 x float> %A, i32 1
-  %6 = extractelement <4 x float> %B, i32 1
-  %add = fadd float %5, 42.0
-  %7 = extractelement <4 x float> %A, i32 3
-  %8 = extractelement <4 x float> %B, i32 3
-  %add2 = fadd float %7, %8
-  %vecinsert1 = insertelement <4 x float> undef, float %add, i32 1
-  %vecinsert2 = insertelement <4 x float> %vecinsert1, float %add2, i32 3
-  %vecinsert3 = insertelement <4 x float> %vecinsert2, float %sub, i32 0
-  %vecinsert4 = insertelement <4 x float> %vecinsert3, float %sub2, i32 2
-  ret <4 x float> %vecinsert4
-}
-
-define <2 x float> @test_addsub_v2f32(<2 x float> %v0, <2 x float> %v1) {
-; SSE-LABEL: test_addsub_v2f32:
-; SSE:       # %bb.0:
-; SSE-NEXT:    addsubps %xmm1, %xmm0
-; SSE-NEXT:    retq
-;
-; AVX-LABEL: test_addsub_v2f32:
-; AVX:       # %bb.0:
-; AVX-NEXT:    vaddsubps %xmm1, %xmm0, %xmm0
-; AVX-NEXT:    retq
-  %v2 = extractelement <2 x float> %v0, i32 0
-  %v3 = extractelement <2 x float> %v1, i32 0
-  %v4 = extractelement <2 x float> %v0, i32 1
-  %v5 = extractelement <2 x float> %v1, i32 1
-  %sub = fsub float %v2, %v3
-  %add = fadd float %v5, %v4
-  %res0 = insertelement <2 x float> undef, float %sub, i32 0
-  %res1 = insertelement <2 x float> %res0, float %add, i32 1
-  ret <2 x float> %res1
-}
-
-define <16 x float> @test_addsub_v16f32(<16 x float> %A, <16 x float> %B) {
-; SSE-LABEL: test_addsub_v16f32:
-; SSE:       # %bb.0:
-; SSE-NEXT:    addsubps %xmm4, %xmm0
-; SSE-NEXT:    addsubps %xmm5, %xmm1
-; SSE-NEXT:    addsubps %xmm6, %xmm2
-; SSE-NEXT:    addsubps %xmm7, %xmm3
-; SSE-NEXT:    retq
-;
-; AVX1-LABEL: test_addsub_v16f32:
-; AVX1:       # %bb.0:
-; AVX1-NEXT:    vaddsubps %ymm2, %ymm0, %ymm0
-; AVX1-NEXT:    vaddsubps %ymm3, %ymm1, %ymm1
-; AVX1-NEXT:    retq
-;
-; AVX512-LABEL: test_addsub_v16f32:
-; AVX512:       # %bb.0:
-; AVX512-NEXT:    vsubps %zmm1, %zmm0, %zmm2
-; AVX512-NEXT:    movw $-21846, %ax # imm = 0xAAAA
-; AVX512-NEXT:    kmovw %eax, %k1
-; AVX512-NEXT:    vaddps %zmm1, %zmm0, %zmm2 {%k1}
-; AVX512-NEXT:    vmovaps %zmm2, %zmm0
-; AVX512-NEXT:    retq
-  %1 = extractelement <16 x float> %A, i32 0
-  %2 = extractelement <16 x float> %B, i32 0
-  %sub = fsub float %1, %2
-  %3 = extractelement <16 x float> %A, i32 2
-  %4 = extractelement <16 x float> %B, i32 2
-  %sub2 = fsub float %3, %4
-  %5 = extractelement <16 x float> %A, i32 1
-  %6 = extractelement <16 x float> %B, i32 1
-  %add = fadd float %5, %6
-  %7 = extractelement <16 x float> %A, i32 3
-  %8 = extractelement <16 x float> %B, i32 3
-  %add2 = fadd float %7, %8
-  %9 = extractelement <16 x float> %A, i32 4
-  %10 = extractelement <16 x float> %B, i32 4
-  %sub3 = fsub float %9, %10
-  %11 = extractelement <16 x float> %A, i32 6
-  %12 = extractelement <16 x float> %B, i32 6
-  %sub4 = fsub float %11, %12
-  %13 = extractelement <16 x float> %A, i32 5
-  %14 = extractelement <16 x float> %B, i32 5
-  %add3 = fadd float %13, %14
-  %15 = extractelement <16 x float> %A, i32 7
-  %16 = extractelement <16 x float> %B, i32 7
-  %add4 = fadd float %15, %16
-  %17 = extractelement <16 x float> %A, i32 8
-  %18 = extractelement <16 x float> %B, i32 8
-  %sub5 = fsub float %17, %18
-  %19 = extractelement <16 x float> %A, i32 10
-  %20 = extractelement <16 x float> %B, i32 10
-  %sub6 = fsub float %19, %20
-  %21 = extractelement <16 x float> %A, i32 9
-  %22 = extractelement <16 x float> %B, i32 9
-  %add5 = fadd float %21, %22
-  %23 = extractelement <16 x float> %A, i32 11
-  %24 = extractelement <16 x float> %B, i32 11
-  %add6 = fadd float %23, %24
-  %25 = extractelement <16 x float> %A, i32 12
-  %26 = extractelement <16 x float> %B, i32 12
-  %sub7 = fsub float %25, %26
-  %27 = extractelement <16 x float> %A, i32 14
-  %28 = extractelement <16 x float> %B, i32 14
-  %sub8 = fsub float %27, %28
-  %29 = extractelement <16 x float> %A, i32 13
-  %30 = extractelement <16 x float> %B, i32 13
-  %add7 = fadd float %29, %30
-  %31 = extractelement <16 x float> %A, i32 15
-  %32 = extractelement <16 x float> %B, i32 15
-  %add8 = fadd float %31, %32
-  %vecinsert1 = insertelement <16 x float> undef, float %add, i32 1
-  %vecinsert2 = insertelement <16 x float> %vecinsert1, float %add2, i32 3
-  %vecinsert3 = insertelement <16 x float> %vecinsert2, float %sub, i32 0
-  %vecinsert4 = insertelement <16 x float> %vecinsert3, float %sub2, i32 2
-  %vecinsert5 = insertelement <16 x float> %vecinsert4, float %add3, i32 5
-  %vecinsert6 = insertelement <16 x float> %vecinsert5, float %add4, i32 7
-  %vecinsert7 = insertelement <16 x float> %vecinsert6, float %sub3, i32 4
-  %vecinsert8 = insertelement <16 x float> %vecinsert7, float %sub4, i32 6
-  %vecinsert9 = insertelement <16 x float> %vecinsert8, float %add5, i32 9
-  %vecinsert10 = insertelement <16 x float> %vecinsert9, float %add6, i32 11
-  %vecinsert11 = insertelement <16 x float> %vecinsert10, float %sub5, i32 8
-  %vecinsert12 = insertelement <16 x float> %vecinsert11, float %sub6, i32 10
-  %vecinsert13 = insertelement <16 x float> %vecinsert12, float %add7, i32 13
-  %vecinsert14 = insertelement <16 x float> %vecinsert13, float %add8, i32 15
-  %vecinsert15 = insertelement <16 x float> %vecinsert14, float %sub7, i32 12
-  %vecinsert16 = insertelement <16 x float> %vecinsert15, float %sub8, i32 14
-  ret <16 x float> %vecinsert16
-}
-
-define <8 x double> @test_addsub_v8f64(<8 x double> %A, <8 x double> %B) {
-; SSE-LABEL: test_addsub_v8f64:
-; SSE:       # %bb.0:
-; SSE-NEXT:    addsubpd %xmm4, %xmm0
-; SSE-NEXT:    addsubpd %xmm5, %xmm1
-; SSE-NEXT:    addsubpd %xmm6, %xmm2
-; SSE-NEXT:    addsubpd %xmm7, %xmm3
-; SSE-NEXT:    retq
-;
-; AVX1-LABEL: test_addsub_v8f64:
-; AVX1:       # %bb.0:
-; AVX1-NEXT:    vaddsubpd %ymm2, %ymm0, %ymm0
-; AVX1-NEXT:    vaddsubpd %ymm3, %ymm1, %ymm1
-; AVX1-NEXT:    retq
-;
-; AVX512-LABEL: test_addsub_v8f64:
-; AVX512:       # %bb.0:
-; AVX512-NEXT:    vaddpd %zmm1, %zmm0, %zmm2
-; AVX512-NEXT:    vsubpd %zmm1, %zmm0, %zmm0
-; AVX512-NEXT:    vshufpd {{.*#+}} zmm0 = zmm0[0],zmm2[1],zmm0[2],zmm2[3],zmm0[4],zmm2[5],zmm0[6],zmm2[7]
-; AVX512-NEXT:    retq
-  %1 = extractelement <8 x double> %A, i32 0
-  %2 = extractelement <8 x double> %B, i32 0
-  %sub = fsub double %1, %2
-  %3 = extractelement <8 x double> %A, i32 2
-  %4 = extractelement <8 x double> %B, i32 2
-  %sub2 = fsub double %3, %4
-  %5 = extractelement <8 x double> %A, i32 1
-  %6 = extractelement <8 x double> %B, i32 1
-  %add = fadd double %5, %6
-  %7 = extractelement <8 x double> %A, i32 3
-  %8 = extractelement <8 x double> %B, i32 3
-  %add2 = fadd double %7, %8
-  %9 = extractelement <8 x double> %A, i32 4
-  %10 = extractelement <8 x double> %B, i32 4
-  %sub3 = fsub double %9, %10
-  %11 = extractelement <8 x double> %A, i32 6
-  %12 = extractelement <8 x double> %B, i32 6
-  %sub4 = fsub double %11, %12
-  %13 = extractelement <8 x double> %A, i32 5
-  %14 = extractelement <8 x double> %B, i32 5
-  %add3 = fadd double %13, %14
-  %15 = extractelement <8 x double> %A, i32 7
-  %16 = extractelement <8 x double> %B, i32 7
-  %add4 = fadd double %15, %16
-  %vecinsert1 = insertelement <8 x double> undef, double %add, i32 1
-  %vecinsert2 = insertelement <8 x double> %vecinsert1, double %add2, i32 3
-  %vecinsert3 = insertelement <8 x double> %vecinsert2, double %sub, i32 0
-  %vecinsert4 = insertelement <8 x double> %vecinsert3, double %sub2, i32 2
-  %vecinsert5 = insertelement <8 x double> %vecinsert4, double %add3, i32 5
-  %vecinsert6 = insertelement <8 x double> %vecinsert5, double %add4, i32 7
-  %vecinsert7 = insertelement <8 x double> %vecinsert6, double %sub3, i32 4
-  %vecinsert8 = insertelement <8 x double> %vecinsert7, double %sub4, i32 6
-  ret <8 x double> %vecinsert8
-}



More information about the llvm-commits mailing list