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 @@ -218,6 +218,11 @@ V0->getType() != V1->getType()) return false; + // If either extract can be constant-folded, return true to trigger + // InstSimplify. + if (isa(Ext0->getOperand(0)) || isa(Ext1->getOperand(0))) + return true; + // If the scalar value 'I' is going to be re-inserted into a vector, then try // to create an extract to that same element. The extract/insert can be // reduced to a "select shuffle". diff --git a/llvm/test/Transforms/VectorCombine/X86/insert-binop-with-constant.ll b/llvm/test/Transforms/VectorCombine/X86/insert-binop-with-constant.ll --- a/llvm/test/Transforms/VectorCombine/X86/insert-binop-with-constant.ll +++ b/llvm/test/Transforms/VectorCombine/X86/insert-binop-with-constant.ll @@ -726,3 +726,15 @@ %bo = frem nnan <2 x double> %ins, ret <2 x double> %bo } + +define i32 @constant_fold_crash(<4 x i32> %x) { +; CHECK-LABEL: @constant_fold_crash( +; CHECK-NEXT: [[B:%.*]] = extractelement <4 x i32> [[X:%.*]], i32 0 +; CHECK-NEXT: [[C:%.*]] = add i32 17, [[B]] +; CHECK-NEXT: ret i32 [[C]] +; + %a = extractelement <4 x i32> , i32 1 + %b = extractelement <4 x i32> %x, i32 0 + %c = add i32 %a, %b + ret i32 %c +}