[clang] Add test for CWG190 "Layout-compatible POD-struct types" (#121668)
[llvm-project.git] / llvm / lib / IR / ConvergenceVerifier.cpp
blob6708f85819df7f66d46cfa5f8930f4b79a359df2
1 //===- ConvergenceVerifier.cpp - Verify convergence control -----*- C++ -*-===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
9 #include "llvm/IR/ConvergenceVerifier.h"
10 #include "llvm/IR/Dominators.h"
11 #include "llvm/IR/GenericConvergenceVerifierImpl.h"
12 #include "llvm/IR/Instructions.h"
13 #include "llvm/IR/SSAContext.h"
15 using namespace llvm;
17 template <>
18 auto GenericConvergenceVerifier<SSAContext>::getConvOp(const Instruction &I)
19 -> ConvOpKind {
20 const auto *CB = dyn_cast<CallBase>(&I);
21 if (!CB)
22 return CONV_NONE;
23 switch (CB->getIntrinsicID()) {
24 default:
25 return CONV_NONE;
26 case Intrinsic::experimental_convergence_anchor:
27 return CONV_ANCHOR;
28 case Intrinsic::experimental_convergence_entry:
29 return CONV_ENTRY;
30 case Intrinsic::experimental_convergence_loop:
31 return CONV_LOOP;
35 template <>
36 void GenericConvergenceVerifier<SSAContext>::checkConvergenceTokenProduced(
37 const Instruction &I) {
38 return;
41 template <>
42 const Instruction *
43 GenericConvergenceVerifier<SSAContext>::findAndCheckConvergenceTokenUsed(
44 const Instruction &I) {
45 auto *CB = dyn_cast<CallBase>(&I);
46 if (!CB)
47 return nullptr;
49 unsigned Count =
50 CB->countOperandBundlesOfType(LLVMContext::OB_convergencectrl);
51 CheckOrNull(Count <= 1,
52 "The 'convergencectrl' bundle can occur at most once on a call",
53 {Context.print(CB)});
54 if (!Count)
55 return nullptr;
57 auto Bundle = CB->getOperandBundle(LLVMContext::OB_convergencectrl);
58 CheckOrNull(Bundle->Inputs.size() == 1 &&
59 Bundle->Inputs[0]->getType()->isTokenTy(),
60 "The 'convergencectrl' bundle requires exactly one token use.",
61 {Context.print(CB)});
62 auto *Token = Bundle->Inputs[0].get();
63 auto *Def = dyn_cast<Instruction>(Token);
65 CheckOrNull(Def && getConvOp(*Def) != CONV_NONE,
66 "Convergence control tokens can only be produced by calls to the "
67 "convergence control intrinsics.",
68 {Context.print(Token), Context.print(&I)});
70 if (Def)
71 Tokens[&I] = Def;
73 return Def;
76 template <>
77 bool GenericConvergenceVerifier<SSAContext>::isInsideConvergentFunction(
78 const Instruction &I) {
79 auto *F = I.getFunction();
80 return F->isConvergent();
83 template <>
84 bool GenericConvergenceVerifier<SSAContext>::isConvergent(
85 const Instruction &I) {
86 if (auto *CB = dyn_cast<CallBase>(&I)) {
87 return CB->isConvergent();
89 return false;
92 template class llvm::GenericConvergenceVerifier<SSAContext>;