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/Constants.h"
16 #include "llvm/IR/Instructions.h"
17 #include "llvm/IR/PatternMatch.h"
20 using namespace llvm::PatternMatch
;
22 bool llvm::isCheckForZeroAndMulWithOverflow(Value
*Op0
, Value
*Op1
, bool IsAnd
,
24 ICmpInst::Predicate Pred
;
29 if (!match(Op0
, m_ICmp(Pred
, m_Value(X
), m_Zero())))
32 /// %Agg = call { i4, i1 } @llvm.[us]mul.with.overflow.i4(i4 %X, i4 %???)
33 /// %V = extractvalue { i4, i1 } %Agg, 1
34 auto matchMulOverflowCheck
= [X
, &II
, &XIdx
](Value
*V
) {
35 auto *Extract
= dyn_cast
<ExtractValueInst
>(V
);
36 // We should only be extracting the overflow bit.
37 if (!Extract
|| !Extract
->getIndices().equals(1))
40 II
= dyn_cast
<IntrinsicInst
>(Extract
->getAggregateOperand());
42 !match(II
, m_CombineOr(m_Intrinsic
<Intrinsic::umul_with_overflow
>(),
43 m_Intrinsic
<Intrinsic::smul_with_overflow
>())))
46 if (II
->getArgOperand(0) == X
)
48 else if (II
->getArgOperand(1) == X
)
56 (IsAnd
&& Pred
== ICmpInst::Predicate::ICMP_NE
&&
57 matchMulOverflowCheck(Op1
)) ||
58 (!IsAnd
&& Pred
== ICmpInst::Predicate::ICMP_EQ
&&
59 match(Op1
, m_Not(m_Value(NotOp1
))) && matchMulOverflowCheck(NotOp1
));
64 Y
= &II
->getArgOperandUse(!XIdx
);
68 bool llvm::isCheckForZeroAndMulWithOverflow(Value
*Op0
, Value
*Op1
,
71 return isCheckForZeroAndMulWithOverflow(Op0
, Op1
, IsAnd
, Y
);