When determining the new index for an insertelement, we may not assume that an
authorNick Lewycky <nicholas@mxc.ca>
Sat, 1 Jun 2013 20:51:31 +0000 (20:51 +0000)
committerNick Lewycky <nicholas@mxc.ca>
Sat, 1 Jun 2013 20:51:31 +0000 (20:51 +0000)
index greater than the size of the vector is invalid. The shuffle may be
shrinking the size of the vector. Fixes a crash!

Also drop the maximum recursion depth of the safety check for this
optimization to five.

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

lib/Transforms/InstCombine/InstCombineVectorOps.cpp
test/Transforms/InstCombine/vec_shuffle.ll

index 53fcb7154efb6f07e64bbe3498696ee586fa7c72..c76aa4c2e6cff24e0ed417033fe83f6516ef71c1 100644 (file)
@@ -497,7 +497,7 @@ Instruction *InstCombiner::visitInsertElementInst(InsertElementInst &IE) {
 /// Return true if we can evaluate the specified expression tree if the vector
 /// elements were shuffled in a different order.
 static bool CanEvaluateShuffled(Value *V, ArrayRef<int> Mask,
-                                unsigned Depth = 100) {
+                                unsigned Depth = 5) {
   // We can always reorder the elements of a constant.
   if (isa<Constant>(V))
     return true;
@@ -718,19 +718,21 @@ InstCombiner::EvaluateInDifferentElementOrder(Value *V, ArrayRef<int> Mask) {
     }
     case Instruction::InsertElement: {
       int Element = cast<ConstantInt>(I->getOperand(2))->getLimitedValue();
-      if (Element < 0 || Element >= (int)Mask.size()) {
-        // Such instructions are valid and exhibit undefined behaviour.
-        return UndefValue::get(I->getType());
-      }
 
       // The insertelement was inserting at Element. Figure out which element
       // that becomes after shuffling. The answer is guaranteed to be unique
       // by CanEvaluateShuffled.
+      bool Found = false;
       int Index = 0;
-      for (int e = Mask.size(); Index != e; ++Index)
-        if (Mask[Index] == Element)
+      for (int e = Mask.size(); Index != e; ++Index) {
+        if (Mask[Index] == Element) {
+          Found = true;
           break;
+        }
+      }
 
+      if (!Found)
+        return UndefValue::get(I->getType());
       Value *V = EvaluateInDifferentElementOrder(I->getOperand(0), Mask);
       return InsertElementInst::Create(V, I->getOperand(1),
                                        Builder->getInt32(Index), "", I);
index 4b7a049baec82fbde8ba84d4a52ecd7f9287cbfc..5ffe6c04372fecc456001a972090f013e471ece1 100644 (file)
@@ -174,3 +174,14 @@ define <2 x i8> @test13b(i8 %x) {
   %B = shufflevector <2 x i8> %A, <2 x i8> undef, <2 x i32> <i32 undef, i32 0>
   ret <2 x i8> %B
 }
+
+define <2 x i8> @test13c(i8 %x1, i8 %x2) {
+; CHECK: @test13c
+; CHECK-NEXT: insertelement <2 x i8> {{.*}}, i32 0
+; CHECK-NEXT: insertelement <2 x i8> {{.*}}, i32 1
+; CHECK-NEXT: ret
+  %A = insertelement <4 x i8> undef, i8 %x1, i32 0
+  %B = insertelement <4 x i8> %A, i8 %x2, i32 2
+  %C = shufflevector <4 x i8> %B, <4 x i8> undef, <2 x i32> <i32 0, i32 2>
+  ret <2 x i8> %C
+}