Index: include/llvm/Analysis/TargetTransformInfo.h =================================================================== --- include/llvm/Analysis/TargetTransformInfo.h +++ include/llvm/Analysis/TargetTransformInfo.h @@ -739,6 +739,10 @@ /// and the number of execution units in the CPU. unsigned getMaxInterleaveFactor(unsigned VF) const; + /// Collect properties of V used in cost analyzis, e.g. OP_PowerOf2. + OperandValueKind getOperandInfo(Value *V, + OperandValueProperties &OpProps) const; + /// This is an approximation of reciprocal throughput of a math/logic op. /// A higher cost indicates less expected throughput. /// From Agner Fog's guides, reciprocal throughput is "the average number of Index: lib/Analysis/TargetTransformInfo.cpp =================================================================== --- lib/Analysis/TargetTransformInfo.cpp +++ lib/Analysis/TargetTransformInfo.cpp @@ -384,6 +384,49 @@ return TTIImpl->getMaxInterleaveFactor(VF); } +TargetTransformInfo::OperandValueKind +TargetTransformInfo::getOperandInfo(Value *V, + OperandValueProperties &OpProps) const { + OperandValueKind OpInfo = OK_AnyValue; + OpProps = OP_None; + + if (auto *CI = dyn_cast(V)) { + if (CI->getValue().isPowerOf2()) + OpProps = OP_PowerOf2; + return OK_UniformConstantValue; + } + + const Value *Splat = getSplatValue(V); + + // Check for a splat of a constant or for a non uniform vector of constants + // and check if the constant(s) are all powers of two. + if (isa(V) || isa(V)) { + OpInfo = OK_NonUniformConstantValue; + if (Splat) { + OpInfo = OK_UniformConstantValue; + if (auto *CI = dyn_cast(Splat)) + if (CI->getValue().isPowerOf2()) + OpProps = OP_PowerOf2; + } else if (auto *CDS = dyn_cast(V)) { + OpProps = OP_PowerOf2; + for (unsigned I = 0, E = CDS->getNumElements(); I != E; ++I) { + if (auto *CI = dyn_cast(CDS->getElementAsConstant(I))) + if (CI->getValue().isPowerOf2()) + continue; + OpProps = OP_None; + break; + } + } + } + + // Check for a splat of a uniform value. This is not loop aware, so return + // true only for the obviously uniform cases (argument, globalvalue) + if (Splat && (isa(Splat) || isa(Splat))) + OpInfo = OK_UniformValue; + + return OpInfo; +} + int TargetTransformInfo::getArithmeticInstrCost( unsigned Opcode, Type *Ty, OperandValueKind Opd1Info, OperandValueKind Opd2Info, OperandValueProperties Opd1PropInfo, @@ -630,49 +673,6 @@ return TTIImpl->getInstructionLatency(I); } -static TargetTransformInfo::OperandValueKind -getOperandInfo(Value *V, TargetTransformInfo::OperandValueProperties &OpProps) { - TargetTransformInfo::OperandValueKind OpInfo = - TargetTransformInfo::OK_AnyValue; - OpProps = TargetTransformInfo::OP_None; - - if (auto *CI = dyn_cast(V)) { - if (CI->getValue().isPowerOf2()) - OpProps = TargetTransformInfo::OP_PowerOf2; - return TargetTransformInfo::OK_UniformConstantValue; - } - - const Value *Splat = getSplatValue(V); - - // Check for a splat of a constant or for a non uniform vector of constants - // and check if the constant(s) are all powers of two. - if (isa(V) || isa(V)) { - OpInfo = TargetTransformInfo::OK_NonUniformConstantValue; - if (Splat) { - OpInfo = TargetTransformInfo::OK_UniformConstantValue; - if (auto *CI = dyn_cast(Splat)) - if (CI->getValue().isPowerOf2()) - OpProps = TargetTransformInfo::OP_PowerOf2; - } else if (auto *CDS = dyn_cast(V)) { - OpProps = TargetTransformInfo::OP_PowerOf2; - for (unsigned I = 0, E = CDS->getNumElements(); I != E; ++I) { - if (auto *CI = dyn_cast(CDS->getElementAsConstant(I))) - if (CI->getValue().isPowerOf2()) - continue; - OpProps = TargetTransformInfo::OP_None; - break; - } - } - } - - // Check for a splat of a uniform value. This is not loop aware, so return - // true only for the obviously uniform cases (argument, globalvalue) - if (Splat && (isa(Splat) || isa(Splat))) - OpInfo = TargetTransformInfo::OK_UniformValue; - - return OpInfo; -} - static bool matchPairwiseShuffleMask(ShuffleVectorInst *SI, bool IsLeft, unsigned Level) { // We don't need a shuffle if we just want to have element 0 in position 0 of Index: lib/Transforms/Vectorize/LoopVectorize.cpp =================================================================== --- lib/Transforms/Vectorize/LoopVectorize.cpp +++ lib/Transforms/Vectorize/LoopVectorize.cpp @@ -5669,38 +5669,18 @@ return 0; // Certain instructions can be cheaper to vectorize if they have a constant // second vector operand. One example of this are shifts on x86. - TargetTransformInfo::OperandValueKind Op1VK = - TargetTransformInfo::OK_AnyValue; - TargetTransformInfo::OperandValueKind Op2VK = - TargetTransformInfo::OK_AnyValue; - TargetTransformInfo::OperandValueProperties Op1VP = - TargetTransformInfo::OP_None; - TargetTransformInfo::OperandValueProperties Op2VP = - TargetTransformInfo::OP_None; Value *Op2 = I->getOperand(1); - - // Check for a splat or for a non uniform vector of constants. - if (isa(Op2)) { - ConstantInt *CInt = cast(Op2); - if (CInt && CInt->getValue().isPowerOf2()) - Op2VP = TargetTransformInfo::OP_PowerOf2; - Op2VK = TargetTransformInfo::OK_UniformConstantValue; - } else if (isa(Op2) || isa(Op2)) { - Op2VK = TargetTransformInfo::OK_NonUniformConstantValue; - Constant *SplatValue = cast(Op2)->getSplatValue(); - if (SplatValue) { - ConstantInt *CInt = dyn_cast(SplatValue); - if (CInt && CInt->getValue().isPowerOf2()) - Op2VP = TargetTransformInfo::OP_PowerOf2; - Op2VK = TargetTransformInfo::OK_UniformConstantValue; - } - } else if (Legal->isUniform(Op2)) { + TargetTransformInfo::OperandValueProperties Op2VP; + TargetTransformInfo::OperandValueKind Op2VK = + TTI.getOperandInfo(Op2, Op2VP); + if (Op2VK == TargetTransformInfo::OK_AnyValue && Legal->isUniform(Op2)) Op2VK = TargetTransformInfo::OK_UniformValue; - } + SmallVector Operands(I->operand_values()); unsigned N = isScalarAfterVectorization(I, VF) ? VF : 1; - return N * TTI.getArithmeticInstrCost(I->getOpcode(), VectorTy, Op1VK, - Op2VK, Op1VP, Op2VP, Operands); + return N * TTI.getArithmeticInstrCost( + I->getOpcode(), VectorTy, TargetTransformInfo::OK_AnyValue, + Op2VK, TargetTransformInfo::OP_None, Op2VP, Operands); } case Instruction::Select: { SelectInst *SI = cast(I);