diff --git a/lib/Transforms/InstCombine/InstCombineVectorOps.cpp b/lib/Transforms/InstCombine/InstCombineVectorOps.cpp index 53fcb7154ef..c76aa4c2e6c 100644 --- a/lib/Transforms/InstCombine/InstCombineVectorOps.cpp +++ b/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/test/Transforms/InstCombine/vec_shuffle.ll b/test/Transforms/InstCombine/vec_shuffle.ll index 4b7a049baec..5ffe6c04372 100644 --- a/test/Transforms/InstCombine/vec_shuffle.ll +++ b/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 +}