diff --git a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp --- a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp +++ b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp @@ -414,6 +414,10 @@ 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 --- a/llvm/test/Transforms/VectorCombine/AArch64/extract-scalable.ll +++ b/llvm/test/Transforms/VectorCombine/AArch64/extract-scalable.ll @@ -20,3 +20,20 @@ %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; +}