[X86] getShuffleScalarElt - peek through insert/extract subvector nodes.
authorSimon Pilgrim <llvm-dev@redking.me.uk>
Sun, 3 Mar 2019 14:11:05 +0000 (14:11 +0000)
committerSimon Pilgrim <llvm-dev@redking.me.uk>
Sun, 3 Mar 2019 14:11:05 +0000 (14:11 +0000)
llvm-svn: 355288

llvm/lib/Target/X86/X86ISelLowering.cpp
llvm/test/CodeGen/X86/avx-load-store.ll

index 7aff9ab9b8758f1ed2088947a439f5ace17678a2..bf7037f58ea0795fcae4eede682f1b9340011176 100644 (file)
@@ -6884,6 +6884,29 @@ static SDValue getShuffleScalarElt(SDNode *N, unsigned Index, SelectionDAG &DAG,
                                Depth+1);
   }
 
+  // Recurse into insert_subvector base/sub vector to find scalars.
+  if (Opcode == ISD::INSERT_SUBVECTOR &&
+      isa<ConstantSDNode>(N->getOperand(2))) {
+    SDValue Vec = N->getOperand(0);
+    SDValue Sub = N->getOperand(1);
+    EVT SubVT = Sub.getValueType();
+    unsigned NumSubElts = SubVT.getVectorNumElements();
+    uint64_t SubIdx = N->getConstantOperandVal(2);
+
+    if (SubIdx <= Index && Index < (SubIdx + NumSubElts))
+      return getShuffleScalarElt(Sub.getNode(), Index - SubIdx, DAG, Depth + 1);
+    return getShuffleScalarElt(Vec.getNode(), Index, DAG, Depth + 1);
+  }
+
+  // Recurse into extract_subvector src vector to find scalars.
+  if (Opcode == ISD::EXTRACT_SUBVECTOR &&
+      isa<ConstantSDNode>(N->getOperand(1))) {
+    SDValue Src = N->getOperand(0);
+    EVT SrcVT = Src.getValueType();
+    uint64_t SrcIdx = N->getConstantOperandVal(1);
+    return getShuffleScalarElt(Src.getNode(), Index + SrcIdx, DAG, Depth + 1);
+  }
+
   // Actual nodes that may contain scalar elements
   if (Opcode == ISD::BITCAST) {
     V = V.getOperand(0);
index f4d0921ae499d60dfc670eb157bdf63f99037ae1..eabe82de4443aa360b6f6929408e5a8c6098d033 100644 (file)
@@ -85,11 +85,6 @@ define <8 x float> @mov00(<8 x float> %v, float * %ptr) nounwind {
 ; CHECK_O0-LABEL: mov00:
 ; CHECK_O0:       # %bb.0:
 ; CHECK_O0-NEXT:    vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero
-; CHECK_O0-NEXT:    # implicit-def: $ymm1
-; CHECK_O0-NEXT:    vmovaps %xmm0, %xmm1
-; CHECK_O0-NEXT:    vmovaps %xmm1, %xmm0
-; CHECK_O0-NEXT:    vxorps %xmm2, %xmm2, %xmm2
-; CHECK_O0-NEXT:    vblendps {{.*#+}} xmm0 = xmm0[0],xmm2[1,2,3]
 ; CHECK_O0-NEXT:    # kill: def $ymm0 killed $xmm0
 ; CHECK_O0-NEXT:    retq
   %val = load float, float* %ptr
@@ -106,11 +101,6 @@ define <4 x double> @mov01(<4 x double> %v, double * %ptr) nounwind {
 ; CHECK_O0-LABEL: mov01:
 ; CHECK_O0:       # %bb.0:
 ; CHECK_O0-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero
-; CHECK_O0-NEXT:    # implicit-def: $ymm1
-; CHECK_O0-NEXT:    vmovaps %xmm0, %xmm1
-; CHECK_O0-NEXT:    vmovaps %xmm1, %xmm0
-; CHECK_O0-NEXT:    vxorps %xmm2, %xmm2, %xmm2
-; CHECK_O0-NEXT:    vblendpd {{.*#+}} xmm0 = xmm0[0],xmm2[1]
 ; CHECK_O0-NEXT:    # kill: def $ymm0 killed $xmm0
 ; CHECK_O0-NEXT:    retq
   %val = load double, double* %ptr