mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-23 19:59:57 +00:00
Support vector casts in more places, fixing a variety of assertion
failures. To support this, add some utility functions to Type to help support vector/scalar-independent code. Change ConstantInt::get and ConstantFP::get to support vector types, and add an overload to ConstantInt::get that uses a static IntegerType type, for convenience. Introduce a new getConstant method for ScalarEvolution, to simplify common use cases. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@73431 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
0d492bdf4d
commit
6de29f8d96
@ -418,6 +418,7 @@ namespace llvm {
|
||||
|
||||
SCEVHandle getConstant(ConstantInt *V);
|
||||
SCEVHandle getConstant(const APInt& Val);
|
||||
SCEVHandle getConstant(const Type *Ty, uint64_t V, bool isSigned = false);
|
||||
SCEVHandle getTruncateExpr(const SCEVHandle &Op, const Type *Ty);
|
||||
SCEVHandle getZeroExtendExpr(const SCEVHandle &Op, const Type *Ty);
|
||||
SCEVHandle getSignExtendExpr(const SCEVHandle &Op, const Type *Ty);
|
||||
|
@ -107,14 +107,19 @@ public:
|
||||
/// either getSExtValue() or getZExtValue() will yield a correctly sized and
|
||||
/// signed value for the type Ty.
|
||||
/// @brief Get a ConstantInt for a specific value.
|
||||
static ConstantInt *get(const Type *Ty, uint64_t V, bool isSigned = false);
|
||||
static ConstantInt *get(const IntegerType *Ty,
|
||||
uint64_t V, bool isSigned = false);
|
||||
static Constant *get(const Type *Ty, uint64_t V, bool isSigned = false);
|
||||
|
||||
/// Return a ConstantInt with the specified value for the specified type. The
|
||||
/// value V will be canonicalized to a an unsigned APInt. Accessing it with
|
||||
/// either getSExtValue() or getZExtValue() will yield a correctly sized and
|
||||
/// signed value for the type Ty.
|
||||
/// @brief Get a ConstantInt for a specific signed value.
|
||||
static ConstantInt *getSigned(const Type *Ty, int64_t V) {
|
||||
static ConstantInt *getSigned(const IntegerType *Ty, int64_t V) {
|
||||
return get(Ty, V, true);
|
||||
}
|
||||
static Constant *getSigned(const Type *Ty, int64_t V) {
|
||||
return get(Ty, V, true);
|
||||
}
|
||||
|
||||
@ -122,6 +127,10 @@ public:
|
||||
/// type is the integer type that corresponds to the bit width of the value.
|
||||
static ConstantInt *get(const APInt &V);
|
||||
|
||||
/// If Ty is a vector type, return a Constant with a splat of the given
|
||||
/// value. Otherwise return a ConstantInt for the given value.
|
||||
static Constant *get(const Type *Ty, const APInt &V);
|
||||
|
||||
/// getType - Specialize the getType() method to always return an IntegerType,
|
||||
/// which reduces the amount of casting needed in parts of the compiler.
|
||||
///
|
||||
@ -251,7 +260,7 @@ public:
|
||||
/// get() - This returns a constant fp for the specified value in the
|
||||
/// specified type. This should only be used for simple constant values like
|
||||
/// 2.0/1.0 etc, that are known-valid both as double and as the target format.
|
||||
static ConstantFP *get(const Type *Ty, double V);
|
||||
static Constant *get(const Type *Ty, double V);
|
||||
|
||||
/// isValueValidForType - return true if Ty is big enough to represent V.
|
||||
static bool isValueValidForType(const Type *Ty, const APFloat& V);
|
||||
|
@ -268,19 +268,16 @@ public:
|
||||
/// primitive type.
|
||||
///
|
||||
unsigned getPrimitiveSizeInBits() const;
|
||||
|
||||
|
||||
/// getScalarSizeInBits - If this is a vector type, return the
|
||||
/// getPrimitiveSizeInBits value for the element type. Otherwise return the
|
||||
/// getPrimitiveSizeInBits value for this type.
|
||||
unsigned getScalarSizeInBits() const;
|
||||
|
||||
/// getFPMantissaWidth - Return the width of the mantissa of this type. This
|
||||
/// is only valid on scalar floating point types. If the FP type does not
|
||||
/// is only valid on floating point types. If the FP type does not
|
||||
/// have a stable mantissa (e.g. ppc long double), this method returns -1.
|
||||
int getFPMantissaWidth() const {
|
||||
assert(isFloatingPoint() && "Not a floating point type!");
|
||||
if (ID == FloatTyID) return 24;
|
||||
if (ID == DoubleTyID) return 53;
|
||||
if (ID == X86_FP80TyID) return 64;
|
||||
if (ID == FP128TyID) return 113;
|
||||
assert(ID == PPC_FP128TyID && "unknown fp type");
|
||||
return -1;
|
||||
}
|
||||
int getFPMantissaWidth() const;
|
||||
|
||||
/// getForwardedType - Return the type that this type has been resolved to if
|
||||
/// it has been resolved to anything. This is used to implement the
|
||||
@ -296,6 +293,10 @@ public:
|
||||
/// function.
|
||||
const Type *getVAArgsPromotedType() const;
|
||||
|
||||
/// getScalarType - If this is a vector type, return the element type,
|
||||
/// otherwise return this.
|
||||
const Type *getScalarType() const;
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Type Iteration support
|
||||
//
|
||||
|
@ -365,7 +365,7 @@ Constant *llvm::ConstantFoldInstOperands(unsigned Opcode, const Type *DestTy,
|
||||
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Ops[0])) {
|
||||
if (TD && CE->getOpcode() == Instruction::IntToPtr) {
|
||||
Constant *Input = CE->getOperand(0);
|
||||
unsigned InWidth = Input->getType()->getPrimitiveSizeInBits();
|
||||
unsigned InWidth = Input->getType()->getScalarSizeInBits();
|
||||
if (TD->getPointerSizeInBits() < InWidth) {
|
||||
Constant *Mask =
|
||||
ConstantInt::get(APInt::getLowBitsSet(InWidth,
|
||||
@ -384,7 +384,7 @@ Constant *llvm::ConstantFoldInstOperands(unsigned Opcode, const Type *DestTy,
|
||||
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Ops[0])) {
|
||||
if (TD &&
|
||||
TD->getPointerSizeInBits() <=
|
||||
CE->getType()->getPrimitiveSizeInBits()) {
|
||||
CE->getType()->getScalarSizeInBits()) {
|
||||
if (CE->getOpcode() == Instruction::PtrToInt) {
|
||||
Constant *Input = CE->getOperand(0);
|
||||
Constant *C = FoldBitCast(Input, DestTy, *TD);
|
||||
|
@ -186,6 +186,11 @@ SCEVHandle ScalarEvolution::getConstant(const APInt& Val) {
|
||||
return getConstant(ConstantInt::get(Val));
|
||||
}
|
||||
|
||||
SCEVHandle
|
||||
ScalarEvolution::getConstant(const Type *Ty, uint64_t V, bool isSigned) {
|
||||
return getConstant(ConstantInt::get(cast<IntegerType>(Ty), V, isSigned));
|
||||
}
|
||||
|
||||
const Type *SCEVConstant::getType() const { return V->getType(); }
|
||||
|
||||
void SCEVConstant::print(raw_ostream &OS) const {
|
||||
@ -2891,7 +2896,7 @@ ComputeLoadConstantCompareBackedgeTakenCount(LoadInst *LI, Constant *RHS,
|
||||
unsigned MaxSteps = MaxBruteForceIterations;
|
||||
for (unsigned IterationNum = 0; IterationNum != MaxSteps; ++IterationNum) {
|
||||
ConstantInt *ItCst =
|
||||
ConstantInt::get(IdxExpr->getType(), IterationNum);
|
||||
ConstantInt::get(cast<IntegerType>(IdxExpr->getType()), IterationNum);
|
||||
ConstantInt *Val = EvaluateConstantChrecAtConstant(IdxExpr, ItCst, *this);
|
||||
|
||||
// Form the GEP offset.
|
||||
@ -3086,7 +3091,7 @@ ComputeBackedgeTakenCountExhaustively(const Loop *L, Value *Cond, bool ExitWhen)
|
||||
if (CondVal->getValue() == uint64_t(ExitWhen)) {
|
||||
ConstantEvolutionLoopExitValue[PN] = PHIVal;
|
||||
++NumBruteForceTripCountsComputed;
|
||||
return getConstant(ConstantInt::get(Type::Int32Ty, IterationNum));
|
||||
return getConstant(Type::Int32Ty, IterationNum);
|
||||
}
|
||||
|
||||
// Compute the value of the PHI node for the next iteration.
|
||||
@ -3777,7 +3782,7 @@ SCEVHandle SCEVAddRecExpr::getNumIterationsInRange(ConstantRange Range,
|
||||
// iteration exits.
|
||||
unsigned BitWidth = SE.getTypeSizeInBits(getType());
|
||||
if (!Range.contains(APInt(BitWidth, 0)))
|
||||
return SE.getConstant(ConstantInt::get(getType(),0));
|
||||
return SE.getIntegerSCEV(0, getType());
|
||||
|
||||
if (isAffine()) {
|
||||
// If this is an affine expression then we have this situation:
|
||||
|
@ -298,9 +298,7 @@ Value *SCEVExpander::expandAddToGEP(const SCEVHandle *op_begin,
|
||||
GepIndices.push_back(ConstantInt::get(Type::Int32Ty, ElIdx));
|
||||
ElTy = STy->getTypeAtIndex(ElIdx);
|
||||
Ops[0] =
|
||||
SE.getConstant(ConstantInt::get(Ty,
|
||||
FullOffset -
|
||||
SL.getElementOffset(ElIdx)));
|
||||
SE.getConstant(Ty, FullOffset - SL.getElementOffset(ElIdx));
|
||||
AnyNonZeroIndices = true;
|
||||
continue;
|
||||
}
|
||||
|
@ -52,11 +52,12 @@ void llvm::ComputeMaskedBits(Value *V, const APInt &Mask,
|
||||
assert(V && "No Value?");
|
||||
assert(Depth <= MaxDepth && "Limit Search Depth");
|
||||
unsigned BitWidth = Mask.getBitWidth();
|
||||
assert((V->getType()->isInteger() || isa<PointerType>(V->getType())) &&
|
||||
assert((V->getType()->isIntOrIntVector() || isa<PointerType>(V->getType())) &&
|
||||
"Not integer or pointer type!");
|
||||
assert((!TD || TD->getTypeSizeInBits(V->getType()) == BitWidth) &&
|
||||
(!isa<IntegerType>(V->getType()) ||
|
||||
V->getType()->getPrimitiveSizeInBits() == BitWidth) &&
|
||||
assert((!TD ||
|
||||
TD->getTypeSizeInBits(V->getType()->getScalarType()) == BitWidth) &&
|
||||
(!V->getType()->isIntOrIntVector() ||
|
||||
V->getType()->getScalarSizeInBits() == BitWidth) &&
|
||||
KnownZero.getBitWidth() == BitWidth &&
|
||||
KnownOne.getBitWidth() == BitWidth &&
|
||||
"V, Mask, KnownOne and KnownZero should have same BitWidth");
|
||||
@ -67,12 +68,26 @@ void llvm::ComputeMaskedBits(Value *V, const APInt &Mask,
|
||||
KnownZero = ~KnownOne & Mask;
|
||||
return;
|
||||
}
|
||||
// Null is all-zeros.
|
||||
if (isa<ConstantPointerNull>(V)) {
|
||||
// Null and aggregate-zero are all-zeros.
|
||||
if (isa<ConstantPointerNull>(V) ||
|
||||
isa<ConstantAggregateZero>(V)) {
|
||||
KnownOne.clear();
|
||||
KnownZero = Mask;
|
||||
return;
|
||||
}
|
||||
// Handle a constant vector by taking the intersection of the known bits of
|
||||
// each element.
|
||||
if (ConstantVector *CV = dyn_cast<ConstantVector>(V)) {
|
||||
KnownZero.set(); KnownOne.set();
|
||||
for (unsigned i = 0, e = CV->getNumOperands(); i != e; ++i) {
|
||||
APInt KnownZero2(BitWidth, 0), KnownOne2(BitWidth, 0);
|
||||
ComputeMaskedBits(CV->getOperand(i), Mask, KnownZero2, KnownOne2,
|
||||
TD, Depth);
|
||||
KnownZero &= KnownZero2;
|
||||
KnownOne &= KnownOne2;
|
||||
}
|
||||
return;
|
||||
}
|
||||
// The address of an aligned GlobalValue has trailing zeros.
|
||||
if (GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
|
||||
unsigned Align = GV->getAlignment();
|
||||
@ -218,7 +233,7 @@ void llvm::ComputeMaskedBits(Value *V, const APInt &Mask,
|
||||
const Type *SrcTy = I->getOperand(0)->getType();
|
||||
unsigned SrcBitWidth = TD ?
|
||||
TD->getTypeSizeInBits(SrcTy) :
|
||||
SrcTy->getPrimitiveSizeInBits();
|
||||
SrcTy->getScalarSizeInBits();
|
||||
APInt MaskIn(Mask);
|
||||
MaskIn.zextOrTrunc(SrcBitWidth);
|
||||
KnownZero.zextOrTrunc(SrcBitWidth);
|
||||
@ -480,7 +495,7 @@ void llvm::ComputeMaskedBits(Value *V, const APInt &Mask,
|
||||
// Handle array index arithmetic.
|
||||
const Type *IndexedTy = GTI.getIndexedType();
|
||||
if (!IndexedTy->isSized()) return;
|
||||
unsigned GEPOpiBits = Index->getType()->getPrimitiveSizeInBits();
|
||||
unsigned GEPOpiBits = Index->getType()->getScalarSizeInBits();
|
||||
uint64_t TypeSize = TD ? TD->getTypeAllocSize(IndexedTy) : 1;
|
||||
LocalMask = APInt::getAllOnesValue(GEPOpiBits);
|
||||
LocalKnownZero = LocalKnownOne = APInt(GEPOpiBits, 0);
|
||||
@ -609,8 +624,8 @@ bool llvm::MaskedValueIsZero(Value *V, const APInt &Mask,
|
||||
/// 'Op' must have a scalar integer type.
|
||||
///
|
||||
unsigned llvm::ComputeNumSignBits(Value *V, TargetData *TD, unsigned Depth) {
|
||||
const IntegerType *Ty = cast<IntegerType>(V->getType());
|
||||
unsigned TyBits = Ty->getBitWidth();
|
||||
const Type *Ty = V->getType();
|
||||
unsigned TyBits = Ty->getScalarSizeInBits();
|
||||
unsigned Tmp, Tmp2;
|
||||
unsigned FirstAnswer = 1;
|
||||
|
||||
|
@ -108,9 +108,9 @@ namespace {
|
||||
class VISIBILITY_HIDDEN GlobalRandomCounter : public Chooser {
|
||||
GlobalVariable* Counter;
|
||||
Value* ResetValue;
|
||||
const Type* T;
|
||||
const IntegerType* T;
|
||||
public:
|
||||
GlobalRandomCounter(Module& M, const Type* t, uint64_t resetval);
|
||||
GlobalRandomCounter(Module& M, const IntegerType* t, uint64_t resetval);
|
||||
virtual ~GlobalRandomCounter();
|
||||
virtual void PrepFunction(Function* F);
|
||||
virtual void ProcessChoicePoint(BasicBlock* bb);
|
||||
@ -121,9 +121,9 @@ namespace {
|
||||
GlobalVariable* Counter;
|
||||
Value* ResetValue;
|
||||
AllocaInst* AI;
|
||||
const Type* T;
|
||||
const IntegerType* T;
|
||||
public:
|
||||
GlobalRandomCounterOpt(Module& M, const Type* t, uint64_t resetval);
|
||||
GlobalRandomCounterOpt(Module& M, const IntegerType* t, uint64_t resetval);
|
||||
virtual ~GlobalRandomCounterOpt();
|
||||
virtual void PrepFunction(Function* F);
|
||||
virtual void ProcessChoicePoint(BasicBlock* bb);
|
||||
@ -193,7 +193,7 @@ static void getBackEdges(Function& F, T& BackEdges);
|
||||
// Methods of choosing when to profile
|
||||
///////////////////////////////////////
|
||||
|
||||
GlobalRandomCounter::GlobalRandomCounter(Module& M, const Type* t,
|
||||
GlobalRandomCounter::GlobalRandomCounter(Module& M, const IntegerType* t,
|
||||
uint64_t resetval) : T(t) {
|
||||
ConstantInt* Init = ConstantInt::get(T, resetval);
|
||||
ResetValue = Init;
|
||||
@ -229,7 +229,7 @@ void GlobalRandomCounter::ProcessChoicePoint(BasicBlock* bb) {
|
||||
ReplacePhiPred(oldnext, bb, resetblock);
|
||||
}
|
||||
|
||||
GlobalRandomCounterOpt::GlobalRandomCounterOpt(Module& M, const Type* t,
|
||||
GlobalRandomCounterOpt::GlobalRandomCounterOpt(Module& M, const IntegerType* t,
|
||||
uint64_t resetval)
|
||||
: AI(0), T(t) {
|
||||
ConstantInt* Init = ConstantInt::get(T, resetval);
|
||||
|
@ -390,7 +390,7 @@ namespace {
|
||||
|
||||
Value *EvaluateInDifferentType(Value *V, const Type *Ty, bool isSigned);
|
||||
|
||||
bool CanEvaluateInDifferentType(Value *V, const IntegerType *Ty,
|
||||
bool CanEvaluateInDifferentType(Value *V, const Type *Ty,
|
||||
unsigned CastOpc, int &NumCastsRemoved);
|
||||
unsigned GetOrEnforceKnownAlignment(Value *V,
|
||||
unsigned PrefAlign = 0);
|
||||
@ -654,30 +654,12 @@ static unsigned getOpcode(const Value *V) {
|
||||
}
|
||||
|
||||
/// AddOne - Add one to a ConstantInt
|
||||
static ConstantInt *AddOne(ConstantInt *C) {
|
||||
APInt Val(C->getValue());
|
||||
return ConstantInt::get(++Val);
|
||||
static Constant *AddOne(Constant *C) {
|
||||
return ConstantExpr::getAdd(C, ConstantInt::get(C->getType(), 1));
|
||||
}
|
||||
/// SubOne - Subtract one from a ConstantInt
|
||||
static ConstantInt *SubOne(ConstantInt *C) {
|
||||
APInt Val(C->getValue());
|
||||
return ConstantInt::get(--Val);
|
||||
}
|
||||
/// Add - Add two ConstantInts together
|
||||
static ConstantInt *Add(ConstantInt *C1, ConstantInt *C2) {
|
||||
return ConstantInt::get(C1->getValue() + C2->getValue());
|
||||
}
|
||||
/// And - Bitwise AND two ConstantInts together
|
||||
static ConstantInt *And(ConstantInt *C1, ConstantInt *C2) {
|
||||
return ConstantInt::get(C1->getValue() & C2->getValue());
|
||||
}
|
||||
/// Subtract - Subtract one ConstantInt from another
|
||||
static ConstantInt *Subtract(ConstantInt *C1, ConstantInt *C2) {
|
||||
return ConstantInt::get(C1->getValue() - C2->getValue());
|
||||
}
|
||||
/// Multiply - Multiply two ConstantInts together
|
||||
static ConstantInt *Multiply(ConstantInt *C1, ConstantInt *C2) {
|
||||
return ConstantInt::get(C1->getValue() * C2->getValue());
|
||||
static Constant *SubOne(ConstantInt *C) {
|
||||
return ConstantExpr::getSub(C, ConstantInt::get(C->getType(), 1));
|
||||
}
|
||||
/// MultiplyOverflows - True if the multiply can not be expressed in an int
|
||||
/// this size.
|
||||
@ -774,7 +756,7 @@ static void ComputeUnsignedMinMaxValuesFromKnownBits(const APInt &KnownZero,
|
||||
/// SimplifyDemandedBits knows about. See if the instruction has any
|
||||
/// properties that allow us to simplify its operands.
|
||||
bool InstCombiner::SimplifyDemandedInstructionBits(Instruction &Inst) {
|
||||
unsigned BitWidth = cast<IntegerType>(Inst.getType())->getBitWidth();
|
||||
unsigned BitWidth = Inst.getType()->getScalarSizeInBits();
|
||||
APInt KnownZero(BitWidth, 0), KnownOne(BitWidth, 0);
|
||||
APInt DemandedMask(APInt::getAllOnesValue(BitWidth));
|
||||
|
||||
@ -830,13 +812,13 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
|
||||
const Type *VTy = V->getType();
|
||||
assert((TD || !isa<PointerType>(VTy)) &&
|
||||
"SimplifyDemandedBits needs to know bit widths!");
|
||||
assert((!TD || TD->getTypeSizeInBits(VTy) == BitWidth) &&
|
||||
(!isa<IntegerType>(VTy) ||
|
||||
VTy->getPrimitiveSizeInBits() == BitWidth) &&
|
||||
assert((!TD || TD->getTypeSizeInBits(VTy->getScalarType()) == BitWidth) &&
|
||||
(!VTy->isIntOrIntVector() ||
|
||||
VTy->getScalarSizeInBits() == BitWidth) &&
|
||||
KnownZero.getBitWidth() == BitWidth &&
|
||||
KnownOne.getBitWidth() == BitWidth &&
|
||||
"Value *V, DemandedMask, KnownZero and KnownOne \
|
||||
must have same BitWidth");
|
||||
"Value *V, DemandedMask, KnownZero and KnownOne "
|
||||
"must have same BitWidth");
|
||||
if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
|
||||
// We know all of the bits for a constant!
|
||||
KnownOne = CI->getValue() & DemandedMask;
|
||||
@ -1089,7 +1071,7 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
|
||||
RHSKnownZero &= LHSKnownZero;
|
||||
break;
|
||||
case Instruction::Trunc: {
|
||||
unsigned truncBf = I->getOperand(0)->getType()->getPrimitiveSizeInBits();
|
||||
unsigned truncBf = I->getOperand(0)->getType()->getScalarSizeInBits();
|
||||
DemandedMask.zext(truncBf);
|
||||
RHSKnownZero.zext(truncBf);
|
||||
RHSKnownOne.zext(truncBf);
|
||||
@ -1112,7 +1094,7 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
|
||||
break;
|
||||
case Instruction::ZExt: {
|
||||
// Compute the bits in the result that are not present in the input.
|
||||
unsigned SrcBitWidth =I->getOperand(0)->getType()->getPrimitiveSizeInBits();
|
||||
unsigned SrcBitWidth =I->getOperand(0)->getType()->getScalarSizeInBits();
|
||||
|
||||
DemandedMask.trunc(SrcBitWidth);
|
||||
RHSKnownZero.trunc(SrcBitWidth);
|
||||
@ -1130,7 +1112,7 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
|
||||
}
|
||||
case Instruction::SExt: {
|
||||
// Compute the bits in the result that are not present in the input.
|
||||
unsigned SrcBitWidth =I->getOperand(0)->getType()->getPrimitiveSizeInBits();
|
||||
unsigned SrcBitWidth =I->getOperand(0)->getType()->getScalarSizeInBits();
|
||||
|
||||
APInt InputDemandedBits = DemandedMask &
|
||||
APInt::getLowBitsSet(BitWidth, SrcBitWidth);
|
||||
@ -2087,7 +2069,7 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
|
||||
|
||||
// See if SimplifyDemandedBits can simplify this. This handles stuff like
|
||||
// (X & 254)+1 -> (X&254)|1
|
||||
if (!isa<VectorType>(I.getType()) && SimplifyDemandedInstructionBits(I))
|
||||
if (SimplifyDemandedInstructionBits(I))
|
||||
return &I;
|
||||
|
||||
// zext(i1) - 1 -> select i1, 0, -1
|
||||
@ -2107,7 +2089,7 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
|
||||
Value *XorLHS = 0;
|
||||
if (isa<ConstantInt>(RHSC) &&
|
||||
match(LHS, m_Xor(m_Value(XorLHS), m_ConstantInt(XorRHS)))) {
|
||||
uint32_t TySizeBits = I.getType()->getPrimitiveSizeInBits();
|
||||
uint32_t TySizeBits = I.getType()->getScalarSizeInBits();
|
||||
const APInt& RHSVal = cast<ConstantInt>(RHSC)->getValue();
|
||||
|
||||
uint32_t Size = TySizeBits / 2;
|
||||
@ -2197,7 +2179,7 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
|
||||
// X*C1 + X*C2 --> X * (C1+C2)
|
||||
ConstantInt *C1;
|
||||
if (X == dyn_castFoldableMul(RHS, C1))
|
||||
return BinaryOperator::CreateMul(X, Add(C1, C2));
|
||||
return BinaryOperator::CreateMul(X, ConstantExpr::getAdd(C1, C2));
|
||||
}
|
||||
|
||||
// X + X*C --> X * (C+1)
|
||||
@ -2262,7 +2244,7 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
|
||||
|
||||
// (X & FF00) + xx00 -> (X+xx00) & FF00
|
||||
if (LHS->hasOneUse() && match(LHS, m_And(m_Value(X), m_ConstantInt(C2)))) {
|
||||
Constant *Anded = And(CRHS, C2);
|
||||
Constant *Anded = ConstantExpr::getAnd(CRHS, C2);
|
||||
if (Anded == CRHS) {
|
||||
// See if all bits from the first bit set in the Add RHS up are included
|
||||
// in the mask. First, get the rightmost bit.
|
||||
@ -2299,7 +2281,7 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
|
||||
Other = LHS;
|
||||
}
|
||||
if (CI && CI->getType()->isSized() &&
|
||||
(CI->getType()->getPrimitiveSizeInBits() ==
|
||||
(CI->getType()->getScalarSizeInBits() ==
|
||||
TD->getIntPtrType()->getPrimitiveSizeInBits())
|
||||
&& isa<PointerType>(CI->getOperand(0)->getType())) {
|
||||
unsigned AS =
|
||||
@ -2523,7 +2505,7 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) {
|
||||
else if (ConstantInt *CI1 = dyn_cast<ConstantInt>(I.getOperand(0))) {
|
||||
if (ConstantInt *CI2 = dyn_cast<ConstantInt>(Op1I->getOperand(1)))
|
||||
// C1-(X+C2) --> (C1-C2)-X
|
||||
return BinaryOperator::CreateSub(Subtract(CI1, CI2),
|
||||
return BinaryOperator::CreateSub(ConstantExpr::getSub(CI1, CI2),
|
||||
Op1I->getOperand(0));
|
||||
}
|
||||
}
|
||||
@ -2564,7 +2546,8 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) {
|
||||
// X - X*C --> X * (1-C)
|
||||
ConstantInt *C2 = 0;
|
||||
if (dyn_castFoldableMul(Op1I, C2) == Op0) {
|
||||
Constant *CP1 = Subtract(ConstantInt::get(I.getType(), 1), C2);
|
||||
Constant *CP1 = ConstantExpr::getSub(ConstantInt::get(I.getType(), 1),
|
||||
C2);
|
||||
return BinaryOperator::CreateMul(Op0, CP1);
|
||||
}
|
||||
}
|
||||
@ -2589,7 +2572,7 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) {
|
||||
|
||||
ConstantInt *C2; // X*C1 - X*C2 -> X * (C1-C2)
|
||||
if (X == dyn_castFoldableMul(Op1, C2))
|
||||
return BinaryOperator::CreateMul(X, Subtract(C1, C2));
|
||||
return BinaryOperator::CreateMul(X, ConstantExpr::getSub(C1, C2));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -2950,12 +2933,12 @@ Instruction *InstCombiner::commonIDivTransforms(BinaryOperator &I) {
|
||||
// (sdiv X, X) --> 1 (udiv X, X) --> 1
|
||||
if (Op0 == Op1) {
|
||||
if (const VectorType *Ty = dyn_cast<VectorType>(I.getType())) {
|
||||
ConstantInt *CI = ConstantInt::get(Ty->getElementType(), 1);
|
||||
Constant *CI = ConstantInt::get(Ty->getElementType(), 1);
|
||||
std::vector<Constant*> Elts(Ty->getNumElements(), CI);
|
||||
return ReplaceInstUsesWith(I, ConstantVector::get(Elts));
|
||||
}
|
||||
|
||||
ConstantInt *CI = ConstantInt::get(I.getType(), 1);
|
||||
Constant *CI = ConstantInt::get(I.getType(), 1);
|
||||
return ReplaceInstUsesWith(I, CI);
|
||||
}
|
||||
|
||||
@ -2980,7 +2963,7 @@ Instruction *InstCombiner::commonIDivTransforms(BinaryOperator &I) {
|
||||
return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
|
||||
else
|
||||
return BinaryOperator::Create(I.getOpcode(), LHS->getOperand(0),
|
||||
Multiply(RHS, LHSRHS));
|
||||
ConstantExpr::getMul(RHS, LHSRHS));
|
||||
}
|
||||
|
||||
if (!RHS->isZero()) { // avoid X udiv 0
|
||||
@ -3513,7 +3496,7 @@ Instruction *InstCombiner::OptAndOp(Instruction *Op,
|
||||
Value *X = Op->getOperand(0);
|
||||
Constant *Together = 0;
|
||||
if (!Op->isShift())
|
||||
Together = And(AndRHS, OpRHS);
|
||||
Together = ConstantExpr::getAnd(AndRHS, OpRHS);
|
||||
|
||||
switch (Op->getOpcode()) {
|
||||
case Instruction::Xor:
|
||||
@ -3724,7 +3707,7 @@ Value *InstCombiner::FoldLogicalPlusAnd(Value *LHS, Value *RHS,
|
||||
switch (LHSI->getOpcode()) {
|
||||
default: return 0;
|
||||
case Instruction::And:
|
||||
if (And(N, Mask) == Mask) {
|
||||
if (ConstantExpr::getAnd(N, Mask) == Mask) {
|
||||
// If the AndRHS is a power of two minus one (0+1+), this is simple.
|
||||
if ((Mask->getValue().countLeadingZeros() +
|
||||
Mask->getValue().countPopulation()) ==
|
||||
@ -3748,7 +3731,7 @@ Value *InstCombiner::FoldLogicalPlusAnd(Value *LHS, Value *RHS,
|
||||
// If the AndRHS is a power of two minus one (0+1+), and N&Mask == 0
|
||||
if ((Mask->getValue().countLeadingZeros() +
|
||||
Mask->getValue().countPopulation()) == Mask->getValue().getBitWidth()
|
||||
&& And(N, Mask)->isZero())
|
||||
&& ConstantExpr::getAnd(N, Mask)->isNullValue())
|
||||
break;
|
||||
return 0;
|
||||
}
|
||||
@ -3946,10 +3929,9 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
|
||||
|
||||
// See if we can simplify any instructions used by the instruction whose sole
|
||||
// purpose is to compute bits we don't care about.
|
||||
if (!isa<VectorType>(I.getType())) {
|
||||
if (SimplifyDemandedInstructionBits(I))
|
||||
return &I;
|
||||
} else {
|
||||
if (SimplifyDemandedInstructionBits(I))
|
||||
return &I;
|
||||
if (isa<VectorType>(I.getType())) {
|
||||
if (ConstantVector *CP = dyn_cast<ConstantVector>(Op1)) {
|
||||
if (CP->isAllOnesValue()) // X & <-1,-1> -> X
|
||||
return ReplaceInstUsesWith(I, I.getOperand(0));
|
||||
@ -3957,7 +3939,7 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
|
||||
return ReplaceInstUsesWith(I, Op1); // X & <0,0> -> <0,0>
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (ConstantInt *AndRHS = dyn_cast<ConstantInt>(Op1)) {
|
||||
const APInt& AndRHSMask = AndRHS->getValue();
|
||||
APInt NotAndRHS(~AndRHSMask);
|
||||
@ -4510,7 +4492,7 @@ Instruction *InstCombiner::FoldOrOfICmps(Instruction &I,
|
||||
Instruction *Add = BinaryOperator::CreateAdd(Val, AddCST,
|
||||
Val->getName()+".off");
|
||||
InsertNewInstBefore(Add, I);
|
||||
AddCST = Subtract(AddOne(RHSCst), LHSCst);
|
||||
AddCST = ConstantExpr::getSub(AddOne(RHSCst), LHSCst);
|
||||
return new ICmpInst(ICmpInst::ICMP_ULT, Add, AddCST);
|
||||
}
|
||||
break; // (X == 13 | X == 15) -> no change
|
||||
@ -4653,18 +4635,17 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) {
|
||||
|
||||
// See if we can simplify any instructions used by the instruction whose sole
|
||||
// purpose is to compute bits we don't care about.
|
||||
if (!isa<VectorType>(I.getType())) {
|
||||
if (SimplifyDemandedInstructionBits(I))
|
||||
return &I;
|
||||
} else if (isa<ConstantAggregateZero>(Op1)) {
|
||||
return ReplaceInstUsesWith(I, Op0); // X | <0,0> -> X
|
||||
} else if (ConstantVector *CP = dyn_cast<ConstantVector>(Op1)) {
|
||||
if (CP->isAllOnesValue()) // X | <-1,-1> -> <-1,-1>
|
||||
return ReplaceInstUsesWith(I, I.getOperand(1));
|
||||
if (SimplifyDemandedInstructionBits(I))
|
||||
return &I;
|
||||
if (isa<VectorType>(I.getType())) {
|
||||
if (isa<ConstantAggregateZero>(Op1)) {
|
||||
return ReplaceInstUsesWith(I, Op0); // X | <0,0> -> X
|
||||
} else if (ConstantVector *CP = dyn_cast<ConstantVector>(Op1)) {
|
||||
if (CP->isAllOnesValue()) // X | <-1,-1> -> <-1,-1>
|
||||
return ReplaceInstUsesWith(I, I.getOperand(1));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// or X, -1 == -1
|
||||
if (ConstantInt *RHS = dyn_cast<ConstantInt>(Op1)) {
|
||||
ConstantInt *C1 = 0; Value *X = 0;
|
||||
@ -4991,12 +4972,11 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) {
|
||||
|
||||
// See if we can simplify any instructions used by the instruction whose sole
|
||||
// purpose is to compute bits we don't care about.
|
||||
if (!isa<VectorType>(I.getType())) {
|
||||
if (SimplifyDemandedInstructionBits(I))
|
||||
return &I;
|
||||
} else if (isa<ConstantAggregateZero>(Op1)) {
|
||||
return ReplaceInstUsesWith(I, Op0); // X ^ <0,0> -> X
|
||||
}
|
||||
if (SimplifyDemandedInstructionBits(I))
|
||||
return &I;
|
||||
if (isa<VectorType>(I.getType()))
|
||||
if (isa<ConstantAggregateZero>(Op1))
|
||||
return ReplaceInstUsesWith(I, Op0); // X ^ <0,0> -> X
|
||||
|
||||
// Is this a ~ operation?
|
||||
if (Value *NotOp = dyn_castNotVal(&I)) {
|
||||
@ -5083,7 +5063,7 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) {
|
||||
Constant *NewRHS = ConstantExpr::getOr(Op0CI, RHS);
|
||||
// Anything in both C1 and C2 is known to be zero, remove it from
|
||||
// NewRHS.
|
||||
Constant *CommonBits = And(Op0CI, RHS);
|
||||
Constant *CommonBits = ConstantExpr::getAnd(Op0CI, RHS);
|
||||
NewRHS = ConstantExpr::getAnd(NewRHS,
|
||||
ConstantExpr::getNot(CommonBits));
|
||||
AddToWorkList(Op0I);
|
||||
@ -5247,12 +5227,13 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) {
|
||||
return Changed ? &I : 0;
|
||||
}
|
||||
|
||||
/// AddWithOverflow - Compute Result = In1+In2, returning true if the result
|
||||
/// overflowed for this type.
|
||||
static bool AddWithOverflow(ConstantInt *&Result, ConstantInt *In1,
|
||||
ConstantInt *In2, bool IsSigned = false) {
|
||||
Result = cast<ConstantInt>(Add(In1, In2));
|
||||
static ConstantInt *ExtractElement(Constant *V, Constant *Idx) {
|
||||
return cast<ConstantInt>(ConstantExpr::getExtractElement(V, Idx));
|
||||
}
|
||||
|
||||
static bool HasAddOverflow(ConstantInt *Result,
|
||||
ConstantInt *In1, ConstantInt *In2,
|
||||
bool IsSigned) {
|
||||
if (IsSigned)
|
||||
if (In2->getValue().isNegative())
|
||||
return Result->getValue().sgt(In1->getValue());
|
||||
@ -5262,12 +5243,32 @@ static bool AddWithOverflow(ConstantInt *&Result, ConstantInt *In1,
|
||||
return Result->getValue().ult(In1->getValue());
|
||||
}
|
||||
|
||||
/// SubWithOverflow - Compute Result = In1-In2, returning true if the result
|
||||
/// AddWithOverflow - Compute Result = In1+In2, returning true if the result
|
||||
/// overflowed for this type.
|
||||
static bool SubWithOverflow(ConstantInt *&Result, ConstantInt *In1,
|
||||
ConstantInt *In2, bool IsSigned = false) {
|
||||
Result = cast<ConstantInt>(Subtract(In1, In2));
|
||||
static bool AddWithOverflow(Constant *&Result, Constant *In1,
|
||||
Constant *In2, bool IsSigned = false) {
|
||||
Result = ConstantExpr::getAdd(In1, In2);
|
||||
|
||||
if (const VectorType *VTy = dyn_cast<VectorType>(In1->getType())) {
|
||||
for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) {
|
||||
Constant *Idx = ConstantInt::get(Type::Int32Ty, i);
|
||||
if (HasAddOverflow(ExtractElement(Result, Idx),
|
||||
ExtractElement(In1, Idx),
|
||||
ExtractElement(In2, Idx),
|
||||
IsSigned))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return HasAddOverflow(cast<ConstantInt>(Result),
|
||||
cast<ConstantInt>(In1), cast<ConstantInt>(In2),
|
||||
IsSigned);
|
||||
}
|
||||
|
||||
static bool HasSubOverflow(ConstantInt *Result,
|
||||
ConstantInt *In1, ConstantInt *In2,
|
||||
bool IsSigned) {
|
||||
if (IsSigned)
|
||||
if (In2->getValue().isNegative())
|
||||
return Result->getValue().slt(In1->getValue());
|
||||
@ -5277,6 +5278,29 @@ static bool SubWithOverflow(ConstantInt *&Result, ConstantInt *In1,
|
||||
return Result->getValue().ugt(In1->getValue());
|
||||
}
|
||||
|
||||
/// SubWithOverflow - Compute Result = In1-In2, returning true if the result
|
||||
/// overflowed for this type.
|
||||
static bool SubWithOverflow(Constant *&Result, Constant *In1,
|
||||
Constant *In2, bool IsSigned = false) {
|
||||
Result = ConstantExpr::getSub(In1, In2);
|
||||
|
||||
if (const VectorType *VTy = dyn_cast<VectorType>(In1->getType())) {
|
||||
for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) {
|
||||
Constant *Idx = ConstantInt::get(Type::Int32Ty, i);
|
||||
if (HasSubOverflow(ExtractElement(Result, Idx),
|
||||
ExtractElement(In1, Idx),
|
||||
ExtractElement(In2, Idx),
|
||||
IsSigned))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return HasSubOverflow(cast<ConstantInt>(Result),
|
||||
cast<ConstantInt>(In1), cast<ConstantInt>(In2),
|
||||
IsSigned);
|
||||
}
|
||||
|
||||
/// EmitGEPOffset - Given a getelementptr instruction/constantexpr, emit the
|
||||
/// code necessary to compute the offset from the base pointer (without adding
|
||||
/// in the base pointer). Return the result as a signed integer of intptr size.
|
||||
@ -5589,7 +5613,7 @@ Instruction *InstCombiner::FoldFCmp_IntToFP_Cst(FCmpInst &I,
|
||||
// Check to see that the input is converted from an integer type that is small
|
||||
// enough that preserves all bits. TODO: check here for "known" sign bits.
|
||||
// This would allow us to handle (fptosi (x >>s 62) to float) if x is i64 f.e.
|
||||
unsigned InputSize = LHSI->getOperand(0)->getType()->getPrimitiveSizeInBits();
|
||||
unsigned InputSize = LHSI->getOperand(0)->getType()->getScalarSizeInBits();
|
||||
|
||||
// If this is a uitofp instruction, we need an extra bit to hold the sign.
|
||||
bool LHSUnsigned = isa<UIToFPInst>(LHSI);
|
||||
@ -5644,7 +5668,7 @@ Instruction *InstCombiner::FoldFCmp_IntToFP_Cst(FCmpInst &I,
|
||||
|
||||
// See if the FP constant is too large for the integer. For example,
|
||||
// comparing an i8 to 300.0.
|
||||
unsigned IntWidth = IntTy->getPrimitiveSizeInBits();
|
||||
unsigned IntWidth = IntTy->getScalarSizeInBits();
|
||||
|
||||
if (!LHSUnsigned) {
|
||||
// If the RHS value is > SignedMax, fold the comparison. This handles +INF
|
||||
@ -6459,7 +6483,7 @@ Instruction *InstCombiner::FoldICmpDivCst(ICmpInst &ICI, BinaryOperator *DivI,
|
||||
// of form X/C1=C2. We solve for X by multiplying C1 (DivRHS) and
|
||||
// C2 (CI). By solving for X we can turn this into a range check
|
||||
// instead of computing a divide.
|
||||
ConstantInt *Prod = Multiply(CmpRHS, DivRHS);
|
||||
Constant *Prod = ConstantExpr::getMul(CmpRHS, DivRHS);
|
||||
|
||||
// Determine if the product overflows by seeing if the product is
|
||||
// not equal to the divide. Make sure we do the same kind of divide
|
||||
@ -6478,7 +6502,7 @@ Instruction *InstCombiner::FoldICmpDivCst(ICmpInst &ICI, BinaryOperator *DivI,
|
||||
// overflow variable is set to 0 if it's corresponding bound variable is valid
|
||||
// -1 if overflowed off the bottom end, or +1 if overflowed off the top end.
|
||||
int LoOverflow = 0, HiOverflow = 0;
|
||||
ConstantInt *LoBound = 0, *HiBound = 0;
|
||||
Constant *LoBound = 0, *HiBound = 0;
|
||||
|
||||
if (!DivIsSigned) { // udiv
|
||||
// e.g. X/5 op 3 --> [15, 20)
|
||||
@ -6966,7 +6990,7 @@ Instruction *InstCombiner::visitICmpInstWithInstAndIntCst(ICmpInst &ICI,
|
||||
if (ConstantInt *BOp1C = dyn_cast<ConstantInt>(BO->getOperand(1))) {
|
||||
if (BO->hasOneUse())
|
||||
return new ICmpInst(ICI.getPredicate(), BO->getOperand(0),
|
||||
Subtract(RHS, BOp1C));
|
||||
ConstantExpr::getSub(RHS, BOp1C));
|
||||
} else if (RHSV == 0) {
|
||||
// Replace ((add A, B) != 0) with (A != -B) if A or B is
|
||||
// efficiently invertible, or if the add has just this one use.
|
||||
@ -7250,7 +7274,7 @@ Instruction *InstCombiner::commonShiftTransforms(BinaryOperator &I) {
|
||||
}
|
||||
|
||||
// See if we can fold away this shift.
|
||||
if (!isa<VectorType>(I.getType()) && SimplifyDemandedInstructionBits(I))
|
||||
if (SimplifyDemandedInstructionBits(I))
|
||||
return &I;
|
||||
|
||||
// Try to fold constant and into select arguments.
|
||||
@ -7729,7 +7753,8 @@ Instruction *InstCombiner::PromoteCastOfAllocation(BitCastInst &CI,
|
||||
// If the allocation size is constant, form a constant mul expression
|
||||
Amt = ConstantInt::get(Type::Int32Ty, Scale);
|
||||
if (isa<ConstantInt>(NumElements))
|
||||
Amt = Multiply(cast<ConstantInt>(NumElements), cast<ConstantInt>(Amt));
|
||||
Amt = ConstantExpr::getMul(cast<ConstantInt>(NumElements),
|
||||
cast<ConstantInt>(Amt));
|
||||
// otherwise multiply the amount and the number of elements
|
||||
else {
|
||||
Instruction *Tmp = BinaryOperator::CreateMul(Amt, NumElements, "tmp");
|
||||
@ -7788,17 +7813,17 @@ Instruction *InstCombiner::PromoteCastOfAllocation(BitCastInst &CI,
|
||||
/// If CastOpc is a sext or zext, we are asking if the low bits of the value can
|
||||
/// bit computed in a larger type, which is then and'd or sext_in_reg'd to get
|
||||
/// the final result.
|
||||
bool InstCombiner::CanEvaluateInDifferentType(Value *V, const IntegerType *Ty,
|
||||
bool InstCombiner::CanEvaluateInDifferentType(Value *V, const Type *Ty,
|
||||
unsigned CastOpc,
|
||||
int &NumCastsRemoved){
|
||||
// We can always evaluate constants in another type.
|
||||
if (isa<ConstantInt>(V))
|
||||
if (isa<Constant>(V))
|
||||
return true;
|
||||
|
||||
Instruction *I = dyn_cast<Instruction>(V);
|
||||
if (!I) return false;
|
||||
|
||||
const IntegerType *OrigTy = cast<IntegerType>(V->getType());
|
||||
const Type *OrigTy = V->getType();
|
||||
|
||||
// If this is an extension or truncate, we can often eliminate it.
|
||||
if (isa<TruncInst>(I) || isa<ZExtInst>(I) || isa<SExtInst>(I)) {
|
||||
@ -7836,8 +7861,8 @@ bool InstCombiner::CanEvaluateInDifferentType(Value *V, const IntegerType *Ty,
|
||||
// If we are truncating the result of this SHL, and if it's a shift of a
|
||||
// constant amount, we can always perform a SHL in a smaller type.
|
||||
if (ConstantInt *CI = dyn_cast<ConstantInt>(I->getOperand(1))) {
|
||||
uint32_t BitWidth = Ty->getBitWidth();
|
||||
if (BitWidth < OrigTy->getBitWidth() &&
|
||||
uint32_t BitWidth = Ty->getScalarSizeInBits();
|
||||
if (BitWidth < OrigTy->getScalarSizeInBits() &&
|
||||
CI->getLimitedValue(BitWidth) < BitWidth)
|
||||
return CanEvaluateInDifferentType(I->getOperand(0), Ty, CastOpc,
|
||||
NumCastsRemoved);
|
||||
@ -7848,8 +7873,8 @@ bool InstCombiner::CanEvaluateInDifferentType(Value *V, const IntegerType *Ty,
|
||||
// lshr iff we know that the bits we would otherwise be shifting in are
|
||||
// already zeros.
|
||||
if (ConstantInt *CI = dyn_cast<ConstantInt>(I->getOperand(1))) {
|
||||
uint32_t OrigBitWidth = OrigTy->getBitWidth();
|
||||
uint32_t BitWidth = Ty->getBitWidth();
|
||||
uint32_t OrigBitWidth = OrigTy->getScalarSizeInBits();
|
||||
uint32_t BitWidth = Ty->getScalarSizeInBits();
|
||||
if (BitWidth < OrigBitWidth &&
|
||||
MaskedValueIsZero(I->getOperand(0),
|
||||
APInt::getHighBitsSet(OrigBitWidth, OrigBitWidth-BitWidth)) &&
|
||||
@ -8131,8 +8156,8 @@ Instruction *InstCombiner::commonIntCastTransforms(CastInst &CI) {
|
||||
Value *Src = CI.getOperand(0);
|
||||
const Type *SrcTy = Src->getType();
|
||||
const Type *DestTy = CI.getType();
|
||||
uint32_t SrcBitSize = SrcTy->getPrimitiveSizeInBits();
|
||||
uint32_t DestBitSize = DestTy->getPrimitiveSizeInBits();
|
||||
uint32_t SrcBitSize = SrcTy->getScalarSizeInBits();
|
||||
uint32_t DestBitSize = DestTy->getScalarSizeInBits();
|
||||
|
||||
// See if we can simplify any instructions used by the LHS whose sole
|
||||
// purpose is to compute bits we don't care about.
|
||||
@ -8151,8 +8176,9 @@ Instruction *InstCombiner::commonIntCastTransforms(CastInst &CI) {
|
||||
// Only do this if the dest type is a simple type, don't convert the
|
||||
// expression tree to something weird like i93 unless the source is also
|
||||
// strange.
|
||||
(isSafeIntegerType(DestTy) || !isSafeIntegerType(SrcI->getType())) &&
|
||||
CanEvaluateInDifferentType(SrcI, cast<IntegerType>(DestTy),
|
||||
(isSafeIntegerType(DestTy->getScalarType()) ||
|
||||
!isSafeIntegerType(SrcI->getType()->getScalarType())) &&
|
||||
CanEvaluateInDifferentType(SrcI, DestTy,
|
||||
CI.getOpcode(), NumCastsRemoved)) {
|
||||
// If this cast is a truncate, evaluting in a different type always
|
||||
// eliminates the cast, so it is always a win. If this is a zero-extension,
|
||||
@ -8350,17 +8376,17 @@ Instruction *InstCombiner::visitTrunc(TruncInst &CI) {
|
||||
|
||||
Value *Src = CI.getOperand(0);
|
||||
const Type *Ty = CI.getType();
|
||||
uint32_t DestBitWidth = Ty->getPrimitiveSizeInBits();
|
||||
uint32_t SrcBitWidth = cast<IntegerType>(Src->getType())->getBitWidth();
|
||||
uint32_t DestBitWidth = Ty->getScalarSizeInBits();
|
||||
uint32_t SrcBitWidth = Src->getType()->getScalarSizeInBits();
|
||||
|
||||
// Canonicalize trunc x to i1 -> (icmp ne (and x, 1), 0)
|
||||
if (DestBitWidth == 1) {
|
||||
if (!isa<VectorType>(Ty) && DestBitWidth == 1) {
|
||||
Constant *One = ConstantInt::get(Src->getType(), 1);
|
||||
Src = InsertNewInstBefore(BinaryOperator::CreateAnd(Src, One, "tmp"), CI);
|
||||
Value *Zero = Constant::getNullValue(Src->getType());
|
||||
return new ICmpInst(ICmpInst::ICMP_NE, Src, Zero);
|
||||
}
|
||||
|
||||
|
||||
// Optimize trunc(lshr(), c) to pull the shift through the truncate.
|
||||
ConstantInt *ShAmtV = 0;
|
||||
Value *ShiftOp = 0;
|
||||
@ -8403,7 +8429,7 @@ Instruction *InstCombiner::transformZExtICmp(ICmpInst *ICI, Instruction &CI,
|
||||
|
||||
Value *In = ICI->getOperand(0);
|
||||
Value *Sh = ConstantInt::get(In->getType(),
|
||||
In->getType()->getPrimitiveSizeInBits()-1);
|
||||
In->getType()->getScalarSizeInBits()-1);
|
||||
In = InsertNewInstBefore(BinaryOperator::CreateLShr(In, Sh,
|
||||
In->getName()+".lobit"),
|
||||
CI);
|
||||
@ -8494,28 +8520,30 @@ Instruction *InstCombiner::visitZExt(ZExtInst &CI) {
|
||||
// Get the sizes of the types involved. We know that the intermediate type
|
||||
// will be smaller than A or C, but don't know the relation between A and C.
|
||||
Value *A = CSrc->getOperand(0);
|
||||
unsigned SrcSize = A->getType()->getPrimitiveSizeInBits();
|
||||
unsigned MidSize = CSrc->getType()->getPrimitiveSizeInBits();
|
||||
unsigned DstSize = CI.getType()->getPrimitiveSizeInBits();
|
||||
unsigned SrcSize = A->getType()->getScalarSizeInBits();
|
||||
unsigned MidSize = CSrc->getType()->getScalarSizeInBits();
|
||||
unsigned DstSize = CI.getType()->getScalarSizeInBits();
|
||||
// If we're actually extending zero bits, then if
|
||||
// SrcSize < DstSize: zext(a & mask)
|
||||
// SrcSize == DstSize: a & mask
|
||||
// SrcSize > DstSize: trunc(a) & mask
|
||||
if (SrcSize < DstSize) {
|
||||
APInt AndValue(APInt::getLowBitsSet(SrcSize, MidSize));
|
||||
Constant *AndConst = ConstantInt::get(AndValue);
|
||||
Constant *AndConst = ConstantInt::get(A->getType(), AndValue);
|
||||
Instruction *And =
|
||||
BinaryOperator::CreateAnd(A, AndConst, CSrc->getName()+".mask");
|
||||
InsertNewInstBefore(And, CI);
|
||||
return new ZExtInst(And, CI.getType());
|
||||
} else if (SrcSize == DstSize) {
|
||||
APInt AndValue(APInt::getLowBitsSet(SrcSize, MidSize));
|
||||
return BinaryOperator::CreateAnd(A, ConstantInt::get(AndValue));
|
||||
return BinaryOperator::CreateAnd(A, ConstantInt::get(A->getType(),
|
||||
AndValue));
|
||||
} else if (SrcSize > DstSize) {
|
||||
Instruction *Trunc = new TruncInst(A, CI.getType(), "tmp");
|
||||
InsertNewInstBefore(Trunc, CI);
|
||||
APInt AndValue(APInt::getLowBitsSet(DstSize, MidSize));
|
||||
return BinaryOperator::CreateAnd(Trunc, ConstantInt::get(AndValue));
|
||||
return BinaryOperator::CreateAnd(Trunc, ConstantInt::get(Trunc->getType(),
|
||||
AndValue));
|
||||
}
|
||||
}
|
||||
|
||||
@ -8556,9 +8584,9 @@ Instruction *InstCombiner::visitSExt(SExtInst &CI) {
|
||||
// eliminate the trunc/sext pair.
|
||||
if (getOpcode(Src) == Instruction::Trunc) {
|
||||
Value *Op = cast<User>(Src)->getOperand(0);
|
||||
unsigned OpBits = cast<IntegerType>(Op->getType())->getBitWidth();
|
||||
unsigned MidBits = cast<IntegerType>(Src->getType())->getBitWidth();
|
||||
unsigned DestBits = cast<IntegerType>(CI.getType())->getBitWidth();
|
||||
unsigned OpBits = Op->getType()->getScalarSizeInBits();
|
||||
unsigned MidBits = Src->getType()->getScalarSizeInBits();
|
||||
unsigned DestBits = CI.getType()->getScalarSizeInBits();
|
||||
unsigned NumSignBits = ComputeNumSignBits(Op);
|
||||
|
||||
if (OpBits == DestBits) {
|
||||
@ -8599,8 +8627,8 @@ Instruction *InstCombiner::visitSExt(SExtInst &CI) {
|
||||
BA == CA && isa<TruncInst>(A)) {
|
||||
Value *I = cast<TruncInst>(A)->getOperand(0);
|
||||
if (I->getType() == CI.getType()) {
|
||||
unsigned MidSize = Src->getType()->getPrimitiveSizeInBits();
|
||||
unsigned SrcDstSize = CI.getType()->getPrimitiveSizeInBits();
|
||||
unsigned MidSize = Src->getType()->getScalarSizeInBits();
|
||||
unsigned SrcDstSize = CI.getType()->getScalarSizeInBits();
|
||||
unsigned ShAmt = CA->getZExtValue()+SrcDstSize-MidSize;
|
||||
Constant *ShAmtV = ConstantInt::get(CI.getType(), ShAmt);
|
||||
I = InsertNewInstBefore(BinaryOperator::CreateShl(I, ShAmtV,
|
||||
@ -8671,11 +8699,11 @@ Instruction *InstCombiner::visitFPTrunc(FPTruncInst &CI) {
|
||||
Value *RHSTrunc = LookThroughFPExtensions(OpI->getOperand(1));
|
||||
if (LHSTrunc->getType() != SrcTy &&
|
||||
RHSTrunc->getType() != SrcTy) {
|
||||
unsigned DstSize = CI.getType()->getPrimitiveSizeInBits();
|
||||
unsigned DstSize = CI.getType()->getScalarSizeInBits();
|
||||
// If the source types were both smaller than the destination type of
|
||||
// the cast, do this xform.
|
||||
if (LHSTrunc->getType()->getPrimitiveSizeInBits() <= DstSize &&
|
||||
RHSTrunc->getType()->getPrimitiveSizeInBits() <= DstSize) {
|
||||
if (LHSTrunc->getType()->getScalarSizeInBits() <= DstSize &&
|
||||
RHSTrunc->getType()->getScalarSizeInBits() <= DstSize) {
|
||||
LHSTrunc = InsertCastBefore(Instruction::FPExt, LHSTrunc,
|
||||
CI.getType(), CI);
|
||||
RHSTrunc = InsertCastBefore(Instruction::FPExt, RHSTrunc,
|
||||
@ -8706,7 +8734,7 @@ Instruction *InstCombiner::visitFPToUI(FPToUIInst &FI) {
|
||||
// 'X' value would cause an undefined result for the fptoui.
|
||||
if ((isa<UIToFPInst>(OpI) || isa<SIToFPInst>(OpI)) &&
|
||||
OpI->getOperand(0)->getType() == FI.getType() &&
|
||||
(int)FI.getType()->getPrimitiveSizeInBits() < /*extra bit for sign */
|
||||
(int)FI.getType()->getScalarSizeInBits() < /*extra bit for sign */
|
||||
OpI->getType()->getFPMantissaWidth())
|
||||
return ReplaceInstUsesWith(FI, OpI->getOperand(0));
|
||||
|
||||
@ -8726,7 +8754,7 @@ Instruction *InstCombiner::visitFPToSI(FPToSIInst &FI) {
|
||||
// 'X' value would cause an undefined result for the fptoui.
|
||||
if ((isa<UIToFPInst>(OpI) || isa<SIToFPInst>(OpI)) &&
|
||||
OpI->getOperand(0)->getType() == FI.getType() &&
|
||||
(int)FI.getType()->getPrimitiveSizeInBits() <=
|
||||
(int)FI.getType()->getScalarSizeInBits() <=
|
||||
OpI->getType()->getFPMantissaWidth())
|
||||
return ReplaceInstUsesWith(FI, OpI->getOperand(0));
|
||||
|
||||
@ -8747,7 +8775,7 @@ Instruction *InstCombiner::visitPtrToInt(PtrToIntInst &CI) {
|
||||
// trunc to be exposed to other transforms. Don't do this for extending
|
||||
// ptrtoint's, because we don't know if the target sign or zero extends its
|
||||
// pointers.
|
||||
if (CI.getType()->getPrimitiveSizeInBits() < TD->getPointerSizeInBits()) {
|
||||
if (CI.getType()->getScalarSizeInBits() < TD->getPointerSizeInBits()) {
|
||||
Value *P = InsertNewInstBefore(new PtrToIntInst(CI.getOperand(0),
|
||||
TD->getIntPtrType(),
|
||||
"tmp"), CI);
|
||||
@ -8763,7 +8791,7 @@ Instruction *InstCombiner::visitIntToPtr(IntToPtrInst &CI) {
|
||||
// allows the trunc to be exposed to other transforms. Don't do this for
|
||||
// extending inttoptr's, because we don't know if the target sign or zero
|
||||
// extends to pointers.
|
||||
if (CI.getOperand(0)->getType()->getPrimitiveSizeInBits() >
|
||||
if (CI.getOperand(0)->getType()->getScalarSizeInBits() >
|
||||
TD->getPointerSizeInBits()) {
|
||||
Value *P = InsertNewInstBefore(new TruncInst(CI.getOperand(0),
|
||||
TD->getIntPtrType(),
|
||||
@ -9194,7 +9222,7 @@ Instruction *InstCombiner::visitSelectInstWithICmp(SelectInst &SI,
|
||||
(Pred == ICmpInst::ICMP_SGT && Op1CV.isAllOnesValue())) {
|
||||
Value *In = ICI->getOperand(0);
|
||||
Value *Sh = ConstantInt::get(In->getType(),
|
||||
In->getType()->getPrimitiveSizeInBits()-1);
|
||||
In->getType()->getScalarSizeInBits()-1);
|
||||
In = InsertNewInstBefore(BinaryOperator::CreateAShr(In, Sh,
|
||||
In->getName()+".lobit"),
|
||||
*ICI);
|
||||
@ -9316,7 +9344,7 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) {
|
||||
// The comparison constant and the result are not neccessarily the
|
||||
// same width. Make an all-ones value by inserting a AShr.
|
||||
Value *X = IC->getOperand(0);
|
||||
uint32_t Bits = X->getType()->getPrimitiveSizeInBits();
|
||||
uint32_t Bits = X->getType()->getScalarSizeInBits();
|
||||
Constant *ShAmt = ConstantInt::get(X->getType(), Bits-1);
|
||||
Instruction *SRA = BinaryOperator::Create(Instruction::AShr, X,
|
||||
ShAmt, "ones");
|
||||
@ -10850,8 +10878,8 @@ Instruction *InstCombiner::visitPHINode(PHINode &PN) {
|
||||
static Value *InsertCastToIntPtrTy(Value *V, const Type *DTy,
|
||||
Instruction *InsertPoint,
|
||||
InstCombiner *IC) {
|
||||
unsigned PtrSize = DTy->getPrimitiveSizeInBits();
|
||||
unsigned VTySize = V->getType()->getPrimitiveSizeInBits();
|
||||
unsigned PtrSize = DTy->getScalarSizeInBits();
|
||||
unsigned VTySize = V->getType()->getScalarSizeInBits();
|
||||
// We must cast correctly to the pointer type. Ensure that we
|
||||
// sign extend the integer value if it is smaller as this is
|
||||
// used for address computation.
|
||||
@ -10892,7 +10920,7 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
|
||||
const Type *SrcTy = CI->getOperand(0)->getType();
|
||||
// We can eliminate a cast from i32 to i64 iff the target
|
||||
// is a 32-bit pointer target.
|
||||
if (SrcTy->getPrimitiveSizeInBits() >= TD->getPointerSizeInBits()) {
|
||||
if (SrcTy->getScalarSizeInBits() >= TD->getPointerSizeInBits()) {
|
||||
MadeChange = true;
|
||||
*i = CI->getOperand(0);
|
||||
}
|
||||
@ -11105,7 +11133,7 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
|
||||
ConstantInt *Scale = 0;
|
||||
if (ArrayEltSize == 1) {
|
||||
NewIdx = GEP.getOperand(1);
|
||||
Scale = ConstantInt::get(NewIdx->getType(), 1);
|
||||
Scale = ConstantInt::get(cast<IntegerType>(NewIdx->getType()), 1);
|
||||
} else if (ConstantInt *CI = dyn_cast<ConstantInt>(GEP.getOperand(1))) {
|
||||
NewIdx = ConstantInt::get(CI->getType(), 1);
|
||||
Scale = CI;
|
||||
@ -11114,7 +11142,8 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
|
||||
isa<ConstantInt>(Inst->getOperand(1))) {
|
||||
ConstantInt *ShAmt = cast<ConstantInt>(Inst->getOperand(1));
|
||||
uint32_t ShAmtVal = ShAmt->getLimitedValue(64);
|
||||
Scale = ConstantInt::get(Inst->getType(), 1ULL << ShAmtVal);
|
||||
Scale = ConstantInt::get(cast<IntegerType>(Inst->getType()),
|
||||
1ULL << ShAmtVal);
|
||||
NewIdx = Inst->getOperand(0);
|
||||
} else if (Inst->getOpcode() == Instruction::Mul &&
|
||||
isa<ConstantInt>(Inst->getOperand(1))) {
|
||||
|
@ -290,13 +290,13 @@ static bool isUsedOutsideLoop(Value *V, Loop *L) {
|
||||
|
||||
// Return V+1
|
||||
static Value *getPlusOne(Value *V, bool Sign, Instruction *InsertPt) {
|
||||
ConstantInt *One = ConstantInt::get(V->getType(), 1, Sign);
|
||||
Constant *One = ConstantInt::get(V->getType(), 1, Sign);
|
||||
return BinaryOperator::CreateAdd(V, One, "lsp", InsertPt);
|
||||
}
|
||||
|
||||
// Return V-1
|
||||
static Value *getMinusOne(Value *V, bool Sign, Instruction *InsertPt) {
|
||||
ConstantInt *One = ConstantInt::get(V->getType(), 1, Sign);
|
||||
Constant *One = ConstantInt::get(V->getType(), 1, Sign);
|
||||
return BinaryOperator::CreateSub(V, One, "lsp", InsertPt);
|
||||
}
|
||||
|
||||
|
@ -2008,15 +2008,15 @@ ICmpInst *LoopStrengthReduce::ChangeCompareStride(Loop *L, ICmpInst *Cond,
|
||||
if (!isa<PointerType>(NewCmpTy))
|
||||
NewCmpRHS = ConstantInt::get(NewCmpTy, NewCmpVal);
|
||||
else {
|
||||
ConstantInt *CI = ConstantInt::get(NewCmpIntTy, NewCmpVal);
|
||||
Constant *CI = ConstantInt::get(NewCmpIntTy, NewCmpVal);
|
||||
NewCmpRHS = ConstantExpr::getIntToPtr(CI, NewCmpTy);
|
||||
}
|
||||
NewOffset = TyBits == NewTyBits
|
||||
? SE->getMulExpr(CondUse->getOffset(),
|
||||
SE->getConstant(ConstantInt::get(CmpTy, Scale)))
|
||||
: SE->getConstant(ConstantInt::get(NewCmpIntTy,
|
||||
SE->getConstant(CmpTy, Scale))
|
||||
: SE->getConstant(NewCmpIntTy,
|
||||
cast<SCEVConstant>(CondUse->getOffset())->getValue()
|
||||
->getSExtValue()*Scale));
|
||||
->getSExtValue()*Scale);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -2242,7 +2242,7 @@ void LoopStrengthReduce::OptimizeShadowIV(Loop *L) {
|
||||
|
||||
ConstantInt *Init = dyn_cast<ConstantInt>(PH->getIncomingValue(Entry));
|
||||
if (!Init) continue;
|
||||
ConstantFP *NewInit = ConstantFP::get(DestTy, Init->getZExtValue());
|
||||
Constant *NewInit = ConstantFP::get(DestTy, Init->getZExtValue());
|
||||
|
||||
BinaryOperator *Incr =
|
||||
dyn_cast<BinaryOperator>(PH->getIncomingValue(Latch));
|
||||
@ -2266,7 +2266,7 @@ void LoopStrengthReduce::OptimizeShadowIV(Loop *L) {
|
||||
PHINode *NewPH = PHINode::Create(DestTy, "IV.S.", PH);
|
||||
|
||||
/* create new increment. '++d' in above example. */
|
||||
ConstantFP *CFP = ConstantFP::get(DestTy, C->getZExtValue());
|
||||
Constant *CFP = ConstantFP::get(DestTy, C->getZExtValue());
|
||||
BinaryOperator *NewIncr =
|
||||
BinaryOperator::Create(Incr->getOpcode() == Instruction::Add ?
|
||||
Instruction::FAdd : Instruction::FSub,
|
||||
@ -2506,7 +2506,7 @@ void LoopStrengthReduce::OptimizeLoopCountIV(Loop *L) {
|
||||
Value *startVal = phi->getIncomingValue(inBlock);
|
||||
Value *endVal = Cond->getOperand(1);
|
||||
// FIXME check for case where both are constant
|
||||
ConstantInt* Zero = ConstantInt::get(Cond->getOperand(1)->getType(), 0);
|
||||
Constant* Zero = ConstantInt::get(Cond->getOperand(1)->getType(), 0);
|
||||
BinaryOperator *NewStartVal =
|
||||
BinaryOperator::Create(Instruction::Sub, endVal, startVal,
|
||||
"tmp", PreInsertPt);
|
||||
|
@ -208,6 +208,22 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, const Constant *V,
|
||||
}
|
||||
}
|
||||
|
||||
// If the cast operand is a constant vector, perform the cast by
|
||||
// operating on each element. In the cast of bitcasts, the element
|
||||
// count may be mismatched; don't attempt to handle that here.
|
||||
if (const ConstantVector *CV = dyn_cast<ConstantVector>(V))
|
||||
if (isa<VectorType>(DestTy) &&
|
||||
cast<VectorType>(DestTy)->getNumElements() ==
|
||||
CV->getType()->getNumElements()) {
|
||||
std::vector<Constant*> res;
|
||||
const VectorType *DestVecTy = cast<VectorType>(DestTy);
|
||||
const Type *DstEltTy = DestVecTy->getElementType();
|
||||
for (unsigned i = 0, e = CV->getType()->getNumElements(); i != e; ++i)
|
||||
res.push_back(ConstantExpr::getCast(opc,
|
||||
CV->getOperand(i), DstEltTy));
|
||||
return ConstantVector::get(DestVecTy, res);
|
||||
}
|
||||
|
||||
// We actually have to do a cast now. Perform the cast according to the
|
||||
// opcode specified.
|
||||
switch (opc) {
|
||||
@ -237,14 +253,6 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, const Constant *V,
|
||||
APInt Val(DestBitWidth, 2, x);
|
||||
return ConstantInt::get(Val);
|
||||
}
|
||||
if (const ConstantVector *CV = dyn_cast<ConstantVector>(V)) {
|
||||
std::vector<Constant*> res;
|
||||
const VectorType *DestVecTy = cast<VectorType>(DestTy);
|
||||
const Type *DstEltTy = DestVecTy->getElementType();
|
||||
for (unsigned i = 0, e = CV->getType()->getNumElements(); i != e; ++i)
|
||||
res.push_back(ConstantExpr::getCast(opc, CV->getOperand(i), DstEltTy));
|
||||
return ConstantVector::get(DestVecTy, res);
|
||||
}
|
||||
return 0; // Can't fold.
|
||||
case Instruction::IntToPtr: //always treated as unsigned
|
||||
if (V->isNullValue()) // Is it an integral null value?
|
||||
@ -266,14 +274,6 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, const Constant *V,
|
||||
APFloat::rmNearestTiesToEven);
|
||||
return ConstantFP::get(apf);
|
||||
}
|
||||
if (const ConstantVector *CV = dyn_cast<ConstantVector>(V)) {
|
||||
std::vector<Constant*> res;
|
||||
const VectorType *DestVecTy = cast<VectorType>(DestTy);
|
||||
const Type *DstEltTy = DestVecTy->getElementType();
|
||||
for (unsigned i = 0, e = CV->getType()->getNumElements(); i != e; ++i)
|
||||
res.push_back(ConstantExpr::getCast(opc, CV->getOperand(i), DstEltTy));
|
||||
return ConstantVector::get(DestVecTy, res);
|
||||
}
|
||||
return 0;
|
||||
case Instruction::ZExt:
|
||||
if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
|
||||
|
@ -269,9 +269,20 @@ typedef DenseMap<DenseMapAPIntKeyInfo::KeyTy, ConstantInt*,
|
||||
DenseMapAPIntKeyInfo> IntMapTy;
|
||||
static ManagedStatic<IntMapTy> IntConstants;
|
||||
|
||||
ConstantInt *ConstantInt::get(const Type *Ty, uint64_t V, bool isSigned) {
|
||||
const IntegerType *ITy = cast<IntegerType>(Ty);
|
||||
return get(APInt(ITy->getBitWidth(), V, isSigned));
|
||||
ConstantInt *ConstantInt::get(const IntegerType *Ty,
|
||||
uint64_t V, bool isSigned) {
|
||||
return get(APInt(Ty->getBitWidth(), V, isSigned));
|
||||
}
|
||||
|
||||
Constant *ConstantInt::get(const Type *Ty, uint64_t V, bool isSigned) {
|
||||
Constant *C = get(cast<IntegerType>(Ty->getScalarType()), V, isSigned);
|
||||
|
||||
// For vectors, broadcast the value.
|
||||
if (const VectorType *VTy = dyn_cast<VectorType>(Ty))
|
||||
return
|
||||
ConstantVector::get(std::vector<Constant *>(VTy->getNumElements(), C));
|
||||
|
||||
return C;
|
||||
}
|
||||
|
||||
// Get a ConstantInt from an APInt. Note that the value stored in the DenseMap
|
||||
@ -292,6 +303,19 @@ ConstantInt *ConstantInt::get(const APInt& V) {
|
||||
return Slot = new ConstantInt(ITy, V);
|
||||
}
|
||||
|
||||
Constant *ConstantInt::get(const Type *Ty, const APInt &V) {
|
||||
ConstantInt *C = ConstantInt::get(V);
|
||||
assert(C->getType() == Ty->getScalarType() &&
|
||||
"ConstantInt type doesn't match the type implied by its value!");
|
||||
|
||||
// For vectors, broadcast the value.
|
||||
if (const VectorType *VTy = dyn_cast<VectorType>(Ty))
|
||||
return
|
||||
ConstantVector::get(std::vector<Constant *>(VTy->getNumElements(), C));
|
||||
|
||||
return C;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// ConstantFP
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -391,11 +415,19 @@ ConstantFP *ConstantFP::get(const APFloat &V) {
|
||||
/// get() - This returns a constant fp for the specified value in the
|
||||
/// specified type. This should only be used for simple constant values like
|
||||
/// 2.0/1.0 etc, that are known-valid both as double and as the target format.
|
||||
ConstantFP *ConstantFP::get(const Type *Ty, double V) {
|
||||
Constant *ConstantFP::get(const Type *Ty, double V) {
|
||||
APFloat FV(V);
|
||||
bool ignored;
|
||||
FV.convert(*TypeToFloatSemantics(Ty), APFloat::rmNearestTiesToEven, &ignored);
|
||||
return get(FV);
|
||||
FV.convert(*TypeToFloatSemantics(Ty->getScalarType()),
|
||||
APFloat::rmNearestTiesToEven, &ignored);
|
||||
Constant *C = get(FV);
|
||||
|
||||
// For vectors, broadcast the value.
|
||||
if (const VectorType *VTy = dyn_cast<VectorType>(Ty))
|
||||
return
|
||||
ConstantVector::get(std::vector<Constant *>(VTy->getNumElements(), C));
|
||||
|
||||
return C;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -1932,19 +1964,19 @@ Constant *ConstantExpr::getCast(unsigned oc, Constant *C, const Type *Ty) {
|
||||
}
|
||||
|
||||
Constant *ConstantExpr::getZExtOrBitCast(Constant *C, const Type *Ty) {
|
||||
if (C->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits())
|
||||
if (C->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits())
|
||||
return getCast(Instruction::BitCast, C, Ty);
|
||||
return getCast(Instruction::ZExt, C, Ty);
|
||||
}
|
||||
|
||||
Constant *ConstantExpr::getSExtOrBitCast(Constant *C, const Type *Ty) {
|
||||
if (C->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits())
|
||||
if (C->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits())
|
||||
return getCast(Instruction::BitCast, C, Ty);
|
||||
return getCast(Instruction::SExt, C, Ty);
|
||||
}
|
||||
|
||||
Constant *ConstantExpr::getTruncOrBitCast(Constant *C, const Type *Ty) {
|
||||
if (C->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits())
|
||||
if (C->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits())
|
||||
return getCast(Instruction::BitCast, C, Ty);
|
||||
return getCast(Instruction::Trunc, C, Ty);
|
||||
}
|
||||
@ -1960,9 +1992,10 @@ Constant *ConstantExpr::getPointerCast(Constant *S, const Type *Ty) {
|
||||
|
||||
Constant *ConstantExpr::getIntegerCast(Constant *C, const Type *Ty,
|
||||
bool isSigned) {
|
||||
assert(C->getType()->isInteger() && Ty->isInteger() && "Invalid cast");
|
||||
unsigned SrcBits = C->getType()->getPrimitiveSizeInBits();
|
||||
unsigned DstBits = Ty->getPrimitiveSizeInBits();
|
||||
assert(C->getType()->isIntOrIntVector() &&
|
||||
Ty->isIntOrIntVector() && "Invalid cast");
|
||||
unsigned SrcBits = C->getType()->getScalarSizeInBits();
|
||||
unsigned DstBits = Ty->getScalarSizeInBits();
|
||||
Instruction::CastOps opcode =
|
||||
(SrcBits == DstBits ? Instruction::BitCast :
|
||||
(SrcBits > DstBits ? Instruction::Trunc :
|
||||
@ -1971,10 +2004,10 @@ Constant *ConstantExpr::getIntegerCast(Constant *C, const Type *Ty,
|
||||
}
|
||||
|
||||
Constant *ConstantExpr::getFPCast(Constant *C, const Type *Ty) {
|
||||
assert(C->getType()->isFloatingPoint() && Ty->isFloatingPoint() &&
|
||||
assert(C->getType()->isFPOrFPVector() && Ty->isFPOrFPVector() &&
|
||||
"Invalid cast");
|
||||
unsigned SrcBits = C->getType()->getPrimitiveSizeInBits();
|
||||
unsigned DstBits = Ty->getPrimitiveSizeInBits();
|
||||
unsigned SrcBits = C->getType()->getScalarSizeInBits();
|
||||
unsigned DstBits = Ty->getScalarSizeInBits();
|
||||
if (SrcBits == DstBits)
|
||||
return C; // Avoid a useless cast
|
||||
Instruction::CastOps opcode =
|
||||
@ -1983,42 +2016,67 @@ Constant *ConstantExpr::getFPCast(Constant *C, const Type *Ty) {
|
||||
}
|
||||
|
||||
Constant *ConstantExpr::getTrunc(Constant *C, const Type *Ty) {
|
||||
assert(C->getType()->isInteger() && "Trunc operand must be integer");
|
||||
assert(Ty->isInteger() && "Trunc produces only integral");
|
||||
assert(C->getType()->getPrimitiveSizeInBits() > Ty->getPrimitiveSizeInBits()&&
|
||||
#ifndef NDEBUG
|
||||
bool fromVec = C->getType()->getTypeID() == Type::VectorTyID;
|
||||
bool toVec = Ty->getTypeID() == Type::VectorTyID;
|
||||
#endif
|
||||
assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
|
||||
assert(C->getType()->isIntOrIntVector() && "Trunc operand must be integer");
|
||||
assert(Ty->isIntOrIntVector() && "Trunc produces only integral");
|
||||
assert(C->getType()->getScalarSizeInBits() > Ty->getScalarSizeInBits()&&
|
||||
"SrcTy must be larger than DestTy for Trunc!");
|
||||
|
||||
return getFoldedCast(Instruction::Trunc, C, Ty);
|
||||
}
|
||||
|
||||
Constant *ConstantExpr::getSExt(Constant *C, const Type *Ty) {
|
||||
assert(C->getType()->isInteger() && "SEXt operand must be integral");
|
||||
assert(Ty->isInteger() && "SExt produces only integer");
|
||||
assert(C->getType()->getPrimitiveSizeInBits() < Ty->getPrimitiveSizeInBits()&&
|
||||
#ifndef NDEBUG
|
||||
bool fromVec = C->getType()->getTypeID() == Type::VectorTyID;
|
||||
bool toVec = Ty->getTypeID() == Type::VectorTyID;
|
||||
#endif
|
||||
assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
|
||||
assert(C->getType()->isIntOrIntVector() && "SExt operand must be integral");
|
||||
assert(Ty->isIntOrIntVector() && "SExt produces only integer");
|
||||
assert(C->getType()->getScalarSizeInBits() < Ty->getScalarSizeInBits()&&
|
||||
"SrcTy must be smaller than DestTy for SExt!");
|
||||
|
||||
return getFoldedCast(Instruction::SExt, C, Ty);
|
||||
}
|
||||
|
||||
Constant *ConstantExpr::getZExt(Constant *C, const Type *Ty) {
|
||||
assert(C->getType()->isInteger() && "ZEXt operand must be integral");
|
||||
assert(Ty->isInteger() && "ZExt produces only integer");
|
||||
assert(C->getType()->getPrimitiveSizeInBits() < Ty->getPrimitiveSizeInBits()&&
|
||||
#ifndef NDEBUG
|
||||
bool fromVec = C->getType()->getTypeID() == Type::VectorTyID;
|
||||
bool toVec = Ty->getTypeID() == Type::VectorTyID;
|
||||
#endif
|
||||
assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
|
||||
assert(C->getType()->isIntOrIntVector() && "ZEXt operand must be integral");
|
||||
assert(Ty->isIntOrIntVector() && "ZExt produces only integer");
|
||||
assert(C->getType()->getScalarSizeInBits() < Ty->getScalarSizeInBits()&&
|
||||
"SrcTy must be smaller than DestTy for ZExt!");
|
||||
|
||||
return getFoldedCast(Instruction::ZExt, C, Ty);
|
||||
}
|
||||
|
||||
Constant *ConstantExpr::getFPTrunc(Constant *C, const Type *Ty) {
|
||||
assert(C->getType()->isFloatingPoint() && Ty->isFloatingPoint() &&
|
||||
C->getType()->getPrimitiveSizeInBits() > Ty->getPrimitiveSizeInBits()&&
|
||||
#ifndef NDEBUG
|
||||
bool fromVec = C->getType()->getTypeID() == Type::VectorTyID;
|
||||
bool toVec = Ty->getTypeID() == Type::VectorTyID;
|
||||
#endif
|
||||
assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
|
||||
assert(C->getType()->isFPOrFPVector() && Ty->isFPOrFPVector() &&
|
||||
C->getType()->getScalarSizeInBits() > Ty->getScalarSizeInBits()&&
|
||||
"This is an illegal floating point truncation!");
|
||||
return getFoldedCast(Instruction::FPTrunc, C, Ty);
|
||||
}
|
||||
|
||||
Constant *ConstantExpr::getFPExtend(Constant *C, const Type *Ty) {
|
||||
assert(C->getType()->isFloatingPoint() && Ty->isFloatingPoint() &&
|
||||
C->getType()->getPrimitiveSizeInBits() < Ty->getPrimitiveSizeInBits()&&
|
||||
#ifndef NDEBUG
|
||||
bool fromVec = C->getType()->getTypeID() == Type::VectorTyID;
|
||||
bool toVec = Ty->getTypeID() == Type::VectorTyID;
|
||||
#endif
|
||||
assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
|
||||
assert(C->getType()->isFPOrFPVector() && Ty->isFPOrFPVector() &&
|
||||
C->getType()->getScalarSizeInBits() < Ty->getScalarSizeInBits()&&
|
||||
"This is an illegal floating point extension!");
|
||||
return getFoldedCast(Instruction::FPExt, C, Ty);
|
||||
}
|
||||
|
@ -1837,11 +1837,11 @@ bool CastInst::isNoopCast(const Type *IntPtrTy) const {
|
||||
case Instruction::BitCast:
|
||||
return true; // BitCast never modifies bits.
|
||||
case Instruction::PtrToInt:
|
||||
return IntPtrTy->getPrimitiveSizeInBits() ==
|
||||
getType()->getPrimitiveSizeInBits();
|
||||
return IntPtrTy->getScalarSizeInBits() ==
|
||||
getType()->getScalarSizeInBits();
|
||||
case Instruction::IntToPtr:
|
||||
return IntPtrTy->getPrimitiveSizeInBits() ==
|
||||
getOperand(0)->getType()->getPrimitiveSizeInBits();
|
||||
return IntPtrTy->getScalarSizeInBits() ==
|
||||
getOperand(0)->getType()->getScalarSizeInBits();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1946,8 +1946,8 @@ unsigned CastInst::isEliminableCastPair(
|
||||
return 0;
|
||||
case 7: {
|
||||
// ptrtoint, inttoptr -> bitcast (ptr -> ptr) if int size is >= ptr size
|
||||
unsigned PtrSize = IntPtrTy->getPrimitiveSizeInBits();
|
||||
unsigned MidSize = MidTy->getPrimitiveSizeInBits();
|
||||
unsigned PtrSize = IntPtrTy->getScalarSizeInBits();
|
||||
unsigned MidSize = MidTy->getScalarSizeInBits();
|
||||
if (MidSize >= PtrSize)
|
||||
return Instruction::BitCast;
|
||||
return 0;
|
||||
@ -1956,8 +1956,8 @@ unsigned CastInst::isEliminableCastPair(
|
||||
// ext, trunc -> bitcast, if the SrcTy and DstTy are same size
|
||||
// ext, trunc -> ext, if sizeof(SrcTy) < sizeof(DstTy)
|
||||
// ext, trunc -> trunc, if sizeof(SrcTy) > sizeof(DstTy)
|
||||
unsigned SrcSize = SrcTy->getPrimitiveSizeInBits();
|
||||
unsigned DstSize = DstTy->getPrimitiveSizeInBits();
|
||||
unsigned SrcSize = SrcTy->getScalarSizeInBits();
|
||||
unsigned DstSize = DstTy->getScalarSizeInBits();
|
||||
if (SrcSize == DstSize)
|
||||
return Instruction::BitCast;
|
||||
else if (SrcSize < DstSize)
|
||||
@ -1985,9 +1985,9 @@ unsigned CastInst::isEliminableCastPair(
|
||||
return 0;
|
||||
case 13: {
|
||||
// inttoptr, ptrtoint -> bitcast if SrcSize<=PtrSize and SrcSize==DstSize
|
||||
unsigned PtrSize = IntPtrTy->getPrimitiveSizeInBits();
|
||||
unsigned SrcSize = SrcTy->getPrimitiveSizeInBits();
|
||||
unsigned DstSize = DstTy->getPrimitiveSizeInBits();
|
||||
unsigned PtrSize = IntPtrTy->getScalarSizeInBits();
|
||||
unsigned SrcSize = SrcTy->getScalarSizeInBits();
|
||||
unsigned DstSize = DstTy->getScalarSizeInBits();
|
||||
if (SrcSize <= PtrSize && SrcSize == DstSize)
|
||||
return Instruction::BitCast;
|
||||
return 0;
|
||||
@ -2051,7 +2051,7 @@ CastInst *CastInst::Create(Instruction::CastOps op, Value *S, const Type *Ty,
|
||||
CastInst *CastInst::CreateZExtOrBitCast(Value *S, const Type *Ty,
|
||||
const std::string &Name,
|
||||
Instruction *InsertBefore) {
|
||||
if (S->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits())
|
||||
if (S->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits())
|
||||
return Create(Instruction::BitCast, S, Ty, Name, InsertBefore);
|
||||
return Create(Instruction::ZExt, S, Ty, Name, InsertBefore);
|
||||
}
|
||||
@ -2059,7 +2059,7 @@ CastInst *CastInst::CreateZExtOrBitCast(Value *S, const Type *Ty,
|
||||
CastInst *CastInst::CreateZExtOrBitCast(Value *S, const Type *Ty,
|
||||
const std::string &Name,
|
||||
BasicBlock *InsertAtEnd) {
|
||||
if (S->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits())
|
||||
if (S->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits())
|
||||
return Create(Instruction::BitCast, S, Ty, Name, InsertAtEnd);
|
||||
return Create(Instruction::ZExt, S, Ty, Name, InsertAtEnd);
|
||||
}
|
||||
@ -2067,7 +2067,7 @@ CastInst *CastInst::CreateZExtOrBitCast(Value *S, const Type *Ty,
|
||||
CastInst *CastInst::CreateSExtOrBitCast(Value *S, const Type *Ty,
|
||||
const std::string &Name,
|
||||
Instruction *InsertBefore) {
|
||||
if (S->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits())
|
||||
if (S->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits())
|
||||
return Create(Instruction::BitCast, S, Ty, Name, InsertBefore);
|
||||
return Create(Instruction::SExt, S, Ty, Name, InsertBefore);
|
||||
}
|
||||
@ -2075,7 +2075,7 @@ CastInst *CastInst::CreateSExtOrBitCast(Value *S, const Type *Ty,
|
||||
CastInst *CastInst::CreateSExtOrBitCast(Value *S, const Type *Ty,
|
||||
const std::string &Name,
|
||||
BasicBlock *InsertAtEnd) {
|
||||
if (S->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits())
|
||||
if (S->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits())
|
||||
return Create(Instruction::BitCast, S, Ty, Name, InsertAtEnd);
|
||||
return Create(Instruction::SExt, S, Ty, Name, InsertAtEnd);
|
||||
}
|
||||
@ -2083,7 +2083,7 @@ CastInst *CastInst::CreateSExtOrBitCast(Value *S, const Type *Ty,
|
||||
CastInst *CastInst::CreateTruncOrBitCast(Value *S, const Type *Ty,
|
||||
const std::string &Name,
|
||||
Instruction *InsertBefore) {
|
||||
if (S->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits())
|
||||
if (S->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits())
|
||||
return Create(Instruction::BitCast, S, Ty, Name, InsertBefore);
|
||||
return Create(Instruction::Trunc, S, Ty, Name, InsertBefore);
|
||||
}
|
||||
@ -2091,7 +2091,7 @@ CastInst *CastInst::CreateTruncOrBitCast(Value *S, const Type *Ty,
|
||||
CastInst *CastInst::CreateTruncOrBitCast(Value *S, const Type *Ty,
|
||||
const std::string &Name,
|
||||
BasicBlock *InsertAtEnd) {
|
||||
if (S->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits())
|
||||
if (S->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits())
|
||||
return Create(Instruction::BitCast, S, Ty, Name, InsertAtEnd);
|
||||
return Create(Instruction::Trunc, S, Ty, Name, InsertAtEnd);
|
||||
}
|
||||
@ -2125,8 +2125,8 @@ CastInst *CastInst::CreateIntegerCast(Value *C, const Type *Ty,
|
||||
bool isSigned, const std::string &Name,
|
||||
Instruction *InsertBefore) {
|
||||
assert(C->getType()->isInteger() && Ty->isInteger() && "Invalid cast");
|
||||
unsigned SrcBits = C->getType()->getPrimitiveSizeInBits();
|
||||
unsigned DstBits = Ty->getPrimitiveSizeInBits();
|
||||
unsigned SrcBits = C->getType()->getScalarSizeInBits();
|
||||
unsigned DstBits = Ty->getScalarSizeInBits();
|
||||
Instruction::CastOps opcode =
|
||||
(SrcBits == DstBits ? Instruction::BitCast :
|
||||
(SrcBits > DstBits ? Instruction::Trunc :
|
||||
@ -2138,8 +2138,8 @@ CastInst *CastInst::CreateIntegerCast(Value *C, const Type *Ty,
|
||||
bool isSigned, const std::string &Name,
|
||||
BasicBlock *InsertAtEnd) {
|
||||
assert(C->getType()->isInteger() && Ty->isInteger() && "Invalid cast");
|
||||
unsigned SrcBits = C->getType()->getPrimitiveSizeInBits();
|
||||
unsigned DstBits = Ty->getPrimitiveSizeInBits();
|
||||
unsigned SrcBits = C->getType()->getScalarSizeInBits();
|
||||
unsigned DstBits = Ty->getScalarSizeInBits();
|
||||
Instruction::CastOps opcode =
|
||||
(SrcBits == DstBits ? Instruction::BitCast :
|
||||
(SrcBits > DstBits ? Instruction::Trunc :
|
||||
@ -2152,8 +2152,8 @@ CastInst *CastInst::CreateFPCast(Value *C, const Type *Ty,
|
||||
Instruction *InsertBefore) {
|
||||
assert(C->getType()->isFloatingPoint() && Ty->isFloatingPoint() &&
|
||||
"Invalid cast");
|
||||
unsigned SrcBits = C->getType()->getPrimitiveSizeInBits();
|
||||
unsigned DstBits = Ty->getPrimitiveSizeInBits();
|
||||
unsigned SrcBits = C->getType()->getScalarSizeInBits();
|
||||
unsigned DstBits = Ty->getScalarSizeInBits();
|
||||
Instruction::CastOps opcode =
|
||||
(SrcBits == DstBits ? Instruction::BitCast :
|
||||
(SrcBits > DstBits ? Instruction::FPTrunc : Instruction::FPExt));
|
||||
@ -2165,8 +2165,8 @@ CastInst *CastInst::CreateFPCast(Value *C, const Type *Ty,
|
||||
BasicBlock *InsertAtEnd) {
|
||||
assert(C->getType()->isFloatingPoint() && Ty->isFloatingPoint() &&
|
||||
"Invalid cast");
|
||||
unsigned SrcBits = C->getType()->getPrimitiveSizeInBits();
|
||||
unsigned DstBits = Ty->getPrimitiveSizeInBits();
|
||||
unsigned SrcBits = C->getType()->getScalarSizeInBits();
|
||||
unsigned DstBits = Ty->getScalarSizeInBits();
|
||||
Instruction::CastOps opcode =
|
||||
(SrcBits == DstBits ? Instruction::BitCast :
|
||||
(SrcBits > DstBits ? Instruction::FPTrunc : Instruction::FPExt));
|
||||
@ -2183,8 +2183,8 @@ bool CastInst::isCastable(const Type *SrcTy, const Type *DestTy) {
|
||||
return true;
|
||||
|
||||
// Get the bit sizes, we'll need these
|
||||
unsigned SrcBits = SrcTy->getPrimitiveSizeInBits(); // 0 for ptr/vector
|
||||
unsigned DestBits = DestTy->getPrimitiveSizeInBits(); // 0 for ptr/vector
|
||||
unsigned SrcBits = SrcTy->getScalarSizeInBits(); // 0 for ptr
|
||||
unsigned DestBits = DestTy->getScalarSizeInBits(); // 0 for ptr
|
||||
|
||||
// Run through the possibilities ...
|
||||
if (DestTy->isInteger()) { // Casting to integral
|
||||
@ -2242,8 +2242,8 @@ CastInst::getCastOpcode(
|
||||
const Value *Src, bool SrcIsSigned, const Type *DestTy, bool DestIsSigned) {
|
||||
// Get the bit sizes, we'll need these
|
||||
const Type *SrcTy = Src->getType();
|
||||
unsigned SrcBits = SrcTy->getPrimitiveSizeInBits(); // 0 for ptr/vector
|
||||
unsigned DestBits = DestTy->getPrimitiveSizeInBits(); // 0 for ptr/vector
|
||||
unsigned SrcBits = SrcTy->getScalarSizeInBits(); // 0 for ptr
|
||||
unsigned DestBits = DestTy->getScalarSizeInBits(); // 0 for ptr
|
||||
|
||||
assert(SrcTy->isFirstClassType() && DestTy->isFirstClassType() &&
|
||||
"Only first class types are castable!");
|
||||
@ -2344,8 +2344,8 @@ CastInst::castIsValid(Instruction::CastOps op, Value *S, const Type *DstTy) {
|
||||
return false;
|
||||
|
||||
// Get the size of the types in bits, we'll need this later
|
||||
unsigned SrcBitSize = SrcTy->getPrimitiveSizeInBits();
|
||||
unsigned DstBitSize = DstTy->getPrimitiveSizeInBits();
|
||||
unsigned SrcBitSize = SrcTy->getScalarSizeInBits();
|
||||
unsigned DstBitSize = DstTy->getScalarSizeInBits();
|
||||
|
||||
// Switch on the opcode provided
|
||||
switch (op) {
|
||||
@ -2400,7 +2400,7 @@ CastInst::castIsValid(Instruction::CastOps op, Value *S, const Type *DstTy) {
|
||||
// Now we know we're not dealing with a pointer/non-pointer mismatch. In all
|
||||
// these cases, the cast is okay if the source and destination bit widths
|
||||
// are identical.
|
||||
return SrcBitSize == DstBitSize;
|
||||
return SrcTy->getPrimitiveSizeInBits() == DstTy->getPrimitiveSizeInBits();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -112,6 +112,14 @@ const Type *Type::getVAArgsPromotedType() const {
|
||||
return this;
|
||||
}
|
||||
|
||||
/// getScalarType - If this is a vector type, return the element type,
|
||||
/// otherwise return this.
|
||||
const Type *Type::getScalarType() const {
|
||||
if (const VectorType *VTy = dyn_cast<VectorType>(this))
|
||||
return VTy->getElementType();
|
||||
return this;
|
||||
}
|
||||
|
||||
/// isIntOrIntVector - Return true if this is an integer type or a vector of
|
||||
/// integer types.
|
||||
///
|
||||
@ -174,6 +182,28 @@ unsigned Type::getPrimitiveSizeInBits() const {
|
||||
}
|
||||
}
|
||||
|
||||
/// getScalarSizeInBits - If this is a vector type, return the
|
||||
/// getPrimitiveSizeInBits value for the element type. Otherwise return the
|
||||
/// getPrimitiveSizeInBits value for this type.
|
||||
unsigned Type::getScalarSizeInBits() const {
|
||||
return getScalarType()->getPrimitiveSizeInBits();
|
||||
}
|
||||
|
||||
/// getFPMantissaWidth - Return the width of the mantissa of this type. This
|
||||
/// is only valid on floating point types. If the FP type does not
|
||||
/// have a stable mantissa (e.g. ppc long double), this method returns -1.
|
||||
int Type::getFPMantissaWidth() const {
|
||||
if (const VectorType *VTy = dyn_cast<VectorType>(this))
|
||||
return VTy->getElementType()->getFPMantissaWidth();
|
||||
assert(isFloatingPoint() && "Not a floating point type!");
|
||||
if (ID == FloatTyID) return 24;
|
||||
if (ID == DoubleTyID) return 53;
|
||||
if (ID == X86_FP80TyID) return 64;
|
||||
if (ID == FP128TyID) return 113;
|
||||
assert(ID == PPC_FP128TyID && "unknown fp type");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// isSizedDerivedType - Derived types like structures and arrays are sized
|
||||
/// iff all of the members of the type are sized as well. Since asking for
|
||||
/// their size is relatively uncommon, move this operation out of line.
|
||||
|
@ -745,8 +745,8 @@ void Verifier::visitTruncInst(TruncInst &I) {
|
||||
const Type *DestTy = I.getType();
|
||||
|
||||
// Get the size of the types in bits, we'll need this later
|
||||
unsigned SrcBitSize = SrcTy->getPrimitiveSizeInBits();
|
||||
unsigned DestBitSize = DestTy->getPrimitiveSizeInBits();
|
||||
unsigned SrcBitSize = SrcTy->getScalarSizeInBits();
|
||||
unsigned DestBitSize = DestTy->getScalarSizeInBits();
|
||||
|
||||
Assert1(SrcTy->isIntOrIntVector(), "Trunc only operates on integer", &I);
|
||||
Assert1(DestTy->isIntOrIntVector(), "Trunc only produces integer", &I);
|
||||
@ -767,8 +767,8 @@ void Verifier::visitZExtInst(ZExtInst &I) {
|
||||
Assert1(DestTy->isIntOrIntVector(), "ZExt only produces an integer", &I);
|
||||
Assert1(isa<VectorType>(SrcTy) == isa<VectorType>(DestTy),
|
||||
"zext source and destination must both be a vector or neither", &I);
|
||||
unsigned SrcBitSize = SrcTy->getPrimitiveSizeInBits();
|
||||
unsigned DestBitSize = DestTy->getPrimitiveSizeInBits();
|
||||
unsigned SrcBitSize = SrcTy->getScalarSizeInBits();
|
||||
unsigned DestBitSize = DestTy->getScalarSizeInBits();
|
||||
|
||||
Assert1(SrcBitSize < DestBitSize,"Type too small for ZExt", &I);
|
||||
|
||||
@ -781,8 +781,8 @@ void Verifier::visitSExtInst(SExtInst &I) {
|
||||
const Type *DestTy = I.getType();
|
||||
|
||||
// Get the size of the types in bits, we'll need this later
|
||||
unsigned SrcBitSize = SrcTy->getPrimitiveSizeInBits();
|
||||
unsigned DestBitSize = DestTy->getPrimitiveSizeInBits();
|
||||
unsigned SrcBitSize = SrcTy->getScalarSizeInBits();
|
||||
unsigned DestBitSize = DestTy->getScalarSizeInBits();
|
||||
|
||||
Assert1(SrcTy->isIntOrIntVector(), "SExt only operates on integer", &I);
|
||||
Assert1(DestTy->isIntOrIntVector(), "SExt only produces an integer", &I);
|
||||
@ -798,8 +798,8 @@ void Verifier::visitFPTruncInst(FPTruncInst &I) {
|
||||
const Type *SrcTy = I.getOperand(0)->getType();
|
||||
const Type *DestTy = I.getType();
|
||||
// Get the size of the types in bits, we'll need this later
|
||||
unsigned SrcBitSize = SrcTy->getPrimitiveSizeInBits();
|
||||
unsigned DestBitSize = DestTy->getPrimitiveSizeInBits();
|
||||
unsigned SrcBitSize = SrcTy->getScalarSizeInBits();
|
||||
unsigned DestBitSize = DestTy->getScalarSizeInBits();
|
||||
|
||||
Assert1(SrcTy->isFPOrFPVector(),"FPTrunc only operates on FP", &I);
|
||||
Assert1(DestTy->isFPOrFPVector(),"FPTrunc only produces an FP", &I);
|
||||
@ -816,8 +816,8 @@ void Verifier::visitFPExtInst(FPExtInst &I) {
|
||||
const Type *DestTy = I.getType();
|
||||
|
||||
// Get the size of the types in bits, we'll need this later
|
||||
unsigned SrcBitSize = SrcTy->getPrimitiveSizeInBits();
|
||||
unsigned DestBitSize = DestTy->getPrimitiveSizeInBits();
|
||||
unsigned SrcBitSize = SrcTy->getScalarSizeInBits();
|
||||
unsigned DestBitSize = DestTy->getScalarSizeInBits();
|
||||
|
||||
Assert1(SrcTy->isFPOrFPVector(),"FPExt only operates on FP", &I);
|
||||
Assert1(DestTy->isFPOrFPVector(),"FPExt only produces an FP", &I);
|
||||
|
37
test/Feature/vector-cast-constant-exprs.ll
Normal file
37
test/Feature/vector-cast-constant-exprs.ll
Normal file
@ -0,0 +1,37 @@
|
||||
; RUN: llvm-as < %s | llvm-dis | not grep {ret.*(}
|
||||
|
||||
; All of these constant expressions should fold.
|
||||
|
||||
define <2 x float> @ga() {
|
||||
ret <2 x float> fptrunc (<2 x double><double 4.3, double 3.2> to <2 x float>)
|
||||
}
|
||||
define <2 x double> @gb() {
|
||||
ret <2 x double> fpext (<2 x float><float 2.0, float 8.0> to <2 x double>)
|
||||
}
|
||||
define <2 x i64> @gd() {
|
||||
ret <2 x i64> zext (<2 x i32><i32 3, i32 4> to <2 x i64>)
|
||||
}
|
||||
define <2 x i64> @ge() {
|
||||
ret <2 x i64> sext (<2 x i32><i32 3, i32 4> to <2 x i64>)
|
||||
}
|
||||
define <2 x i32> @gf() {
|
||||
ret <2 x i32> trunc (<2 x i64><i64 3, i64 4> to <2 x i32>)
|
||||
}
|
||||
define <2 x i32> @gh() {
|
||||
ret <2 x i32> fptoui (<2 x float><float 8.0, float 7.0> to <2 x i32>)
|
||||
}
|
||||
define <2 x i32> @gi() {
|
||||
ret <2 x i32> fptosi (<2 x float><float 8.0, float 7.0> to <2 x i32>)
|
||||
}
|
||||
define <2 x float> @gj() {
|
||||
ret <2 x float> uitofp (<2 x i32><i32 8, i32 7> to <2 x float>)
|
||||
}
|
||||
define <2 x float> @gk() {
|
||||
ret <2 x float> sitofp (<2 x i32><i32 8, i32 7> to <2 x float>)
|
||||
}
|
||||
define <2 x double> @gl() {
|
||||
ret <2 x double> bitcast (<2 x double><double 4.0, double 3.0> to <2 x double>)
|
||||
}
|
||||
define <2 x double> @gm() {
|
||||
ret <2 x double> bitcast (<2 x i64><i64 4, i64 3> to <2 x double>)
|
||||
}
|
55
test/Transforms/InstCombine/vector-casts.ll
Normal file
55
test/Transforms/InstCombine/vector-casts.ll
Normal file
@ -0,0 +1,55 @@
|
||||
; RUN: llvm-as < %s | opt -instcombine
|
||||
|
||||
define void @convert(<2 x i32>* %dst.addr, <2 x i64> %src) nounwind {
|
||||
entry:
|
||||
%val = trunc <2 x i64> %src to <2 x i32> ; <<2 x i32>> [#uses=1]
|
||||
%add = add <2 x i32> %val, <i32 1, i32 1> ; <<2 x i32>> [#uses=1]
|
||||
store <2 x i32> %add, <2 x i32>* %dst.addr
|
||||
ret void
|
||||
}
|
||||
|
||||
define <2 x i65> @foo(<2 x i64> %t) {
|
||||
%a = trunc <2 x i64> %t to <2 x i32>
|
||||
%b = zext <2 x i32> %a to <2 x i65>
|
||||
ret <2 x i65> %b
|
||||
}
|
||||
define <2 x i64> @bar(<2 x i65> %t) {
|
||||
%a = trunc <2 x i65> %t to <2 x i32>
|
||||
%b = zext <2 x i32> %a to <2 x i64>
|
||||
ret <2 x i64> %b
|
||||
}
|
||||
define <2 x i65> @foos(<2 x i64> %t) {
|
||||
%a = trunc <2 x i64> %t to <2 x i32>
|
||||
%b = sext <2 x i32> %a to <2 x i65>
|
||||
ret <2 x i65> %b
|
||||
}
|
||||
define <2 x i64> @bars(<2 x i65> %t) {
|
||||
%a = trunc <2 x i65> %t to <2 x i32>
|
||||
%b = sext <2 x i32> %a to <2 x i64>
|
||||
ret <2 x i64> %b
|
||||
}
|
||||
define <2 x i64> @quxs(<2 x i64> %t) {
|
||||
%a = trunc <2 x i64> %t to <2 x i32>
|
||||
%b = sext <2 x i32> %a to <2 x i64>
|
||||
ret <2 x i64> %b
|
||||
}
|
||||
define <2 x i64> @quxt(<2 x i64> %t) {
|
||||
%a = shl <2 x i64> %t, <i64 32, i64 32>
|
||||
%b = ashr <2 x i64> %a, <i64 32, i64 32>
|
||||
ret <2 x i64> %b
|
||||
}
|
||||
define <2 x double> @fa(<2 x double> %t) {
|
||||
%a = fptrunc <2 x double> %t to <2 x float>
|
||||
%b = fpext <2 x float> %a to <2 x double>
|
||||
ret <2 x double> %b
|
||||
}
|
||||
define <2 x double> @fb(<2 x double> %t) {
|
||||
%a = fptoui <2 x double> %t to <2 x i64>
|
||||
%b = uitofp <2 x i64> %a to <2 x double>
|
||||
ret <2 x double> %b
|
||||
}
|
||||
define <2 x double> @fc(<2 x double> %t) {
|
||||
%a = fptosi <2 x double> %t to <2 x i64>
|
||||
%b = sitofp <2 x i64> %a to <2 x double>
|
||||
ret <2 x double> %b
|
||||
}
|
Loading…
Reference in New Issue
Block a user