Index: llvm/lib/Transforms/Vectorize/LoopVectorize.cpp =================================================================== --- llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -6563,11 +6563,12 @@ return None; RetI = RetI->user_back(); } - if (match(RetI, m_Mul(m_Value(), m_Value())) && - RetI->user_back()->getOpcode() == Instruction::Add) { + + if (match(RetI, m_Mul(m_Value(), m_Value()))) { if (!RetI->hasOneUser()) return None; - RetI = RetI->user_back(); + else if (RetI->user_back()->getOpcode() == Instruction::Add) + RetI = RetI->user_back(); } // Test if the found instruction is a reduction, and if not return an invalid Index: llvm/test/Transforms/LoopVectorize/pr56627.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/LoopVectorize/pr56627.ll @@ -0,0 +1,58 @@ +; RUN: opt < %s -S -passes=loop-vectorize -force-vector-width=2 | FileCheck %s + +; Check that we can vectorize this loop without crashing. + +define void @quux() { +; CHECK-LABEL: @quux( +; CHECK: bb: +; CHECK-NEXT: br i1 false, label [[SCALAR_PHI:%.*]], label [[VECTOR_PHI:%.*]] +; CHECK: vector.ph: +; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] +; CHECK: vector.body: +; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PHI]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ] +; CHECK-NEXT: [[VEC_PHI:%.*]] = phi <2 x float> [ , [[VECTOR_PHI]] ], [ [[TMP0:%.*]], [[VECTOR_BODY]] ] +; CHECK-NEXT: [[TMP0]] = fadd <2 x float> [[VEC_PHI]], zeroinitializer +; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2 +; CHECK-NEXT: br i1 true, label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]] +; CHECK: middle.block: +; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.vector.reduce.fadd.v2f32(float -0.000000e+00, <2 x float> [[TMP0]]) +; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 2, 2 +; CHECK-NEXT: br i1 [[CMP_N]], label [[BB8:%.*]], label [[SCALAR_PHI]] +; CHECK: scalar.ph: +; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 2, [[MIDDLE_BLOCK]] ], [ 0, [[BB:%.*]] ] +; CHECK-NEXT: [[BC_MERGE_RDX:%.*]] = phi float [ 0.000000e+00, %bb ], [ [[TMP1]], [[MIDDLE_BLOCK]] ] +; CHECK-NEXT: br label [[BB1:%.*]] +; CHECK: bb1: +; CHECK-NEXT: [[TMP:%.*]] = phi i64 [ [[TMP3:%.*]], [[BB4:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PHI]] ] +; CHECK-NEXT: [[TMP2:%.*]] = phi float [ [[TMP5:%.*]], [[BB4]] ], [ [[BC_MERGE_RDX]], [[SCALAR_PHI]] ] +; CHECK-NEXT: [[TMP3]] = add nsw i64 [[TMP]], 1 +; CHECK-NEXT: br label [[BB4]] +; CHECK: bb4: +; CHECK-NEXT: [[TMP5]] = fadd float [[TMP2]], 0.000000e+00 +; CHECK-NEXT: [[TMP6:%.*]] = mul i32 0, 0 +; CHECK-NEXT: [[TMP7:%.*]] = icmp sgt i64 [[TMP]], 0 +; CHECK-NEXT: br i1 [[TMP7]], label [[BB8]], label [[BB1]] +; CHECK: bb8: +; CHECK-NEXT: [[TMP9:%.*]] = phi float [ [[TMP5]], [[BB4]] ], [ [[TMP1]], [[MIDDLE_BLOCK]] ] +; CHECK-NEXT: ret void +; + +bb: + br label %bb1 + +bb1: + %tmp = phi i64 [ %tmp3, %bb4 ], [ 0, %bb ] + %tmp2 = phi float [ %tmp5, %bb4 ], [ 0.000000e+00, %bb ] + %tmp3 = add nsw i64 %tmp, 1 + br label %bb4 + +bb4: + %tmp5 = fadd float %tmp2, 0.000000e+00 + %tmp6 = mul i32 0, 0 + %tmp7 = icmp sgt i64 %tmp, 0 + br i1 %tmp7, label %bb8, label %bb1 + +bb8: + %tmp9 = phi float [ %tmp5, %bb4 ] + ret void +}