The reduced test case is in phi-undef-input.ll
We expect SLP to generate code like this:
entry: br i1 %cond, label %bb2, label %bb3 bb2: br label %bb3 bb3: %phi = phi <2 x i8> [ %arg0, %bb2 ], [ <i8 0, i8 undef> %entry ] %zext = zext <2 x i8> %phi to <2 x i32>
If we get to bb3 through the entry block, then %zext lane 1 should have its high-order bits 0.
But instead it generates a poison in phi's input coming from %entry:
entry: br i1 %cond, label %bb2, label %bb3 bb2: br label %bb3 bb3: %phi = phi <2 x i8> [ %arg0, %bb2 ], [ <i8 0, i8 poison> %entry ] %zext = zext <2 x i8> %phi to <2 x i32>
This time if we get to bb3 through the entry block, then %zext lane 1 is poison, so no guarantees about the high-order bits.
Please also check: https://alive2.llvm.org/ce/z/aMa3qD
What if we try this the other way around? We have the initialisation of NumValues here to find the last non-undef value and then assume we do not need to look beyond that. What if we look for the last non-poison value there, by changing this to return !isa<PoisonValue>(V); and treat undef as just another constant that needs to be preserved? (The isa<UndefValue> inside the next loop would also need to be changed to isa<PoisonValue>.) That appears to fix your test just as well, and the impact on other existing SLPVectorizer tests is far less great. Does that also fix your original test?