OverflowInstAnalysis.cpp 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. //==-- OverflowInstAnalysis.cpp - Utils to fold overflow insts ----*- 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. //
  9. // This file holds routines to help analyse overflow instructions
  10. // and fold them into constants or other overflow instructions
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "llvm/Analysis/OverflowInstAnalysis.h"
  14. #include "llvm/IR/Instructions.h"
  15. #include "llvm/IR/PatternMatch.h"
  16. using namespace llvm;
  17. using namespace llvm::PatternMatch;
  18. bool llvm::isCheckForZeroAndMulWithOverflow(Value *Op0, Value *Op1, bool IsAnd,
  19. Use *&Y) {
  20. ICmpInst::Predicate Pred;
  21. Value *X, *NotOp1;
  22. int XIdx;
  23. IntrinsicInst *II;
  24. if (!match(Op0, m_ICmp(Pred, m_Value(X), m_Zero())))
  25. return false;
  26. /// %Agg = call { i4, i1 } @llvm.[us]mul.with.overflow.i4(i4 %X, i4 %???)
  27. /// %V = extractvalue { i4, i1 } %Agg, 1
  28. auto matchMulOverflowCheck = [X, &II, &XIdx](Value *V) {
  29. auto *Extract = dyn_cast<ExtractValueInst>(V);
  30. // We should only be extracting the overflow bit.
  31. if (!Extract || !Extract->getIndices().equals(1))
  32. return false;
  33. II = dyn_cast<IntrinsicInst>(Extract->getAggregateOperand());
  34. if (!II ||
  35. !match(II, m_CombineOr(m_Intrinsic<Intrinsic::umul_with_overflow>(),
  36. m_Intrinsic<Intrinsic::smul_with_overflow>())))
  37. return false;
  38. if (II->getArgOperand(0) == X)
  39. XIdx = 0;
  40. else if (II->getArgOperand(1) == X)
  41. XIdx = 1;
  42. else
  43. return false;
  44. return true;
  45. };
  46. bool Matched =
  47. (IsAnd && Pred == ICmpInst::Predicate::ICMP_NE &&
  48. matchMulOverflowCheck(Op1)) ||
  49. (!IsAnd && Pred == ICmpInst::Predicate::ICMP_EQ &&
  50. match(Op1, m_Not(m_Value(NotOp1))) && matchMulOverflowCheck(NotOp1));
  51. if (!Matched)
  52. return false;
  53. Y = &II->getArgOperandUse(!XIdx);
  54. return true;
  55. }
  56. bool llvm::isCheckForZeroAndMulWithOverflow(Value *Op0, Value *Op1,
  57. bool IsAnd) {
  58. Use *Y;
  59. return isCheckForZeroAndMulWithOverflow(Op0, Op1, IsAnd, Y);
  60. }