[llvm] r208487 - Fixed a bug when lowering build_vector (PR19694)

Filipe Cabecinhas me at filcab.net
Sun May 11 01:12:57 PDT 2014


Author: filcab
Date: Sun May 11 03:12:56 2014
New Revision: 208487

URL: http://llvm.org/viewvc/llvm-project?rev=208487&view=rev
Log:
Fixed a bug when lowering build_vector (PR19694)

When lowering build_vector to an insertps, we would still lower it, even
if the source vectors weren't v4x32. This would break on avx if the source
was a v8x32. We now check the type of the source vectors.

Modified:
    llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
    llvm/trunk/test/CodeGen/X86/avx-shuffle.ll

Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=208487&r1=208486&r2=208487&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Sun May 11 03:12:56 2014
@@ -5458,7 +5458,12 @@ static SDValue LowerBuildVectorv4x32(SDV
     return SDValue();
 
   SDValue V = FirstNonZero.getOperand(0);
-  unsigned FirstNonZeroDst = cast<ConstantSDNode>(FirstNonZero.getOperand(1))->getZExtValue();
+  MVT VVT = V.getSimpleValueType();
+  if (VVT != MVT::v4f32 && VVT != MVT::v4i32)
+    return SDValue();
+
+  unsigned FirstNonZeroDst =
+      cast<ConstantSDNode>(FirstNonZero.getOperand(1))->getZExtValue();
   unsigned CorrectIdx = FirstNonZeroDst == FirstNonZeroIdx;
   unsigned IncorrectIdx = CorrectIdx ? -1U : FirstNonZeroIdx;
   unsigned IncorrectDst = CorrectIdx ? -1U : FirstNonZeroDst;
@@ -5498,8 +5503,8 @@ static SDValue LowerBuildVectorv4x32(SDV
     else
       ElementMoveMask = IncorrectDst << 6 | IncorrectIdx << 4;
 
-    SDValue InsertpsMask = DAG.getIntPtrConstant(
-        ElementMoveMask | (~NonZeros & 0xf));
+    SDValue InsertpsMask =
+        DAG.getIntPtrConstant(ElementMoveMask | (~NonZeros & 0xf));
     return DAG.getNode(X86ISD::INSERTPS, dl, VT, V, V, InsertpsMask);
   }
 

Modified: llvm/trunk/test/CodeGen/X86/avx-shuffle.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/avx-shuffle.ll?rev=208487&r1=208486&r2=208487&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/avx-shuffle.ll (original)
+++ llvm/trunk/test/CodeGen/X86/avx-shuffle.ll Sun May 11 03:12:56 2014
@@ -314,3 +314,21 @@ define <2 x i64> @test_insert_64_zext(<2
   %1 = shufflevector <2 x i64> %i, <2 x i64> <i64 0, i64 undef>, <2 x i32> <i32 0, i32 2>
   ret <2 x i64> %1
 }
+
+;; Ensure we don't use insertps from non v4x32 vectors.
+;; On SSE4.1 it works because bigger vectors use more than 1 register.
+;; On AVX they get passed in a single register.
+;; FIXME: We could probably optimize this case, if we're only using the
+;; first 4 indices.
+define <4 x i32> @insert_from_diff_size(<8 x i32> %x) {
+; CHECK-LABEL: insert_from_diff_size:
+; CHECK-NOT: insertps
+; CHECK: ret
+  %vecext = extractelement <8 x i32> %x, i32 0
+  %vecinit = insertelement <4 x i32> undef, i32 %vecext, i32 0
+  %vecinit1 = insertelement <4 x i32> %vecinit, i32 0, i32 1
+  %vecinit2 = insertelement <4 x i32> %vecinit1, i32 0, i32 2
+  %a.0 = extractelement <8 x i32> %x, i32 0
+  %vecinit3 = insertelement <4 x i32> %vecinit2, i32 %a.0, i32 3
+  ret <4 x i32> %vecinit3
+}





More information about the llvm-commits mailing list