diff --git a/llvm/lib/Transforms/Scalar/Scalarizer.cpp b/llvm/lib/Transforms/Scalar/Scalarizer.cpp index 46f92c3de04d..0ef8e5790b7f 100644 --- a/llvm/lib/Transforms/Scalar/Scalarizer.cpp +++ b/llvm/lib/Transforms/Scalar/Scalarizer.cpp @@ -1133,6 +1133,8 @@ bool ScalarizerVisitor::visitExtractElementInst(ExtractElementInst &EEI) { if (auto *CI = dyn_cast(ExtIdx)) { unsigned Idx = CI->getZExtValue(); + if (Idx >= VS->VecTy->getNumElements()) + return false; unsigned Fragment = Idx / VS->NumPacked; Value *Res = Op0[Fragment]; bool IsPacked = VS->NumPacked > 1; diff --git a/llvm/test/Transforms/Scalarizer/constant-extractelement.ll b/llvm/test/Transforms/Scalarizer/constant-extractelement.ll index ad1561e8bae8..d93a2796f08c 100644 --- a/llvm/test/Transforms/Scalarizer/constant-extractelement.ll +++ b/llvm/test/Transforms/Scalarizer/constant-extractelement.ll @@ -16,3 +16,13 @@ define i32 @f1(ptr %src, i32 %index) { %val2 = extractelement <4 x i32> %val1, i32 3 ret i32 %val2 } + +; Test that out-of-bounds extractelement doesn't crash the scalarizer. +define ptr @oob_extract() { +; ALL-LABEL: @oob_extract( +; ALL-NEXT: [[E:%.*]] = extractelement <4 x ptr> zeroinitializer, i32 100 +; ALL-NEXT: ret ptr [[E]] +; + %E = extractelement <4 x ptr> zeroinitializer, i32 100 + ret ptr %E +}