Index: lib/CodeGen/SelectionDAG/SelectionDAG.cpp =================================================================== --- lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -4373,6 +4373,15 @@ return getNode(ISD::EXTRACT_VECTOR_ELT, DL, VT, N1.getOperand(0), N2); } } + + // EXTRACT_VECTOR_ELT of v1iX EXTRACT_SUBVECTOR could be formed + // when vetor types are scalarized and v1iX is legal. + if (N1.getOpcode() == ISD::EXTRACT_SUBVECTOR && + N1.getValueType().getVectorNumElements() == 1) { + // vextract (v1iX extract_subvector(vNiX, Idx)) -> vextract(vNiX,Idx) + return getNode(ISD::EXTRACT_VECTOR_ELT, DL, VT, N1.getOperand(0), + N1.getOperand(1)); + } break; case ISD::EXTRACT_ELEMENT: assert(N2C && (unsigned)N2C->getZExtValue() < 2 && "Bad EXTRACT_ELEMENT!"); Index: test/CodeGen/X86/pr33349.ll =================================================================== --- test/CodeGen/X86/pr33349.ll +++ test/CodeGen/X86/pr33349.ll @@ -43,8 +43,6 @@ ; SKX-NEXT: kshiftrw $2, %k0, %k1 ; SKX-NEXT: kshiftlw $15, %k1, %k2 ; SKX-NEXT: kshiftrw $15, %k2, %k2 -; SKX-NEXT: kshiftlw $15, %k2, %k2 -; SKX-NEXT: kshiftrw $15, %k2, %k2 ; SKX-NEXT: kmovd %k2, %eax ; SKX-NEXT: testb $1, %al ; SKX-NEXT: fld1 @@ -53,24 +51,18 @@ ; SKX-NEXT: fcmovne %st(2), %st(0) ; SKX-NEXT: kshiftlw $14, %k1, %k1 ; SKX-NEXT: kshiftrw $15, %k1, %k1 -; SKX-NEXT: kshiftlw $15, %k1, %k1 -; SKX-NEXT: kshiftrw $15, %k1, %k1 ; SKX-NEXT: kmovd %k1, %eax ; SKX-NEXT: testb $1, %al ; SKX-NEXT: fld %st(1) ; SKX-NEXT: fcmovne %st(3), %st(0) ; SKX-NEXT: kshiftlw $15, %k0, %k1 ; SKX-NEXT: kshiftrw $15, %k1, %k1 -; SKX-NEXT: kshiftlw $15, %k1, %k1 -; SKX-NEXT: kshiftrw $15, %k1, %k1 ; SKX-NEXT: kmovd %k1, %eax ; SKX-NEXT: testb $1, %al ; SKX-NEXT: fld %st(2) ; SKX-NEXT: fcmovne %st(4), %st(0) ; SKX-NEXT: kshiftlw $14, %k0, %k0 ; SKX-NEXT: kshiftrw $15, %k0, %k0 -; SKX-NEXT: kshiftlw $15, %k0, %k0 -; SKX-NEXT: kshiftrw $15, %k0, %k0 ; SKX-NEXT: kmovd %k0, %eax ; SKX-NEXT: testb $1, %al ; SKX-NEXT: fxch %st(3)