Index: llvm/include/llvm/ADT/STLExtras.h =================================================================== --- llvm/include/llvm/ADT/STLExtras.h +++ llvm/include/llvm/ADT/STLExtras.h @@ -1360,6 +1360,15 @@ Indices{}); } +/// Wrapper function around std::equal to detect if all elements +/// in a container are same. +template +bool is_splat(R &&Range) { + size_t range_size = size(Range); + return range_size != 0 && (range_size == 1 || + std::equal(adl_begin(Range) + 1, adl_end(Range), adl_begin(Range))); +} + } // end namespace llvm #endif // LLVM_ADT_STLEXTRAS_H Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp =================================================================== --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -2932,7 +2932,7 @@ ISD::VSELECT : ISD::SELECT; // Min/max matching is only viable if all output VTs are the same. - if (std::equal(ValueVTs.begin(), ValueVTs.end(), ValueVTs.begin())) { + if (is_splat(ValueVTs)) { EVT VT = ValueVTs[0]; LLVMContext &Ctx = *DAG.getContext(); auto &TLI = DAG.getTargetLoweringInfo(); Index: llvm/lib/Transforms/Scalar/NewGVN.cpp =================================================================== --- llvm/lib/Transforms/Scalar/NewGVN.cpp +++ llvm/lib/Transforms/Scalar/NewGVN.cpp @@ -3174,10 +3174,7 @@ SmallVector OperandList; std::copy(FilteredPhiArgs.begin(), FilteredPhiArgs.end(), std::back_inserter(OperandList)); - bool Okay = OperandList.size() == 1; - if (!Okay) - Okay = - std::equal(OperandList.begin(), OperandList.end(), OperandList.begin()); + bool Okay = is_splat(OperandList); if (Okay) return singleReachablePHIPath(Visited, cast(OperandList[0]), Second); @@ -3272,8 +3269,7 @@ const MemoryDef *MD = cast(U); return ValueToClass.lookup(MD->getMemoryInst()); }); - assert(std::equal(PhiOpClasses.begin(), PhiOpClasses.end(), - PhiOpClasses.begin()) && + assert(is_splat(PhiOpClasses) && "All MemoryPhi arguments should be in the same class"); } } Index: llvm/unittests/ADT/STLExtrasTest.cpp =================================================================== --- llvm/unittests/ADT/STLExtrasTest.cpp +++ llvm/unittests/ADT/STLExtrasTest.cpp @@ -415,4 +415,19 @@ EXPECT_EQ(EIR.end(), I); } +TEST(STLExtrasTest, splat) { + std::vector V; + EXPECT_FALSE(is_splat(V)); + + V.push_back(1); + EXPECT_TRUE(is_splat(V)); + + V.push_back(1); + V.push_back(1); + EXPECT_TRUE(is_splat(V)); + + V.push_back(2); + EXPECT_FALSE(is_splat(V)); +} + } // namespace