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 @@ -13363,6 +13363,15 @@ auto Mask = SVI->getShuffleMask(); + // Sanity check if all the indices are NOT in range. + // If mask is `undef` or `poison`, `Mask` may be a vector of -1s. + // If all of them are -1, OOB read will happen later. + if (std::none_of(Mask.begin(), Mask.end(), [VecTy](unsigned Idx) { + return Idx < VecTy->getNumElements() * 2; + })) { + return false; + } + Type *PtrTy = UseScalable ? STVTy->getElementType()->getPointerTo(SI->getPointerAddressSpace()) diff --git a/llvm/test/CodeGen/AArch64/aarch64-shufflevector.ll b/llvm/test/CodeGen/AArch64/aarch64-shufflevector.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/aarch64-shufflevector.ll @@ -0,0 +1,25 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=aarch64-linux-gnu -opaque-pointers < %s | FileCheck %s + +target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128" +target triple = "aarch64-unknown-linux-gnu" + +define void @f_undef(<8 x i64> %a, ptr %dst) { +; CHECK-LABEL: f_undef: +; CHECK: // %bb.0: // %BB +; CHECK-NEXT: ret +BB: + %S = shufflevector <8 x i64> %a, <8 x i64> %a, <16 x i32> undef + store <16 x i64> %S, ptr %dst, align 64 + ret void +} + +define void @f_poison(<8 x i64> %a, ptr %dst) { +; CHECK-LABEL: f_poison: +; CHECK: // %bb.0: // %BB +; CHECK-NEXT: ret +BB: + %S = shufflevector <8 x i64> %a, <8 x i64> %a, <16 x i32> poison + store <16 x i64> %S, ptr %dst, align 64 + ret void +}