xref: /llvm-project/llvm/lib/Analysis/GuardUtils.cpp (revision bd374b27cc33567b0a0522ee511fc1ea9f0bb1df)
1 //===-- GuardUtils.cpp - Utils for work with guards -------------*- 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 //===----------------------------------------------------------------------===//
8 // Utils that are used to perform analyzes related to guards and their
9 // conditions.
10 //===----------------------------------------------------------------------===//
11 
12 #include "llvm/Analysis/GuardUtils.h"
13 #include "llvm/IR/PatternMatch.h"
14 
15 using namespace llvm;
16 
17 bool llvm::isGuard(const User *U) {
18   using namespace llvm::PatternMatch;
19   return match(U, m_Intrinsic<Intrinsic::experimental_guard>());
20 }
21 
22 bool llvm::isGuardAsWidenableBranch(const User *U) {
23   using namespace llvm::PatternMatch;
24   const BranchInst *BI = dyn_cast<BranchInst>(U);
25 
26   // We are looking for the following pattern:
27   //   br i1 %cond & widenable_condition(), label %guarded, label %deopt
28   // deopt:
29   //   <non-side-effecting instructions>
30   //   deoptimize()
31   if (!BI || !BI->isConditional())
32     return false;
33 
34   if (!match(BI->getCondition(),
35              m_And(m_Value(),
36                    m_Intrinsic<Intrinsic::experimental_widenable_condition>())))
37     return false;
38 
39   const BasicBlock *DeoptBlock = BI->getSuccessor(1);
40   for (auto &Insn : *DeoptBlock) {
41     if (match(&Insn, m_Intrinsic<Intrinsic::experimental_deoptimize>()))
42       return true;
43     if (Insn.mayHaveSideEffects())
44       return false;
45   }
46   return false;
47 }
48