Fix a crash in AVX2 when trying to broadcast a double into a 128-bit vector. There...
authorCraig Topper <craig.topper@gmail.com>
Tue, 10 Jan 2012 08:23:59 +0000 (08:23 +0000)
committerCraig Topper <craig.topper@gmail.com>
Tue, 10 Jan 2012 08:23:59 +0000 (08:23 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@147844 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/X86ISelLowering.cpp
test/CodeGen/X86/avx-vbroadcast.ll
test/CodeGen/X86/avx2-vbroadcast.ll

index 7ba7c79b39af20b34c4e21d12c3436bfa9227af3..d48cfbf49a565f61bbece68f010be796b732abdf 100644 (file)
@@ -4963,7 +4963,10 @@ static SDValue EltsFromConsecutiveLoads(EVT VT, SmallVectorImpl<SDValue> &Elts,
 /// a scalar load.
 /// The scalar load node is returned when a pattern is found,
 /// or SDValue() otherwise.
-static SDValue isVectorBroadcast(SDValue &Op, bool hasAVX2) {
+static SDValue isVectorBroadcast(SDValue &Op, const X86Subtarget *Subtarget) {
+  if (!Subtarget->hasAVX())
+    return SDValue();
+
   EVT VT = Op.getValueType();
   SDValue V = Op;
 
@@ -5022,18 +5025,6 @@ static SDValue isVectorBroadcast(SDValue &Op, bool hasAVX2) {
   bool Is128 = VT.getSizeInBits() == 128;
   unsigned ScalarSize = Ld.getValueType().getSizeInBits();
 
-  if (hasAVX2) {
-    // VBroadcast to YMM
-    if (Is256 && (ScalarSize == 8  || ScalarSize == 16 ||
-                  ScalarSize == 32 || ScalarSize == 64 ))
-      return Ld;
-
-    // VBroadcast to XMM
-    if (Is128 && (ScalarSize ==  8 || ScalarSize == 32 ||
-                  ScalarSize == 16 || ScalarSize == 64 ))
-      return Ld;
-  }
-
   // VBroadcast to YMM
   if (Is256 && (ScalarSize == 32 || ScalarSize == 64))
     return Ld;
@@ -5042,6 +5033,17 @@ static SDValue isVectorBroadcast(SDValue &Op, bool hasAVX2) {
   if (Is128 && (ScalarSize == 32))
     return Ld;
 
+  // The integer check is needed for the 64-bit into 128-bit so it doesn't match
+  // double since there is vbroadcastsd xmm
+  if (Subtarget->hasAVX2() && Ld.getValueType().isInteger()) {
+    // VBroadcast to YMM
+    if (Is256 && (ScalarSize == 8 || ScalarSize == 16))
+      return Ld;
+
+    // VBroadcast to XMM
+    if (Is128 && (ScalarSize ==  8 || ScalarSize == 16 || ScalarSize == 64))
+      return Ld;
+  }
 
   // Unsupported broadcast.
   return SDValue();
@@ -5077,9 +5079,9 @@ X86TargetLowering::LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const {
     return getOnesVector(Op.getValueType(), Subtarget->hasAVX2(), DAG, dl);
   }
 
-  SDValue LD = isVectorBroadcast(Op, Subtarget->hasAVX2());
-  if (Subtarget->hasAVX() && LD.getNode())
-      return DAG.getNode(X86ISD::VBROADCAST, dl, VT, LD);
+  SDValue LD = isVectorBroadcast(Op, Subtarget);
+  if (LD.getNode())
+    return DAG.getNode(X86ISD::VBROADCAST, dl, VT, LD);
 
   unsigned EVTBits = ExtVT.getSizeInBits();
 
@@ -6416,8 +6418,8 @@ SDValue NormalizeVectorShuffle(SDValue Op, SelectionDAG &DAG,
       return Op;
 
     // Use vbroadcast whenever the splat comes from a foldable load
-    SDValue LD = isVectorBroadcast(Op, Subtarget->hasAVX2());
-    if (Subtarget->hasAVX() && LD.getNode())
+    SDValue LD = isVectorBroadcast(Op, Subtarget);
+    if (LD.getNode())
       return DAG.getNode(X86ISD::VBROADCAST, dl, VT, LD);
 
     // Handle splats by matching through known shuffle masks
index 8fbd02ac7d2474647cac11fc7d341e04239116f9..5bf9f4f2e2fe2b74047b71fc8e17d6d14277a21c 100644 (file)
@@ -89,3 +89,13 @@ define <4 x i32> @H(<4 x i32> %a) {
   ret <4 x i32> %x
 }
 
+; CHECK: _I
+; CHECK-NOT: vbroadcastsd (%
+; CHECK: ret
+define <2 x double> @I(double* %ptr) nounwind uwtable readnone ssp {
+entry:
+  %q = load double* %ptr, align 4
+  %vecinit.i = insertelement <2 x double> undef, double %q, i32 0
+  %vecinit2.i = insertelement <2 x double> %vecinit.i, double %q, i32 1
+  ret <2 x double> %vecinit2.i
+}
index 142be33c5e2215fedae3d106831176d75dfb7bc1..fbabb1515882ee0cb5f6c4218c319a70d2bbe7f8 100644 (file)
@@ -140,3 +140,13 @@ entry:
   %q3 = insertelement <4 x i64> %q2, i64 %q, i32 3
   ret <4 x i64> %q3
 }
+
+; make sure that we still don't support broadcast double into 128-bit vector
+; this used to crash
+define <2 x double> @I(double* %ptr) nounwind uwtable readnone ssp {
+entry:
+  %q = load double* %ptr, align 4
+  %vecinit.i = insertelement <2 x double> undef, double %q, i32 0
+  %vecinit2.i = insertelement <2 x double> %vecinit.i, double %q, i32 1
+  ret <2 x double> %vecinit2.i
+}