1 //==-- OverflowInstAnalysis.cpp - Utils to fold overflow insts ----*- 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 file holds routines to help analyse overflow instructions
10 // and fold them into constants or other overflow instructions
12 //===----------------------------------------------------------------------===//
14 #include "llvm/Analysis/OverflowInstAnalysis.h"
15 #include "llvm/IR/Instructions.h"
16 #include "llvm/IR/PatternMatch.h"
19 using namespace llvm::PatternMatch
;
21 bool llvm::isCheckForZeroAndMulWithOverflow(Value
*Op0
, Value
*Op1
, bool IsAnd
,
28 if (!match(Op0
, m_ICmp(Pred
, m_Value(X
), m_Zero())))
31 /// %Agg = call { i4, i1 } @llvm.[us]mul.with.overflow.i4(i4 %X, i4 %???)
32 /// %V = extractvalue { i4, i1 } %Agg, 1
33 auto matchMulOverflowCheck
= [X
, &II
, &XIdx
](Value
*V
) {
34 auto *Extract
= dyn_cast
<ExtractValueInst
>(V
);
35 // We should only be extracting the overflow bit.
36 if (!Extract
|| !Extract
->getIndices().equals(1))
39 II
= dyn_cast
<IntrinsicInst
>(Extract
->getAggregateOperand());
41 !match(II
, m_CombineOr(m_Intrinsic
<Intrinsic::umul_with_overflow
>(),
42 m_Intrinsic
<Intrinsic::smul_with_overflow
>())))
45 if (II
->getArgOperand(0) == X
)
47 else if (II
->getArgOperand(1) == X
)
55 (IsAnd
&& Pred
== ICmpInst::Predicate::ICMP_NE
&&
56 matchMulOverflowCheck(Op1
)) ||
57 (!IsAnd
&& Pred
== ICmpInst::Predicate::ICMP_EQ
&&
58 match(Op1
, m_Not(m_Value(NotOp1
))) && matchMulOverflowCheck(NotOp1
));
63 Y
= &II
->getArgOperandUse(!XIdx
);
67 bool llvm::isCheckForZeroAndMulWithOverflow(Value
*Op0
, Value
*Op1
,
70 return isCheckForZeroAndMulWithOverflow(Op0
, Op1
, IsAnd
, Y
);