================ @@ -1130,8 +1130,96 @@ struct BitTest { static BitTest decodeBitTestBuiltin(unsigned BuiltinID); }; + +// Returns the first convergence entry/loop/anchor instruction found in |BB|. +// std::nullopt otherwise. +std::optional<llvm::IntrinsicInst *> getConvergenceToken(llvm::BasicBlock *BB) { + for (auto &I : *BB) { + auto *II = dyn_cast<llvm::IntrinsicInst>(&I); + if (II && isConvergenceControlIntrinsic(II->getIntrinsicID())) + return II; + } + return std::nullopt; +} + } // namespace +llvm::CallBase * +CodeGenFunction::AddConvergenceControlAttr(llvm::CallBase *Input, + llvm::Value *ParentToken) { + llvm::Value *bundleArgs[] = {ParentToken}; + llvm::OperandBundleDef OB("convergencectrl", bundleArgs); + auto Output = llvm::CallBase::addOperandBundle( + Input, llvm::LLVMContext::OB_convergencectrl, OB, Input); + Input->replaceAllUsesWith(Output); + Input->eraseFromParent(); + return Output; +} + +llvm::IntrinsicInst * +CodeGenFunction::EmitConvergenceLoop(llvm::BasicBlock *BB, + llvm::Value *ParentToken) { + CGBuilderTy::InsertPoint IP = Builder.saveIP(); + Builder.SetInsertPoint(&BB->front()); + auto CB = Builder.CreateIntrinsic( + llvm::Intrinsic::experimental_convergence_loop, {}, {}); + Builder.restoreIP(IP); + + auto I = AddConvergenceControlAttr(CB, ParentToken); + // Controlled convergence is incompatible with uncontrolled convergence. + // Removing any old attributes. + I->setNotConvergent(); ---------------- Keenuts wrote:
good catch, I have no idea why this is here. I recall something around validation, but today reading it, it does not make sense. Thanks! https://github.com/llvm/llvm-project/pull/80680 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits