X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=lib%2FVMCore%2FConstantFold.cpp;h=20e04cae4fb5aaa927c6f7200020c0e063e5dd19;hp=170df73272330a34d597348d7e739fc81578d758;hb=43ad6b3e0d6ada51e9b23aab3e061187f1f5710c;hpb=fdf15e1dc8f1c4cb48a16eb20c536072ca7188fd diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp index 170df732723..20e04cae4fb 100644 --- a/lib/VMCore/ConstantFold.cpp +++ b/lib/VMCore/ConstantFold.cpp @@ -1,4 +1,4 @@ -//===- ConstantFolding.cpp - LLVM constant folder -------------------------===// +//===- ConstantFold.cpp - LLVM constant folder ----------------------------===// // // The LLVM Compiler Infrastructure // @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// // // This file implements folding of constants for LLVM. This implements the -// (internal) ConstantFolding.h interface, which is used by the +// (internal) ConstantFold.h interface, which is used by the // ConstantExpr::get* methods to automatically fold constants when possible. // // The current constant folding implementation is implemented in two pieces: the @@ -18,11 +18,13 @@ // //===----------------------------------------------------------------------===// -#include "ConstantFolding.h" +#include "ConstantFold.h" #include "llvm/Constants.h" #include "llvm/Instructions.h" #include "llvm/DerivedTypes.h" #include "llvm/Function.h" +#include "llvm/GlobalAlias.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/GetElementPtrTypeIterator.h" #include "llvm/Support/ManagedStatic.h" @@ -30,778 +32,41 @@ #include using namespace llvm; -namespace { - struct VISIBILITY_HIDDEN ConstRules { - ConstRules() {} - virtual ~ConstRules() {} - - // Binary Operators... - virtual Constant *add(const Constant *V1, const Constant *V2) const = 0; - virtual Constant *sub(const Constant *V1, const Constant *V2) const = 0; - virtual Constant *mul(const Constant *V1, const Constant *V2) const = 0; - virtual Constant *urem(const Constant *V1, const Constant *V2) const = 0; - virtual Constant *srem(const Constant *V1, const Constant *V2) const = 0; - virtual Constant *frem(const Constant *V1, const Constant *V2) const = 0; - virtual Constant *udiv(const Constant *V1, const Constant *V2) const = 0; - virtual Constant *sdiv(const Constant *V1, const Constant *V2) const = 0; - virtual Constant *fdiv(const Constant *V1, const Constant *V2) const = 0; - virtual Constant *op_and(const Constant *V1, const Constant *V2) const = 0; - virtual Constant *op_or (const Constant *V1, const Constant *V2) const = 0; - virtual Constant *op_xor(const Constant *V1, const Constant *V2) const = 0; - virtual Constant *shl(const Constant *V1, const Constant *V2) const = 0; - virtual Constant *lshr(const Constant *V1, const Constant *V2) const = 0; - virtual Constant *ashr(const Constant *V1, const Constant *V2) const = 0; - virtual Constant *lessthan(const Constant *V1, const Constant *V2) const =0; - virtual Constant *equalto(const Constant *V1, const Constant *V2) const = 0; - - // Casting operators. - virtual Constant *castToBool (const Constant *V) const = 0; - virtual Constant *castToSByte (const Constant *V) const = 0; - virtual Constant *castToUByte (const Constant *V) const = 0; - virtual Constant *castToShort (const Constant *V) const = 0; - virtual Constant *castToUShort(const Constant *V) const = 0; - virtual Constant *castToInt (const Constant *V) const = 0; - virtual Constant *castToUInt (const Constant *V) const = 0; - virtual Constant *castToLong (const Constant *V) const = 0; - virtual Constant *castToULong (const Constant *V) const = 0; - virtual Constant *castToFloat (const Constant *V) const = 0; - virtual Constant *castToDouble(const Constant *V) const = 0; - virtual Constant *castToPointer(const Constant *V, - const PointerType *Ty) const = 0; - - // ConstRules::get - Return an instance of ConstRules for the specified - // constant operands. - // - static ConstRules &get(const Constant *V1, const Constant *V2); - private: - ConstRules(const ConstRules &); // Do not implement - ConstRules &operator=(const ConstRules &); // Do not implement - }; -} - - //===----------------------------------------------------------------------===// -// TemplateRules Class +// ConstantFold*Instruction Implementations //===----------------------------------------------------------------------===// -// -// TemplateRules - Implement a subclass of ConstRules that provides all -// operations as noops. All other rules classes inherit from this class so -// that if functionality is needed in the future, it can simply be added here -// and to ConstRules without changing anything else... -// -// This class also provides subclasses with typesafe implementations of methods -// so that don't have to do type casting. -// -namespace { -template -class VISIBILITY_HIDDEN TemplateRules : public ConstRules { - - - //===--------------------------------------------------------------------===// - // Redirecting functions that cast to the appropriate types - //===--------------------------------------------------------------------===// - - virtual Constant *add(const Constant *V1, const Constant *V2) const { - return SubClassName::Add((const ArgType *)V1, (const ArgType *)V2); - } - virtual Constant *sub(const Constant *V1, const Constant *V2) const { - return SubClassName::Sub((const ArgType *)V1, (const ArgType *)V2); - } - virtual Constant *mul(const Constant *V1, const Constant *V2) const { - return SubClassName::Mul((const ArgType *)V1, (const ArgType *)V2); - } - virtual Constant *udiv(const Constant *V1, const Constant *V2) const { - return SubClassName::UDiv((const ArgType *)V1, (const ArgType *)V2); - } - virtual Constant *sdiv(const Constant *V1, const Constant *V2) const { - return SubClassName::SDiv((const ArgType *)V1, (const ArgType *)V2); - } - virtual Constant *fdiv(const Constant *V1, const Constant *V2) const { - return SubClassName::FDiv((const ArgType *)V1, (const ArgType *)V2); - } - virtual Constant *urem(const Constant *V1, const Constant *V2) const { - return SubClassName::URem((const ArgType *)V1, (const ArgType *)V2); - } - virtual Constant *srem(const Constant *V1, const Constant *V2) const { - return SubClassName::SRem((const ArgType *)V1, (const ArgType *)V2); - } - virtual Constant *frem(const Constant *V1, const Constant *V2) const { - return SubClassName::FRem((const ArgType *)V1, (const ArgType *)V2); - } - virtual Constant *op_and(const Constant *V1, const Constant *V2) const { - return SubClassName::And((const ArgType *)V1, (const ArgType *)V2); - } - virtual Constant *op_or(const Constant *V1, const Constant *V2) const { - return SubClassName::Or((const ArgType *)V1, (const ArgType *)V2); - } - virtual Constant *op_xor(const Constant *V1, const Constant *V2) const { - return SubClassName::Xor((const ArgType *)V1, (const ArgType *)V2); - } - virtual Constant *shl(const Constant *V1, const Constant *V2) const { - return SubClassName::Shl((const ArgType *)V1, (const ArgType *)V2); - } - virtual Constant *lshr(const Constant *V1, const Constant *V2) const { - return SubClassName::LShr((const ArgType *)V1, (const ArgType *)V2); - } - virtual Constant *ashr(const Constant *V1, const Constant *V2) const { - return SubClassName::AShr((const ArgType *)V1, (const ArgType *)V2); - } - virtual Constant *lessthan(const Constant *V1, const Constant *V2) const { - return SubClassName::LessThan((const ArgType *)V1, (const ArgType *)V2); - } - virtual Constant *equalto(const Constant *V1, const Constant *V2) const { - return SubClassName::EqualTo((const ArgType *)V1, (const ArgType *)V2); - } - - // Casting operators. ick - virtual Constant *castToBool(const Constant *V) const { - return SubClassName::CastToBool((const ArgType*)V); - } - virtual Constant *castToSByte(const Constant *V) const { - return SubClassName::CastToSByte((const ArgType*)V); - } - virtual Constant *castToUByte(const Constant *V) const { - return SubClassName::CastToUByte((const ArgType*)V); - } - virtual Constant *castToShort(const Constant *V) const { - return SubClassName::CastToShort((const ArgType*)V); - } - virtual Constant *castToUShort(const Constant *V) const { - return SubClassName::CastToUShort((const ArgType*)V); - } - virtual Constant *castToInt(const Constant *V) const { - return SubClassName::CastToInt((const ArgType*)V); - } - virtual Constant *castToUInt(const Constant *V) const { - return SubClassName::CastToUInt((const ArgType*)V); - } - virtual Constant *castToLong(const Constant *V) const { - return SubClassName::CastToLong((const ArgType*)V); - } - virtual Constant *castToULong(const Constant *V) const { - return SubClassName::CastToULong((const ArgType*)V); - } - virtual Constant *castToFloat(const Constant *V) const { - return SubClassName::CastToFloat((const ArgType*)V); - } - virtual Constant *castToDouble(const Constant *V) const { - return SubClassName::CastToDouble((const ArgType*)V); - } - virtual Constant *castToPointer(const Constant *V, - const PointerType *Ty) const { - return SubClassName::CastToPointer((const ArgType*)V, Ty); - } - - //===--------------------------------------------------------------------===// - // Default "noop" implementations - //===--------------------------------------------------------------------===// - - static Constant *Add (const ArgType *V1, const ArgType *V2) { return 0; } - static Constant *Sub (const ArgType *V1, const ArgType *V2) { return 0; } - static Constant *Mul (const ArgType *V1, const ArgType *V2) { return 0; } - static Constant *SDiv(const ArgType *V1, const ArgType *V2) { return 0; } - static Constant *UDiv(const ArgType *V1, const ArgType *V2) { return 0; } - static Constant *FDiv(const ArgType *V1, const ArgType *V2) { return 0; } - static Constant *URem(const ArgType *V1, const ArgType *V2) { return 0; } - static Constant *SRem(const ArgType *V1, const ArgType *V2) { return 0; } - static Constant *FRem(const ArgType *V1, const ArgType *V2) { return 0; } - static Constant *And (const ArgType *V1, const ArgType *V2) { return 0; } - static Constant *Or (const ArgType *V1, const ArgType *V2) { return 0; } - static Constant *Xor (const ArgType *V1, const ArgType *V2) { return 0; } - static Constant *Shl (const ArgType *V1, const ArgType *V2) { return 0; } - static Constant *LShr(const ArgType *V1, const ArgType *V2) { return 0; } - static Constant *AShr(const ArgType *V1, const ArgType *V2) { return 0; } - static Constant *LessThan(const ArgType *V1, const ArgType *V2) { - return 0; - } - static Constant *EqualTo(const ArgType *V1, const ArgType *V2) { - return 0; - } - - // Casting operators. ick - static Constant *CastToBool (const Constant *V) { return 0; } - static Constant *CastToSByte (const Constant *V) { return 0; } - static Constant *CastToUByte (const Constant *V) { return 0; } - static Constant *CastToShort (const Constant *V) { return 0; } - static Constant *CastToUShort(const Constant *V) { return 0; } - static Constant *CastToInt (const Constant *V) { return 0; } - static Constant *CastToUInt (const Constant *V) { return 0; } - static Constant *CastToLong (const Constant *V) { return 0; } - static Constant *CastToULong (const Constant *V) { return 0; } - static Constant *CastToFloat (const Constant *V) { return 0; } - static Constant *CastToDouble(const Constant *V) { return 0; } - static Constant *CastToPointer(const Constant *, - const PointerType *) {return 0;} - -public: - virtual ~TemplateRules() {} -}; -} // end anonymous namespace - - -//===----------------------------------------------------------------------===// -// EmptyRules Class -//===----------------------------------------------------------------------===// -// -// EmptyRules provides a concrete base class of ConstRules that does nothing -// -namespace { -struct VISIBILITY_HIDDEN EmptyRules - : public TemplateRules { - static Constant *EqualTo(const Constant *V1, const Constant *V2) { - if (V1 == V2) return ConstantBool::getTrue(); +/// BitCastConstantVector - Convert the specified ConstantVector node to the +/// specified vector type. At this point, we know that the elements of the +/// input vector constant are all simple integer or FP values. +static Constant *BitCastConstantVector(ConstantVector *CV, + const VectorType *DstTy) { + // If this cast changes element count then we can't handle it here: + // doing so requires endianness information. This should be handled by + // Analysis/ConstantFolding.cpp + unsigned NumElts = DstTy->getNumElements(); + if (NumElts != CV->getNumOperands()) return 0; - } -}; -} // end anonymous namespace - - - -//===----------------------------------------------------------------------===// -// BoolRules Class -//===----------------------------------------------------------------------===// -// -// BoolRules provides a concrete base class of ConstRules for the 'bool' type. -// -namespace { -struct VISIBILITY_HIDDEN BoolRules - : public TemplateRules { - - static Constant *LessThan(const ConstantBool *V1, const ConstantBool *V2) { - return ConstantBool::get(V1->getValue() < V2->getValue()); - } - - static Constant *EqualTo(const Constant *V1, const Constant *V2) { - return ConstantBool::get(V1 == V2); - } - - static Constant *And(const ConstantBool *V1, const ConstantBool *V2) { - return ConstantBool::get(V1->getValue() & V2->getValue()); - } - - static Constant *Or(const ConstantBool *V1, const ConstantBool *V2) { - return ConstantBool::get(V1->getValue() | V2->getValue()); - } - - static Constant *Xor(const ConstantBool *V1, const ConstantBool *V2) { - return ConstantBool::get(V1->getValue() ^ V2->getValue()); - } - - // Casting operators. ick -#define DEF_CAST(TYPE, CLASS, CTYPE) \ - static Constant *CastTo##TYPE (const ConstantBool *V) { \ - return CLASS::get(Type::TYPE##Ty, (CTYPE)(bool)V->getValue()); \ - } - - DEF_CAST(Bool , ConstantBool, bool) - DEF_CAST(SByte , ConstantInt, signed char) - DEF_CAST(UByte , ConstantInt, unsigned char) - DEF_CAST(Short , ConstantInt, signed short) - DEF_CAST(UShort, ConstantInt, unsigned short) - DEF_CAST(Int , ConstantInt, signed int) - DEF_CAST(UInt , ConstantInt, unsigned int) - DEF_CAST(Long , ConstantInt, int64_t) - DEF_CAST(ULong , ConstantInt, uint64_t) - DEF_CAST(Float , ConstantFP , float) - DEF_CAST(Double, ConstantFP , double) -#undef DEF_CAST -}; -} // end anonymous namespace - - -//===----------------------------------------------------------------------===// -// NullPointerRules Class -//===----------------------------------------------------------------------===// -// -// NullPointerRules provides a concrete base class of ConstRules for null -// pointers. -// -namespace { -struct VISIBILITY_HIDDEN NullPointerRules - : public TemplateRules { - static Constant *EqualTo(const Constant *V1, const Constant *V2) { - return ConstantBool::getTrue(); // Null pointers are always equal - } - static Constant *CastToBool(const Constant *V) { - return ConstantBool::getFalse(); - } - static Constant *CastToSByte (const Constant *V) { - return ConstantInt::get(Type::SByteTy, 0); - } - static Constant *CastToUByte (const Constant *V) { - return ConstantInt::get(Type::UByteTy, 0); - } - static Constant *CastToShort (const Constant *V) { - return ConstantInt::get(Type::ShortTy, 0); - } - static Constant *CastToUShort(const Constant *V) { - return ConstantInt::get(Type::UShortTy, 0); - } - static Constant *CastToInt (const Constant *V) { - return ConstantInt::get(Type::IntTy, 0); - } - static Constant *CastToUInt (const Constant *V) { - return ConstantInt::get(Type::UIntTy, 0); - } - static Constant *CastToLong (const Constant *V) { - return ConstantInt::get(Type::LongTy, 0); - } - static Constant *CastToULong (const Constant *V) { - return ConstantInt::get(Type::ULongTy, 0); - } - static Constant *CastToFloat (const Constant *V) { - return ConstantFP::get(Type::FloatTy, 0); - } - static Constant *CastToDouble(const Constant *V) { - return ConstantFP::get(Type::DoubleTy, 0); - } - - static Constant *CastToPointer(const ConstantPointerNull *V, - const PointerType *PTy) { - return ConstantPointerNull::get(PTy); - } -}; -} // end anonymous namespace - -//===----------------------------------------------------------------------===// -// ConstantPackedRules Class -//===----------------------------------------------------------------------===// - -/// DoVectorOp - Given two packed constants and a function pointer, apply the -/// function pointer to each element pair, producing a new ConstantPacked -/// constant. -static Constant *EvalVectorOp(const ConstantPacked *V1, - const ConstantPacked *V2, - Constant *(*FP)(Constant*, Constant*)) { - std::vector Res; - for (unsigned i = 0, e = V1->getNumOperands(); i != e; ++i) - Res.push_back(FP(const_cast(V1->getOperand(i)), - const_cast(V2->getOperand(i)))); - return ConstantPacked::get(Res); -} - -/// PackedTypeRules provides a concrete base class of ConstRules for -/// ConstantPacked operands. -/// -namespace { -struct VISIBILITY_HIDDEN ConstantPackedRules - : public TemplateRules { - static Constant *Add(const ConstantPacked *V1, const ConstantPacked *V2) { - return EvalVectorOp(V1, V2, ConstantExpr::getAdd); - } - static Constant *Sub(const ConstantPacked *V1, const ConstantPacked *V2) { - return EvalVectorOp(V1, V2, ConstantExpr::getSub); - } - static Constant *Mul(const ConstantPacked *V1, const ConstantPacked *V2) { - return EvalVectorOp(V1, V2, ConstantExpr::getMul); - } - static Constant *UDiv(const ConstantPacked *V1, const ConstantPacked *V2) { - return EvalVectorOp(V1, V2, ConstantExpr::getUDiv); - } - static Constant *SDiv(const ConstantPacked *V1, const ConstantPacked *V2) { - return EvalVectorOp(V1, V2, ConstantExpr::getSDiv); - } - static Constant *FDiv(const ConstantPacked *V1, const ConstantPacked *V2) { - return EvalVectorOp(V1, V2, ConstantExpr::getFDiv); - } - static Constant *URem(const ConstantPacked *V1, const ConstantPacked *V2) { - return EvalVectorOp(V1, V2, ConstantExpr::getURem); - } - static Constant *SRem(const ConstantPacked *V1, const ConstantPacked *V2) { - return EvalVectorOp(V1, V2, ConstantExpr::getSRem); - } - static Constant *FRem(const ConstantPacked *V1, const ConstantPacked *V2) { - return EvalVectorOp(V1, V2, ConstantExpr::getFRem); - } - static Constant *And(const ConstantPacked *V1, const ConstantPacked *V2) { - return EvalVectorOp(V1, V2, ConstantExpr::getAnd); - } - static Constant *Or (const ConstantPacked *V1, const ConstantPacked *V2) { - return EvalVectorOp(V1, V2, ConstantExpr::getOr); - } - static Constant *Xor(const ConstantPacked *V1, const ConstantPacked *V2) { - return EvalVectorOp(V1, V2, ConstantExpr::getXor); - } - static Constant *LessThan(const ConstantPacked *V1, const ConstantPacked *V2){ - return 0; - } - static Constant *EqualTo(const ConstantPacked *V1, const ConstantPacked *V2) { - for (unsigned i = 0, e = V1->getNumOperands(); i != e; ++i) { - Constant *C = - ConstantExpr::getSetEQ(const_cast(V1->getOperand(i)), - const_cast(V2->getOperand(i))); - if (ConstantBool *CB = dyn_cast(C)) - return CB; - } - // Otherwise, could not decide from any element pairs. - return 0; - } -}; -} // end anonymous namespace - - -//===----------------------------------------------------------------------===// -// GeneralPackedRules Class -//===----------------------------------------------------------------------===// - -/// GeneralPackedRules provides a concrete base class of ConstRules for -/// PackedType operands, where both operands are not ConstantPacked. The usual -/// cause for this is that one operand is a ConstantAggregateZero. -/// -namespace { -struct VISIBILITY_HIDDEN GeneralPackedRules - : public TemplateRules { -}; -} // end anonymous namespace - - -//===----------------------------------------------------------------------===// -// DirectIntRules Class -//===----------------------------------------------------------------------===// -// -// DirectIntRules provides implementations of functions that are valid on -// integer types, but not all types in general. -// -namespace { -template -struct VISIBILITY_HIDDEN DirectIntRules - : public TemplateRules > { - - static Constant *Add(const ConstantInt *V1, const ConstantInt *V2) { - BuiltinType R = (BuiltinType)V1->getZExtValue() + - (BuiltinType)V2->getZExtValue(); - return ConstantInt::get(*Ty, R); - } - - static Constant *Sub(const ConstantInt *V1, const ConstantInt *V2) { - BuiltinType R = (BuiltinType)V1->getZExtValue() - - (BuiltinType)V2->getZExtValue(); - return ConstantInt::get(*Ty, R); - } - - static Constant *Mul(const ConstantInt *V1, const ConstantInt *V2) { - BuiltinType R = (BuiltinType)V1->getZExtValue() * - (BuiltinType)V2->getZExtValue(); - return ConstantInt::get(*Ty, R); - } - - static Constant *LessThan(const ConstantInt *V1, const ConstantInt *V2) { - bool R = (BuiltinType)V1->getZExtValue() < (BuiltinType)V2->getZExtValue(); - return ConstantBool::get(R); - } - - static Constant *EqualTo(const ConstantInt *V1, const ConstantInt *V2) { - bool R = (BuiltinType)V1->getZExtValue() == (BuiltinType)V2->getZExtValue(); - return ConstantBool::get(R); - } - - static Constant *CastToPointer(const ConstantInt *V, - const PointerType *PTy) { - if (V->isNullValue()) // Is it a FP or Integral null value? - return ConstantPointerNull::get(PTy); - return 0; // Can't const prop other types of pointers - } - - // Casting operators. ick -#define DEF_CAST(TYPE, CLASS, CTYPE) \ - static Constant *CastTo##TYPE (const ConstantInt *V) { \ - return CLASS::get(Type::TYPE##Ty, (CTYPE)((BuiltinType)V->getZExtValue()));\ - } - - DEF_CAST(Bool , ConstantBool, bool) - DEF_CAST(SByte , ConstantInt, signed char) - DEF_CAST(UByte , ConstantInt, unsigned char) - DEF_CAST(Short , ConstantInt, signed short) - DEF_CAST(UShort, ConstantInt, unsigned short) - DEF_CAST(Int , ConstantInt, signed int) - DEF_CAST(UInt , ConstantInt, unsigned int) - DEF_CAST(Long , ConstantInt, int64_t) - DEF_CAST(ULong , ConstantInt, uint64_t) - DEF_CAST(Float , ConstantFP , float) - DEF_CAST(Double, ConstantFP , double) -#undef DEF_CAST - - static Constant *UDiv(const ConstantInt *V1, const ConstantInt *V2) { - if (V2->isNullValue()) // X / 0 - return 0; - BuiltinType R = (BuiltinType)(V1->getZExtValue() / V2->getZExtValue()); - return ConstantInt::get(*Ty, R); - } - - static Constant *SDiv(const ConstantInt *V1, const ConstantInt *V2) { - if (V2->isNullValue()) // X / 0 - return 0; - if (V2->isAllOnesValue() && // MIN_INT / -1 - (BuiltinType)V1->getSExtValue() == -(BuiltinType)V1->getSExtValue()) + // Check to verify that all elements of the input are simple. + for (unsigned i = 0; i != NumElts; ++i) { + if (!isa(CV->getOperand(i)) && + !isa(CV->getOperand(i))) return 0; - BuiltinType R = (BuiltinType)(V1->getSExtValue() / V2->getSExtValue()); - return ConstantInt::get(*Ty, R); } - static Constant *URem(const ConstantInt *V1, - const ConstantInt *V2) { - if (V2->isNullValue()) return 0; // X / 0 - BuiltinType R = (BuiltinType)(V1->getZExtValue() % V2->getZExtValue()); - return ConstantInt::get(*Ty, R); - } - - static Constant *SRem(const ConstantInt *V1, - const ConstantInt *V2) { - if (V2->isNullValue()) return 0; // X % 0 - if (V2->isAllOnesValue() && // MIN_INT % -1 - (BuiltinType)V1->getSExtValue() == -(BuiltinType)V1->getSExtValue()) - return 0; - BuiltinType R = (BuiltinType)(V1->getSExtValue() % V2->getSExtValue()); - return ConstantInt::get(*Ty, R); - } - - static Constant *And(const ConstantInt *V1, const ConstantInt *V2) { - BuiltinType R = - (BuiltinType)V1->getZExtValue() & (BuiltinType)V2->getZExtValue(); - return ConstantInt::get(*Ty, R); - } - static Constant *Or(const ConstantInt *V1, const ConstantInt *V2) { - BuiltinType R = - (BuiltinType)V1->getZExtValue() | (BuiltinType)V2->getZExtValue(); - return ConstantInt::get(*Ty, R); - } - static Constant *Xor(const ConstantInt *V1, const ConstantInt *V2) { - BuiltinType R = - (BuiltinType)V1->getZExtValue() ^ (BuiltinType)V2->getZExtValue(); - return ConstantInt::get(*Ty, R); - } - - static Constant *Shl(const ConstantInt *V1, const ConstantInt *V2) { - BuiltinType R = - (BuiltinType)V1->getZExtValue() << (BuiltinType)V2->getZExtValue(); - return ConstantInt::get(*Ty, R); - } - - static Constant *LShr(const ConstantInt *V1, const ConstantInt *V2) { - BuiltinType R = BuiltinType(V1->getZExtValue() >> V2->getZExtValue()); - return ConstantInt::get(*Ty, R); - } - - static Constant *AShr(const ConstantInt *V1, const ConstantInt *V2) { - BuiltinType R = BuiltinType(V1->getSExtValue() >> V2->getZExtValue()); - return ConstantInt::get(*Ty, R); - } -}; -} // end anonymous namespace - - -//===----------------------------------------------------------------------===// -// DirectFPRules Class -//===----------------------------------------------------------------------===// -// -/// DirectFPRules provides implementations of functions that are valid on -/// floating point types, but not all types in general. -/// -namespace { -template -struct VISIBILITY_HIDDEN DirectFPRules - : public TemplateRules > { - - static Constant *Add(const ConstantFP *V1, const ConstantFP *V2) { - BuiltinType R = (BuiltinType)V1->getValue() + - (BuiltinType)V2->getValue(); - return ConstantFP::get(*Ty, R); - } - - static Constant *Sub(const ConstantFP *V1, const ConstantFP *V2) { - BuiltinType R = (BuiltinType)V1->getValue() - (BuiltinType)V2->getValue(); - return ConstantFP::get(*Ty, R); - } - - static Constant *Mul(const ConstantFP *V1, const ConstantFP *V2) { - BuiltinType R = (BuiltinType)V1->getValue() * (BuiltinType)V2->getValue(); - return ConstantFP::get(*Ty, R); - } - - static Constant *LessThan(const ConstantFP *V1, const ConstantFP *V2) { - bool R = (BuiltinType)V1->getValue() < (BuiltinType)V2->getValue(); - return ConstantBool::get(R); - } - - static Constant *EqualTo(const ConstantFP *V1, const ConstantFP *V2) { - bool R = (BuiltinType)V1->getValue() == (BuiltinType)V2->getValue(); - return ConstantBool::get(R); - } - - static Constant *CastToPointer(const ConstantFP *V, - const PointerType *PTy) { - if (V->isNullValue()) // Is it a FP or Integral null value? - return ConstantPointerNull::get(PTy); - return 0; // Can't const prop other types of pointers - } - - // Casting operators. ick -#define DEF_CAST(TYPE, CLASS, CTYPE) \ - static Constant *CastTo##TYPE (const ConstantFP *V) { \ - return CLASS::get(Type::TYPE##Ty, (CTYPE)(BuiltinType)V->getValue()); \ - } - - DEF_CAST(Bool , ConstantBool, bool) - DEF_CAST(SByte , ConstantInt, signed char) - DEF_CAST(UByte , ConstantInt, unsigned char) - DEF_CAST(Short , ConstantInt, signed short) - DEF_CAST(UShort, ConstantInt, unsigned short) - DEF_CAST(Int , ConstantInt, signed int) - DEF_CAST(UInt , ConstantInt, unsigned int) - DEF_CAST(Long , ConstantInt, int64_t) - DEF_CAST(ULong , ConstantInt, uint64_t) - DEF_CAST(Float , ConstantFP , float) - DEF_CAST(Double, ConstantFP , double) -#undef DEF_CAST - - static Constant *FRem(const ConstantFP *V1, const ConstantFP *V2) { - if (V2->isNullValue()) return 0; - BuiltinType Result = std::fmod((BuiltinType)V1->getValue(), - (BuiltinType)V2->getValue()); - return ConstantFP::get(*Ty, Result); - } - static Constant *FDiv(const ConstantFP *V1, const ConstantFP *V2) { - BuiltinType inf = std::numeric_limits::infinity(); - if (V2->isExactlyValue(0.0)) return ConstantFP::get(*Ty, inf); - if (V2->isExactlyValue(-0.0)) return ConstantFP::get(*Ty, -inf); - BuiltinType R = (BuiltinType)V1->getValue() / (BuiltinType)V2->getValue(); - return ConstantFP::get(*Ty, R); - } -}; -} // end anonymous namespace - -static ManagedStatic EmptyR; -static ManagedStatic BoolR; -static ManagedStatic NullPointerR; -static ManagedStatic ConstantPackedR; -static ManagedStatic GeneralPackedR; -static ManagedStatic > SByteR; -static ManagedStatic > UByteR; -static ManagedStatic > ShortR; -static ManagedStatic > UShortR; -static ManagedStatic > IntR; -static ManagedStatic > UIntR; -static ManagedStatic > LongR; -static ManagedStatic > ULongR; -static ManagedStatic > FloatR; -static ManagedStatic > DoubleR; - -/// ConstRules::get - This method returns the constant rules implementation that -/// implements the semantics of the two specified constants. -ConstRules &ConstRules::get(const Constant *V1, const Constant *V2) { - if (isa(V1) || isa(V2) || - isa(V1) || isa(V2) || - isa(V1) || isa(V2)) - return *EmptyR; - - switch (V1->getType()->getTypeID()) { - default: assert(0 && "Unknown value type for constant folding!"); - case Type::BoolTyID: return *BoolR; - case Type::PointerTyID: return *NullPointerR; - case Type::SByteTyID: return *SByteR; - case Type::UByteTyID: return *UByteR; - case Type::ShortTyID: return *ShortR; - case Type::UShortTyID: return *UShortR; - case Type::IntTyID: return *IntR; - case Type::UIntTyID: return *UIntR; - case Type::LongTyID: return *LongR; - case Type::ULongTyID: return *ULongR; - case Type::FloatTyID: return *FloatR; - case Type::DoubleTyID: return *DoubleR; - case Type::PackedTyID: - if (isa(V1) && isa(V2)) - return *ConstantPackedR; - return *GeneralPackedR; // Constant folding rules for ConstantAggregateZero. - } -} - - -//===----------------------------------------------------------------------===// -// ConstantFold*Instruction Implementations -//===----------------------------------------------------------------------===// - -/// CastConstantPacked - Convert the specified ConstantPacked node to the -/// specified packed type. At this point, we know that the elements of the -/// input packed constant are all simple integer or FP values. -static Constant *CastConstantPacked(ConstantPacked *CP, - const PackedType *DstTy) { - unsigned SrcNumElts = CP->getType()->getNumElements(); - unsigned DstNumElts = DstTy->getNumElements(); - const Type *SrcEltTy = CP->getType()->getElementType(); + // Bitcast each element now. + std::vector Result; const Type *DstEltTy = DstTy->getElementType(); - - // If both vectors have the same number of elements (thus, the elements - // are the same size), perform the conversion now. - if (SrcNumElts == DstNumElts) { - std::vector Result; - - // If the src and dest elements are both integers, or both floats, we can - // just BitCast each element because the elements are the same size. - if ((SrcEltTy->isIntegral() && DstEltTy->isIntegral()) || - (SrcEltTy->isFloatingPoint() && DstEltTy->isFloatingPoint())) { - for (unsigned i = 0; i != SrcNumElts; ++i) - Result.push_back( - ConstantExpr::getBitCast(CP->getOperand(i), DstEltTy)); - return ConstantPacked::get(Result); - } - - // If this is an int-to-fp cast .. - if (SrcEltTy->isIntegral()) { - // Ensure that it is int-to-fp cast - assert(DstEltTy->isFloatingPoint()); - if (DstEltTy->getTypeID() == Type::DoubleTyID) { - for (unsigned i = 0; i != SrcNumElts; ++i) { - double V = - BitsToDouble(cast(CP->getOperand(i))->getZExtValue()); - Result.push_back(ConstantFP::get(Type::DoubleTy, V)); - } - return ConstantPacked::get(Result); - } - assert(DstEltTy == Type::FloatTy && "Unknown fp type!"); - for (unsigned i = 0; i != SrcNumElts; ++i) { - float V = - BitsToFloat(cast(CP->getOperand(i))->getZExtValue()); - Result.push_back(ConstantFP::get(Type::FloatTy, V)); - } - return ConstantPacked::get(Result); - } - - // Otherwise, this is an fp-to-int cast. - assert(SrcEltTy->isFloatingPoint() && DstEltTy->isIntegral()); - - if (SrcEltTy->getTypeID() == Type::DoubleTyID) { - for (unsigned i = 0; i != SrcNumElts; ++i) { - uint64_t V = - DoubleToBits(cast(CP->getOperand(i))->getValue()); - Constant *C = ConstantInt::get(Type::ULongTy, V); - Result.push_back(ConstantExpr::getBitCast(C, DstEltTy )); - } - return ConstantPacked::get(Result); - } - - assert(SrcEltTy->getTypeID() == Type::FloatTyID); - for (unsigned i = 0; i != SrcNumElts; ++i) { - uint32_t V = FloatToBits(cast(CP->getOperand(i))->getValue()); - Constant *C = ConstantInt::get(Type::UIntTy, V); - Result.push_back(ConstantExpr::getBitCast(C, DstEltTy)); - } - return ConstantPacked::get(Result); - } - - // Otherwise, this is a cast that changes element count and size. Handle - // casts which shrink the elements here. - - // FIXME: We need to know endianness to do this! - - return 0; + for (unsigned i = 0; i != NumElts; ++i) + Result.push_back(ConstantExpr::getBitCast(CV->getOperand(i), DstEltTy)); + return ConstantVector::get(Result); } /// This function determines which opcode to use to fold two constant cast /// expressions together. It uses CastInst::isEliminableCastPair to determine /// the opcode. Consequently its just a wrapper around that function. -/// @Determine if it is valid to fold a cast of a cast +/// @brief Determine if it is valid to fold a cast of a cast static unsigned foldConstantCastPair( unsigned opc, ///< opcode of the second cast constant expression @@ -820,15 +85,103 @@ foldConstantCastPair( // Let CastInst::isEliminableCastPair do the heavy lifting. return CastInst::isEliminableCastPair(firstOp, secondOp, SrcTy, MidTy, DstTy, - Type::ULongTy); + Type::Int64Ty); +} + +static Constant *FoldBitCast(Constant *V, const Type *DestTy) { + const Type *SrcTy = V->getType(); + if (SrcTy == DestTy) + return V; // no-op cast + + // Check to see if we are casting a pointer to an aggregate to a pointer to + // the first element. If so, return the appropriate GEP instruction. + if (const PointerType *PTy = dyn_cast(V->getType())) + if (const PointerType *DPTy = dyn_cast(DestTy)) { + SmallVector IdxList; + IdxList.push_back(Constant::getNullValue(Type::Int32Ty)); + const Type *ElTy = PTy->getElementType(); + while (ElTy != DPTy->getElementType()) { + if (const StructType *STy = dyn_cast(ElTy)) { + if (STy->getNumElements() == 0) break; + ElTy = STy->getElementType(0); + IdxList.push_back(Constant::getNullValue(Type::Int32Ty)); + } else if (const SequentialType *STy = dyn_cast(ElTy)) { + if (isa(ElTy)) break; // Can't index into pointers! + ElTy = STy->getElementType(); + IdxList.push_back(IdxList[0]); + } else { + break; + } + } + + if (ElTy == DPTy->getElementType()) + return ConstantExpr::getGetElementPtr(V, &IdxList[0], IdxList.size()); + } + + // Handle casts from one vector constant to another. We know that the src + // and dest type have the same size (otherwise its an illegal cast). + if (const VectorType *DestPTy = dyn_cast(DestTy)) { + if (const VectorType *SrcTy = dyn_cast(V->getType())) { + assert(DestPTy->getBitWidth() == SrcTy->getBitWidth() && + "Not cast between same sized vectors!"); + // First, check for null. Undef is already handled. + if (isa(V)) + return Constant::getNullValue(DestTy); + + if (ConstantVector *CV = dyn_cast(V)) + return BitCastConstantVector(CV, DestPTy); + } + } + + // Finally, implement bitcast folding now. The code below doesn't handle + // bitcast right. + if (isa(V)) // ptr->ptr cast. + return ConstantPointerNull::get(cast(DestTy)); + + // Handle integral constant input. + if (const ConstantInt *CI = dyn_cast(V)) { + if (DestTy->isInteger()) + // Integral -> Integral. This is a no-op because the bit widths must + // be the same. Consequently, we just fold to V. + return V; + + if (DestTy->isFloatingPoint()) { + assert((DestTy == Type::DoubleTy || DestTy == Type::FloatTy) && + "Unknown FP type!"); + return ConstantFP::get(DestTy, APFloat(CI->getValue())); + } + // Otherwise, can't fold this (vector?) + return 0; + } + + // Handle ConstantFP input. + if (const ConstantFP *FP = dyn_cast(V)) { + // FP -> Integral. + if (DestTy == Type::Int32Ty) { + return ConstantInt::get(FP->getValueAPF().convertToAPInt()); + } else { + assert(DestTy == Type::Int64Ty && "only support f32/f64 for now!"); + return ConstantInt::get(FP->getValueAPF().convertToAPInt()); + } + } + return 0; } + Constant *llvm::ConstantFoldCastInstruction(unsigned opc, const Constant *V, const Type *DestTy) { const Type *SrcTy = V->getType(); - if (isa(V)) + if (isa(V)) { + // zext(undef) = 0, because the top bits will be zero. + // sext(undef) = 0, because the top bits will all be the same. + if (opc == Instruction::ZExt || opc == Instruction::SExt) + return Constant::getNullValue(DestTy); return UndefValue::get(DestTy); + } + // No compile-time operations on this type yet. + if (V->getType() == Type::PPC_FP128Ty || DestTy == Type::PPC_FP128Ty) + return 0; // If the cast operand is a constant expression, there's a few things we can // do to try to simplify it. @@ -852,175 +205,114 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, const Constant *V, } } - // We actually have to do a cast now, but first, we might need to fix up - // the value of the operand. + // We actually have to do a cast now. Perform the cast according to the + // opcode specified. switch (opc) { - case Instruction::PtrToInt: case Instruction::FPTrunc: case Instruction::FPExt: - break; - case Instruction::FPToUI: { - ConstRules &Rules = ConstRules::get(V, V); - V = Rules.castToULong(V); // make sure we get an unsigned value first - break; - } - case Instruction::FPToSI: { - ConstRules &Rules = ConstRules::get(V, V); - V = Rules.castToLong(V); // make sure we get a signed value first - break; - } - case Instruction::IntToPtr: //always treated as unsigned + if (const ConstantFP *FPC = dyn_cast(V)) { + APFloat Val = FPC->getValueAPF(); + Val.convert(DestTy == Type::FloatTy ? APFloat::IEEEsingle : + DestTy == Type::DoubleTy ? APFloat::IEEEdouble : + DestTy == Type::X86_FP80Ty ? APFloat::x87DoubleExtended : + DestTy == Type::FP128Ty ? APFloat::IEEEquad : + APFloat::Bogus, + APFloat::rmNearestTiesToEven); + return ConstantFP::get(DestTy, Val); + } + return 0; // Can't fold. + case Instruction::FPToUI: + case Instruction::FPToSI: + if (const ConstantFP *FPC = dyn_cast(V)) { + const APFloat &V = FPC->getValueAPF(); + uint64_t x[2]; + uint32_t DestBitWidth = cast(DestTy)->getBitWidth(); + (void) V.convertToInteger(x, DestBitWidth, opc==Instruction::FPToSI, + APFloat::rmTowardZero); + APInt Val(DestBitWidth, 2, x); + return ConstantInt::get(Val); + } + if (const ConstantVector *CV = dyn_cast(V)) { + std::vector res; + const VectorType *DestVecTy = cast(DestTy); + const Type *DstEltTy = DestVecTy->getElementType(); + for (unsigned i = 0, e = CV->getType()->getNumElements(); i != e; ++i) + res.push_back(ConstantFoldCastInstruction(opc, V->getOperand(i), + DstEltTy)); + return ConstantVector::get(DestVecTy, res); + } + return 0; // Can't fold. + case Instruction::IntToPtr: //always treated as unsigned + if (V->isNullValue()) // Is it an integral null value? + return ConstantPointerNull::get(cast(DestTy)); + return 0; // Other pointer types cannot be casted + case Instruction::PtrToInt: // always treated as unsigned + if (V->isNullValue()) // is it a null pointer value? + return ConstantInt::get(DestTy, 0); + return 0; // Other pointer types cannot be casted case Instruction::UIToFP: - case Instruction::ZExt: - // A ZExt always produces an unsigned value so we need to cast the value - // now before we try to cast it to the destination type - if (isa(V)) - V = ConstantInt::get(SrcTy->getUnsignedVersion(), - cast(V)->getZExtValue()); - break; case Instruction::SIToFP: - case Instruction::SExt: - // A SExt always produces a signed value so we need to cast the value - // now before we try to cast it to the destiniation type. - if (isa(V)) - V = ConstantInt::get(SrcTy->getSignedVersion(), - cast(V)->getSExtValue()); - else if (const ConstantBool *CB = dyn_cast(V)) - V = ConstantInt::get(Type::SByteTy, CB->getValue() ? -1 : 0); - - break; - case Instruction::Trunc: - // We just handle trunc directly here. The code below doesn't work for - // trunc to bool. - if (const ConstantInt *CI = dyn_cast(V)) - return ConstantIntegral::get(DestTy, CI->getZExtValue()); + if (const ConstantInt *CI = dyn_cast(V)) { + APInt api = CI->getValue(); + const uint64_t zero[] = {0, 0}; + uint32_t BitWidth = cast(SrcTy)->getBitWidth(); + APFloat apf = APFloat(APInt(DestTy->getPrimitiveSizeInBits(), + 2, zero)); + (void)apf.convertFromZeroExtendedInteger(api.getRawData(), BitWidth, + opc==Instruction::SIToFP, + APFloat::rmNearestTiesToEven); + return ConstantFP::get(DestTy, apf); + } + if (const ConstantVector *CV = dyn_cast(V)) { + std::vector res; + const VectorType *DestVecTy = cast(DestTy); + const Type *DstEltTy = DestVecTy->getElementType(); + for (unsigned i = 0, e = CV->getType()->getNumElements(); i != e; ++i) + res.push_back(ConstantFoldCastInstruction(opc, V->getOperand(i), + DstEltTy)); + return ConstantVector::get(DestVecTy, res); + } return 0; - case Instruction::BitCast: - if (SrcTy == DestTy) return (Constant*)V; // no-op cast - - // Check to see if we are casting a pointer to an aggregate to a pointer to - // the first element. If so, return the appropriate GEP instruction. - if (const PointerType *PTy = dyn_cast(V->getType())) - if (const PointerType *DPTy = dyn_cast(DestTy)) { - std::vector IdxList; - IdxList.push_back(Constant::getNullValue(Type::IntTy)); - const Type *ElTy = PTy->getElementType(); - while (ElTy != DPTy->getElementType()) { - if (const StructType *STy = dyn_cast(ElTy)) { - if (STy->getNumElements() == 0) break; - ElTy = STy->getElementType(0); - IdxList.push_back(Constant::getNullValue(Type::UIntTy)); - } else if (const SequentialType *STy = - dyn_cast(ElTy)) { - if (isa(ElTy)) break; // Can't index into pointers! - ElTy = STy->getElementType(); - IdxList.push_back(IdxList[0]); - } else { - break; - } - } - - if (ElTy == DPTy->getElementType()) - return ConstantExpr::getGetElementPtr( - const_cast(V),IdxList); - } - - // Handle casts from one packed constant to another. We know that the src - // and dest type have the same size (otherwise its an illegal cast). - if (const PackedType *DestPTy = dyn_cast(DestTy)) { - if (const PackedType *SrcTy = dyn_cast(V->getType())) { - assert(DestPTy->getBitWidth() == SrcTy->getBitWidth() && - "Not cast between same sized vectors!"); - // First, check for null and undef - if (isa(V)) - return Constant::getNullValue(DestTy); - if (isa(V)) - return UndefValue::get(DestTy); - - if (const ConstantPacked *CP = dyn_cast(V)) { - // This is a cast from a ConstantPacked of one type to a - // ConstantPacked of another type. Check to see if all elements of - // the input are simple. - bool AllSimpleConstants = true; - for (unsigned i = 0, e = CP->getNumOperands(); i != e; ++i) { - if (!isa(CP->getOperand(i)) && - !isa(CP->getOperand(i))) { - AllSimpleConstants = false; - break; - } - } - - // If all of the elements are simple constants, we can fold this. - if (AllSimpleConstants) - return CastConstantPacked(const_cast(CP), DestPTy); - } - } + case Instruction::ZExt: + if (const ConstantInt *CI = dyn_cast(V)) { + uint32_t BitWidth = cast(DestTy)->getBitWidth(); + APInt Result(CI->getValue()); + Result.zext(BitWidth); + return ConstantInt::get(Result); } - - // Finally, implement bitcast folding now. The code below doesn't handle - // bitcast right. - if (isa(V)) // ptr->ptr cast. - return ConstantPointerNull::get(cast(DestTy)); - - // Handle integral constant input. + return 0; + case Instruction::SExt: if (const ConstantInt *CI = dyn_cast(V)) { - // Integral -> Integral, must be changing sign. - if (DestTy->isIntegral()) - return ConstantInt::get(DestTy, CI->getZExtValue()); - - if (DestTy->isFloatingPoint()) { - if (DestTy == Type::FloatTy) - return ConstantFP::get(DestTy, BitsToFloat(CI->getZExtValue())); - assert(DestTy == Type::DoubleTy && "Unknown FP type!"); - return ConstantFP::get(DestTy, BitsToDouble(CI->getZExtValue())); - } - // Otherwise, can't fold this (packed?) - return 0; + uint32_t BitWidth = cast(DestTy)->getBitWidth(); + APInt Result(CI->getValue()); + Result.sext(BitWidth); + return ConstantInt::get(Result); } - - // Handle ConstantFP input. - if (const ConstantFP *FP = dyn_cast(V)) { - // FP -> Integral. - if (DestTy->isIntegral()) { - if (DestTy == Type::IntTy || DestTy == Type::UIntTy) - return ConstantInt::get(DestTy, FloatToBits(FP->getValue())); - assert((DestTy == Type::LongTy || DestTy == Type::ULongTy) - && "Incorrect integer type for bitcast!"); - return ConstantInt::get(DestTy, DoubleToBits(FP->getValue())); - } + return 0; + case Instruction::Trunc: + if (const ConstantInt *CI = dyn_cast(V)) { + uint32_t BitWidth = cast(DestTy)->getBitWidth(); + APInt Result(CI->getValue()); + Result.trunc(BitWidth); + return ConstantInt::get(Result); } return 0; + case Instruction::BitCast: + return FoldBitCast(const_cast(V), DestTy); default: assert(!"Invalid CE CastInst opcode"); break; } - // Okay, no more folding possible, time to cast - ConstRules &Rules = ConstRules::get(V, V); - switch (DestTy->getTypeID()) { - case Type::BoolTyID: return Rules.castToBool(V); - case Type::UByteTyID: return Rules.castToUByte(V); - case Type::SByteTyID: return Rules.castToSByte(V); - case Type::UShortTyID: return Rules.castToUShort(V); - case Type::ShortTyID: return Rules.castToShort(V); - case Type::UIntTyID: return Rules.castToUInt(V); - case Type::IntTyID: return Rules.castToInt(V); - case Type::ULongTyID: return Rules.castToULong(V); - case Type::LongTyID: return Rules.castToLong(V); - case Type::FloatTyID: return Rules.castToFloat(V); - case Type::DoubleTyID: return Rules.castToDouble(V); - case Type::PointerTyID: - return Rules.castToPointer(V, cast(DestTy)); - // what about packed ? - default: return 0; - } + assert(0 && "Failed to cast constant expression"); + return 0; } Constant *llvm::ConstantFoldSelectInstruction(const Constant *Cond, const Constant *V1, const Constant *V2) { - if (const ConstantBool *CB = dyn_cast(Cond)) - return const_cast(CB->getValue() ? V1 : V2); + if (const ConstantInt *CB = dyn_cast(Cond)) + return const_cast(CB->getZExtValue() ? V1 : V2); if (isa(V1)) return const_cast(V2); if (isa(V2)) return const_cast(V1); @@ -1029,89 +321,436 @@ Constant *llvm::ConstantFoldSelectInstruction(const Constant *Cond, return 0; } -Constant *llvm::ConstantFoldExtractElementInstruction(const Constant *Val, - const Constant *Idx) { - if (isa(Val)) // ee(undef, x) -> undef - return UndefValue::get(cast(Val->getType())->getElementType()); - if (Val->isNullValue()) // ee(zero, x) -> zero - return Constant::getNullValue( - cast(Val->getType())->getElementType()); - - if (const ConstantPacked *CVal = dyn_cast(Val)) { - if (const ConstantInt *CIdx = dyn_cast(Idx)) { - return const_cast(CVal->getOperand(CIdx->getZExtValue())); - } else if (isa(Idx)) { - // ee({w,x,y,z}, undef) -> w (an arbitrary value). - return const_cast(CVal->getOperand(0)); +Constant *llvm::ConstantFoldExtractElementInstruction(const Constant *Val, + const Constant *Idx) { + if (isa(Val)) // ee(undef, x) -> undef + return UndefValue::get(cast(Val->getType())->getElementType()); + if (Val->isNullValue()) // ee(zero, x) -> zero + return Constant::getNullValue( + cast(Val->getType())->getElementType()); + + if (const ConstantVector *CVal = dyn_cast(Val)) { + if (const ConstantInt *CIdx = dyn_cast(Idx)) { + return const_cast(CVal->getOperand(CIdx->getZExtValue())); + } else if (isa(Idx)) { + // ee({w,x,y,z}, undef) -> w (an arbitrary value). + return const_cast(CVal->getOperand(0)); + } + } + return 0; +} + +Constant *llvm::ConstantFoldInsertElementInstruction(const Constant *Val, + const Constant *Elt, + const Constant *Idx) { + const ConstantInt *CIdx = dyn_cast(Idx); + if (!CIdx) return 0; + APInt idxVal = CIdx->getValue(); + if (isa(Val)) { + // Insertion of scalar constant into vector undef + // Optimize away insertion of undef + if (isa(Elt)) + return const_cast(Val); + // Otherwise break the aggregate undef into multiple undefs and do + // the insertion + unsigned numOps = + cast(Val->getType())->getNumElements(); + std::vector Ops; + Ops.reserve(numOps); + for (unsigned i = 0; i < numOps; ++i) { + const Constant *Op = + (idxVal == i) ? Elt : UndefValue::get(Elt->getType()); + Ops.push_back(const_cast(Op)); + } + return ConstantVector::get(Ops); + } + if (isa(Val)) { + // Insertion of scalar constant into vector aggregate zero + // Optimize away insertion of zero + if (Elt->isNullValue()) + return const_cast(Val); + // Otherwise break the aggregate zero into multiple zeros and do + // the insertion + unsigned numOps = + cast(Val->getType())->getNumElements(); + std::vector Ops; + Ops.reserve(numOps); + for (unsigned i = 0; i < numOps; ++i) { + const Constant *Op = + (idxVal == i) ? Elt : Constant::getNullValue(Elt->getType()); + Ops.push_back(const_cast(Op)); + } + return ConstantVector::get(Ops); + } + if (const ConstantVector *CVal = dyn_cast(Val)) { + // Insertion of scalar constant into vector constant + std::vector Ops; + Ops.reserve(CVal->getNumOperands()); + for (unsigned i = 0; i < CVal->getNumOperands(); ++i) { + const Constant *Op = + (idxVal == i) ? Elt : cast(CVal->getOperand(i)); + Ops.push_back(const_cast(Op)); + } + return ConstantVector::get(Ops); + } + return 0; +} + +/// GetVectorElement - If C is a ConstantVector, ConstantAggregateZero or Undef +/// return the specified element value. Otherwise return null. +static Constant *GetVectorElement(const Constant *C, unsigned EltNo) { + if (const ConstantVector *CV = dyn_cast(C)) + return const_cast(CV->getOperand(EltNo)); + + const Type *EltTy = cast(C->getType())->getElementType(); + if (isa(C)) + return Constant::getNullValue(EltTy); + if (isa(C)) + return UndefValue::get(EltTy); + return 0; +} + +Constant *llvm::ConstantFoldShuffleVectorInstruction(const Constant *V1, + const Constant *V2, + const Constant *Mask) { + // Undefined shuffle mask -> undefined value. + if (isa(Mask)) return UndefValue::get(V1->getType()); + + unsigned NumElts = cast(V1->getType())->getNumElements(); + const Type *EltTy = cast(V1->getType())->getElementType(); + + // Loop over the shuffle mask, evaluating each element. + SmallVector Result; + for (unsigned i = 0; i != NumElts; ++i) { + Constant *InElt = GetVectorElement(Mask, i); + if (InElt == 0) return 0; + + if (isa(InElt)) + InElt = UndefValue::get(EltTy); + else if (ConstantInt *CI = dyn_cast(InElt)) { + unsigned Elt = CI->getZExtValue(); + if (Elt >= NumElts*2) + InElt = UndefValue::get(EltTy); + else if (Elt >= NumElts) + InElt = GetVectorElement(V2, Elt-NumElts); + else + InElt = GetVectorElement(V1, Elt); + if (InElt == 0) return 0; + } else { + // Unknown value. + return 0; + } + Result.push_back(InElt); + } + + return ConstantVector::get(&Result[0], Result.size()); +} + +/// EvalVectorOp - Given two vector constants and a function pointer, apply the +/// function pointer to each element pair, producing a new ConstantVector +/// constant. Either or both of V1 and V2 may be NULL, meaning a +/// ConstantAggregateZero operand. +static Constant *EvalVectorOp(const ConstantVector *V1, + const ConstantVector *V2, + const VectorType *VTy, + Constant *(*FP)(Constant*, Constant*)) { + std::vector Res; + const Type *EltTy = VTy->getElementType(); + for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) { + const Constant *C1 = V1 ? V1->getOperand(i) : Constant::getNullValue(EltTy); + const Constant *C2 = V2 ? V2->getOperand(i) : Constant::getNullValue(EltTy); + Res.push_back(FP(const_cast(C1), + const_cast(C2))); + } + return ConstantVector::get(Res); +} + +Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, + const Constant *C1, + const Constant *C2) { + // No compile-time operations on this type yet. + if (C1->getType() == Type::PPC_FP128Ty) + return 0; + + // Handle UndefValue up front + if (isa(C1) || isa(C2)) { + switch (Opcode) { + case Instruction::Add: + case Instruction::Sub: + case Instruction::Xor: + return UndefValue::get(C1->getType()); + case Instruction::Mul: + case Instruction::And: + return Constant::getNullValue(C1->getType()); + case Instruction::UDiv: + case Instruction::SDiv: + case Instruction::FDiv: + case Instruction::URem: + case Instruction::SRem: + case Instruction::FRem: + if (!isa(C2)) // undef / X -> 0 + return Constant::getNullValue(C1->getType()); + return const_cast(C2); // X / undef -> undef + case Instruction::Or: // X | undef -> -1 + if (const VectorType *PTy = dyn_cast(C1->getType())) + return ConstantVector::getAllOnesValue(PTy); + return ConstantInt::getAllOnesValue(C1->getType()); + case Instruction::LShr: + if (isa(C2) && isa(C1)) + return const_cast(C1); // undef lshr undef -> undef + return Constant::getNullValue(C1->getType()); // X lshr undef -> 0 + // undef lshr X -> 0 + case Instruction::AShr: + if (!isa(C2)) + return const_cast(C1); // undef ashr X --> undef + else if (isa(C1)) + return const_cast(C1); // undef ashr undef -> undef + else + return const_cast(C1); // X ashr undef --> X + case Instruction::Shl: + // undef << X -> 0 or X << undef -> 0 + return Constant::getNullValue(C1->getType()); + } + } + + if (const ConstantExpr *CE1 = dyn_cast(C1)) { + if (isa(C2)) { + // There are many possible foldings we could do here. We should probably + // at least fold add of a pointer with an integer into the appropriate + // getelementptr. This will improve alias analysis a bit. + } else { + // Just implement a couple of simple identities. + switch (Opcode) { + case Instruction::Add: + if (C2->isNullValue()) return const_cast(C1); // X + 0 == X + break; + case Instruction::Sub: + if (C2->isNullValue()) return const_cast(C1); // X - 0 == X + break; + case Instruction::Mul: + if (C2->isNullValue()) return const_cast(C2); // X * 0 == 0 + if (const ConstantInt *CI = dyn_cast(C2)) + if (CI->equalsInt(1)) + return const_cast(C1); // X * 1 == X + break; + case Instruction::UDiv: + case Instruction::SDiv: + if (const ConstantInt *CI = dyn_cast(C2)) + if (CI->equalsInt(1)) + return const_cast(C1); // X / 1 == X + break; + case Instruction::URem: + case Instruction::SRem: + if (const ConstantInt *CI = dyn_cast(C2)) + if (CI->equalsInt(1)) + return Constant::getNullValue(CI->getType()); // X % 1 == 0 + break; + case Instruction::And: + if (const ConstantInt *CI = dyn_cast(C2)) { + if (CI->isZero()) return const_cast(C2); // X & 0 == 0 + if (CI->isAllOnesValue()) + return const_cast(C1); // X & -1 == X + + // (zext i32 to i64) & 4294967295 -> (zext i32 to i64) + if (CE1->getOpcode() == Instruction::ZExt) { + APInt PossiblySetBits + = cast(CE1->getOperand(0)->getType())->getMask(); + PossiblySetBits.zext(C1->getType()->getPrimitiveSizeInBits()); + if ((PossiblySetBits & CI->getValue()) == PossiblySetBits) + return const_cast(C1); + } + } + if (CE1->isCast() && isa(CE1->getOperand(0))) { + GlobalValue *CPR = cast(CE1->getOperand(0)); + + // Functions are at least 4-byte aligned. If and'ing the address of a + // function with a constant < 4, fold it to zero. + if (const ConstantInt *CI = dyn_cast(C2)) + if (CI->getValue().ult(APInt(CI->getType()->getBitWidth(),4)) && + isa(CPR)) + return Constant::getNullValue(CI->getType()); + } + break; + case Instruction::Or: + if (C2->isNullValue()) return const_cast(C1); // X | 0 == X + if (const ConstantInt *CI = dyn_cast(C2)) + if (CI->isAllOnesValue()) + return const_cast(C2); // X | -1 == -1 + break; + case Instruction::Xor: + if (C2->isNullValue()) return const_cast(C1); // X ^ 0 == X + break; + case Instruction::AShr: + // ashr (zext C to Ty), C2 -> lshr (zext C, CSA), C2 + if (CE1->getOpcode() == Instruction::ZExt) // Top bits known zero. + return ConstantExpr::getLShr(const_cast(C1), + const_cast(C2)); + break; + } } - } - return 0; -} + } else if (isa(C2)) { + // If C2 is a constant expr and C1 isn't, flop them around and fold the + // other way if possible. + switch (Opcode) { + case Instruction::Add: + case Instruction::Mul: + case Instruction::And: + case Instruction::Or: + case Instruction::Xor: + // No change of opcode required. + return ConstantFoldBinaryInstruction(Opcode, C2, C1); -Constant *llvm::ConstantFoldInsertElementInstruction(const Constant *Val, - const Constant *Elt, - const Constant *Idx) { - const ConstantInt *CIdx = dyn_cast(Idx); - if (!CIdx) return 0; - uint64_t idxVal = CIdx->getZExtValue(); - if (isa(Val)) { - // Insertion of scalar constant into packed undef - // Optimize away insertion of undef - if (isa(Elt)) - return const_cast(Val); - // Otherwise break the aggregate undef into multiple undefs and do - // the insertion - unsigned numOps = - cast(Val->getType())->getNumElements(); - std::vector Ops; - Ops.reserve(numOps); - for (unsigned i = 0; i < numOps; ++i) { - const Constant *Op = - (i == idxVal) ? Elt : UndefValue::get(Elt->getType()); - Ops.push_back(const_cast(Op)); + case Instruction::Shl: + case Instruction::LShr: + case Instruction::AShr: + case Instruction::Sub: + case Instruction::SDiv: + case Instruction::UDiv: + case Instruction::FDiv: + case Instruction::URem: + case Instruction::SRem: + case Instruction::FRem: + default: // These instructions cannot be flopped around. + return 0; } - return ConstantPacked::get(Ops); } - if (isa(Val)) { - // Insertion of scalar constant into packed aggregate zero - // Optimize away insertion of zero - if (Elt->isNullValue()) - return const_cast(Val); - // Otherwise break the aggregate zero into multiple zeros and do - // the insertion - unsigned numOps = - cast(Val->getType())->getNumElements(); - std::vector Ops; - Ops.reserve(numOps); - for (unsigned i = 0; i < numOps; ++i) { - const Constant *Op = - (i == idxVal) ? Elt : Constant::getNullValue(Elt->getType()); - Ops.push_back(const_cast(Op)); + + // At this point we know neither constant is an UndefValue nor a ConstantExpr + // so look at directly computing the value. + if (const ConstantInt *CI1 = dyn_cast(C1)) { + if (const ConstantInt *CI2 = dyn_cast(C2)) { + using namespace APIntOps; + APInt C1V = CI1->getValue(); + APInt C2V = CI2->getValue(); + switch (Opcode) { + default: + break; + case Instruction::Add: + return ConstantInt::get(C1V + C2V); + case Instruction::Sub: + return ConstantInt::get(C1V - C2V); + case Instruction::Mul: + return ConstantInt::get(C1V * C2V); + case Instruction::UDiv: + if (CI2->isNullValue()) + return 0; // X / 0 -> can't fold + return ConstantInt::get(C1V.udiv(C2V)); + case Instruction::SDiv: + if (CI2->isNullValue()) + return 0; // X / 0 -> can't fold + if (C2V.isAllOnesValue() && C1V.isMinSignedValue()) + return 0; // MIN_INT / -1 -> overflow + return ConstantInt::get(C1V.sdiv(C2V)); + case Instruction::URem: + if (C2->isNullValue()) + return 0; // X / 0 -> can't fold + return ConstantInt::get(C1V.urem(C2V)); + case Instruction::SRem: + if (CI2->isNullValue()) + return 0; // X % 0 -> can't fold + if (C2V.isAllOnesValue() && C1V.isMinSignedValue()) + return 0; // MIN_INT % -1 -> overflow + return ConstantInt::get(C1V.srem(C2V)); + case Instruction::And: + return ConstantInt::get(C1V & C2V); + case Instruction::Or: + return ConstantInt::get(C1V | C2V); + case Instruction::Xor: + return ConstantInt::get(C1V ^ C2V); + case Instruction::Shl: + if (uint32_t shiftAmt = C2V.getZExtValue()) + if (shiftAmt < C1V.getBitWidth()) + return ConstantInt::get(C1V.shl(shiftAmt)); + else + return UndefValue::get(C1->getType()); // too big shift is undef + return const_cast(CI1); // Zero shift is identity + case Instruction::LShr: + if (uint32_t shiftAmt = C2V.getZExtValue()) + if (shiftAmt < C1V.getBitWidth()) + return ConstantInt::get(C1V.lshr(shiftAmt)); + else + return UndefValue::get(C1->getType()); // too big shift is undef + return const_cast(CI1); // Zero shift is identity + case Instruction::AShr: + if (uint32_t shiftAmt = C2V.getZExtValue()) + if (shiftAmt < C1V.getBitWidth()) + return ConstantInt::get(C1V.ashr(shiftAmt)); + else + return UndefValue::get(C1->getType()); // too big shift is undef + return const_cast(CI1); // Zero shift is identity + } } - return ConstantPacked::get(Ops); - } - if (const ConstantPacked *CVal = dyn_cast(Val)) { - // Insertion of scalar constant into packed constant - std::vector Ops; - Ops.reserve(CVal->getNumOperands()); - for (unsigned i = 0; i < CVal->getNumOperands(); ++i) { - const Constant *Op = - (i == idxVal) ? Elt : cast(CVal->getOperand(i)); - Ops.push_back(const_cast(Op)); + } else if (const ConstantFP *CFP1 = dyn_cast(C1)) { + if (const ConstantFP *CFP2 = dyn_cast(C2)) { + APFloat C1V = CFP1->getValueAPF(); + APFloat C2V = CFP2->getValueAPF(); + APFloat C3V = C1V; // copy for modification + bool isDouble = CFP1->getType()==Type::DoubleTy; + switch (Opcode) { + default: + break; + case Instruction::Add: + (void)C3V.add(C2V, APFloat::rmNearestTiesToEven); + return ConstantFP::get(CFP1->getType(), C3V); + case Instruction::Sub: + (void)C3V.subtract(C2V, APFloat::rmNearestTiesToEven); + return ConstantFP::get(CFP1->getType(), C3V); + case Instruction::Mul: + (void)C3V.multiply(C2V, APFloat::rmNearestTiesToEven); + return ConstantFP::get(CFP1->getType(), C3V); + case Instruction::FDiv: + (void)C3V.divide(C2V, APFloat::rmNearestTiesToEven); + return ConstantFP::get(CFP1->getType(), C3V); + case Instruction::FRem: + if (C2V.isZero()) + // IEEE 754, Section 7.1, #5 + return ConstantFP::get(CFP1->getType(), isDouble ? + APFloat(std::numeric_limits::quiet_NaN()) : + APFloat(std::numeric_limits::quiet_NaN())); + (void)C3V.mod(C2V, APFloat::rmNearestTiesToEven); + return ConstantFP::get(CFP1->getType(), C3V); + } + } + } else if (const VectorType *VTy = dyn_cast(C1->getType())) { + const ConstantVector *CP1 = dyn_cast(C1); + const ConstantVector *CP2 = dyn_cast(C2); + if ((CP1 != NULL || isa(C1)) && + (CP2 != NULL || isa(C2))) { + switch (Opcode) { + default: + break; + case Instruction::Add: + return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getAdd); + case Instruction::Sub: + return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getSub); + case Instruction::Mul: + return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getMul); + case Instruction::UDiv: + return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getUDiv); + case Instruction::SDiv: + return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getSDiv); + case Instruction::FDiv: + return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getFDiv); + case Instruction::URem: + return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getURem); + case Instruction::SRem: + return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getSRem); + case Instruction::FRem: + return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getFRem); + case Instruction::And: + return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getAnd); + case Instruction::Or: + return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getOr); + case Instruction::Xor: + return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getXor); + } } - return ConstantPacked::get(Ops); } - return 0; -} -Constant *llvm::ConstantFoldShuffleVectorInstruction(const Constant *V1, - const Constant *V2, - const Constant *Mask) { - // TODO: + // We don't know how to fold this return 0; } - /// isZeroSizedType - This type is zero sized if its an array or structure of /// zero sized types. The only leaf zero sized type is an empty structure. static bool isMaybeZeroSizedType(const Type *Ty) { @@ -1139,23 +778,20 @@ static bool isMaybeZeroSizedType(const Type *Ty) { static int IdxCompare(Constant *C1, Constant *C2, const Type *ElTy) { if (C1 == C2) return 0; - // Ok, we found a different index. Are either of the operands ConstantExprs? - // If so, we can't do anything with them. + // Ok, we found a different index. If they are not ConstantInt, we can't do + // anything with them. if (!isa(C1) || !isa(C2)) return -2; // don't know! // Ok, we have two differing integer indices. Sign extend them to be the same // type. Long is always big enough, so we use it. - if (C1->getType() != Type::LongTy && C1->getType() != Type::ULongTy) - C1 = ConstantExpr::getSExt(C1, Type::LongTy); - else - C1 = ConstantExpr::getBitCast(C1, Type::LongTy); - if (C2->getType() != Type::LongTy && C1->getType() != Type::ULongTy) - C2 = ConstantExpr::getSExt(C2, Type::LongTy); - else - C2 = ConstantExpr::getBitCast(C2, Type::LongTy); + if (C1->getType() != Type::Int64Ty) + C1 = ConstantExpr::getSExt(C1, Type::Int64Ty); + + if (C2->getType() != Type::Int64Ty) + C2 = ConstantExpr::getSExt(C2, Type::Int64Ty); - if (C1 == C2) return 0; // Are they just differing types? + if (C1 == C2) return 0; // They are equal // If the type being indexed over is really just a zero sized type, there is // no pointer difference being made here. @@ -1171,68 +807,153 @@ static int IdxCompare(Constant *C1, Constant *C2, const Type *ElTy) { return 1; } -/// evaluateRelation - This function determines if there is anything we can +/// evaluateFCmpRelation - This function determines if there is anything we can +/// decide about the two constants provided. This doesn't need to handle simple +/// things like ConstantFP comparisons, but should instead handle ConstantExprs. +/// If we can determine that the two constants have a particular relation to +/// each other, we should return the corresponding FCmpInst predicate, +/// otherwise return FCmpInst::BAD_FCMP_PREDICATE. This is used below in +/// ConstantFoldCompareInstruction. +/// +/// To simplify this code we canonicalize the relation so that the first +/// operand is always the most "complex" of the two. We consider ConstantFP +/// to be the simplest, and ConstantExprs to be the most complex. +static FCmpInst::Predicate evaluateFCmpRelation(const Constant *V1, + const Constant *V2) { + assert(V1->getType() == V2->getType() && + "Cannot compare values of different types!"); + + // No compile-time operations on this type yet. + if (V1->getType() == Type::PPC_FP128Ty) + return FCmpInst::BAD_FCMP_PREDICATE; + + // Handle degenerate case quickly + if (V1 == V2) return FCmpInst::FCMP_OEQ; + + if (!isa(V1)) { + if (!isa(V2)) { + // We distilled thisUse the standard constant folder for a few cases + ConstantInt *R = 0; + Constant *C1 = const_cast(V1); + Constant *C2 = const_cast(V2); + R = dyn_cast( + ConstantExpr::getFCmp(FCmpInst::FCMP_OEQ, C1, C2)); + if (R && !R->isZero()) + return FCmpInst::FCMP_OEQ; + R = dyn_cast( + ConstantExpr::getFCmp(FCmpInst::FCMP_OLT, C1, C2)); + if (R && !R->isZero()) + return FCmpInst::FCMP_OLT; + R = dyn_cast( + ConstantExpr::getFCmp(FCmpInst::FCMP_OGT, C1, C2)); + if (R && !R->isZero()) + return FCmpInst::FCMP_OGT; + + // Nothing more we can do + return FCmpInst::BAD_FCMP_PREDICATE; + } + + // If the first operand is simple and second is ConstantExpr, swap operands. + FCmpInst::Predicate SwappedRelation = evaluateFCmpRelation(V2, V1); + if (SwappedRelation != FCmpInst::BAD_FCMP_PREDICATE) + return FCmpInst::getSwappedPredicate(SwappedRelation); + } else { + // Ok, the LHS is known to be a constantexpr. The RHS can be any of a + // constantexpr or a simple constant. + const ConstantExpr *CE1 = cast(V1); + switch (CE1->getOpcode()) { + case Instruction::FPTrunc: + case Instruction::FPExt: + case Instruction::UIToFP: + case Instruction::SIToFP: + // We might be able to do something with these but we don't right now. + break; + default: + break; + } + } + // There are MANY other foldings that we could perform here. They will + // probably be added on demand, as they seem needed. + return FCmpInst::BAD_FCMP_PREDICATE; +} + +/// evaluateICmpRelation - This function determines if there is anything we can /// decide about the two constants provided. This doesn't need to handle simple /// things like integer comparisons, but should instead handle ConstantExprs /// and GlobalValues. If we can determine that the two constants have a -/// particular relation to each other, we should return the corresponding SetCC -/// code, otherwise return Instruction::BinaryOpsEnd. +/// particular relation to each other, we should return the corresponding ICmp +/// predicate, otherwise return ICmpInst::BAD_ICMP_PREDICATE. /// /// To simplify this code we canonicalize the relation so that the first /// operand is always the most "complex" of the two. We consider simple /// constants (like ConstantInt) to be the simplest, followed by /// GlobalValues, followed by ConstantExpr's (the most complex). /// -static Instruction::BinaryOps evaluateRelation(Constant *V1, Constant *V2) { +static ICmpInst::Predicate evaluateICmpRelation(const Constant *V1, + const Constant *V2, + bool isSigned) { assert(V1->getType() == V2->getType() && "Cannot compare different types of values!"); - if (V1 == V2) return Instruction::SetEQ; + if (V1 == V2) return ICmpInst::ICMP_EQ; if (!isa(V1) && !isa(V1)) { if (!isa(V2) && !isa(V2)) { // We distilled this down to a simple case, use the standard constant // folder. - ConstantBool *R = dyn_cast(ConstantExpr::getSetEQ(V1, V2)); - if (R && R->getValue()) return Instruction::SetEQ; - R = dyn_cast(ConstantExpr::getSetLT(V1, V2)); - if (R && R->getValue()) return Instruction::SetLT; - R = dyn_cast(ConstantExpr::getSetGT(V1, V2)); - if (R && R->getValue()) return Instruction::SetGT; + ConstantInt *R = 0; + Constant *C1 = const_cast(V1); + Constant *C2 = const_cast(V2); + ICmpInst::Predicate pred = ICmpInst::ICMP_EQ; + R = dyn_cast(ConstantExpr::getICmp(pred, C1, C2)); + if (R && !R->isZero()) + return pred; + pred = isSigned ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT; + R = dyn_cast(ConstantExpr::getICmp(pred, C1, C2)); + if (R && !R->isZero()) + return pred; + pred = isSigned ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT; + R = dyn_cast(ConstantExpr::getICmp(pred, C1, C2)); + if (R && !R->isZero()) + return pred; // If we couldn't figure it out, bail. - return Instruction::BinaryOpsEnd; + return ICmpInst::BAD_ICMP_PREDICATE; } // If the first operand is simple, swap operands. - Instruction::BinaryOps SwappedRelation = evaluateRelation(V2, V1); - if (SwappedRelation != Instruction::BinaryOpsEnd) - return SetCondInst::getSwappedCondition(SwappedRelation); + ICmpInst::Predicate SwappedRelation = + evaluateICmpRelation(V2, V1, isSigned); + if (SwappedRelation != ICmpInst::BAD_ICMP_PREDICATE) + return ICmpInst::getSwappedPredicate(SwappedRelation); } else if (const GlobalValue *CPR1 = dyn_cast(V1)) { if (isa(V2)) { // Swap as necessary. - Instruction::BinaryOps SwappedRelation = evaluateRelation(V2, V1); - if (SwappedRelation != Instruction::BinaryOpsEnd) - return SetCondInst::getSwappedCondition(SwappedRelation); + ICmpInst::Predicate SwappedRelation = + evaluateICmpRelation(V2, V1, isSigned); + if (SwappedRelation != ICmpInst::BAD_ICMP_PREDICATE) + return ICmpInst::getSwappedPredicate(SwappedRelation); else - return Instruction::BinaryOpsEnd; + return ICmpInst::BAD_ICMP_PREDICATE; } // Now we know that the RHS is a GlobalValue or simple constant, // which (since the types must match) means that it's a ConstantPointerNull. if (const GlobalValue *CPR2 = dyn_cast(V2)) { - if (!CPR1->hasExternalWeakLinkage() || !CPR2->hasExternalWeakLinkage()) - return Instruction::SetNE; + // Don't try to decide equality of aliases. + if (!isa(CPR1) && !isa(CPR2)) + if (!CPR1->hasExternalWeakLinkage() || !CPR2->hasExternalWeakLinkage()) + return ICmpInst::ICMP_NE; } else { - // GlobalVals can never be null. assert(isa(V2) && "Canonicalization guarantee!"); - if (!CPR1->hasExternalWeakLinkage()) - return Instruction::SetNE; + // GlobalVals can never be null. Don't try to evaluate aliases. + if (!CPR1->hasExternalWeakLinkage() && !isa(CPR1)) + return ICmpInst::ICMP_NE; } } else { // Ok, the LHS is known to be a constantexpr. The RHS can be any of a // constantexpr, a CPR, or a simple constant. - ConstantExpr *CE1 = cast(V1); - Constant *CE1Op0 = CE1->getOperand(0); + const ConstantExpr *CE1 = cast(V1); + const Constant *CE1Op0 = CE1->getOperand(0); switch (CE1->getOpcode()) { case Instruction::Trunc: @@ -1240,30 +961,38 @@ static Instruction::BinaryOps evaluateRelation(Constant *V1, Constant *V2) { case Instruction::FPExt: case Instruction::FPToUI: case Instruction::FPToSI: - break; // We don't do anything with floating point. - case Instruction::ZExt: - case Instruction::SExt: + break; // We can't evaluate floating point casts or truncations. + case Instruction::UIToFP: case Instruction::SIToFP: - case Instruction::PtrToInt: - case Instruction::IntToPtr: case Instruction::BitCast: + case Instruction::ZExt: + case Instruction::SExt: // If the cast is not actually changing bits, and the second operand is a // null pointer, do the comparison with the pre-casted value. if (V2->isNullValue() && - (isa(CE1->getType()) || CE1->getType()->isIntegral())) - return evaluateRelation(CE1Op0, - Constant::getNullValue(CE1Op0->getType())); + (isa(CE1->getType()) || CE1->getType()->isInteger())) { + bool sgnd = isSigned; + if (CE1->getOpcode() == Instruction::ZExt) isSigned = false; + if (CE1->getOpcode() == Instruction::SExt) isSigned = true; + return evaluateICmpRelation(CE1Op0, + Constant::getNullValue(CE1Op0->getType()), + sgnd); + } // If the dest type is a pointer type, and the RHS is a constantexpr cast // from the same type as the src of the LHS, evaluate the inputs. This is - // important for things like "seteq (cast 4 to int*), (cast 5 to int*)", + // important for things like "icmp eq (cast 4 to int*), (cast 5 to int*)", // which happens a lot in compilers with tagged integers. - if (ConstantExpr *CE2 = dyn_cast(V2)) - if (isa(CE1->getType()) && CE2->isCast() && + if (const ConstantExpr *CE2 = dyn_cast(V2)) + if (CE2->isCast() && isa(CE1->getType()) && CE1->getOperand(0)->getType() == CE2->getOperand(0)->getType() && - CE1->getOperand(0)->getType()->isIntegral()) { - return evaluateRelation(CE1->getOperand(0), CE2->getOperand(0)); + CE1->getOperand(0)->getType()->isInteger()) { + bool sgnd = isSigned; + if (CE1->getOpcode() == Instruction::ZExt) isSigned = false; + if (CE1->getOpcode() == Instruction::SExt) isSigned = true; + return evaluateICmpRelation(CE1->getOperand(0), CE2->getOperand(0), + sgnd); } break; @@ -1273,24 +1002,24 @@ static Instruction::BinaryOps evaluateRelation(Constant *V1, Constant *V2) { if (isa(V2)) { // If we are comparing a GEP to a null pointer, check to see if the base // of the GEP equals the null pointer. - if (GlobalValue *GV = dyn_cast(CE1Op0)) { + if (const GlobalValue *GV = dyn_cast(CE1Op0)) { if (GV->hasExternalWeakLinkage()) // Weak linkage GVals could be zero or not. We're comparing that // to null pointer so its greater-or-equal - return Instruction::SetGE; + return isSigned ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_UGE; else // If its not weak linkage, the GVal must have a non-zero address // so the result is greater-than - return Instruction::SetGT; + return isSigned ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT; } else if (isa(CE1Op0)) { // If we are indexing from a null pointer, check to see if we have any // non-zero indices. for (unsigned i = 1, e = CE1->getNumOperands(); i != e; ++i) if (!CE1->getOperand(i)->isNullValue()) // Offsetting from null, must not be equal. - return Instruction::SetGT; + return isSigned ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT; // Only zero indexes from null, must still be zero. - return Instruction::SetEQ; + return ICmpInst::ICMP_EQ; } // Otherwise, we can't really say if the first operand is null or not. } else if (const GlobalValue *CPR2 = dyn_cast(V2)) { @@ -1298,11 +1027,11 @@ static Instruction::BinaryOps evaluateRelation(Constant *V1, Constant *V2) { if (CPR2->hasExternalWeakLinkage()) // Weak linkage GVals could be zero or not. We're comparing it to // a null pointer, so its less-or-equal - return Instruction::SetLE; + return isSigned ? ICmpInst::ICMP_SLE : ICmpInst::ICMP_ULE; else // If its not weak linkage, the GVal must have a non-zero address // so the result is less-than - return Instruction::SetLT; + return isSigned ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT; } else if (const GlobalValue *CPR1 = dyn_cast(CE1Op0)) { if (CPR1 == CPR2) { // If this is a getelementptr of the same global, then it must be @@ -1312,11 +1041,11 @@ static Instruction::BinaryOps evaluateRelation(Constant *V1, Constant *V2) { assert(CE1->getNumOperands() == 2 && !CE1->getOperand(1)->isNullValue() && "Suprising getelementptr!"); - return Instruction::SetGT; + return isSigned ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT; } else { // If they are different globals, we don't know what the value is, // but they can't be equal. - return Instruction::SetNE; + return ICmpInst::ICMP_NE; } } } else { @@ -1332,7 +1061,7 @@ static Instruction::BinaryOps evaluateRelation(Constant *V1, Constant *V2) { // obviously to the same or different globals. if (isa(CE1Op0) && isa(CE2Op0)) { if (CE1Op0 != CE2Op0) // Don't know relative ordering, but not equal - return Instruction::SetNE; + return ICmpInst::ICMP_NE; // Ok, we know that both getelementptr instructions are based on the // same global. From this, we can precisely determine the relative // ordering of the resultant pointers. @@ -1344,335 +1073,342 @@ static Instruction::BinaryOps evaluateRelation(Constant *V1, Constant *V2) { ++i, ++GTI) switch (IdxCompare(CE1->getOperand(i), CE2->getOperand(i), GTI.getIndexedType())) { - case -1: return Instruction::SetLT; - case 1: return Instruction::SetGT; - case -2: return Instruction::BinaryOpsEnd; + case -1: return isSigned ? ICmpInst::ICMP_SLT:ICmpInst::ICMP_ULT; + case 1: return isSigned ? ICmpInst::ICMP_SGT:ICmpInst::ICMP_UGT; + case -2: return ICmpInst::BAD_ICMP_PREDICATE; } // Ok, we ran out of things they have in common. If any leftovers // are non-zero then we have a difference, otherwise we are equal. for (; i < CE1->getNumOperands(); ++i) if (!CE1->getOperand(i)->isNullValue()) - if (isa(CE1->getOperand(i))) - return Instruction::SetGT; + if (isa(CE1->getOperand(i))) + return isSigned ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT; else - return Instruction::BinaryOpsEnd; // Might be equal. + return ICmpInst::BAD_ICMP_PREDICATE; // Might be equal. for (; i < CE2->getNumOperands(); ++i) if (!CE2->getOperand(i)->isNullValue()) - if (isa(CE2->getOperand(i))) - return Instruction::SetLT; + if (isa(CE2->getOperand(i))) + return isSigned ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT; else - return Instruction::BinaryOpsEnd; // Might be equal. - return Instruction::SetEQ; + return ICmpInst::BAD_ICMP_PREDICATE; // Might be equal. + return ICmpInst::ICMP_EQ; } } } - default: break; } } - return Instruction::BinaryOpsEnd; + return ICmpInst::BAD_ICMP_PREDICATE; } -Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, - const Constant *V1, - const Constant *V2) { - Constant *C = 0; - switch (Opcode) { - default: break; - case Instruction::Add: C = ConstRules::get(V1, V2).add(V1, V2); break; - case Instruction::Sub: C = ConstRules::get(V1, V2).sub(V1, V2); break; - case Instruction::Mul: C = ConstRules::get(V1, V2).mul(V1, V2); break; - case Instruction::UDiv: C = ConstRules::get(V1, V2).udiv(V1, V2); break; - case Instruction::SDiv: C = ConstRules::get(V1, V2).sdiv(V1, V2); break; - case Instruction::FDiv: C = ConstRules::get(V1, V2).fdiv(V1, V2); break; - case Instruction::URem: C = ConstRules::get(V1, V2).urem(V1, V2); break; - case Instruction::SRem: C = ConstRules::get(V1, V2).srem(V1, V2); break; - case Instruction::FRem: C = ConstRules::get(V1, V2).frem(V1, V2); break; - case Instruction::And: C = ConstRules::get(V1, V2).op_and(V1, V2); break; - case Instruction::Or: C = ConstRules::get(V1, V2).op_or (V1, V2); break; - case Instruction::Xor: C = ConstRules::get(V1, V2).op_xor(V1, V2); break; - case Instruction::Shl: C = ConstRules::get(V1, V2).shl(V1, V2); break; - case Instruction::LShr: C = ConstRules::get(V1, V2).lshr(V1, V2); break; - case Instruction::AShr: C = ConstRules::get(V1, V2).ashr(V1, V2); break; - case Instruction::SetEQ: - // SetEQ(null,GV) -> false - if (V1->isNullValue()) { - if (const GlobalValue *GV = dyn_cast(V2)) - if (!GV->hasExternalWeakLinkage()) - return ConstantBool::getFalse(); - // SetEQ(GV,null) -> false - } else if (V2->isNullValue()) { - if (const GlobalValue *GV = dyn_cast(V1)) - if (!GV->hasExternalWeakLinkage()) - return ConstantBool::getFalse(); +Constant *llvm::ConstantFoldCompareInstruction(unsigned short pred, + const Constant *C1, + const Constant *C2) { + + // Handle some degenerate cases first + if (isa(C1) || isa(C2)) + return UndefValue::get(Type::Int1Ty); + + // No compile-time operations on this type yet. + if (C1->getType() == Type::PPC_FP128Ty) + return 0; + + // icmp eq/ne(null,GV) -> false/true + if (C1->isNullValue()) { + if (const GlobalValue *GV = dyn_cast(C2)) + // Don't try to evaluate aliases. External weak GV can be null. + if (!isa(GV) && !GV->hasExternalWeakLinkage()) + if (pred == ICmpInst::ICMP_EQ) + return ConstantInt::getFalse(); + else if (pred == ICmpInst::ICMP_NE) + return ConstantInt::getTrue(); + // icmp eq/ne(GV,null) -> false/true + } else if (C2->isNullValue()) { + if (const GlobalValue *GV = dyn_cast(C1)) + // Don't try to evaluate aliases. External weak GV can be null. + if (!isa(GV) && !GV->hasExternalWeakLinkage()) + if (pred == ICmpInst::ICMP_EQ) + return ConstantInt::getFalse(); + else if (pred == ICmpInst::ICMP_NE) + return ConstantInt::getTrue(); + } + + if (isa(C1) && isa(C2)) { + APInt V1 = cast(C1)->getValue(); + APInt V2 = cast(C2)->getValue(); + switch (pred) { + default: assert(0 && "Invalid ICmp Predicate"); return 0; + case ICmpInst::ICMP_EQ: return ConstantInt::get(Type::Int1Ty, V1 == V2); + case ICmpInst::ICMP_NE: return ConstantInt::get(Type::Int1Ty, V1 != V2); + case ICmpInst::ICMP_SLT:return ConstantInt::get(Type::Int1Ty, V1.slt(V2)); + case ICmpInst::ICMP_SGT:return ConstantInt::get(Type::Int1Ty, V1.sgt(V2)); + case ICmpInst::ICMP_SLE:return ConstantInt::get(Type::Int1Ty, V1.sle(V2)); + case ICmpInst::ICMP_SGE:return ConstantInt::get(Type::Int1Ty, V1.sge(V2)); + case ICmpInst::ICMP_ULT:return ConstantInt::get(Type::Int1Ty, V1.ult(V2)); + case ICmpInst::ICMP_UGT:return ConstantInt::get(Type::Int1Ty, V1.ugt(V2)); + case ICmpInst::ICMP_ULE:return ConstantInt::get(Type::Int1Ty, V1.ule(V2)); + case ICmpInst::ICMP_UGE:return ConstantInt::get(Type::Int1Ty, V1.uge(V2)); } - C = ConstRules::get(V1, V2).equalto(V1, V2); - break; - case Instruction::SetLT: C = ConstRules::get(V1, V2).lessthan(V1, V2);break; - case Instruction::SetGT: C = ConstRules::get(V1, V2).lessthan(V2, V1);break; - case Instruction::SetNE: - // SetNE(null,GV) -> true - if (V1->isNullValue()) { - if (const GlobalValue *GV = dyn_cast(V2)) - if (!GV->hasExternalWeakLinkage()) - return ConstantBool::getTrue(); - // SetNE(GV,null) -> true - } else if (V2->isNullValue()) { - if (const GlobalValue *GV = dyn_cast(V1)) - if (!GV->hasExternalWeakLinkage()) - return ConstantBool::getTrue(); + } else if (isa(C1) && isa(C2)) { + APFloat C1V = cast(C1)->getValueAPF(); + APFloat C2V = cast(C2)->getValueAPF(); + APFloat::cmpResult R = C1V.compare(C2V); + switch (pred) { + default: assert(0 && "Invalid FCmp Predicate"); return 0; + case FCmpInst::FCMP_FALSE: return ConstantInt::getFalse(); + case FCmpInst::FCMP_TRUE: return ConstantInt::getTrue(); + case FCmpInst::FCMP_UNO: + return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpUnordered); + case FCmpInst::FCMP_ORD: + return ConstantInt::get(Type::Int1Ty, R!=APFloat::cmpUnordered); + case FCmpInst::FCMP_UEQ: + return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpUnordered || + R==APFloat::cmpEqual); + case FCmpInst::FCMP_OEQ: + return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpEqual); + case FCmpInst::FCMP_UNE: + return ConstantInt::get(Type::Int1Ty, R!=APFloat::cmpEqual); + case FCmpInst::FCMP_ONE: + return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpLessThan || + R==APFloat::cmpGreaterThan); + case FCmpInst::FCMP_ULT: + return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpUnordered || + R==APFloat::cmpLessThan); + case FCmpInst::FCMP_OLT: + return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpLessThan); + case FCmpInst::FCMP_UGT: + return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpUnordered || + R==APFloat::cmpGreaterThan); + case FCmpInst::FCMP_OGT: + return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpGreaterThan); + case FCmpInst::FCMP_ULE: + return ConstantInt::get(Type::Int1Ty, R!=APFloat::cmpGreaterThan); + case FCmpInst::FCMP_OLE: + return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpLessThan || + R==APFloat::cmpEqual); + case FCmpInst::FCMP_UGE: + return ConstantInt::get(Type::Int1Ty, R!=APFloat::cmpLessThan); + case FCmpInst::FCMP_OGE: + return ConstantInt::get(Type::Int1Ty, R==APFloat::cmpGreaterThan || + R==APFloat::cmpEqual); + } + } else if (const ConstantVector *CP1 = dyn_cast(C1)) { + if (const ConstantVector *CP2 = dyn_cast(C2)) { + if (pred == FCmpInst::FCMP_OEQ || pred == FCmpInst::FCMP_UEQ) { + for (unsigned i = 0, e = CP1->getNumOperands(); i != e; ++i) { + Constant *C= ConstantExpr::getFCmp(FCmpInst::FCMP_OEQ, + const_cast(CP1->getOperand(i)), + const_cast(CP2->getOperand(i))); + if (ConstantInt *CB = dyn_cast(C)) + return CB; + } + // Otherwise, could not decide from any element pairs. + return 0; + } else if (pred == ICmpInst::ICMP_EQ) { + for (unsigned i = 0, e = CP1->getNumOperands(); i != e; ++i) { + Constant *C = ConstantExpr::getICmp(ICmpInst::ICMP_EQ, + const_cast(CP1->getOperand(i)), + const_cast(CP2->getOperand(i))); + if (ConstantInt *CB = dyn_cast(C)) + return CB; + } + // Otherwise, could not decide from any element pairs. + return 0; + } } - // V1 != V2 === !(V1 == V2) - C = ConstRules::get(V1, V2).equalto(V1, V2); - if (C) return ConstantExpr::getNot(C); - break; - case Instruction::SetLE: // V1 <= V2 === !(V2 < V1) - C = ConstRules::get(V1, V2).lessthan(V2, V1); - if (C) return ConstantExpr::getNot(C); - break; - case Instruction::SetGE: // V1 >= V2 === !(V1 < V2) - C = ConstRules::get(V1, V2).lessthan(V1, V2); - if (C) return ConstantExpr::getNot(C); - break; } - // If we successfully folded the expression, return it now. - if (C) return C; - - if (SetCondInst::isComparison(Opcode)) { - if (isa(V1) || isa(V2)) - return UndefValue::get(Type::BoolTy); - switch (evaluateRelation(const_cast(V1), - const_cast(V2))) { + if (C1->getType()->isFloatingPoint()) { + switch (evaluateFCmpRelation(C1, C2)) { + default: assert(0 && "Unknown relation!"); + case FCmpInst::FCMP_UNO: + case FCmpInst::FCMP_ORD: + case FCmpInst::FCMP_UEQ: + case FCmpInst::FCMP_UNE: + case FCmpInst::FCMP_ULT: + case FCmpInst::FCMP_UGT: + case FCmpInst::FCMP_ULE: + case FCmpInst::FCMP_UGE: + case FCmpInst::FCMP_TRUE: + case FCmpInst::FCMP_FALSE: + case FCmpInst::BAD_FCMP_PREDICATE: + break; // Couldn't determine anything about these constants. + case FCmpInst::FCMP_OEQ: // We know that C1 == C2 + return ConstantInt::get(Type::Int1Ty, + pred == FCmpInst::FCMP_UEQ || pred == FCmpInst::FCMP_OEQ || + pred == FCmpInst::FCMP_ULE || pred == FCmpInst::FCMP_OLE || + pred == FCmpInst::FCMP_UGE || pred == FCmpInst::FCMP_OGE); + case FCmpInst::FCMP_OLT: // We know that C1 < C2 + return ConstantInt::get(Type::Int1Ty, + pred == FCmpInst::FCMP_UNE || pred == FCmpInst::FCMP_ONE || + pred == FCmpInst::FCMP_ULT || pred == FCmpInst::FCMP_OLT || + pred == FCmpInst::FCMP_ULE || pred == FCmpInst::FCMP_OLE); + case FCmpInst::FCMP_OGT: // We know that C1 > C2 + return ConstantInt::get(Type::Int1Ty, + pred == FCmpInst::FCMP_UNE || pred == FCmpInst::FCMP_ONE || + pred == FCmpInst::FCMP_UGT || pred == FCmpInst::FCMP_OGT || + pred == FCmpInst::FCMP_UGE || pred == FCmpInst::FCMP_OGE); + case FCmpInst::FCMP_OLE: // We know that C1 <= C2 + // We can only partially decide this relation. + if (pred == FCmpInst::FCMP_UGT || pred == FCmpInst::FCMP_OGT) + return ConstantInt::getFalse(); + if (pred == FCmpInst::FCMP_ULT || pred == FCmpInst::FCMP_OLT) + return ConstantInt::getTrue(); + break; + case FCmpInst::FCMP_OGE: // We known that C1 >= C2 + // We can only partially decide this relation. + if (pred == FCmpInst::FCMP_ULT || pred == FCmpInst::FCMP_OLT) + return ConstantInt::getFalse(); + if (pred == FCmpInst::FCMP_UGT || pred == FCmpInst::FCMP_OGT) + return ConstantInt::getTrue(); + break; + case ICmpInst::ICMP_NE: // We know that C1 != C2 + // We can only partially decide this relation. + if (pred == FCmpInst::FCMP_OEQ || pred == FCmpInst::FCMP_UEQ) + return ConstantInt::getFalse(); + if (pred == FCmpInst::FCMP_ONE || pred == FCmpInst::FCMP_UNE) + return ConstantInt::getTrue(); + break; + } + } else { + // Evaluate the relation between the two constants, per the predicate. + switch (evaluateICmpRelation(C1, C2, CmpInst::isSigned(pred))) { default: assert(0 && "Unknown relational!"); - case Instruction::BinaryOpsEnd: + case ICmpInst::BAD_ICMP_PREDICATE: break; // Couldn't determine anything about these constants. - case Instruction::SetEQ: // We know the constants are equal! + case ICmpInst::ICMP_EQ: // We know the constants are equal! // If we know the constants are equal, we can decide the result of this // computation precisely. - return ConstantBool::get(Opcode == Instruction::SetEQ || - Opcode == Instruction::SetLE || - Opcode == Instruction::SetGE); - case Instruction::SetLT: - // If we know that V1 < V2, we can decide the result of this computation + return ConstantInt::get(Type::Int1Ty, + pred == ICmpInst::ICMP_EQ || + pred == ICmpInst::ICMP_ULE || + pred == ICmpInst::ICMP_SLE || + pred == ICmpInst::ICMP_UGE || + pred == ICmpInst::ICMP_SGE); + case ICmpInst::ICMP_ULT: + // If we know that C1 < C2, we can decide the result of this computation + // precisely. + return ConstantInt::get(Type::Int1Ty, + pred == ICmpInst::ICMP_ULT || + pred == ICmpInst::ICMP_NE || + pred == ICmpInst::ICMP_ULE); + case ICmpInst::ICMP_SLT: + // If we know that C1 < C2, we can decide the result of this computation + // precisely. + return ConstantInt::get(Type::Int1Ty, + pred == ICmpInst::ICMP_SLT || + pred == ICmpInst::ICMP_NE || + pred == ICmpInst::ICMP_SLE); + case ICmpInst::ICMP_UGT: + // If we know that C1 > C2, we can decide the result of this computation // precisely. - return ConstantBool::get(Opcode == Instruction::SetLT || - Opcode == Instruction::SetNE || - Opcode == Instruction::SetLE); - case Instruction::SetGT: - // If we know that V1 > V2, we can decide the result of this computation + return ConstantInt::get(Type::Int1Ty, + pred == ICmpInst::ICMP_UGT || + pred == ICmpInst::ICMP_NE || + pred == ICmpInst::ICMP_UGE); + case ICmpInst::ICMP_SGT: + // If we know that C1 > C2, we can decide the result of this computation // precisely. - return ConstantBool::get(Opcode == Instruction::SetGT || - Opcode == Instruction::SetNE || - Opcode == Instruction::SetGE); - case Instruction::SetLE: - // If we know that V1 <= V2, we can only partially decide this relation. - if (Opcode == Instruction::SetGT) return ConstantBool::getFalse(); - if (Opcode == Instruction::SetLT) return ConstantBool::getTrue(); + return ConstantInt::get(Type::Int1Ty, + pred == ICmpInst::ICMP_SGT || + pred == ICmpInst::ICMP_NE || + pred == ICmpInst::ICMP_SGE); + case ICmpInst::ICMP_ULE: + // If we know that C1 <= C2, we can only partially decide this relation. + if (pred == ICmpInst::ICMP_UGT) return ConstantInt::getFalse(); + if (pred == ICmpInst::ICMP_ULT) return ConstantInt::getTrue(); break; - - case Instruction::SetGE: - // If we know that V1 >= V2, we can only partially decide this relation. - if (Opcode == Instruction::SetLT) return ConstantBool::getFalse(); - if (Opcode == Instruction::SetGT) return ConstantBool::getTrue(); + case ICmpInst::ICMP_SLE: + // If we know that C1 <= C2, we can only partially decide this relation. + if (pred == ICmpInst::ICMP_SGT) return ConstantInt::getFalse(); + if (pred == ICmpInst::ICMP_SLT) return ConstantInt::getTrue(); break; - case Instruction::SetNE: - // If we know that V1 != V2, we can only partially decide this relation. - if (Opcode == Instruction::SetEQ) return ConstantBool::getFalse(); - if (Opcode == Instruction::SetNE) return ConstantBool::getTrue(); + case ICmpInst::ICMP_UGE: + // If we know that C1 >= C2, we can only partially decide this relation. + if (pred == ICmpInst::ICMP_ULT) return ConstantInt::getFalse(); + if (pred == ICmpInst::ICMP_UGT) return ConstantInt::getTrue(); + break; + case ICmpInst::ICMP_SGE: + // If we know that C1 >= C2, we can only partially decide this relation. + if (pred == ICmpInst::ICMP_SLT) return ConstantInt::getFalse(); + if (pred == ICmpInst::ICMP_SGT) return ConstantInt::getTrue(); break; - } - } - - if (isa(V1) || isa(V2)) { - switch (Opcode) { - case Instruction::Add: - case Instruction::Sub: - case Instruction::Xor: - return UndefValue::get(V1->getType()); - case Instruction::Mul: - case Instruction::And: - return Constant::getNullValue(V1->getType()); - case Instruction::UDiv: - case Instruction::SDiv: - case Instruction::FDiv: - case Instruction::URem: - case Instruction::SRem: - case Instruction::FRem: - if (!isa(V2)) // undef / X -> 0 - return Constant::getNullValue(V1->getType()); - return const_cast(V2); // X / undef -> undef - case Instruction::Or: // X | undef -> -1 - return ConstantInt::getAllOnesValue(V1->getType()); - case Instruction::LShr: - if (isa(V2) && isa(V1)) - return const_cast(V1); // undef lshr undef -> undef - return Constant::getNullValue(V1->getType()); // X lshr undef -> 0 - // undef lshr X -> 0 - case Instruction::AShr: - if (!isa(V2)) - return const_cast(V1); // undef ashr X --> undef - else if (isa(V1)) - return const_cast(V1); // undef ashr undef -> undef - else - return const_cast(V1); // X ashr undef --> X - case Instruction::Shl: - // undef << X -> 0 or X << undef -> 0 - return Constant::getNullValue(V1->getType()); + case ICmpInst::ICMP_NE: + // If we know that C1 != C2, we can only partially decide this relation. + if (pred == ICmpInst::ICMP_EQ) return ConstantInt::getFalse(); + if (pred == ICmpInst::ICMP_NE) return ConstantInt::getTrue(); + break; } - } - - if (const ConstantExpr *CE1 = dyn_cast(V1)) { - if (isa(V2)) { - // There are many possible foldings we could do here. We should probably - // at least fold add of a pointer with an integer into the appropriate - // getelementptr. This will improve alias analysis a bit. - } else { - // Just implement a couple of simple identities. - switch (Opcode) { - case Instruction::Add: - if (V2->isNullValue()) return const_cast(V1); // X + 0 == X - break; - case Instruction::Sub: - if (V2->isNullValue()) return const_cast(V1); // X - 0 == X - break; - case Instruction::Mul: - if (V2->isNullValue()) return const_cast(V2); // X * 0 == 0 - if (const ConstantInt *CI = dyn_cast(V2)) - if (CI->getZExtValue() == 1) - return const_cast(V1); // X * 1 == X - break; - case Instruction::UDiv: - case Instruction::SDiv: - if (const ConstantInt *CI = dyn_cast(V2)) - if (CI->getZExtValue() == 1) - return const_cast(V1); // X / 1 == X - break; - case Instruction::URem: - case Instruction::SRem: - if (const ConstantInt *CI = dyn_cast(V2)) - if (CI->getZExtValue() == 1) - return Constant::getNullValue(CI->getType()); // X % 1 == 0 - break; - case Instruction::And: - if (cast(V2)->isAllOnesValue()) - return const_cast(V1); // X & -1 == X - if (V2->isNullValue()) return const_cast(V2); // X & 0 == 0 - if (CE1->isCast() && isa(CE1->getOperand(0))) { - GlobalValue *CPR = cast(CE1->getOperand(0)); - // Functions are at least 4-byte aligned. If and'ing the address of a - // function with a constant < 4, fold it to zero. - if (const ConstantInt *CI = dyn_cast(V2)) - if (CI->getZExtValue() < 4 && isa(CPR)) - return Constant::getNullValue(CI->getType()); - } - break; - case Instruction::Or: - if (V2->isNullValue()) return const_cast(V1); // X | 0 == X - if (cast(V2)->isAllOnesValue()) - return const_cast(V2); // X | -1 == -1 - break; - case Instruction::Xor: - if (V2->isNullValue()) return const_cast(V1); // X ^ 0 == X + if (!isa(C1) && isa(C2)) { + // If C2 is a constant expr and C1 isn't, flop them around and fold the + // other way if possible. + switch (pred) { + case ICmpInst::ICMP_EQ: + case ICmpInst::ICMP_NE: + // No change of predicate required. + return ConstantFoldCompareInstruction(pred, C2, C1); + + case ICmpInst::ICMP_ULT: + case ICmpInst::ICMP_SLT: + case ICmpInst::ICMP_UGT: + case ICmpInst::ICMP_SGT: + case ICmpInst::ICMP_ULE: + case ICmpInst::ICMP_SLE: + case ICmpInst::ICMP_UGE: + case ICmpInst::ICMP_SGE: + // Change the predicate as necessary to swap the operands. + pred = ICmpInst::getSwappedPredicate((ICmpInst::Predicate)pred); + return ConstantFoldCompareInstruction(pred, C2, C1); + + default: // These predicates cannot be flopped around. break; } } - - } else if (isa(V2)) { - // If V2 is a constant expr and V1 isn't, flop them around and fold the - // other way if possible. - switch (Opcode) { - case Instruction::Add: - case Instruction::Mul: - case Instruction::And: - case Instruction::Or: - case Instruction::Xor: - case Instruction::SetEQ: - case Instruction::SetNE: - // No change of opcode required. - return ConstantFoldBinaryInstruction(Opcode, V2, V1); - - case Instruction::SetLT: - case Instruction::SetGT: - case Instruction::SetLE: - case Instruction::SetGE: - // Change the opcode as necessary to swap the operands. - Opcode = SetCondInst::getSwappedCondition((Instruction::BinaryOps)Opcode); - return ConstantFoldBinaryInstruction(Opcode, V2, V1); - - case Instruction::Shl: - case Instruction::LShr: - case Instruction::AShr: - case Instruction::Sub: - case Instruction::SDiv: - case Instruction::UDiv: - case Instruction::FDiv: - case Instruction::URem: - case Instruction::SRem: - case Instruction::FRem: - default: // These instructions cannot be flopped around. - break; - } } return 0; } -Constant *llvm::ConstantFoldCompare( - unsigned opcode, Constant *C1, Constant *C2, unsigned short predicate) -{ - // Place holder for future folding of ICmp and FCmp instructions - return 0; -} - Constant *llvm::ConstantFoldGetElementPtr(const Constant *C, - const std::vector &IdxList) { - if (IdxList.size() == 0 || - (IdxList.size() == 1 && cast(IdxList[0])->isNullValue())) + Constant* const *Idxs, + unsigned NumIdx) { + if (NumIdx == 0 || + (NumIdx == 1 && Idxs[0]->isNullValue())) return const_cast(C); if (isa(C)) { - const Type *Ty = GetElementPtrInst::getIndexedType(C->getType(), IdxList, + const PointerType *Ptr = cast(C->getType()); + const Type *Ty = GetElementPtrInst::getIndexedType(Ptr, + (Value **)Idxs, + (Value **)Idxs+NumIdx, true); assert(Ty != 0 && "Invalid indices for GEP!"); - return UndefValue::get(PointerType::get(Ty)); + return UndefValue::get(PointerType::get(Ty, Ptr->getAddressSpace())); } - Constant *Idx0 = cast(IdxList[0]); + Constant *Idx0 = Idxs[0]; if (C->isNullValue()) { bool isNull = true; - for (unsigned i = 0, e = IdxList.size(); i != e; ++i) - if (!cast(IdxList[i])->isNullValue()) { + for (unsigned i = 0, e = NumIdx; i != e; ++i) + if (!Idxs[i]->isNullValue()) { isNull = false; break; } if (isNull) { - const Type *Ty = GetElementPtrInst::getIndexedType(C->getType(), IdxList, + const PointerType *Ptr = cast(C->getType()); + const Type *Ty = GetElementPtrInst::getIndexedType(Ptr, + (Value**)Idxs, + (Value**)Idxs+NumIdx, true); assert(Ty != 0 && "Invalid indices for GEP!"); - return ConstantPointerNull::get(PointerType::get(Ty)); - } - - if (IdxList.size() == 1) { - const Type *ElTy = cast(C->getType())->getElementType(); - if (uint32_t ElSize = ElTy->getPrimitiveSize()) { - // gep null, C is equal to C*sizeof(nullty). If nullty is a known llvm - // type, we can statically fold this. - Constant *R = ConstantInt::get(Type::UIntTy, ElSize); - // We know R is unsigned, Idx0 is signed because it must be an index - // through a sequential type (gep pointer operand) which is always - // signed. - R = ConstantExpr::getSExtOrBitCast(R, Idx0->getType()); - R = ConstantExpr::getMul(R, Idx0); // signed multiply - // R is a signed integer, C is the GEP pointer so -> IntToPtr - return ConstantExpr::getIntToPtr(R, C->getType()); - } + return + ConstantPointerNull::get(PointerType::get(Ty,Ptr->getAddressSpace())); } } @@ -1688,8 +1424,8 @@ Constant *llvm::ConstantFoldGetElementPtr(const Constant *C, LastTy = *I; if ((LastTy && isa(LastTy)) || Idx0->isNullValue()) { - std::vector NewIndices; - NewIndices.reserve(IdxList.size() + CE->getNumOperands()); + SmallVector NewIndices; + NewIndices.reserve(NumIdx + CE->getNumOperands()); for (unsigned i = 1, e = CE->getNumOperands()-1; i != e; ++i) NewIndices.push_back(CE->getOperand(i)); @@ -1700,9 +1436,9 @@ Constant *llvm::ConstantFoldGetElementPtr(const Constant *C, if (!Idx0->isNullValue()) { const Type *IdxTy = Combined->getType(); if (IdxTy != Idx0->getType()) { - Constant *C1 = ConstantExpr::getSExtOrBitCast(Idx0, Type::LongTy); + Constant *C1 = ConstantExpr::getSExtOrBitCast(Idx0, Type::Int64Ty); Constant *C2 = ConstantExpr::getSExtOrBitCast(Combined, - Type::LongTy); + Type::Int64Ty); Combined = ConstantExpr::get(Instruction::Add, C1, C2); } else { Combined = @@ -1711,8 +1447,9 @@ Constant *llvm::ConstantFoldGetElementPtr(const Constant *C, } NewIndices.push_back(Combined); - NewIndices.insert(NewIndices.end(), IdxList.begin()+1, IdxList.end()); - return ConstantExpr::getGetElementPtr(CE->getOperand(0), NewIndices); + NewIndices.insert(NewIndices.end(), Idxs+1, Idxs+NumIdx); + return ConstantExpr::getGetElementPtr(CE->getOperand(0), &NewIndices[0], + NewIndices.size()); } } @@ -1721,7 +1458,7 @@ Constant *llvm::ConstantFoldGetElementPtr(const Constant *C, // long 0, long 0) // To: int* getelementptr ([3 x int]* %X, long 0, long 0) // - if (CE->isCast() && IdxList.size() > 1 && Idx0->isNullValue()) + if (CE->isCast() && NumIdx > 1 && Idx0->isNullValue()) { if (const PointerType *SPT = dyn_cast(CE->getOperand(0)->getType())) if (const ArrayType *SAT = dyn_cast(SPT->getElementType())) @@ -1729,7 +1466,29 @@ Constant *llvm::ConstantFoldGetElementPtr(const Constant *C, dyn_cast(cast(C->getType())->getElementType())) if (CAT->getElementType() == SAT->getElementType()) return ConstantExpr::getGetElementPtr( - (Constant*)CE->getOperand(0), IdxList); + (Constant*)CE->getOperand(0), Idxs, NumIdx); + } + + // Fold: getelementptr (i8* inttoptr (i64 1 to i8*), i32 -1) + // Into: inttoptr (i64 0 to i8*) + // This happens with pointers to member functions in C++. + if (CE->getOpcode() == Instruction::IntToPtr && NumIdx == 1 && + isa(CE->getOperand(0)) && isa(Idxs[0]) && + cast(CE->getType())->getElementType() == Type::Int8Ty) { + Constant *Base = CE->getOperand(0); + Constant *Offset = Idxs[0]; + + // Convert the smaller integer to the larger type. + if (Offset->getType()->getPrimitiveSizeInBits() < + Base->getType()->getPrimitiveSizeInBits()) + Offset = ConstantExpr::getSExt(Offset, Base->getType()); + else if (Base->getType()->getPrimitiveSizeInBits() < + Offset->getType()->getPrimitiveSizeInBits()) + Base = ConstantExpr::getZExt(Base, Base->getType()); + + Base = ConstantExpr::getAdd(Base, Offset); + return ConstantExpr::getIntToPtr(Base, CE->getType()); + } } return 0; }