#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Analysis/TargetFolder.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/Analysis/VectorUtils.h"
#include "llvm/Config/config.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/ConstantFold.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/IntrinsicsAArch64.h"
#include "llvm/IR/IntrinsicsAMDGPU.h"
#include "llvm/IR/IntrinsicsARM.h"
#include "llvm/IR/IntrinsicsWebAssembly.h"
#include "llvm/IR/IntrinsicsX86.h"
#include "llvm/IR/Operator.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Value.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/KnownBits.h"
#include "llvm/Support/MathExtras.h"
#include <cassert>
#include <cerrno>
#include <cfenv>
#include <cmath>
#include <cstdint>
usingnamespacellvm;
namespace {
static Constant *foldConstVectorToAPInt(APInt &Result, Type *DestTy,
Constant *C, Type *SrcEltTy,
unsigned NumSrcElts,
const DataLayout &DL) { … }
Constant *FoldBitCast(Constant *C, Type *DestTy, const DataLayout &DL) { … }
}
bool llvm::IsConstantOffsetFromGlobal(Constant *C, GlobalValue *&GV,
APInt &Offset, const DataLayout &DL,
DSOLocalEquivalent **DSOEquiv) { … }
Constant *llvm::ConstantFoldLoadThroughBitcast(Constant *C, Type *DestTy,
const DataLayout &DL) { … }
namespace {
bool ReadDataFromGlobal(Constant *C, uint64_t ByteOffset, unsigned char *CurPtr,
unsigned BytesLeft, const DataLayout &DL) { … }
Constant *FoldReinterpretLoadFromConst(Constant *C, Type *LoadTy,
int64_t Offset, const DataLayout &DL) { … }
}
Constant *llvm::ReadByteArrayFromGlobal(const GlobalVariable *GV,
uint64_t Offset) { … }
Constant *getConstantAtOffset(Constant *Base, APInt Offset,
const DataLayout &DL) { … }
Constant *llvm::ConstantFoldLoadFromConst(Constant *C, Type *Ty,
const APInt &Offset,
const DataLayout &DL) { … }
Constant *llvm::ConstantFoldLoadFromConst(Constant *C, Type *Ty,
const DataLayout &DL) { … }
Constant *llvm::ConstantFoldLoadFromConstPtr(Constant *C, Type *Ty,
APInt Offset,
const DataLayout &DL) { … }
Constant *llvm::ConstantFoldLoadFromConstPtr(Constant *C, Type *Ty,
const DataLayout &DL) { … }
Constant *llvm::ConstantFoldLoadFromUniformValue(Constant *C, Type *Ty,
const DataLayout &DL) { … }
namespace {
Constant *SymbolicallyEvaluateBinop(unsigned Opc, Constant *Op0, Constant *Op1,
const DataLayout &DL) { … }
Constant *CastGEPIndices(Type *SrcElemTy, ArrayRef<Constant *> Ops,
Type *ResultTy, GEPNoWrapFlags NW,
std::optional<ConstantRange> InRange,
const DataLayout &DL, const TargetLibraryInfo *TLI) { … }
Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP,
ArrayRef<Constant *> Ops,
const DataLayout &DL,
const TargetLibraryInfo *TLI) { … }
Constant *ConstantFoldInstOperandsImpl(const Value *InstOrCE, unsigned Opcode,
ArrayRef<Constant *> Ops,
const DataLayout &DL,
const TargetLibraryInfo *TLI,
bool AllowNonDeterministic) { … }
}
namespace {
Constant *
ConstantFoldConstantImpl(const Constant *C, const DataLayout &DL,
const TargetLibraryInfo *TLI,
SmallDenseMap<Constant *, Constant *> &FoldedOps) { … }
}
Constant *llvm::ConstantFoldInstruction(Instruction *I, const DataLayout &DL,
const TargetLibraryInfo *TLI) { … }
Constant *llvm::ConstantFoldConstant(const Constant *C, const DataLayout &DL,
const TargetLibraryInfo *TLI) { … }
Constant *llvm::ConstantFoldInstOperands(Instruction *I,
ArrayRef<Constant *> Ops,
const DataLayout &DL,
const TargetLibraryInfo *TLI,
bool AllowNonDeterministic) { … }
Constant *llvm::ConstantFoldCompareInstOperands(
unsigned IntPredicate, Constant *Ops0, Constant *Ops1, const DataLayout &DL,
const TargetLibraryInfo *TLI, const Instruction *I) { … }
Constant *llvm::ConstantFoldUnaryOpOperand(unsigned Opcode, Constant *Op,
const DataLayout &DL) { … }
Constant *llvm::ConstantFoldBinaryOpOperands(unsigned Opcode, Constant *LHS,
Constant *RHS,
const DataLayout &DL) { … }
Constant *llvm::FlushFPConstant(Constant *Operand, const Instruction *I,
bool IsOutput) { … }
Constant *llvm::ConstantFoldFPInstOperands(unsigned Opcode, Constant *LHS,
Constant *RHS, const DataLayout &DL,
const Instruction *I,
bool AllowNonDeterministic) { … }
Constant *llvm::ConstantFoldCastOperand(unsigned Opcode, Constant *C,
Type *DestTy, const DataLayout &DL) { … }
Constant *llvm::ConstantFoldIntegerCast(Constant *C, Type *DestTy,
bool IsSigned, const DataLayout &DL) { … }
bool llvm::canConstantFoldCallTo(const CallBase *Call, const Function *F) { … }
namespace {
Constant *GetConstantFoldFPValue(double V, Type *Ty) { … }
#if defined(HAS_IEE754_FLOAT128) && defined(HAS_LOGF128)
Constant *GetConstantFoldFPValue128(float128 V, Type *Ty) {
if (Ty->isFP128Ty())
return ConstantFP::get(Ty, V);
llvm_unreachable("Can only constant fold fp128");
}
#endif
inline void llvm_fenv_clearexcept() { … }
inline bool llvm_fenv_testexcept() { … }
Constant *ConstantFoldFP(double (*NativeFP)(double), const APFloat &V,
Type *Ty) { … }
#if defined(HAS_IEE754_FLOAT128) && defined(HAS_LOGF128)
Constant *ConstantFoldFP128(float128 (*NativeFP)(float128), const APFloat &V,
Type *Ty) {
llvm_fenv_clearexcept();
float128 Result = NativeFP(V.convertToQuad());
if (llvm_fenv_testexcept()) {
llvm_fenv_clearexcept();
return nullptr;
}
return GetConstantFoldFPValue128(Result, Ty);
}
#endif
Constant *ConstantFoldBinaryFP(double (*NativeFP)(double, double),
const APFloat &V, const APFloat &W, Type *Ty) { … }
Constant *constantFoldVectorReduce(Intrinsic::ID IID, Constant *Op) { … }
Constant *ConstantFoldSSEConvertToInt(const APFloat &Val, bool roundTowardZero,
Type *Ty, bool IsSigned) { … }
double getValueAsDouble(ConstantFP *Op) { … }
static bool getConstIntOrUndef(Value *Op, const APInt *&C) { … }
static bool mayFoldConstrained(ConstrainedFPIntrinsic *CI,
APFloat::opStatus St) { … }
static RoundingMode
getEvaluationRoundingMode(const ConstrainedFPIntrinsic *CI) { … }
static Constant *constantFoldCanonicalize(const Type *Ty, const CallBase *CI,
const APFloat &Src) { … }
static Constant *ConstantFoldScalarCall1(StringRef Name,
Intrinsic::ID IntrinsicID,
Type *Ty,
ArrayRef<Constant *> Operands,
const TargetLibraryInfo *TLI,
const CallBase *Call) { … }
static Constant *evaluateCompare(const APFloat &Op1, const APFloat &Op2,
const ConstrainedFPIntrinsic *Call) { … }
static Constant *ConstantFoldLibCall2(StringRef Name, Type *Ty,
ArrayRef<Constant *> Operands,
const TargetLibraryInfo *TLI) { … }
static Constant *ConstantFoldIntrinsicCall2(Intrinsic::ID IntrinsicID, Type *Ty,
ArrayRef<Constant *> Operands,
const CallBase *Call) { … }
static APFloat ConstantFoldAMDGCNCubeIntrinsic(Intrinsic::ID IntrinsicID,
const APFloat &S0,
const APFloat &S1,
const APFloat &S2) { … }
static Constant *ConstantFoldAMDGCNPermIntrinsic(ArrayRef<Constant *> Operands,
Type *Ty) { … }
static Constant *ConstantFoldScalarCall3(StringRef Name,
Intrinsic::ID IntrinsicID,
Type *Ty,
ArrayRef<Constant *> Operands,
const TargetLibraryInfo *TLI,
const CallBase *Call) { … }
static Constant *ConstantFoldScalarCall(StringRef Name,
Intrinsic::ID IntrinsicID,
Type *Ty,
ArrayRef<Constant *> Operands,
const TargetLibraryInfo *TLI,
const CallBase *Call) { … }
static Constant *ConstantFoldFixedVectorCall(
StringRef Name, Intrinsic::ID IntrinsicID, FixedVectorType *FVTy,
ArrayRef<Constant *> Operands, const DataLayout &DL,
const TargetLibraryInfo *TLI, const CallBase *Call) { … }
static Constant *ConstantFoldScalableVectorCall(
StringRef Name, Intrinsic::ID IntrinsicID, ScalableVectorType *SVTy,
ArrayRef<Constant *> Operands, const DataLayout &DL,
const TargetLibraryInfo *TLI, const CallBase *Call) { … }
static std::pair<Constant *, Constant *>
ConstantFoldScalarFrexpCall(Constant *Op, Type *IntTy) { … }
static Constant *
ConstantFoldStructCall(StringRef Name, Intrinsic::ID IntrinsicID,
StructType *StTy, ArrayRef<Constant *> Operands,
const DataLayout &DL, const TargetLibraryInfo *TLI,
const CallBase *Call) { … }
}
Constant *llvm::ConstantFoldBinaryIntrinsic(Intrinsic::ID ID, Constant *LHS,
Constant *RHS, Type *Ty,
Instruction *FMFSource) { … }
Constant *llvm::ConstantFoldCall(const CallBase *Call, Function *F,
ArrayRef<Constant *> Operands,
const TargetLibraryInfo *TLI,
bool AllowNonDeterministic) { … }
bool llvm::isMathLibCallNoop(const CallBase *Call,
const TargetLibraryInfo *TLI) { … }
void TargetFolder::anchor() { … }