diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp index fce2cf211cd9..d5c6ff8cad2f 100644 --- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -2105,7 +2105,6 @@ InnerLoopVectorizer::vectorizeBlockInLoop(LoopVectorizationLegality *Legal, // optimizations will clean it up. unsigned NumIncoming = P->getNumIncomingValues(); - assert(NumIncoming > 1 && "Invalid PHI"); // Generate a sequence of selects of the form: // SELECT(Mask3, In3, @@ -2117,10 +2116,11 @@ InnerLoopVectorizer::vectorizeBlockInLoop(LoopVectorizationLegality *Legal, VectorParts &In0 = getVectorValue(P->getIncomingValue(In)); for (unsigned part = 0; part < UF; ++part) { - // We don't need to 'select' the first PHI operand because it is - // the default value if all of the other masks don't match. + // We might have single edge PHIs (blocks) - use an identity + // 'select' for the first PHI operand. if (In == 0) - Entry[part] = In0[part]; + Entry[part] = Builder.CreateSelect(Cond[part], In0[part], + In0[part]); else // Select between the current value and the previous incoming edge // based on the incoming mask. diff --git a/llvm/test/Transforms/LoopVectorize/if-conv-crash.ll b/llvm/test/Transforms/LoopVectorize/if-conv-crash.ll index 3283456aa3c3..f8f2cf1fff4b 100644 --- a/llvm/test/Transforms/LoopVectorize/if-conv-crash.ll +++ b/llvm/test/Transforms/LoopVectorize/if-conv-crash.ll @@ -37,3 +37,25 @@ if.end21: ; preds = %lor.lhs.false if.end25: ; preds = %entry ret void } + +; PR15990 +; We can have basic blocks with single entry PHI nodes. +define void @single_entry_phi(i32* %a, i32 *%b) { +entry: + br label %for.cond1.preheader + +for.cond1.preheader: + %inc10 = phi i32 [ 0, %entry ], [ %inc, %for.end ] + br label %for.end + +for.end: + %malicious.phi = phi i32 [ 0, %for.cond1.preheader ] + %inc = add nsw i32 %inc10, 1 + %tobool = icmp eq i32 %inc, 0 + br i1 %tobool, label %for.cond.for.end5, label %for.cond1.preheader + +for.cond.for.end5: + %and.lcssa = phi i32 [ %malicious.phi, %for.end ] + store i32 %and.lcssa, i32* %a, align 4 + ret void +}