/// Return a random value with a known type. Value *getRandomValue(Type *Tp) { unsigned index = Ran->Rand(); for (unsigned i=0; i<PT->size(); ++i) { Value *V = PT->at((index + i) % PT->size()); if (V->getType() == Tp) return V; } // If the requested type was not found, generate a constant value. if (Tp->isIntegerTy()) { if (Ran->Rand() & 1) return ConstantInt::getAllOnesValue(Tp); return ConstantInt::getNullValue(Tp); } else if (Tp->isFloatingPointTy()) { if (Ran->Rand() & 1) return ConstantFP::getAllOnesValue(Tp); return ConstantFP::getNullValue(Tp); } else if (Tp->isVectorTy()) { VectorType *VTp = cast<VectorType>(Tp); std::vector<Constant*> TempValues; TempValues.reserve(VTp->getNumElements()); for (unsigned i = 0; i < VTp->getNumElements(); ++i) TempValues.push_back(getRandomConstant(VTp->getScalarType())); ArrayRef<Constant*> VectorValue(TempValues); return ConstantVector::get(VectorValue); } return UndefValue::get(Tp); }
unsigned X86TTIImpl::getMaskedMemoryOpCost(unsigned Opcode, Type *SrcTy, unsigned Alignment, unsigned AddressSpace) { VectorType *SrcVTy = dyn_cast<VectorType>(SrcTy); if (!SrcVTy) // To calculate scalar take the regular cost, without mask return getMemoryOpCost(Opcode, SrcTy, Alignment, AddressSpace); unsigned NumElem = SrcVTy->getVectorNumElements(); VectorType *MaskTy = VectorType::get(Type::getInt8Ty(getGlobalContext()), NumElem); if ((Opcode == Instruction::Load && !isLegalMaskedLoad(SrcVTy, 1)) || (Opcode == Instruction::Store && !isLegalMaskedStore(SrcVTy, 1)) || !isPowerOf2_32(NumElem)) { // Scalarization unsigned MaskSplitCost = getScalarizationOverhead(MaskTy, false, true); unsigned ScalarCompareCost = getCmpSelInstrCost(Instruction::ICmp, Type::getInt8Ty(getGlobalContext()), NULL); unsigned BranchCost = getCFInstrCost(Instruction::Br); unsigned MaskCmpCost = NumElem * (BranchCost + ScalarCompareCost); unsigned ValueSplitCost = getScalarizationOverhead(SrcVTy, Opcode == Instruction::Load, Opcode == Instruction::Store); unsigned MemopCost = NumElem * BaseT::getMemoryOpCost(Opcode, SrcVTy->getScalarType(), Alignment, AddressSpace); return MemopCost + ValueSplitCost + MaskSplitCost + MaskCmpCost; } // Legalize the type. std::pair<unsigned, MVT> LT = TLI->getTypeLegalizationCost(SrcVTy); unsigned Cost = 0; if (LT.second != TLI->getValueType(SrcVTy).getSimpleVT() && LT.second.getVectorNumElements() == NumElem) // Promotion requires expand/truncate for data and a shuffle for mask. Cost += getShuffleCost(TTI::SK_Alternate, SrcVTy, 0, 0) + getShuffleCost(TTI::SK_Alternate, MaskTy, 0, 0); else if (LT.second.getVectorNumElements() > NumElem) { VectorType *NewMaskTy = VectorType::get(MaskTy->getVectorElementType(), LT.second.getVectorNumElements()); // Expanding requires fill mask with zeroes Cost += getShuffleCost(TTI::SK_InsertSubvector, NewMaskTy, 0, MaskTy); } if (!ST->hasAVX512()) return Cost + LT.first*4; // Each maskmov costs 4 // AVX-512 masked load/store is cheapper return Cost+LT.first; }