From 3f715e260a372e32fe4635d7510eaee11d53129d Mon Sep 17 00:00:00 2001 From: Nick Lewycky Date: Sat, 1 Jun 2013 20:51:31 +0000 Subject: [PATCH] When determining the new index for an insertelement, we may not assume that an 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. llvm-svn: 183080 --- .../InstCombine/InstCombineVectorOps.cpp | 16 +++++++++------- llvm/test/Transforms/InstCombine/vec_shuffle.ll | 11 +++++++++++ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp index 53fcb7154efb..c76aa4c2e6cf 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp @@ -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 Mask, - unsigned Depth = 100) { + unsigned Depth = 5) { // We can always reorder the elements of a constant. if (isa(V)) return true; @@ -718,19 +718,21 @@ InstCombiner::EvaluateInDifferentElementOrder(Value *V, ArrayRef Mask) { } case Instruction::InsertElement: { int Element = cast(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); diff --git a/llvm/test/Transforms/InstCombine/vec_shuffle.ll b/llvm/test/Transforms/InstCombine/vec_shuffle.ll index 4b7a049baec8..5ffe6c04372f 100644 --- a/llvm/test/Transforms/InstCombine/vec_shuffle.ll +++ b/llvm/test/Transforms/InstCombine/vec_shuffle.ll @@ -174,3 +174,14 @@ define <2 x i8> @test13b(i8 %x) { %B = shufflevector <2 x i8> %A, <2 x i8> undef, <2 x i32> 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> + ret <2 x i8> %C +}