X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FConstantFold.cpp;h=73ca47a9aa56c565f3e69b5e19d2c698d15fcb10;hb=d070d1e56fbfdad752342838dda39e14582ccad5;hp=2263d5ed83dd17a51aa4f7adbc6307a0756bfc1c;hpb=a4f0b3a084d120cfc5b5bb06f64b222f5cb72740;p=oota-llvm.git diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp index 2263d5ed83d..73ca47a9aa5 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,640 +18,32 @@ // //===----------------------------------------------------------------------===// -#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" #include "llvm/Support/MathExtras.h" -#include "llvm/Support/Compiler.h" #include -#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 *div(const Constant *V1, const Constant *V2) const = 0; - virtual Constant *rem(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 *shr(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 -//===----------------------------------------------------------------------===// -// -// 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 *div(const Constant *V1, const Constant *V2) const { - return SubClassName::Div((const ArgType *)V1, (const ArgType *)V2); - } - virtual Constant *rem(const Constant *V1, const Constant *V2) const { - return SubClassName::Rem((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 *shr(const Constant *V1, const Constant *V2) const { - return SubClassName::Shr((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 *Div(const ArgType *V1, const ArgType *V2) { return 0; } - static Constant *Rem(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 *Shr(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::True; - 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 , ConstantSInt, signed char) - DEF_CAST(UByte , ConstantUInt, unsigned char) - DEF_CAST(Short , ConstantSInt, signed short) - DEF_CAST(UShort, ConstantUInt, unsigned short) - DEF_CAST(Int , ConstantSInt, signed int) - DEF_CAST(UInt , ConstantUInt, unsigned int) - DEF_CAST(Long , ConstantSInt, int64_t) - DEF_CAST(ULong , ConstantUInt, 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::True; // Null pointers are always equal - } - static Constant *CastToBool(const Constant *V) { - return ConstantBool::False; - } - static Constant *CastToSByte (const Constant *V) { - return ConstantSInt::get(Type::SByteTy, 0); - } - static Constant *CastToUByte (const Constant *V) { - return ConstantUInt::get(Type::UByteTy, 0); - } - static Constant *CastToShort (const Constant *V) { - return ConstantSInt::get(Type::ShortTy, 0); - } - static Constant *CastToUShort(const Constant *V) { - return ConstantUInt::get(Type::UShortTy, 0); - } - static Constant *CastToInt (const Constant *V) { - return ConstantSInt::get(Type::IntTy, 0); - } - static Constant *CastToUInt (const Constant *V) { - return ConstantUInt::get(Type::UIntTy, 0); - } - static Constant *CastToLong (const Constant *V) { - return ConstantSInt::get(Type::LongTy, 0); - } - static Constant *CastToULong (const Constant *V) { - return ConstantUInt::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 *Div(const ConstantPacked *V1, const ConstantPacked *V2) { - return EvalVectorOp(V1, V2, ConstantExpr::getDiv); - } - static Constant *Rem(const ConstantPacked *V1, const ConstantPacked *V2) { - return EvalVectorOp(V1, V2, ConstantExpr::getRem); - } - 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 *Shl(const ConstantPacked *V1, const ConstantPacked *V2) { - return EvalVectorOp(V1, V2, ConstantExpr::getShl); - } - static Constant *Shr(const ConstantPacked *V1, const ConstantPacked *V2) { - return EvalVectorOp(V1, V2, ConstantExpr::getShr); - } - 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 - - -//===----------------------------------------------------------------------===// -// DirectRules Class -//===----------------------------------------------------------------------===// -// -// DirectRules provides a concrete base classes of ConstRules for a variety of -// different types. This allows the C++ compiler to automatically generate our -// constant handling operations in a typesafe and accurate manner. -// -namespace { -template -struct VISIBILITY_HIDDEN DirectRules - : public TemplateRules { - static Constant *Add(const ConstantClass *V1, const ConstantClass *V2) { - BuiltinType R = (BuiltinType)V1->getValue() + (BuiltinType)V2->getValue(); - return ConstantClass::get(*Ty, R); - } - - static Constant *Sub(const ConstantClass *V1, const ConstantClass *V2) { - BuiltinType R = (BuiltinType)V1->getValue() - (BuiltinType)V2->getValue(); - return ConstantClass::get(*Ty, R); - } - - static Constant *Mul(const ConstantClass *V1, const ConstantClass *V2) { - BuiltinType R = (BuiltinType)V1->getValue() * (BuiltinType)V2->getValue(); - return ConstantClass::get(*Ty, R); - } - - static Constant *Div(const ConstantClass *V1, const ConstantClass *V2) { - if (V2->isNullValue()) return 0; - BuiltinType R = (BuiltinType)V1->getValue() / (BuiltinType)V2->getValue(); - return ConstantClass::get(*Ty, R); - } - - static Constant *LessThan(const ConstantClass *V1, const ConstantClass *V2) { - bool R = (BuiltinType)V1->getValue() < (BuiltinType)V2->getValue(); - return ConstantBool::get(R); - } - - static Constant *EqualTo(const ConstantClass *V1, const ConstantClass *V2) { - bool R = (BuiltinType)V1->getValue() == (BuiltinType)V2->getValue(); - return ConstantBool::get(R); - } - - static Constant *CastToPointer(const ConstantClass *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 ConstantClass *V) { \ - return CLASS::get(Type::TYPE##Ty, (CTYPE)(BuiltinType)V->getValue()); \ - } - - DEF_CAST(Bool , ConstantBool, bool) - DEF_CAST(SByte , ConstantSInt, signed char) - DEF_CAST(UByte , ConstantUInt, unsigned char) - DEF_CAST(Short , ConstantSInt, signed short) - DEF_CAST(UShort, ConstantUInt, unsigned short) - DEF_CAST(Int , ConstantSInt, signed int) - DEF_CAST(UInt , ConstantUInt, unsigned int) - DEF_CAST(Long , ConstantSInt, int64_t) - DEF_CAST(ULong , ConstantUInt, uint64_t) - DEF_CAST(Float , ConstantFP , float) - DEF_CAST(Double, ConstantFP , double) -#undef DEF_CAST -}; -} // 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 DirectRules > { - - static Constant *Div(const ConstantClass *V1, const ConstantClass *V2) { - if (V2->isNullValue()) return 0; - if (V2->isAllOnesValue() && // MIN_INT / -1 - (BuiltinType)V1->getValue() == -(BuiltinType)V1->getValue()) - return 0; - BuiltinType R = (BuiltinType)V1->getValue() / (BuiltinType)V2->getValue(); - return ConstantClass::get(*Ty, R); - } - - static Constant *Rem(const ConstantClass *V1, - const ConstantClass *V2) { - if (V2->isNullValue()) return 0; // X / 0 - if (V2->isAllOnesValue() && // MIN_INT / -1 - (BuiltinType)V1->getValue() == -(BuiltinType)V1->getValue()) - return 0; - BuiltinType R = (BuiltinType)V1->getValue() % (BuiltinType)V2->getValue(); - return ConstantClass::get(*Ty, R); - } - - static Constant *And(const ConstantClass *V1, const ConstantClass *V2) { - BuiltinType R = (BuiltinType)V1->getValue() & (BuiltinType)V2->getValue(); - return ConstantClass::get(*Ty, R); - } - static Constant *Or(const ConstantClass *V1, const ConstantClass *V2) { - BuiltinType R = (BuiltinType)V1->getValue() | (BuiltinType)V2->getValue(); - return ConstantClass::get(*Ty, R); - } - static Constant *Xor(const ConstantClass *V1, const ConstantClass *V2) { - BuiltinType R = (BuiltinType)V1->getValue() ^ (BuiltinType)V2->getValue(); - return ConstantClass::get(*Ty, R); - } - - static Constant *Shl(const ConstantClass *V1, const ConstantClass *V2) { - BuiltinType R = (BuiltinType)V1->getValue() << (BuiltinType)V2->getValue(); - return ConstantClass::get(*Ty, R); - } - - static Constant *Shr(const ConstantClass *V1, const ConstantClass *V2) { - BuiltinType R = (BuiltinType)V1->getValue() >> (BuiltinType)V2->getValue(); - return ConstantClass::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 DirectRules > { - static Constant *Rem(const ConstantClass *V1, const ConstantClass *V2) { - if (V2->isNullValue()) return 0; - BuiltinType Result = std::fmod((BuiltinType)V1->getValue(), - (BuiltinType)V2->getValue()); - return ConstantClass::get(*Ty, Result); - } - static Constant *Div(const ConstantClass *V1, const ConstantClass *V2) { - BuiltinType inf = std::numeric_limits::infinity(); - if (V2->isExactlyValue(0.0)) return ConstantClass::get(*Ty, inf); - if (V2->isExactlyValue(-0.0)) return ConstantClass::get(*Ty, -inf); - BuiltinType R = (BuiltinType)V1->getValue() / (BuiltinType)V2->getValue(); - return ConstantClass::get(*Ty, R); - } -}; -} // end anonymous namespace - - -/// 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) { - static EmptyRules EmptyR; - static BoolRules BoolR; - static NullPointerRules NullPointerR; - static ConstantPackedRules ConstantPackedR; - static GeneralPackedRules GeneralPackedR; - static DirectIntRules SByteR; - static DirectIntRules UByteR; - static DirectIntRules ShortR; - static DirectIntRules UShortR; - static DirectIntRules IntR; - static DirectIntRules UIntR; - static DirectIntRules LongR; - static DirectIntRules ULongR; - static DirectFPRules FloatR; - static DirectFPRules DoubleR; - - 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 //===----------------------------------------------------------------------===// -// -// These methods contain the special case hackery required to symbolically -// evaluate some constant expression cases, and use the ConstantRules class to -// evaluate normal constants. -// -static unsigned getSize(const Type *Ty) { - unsigned S = Ty->getPrimitiveSize(); - return S ? S : 8; // Treat pointers at 8 bytes -} -/// 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(); +/// CastConstantVector - 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 *CastConstantVector(ConstantVector *CV, + const VectorType *DstTy) { + unsigned SrcNumElts = CV->getType()->getNumElements(); unsigned DstNumElts = DstTy->getNumElements(); - const Type *SrcEltTy = CP->getType()->getElementType(); + const Type *SrcEltTy = CV->getType()->getElementType(); const Type *DstEltTy = DstTy->getElementType(); // If both vectors have the same number of elements (thus, the elements @@ -659,55 +51,58 @@ static Constant *CastConstantPacked(ConstantPacked *CP, if (SrcNumElts == DstNumElts) { std::vector Result; - // If the src and dest elements are both integers, just cast each one - // which will do the appropriate bit-convert. - if (SrcEltTy->isIntegral() && DstEltTy->isIntegral()) { + // 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->isInteger() && DstEltTy->isInteger()) || + (SrcEltTy->isFloatingPoint() && DstEltTy->isFloatingPoint())) { for (unsigned i = 0; i != SrcNumElts; ++i) - Result.push_back(ConstantExpr::getCast(CP->getOperand(i), - DstEltTy)); - return ConstantPacked::get(Result); + Result.push_back( + ConstantExpr::getBitCast(CV->getOperand(i), DstEltTy)); + return ConstantVector::get(Result); } - if (SrcEltTy->isIntegral()) { - // Otherwise, this is an int-to-fp cast. + // If this is an int-to-fp cast .. + if (SrcEltTy->isInteger()) { + // 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))->getRawValue()); - Result.push_back(ConstantFP::get(Type::DoubleTy, V)); + ConstantInt *CI = cast(CV->getOperand(i)); + double V = CI->getValue().bitsToDouble(); + Result.push_back(ConstantFP::get(Type::DoubleTy, APFloat(V))); } - return ConstantPacked::get(Result); + return ConstantVector::get(Result); } assert(DstEltTy == Type::FloatTy && "Unknown fp type!"); for (unsigned i = 0; i != SrcNumElts; ++i) { - float V = - BitsToFloat(cast(CP->getOperand(i))->getRawValue()); - Result.push_back(ConstantFP::get(Type::FloatTy, V)); + ConstantInt *CI = cast(CV->getOperand(i)); + float V = CI->getValue().bitsToFloat(); + Result.push_back(ConstantFP::get(Type::FloatTy, APFloat(V))); } - return ConstantPacked::get(Result); + return ConstantVector::get(Result); } // Otherwise, this is an fp-to-int cast. - assert(SrcEltTy->isFloatingPoint() && DstEltTy->isIntegral()); + assert(SrcEltTy->isFloatingPoint() && DstEltTy->isInteger()); if (SrcEltTy->getTypeID() == Type::DoubleTyID) { for (unsigned i = 0; i != SrcNumElts; ++i) { - uint64_t V = - DoubleToBits(cast(CP->getOperand(i))->getValue()); - Constant *C = ConstantUInt::get(Type::ULongTy, V); - Result.push_back(ConstantExpr::getCast(C, DstEltTy)); + uint64_t V = cast(CV->getOperand(i))-> + getValueAPF().convertToAPInt().getZExtValue(); + Constant *C = ConstantInt::get(Type::Int64Ty, V); + Result.push_back(ConstantExpr::getBitCast(C, DstEltTy )); } - return ConstantPacked::get(Result); + return ConstantVector::get(Result); } assert(SrcEltTy->getTypeID() == Type::FloatTyID); for (unsigned i = 0; i != SrcNumElts; ++i) { - unsigned V = FloatToBits(cast(CP->getOperand(i))->getValue()); - Constant *C = ConstantUInt::get(Type::UIntTy, V); - Result.push_back(ConstantExpr::getCast(C, DstEltTy)); + uint32_t V = (uint32_t)cast(CV->getOperand(i))-> + getValueAPF().convertToAPInt().getZExtValue(); + Constant *C = ConstantInt::get(Type::Int32Ty, V); + Result.push_back(ConstantExpr::getBitCast(C, DstEltTy)); } - return ConstantPacked::get(Result); + return ConstantVector::get(Result); } // Otherwise, this is a cast that changes element count and size. Handle @@ -718,34 +113,50 @@ static Constant *CastConstantPacked(ConstantPacked *CP, return 0; } +/// 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. +/// @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 + const ConstantExpr*Op, ///< the first cast constant expression + const Type *DstTy ///< desintation type of the first cast +) { + assert(Op && Op->isCast() && "Can't fold cast of cast without a cast!"); + assert(DstTy && DstTy->isFirstClassType() && "Invalid cast destination type"); + assert(CastInst::isCast(opc) && "Invalid cast opcode"); + + // The the types and opcodes for the two Cast constant expressions + const Type *SrcTy = Op->getOperand(0)->getType(); + const Type *MidTy = Op->getType(); + Instruction::CastOps firstOp = Instruction::CastOps(Op->getOpcode()); + Instruction::CastOps secondOp = Instruction::CastOps(opc); + + // Let CastInst::isEliminableCastPair do the heavy lifting. + return CastInst::isEliminableCastPair(firstOp, secondOp, SrcTy, MidTy, DstTy, + Type::Int64Ty); +} -Constant *llvm::ConstantFoldCastInstruction(const Constant *V, +Constant *llvm::ConstantFoldCastInstruction(unsigned opc, const Constant *V, const Type *DestTy) { - if (V->getType() == DestTy) return (Constant*)V; - - // Cast of a global address to boolean is always true. - if (const GlobalValue *GV = dyn_cast(V)) { - if (DestTy == Type::BoolTy) - // FIXME: When we support 'external weak' references, we have to prevent - // this transformation from happening. This code will need to be updated - // to ignore external weak symbols when we support it. - return ConstantBool::True; - } else if (const ConstantExpr *CE = dyn_cast(V)) { - if (CE->getOpcode() == Instruction::Cast) { - Constant *Op = const_cast(CE->getOperand(0)); - // Try to not produce a cast of a cast, which is almost always redundant. - if (!Op->getType()->isFloatingPoint() && - !CE->getType()->isFloatingPoint() && - !DestTy->isFloatingPoint()) { - unsigned S1 = getSize(Op->getType()), S2 = getSize(CE->getType()); - unsigned S3 = getSize(DestTy); - if (Op->getType() == DestTy && S3 >= S2) - return Op; - if (S1 >= S2 && S2 >= S3) - return ConstantExpr::getCast(Op, DestTy); - if (S1 <= S2 && S2 >= S3 && S1 <= S3) - return ConstantExpr::getCast(Op, DestTy); - } + const Type *SrcTy = V->getType(); + + 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); + } + + // If the cast operand is a constant expression, there's a few things we can + // do to try to simplify it. + if (const ConstantExpr *CE = dyn_cast(V)) { + if (CE->isCast()) { + // Try hard to fold cast of cast because they are often eliminable. + if (unsigned newOpc = foldConstantCastPair(opc, CE, DestTy)) + return ConstantExpr::getCast(newOpc, CE->getOperand(0), DestTy); } else if (CE->getOpcode() == Instruction::GetElementPtr) { // If all of the indexes in the GEP are null values, there is no pointer // adjustment going on. We might as well cast the source pointer. @@ -756,96 +167,202 @@ Constant *llvm::ConstantFoldCastInstruction(const Constant *V, break; } if (isAllNull) - return ConstantExpr::getCast(CE->getOperand(0), DestTy); + // This is casting one pointer type to another, always BitCast + return ConstantExpr::getPointerCast(CE->getOperand(0), DestTy); } - } else if (isa(V)) { - return UndefValue::get(DestTy); } - // Check to see if we are casting an 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; + // We actually have to do a cast now. Perform the cast according to the + // opcode specified. + switch (opc) { + case Instruction::FPTrunc: + case Instruction::FPExt: + 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)) { + 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); + } + 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: + if (const ConstantInt *CI = dyn_cast(V)) { + double d = CI->getValue().roundToDouble(); + if (DestTy==Type::FloatTy) + return ConstantFP::get(DestTy, APFloat((float)d)); + else if (DestTy==Type::DoubleTy) + return ConstantFP::get(DestTy, APFloat(d)); + else + return 0; // FIXME do this for long double + } + return 0; + case Instruction::SIToFP: + if (const ConstantInt *CI = dyn_cast(V)) { + double d = CI->getValue().signedRoundToDouble(); + if (DestTy==Type::FloatTy) + return ConstantFP::get(DestTy, APFloat((float)d)); + else if (DestTy==Type::DoubleTy) + return ConstantFP::get(DestTy, APFloat(d)); + else + return 0; // FIXME do this for long double + } + return 0; + 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); + } + return 0; + case Instruction::SExt: + if (const ConstantInt *CI = dyn_cast(V)) { + uint32_t BitWidth = cast(DestTy)->getBitWidth(); + APInt Result(CI->getValue()); + Result.sext(BitWidth); + return ConstantInt::get(Result); + } + 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: + 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)) { + 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( + const_cast(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 and undef + if (isa(V)) + return Constant::getNullValue(DestTy); + if (isa(V)) + return UndefValue::get(DestTy); + + if (const ConstantVector *CV = dyn_cast(V)) { + // This is a cast from a ConstantVector of one type to a + // ConstantVector of another type. Check to see if all elements of + // the input are simple. + bool AllSimpleConstants = true; + for (unsigned i = 0, e = CV->getNumOperands(); i != e; ++i) { + if (!isa(CV->getOperand(i)) && + !isa(CV->getOperand(i))) { + AllSimpleConstants = false; + break; + } + } + + // If all of the elements are simple constants, we can fold this. + if (AllSimpleConstants) + return CastConstantVector(const_cast(CV), DestPTy); } } + } - if (ElTy == DPTy->getElementType()) - return ConstantExpr::getGetElementPtr(const_cast(V),IdxList); + // 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 const_cast(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 casts from one packed constant to another. We know that the src and - // dest type have the same size. - if (const PackedType *DestPTy = dyn_cast(DestTy)) { - if (const PackedType *SrcTy = dyn_cast(V->getType())) { - assert(DestPTy->getElementType()->getPrimitiveSizeInBits() * - DestPTy->getNumElements() == - SrcTy->getElementType()->getPrimitiveSizeInBits() * - SrcTy->getNumElements() && "Not cast between same sized vectors!"); - 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); + // 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; + default: + assert(!"Invalid CE CastInst opcode"); + break; } - 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)); - 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 (Cond == ConstantBool::True) - return const_cast(V1); - else if (Cond == ConstantBool::False) - return const_cast(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); @@ -857,14 +374,14 @@ Constant *llvm::ConstantFoldSelectInstruction(const Constant *Cond, Constant *llvm::ConstantFoldExtractElementInstruction(const Constant *Val, const Constant *Idx) { if (isa(Val)) // ee(undef, x) -> undef - return UndefValue::get(cast(Val->getType())->getElementType()); + return UndefValue::get(cast(Val->getType())->getElementType()); if (Val->isNullValue()) // ee(zero, x) -> zero return Constant::getNullValue( - cast(Val->getType())->getElementType()); + cast(Val->getType())->getElementType()); - if (const ConstantPacked *CVal = dyn_cast(Val)) { - if (const ConstantUInt *CIdx = dyn_cast(Idx)) { - return const_cast(CVal->getOperand(CIdx->getValue())); + 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)); @@ -876,56 +393,55 @@ Constant *llvm::ConstantFoldExtractElementInstruction(const Constant *Val, Constant *llvm::ConstantFoldInsertElementInstruction(const Constant *Val, const Constant *Elt, const Constant *Idx) { - const ConstantUInt *CIdx = dyn_cast(Idx); + const ConstantInt *CIdx = dyn_cast(Idx); if (!CIdx) return 0; - unsigned idxVal = CIdx->getValue(); - if (const UndefValue *UVal = dyn_cast(Val)) { - // Insertion of scalar constant into packed undef + 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(); + 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()); + (idxVal == i) ? Elt : UndefValue::get(Elt->getType()); Ops.push_back(const_cast(Op)); } - return ConstantPacked::get(Ops); + return ConstantVector::get(Ops); } - if (const ConstantAggregateZero *CVal = - dyn_cast(Val)) { - // Insertion of scalar constant into packed aggregate zero + 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(); + 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()); + (idxVal == i) ? Elt : Constant::getNullValue(Elt->getType()); Ops.push_back(const_cast(Op)); } - return ConstantPacked::get(Ops); + return ConstantVector::get(Ops); } - if (const ConstantPacked *CVal = dyn_cast(Val)) { - // Insertion of scalar constant into packed constant + 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 = - (i == idxVal) ? Elt : cast(CVal->getOperand(i)); + (idxVal == i) ? Elt : cast(CVal->getOperand(i)); Ops.push_back(const_cast(Op)); } - return ConstantPacked::get(Ops); + return ConstantVector::get(Ops); } return 0; } @@ -937,6 +453,297 @@ Constant *llvm::ConstantFoldShuffleVectorInstruction(const Constant *V1, return 0; } +/// EvalVectorOp - Given two vector constants and a function pointer, apply the +/// function pointer to each element pair, producing a new ConstantVector +/// constant. +static Constant *EvalVectorOp(const ConstantVector *V1, + const ConstantVector *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 ConstantVector::get(Res); +} + +Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, + const Constant *C1, + const Constant *C2) { + // 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; + } + } + } 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); + + 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; + } + } + + // 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 + } + } + } 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 ConstantVector *CP1 = dyn_cast(C1)) { + if (const ConstantVector *CP2 = dyn_cast(C2)) { + switch (Opcode) { + default: + break; + case Instruction::Add: + return EvalVectorOp(CP1, CP2, ConstantExpr::getAdd); + case Instruction::Sub: + return EvalVectorOp(CP1, CP2, ConstantExpr::getSub); + case Instruction::Mul: + return EvalVectorOp(CP1, CP2, ConstantExpr::getMul); + case Instruction::UDiv: + return EvalVectorOp(CP1, CP2, ConstantExpr::getUDiv); + case Instruction::SDiv: + return EvalVectorOp(CP1, CP2, ConstantExpr::getSDiv); + case Instruction::FDiv: + return EvalVectorOp(CP1, CP2, ConstantExpr::getFDiv); + case Instruction::URem: + return EvalVectorOp(CP1, CP2, ConstantExpr::getURem); + case Instruction::SRem: + return EvalVectorOp(CP1, CP2, ConstantExpr::getSRem); + case Instruction::FRem: + return EvalVectorOp(CP1, CP2, ConstantExpr::getFRem); + case Instruction::And: + return EvalVectorOp(CP1, CP2, ConstantExpr::getAnd); + case Instruction::Or: + return EvalVectorOp(CP1, CP2, ConstantExpr::getOr); + case Instruction::Xor: + return EvalVectorOp(CP1, CP2, ConstantExpr::getXor); + } + } + } + + // 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. @@ -965,16 +772,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. - C1 = ConstantExpr::getSignExtend(C1, Type::LongTy); - C2 = ConstantExpr::getSignExtend(C2, Type::LongTy); - if (C1 == C2) return 0; // Are they just differing types? + 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; // They are equal // If the type being indexed over is really just a zero sized type, there is // no pointer difference being made here. @@ -983,97 +794,195 @@ static int IdxCompare(Constant *C1, Constant *C2, const Type *ElTy) { // If they are really different, now that they are the same type, then we // found a difference! - if (cast(C1)->getValue() < cast(C2)->getValue()) + if (cast(C1)->getSExtValue() < + cast(C2)->getSExtValue()) return -1; else 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!"); + // 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 GlobalValuess. 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. +/// and GlobalValues. If we can determine that the two constants have a +/// 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 == ConstantBool::True) return Instruction::SetEQ; - R = dyn_cast(ConstantExpr::getSetLT(V1, V2)); - if (R == ConstantBool::True) return Instruction::SetLT; - R = dyn_cast(ConstantExpr::getSetGT(V1, V2)); - if (R == ConstantBool::True) 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)) { - assert(CPR1 != CPR2 && - "GVs for the same value exist at different addresses??"); - // FIXME: If both globals are external weak, they might both be null! - 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 { assert(isa(V2) && "Canonicalization guarantee!"); - // Global can never be null. FIXME: if we implement external weak - // linkage, this is not necessarily true! - 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::Cast: + case Instruction::Trunc: + case Instruction::FPTrunc: + case Instruction::FPExt: + case Instruction::FPToUI: + case Instruction::FPToSI: + break; // We can't evaluate floating point casts or truncations. + + case Instruction::UIToFP: + case Instruction::SIToFP: + case Instruction::IntToPtr: + case Instruction::BitCast: + case Instruction::ZExt: + case Instruction::SExt: + case Instruction::PtrToInt: // 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 = CE1->getOpcode() == Instruction::ZExt ? false : + (CE1->getOpcode() == Instruction::SExt ? true : + (CE1->getOpcode() == Instruction::PtrToInt ? false : isSigned)); + 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->getOpcode() == Instruction::Cast && + 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 = CE1->getOpcode() == Instruction::ZExt ? false : + (CE1->getOpcode() == Instruction::SExt ? true : + (CE1->getOpcode() == Instruction::PtrToInt ? false : isSigned)); + return evaluateICmpRelation(CE1->getOperand(0), CE2->getOperand(0), + sgnd); } break; @@ -1083,25 +992,36 @@ 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 (isa(CE1Op0)) { - // FIXME: this is not true when we have external weak references! - // No offset can go from a global to a null pointer. - return Instruction::SetGT; + 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 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 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)) { if (isa(CE1Op0)) { - // FIXME: This is not true with external weak references. - return Instruction::SetLT; + 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 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 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 @@ -1111,11 +1031,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 { @@ -1131,7 +1051,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. @@ -1143,291 +1063,336 @@ 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::Div: C = ConstRules::get(V1, V2).div(V1, V2); break; - case Instruction::Rem: C = ConstRules::get(V1, V2).rem(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::Shr: C = ConstRules::get(V1, V2).shr(V1, V2); break; - case Instruction::SetEQ: 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: // 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; +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); + + // 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)); + } + } 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; + } + } } - // If we successfully folded the expression, return it now. - if (C) return C; - - if (SetCondInst::isRelational(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 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_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::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::False; - if (Opcode == Instruction::SetLT) return ConstantBool::True; + 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 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::False; - if (Opcode == Instruction::SetGT) return ConstantBool::True; + 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::False; - if (Opcode == Instruction::SetNE) return ConstantBool::True; + 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::Div: - case Instruction::Rem: - 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::Shr: - if (!isa(V2)) { - if (V1->getType()->isSigned()) - return const_cast(V1); // undef >>s X -> undef - // undef >>u X -> 0 - } else if (isa(V1)) { - return const_cast(V1); // undef >> undef -> undef - } else { - if (V1->getType()->isSigned()) - return const_cast(V1); // X >>s undef -> X - // X >>u undef -> 0 - } - return Constant::getNullValue(V1->getType()); - case Instruction::Shl: - // undef << X -> 0 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 (const ConstantExpr *CE2 = dyn_cast(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->getRawValue() == 1) - return const_cast(V1); // X * 1 == X - break; - case Instruction::Div: - if (const ConstantInt *CI = dyn_cast(V2)) - if (CI->getRawValue() == 1) - return const_cast(V1); // X / 1 == X - break; - case Instruction::Rem: - if (const ConstantInt *CI = dyn_cast(V2)) - if (CI->getRawValue() == 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->getOpcode() == Instruction::Cast && - 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->getRawValue() < 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 (const ConstantExpr *CE2 = dyn_cast(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::Shr: - case Instruction::Sub: - case Instruction::Div: - case Instruction::Rem: - default: // These instructions cannot be flopped around. - break; - } } 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 Type *Ty = GetElementPtrInst::getIndexedType(C->getType(), + (Value **)Idxs, + (Value **)Idxs+NumIdx, true); assert(Ty != 0 && "Invalid indices for GEP!"); return UndefValue::get(PointerType::get(Ty)); } - 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 Type *Ty = GetElementPtrInst::getIndexedType(C->getType(), + (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 (unsigned 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 = ConstantUInt::get(Type::UIntTy, ElSize); - R = ConstantExpr::getCast(R, Idx0->getType()); - R = ConstantExpr::getMul(R, Idx0); - return ConstantExpr::getCast(R, C->getType()); - } - } } if (ConstantExpr *CE = dyn_cast(const_cast(C))) { @@ -1442,8 +1407,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)); @@ -1453,16 +1418,21 @@ Constant *llvm::ConstantFoldGetElementPtr(const Constant *C, // Otherwise it must be an array. if (!Idx0->isNullValue()) { const Type *IdxTy = Combined->getType(); - if (IdxTy != Idx0->getType()) IdxTy = Type::LongTy; - Combined = - ConstantExpr::get(Instruction::Add, - ConstantExpr::getCast(Idx0, IdxTy), - ConstantExpr::getCast(Combined, IdxTy)); + if (IdxTy != Idx0->getType()) { + Constant *C1 = ConstantExpr::getSExtOrBitCast(Idx0, Type::Int64Ty); + Constant *C2 = ConstantExpr::getSExtOrBitCast(Combined, + Type::Int64Ty); + Combined = ConstantExpr::get(Instruction::Add, C1, C2); + } else { + Combined = + ConstantExpr::get(Instruction::Add, Idx0, Combined); + } } 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()); } } @@ -1471,8 +1441,7 @@ Constant *llvm::ConstantFoldGetElementPtr(const Constant *C, // long 0, long 0) // To: int* getelementptr ([3 x int]* %X, long 0, long 0) // - if (CE->getOpcode() == Instruction::Cast && 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())) @@ -1480,7 +1449,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; }