1 //===-- GuardUtils.cpp - Utils for work with guards -------------*- 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 //===----------------------------------------------------------------------===//
8 // Utils that are used to perform analyzes related to guards and their
10 //===----------------------------------------------------------------------===//
12 #include "llvm/Analysis/GuardUtils.h"
13 #include "llvm/IR/PatternMatch.h"
16 using namespace llvm::PatternMatch
;
18 bool llvm::isGuard(const User
*U
) {
19 return match(U
, m_Intrinsic
<Intrinsic::experimental_guard
>());
22 bool llvm::isWidenableBranch(const User
*U
) {
23 Value
*Condition
, *WidenableCondition
;
24 BasicBlock
*GuardedBB
, *DeoptBB
;
25 return parseWidenableBranch(U
, Condition
, WidenableCondition
, GuardedBB
,
29 bool llvm::isGuardAsWidenableBranch(const User
*U
) {
30 Value
*Condition
, *WidenableCondition
;
31 BasicBlock
*GuardedBB
, *DeoptBB
;
32 if (!parseWidenableBranch(U
, Condition
, WidenableCondition
, GuardedBB
,
35 for (auto &Insn
: *DeoptBB
) {
36 if (match(&Insn
, m_Intrinsic
<Intrinsic::experimental_deoptimize
>()))
38 if (Insn
.mayHaveSideEffects())
44 bool llvm::parseWidenableBranch(const User
*U
, Value
*&Condition
,
45 Value
*&WidenableCondition
,
46 BasicBlock
*&IfTrueBB
, BasicBlock
*&IfFalseBB
) {
49 if (parseWidenableBranch(const_cast<User
*>(U
), C
, WC
, IfTrueBB
, IfFalseBB
)) {
53 Condition
= ConstantInt::getTrue(IfTrueBB
->getContext());
54 WidenableCondition
= WC
->get();
60 bool llvm::parseWidenableBranch(User
*U
, Use
*&C
,Use
*&WC
,
61 BasicBlock
*&IfTrueBB
, BasicBlock
*&IfFalseBB
) {
63 auto *BI
= dyn_cast
<BranchInst
>(U
);
64 if (!BI
|| !BI
->isConditional())
66 auto *Cond
= BI
->getCondition();
67 if (!Cond
->hasOneUse())
70 IfTrueBB
= BI
->getSuccessor(0);
71 IfFalseBB
= BI
->getSuccessor(1);
73 if (match(Cond
, m_Intrinsic
<Intrinsic::experimental_widenable_condition
>())) {
74 WC
= &BI
->getOperandUse(0);
79 // Check for two cases:
80 // 1) br (i1 (and A, WC())), label %IfTrue, label %IfFalse
81 // 2) br (i1 (and WC(), B)), label %IfTrue, label %IfFalse
82 // We do not check for more generalized and trees as we should canonicalize
83 // to the form above in instcombine. (TODO)
85 if (!match(Cond
, m_And(m_Value(A
), m_Value(B
))))
87 auto *And
= dyn_cast
<Instruction
>(Cond
);
89 // Could be a constexpr
92 if (match(A
, m_Intrinsic
<Intrinsic::experimental_widenable_condition
>()) &&
94 WC
= &And
->getOperandUse(0);
95 C
= &And
->getOperandUse(1);
99 if (match(B
, m_Intrinsic
<Intrinsic::experimental_widenable_condition
>()) &&
101 WC
= &And
->getOperandUse(1);
102 C
= &And
->getOperandUse(0);