llvm/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp

//===- InstCombineAddSub.cpp ------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements the visit functions for add, fadd, sub, and fsub.
//
//===----------------------------------------------------------------------===//

#include "InstCombineInternal.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Operator.h"
#include "llvm/IR/PatternMatch.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Value.h"
#include "llvm/Support/AlignOf.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/KnownBits.h"
#include "llvm/Transforms/InstCombine/InstCombiner.h"
#include <cassert>
#include <utility>

usingnamespacellvm;
usingnamespacePatternMatch;

#define DEBUG_TYPE

namespace {

  /// Class representing coefficient of floating-point addend.
  /// This class needs to be highly efficient, which is especially true for
  /// the constructor. As of I write this comment, the cost of the default
  /// constructor is merely 4-byte-store-zero (Assuming compiler is able to
  /// perform write-merging).
  ///
  class FAddendCoef {};

  /// FAddend is used to represent floating-point addend. An addend is
  /// represented as <C, V>, where the V is a symbolic value, and C is a
  /// constant coefficient. A constant addend is represented as <C, 0>.
  class FAddend {};

  /// FAddCombine is the class for optimizing an unsafe fadd/fsub along
  /// with its neighboring at most two instructions.
  ///
  class FAddCombine {};

} // end anonymous namespace

//===----------------------------------------------------------------------===//
//
// Implementation of
//    {FAddendCoef, FAddend, FAddition, FAddCombine}.
//
//===----------------------------------------------------------------------===//
FAddendCoef::~FAddendCoef() {}

void FAddendCoef::set(const APFloat& C) {}

void FAddendCoef::convertToFpType(const fltSemantics &Sem) {}

APFloat FAddendCoef::createAPFloatFromInt(const fltSemantics &Sem, int Val) {}

void FAddendCoef::operator=(const FAddendCoef &That) {}

void FAddendCoef::operator+=(const FAddendCoef &That) {}

void FAddendCoef::operator*=(const FAddendCoef &That) {}

void FAddendCoef::negate() {}

Value *FAddendCoef::getValue(Type *Ty) const {}

// The definition of <Val>     Addends
// =========================================
//  A + B                     <1, A>, <1,B>
//  A - B                     <1, A>, <1,B>
//  0 - B                     <-1, B>
//  C * A,                    <C, A>
//  A + C                     <1, A> <C, NULL>
//  0 +/- 0                   <0, NULL> (corner case)
//
// Legend: A and B are not constant, C is constant
unsigned FAddend::drillValueDownOneStep
  (Value *Val, FAddend &Addend0, FAddend &Addend1) {}

// Try to break *this* addend into two addends. e.g. Suppose this addend is
// <2.3, V>, and V = X + Y, by calling this function, we obtain two addends,
// i.e. <2.3, X> and <2.3, Y>.
unsigned FAddend::drillAddendDownOneStep
  (FAddend &Addend0, FAddend &Addend1) const {}

Value *FAddCombine::simplify(Instruction *I) {}

Value *FAddCombine::simplifyFAdd(AddendVect& Addends, unsigned InstrQuota) {}

Value *FAddCombine::createNaryFAdd
  (const AddendVect &Opnds, unsigned InstrQuota) {}

Value *FAddCombine::createFSub(Value *Opnd0, Value *Opnd1) {}

Value *FAddCombine::createFNeg(Value *V) {}

Value *FAddCombine::createFAdd(Value *Opnd0, Value *Opnd1) {}

Value *FAddCombine::createFMul(Value *Opnd0, Value *Opnd1) {}

void FAddCombine::createInstPostProc(Instruction *NewInstr, bool NoNumber) {}

// Return the number of instruction needed to emit the N-ary addition.
// NOTE: Keep this function in sync with createAddendVal().
unsigned FAddCombine::calcInstrNumber(const AddendVect &Opnds) {}

// Input Addend        Value           NeedNeg(output)
// ================================================================
// Constant C          C               false
// <+/-1, V>           V               coefficient is -1
// <2/-2, V>          "fadd V, V"      coefficient is -2
// <C, V>             "fmul V, C"      false
//
// NOTE: Keep this function in sync with FAddCombine::calcInstrNumber.
Value *FAddCombine::createAddendVal(const FAddend &Opnd, bool &NeedNeg) {}

// Checks if any operand is negative and we can convert add to sub.
// This function checks for following negative patterns
//   ADD(XOR(OR(Z, NOT(C)), C)), 1) == NEG(AND(Z, C))
//   ADD(XOR(AND(Z, C), C), 1) == NEG(OR(Z, ~C))
//   XOR(AND(Z, C), (C + 1)) == NEG(OR(Z, ~C)) if C is even
static Value *checkForNegativeOperand(BinaryOperator &I,
                                      InstCombiner::BuilderTy &Builder) {}

/// Wrapping flags may allow combining constants separated by an extend.
static Instruction *foldNoWrapAdd(BinaryOperator &Add,
                                  InstCombiner::BuilderTy &Builder) {}

Instruction *InstCombinerImpl::foldAddWithConstant(BinaryOperator &Add) {}

// match variations of a^2 + 2*a*b + b^2
//
// to reuse the code between the FP and Int versions, the instruction OpCodes
//  and constant types have been turned into template parameters.
//
// Mul2Rhs: The constant to perform the multiplicative equivalent of X*2 with;
//  should be `m_SpecificFP(2.0)` for FP and `m_SpecificInt(1)` for Int
//  (we're matching `X<<1` instead of `X*2` for Int)
template <bool FP, typename Mul2Rhs>
static bool matchesSquareSum(BinaryOperator &I, Mul2Rhs M2Rhs, Value *&A,
                             Value *&B) {}

// Fold integer variations of a^2 + 2*a*b + b^2 -> (a + b)^2
Instruction *InstCombinerImpl::foldSquareSumInt(BinaryOperator &I) {}

// Fold floating point variations of a^2 + 2*a*b + b^2 -> (a + b)^2
// Requires `nsz` and `reassoc`.
Instruction *InstCombinerImpl::foldSquareSumFP(BinaryOperator &I) {}

// Matches multiplication expression Op * C where C is a constant. Returns the
// constant value in C and the other operand in Op. Returns true if such a
// match is found.
static bool MatchMul(Value *E, Value *&Op, APInt &C) {}

// Matches remainder expression Op % C where C is a constant. Returns the
// constant value in C and the other operand in Op. Returns the signedness of
// the remainder operation in IsSigned. Returns true if such a match is
// found.
static bool MatchRem(Value *E, Value *&Op, APInt &C, bool &IsSigned) {}

// Matches division expression Op / C with the given signedness as indicated
// by IsSigned, where C is a constant. Returns the constant value in C and the
// other operand in Op. Returns true if such a match is found.
static bool MatchDiv(Value *E, Value *&Op, APInt &C, bool IsSigned) {}

// Returns whether C0 * C1 with the given signedness overflows.
static bool MulWillOverflow(APInt &C0, APInt &C1, bool IsSigned) {}

// Simplifies X % C0 + (( X / C0 ) % C1) * C0 to X % (C0 * C1), where (C0 * C1)
// does not overflow.
// Simplifies (X / C0) * C1 + (X % C0) * C2 to
// (X / C0) * (C1 - C2 * C0) + X * C2
Value *InstCombinerImpl::SimplifyAddWithRemainder(BinaryOperator &I) {}

/// Fold
///   (1 << NBits) - 1
/// Into:
///   ~(-(1 << NBits))
/// Because a 'not' is better for bit-tracking analysis and other transforms
/// than an 'add'. The new shl is always nsw, and is nuw if old `and` was.
static Instruction *canonicalizeLowbitMask(BinaryOperator &I,
                                           InstCombiner::BuilderTy &Builder) {}

static Instruction *foldToUnsignedSaturatedAdd(BinaryOperator &I) {}

// Transform:
//  (add A, (shl (neg B), Y))
//      -> (sub A, (shl B, Y))
static Instruction *combineAddSubWithShlAddSub(InstCombiner::BuilderTy &Builder,
                                               const BinaryOperator &I) {}

/// Try to reduce signed division by power-of-2 to an arithmetic shift right.
static Instruction *foldAddToAshr(BinaryOperator &Add) {}

Instruction *InstCombinerImpl::foldAddLikeCommutative(Value *LHS, Value *RHS,
                                                      bool NSW, bool NUW) {}

Instruction *InstCombinerImpl::
    canonicalizeCondSignextOfHighBitExtractToSignextHighBitExtract(
        BinaryOperator &I) {}

/// This is a specialization of a more general transform from
/// foldUsingDistributiveLaws. If that code can be made to work optimally
/// for multi-use cases or propagating nsw/nuw, then we would not need this.
static Instruction *factorizeMathWithShlOps(BinaryOperator &I,
                                            InstCombiner::BuilderTy &Builder) {}

/// Reduce a sequence of masked half-width multiplies to a single multiply.
/// ((XLow * YHigh) + (YLow * XHigh)) << HalfBits) + (XLow * YLow) --> X * Y
static Instruction *foldBoxMultiply(BinaryOperator &I) {}

Instruction *InstCombinerImpl::visitAdd(BinaryOperator &I) {}

/// Eliminate an op from a linear interpolation (lerp) pattern.
static Instruction *factorizeLerp(BinaryOperator &I,
                                  InstCombiner::BuilderTy &Builder) {}

/// Factor a common operand out of fadd/fsub of fmul/fdiv.
static Instruction *factorizeFAddFSub(BinaryOperator &I,
                                      InstCombiner::BuilderTy &Builder) {}

Instruction *InstCombinerImpl::visitFAdd(BinaryOperator &I) {}

/// Optimize pointer differences into the same array into a size.  Consider:
///  &A[10] - &A[0]: we should compile this to "10".  LHS/RHS are the pointer
/// operands to the ptrtoint instructions for the LHS/RHS of the subtract.
Value *InstCombinerImpl::OptimizePointerDifference(Value *LHS, Value *RHS,
                                                   Type *Ty, bool IsNUW) {}

static Instruction *foldSubOfMinMax(BinaryOperator &I,
                                    InstCombiner::BuilderTy &Builder) {}

Instruction *InstCombinerImpl::visitSub(BinaryOperator &I) {}

/// This eliminates floating-point negation in either 'fneg(X)' or
/// 'fsub(-0.0, X)' form by combining into a constant operand.
static Instruction *foldFNegIntoConstant(Instruction &I, const DataLayout &DL) {}

Instruction *InstCombinerImpl::hoistFNegAboveFMulFDiv(Value *FNegOp,
                                                      Instruction &FMFSource) {}

Instruction *InstCombinerImpl::visitFNeg(UnaryOperator &I) {}

Instruction *InstCombinerImpl::visitFSub(BinaryOperator &I) {}