diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -11810,6 +11810,11 @@ (PreExtendType == MVT::Other)) return SDValue(); + // Restrict valid pre-extend data type + if (PreExtendType != MVT::i8 && PreExtendType != MVT::i16 && + PreExtendType != MVT::i32) + return SDValue(); + EVT PreExtendVT = TargetType.changeVectorElementType(PreExtendType); if (PreExtendVT.getVectorElementCount() != TargetType.getVectorElementCount()) diff --git a/llvm/test/CodeGen/AArch64/aarch64-dup-ext-vectortype-crash.ll b/llvm/test/CodeGen/AArch64/aarch64-dup-ext-vectortype-crash.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/aarch64-dup-ext-vectortype-crash.ll @@ -0,0 +1,16 @@ +; RUN: llc < %s -mtriple aarch64-none-linux-gnu | FileCheck %s + +; This test covers a case where extended value types can't be converted to +; vector types, resulting in a crash. We don't care about the specific output +; here, only that this case no longer causes said crash. +; See https://reviews.llvm.org/D91255#2484399 for context +define <8 x i16> @extend_i7_v8i16(i7 %src, <8 x i8> %b) { +; CHECK-LABEL: extend_i7_v8i16: +entry: + %in = sext i7 %src to i16 + %ext.b = sext <8 x i8> %b to <8 x i16> + %broadcast.splatinsert = insertelement <8 x i16> undef, i16 %in, i16 0 + %broadcast.splat = shufflevector <8 x i16> %broadcast.splatinsert, <8 x i16> undef, <8 x i32> zeroinitializer + %out = mul nsw <8 x i16> %broadcast.splat, %ext.b + ret <8 x i16> %out +}