From c4977030a6afe7514e8b14246fedcac30076d841 Mon Sep 17 00:00:00 2001 From: Simon Pilgrim Date: Thu, 2 Mar 2017 18:56:06 +0000 Subject: [PATCH] [X86][MMX] Fixed i32 extraction on 32-bit targets MMX extraction often ends up as extract_i32(bitcast_v2i32(extract_i64(bitcast_v1i64(x86mmx v), 0)), 0) which fails to simplify on 32-bit targets as i64 isn't legal llvm-svn: 296782 --- lib/Target/X86/X86ISelLowering.cpp | 10 ++++++++++ test/CodeGen/X86/vec_extract-mmx.ll | 27 ++++++--------------------- 2 files changed, 16 insertions(+), 21 deletions(-) diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index e3a880957ed..65d5ad3f242 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -29027,6 +29027,16 @@ static SDValue combineExtractVectorElt(SDNode *N, SelectionDAG &DAG, EVT VT = N->getValueType(0); SDLoc dl(InputVector); + // Detect mmx extraction of all bits as a i64. It works better as a bitcast. + if (InputVector.getOpcode() == ISD::BITCAST && InputVector.hasOneUse() && + VT == MVT::i64 && SrcVT == MVT::v1i64 && isNullConstant(EltIdx)) { + SDValue MMXSrc = InputVector.getOperand(0); + + // The bitcast source is a direct mmx result. + if (MMXSrc.getValueType() == MVT::x86mmx) + return DAG.getBitcast(VT, InputVector); + } + // Detect mmx to i32 conversion through a v2i32 elt extract. if (InputVector.getOpcode() == ISD::BITCAST && InputVector.hasOneUse() && VT == MVT::i32 && SrcVT == MVT::v2i32 && isNullConstant(EltIdx)) { diff --git a/test/CodeGen/X86/vec_extract-mmx.ll b/test/CodeGen/X86/vec_extract-mmx.ll index 52607ea8ade..a137d052d29 100644 --- a/test/CodeGen/X86/vec_extract-mmx.ll +++ b/test/CodeGen/X86/vec_extract-mmx.ll @@ -8,15 +8,14 @@ define i32 @test0(<1 x i64>* %v4) nounwind { ; X32-NEXT: pushl %ebp ; X32-NEXT: movl %esp, %ebp ; X32-NEXT: andl $-8, %esp -; X32-NEXT: subl $24, %esp +; X32-NEXT: subl $8, %esp ; X32-NEXT: movl 8(%ebp), %eax ; X32-NEXT: movl (%eax), %ecx ; X32-NEXT: movl 4(%eax), %eax ; X32-NEXT: movl %eax, {{[0-9]+}}(%esp) ; X32-NEXT: movl %ecx, (%esp) ; X32-NEXT: pshufw $238, (%esp), %mm0 # mm0 = mem[2,3,2,3] -; X32-NEXT: movq %mm0, {{[0-9]+}}(%esp) -; X32-NEXT: movl {{[0-9]+}}(%esp), %eax +; X32-NEXT: movd %mm0, %eax ; X32-NEXT: addl $32, %eax ; X32-NEXT: movl %ebp, %esp ; X32-NEXT: popl %ebp @@ -45,18 +44,11 @@ entry: define i32 @test1(i32* nocapture readonly %ptr) nounwind { ; X32-LABEL: test1: ; X32: # BB#0: # %entry -; X32-NEXT: pushl %ebp -; X32-NEXT: movl %esp, %ebp -; X32-NEXT: andl $-8, %esp -; X32-NEXT: subl $16, %esp -; X32-NEXT: movl 8(%ebp), %eax +; X32-NEXT: movl {{[0-9]+}}(%esp), %eax ; X32-NEXT: movd (%eax), %mm0 ; X32-NEXT: pshufw $232, %mm0, %mm0 # mm0 = mm0[0,2,2,3] -; X32-NEXT: movq %mm0, (%esp) -; X32-NEXT: movl (%esp), %eax +; X32-NEXT: movd %mm0, %eax ; X32-NEXT: emms -; X32-NEXT: movl %ebp, %esp -; X32-NEXT: popl %ebp ; X32-NEXT: retl ; ; X64-LABEL: test1: @@ -87,17 +79,10 @@ entry: define i32 @test2(i32* nocapture readonly %ptr) nounwind { ; X32-LABEL: test2: ; X32: # BB#0: # %entry -; X32-NEXT: pushl %ebp -; X32-NEXT: movl %esp, %ebp -; X32-NEXT: andl $-8, %esp -; X32-NEXT: subl $16, %esp -; X32-NEXT: movl 8(%ebp), %eax +; X32-NEXT: movl {{[0-9]+}}(%esp), %eax ; X32-NEXT: pshufw $232, (%eax), %mm0 # mm0 = mem[0,2,2,3] -; X32-NEXT: movq %mm0, (%esp) -; X32-NEXT: movl (%esp), %eax +; X32-NEXT: movd %mm0, %eax ; X32-NEXT: emms -; X32-NEXT: movl %ebp, %esp -; X32-NEXT: popl %ebp ; X32-NEXT: retl ; ; X64-LABEL: test2: