diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp --- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp +++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp @@ -7331,23 +7331,24 @@ InstructionCost ScalarCost = 0; SmallPtrSet CountedOps; for (Value *V : VL) { - auto *PHI = dyn_cast(V); - if (!PHI) - continue; + auto *PHI = cast(V); - ValueList Operands(PHI->getNumIncomingValues(), nullptr); - for (unsigned I = 0, N = PHI->getNumIncomingValues(); I < N; ++I) { - Value *Op = PHI->getIncomingValue(I); - Operands[I] = Op; - } + ValueList Operands(PHI->incoming_values()); if (const TreeEntry *OpTE = getTreeEntry(Operands.front())) if (OpTE->isSame(Operands) && CountedOps.insert(OpTE).second) if (!OpTE->ReuseShuffleIndices.empty()) - ScalarCost += TTI::TCC_Basic * (OpTE->ReuseShuffleIndices.size() - - OpTE->Scalars.size()); + ScalarCost += + TTI->getPHICost(PHI->getType(), TTI::TCK_RecipThroughput) * + (OpTE->ReuseShuffleIndices.size() - OpTE->Scalars.size()); } - return CommonCost - ScalarCost; + SmallVector OpInfos; + for (unsigned I = 0; I < E->getMainOp()->getNumOperands(); I++) + OpInfos.push_back(getOperandInfo(VL, I)); + InstructionCost VecCost = + TTI->getPHICost(VecTy, TTI::TCK_RecipThroughput, OpInfos); + + return VecCost + CommonCost - ScalarCost; } case Instruction::ExtractValue: case Instruction::ExtractElement: { diff --git a/llvm/test/Transforms/SLPVectorizer/RISCV/phi-const.ll b/llvm/test/Transforms/SLPVectorizer/RISCV/phi-const.ll --- a/llvm/test/Transforms/SLPVectorizer/RISCV/phi-const.ll +++ b/llvm/test/Transforms/SLPVectorizer/RISCV/phi-const.ll @@ -11,14 +11,17 @@ ; CHECK-LABEL: define void @f ; CHECK-SAME: (ptr [[P:%.*]], i1 [[C:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: [[P_0:%.*]] = getelementptr i8, ptr [[P]] +; CHECK-NEXT: [[P_1:%.*]] = getelementptr i8, ptr [[P]], i32 1 ; CHECK-NEXT: br i1 [[C]], label [[A:%.*]], label [[B:%.*]] ; CHECK: a: ; CHECK-NEXT: br label [[D:%.*]] ; CHECK: b: ; CHECK-NEXT: br label [[D]] ; CHECK: d: -; CHECK-NEXT: [[TMP1:%.*]] = phi <2 x i8> [ , [[A]] ], [ , [[B]] ] -; CHECK-NEXT: store <2 x i8> [[TMP1]], ptr [[P_0]], align 1 +; CHECK-NEXT: [[X:%.*]] = phi i8 [ 1, [[A]] ], [ -1, [[B]] ] +; CHECK-NEXT: [[Y:%.*]] = phi i8 [ -1, [[A]] ], [ 1, [[B]] ] +; CHECK-NEXT: store i8 [[X]], ptr [[P_0]], align 1 +; CHECK-NEXT: store i8 [[Y]], ptr [[P_1]], align 1 ; CHECK-NEXT: ret void ; %p.0 = getelementptr i8, ptr %p @@ -40,15 +43,19 @@ ; CHECK-LABEL: define void @g ; CHECK-SAME: (ptr [[P:%.*]], i1 [[C:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: [[P_0:%.*]] = getelementptr i8, ptr [[P]] +; CHECK-NEXT: [[P_1:%.*]] = getelementptr i8, ptr [[P]], i32 1 ; CHECK-NEXT: br i1 [[C]], label [[A:%.*]], label [[B:%.*]] ; CHECK: a: ; CHECK-NEXT: br label [[D:%.*]] ; CHECK: b: ; CHECK-NEXT: br label [[D]] ; CHECK: d: -; CHECK-NEXT: [[TMP1:%.*]] = phi <2 x i8> [ , [[A]] ], [ , [[B]] ] -; CHECK-NEXT: [[TMP2:%.*]] = add <2 x i8> [[TMP1]], -; CHECK-NEXT: store <2 x i8> [[TMP2]], ptr [[P_0]], align 1 +; CHECK-NEXT: [[X:%.*]] = phi i8 [ 1, [[A]] ], [ -1, [[B]] ] +; CHECK-NEXT: [[Y:%.*]] = phi i8 [ -1, [[A]] ], [ 1, [[B]] ] +; CHECK-NEXT: [[X_ADD:%.*]] = add i8 [[X]], 1 +; CHECK-NEXT: [[Y_ADD:%.*]] = add i8 [[Y]], 1 +; CHECK-NEXT: store i8 [[X_ADD]], ptr [[P_0]], align 1 +; CHECK-NEXT: store i8 [[Y_ADD]], ptr [[P_1]], align 1 ; CHECK-NEXT: ret void ; %p.0 = getelementptr i8, ptr %p