[clang] [clang][SPIR-V] Always add convervence intrinsics (PR #88918)
Keenuts wrote: Hi all, rebased on main, and addressed the comments. This commits changes the register order on SPIR-V vs DXIL, which required me to fix the mad+lerp intrinsic tests. Should be NFC, just storing the register name in a CHECK variable. https://github.com/llvm/llvm-project/pull/88918 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][SPIR-V] Always add convervence intrinsics (PR #88918)
https://github.com/Keenuts updated https://github.com/llvm/llvm-project/pull/88918 From a8bf6fe83a1c145ef81ee30471dc51de1b5354ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nathan=20Gau=C3=ABr?= Date: Mon, 15 Apr 2024 17:05:40 +0200 Subject: [PATCH 1/5] [clang][SPIR-V] Always add convervence intrinsics MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR #80680 added bits in the codegen to lazily add convergence intrinsics when required. This logic relied on the LoopStack. The issue is when parsing the condition, the loopstack doesn't yet reflect the correct values, as expected since we are not yet in the loop. However, convergence tokens should sometimes already be available. The solution which seemed the simplest is to greedily generate the tokens when we generate SPIR-V. Fixes #88144 Signed-off-by: Nathan Gauër --- clang/lib/CodeGen/CGBuiltin.cpp | 88 + clang/lib/CodeGen/CGCall.cpp | 3 + clang/lib/CodeGen/CGStmt.cpp | 94 ++ clang/lib/CodeGen/CodeGenFunction.cpp | 9 ++ clang/lib/CodeGen/CodeGenFunction.h | 9 +- .../builtins/RWBuffer-constructor.hlsl| 1 - .../CodeGenHLSL/convergence/do.while.hlsl | 90 + clang/test/CodeGenHLSL/convergence/for.hlsl | 121 ++ clang/test/CodeGenHLSL/convergence/while.hlsl | 119 + 9 files changed, 445 insertions(+), 89 deletions(-) create mode 100644 clang/test/CodeGenHLSL/convergence/do.while.hlsl create mode 100644 clang/test/CodeGenHLSL/convergence/for.hlsl create mode 100644 clang/test/CodeGenHLSL/convergence/while.hlsl diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 8e31652f4dabef..fb5904558bbae6 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -1141,91 +1141,8 @@ struct BitTest { static BitTest decodeBitTestBuiltin(unsigned BuiltinID); }; -// Returns the first convergence entry/loop/anchor instruction found in |BB|. -// std::nullptr otherwise. -llvm::IntrinsicInst *getConvergenceToken(llvm::BasicBlock *BB) { - for (auto : *BB) { -auto *II = dyn_cast(); -if (II && isConvergenceControlIntrinsic(II->getIntrinsicID())) - return II; - } - return nullptr; -} - } // namespace -llvm::CallBase * -CodeGenFunction::addConvergenceControlToken(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::emitConvergenceLoopToken(llvm::BasicBlock *BB, - llvm::Value *ParentToken) { - CGBuilderTy::InsertPoint IP = Builder.saveIP(); - Builder.SetInsertPoint(>front()); - auto CB = Builder.CreateIntrinsic( - llvm::Intrinsic::experimental_convergence_loop, {}, {}); - Builder.restoreIP(IP); - - auto I = addConvergenceControlToken(CB, ParentToken); - return cast(I); -} - -llvm::IntrinsicInst * -CodeGenFunction::getOrEmitConvergenceEntryToken(llvm::Function *F) { - auto *BB = >getEntryBlock(); - auto *token = getConvergenceToken(BB); - if (token) -return token; - - // Adding a convergence token requires the function to be marked as - // convergent. - F->setConvergent(); - - CGBuilderTy::InsertPoint IP = Builder.saveIP(); - Builder.SetInsertPoint(>front()); - auto I = Builder.CreateIntrinsic( - llvm::Intrinsic::experimental_convergence_entry, {}, {}); - assert(isa(I)); - Builder.restoreIP(IP); - - return cast(I); -} - -llvm::IntrinsicInst * -CodeGenFunction::getOrEmitConvergenceLoopToken(const LoopInfo *LI) { - assert(LI != nullptr); - - auto *token = getConvergenceToken(LI->getHeader()); - if (token) -return token; - - llvm::IntrinsicInst *PII = - LI->getParent() - ? emitConvergenceLoopToken( -LI->getHeader(), getOrEmitConvergenceLoopToken(LI->getParent())) - : getOrEmitConvergenceEntryToken(LI->getHeader()->getParent()); - - return emitConvergenceLoopToken(LI->getHeader(), PII); -} - -llvm::CallBase * -CodeGenFunction::addControlledConvergenceToken(llvm::CallBase *Input) { - llvm::Value *ParentToken = - LoopStack.hasInfo() - ? getOrEmitConvergenceLoopToken(()) - : getOrEmitConvergenceEntryToken(Input->getFunction()); - return addConvergenceControlToken(Input, ParentToken); -} - BitTest BitTest::decodeBitTestBuiltin(unsigned BuiltinID) { switch (BuiltinID) { // Main portable variants. @@ -18400,12 +18317,9 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, ArrayRef{Op0}, nullptr, "dx.rsqrt"); } case
[clang] [clang][SPIR-V] Always add convervence intrinsics (PR #88918)
@@ -3101,3 +3130,68 @@ CodeGenFunction::GenerateCapturedStmtFunction(const CapturedStmt ) { return F; } + +namespace { +// Returns the first convergence entry/loop/anchor instruction found in |BB|. +// std::nullptr otherwise. +llvm::IntrinsicInst *getConvergenceToken(llvm::BasicBlock *BB) { + for (auto : *BB) { +auto *II = dyn_cast(); +if (II && llvm::isConvergenceControlIntrinsic(II->getIntrinsicID())) + return II; + } + return nullptr; +} + +} // namespace + +llvm::CallBase * +CodeGenFunction::addConvergenceControlToken(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::emitConvergenceLoopToken(llvm::BasicBlock *BB, + llvm::Value *ParentToken) { + CGBuilderTy::InsertPoint IP = Builder.saveIP(); + + if (BB->empty()) +Builder.SetInsertPoint(BB); + else +Builder.SetInsertPoint(>front()); + + auto CB = Builder.CreateIntrinsic( + llvm::Intrinsic::experimental_convergence_loop, {}, {}); + Builder.restoreIP(IP); + + auto I = addConvergenceControlToken(CB, ParentToken); Keenuts wrote: Right, replaced the auto usage https://github.com/llvm/llvm-project/pull/88918 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][SPIR-V] Always add convervence intrinsics (PR #88918)
https://github.com/Keenuts updated https://github.com/llvm/llvm-project/pull/88918 From 94d76dcdfac88d1d50fe705406c0280c33766e15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nathan=20Gau=C3=ABr?= Date: Mon, 15 Apr 2024 17:05:40 +0200 Subject: [PATCH 1/4] [clang][SPIR-V] Always add convervence intrinsics MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR #80680 added bits in the codegen to lazily add convergence intrinsics when required. This logic relied on the LoopStack. The issue is when parsing the condition, the loopstack doesn't yet reflect the correct values, as expected since we are not yet in the loop. However, convergence tokens should sometimes already be available. The solution which seemed the simplest is to greedily generate the tokens when we generate SPIR-V. Fixes #88144 Signed-off-by: Nathan Gauër --- clang/lib/CodeGen/CGBuiltin.cpp | 88 + clang/lib/CodeGen/CGCall.cpp | 3 + clang/lib/CodeGen/CGStmt.cpp | 94 ++ clang/lib/CodeGen/CodeGenFunction.cpp | 9 ++ clang/lib/CodeGen/CodeGenFunction.h | 9 +- .../builtins/RWBuffer-constructor.hlsl| 1 - .../CodeGenHLSL/convergence/do.while.hlsl | 90 + clang/test/CodeGenHLSL/convergence/for.hlsl | 121 ++ clang/test/CodeGenHLSL/convergence/while.hlsl | 119 + 9 files changed, 445 insertions(+), 89 deletions(-) create mode 100644 clang/test/CodeGenHLSL/convergence/do.while.hlsl create mode 100644 clang/test/CodeGenHLSL/convergence/for.hlsl create mode 100644 clang/test/CodeGenHLSL/convergence/while.hlsl diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index df7502b8def5314..f5d40a1555fcb57 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -1133,91 +1133,8 @@ struct BitTest { static BitTest decodeBitTestBuiltin(unsigned BuiltinID); }; -// Returns the first convergence entry/loop/anchor instruction found in |BB|. -// std::nullptr otherwise. -llvm::IntrinsicInst *getConvergenceToken(llvm::BasicBlock *BB) { - for (auto : *BB) { -auto *II = dyn_cast(); -if (II && isConvergenceControlIntrinsic(II->getIntrinsicID())) - return II; - } - return nullptr; -} - } // namespace -llvm::CallBase * -CodeGenFunction::addConvergenceControlToken(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::emitConvergenceLoopToken(llvm::BasicBlock *BB, - llvm::Value *ParentToken) { - CGBuilderTy::InsertPoint IP = Builder.saveIP(); - Builder.SetInsertPoint(>front()); - auto CB = Builder.CreateIntrinsic( - llvm::Intrinsic::experimental_convergence_loop, {}, {}); - Builder.restoreIP(IP); - - auto I = addConvergenceControlToken(CB, ParentToken); - return cast(I); -} - -llvm::IntrinsicInst * -CodeGenFunction::getOrEmitConvergenceEntryToken(llvm::Function *F) { - auto *BB = >getEntryBlock(); - auto *token = getConvergenceToken(BB); - if (token) -return token; - - // Adding a convergence token requires the function to be marked as - // convergent. - F->setConvergent(); - - CGBuilderTy::InsertPoint IP = Builder.saveIP(); - Builder.SetInsertPoint(>front()); - auto I = Builder.CreateIntrinsic( - llvm::Intrinsic::experimental_convergence_entry, {}, {}); - assert(isa(I)); - Builder.restoreIP(IP); - - return cast(I); -} - -llvm::IntrinsicInst * -CodeGenFunction::getOrEmitConvergenceLoopToken(const LoopInfo *LI) { - assert(LI != nullptr); - - auto *token = getConvergenceToken(LI->getHeader()); - if (token) -return token; - - llvm::IntrinsicInst *PII = - LI->getParent() - ? emitConvergenceLoopToken( -LI->getHeader(), getOrEmitConvergenceLoopToken(LI->getParent())) - : getOrEmitConvergenceEntryToken(LI->getHeader()->getParent()); - - return emitConvergenceLoopToken(LI->getHeader(), PII); -} - -llvm::CallBase * -CodeGenFunction::addControlledConvergenceToken(llvm::CallBase *Input) { - llvm::Value *ParentToken = - LoopStack.hasInfo() - ? getOrEmitConvergenceLoopToken(()) - : getOrEmitConvergenceEntryToken(Input->getFunction()); - return addConvergenceControlToken(Input, ParentToken); -} - BitTest BitTest::decodeBitTestBuiltin(unsigned BuiltinID) { switch (BuiltinID) { // Main portable variants. @@ -18306,12 +18223,9 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, ArrayRef{Op0}, nullptr, "dx.rsqrt"); } case
[clang] [clang][SPIR-V] Always add convervence intrinsics (PR #88918)
Nathan =?utf-8?q?Gauër?= , Nathan =?utf-8?q?Gauër?= Message-ID: In-Reply-To: @@ -3101,3 +3130,68 @@ CodeGenFunction::GenerateCapturedStmtFunction(const CapturedStmt ) { return F; } + +namespace { +// Returns the first convergence entry/loop/anchor instruction found in |BB|. +// std::nullptr otherwise. +llvm::IntrinsicInst *getConvergenceToken(llvm::BasicBlock *BB) { + for (auto : *BB) { +auto *II = dyn_cast(); +if (II && llvm::isConvergenceControlIntrinsic(II->getIntrinsicID())) + return II; + } + return nullptr; +} + +} // namespace + +llvm::CallBase * +CodeGenFunction::addConvergenceControlToken(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::emitConvergenceLoopToken(llvm::BasicBlock *BB, + llvm::Value *ParentToken) { + CGBuilderTy::InsertPoint IP = Builder.saveIP(); + + if (BB->empty()) +Builder.SetInsertPoint(BB); + else +Builder.SetInsertPoint(>front()); + + auto CB = Builder.CreateIntrinsic( + llvm::Intrinsic::experimental_convergence_loop, {}, {}); + Builder.restoreIP(IP); + + auto I = addConvergenceControlToken(CB, ParentToken); llvm-beanz wrote: I'm pretty sure that some of this is just code that you moved from CGBuiltin.cpp, but we probably should change the gratuitous use of `auto`. LLVM's conventions only use `auto` when it improves readability (see: https://llvm.org/docs/CodingStandards.html#use-auto-type-deduction-to-make-code-more-readable). In quite a few of these cases the explicit type would be much more readable. https://github.com/llvm/llvm-project/pull/88918 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][SPIR-V] Always add convervence intrinsics (PR #88918)
Nathan =?utf-8?q?Gauër?= , Nathan =?utf-8?q?Gauër?= Message-ID: In-Reply-To: @@ -3101,3 +3130,68 @@ CodeGenFunction::GenerateCapturedStmtFunction(const CapturedStmt ) { return F; } + +namespace { +// Returns the first convergence entry/loop/anchor instruction found in |BB|. +// std::nullptr otherwise. +llvm::IntrinsicInst *getConvergenceToken(llvm::BasicBlock *BB) { + for (auto : *BB) { +auto *II = dyn_cast(); +if (II && llvm::isConvergenceControlIntrinsic(II->getIntrinsicID())) + return II; + } + return nullptr; +} + +} // namespace + +llvm::CallBase * +CodeGenFunction::addConvergenceControlToken(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::emitConvergenceLoopToken(llvm::BasicBlock *BB, + llvm::Value *ParentToken) { + CGBuilderTy::InsertPoint IP = Builder.saveIP(); + + if (BB->empty()) +Builder.SetInsertPoint(BB); + else +Builder.SetInsertPoint(>front()); + + auto CB = Builder.CreateIntrinsic( + llvm::Intrinsic::experimental_convergence_loop, {}, {}); + Builder.restoreIP(IP); + + auto I = addConvergenceControlToken(CB, ParentToken); + return cast(I); +} + +llvm::IntrinsicInst * +CodeGenFunction::getOrEmitConvergenceEntryToken(llvm::Function *F) { + auto *BB = >getEntryBlock(); + auto *token = getConvergenceToken(BB); bogner wrote: LLVM naming prefers `Token` https://github.com/llvm/llvm-project/pull/88918 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][SPIR-V] Always add convervence intrinsics (PR #88918)
Nathan =?utf-8?q?Gauër?= , Nathan =?utf-8?q?Gauër?= Message-ID: In-Reply-To: @@ -3101,3 +3130,68 @@ CodeGenFunction::GenerateCapturedStmtFunction(const CapturedStmt ) { return F; } + +namespace { +// Returns the first convergence entry/loop/anchor instruction found in |BB|. +// std::nullptr otherwise. +llvm::IntrinsicInst *getConvergenceToken(llvm::BasicBlock *BB) { + for (auto : *BB) { +auto *II = dyn_cast(); +if (II && llvm::isConvergenceControlIntrinsic(II->getIntrinsicID())) + return II; + } + return nullptr; +} + +} // namespace + +llvm::CallBase * +CodeGenFunction::addConvergenceControlToken(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::emitConvergenceLoopToken(llvm::BasicBlock *BB, + llvm::Value *ParentToken) { + CGBuilderTy::InsertPoint IP = Builder.saveIP(); + + if (BB->empty()) +Builder.SetInsertPoint(BB); + else +Builder.SetInsertPoint(>front()); bogner wrote: Should this be something like `BB->getFirstInsertionPt()`? That's more concise and better behaved around PHI nodes and the like https://github.com/llvm/llvm-project/pull/88918 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][SPIR-V] Always add convervence intrinsics (PR #88918)
@@ -1109,6 +1124,10 @@ void CodeGenFunction::EmitForStmt(const ForStmt , llvm::BasicBlock *CondBlock = CondDest.getBlock(); EmitBlock(CondBlock); + if (getTarget().getTriple().isSPIRVLogical()) Keenuts wrote: Changed those for a module-level function which hides the target specific bit behind a more generic check. Let me know if that's not what you had in mind! https://github.com/llvm/llvm-project/pull/88918 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][SPIR-V] Always add convervence intrinsics (PR #88918)
https://github.com/Keenuts updated https://github.com/llvm/llvm-project/pull/88918 From 94d76dcdfac88d1d50fe705406c0280c33766e15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nathan=20Gau=C3=ABr?= Date: Mon, 15 Apr 2024 17:05:40 +0200 Subject: [PATCH 1/3] [clang][SPIR-V] Always add convervence intrinsics MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR #80680 added bits in the codegen to lazily add convergence intrinsics when required. This logic relied on the LoopStack. The issue is when parsing the condition, the loopstack doesn't yet reflect the correct values, as expected since we are not yet in the loop. However, convergence tokens should sometimes already be available. The solution which seemed the simplest is to greedily generate the tokens when we generate SPIR-V. Fixes #88144 Signed-off-by: Nathan Gauër --- clang/lib/CodeGen/CGBuiltin.cpp | 88 + clang/lib/CodeGen/CGCall.cpp | 3 + clang/lib/CodeGen/CGStmt.cpp | 94 ++ clang/lib/CodeGen/CodeGenFunction.cpp | 9 ++ clang/lib/CodeGen/CodeGenFunction.h | 9 +- .../builtins/RWBuffer-constructor.hlsl| 1 - .../CodeGenHLSL/convergence/do.while.hlsl | 90 + clang/test/CodeGenHLSL/convergence/for.hlsl | 121 ++ clang/test/CodeGenHLSL/convergence/while.hlsl | 119 + 9 files changed, 445 insertions(+), 89 deletions(-) create mode 100644 clang/test/CodeGenHLSL/convergence/do.while.hlsl create mode 100644 clang/test/CodeGenHLSL/convergence/for.hlsl create mode 100644 clang/test/CodeGenHLSL/convergence/while.hlsl diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index df7502b8def531..f5d40a1555fcb5 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -1133,91 +1133,8 @@ struct BitTest { static BitTest decodeBitTestBuiltin(unsigned BuiltinID); }; -// Returns the first convergence entry/loop/anchor instruction found in |BB|. -// std::nullptr otherwise. -llvm::IntrinsicInst *getConvergenceToken(llvm::BasicBlock *BB) { - for (auto : *BB) { -auto *II = dyn_cast(); -if (II && isConvergenceControlIntrinsic(II->getIntrinsicID())) - return II; - } - return nullptr; -} - } // namespace -llvm::CallBase * -CodeGenFunction::addConvergenceControlToken(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::emitConvergenceLoopToken(llvm::BasicBlock *BB, - llvm::Value *ParentToken) { - CGBuilderTy::InsertPoint IP = Builder.saveIP(); - Builder.SetInsertPoint(>front()); - auto CB = Builder.CreateIntrinsic( - llvm::Intrinsic::experimental_convergence_loop, {}, {}); - Builder.restoreIP(IP); - - auto I = addConvergenceControlToken(CB, ParentToken); - return cast(I); -} - -llvm::IntrinsicInst * -CodeGenFunction::getOrEmitConvergenceEntryToken(llvm::Function *F) { - auto *BB = >getEntryBlock(); - auto *token = getConvergenceToken(BB); - if (token) -return token; - - // Adding a convergence token requires the function to be marked as - // convergent. - F->setConvergent(); - - CGBuilderTy::InsertPoint IP = Builder.saveIP(); - Builder.SetInsertPoint(>front()); - auto I = Builder.CreateIntrinsic( - llvm::Intrinsic::experimental_convergence_entry, {}, {}); - assert(isa(I)); - Builder.restoreIP(IP); - - return cast(I); -} - -llvm::IntrinsicInst * -CodeGenFunction::getOrEmitConvergenceLoopToken(const LoopInfo *LI) { - assert(LI != nullptr); - - auto *token = getConvergenceToken(LI->getHeader()); - if (token) -return token; - - llvm::IntrinsicInst *PII = - LI->getParent() - ? emitConvergenceLoopToken( -LI->getHeader(), getOrEmitConvergenceLoopToken(LI->getParent())) - : getOrEmitConvergenceEntryToken(LI->getHeader()->getParent()); - - return emitConvergenceLoopToken(LI->getHeader(), PII); -} - -llvm::CallBase * -CodeGenFunction::addControlledConvergenceToken(llvm::CallBase *Input) { - llvm::Value *ParentToken = - LoopStack.hasInfo() - ? getOrEmitConvergenceLoopToken(()) - : getOrEmitConvergenceEntryToken(Input->getFunction()); - return addConvergenceControlToken(Input, ParentToken); -} - BitTest BitTest::decodeBitTestBuiltin(unsigned BuiltinID) { switch (BuiltinID) { // Main portable variants. @@ -18306,12 +18223,9 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, ArrayRef{Op0}, nullptr, "dx.rsqrt"); } case
[clang] [clang][SPIR-V] Always add convervence intrinsics (PR #88918)
@@ -1109,6 +1124,10 @@ void CodeGenFunction::EmitForStmt(const ForStmt , llvm::BasicBlock *CondBlock = CondDest.getBlock(); EmitBlock(CondBlock); + if (getTarget().getTriple().isSPIRVLogical()) Keenuts wrote: Right, something at the module level, which hides this into a more genering function, like the `shouldEmitRTTI`. Will fix. https://github.com/llvm/llvm-project/pull/88918 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][SPIR-V] Always add convervence intrinsics (PR #88918)
Nathan =?utf-8?q?Gauër?= Message-ID: In-Reply-To: @@ -4824,6 +4824,9 @@ llvm::CallInst *CodeGenFunction::EmitRuntimeCall(llvm::FunctionCallee callee, llvm::CallInst *call = Builder.CreateCall( callee, args, getBundlesForFunclet(callee.getCallee()), name); call->setCallingConv(getRuntimeCC()); + + if (getTarget().getTriple().isSPIRVLogical() && call->isConvergent()) arsenm wrote: Shouldn't have this target check https://github.com/llvm/llvm-project/pull/88918 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][SPIR-V] Always add convervence intrinsics (PR #88918)
Nathan =?utf-8?q?Gauër?= Message-ID: In-Reply-To: @@ -1109,6 +1124,10 @@ void CodeGenFunction::EmitForStmt(const ForStmt , llvm::BasicBlock *CondBlock = CondDest.getBlock(); EmitBlock(CondBlock); + if (getTarget().getTriple().isSPIRVLogical()) arsenm wrote: None of these target checks have anything to do with the target. If you want to conditionally enable these for bringup, these should be hidden in an enableConvergenceTokenEmission or something predicate https://github.com/llvm/llvm-project/pull/88918 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][SPIR-V] Always add convervence intrinsics (PR #88918)
https://github.com/Keenuts updated https://github.com/llvm/llvm-project/pull/88918 From 94d76dcdfac88d1d50fe705406c0280c33766e15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nathan=20Gau=C3=ABr?= Date: Mon, 15 Apr 2024 17:05:40 +0200 Subject: [PATCH 1/2] [clang][SPIR-V] Always add convervence intrinsics MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR #80680 added bits in the codegen to lazily add convergence intrinsics when required. This logic relied on the LoopStack. The issue is when parsing the condition, the loopstack doesn't yet reflect the correct values, as expected since we are not yet in the loop. However, convergence tokens should sometimes already be available. The solution which seemed the simplest is to greedily generate the tokens when we generate SPIR-V. Fixes #88144 Signed-off-by: Nathan Gauër --- clang/lib/CodeGen/CGBuiltin.cpp | 88 + clang/lib/CodeGen/CGCall.cpp | 3 + clang/lib/CodeGen/CGStmt.cpp | 94 ++ clang/lib/CodeGen/CodeGenFunction.cpp | 9 ++ clang/lib/CodeGen/CodeGenFunction.h | 9 +- .../builtins/RWBuffer-constructor.hlsl| 1 - .../CodeGenHLSL/convergence/do.while.hlsl | 90 + clang/test/CodeGenHLSL/convergence/for.hlsl | 121 ++ clang/test/CodeGenHLSL/convergence/while.hlsl | 119 + 9 files changed, 445 insertions(+), 89 deletions(-) create mode 100644 clang/test/CodeGenHLSL/convergence/do.while.hlsl create mode 100644 clang/test/CodeGenHLSL/convergence/for.hlsl create mode 100644 clang/test/CodeGenHLSL/convergence/while.hlsl diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index df7502b8def531..f5d40a1555fcb5 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -1133,91 +1133,8 @@ struct BitTest { static BitTest decodeBitTestBuiltin(unsigned BuiltinID); }; -// Returns the first convergence entry/loop/anchor instruction found in |BB|. -// std::nullptr otherwise. -llvm::IntrinsicInst *getConvergenceToken(llvm::BasicBlock *BB) { - for (auto : *BB) { -auto *II = dyn_cast(); -if (II && isConvergenceControlIntrinsic(II->getIntrinsicID())) - return II; - } - return nullptr; -} - } // namespace -llvm::CallBase * -CodeGenFunction::addConvergenceControlToken(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::emitConvergenceLoopToken(llvm::BasicBlock *BB, - llvm::Value *ParentToken) { - CGBuilderTy::InsertPoint IP = Builder.saveIP(); - Builder.SetInsertPoint(>front()); - auto CB = Builder.CreateIntrinsic( - llvm::Intrinsic::experimental_convergence_loop, {}, {}); - Builder.restoreIP(IP); - - auto I = addConvergenceControlToken(CB, ParentToken); - return cast(I); -} - -llvm::IntrinsicInst * -CodeGenFunction::getOrEmitConvergenceEntryToken(llvm::Function *F) { - auto *BB = >getEntryBlock(); - auto *token = getConvergenceToken(BB); - if (token) -return token; - - // Adding a convergence token requires the function to be marked as - // convergent. - F->setConvergent(); - - CGBuilderTy::InsertPoint IP = Builder.saveIP(); - Builder.SetInsertPoint(>front()); - auto I = Builder.CreateIntrinsic( - llvm::Intrinsic::experimental_convergence_entry, {}, {}); - assert(isa(I)); - Builder.restoreIP(IP); - - return cast(I); -} - -llvm::IntrinsicInst * -CodeGenFunction::getOrEmitConvergenceLoopToken(const LoopInfo *LI) { - assert(LI != nullptr); - - auto *token = getConvergenceToken(LI->getHeader()); - if (token) -return token; - - llvm::IntrinsicInst *PII = - LI->getParent() - ? emitConvergenceLoopToken( -LI->getHeader(), getOrEmitConvergenceLoopToken(LI->getParent())) - : getOrEmitConvergenceEntryToken(LI->getHeader()->getParent()); - - return emitConvergenceLoopToken(LI->getHeader(), PII); -} - -llvm::CallBase * -CodeGenFunction::addControlledConvergenceToken(llvm::CallBase *Input) { - llvm::Value *ParentToken = - LoopStack.hasInfo() - ? getOrEmitConvergenceLoopToken(()) - : getOrEmitConvergenceEntryToken(Input->getFunction()); - return addConvergenceControlToken(Input, ParentToken); -} - BitTest BitTest::decodeBitTestBuiltin(unsigned BuiltinID) { switch (BuiltinID) { // Main portable variants. @@ -18306,12 +18223,9 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, ArrayRef{Op0}, nullptr, "dx.rsqrt"); } case
[clang] [clang][SPIR-V] Always add convervence intrinsics (PR #88918)
@@ -4987,7 +4990,11 @@ class CodeGenFunction : public CodeGenTypeCache { const llvm::Twine = ""); // Adds a convergence_ctrl token to |Input| and emits the required parent // convergence instructions. - llvm::CallBase *addControlledConvergenceToken(llvm::CallBase *Input); + template + CallType *addControlledConvergenceToken(CallType *Input) { +return dyn_cast( Keenuts wrote: Forgot to fix the use, and yes, should be a cast. Bad habits... https://github.com/llvm/llvm-project/pull/88918 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][SPIR-V] Always add convervence intrinsics (PR #88918)
@@ -4824,6 +4824,9 @@ llvm::CallInst *CodeGenFunction::EmitRuntimeCall(llvm::FunctionCallee callee, llvm::CallInst *call = Builder.CreateCall( callee, args, getBundlesForFunclet(callee.getCallee()), name); call->setCallingConv(getRuntimeCC()); + + if (getTarget().getTriple().isSPIRVLogical() && call->isConvergent()) +return dyn_cast(addControlledConvergenceToken(call)); arsenm wrote: can this just be cast<>? https://github.com/llvm/llvm-project/pull/88918 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][SPIR-V] Always add convervence intrinsics (PR #88918)
@@ -4987,7 +4990,11 @@ class CodeGenFunction : public CodeGenTypeCache { const llvm::Twine = ""); // Adds a convergence_ctrl token to |Input| and emits the required parent // convergence instructions. - llvm::CallBase *addControlledConvergenceToken(llvm::CallBase *Input); + template + CallType *addControlledConvergenceToken(CallType *Input) { +return dyn_cast( arsenm wrote: should just be cast? You also have yet another dyn_cast on the use? https://github.com/llvm/llvm-project/pull/88918 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][SPIR-V] Always add convervence intrinsics (PR #88918)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Nathan Gauër (Keenuts) Changes PR #80680 added bits in the codegen to lazily add convergence intrinsics when required. This logic relied on the LoopStack. The issue is when parsing the condition, the loopstack doesn't yet reflect the correct values, as expected since we are not yet in the loop. However, convergence tokens should sometimes already be available. The solution which seemed the simplest is to greedily generate the tokens when we generate SPIR-V. Fixes #88144 --- Patch is 26.72 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/88918.diff 9 Files Affected: - (modified) clang/lib/CodeGen/CGBuiltin.cpp (+1-87) - (modified) clang/lib/CodeGen/CGCall.cpp (+3) - (modified) clang/lib/CodeGen/CGStmt.cpp (+94) - (modified) clang/lib/CodeGen/CodeGenFunction.cpp (+9) - (modified) clang/lib/CodeGen/CodeGenFunction.h (+8-1) - (modified) clang/test/CodeGenHLSL/builtins/RWBuffer-constructor.hlsl (-1) - (added) clang/test/CodeGenHLSL/convergence/do.while.hlsl (+90) - (added) clang/test/CodeGenHLSL/convergence/for.hlsl (+121) - (added) clang/test/CodeGenHLSL/convergence/while.hlsl (+119) ``diff diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index df7502b8def531..f5d40a1555fcb5 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -1133,91 +1133,8 @@ struct BitTest { static BitTest decodeBitTestBuiltin(unsigned BuiltinID); }; -// Returns the first convergence entry/loop/anchor instruction found in |BB|. -// std::nullptr otherwise. -llvm::IntrinsicInst *getConvergenceToken(llvm::BasicBlock *BB) { - for (auto : *BB) { -auto *II = dyn_cast(); -if (II && isConvergenceControlIntrinsic(II->getIntrinsicID())) - return II; - } - return nullptr; -} - } // namespace -llvm::CallBase * -CodeGenFunction::addConvergenceControlToken(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::emitConvergenceLoopToken(llvm::BasicBlock *BB, - llvm::Value *ParentToken) { - CGBuilderTy::InsertPoint IP = Builder.saveIP(); - Builder.SetInsertPoint(>front()); - auto CB = Builder.CreateIntrinsic( - llvm::Intrinsic::experimental_convergence_loop, {}, {}); - Builder.restoreIP(IP); - - auto I = addConvergenceControlToken(CB, ParentToken); - return cast(I); -} - -llvm::IntrinsicInst * -CodeGenFunction::getOrEmitConvergenceEntryToken(llvm::Function *F) { - auto *BB = >getEntryBlock(); - auto *token = getConvergenceToken(BB); - if (token) -return token; - - // Adding a convergence token requires the function to be marked as - // convergent. - F->setConvergent(); - - CGBuilderTy::InsertPoint IP = Builder.saveIP(); - Builder.SetInsertPoint(>front()); - auto I = Builder.CreateIntrinsic( - llvm::Intrinsic::experimental_convergence_entry, {}, {}); - assert(isa(I)); - Builder.restoreIP(IP); - - return cast(I); -} - -llvm::IntrinsicInst * -CodeGenFunction::getOrEmitConvergenceLoopToken(const LoopInfo *LI) { - assert(LI != nullptr); - - auto *token = getConvergenceToken(LI->getHeader()); - if (token) -return token; - - llvm::IntrinsicInst *PII = - LI->getParent() - ? emitConvergenceLoopToken( -LI->getHeader(), getOrEmitConvergenceLoopToken(LI->getParent())) - : getOrEmitConvergenceEntryToken(LI->getHeader()->getParent()); - - return emitConvergenceLoopToken(LI->getHeader(), PII); -} - -llvm::CallBase * -CodeGenFunction::addControlledConvergenceToken(llvm::CallBase *Input) { - llvm::Value *ParentToken = - LoopStack.hasInfo() - ? getOrEmitConvergenceLoopToken(()) - : getOrEmitConvergenceEntryToken(Input->getFunction()); - return addConvergenceControlToken(Input, ParentToken); -} - BitTest BitTest::decodeBitTestBuiltin(unsigned BuiltinID) { switch (BuiltinID) { // Main portable variants. @@ -18306,12 +18223,9 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, ArrayRef{Op0}, nullptr, "dx.rsqrt"); } case Builtin::BI__builtin_hlsl_wave_get_lane_index: { -auto *CI = EmitRuntimeCall(CGM.CreateRuntimeFunction( +return EmitRuntimeCall(CGM.CreateRuntimeFunction( llvm::FunctionType::get(IntTy, {}, false), "__hlsl_wave_get_lane_index", {}, false, true)); -if (getTarget().getTriple().isSPIRVLogical()) - CI = dyn_cast(addControlledConvergenceToken(CI)); -return CI; } } return nullptr; diff --git a/clang/lib/CodeGen/CGCall.cpp
[clang] [clang][SPIR-V] Always add convervence intrinsics (PR #88918)
https://github.com/Keenuts created https://github.com/llvm/llvm-project/pull/88918 PR #80680 added bits in the codegen to lazily add convergence intrinsics when required. This logic relied on the LoopStack. The issue is when parsing the condition, the loopstack doesn't yet reflect the correct values, as expected since we are not yet in the loop. However, convergence tokens should sometimes already be available. The solution which seemed the simplest is to greedily generate the tokens when we generate SPIR-V. Fixes #88144 From 94d76dcdfac88d1d50fe705406c0280c33766e15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nathan=20Gau=C3=ABr?= Date: Mon, 15 Apr 2024 17:05:40 +0200 Subject: [PATCH] [clang][SPIR-V] Always add convervence intrinsics MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR #80680 added bits in the codegen to lazily add convergence intrinsics when required. This logic relied on the LoopStack. The issue is when parsing the condition, the loopstack doesn't yet reflect the correct values, as expected since we are not yet in the loop. However, convergence tokens should sometimes already be available. The solution which seemed the simplest is to greedily generate the tokens when we generate SPIR-V. Fixes #88144 Signed-off-by: Nathan Gauër --- clang/lib/CodeGen/CGBuiltin.cpp | 88 + clang/lib/CodeGen/CGCall.cpp | 3 + clang/lib/CodeGen/CGStmt.cpp | 94 ++ clang/lib/CodeGen/CodeGenFunction.cpp | 9 ++ clang/lib/CodeGen/CodeGenFunction.h | 9 +- .../builtins/RWBuffer-constructor.hlsl| 1 - .../CodeGenHLSL/convergence/do.while.hlsl | 90 + clang/test/CodeGenHLSL/convergence/for.hlsl | 121 ++ clang/test/CodeGenHLSL/convergence/while.hlsl | 119 + 9 files changed, 445 insertions(+), 89 deletions(-) create mode 100644 clang/test/CodeGenHLSL/convergence/do.while.hlsl create mode 100644 clang/test/CodeGenHLSL/convergence/for.hlsl create mode 100644 clang/test/CodeGenHLSL/convergence/while.hlsl diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index df7502b8def531..f5d40a1555fcb5 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -1133,91 +1133,8 @@ struct BitTest { static BitTest decodeBitTestBuiltin(unsigned BuiltinID); }; -// Returns the first convergence entry/loop/anchor instruction found in |BB|. -// std::nullptr otherwise. -llvm::IntrinsicInst *getConvergenceToken(llvm::BasicBlock *BB) { - for (auto : *BB) { -auto *II = dyn_cast(); -if (II && isConvergenceControlIntrinsic(II->getIntrinsicID())) - return II; - } - return nullptr; -} - } // namespace -llvm::CallBase * -CodeGenFunction::addConvergenceControlToken(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::emitConvergenceLoopToken(llvm::BasicBlock *BB, - llvm::Value *ParentToken) { - CGBuilderTy::InsertPoint IP = Builder.saveIP(); - Builder.SetInsertPoint(>front()); - auto CB = Builder.CreateIntrinsic( - llvm::Intrinsic::experimental_convergence_loop, {}, {}); - Builder.restoreIP(IP); - - auto I = addConvergenceControlToken(CB, ParentToken); - return cast(I); -} - -llvm::IntrinsicInst * -CodeGenFunction::getOrEmitConvergenceEntryToken(llvm::Function *F) { - auto *BB = >getEntryBlock(); - auto *token = getConvergenceToken(BB); - if (token) -return token; - - // Adding a convergence token requires the function to be marked as - // convergent. - F->setConvergent(); - - CGBuilderTy::InsertPoint IP = Builder.saveIP(); - Builder.SetInsertPoint(>front()); - auto I = Builder.CreateIntrinsic( - llvm::Intrinsic::experimental_convergence_entry, {}, {}); - assert(isa(I)); - Builder.restoreIP(IP); - - return cast(I); -} - -llvm::IntrinsicInst * -CodeGenFunction::getOrEmitConvergenceLoopToken(const LoopInfo *LI) { - assert(LI != nullptr); - - auto *token = getConvergenceToken(LI->getHeader()); - if (token) -return token; - - llvm::IntrinsicInst *PII = - LI->getParent() - ? emitConvergenceLoopToken( -LI->getHeader(), getOrEmitConvergenceLoopToken(LI->getParent())) - : getOrEmitConvergenceEntryToken(LI->getHeader()->getParent()); - - return emitConvergenceLoopToken(LI->getHeader(), PII); -} - -llvm::CallBase * -CodeGenFunction::addControlledConvergenceToken(llvm::CallBase *Input) { - llvm::Value *ParentToken = - LoopStack.hasInfo() -