diff --git a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp index 6a6efd03d49ad..d12624ffb824f 100644 --- a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp +++ b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp @@ -414,6 +414,10 @@ static Value *createShiftShuffle(Value *Vec, unsigned OldIndex, static ExtractElementInst *translateExtract(ExtractElementInst *ExtElt, unsigned NewIndex, IRBuilder<> &Builder) { + // Shufflevectors can only be created for fixed-width vectors. + if (!isa(ExtElt->getOperand(0)->getType())) + return nullptr; + // If the extract can be constant-folded, this code is unsimplified. Defer // to other passes to handle that. Value *X = ExtElt->getVectorOperand(); diff --git a/llvm/test/Transforms/VectorCombine/AArch64/extract-scalable.ll b/llvm/test/Transforms/VectorCombine/AArch64/extract-scalable.ll index 0b6ced730e7f2..fe32b2383592b 100644 --- a/llvm/test/Transforms/VectorCombine/AArch64/extract-scalable.ll +++ b/llvm/test/Transforms/VectorCombine/AArch64/extract-scalable.ll @@ -20,3 +20,20 @@ define i1 @extract_cmp_binop( %a) { %r = xor i1 %cmp1, %cmp2 ret i1 %r } + +; Test that VectorCombine doesn't try to create a shufflevector for +; an extract-extract pattern on a scalable vector type. +define i32 @extract_extract( %vec) { +; CHECK-LABEL: @extract_extract( +; CHECK-NEXT: [[ELT0:%.*]] = extractelement [[VEC:%.*]], i32 0 +; CHECK-NEXT: [[ELT1:%.*]] = extractelement [[VEC]], i32 1 +; CHECK-NEXT: [[IDX:%.*]] = add i32 [[ELT0]], [[ELT1]] +; CHECK-NEXT: [[ELTIDX:%.*]] = extractelement [[VEC]], i32 [[IDX]] +; CHECK-NEXT: ret i32 [[ELTIDX]] +; + %elt0 = extractelement %vec, i32 0 + %elt1 = extractelement %vec, i32 1 + %idx = add i32 %elt0, %elt1 + %eltidx = extractelement %vec, i32 %idx + ret i32 %eltidx; +}