diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp index 1185b748599d1..f8198cf9133bf 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp @@ -1256,6 +1256,9 @@ getOpcodeOrIntrinsicID(const VPSingleDefRecipe *R) { .Case( [](auto *I) { return std::make_pair(false, I->getOpcode()); }) + .Case([](const VPWidenPHIRecipe *I) { + return std::make_pair(true, Instruction::PHI); + }) .Case( [](auto *I) { // For recipes that do not directly map to LLVM IR instructions, @@ -2571,6 +2574,10 @@ struct VPCSEDenseMapInfo : public DenseMapInfo { if (LSIV->getInductionOpcode() != cast(R)->getInductionOpcode()) return false; + // Phi recipes can only be equal if they are in the same VPBB, as they + // implicitly depend on their predecessors. + if (isa(L) && L->getParent() != R->getParent()) + return false; // Recipes in replicate regions implicitly depend on predicate. If either // recipe is in a replicate region, only consider them equal if both have // the same parent. diff --git a/llvm/test/Transforms/LoopVectorize/cse-replicate-regions.ll b/llvm/test/Transforms/LoopVectorize/cse-replicate-regions.ll index bcaa78386f5f4..5d52a7cdc3d31 100644 --- a/llvm/test/Transforms/LoopVectorize/cse-replicate-regions.ll +++ b/llvm/test/Transforms/LoopVectorize/cse-replicate-regions.ll @@ -21,19 +21,18 @@ define void @multiple_vppredinstphi_with_same_predicate(ptr %A, i32 %d) { ; CHECK-NEXT: br label %[[PRED_SDIV_CONTINUE]] ; CHECK: [[PRED_SDIV_CONTINUE]]: ; CHECK-NEXT: [[TMP5:%.*]] = phi <2 x i32> [ poison, %[[VECTOR_BODY]] ], [ [[TMP4]], %[[PRED_SDIV_IF]] ] -; CHECK-NEXT: [[TMP8:%.*]] = phi <2 x i32> [ poison, %[[VECTOR_BODY]] ], [ [[TMP4]], %[[PRED_SDIV_IF]] ] ; CHECK-NEXT: [[TMP6:%.*]] = extractelement <2 x i1> [[TMP1]], i64 1 ; CHECK-NEXT: br i1 [[TMP6]], label %[[PRED_SDIV_IF1:.*]], label %[[PRED_SDIV_CONTINUE2]] ; CHECK: [[PRED_SDIV_IF1]]: ; CHECK-NEXT: [[TMP7:%.*]] = sdiv i32 -10, [[D]] -; CHECK-NEXT: [[TMP9:%.*]] = insertelement <2 x i32> [[TMP5]], i32 [[TMP7]], i64 1 -; CHECK-NEXT: [[TMP14:%.*]] = sdiv i32 -10, [[D]] -; CHECK-NEXT: [[TMP15:%.*]] = insertelement <2 x i32> [[TMP8]], i32 [[TMP14]], i64 1 +; CHECK-NEXT: [[TMP8:%.*]] = insertelement <2 x i32> [[TMP5]], i32 [[TMP7]], i64 1 +; CHECK-NEXT: [[TMP9:%.*]] = sdiv i32 -10, [[D]] +; CHECK-NEXT: [[TMP13:%.*]] = insertelement <2 x i32> [[TMP5]], i32 [[TMP9]], i64 1 ; CHECK-NEXT: br label %[[PRED_SDIV_CONTINUE2]] ; CHECK: [[PRED_SDIV_CONTINUE2]]: -; CHECK-NEXT: [[TMP12:%.*]] = phi <2 x i32> [ [[TMP5]], %[[PRED_SDIV_CONTINUE]] ], [ [[TMP9]], %[[PRED_SDIV_IF1]] ] -; CHECK-NEXT: [[TMP13:%.*]] = phi <2 x i32> [ [[TMP8]], %[[PRED_SDIV_CONTINUE]] ], [ [[TMP15]], %[[PRED_SDIV_IF1]] ] -; CHECK-NEXT: [[TMP10:%.*]] = add <2 x i32> [[TMP13]], [[TMP12]] +; CHECK-NEXT: [[TMP14:%.*]] = phi <2 x i32> [ [[TMP5]], %[[PRED_SDIV_CONTINUE]] ], [ [[TMP8]], %[[PRED_SDIV_IF1]] ] +; CHECK-NEXT: [[TMP12:%.*]] = phi <2 x i32> [ [[TMP5]], %[[PRED_SDIV_CONTINUE]] ], [ [[TMP13]], %[[PRED_SDIV_IF1]] ] +; CHECK-NEXT: [[TMP10:%.*]] = add <2 x i32> [[TMP12]], [[TMP14]] ; CHECK-NEXT: [[PREDPHI:%.*]] = select <2 x i1> [[TMP1]], <2 x i32> [[TMP10]], <2 x i32> zeroinitializer ; CHECK-NEXT: store <2 x i32> [[PREDPHI]], ptr [[TMP0]], align 4 ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 2