1 //===-- SPIRVStripConvergentIntrinsics.cpp ----------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This pass trims convergence intrinsics as those were only useful when
10 // modifying the CFG during IR passes.
12 //===----------------------------------------------------------------------===//
15 #include "SPIRVSubtarget.h"
16 #include "SPIRVTargetMachine.h"
17 #include "SPIRVUtils.h"
18 #include "llvm/CodeGen/IntrinsicLowering.h"
19 #include "llvm/IR/IRBuilder.h"
20 #include "llvm/IR/IntrinsicInst.h"
21 #include "llvm/IR/Intrinsics.h"
22 #include "llvm/IR/IntrinsicsSPIRV.h"
23 #include "llvm/Transforms/Utils/Cloning.h"
24 #include "llvm/Transforms/Utils/LowerMemIntrinsics.h"
29 void initializeSPIRVStripConvergentIntrinsicsPass(PassRegistry
&);
32 class SPIRVStripConvergentIntrinsics
: public FunctionPass
{
36 SPIRVStripConvergentIntrinsics() : FunctionPass(ID
) {
37 initializeSPIRVStripConvergentIntrinsicsPass(
38 *PassRegistry::getPassRegistry());
41 virtual bool runOnFunction(Function
&F
) override
{
42 DenseSet
<Instruction
*> ToRemove
;
44 for (BasicBlock
&BB
: F
) {
45 for (Instruction
&I
: BB
) {
46 if (auto *II
= dyn_cast
<IntrinsicInst
>(&I
)) {
47 if (II
->getIntrinsicID() !=
48 Intrinsic::experimental_convergence_entry
&&
49 II
->getIntrinsicID() !=
50 Intrinsic::experimental_convergence_loop
&&
51 II
->getIntrinsicID() !=
52 Intrinsic::experimental_convergence_anchor
) {
56 II
->replaceAllUsesWith(UndefValue::get(II
->getType()));
58 } else if (auto *CI
= dyn_cast
<CallInst
>(&I
)) {
59 auto OB
= CI
->getOperandBundle(LLVMContext::OB_convergencectrl
);
63 auto *NewCall
= CallBase::removeOperandBundle(
64 CI
, LLVMContext::OB_convergencectrl
, CI
);
65 NewCall
->copyMetadata(*CI
);
66 CI
->replaceAllUsesWith(NewCall
);
72 // All usages must be removed before their definition is removed.
73 for (Instruction
*I
: ToRemove
)
76 return ToRemove
.size() != 0;
80 char SPIRVStripConvergentIntrinsics::ID
= 0;
81 INITIALIZE_PASS(SPIRVStripConvergentIntrinsics
, "strip-convergent-intrinsics",
82 "SPIRV strip convergent intrinsics", false, false)
84 FunctionPass
*llvm::createSPIRVStripConvergenceIntrinsicsPass() {
85 return new SPIRVStripConvergentIntrinsics();