]> granicus.if.org Git - llvm/commitdiff
[X86][MMX] Fixed i32 extraction on 32-bit targets
authorSimon Pilgrim <llvm-dev@redking.me.uk>
Thu, 2 Mar 2017 18:56:06 +0000 (18:56 +0000)
committerSimon Pilgrim <llvm-dev@redking.me.uk>
Thu, 2 Mar 2017 18:56:06 +0000 (18:56 +0000)
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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@296782 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/X86ISelLowering.cpp
test/CodeGen/X86/vec_extract-mmx.ll

index e3a880957ed33ae099028421b9df926fa73ec57f..65d5ad3f2423b8f90f3388b687717cca3218cd0c 100644 (file)
@@ -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)) {
index 52607ea8adeec4c48ff69960b8eac158b3545686..a137d052d2967fada174a6fd1544f677c2cab1d6 100644 (file)
@@ -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: