================ @@ -14439,33 +14440,60 @@ Value *CodeGenFunction::EmitRISCVCpuSupports(const CallExpr *E) { if (!getContext().getTargetInfo().validateCpuSupports(FeatureStr)) return Builder.getFalse(); - // Note: We are making an unchecked assumption that the size of the - // feature array is >= 1. This holds for any version of compiler-rt - // which defines this interface. - llvm::ArrayType *ArrayOfInt64Ty = llvm::ArrayType::get(Int64Ty, 1); + return EmitRISCVCpuSupports(ArrayRef<StringRef>(FeatureStr)); +} + +static Value *loadRISCVFeatureBits(unsigned Index, CGBuilderTy &Builder, + CodeGenModule &CGM, + llvm::LLVMContext &Context) { + llvm::Type *Int32Ty = llvm::Type::getInt32Ty(Context); + llvm::Type *Int64Ty = llvm::Type::getInt64Ty(Context); + llvm::ArrayType *ArrayOfInt64Ty = + llvm::ArrayType::get(Int64Ty, llvm::RISCV::RISCVFeatureBitSize); llvm::Type *StructTy = llvm::StructType::get(Int32Ty, ArrayOfInt64Ty); llvm::Constant *RISCVFeaturesBits = CGM.CreateRuntimeVariable(StructTy, "__riscv_feature_bits"); - auto *GV = cast<llvm::GlobalValue>(RISCVFeaturesBits); - GV->setDSOLocal(true); - - auto LoadFeatureBit = [&](unsigned Index) { - // Create GEP then load. - Value *IndexVal = llvm::ConstantInt::get(Int32Ty, Index); - llvm::Value *GEPIndices[] = {Builder.getInt32(0), Builder.getInt32(1), - IndexVal}; - Value *Ptr = - Builder.CreateInBoundsGEP(StructTy, RISCVFeaturesBits, GEPIndices); - Value *FeaturesBit = - Builder.CreateAlignedLoad(Int64Ty, Ptr, CharUnits::fromQuantity(8)); - return FeaturesBit; - }; + cast<llvm::GlobalValue>(RISCVFeaturesBits)->setDSOLocal(true); + Value *IndexVal = llvm::ConstantInt::get(Int32Ty, Index); + llvm::Value *GEPIndices[] = {Builder.getInt32(0), Builder.getInt32(1), + IndexVal}; + Value *Ptr = + Builder.CreateInBoundsGEP(StructTy, RISCVFeaturesBits, GEPIndices); + Value *FeaturesBit = + Builder.CreateAlignedLoad(Int64Ty, Ptr, CharUnits::fromQuantity(8)); + return FeaturesBit; +} + +Value *CodeGenFunction::EmitRISCVCpuSupports(ArrayRef<StringRef> FeaturesStrs) { + const unsigned RISCVFeatureLength = llvm::RISCV::RISCVFeatureBitSize; + SmallVector<uint64_t, 2> RequireBitMasks(RISCVFeatureLength); + + for (auto Feat : FeaturesStrs) { + auto [GroupID, BitPos] = RISCVISAInfo::getRISCVFeaturesBitsInfo(Feat); + + // If there isn't BitPos for this feature, skip this version. + // It also report the warning to user during compilation. + if (BitPos == -1) + return Builder.getFalse(); - auto [GroupID, BitPos] = RISCVISAInfo::getRISCVFeaturesBitsInfo(FeatureStr); - assert(BitPos != -1 && "validation should have rejected this feature"); - Value *MaskV = Builder.getInt64(1ULL << BitPos); - Value *Bitset = Builder.CreateAnd(LoadFeatureBit(GroupID), MaskV); - return Builder.CreateICmpEQ(Bitset, MaskV); + RequireBitMasks[GroupID] |= (1ULL << BitPos); + } + + Value *Result = nullptr; + for (unsigned Idx = 0; Idx < RISCVFeatureLength; Idx++) { + if (RequireBitMasks[Idx] == 0) + continue; + + Value *Mask = Builder.getInt64(RequireBitMasks[Idx]); + Value *Bitset = Builder.CreateAnd( + loadRISCVFeatureBits(Idx, Builder, CGM, getLLVMContext()), Mask); + Value *CmpV = Builder.CreateICmpEQ(Bitset, Mask); + Result = (!Result) ? CmpV : Builder.CreateAnd(Result, CmpV); + } + + assert(Result && "Should has value here."); ---------------- topperc wrote:
has -> have https://github.com/llvm/llvm-project/pull/104917 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits