[llvm-commits] [llvm] r136002 - in /llvm/trunk: lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrFormats.td lib/Target/X86/X86InstrFragmentsSIMD.td lib/Target/X86/X86InstrSSE.td test/CodeGen/X86/avx-256-splat.ll test/CodeGen/X86/avx-256.ll

Bruno Cardoso Lopes bruno.cardoso at gmail.com
Mon Jul 25 16:05:25 PDT 2011


Author: bruno
Date: Mon Jul 25 18:05:25 2011
New Revision: 136002

URL: http://llvm.org/viewvc/llvm-project?rev=136002&view=rev
Log:
- Handle special scalar_to_vector case: splats. Using a native 128-bit
shuffle before inserting on a 256-bit vector.
- Add AVX versions of movd/movq instructions
- Introduce a few COPY patterns to match insert_subvector instructions.
This turns a trivial insert_subvector instruction into a register copy,
coalescing the xmm into a ymm and avoid emiting on more instruction.

Modified:
    llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
    llvm/trunk/lib/Target/X86/X86InstrFormats.td
    llvm/trunk/lib/Target/X86/X86InstrFragmentsSIMD.td
    llvm/trunk/lib/Target/X86/X86InstrSSE.td
    llvm/trunk/test/CodeGen/X86/avx-256-splat.ll
    llvm/trunk/test/CodeGen/X86/avx-256.ll

Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=136002&r1=136001&r2=136002&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Mon Jul 25 18:05:25 2011
@@ -3955,6 +3955,34 @@
   return DAG.getNode(ISD::BITCAST, dl, VT, V);
 }
 
+/// PromoteVectorToScalarSplat - Since there's no native support for
+/// scalar_to_vector for 256-bit AVX, a 128-bit scalar_to_vector +
+/// INSERT_SUBVECTOR is generated. Recognize this idiom and do the
+/// shuffle before the insertion, this yields less instructions in the end.
+static SDValue PromoteVectorToScalarSplat(ShuffleVectorSDNode *SV,
+                                          SelectionDAG &DAG) {
+  EVT SrcVT = SV->getValueType(0);
+  SDValue V1 = SV->getOperand(0);
+  DebugLoc dl = SV->getDebugLoc();
+  int NumElems = SrcVT.getVectorNumElements();
+
+  assert(SrcVT.is256BitVector() && "unknown howto handle vector type");
+
+  SmallVector<int, 4> Mask;
+  for (int i = 0; i < NumElems/2; ++i)
+    Mask.push_back(SV->getMaskElt(i));
+
+  EVT SVT = EVT::getVectorVT(*DAG.getContext(), SrcVT.getVectorElementType(),
+                             NumElems/2);
+  SDValue SV1 = DAG.getVectorShuffle(SVT, dl, V1.getOperand(1),
+                                     DAG.getUNDEF(SVT), &Mask[0]);
+  SDValue InsV = Insert128BitVector(DAG.getUNDEF(SrcVT), SV1,
+                                    DAG.getConstant(0, MVT::i32), DAG, dl);
+
+  return Insert128BitVector(InsV, SV1,
+                       DAG.getConstant(NumElems/2, MVT::i32), DAG, dl);
+}
+
 /// PromoteSplat - Promote a splat of v4i32, v8i16 or v16i8 to v4f32 and
 /// v8i32, v16i16 or v32i8 to v8f32.
 static SDValue PromoteSplat(ShuffleVectorSDNode *SV, SelectionDAG &DAG) {
@@ -5742,7 +5770,17 @@
     if (NumElem <= 4 && CanXFormVExtractWithShuffleIntoLoad(Op, DAG, TLI))
       return Op;
 
-    // Handle splats by matching through known masks
+    // Since there's no native support for scalar_to_vector for 256-bit AVX, a
+    // 128-bit scalar_to_vector + INSERT_SUBVECTOR is generated. Recognize this
+    // idiom and do the shuffle before the insertion, this yields less
+    // instructions in the end.
+    if (VT.is256BitVector() &&
+        V1.getOpcode() == ISD::INSERT_SUBVECTOR &&
+        V1.getOperand(0).getOpcode() == ISD::UNDEF &&
+        V1.getOperand(1).getOpcode() == ISD::SCALAR_TO_VECTOR)
+      return PromoteVectorToScalarSplat(SVOp, DAG);
+
+    // Handle splats by matching through known shuffle masks
     if ((VT.is128BitVector() && NumElem <= 4) ||
         (VT.is256BitVector() && NumElem <= 8))
       return SDValue();

Modified: llvm/trunk/lib/Target/X86/X86InstrFormats.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrFormats.td?rev=136002&r1=136001&r2=136002&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstrFormats.td (original)
+++ llvm/trunk/lib/Target/X86/X86InstrFormats.td Mon Jul 25 18:05:25 2011
@@ -501,6 +501,9 @@
 class RPDI<bits<8> o, Format F, dag outs, dag ins, string asm,
            list<dag> pattern>
       : PDI<o, F, outs, ins, asm, pattern>, REX_W;
+class VRPDI<bits<8> o, Format F, dag outs, dag ins, string asm,
+           list<dag> pattern>
+      : VPDI<o, F, outs, ins, asm, pattern>, VEX_W;
 
 // MMX Instruction templates
 //

Modified: llvm/trunk/lib/Target/X86/X86InstrFragmentsSIMD.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrFragmentsSIMD.td?rev=136002&r1=136001&r2=136002&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstrFragmentsSIMD.td (original)
+++ llvm/trunk/lib/Target/X86/X86InstrFragmentsSIMD.td Mon Jul 25 18:05:25 2011
@@ -467,3 +467,4 @@
                                                    node:$index), [{
   return X86::isVINSERTF128Index(N);
 }], INSERT_get_vinsertf128_imm>;
+

Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrSSE.td?rev=136002&r1=136001&r2=136002&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstrSSE.td (original)
+++ llvm/trunk/lib/Target/X86/X86InstrSSE.td Mon Jul 25 18:05:25 2011
@@ -2858,6 +2858,14 @@
                       [(set VR128:$dst,
                         (v4i32 (scalar_to_vector (loadi32 addr:$src))))]>,
                       VEX;
+def VMOV64toPQIrr : VRPDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR64:$src),
+                        "mov{d|q}\t{$src, $dst|$dst, $src}",
+                        [(set VR128:$dst,
+                          (v2i64 (scalar_to_vector GR64:$src)))]>, VEX;
+def VMOV64toSDrr : VRPDI<0x6E, MRMSrcReg, (outs FR64:$dst), (ins GR64:$src),
+                       "mov{d|q}\t{$src, $dst|$dst, $src}",
+                       [(set FR64:$dst, (bitconvert GR64:$src))]>, VEX;
+
 def MOVDI2PDIrr : PDI<0x6E, MRMSrcReg, (outs VR128:$dst), (ins GR32:$src),
                       "movd\t{$src, $dst|$dst, $src}",
                       [(set VR128:$dst,
@@ -5358,6 +5366,20 @@
           (VINSERTF128rr VR256:$src1, VR128:$src2,
                          (INSERT_get_vinsertf128_imm VR256:$ins))>;
 
+// Special COPY patterns
+def : Pat<(insert_subvector undef, (v2i64 VR128:$src), (i32 0)),
+          (INSERT_SUBREG (v4i64 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
+def : Pat<(insert_subvector undef, (v2f64 VR128:$src), (i32 0)),
+          (INSERT_SUBREG (v4f64 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
+def : Pat<(insert_subvector undef, (v4i32 VR128:$src), (i32 0)),
+          (INSERT_SUBREG (v8i32 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
+def : Pat<(insert_subvector undef, (v4f32 VR128:$src), (i32 0)),
+          (INSERT_SUBREG (v8f32 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
+def : Pat<(insert_subvector undef, (v8i16 VR128:$src), (i32 0)),
+          (INSERT_SUBREG (v16i16 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
+def : Pat<(insert_subvector undef, (v16i8 VR128:$src), (i32 0)),
+          (INSERT_SUBREG (v32i8 (IMPLICIT_DEF)), VR128:$src, sub_xmm)>;
+
 //===----------------------------------------------------------------------===//
 // VEXTRACTF128 - Extract packed floating-point values
 //

Modified: llvm/trunk/test/CodeGen/X86/avx-256-splat.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/avx-256-splat.ll?rev=136002&r1=136001&r2=136002&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/avx-256-splat.ll (original)
+++ llvm/trunk/test/CodeGen/X86/avx-256-splat.ll Mon Jul 25 18:05:25 2011
@@ -5,7 +5,6 @@
 ; CHECK: vextractf128 $0
 ; CHECK-NEXT: punpcklbw
 ; CHECK-NEXT: punpckhbw
-; CHECK-NEXT: vinsertf128 $0
 ; CHECK-NEXT: vinsertf128 $1
 ; CHECK-NEXT: vpermilps $85
 define <32 x i8> @funcA(<32 x i8> %a) nounwind uwtable readnone ssp {
@@ -16,7 +15,6 @@
 
 ; CHECK: vextractf128 $0
 ; CHECK-NEXT: punpckhwd
-; CHECK-NEXT: vinsertf128 $0
 ; CHECK-NEXT: vinsertf128 $1
 ; CHECK-NEXT: vpermilps $85
 define <16 x i16> @funcB(<16 x i16> %a) nounwind uwtable readnone ssp {
@@ -25,3 +23,25 @@
   ret <16 x i16> %shuffle
 }
 
+; CHECK: vmovd
+; CHECK-NEXT: movlhps
+; CHECK-NEXT: vinsertf128 $1
+define <4 x i64> @funcC(i64 %q) nounwind uwtable readnone ssp {
+entry:
+  %vecinit.i = insertelement <4 x i64> undef, i64 %q, i32 0
+  %vecinit2.i = insertelement <4 x i64> %vecinit.i, i64 %q, i32 1
+  %vecinit4.i = insertelement <4 x i64> %vecinit2.i, i64 %q, i32 2
+  %vecinit6.i = insertelement <4 x i64> %vecinit4.i, i64 %q, i32 3
+  ret <4 x i64> %vecinit6.i
+}
+
+; CHECK: vshufpd
+; CHECK-NEXT: vinsertf128 $1
+define <4 x double> @funcD(double %q) nounwind uwtable readnone ssp {
+entry:
+  %vecinit.i = insertelement <4 x double> undef, double %q, i32 0
+  %vecinit2.i = insertelement <4 x double> %vecinit.i, double %q, i32 1
+  %vecinit4.i = insertelement <4 x double> %vecinit2.i, double %q, i32 2
+  %vecinit6.i = insertelement <4 x double> %vecinit4.i, double %q, i32 3
+  ret <4 x double> %vecinit6.i
+}

Modified: llvm/trunk/test/CodeGen/X86/avx-256.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/avx-256.ll?rev=136002&r1=136001&r2=136002&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/avx-256.ll (original)
+++ llvm/trunk/test/CodeGen/X86/avx-256.ll Mon Jul 25 18:05:25 2011
@@ -1,4 +1,4 @@
-; RUN: llc < %s -mtriple=x86_64-apple-darwin -march=x86 -mcpu=corei7 -mattr=avx | FileCheck %s
+; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=corei7-avx -mattr=+avx | FileCheck %s
 
 @x = common global <8 x float> zeroinitializer, align 32
 @y = common global <4 x double> zeroinitializer, align 32
@@ -12,4 +12,3 @@
   store <4 x double> zeroinitializer, <4 x double>* @y, align 32
   ret void
 }
-





More information about the llvm-commits mailing list