diff --git a/lib/Transforms/Vectorize/VectorCombine.cpp b/lib/Transforms/Vectorize/VectorCombine.cpp index 5cbe3d85fb7..2ea19493a69 100644 --- a/lib/Transforms/Vectorize/VectorCombine.cpp +++ b/lib/Transforms/Vectorize/VectorCombine.cpp @@ -233,6 +233,11 @@ static bool foldExtractExtract(Instruction &I, const TargetTransformInfo &TTI) { return false; if (ConvertToShuffle) { + // If the extract can be constant-folded, this code is unsimplified. Defer + // to other passes to handle that. + if (isa(ConvertToShuffle->getOperand(0))) + return false; + // The shuffle mask is undefined except for 1 lane that is being translated // to the cheap extraction lane. Example: // ShufMask = { 2, undef, undef, undef } diff --git a/test/Transforms/VectorCombine/X86/extract-binop.ll b/test/Transforms/VectorCombine/X86/extract-binop.ll index 17fab6b5c3c..e4f18f6083a 100644 --- a/test/Transforms/VectorCombine/X86/extract-binop.ll +++ b/test/Transforms/VectorCombine/X86/extract-binop.ll @@ -547,3 +547,29 @@ define i32 @ext_ext_partial_add_reduction_and_extra_add_v4i32(<4 x i32> %x, <4 x %x2y210 = add i32 %x2, %y210 ret i32 %x2y210 } + +define i32 @constant_fold_crash(<4 x i32> %x) { +; CHECK-LABEL: @constant_fold_crash( +; CHECK-NEXT: [[A:%.*]] = extractelement <4 x i32> , i32 1 +; CHECK-NEXT: [[B:%.*]] = extractelement <4 x i32> [[X:%.*]], i32 0 +; CHECK-NEXT: [[C:%.*]] = add i32 [[A]], [[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 +} + +define float @constant_fold_crash_commute(<4 x float> %x) { +; CHECK-LABEL: @constant_fold_crash_commute( +; CHECK-NEXT: [[A:%.*]] = extractelement <4 x float> , i32 3 +; CHECK-NEXT: [[B:%.*]] = extractelement <4 x float> [[X:%.*]], i32 1 +; CHECK-NEXT: [[C:%.*]] = fadd float [[B]], [[A]] +; CHECK-NEXT: ret float [[C]] +; + %a = extractelement <4 x float> , i32 3 + %b = extractelement <4 x float> %x, i32 1 + %c = fadd float %b, %a + ret float %c +}