switch (CE->getOpcode()) {
default: return 0;
case Instruction::Or: {
- Constant *RHS = ExtractConstantBytes(C->getOperand(1), ByteStart, ByteSize);
+ Constant *RHS = ExtractConstantBytes(CE->getOperand(1), ByteStart,ByteSize);
if (RHS == 0)
return 0;
if (RHSC->isAllOnesValue())
return RHSC;
- Constant *LHS = ExtractConstantBytes(C->getOperand(0), ByteStart, ByteSize);
+ Constant *LHS = ExtractConstantBytes(CE->getOperand(0), ByteStart,ByteSize);
if (LHS == 0)
return 0;
return ConstantExpr::getOr(LHS, RHS);
}
case Instruction::And: {
- Constant *RHS = ExtractConstantBytes(C->getOperand(1), ByteStart, ByteSize);
+ Constant *RHS = ExtractConstantBytes(CE->getOperand(1), ByteStart,ByteSize);
if (RHS == 0)
return 0;
if (RHS->isNullValue())
return RHS;
- Constant *LHS = ExtractConstantBytes(C->getOperand(0), ByteStart, ByteSize);
+ Constant *LHS = ExtractConstantBytes(CE->getOperand(0), ByteStart,ByteSize);
if (LHS == 0)
return 0;
return ConstantExpr::getAnd(LHS, RHS);
ByteSize*8));
// If the extract is known to be fully in the input, extract it.
if (ByteStart+ByteSize+ShAmt <= CSize)
- return ExtractConstantBytes(C->getOperand(0), ByteStart+ShAmt, ByteSize);
+ return ExtractConstantBytes(CE->getOperand(0), ByteStart+ShAmt, ByteSize);
// TODO: Handle the 'partially zero' case.
return 0;
ByteSize*8));
// If the extract is known to be fully in the input, extract it.
if (ByteStart >= ShAmt)
- return ExtractConstantBytes(C->getOperand(0), ByteStart-ShAmt, ByteSize);
+ return ExtractConstantBytes(CE->getOperand(0), ByteStart-ShAmt, ByteSize);
// TODO: Handle the 'partially zero' case.
return 0;
case Instruction::ZExt: {
unsigned SrcBitSize =
- cast<IntegerType>(C->getOperand(0)->getType())->getBitWidth();
+ cast<IntegerType>(CE->getOperand(0)->getType())->getBitWidth();
// If extracting something that is completely zero, return 0.
if (ByteStart*8 >= SrcBitSize)
// If exactly extracting the input, return it.
if (ByteStart == 0 && ByteSize*8 == SrcBitSize)
- return C->getOperand(0);
+ return CE->getOperand(0);
// If extracting something completely in the input, if if the input is a
// multiple of 8 bits, recurse.
if ((SrcBitSize&7) == 0 && (ByteStart+ByteSize)*8 <= SrcBitSize)
- return ExtractConstantBytes(C->getOperand(0), ByteStart, ByteSize);
+ return ExtractConstantBytes(CE->getOperand(0), ByteStart, ByteSize);
// Otherwise, if extracting a subset of the input, which is not multiple of
// 8 bits, do a shift and trunc to get the bits.
if ((ByteStart+ByteSize)*8 < SrcBitSize) {
assert((SrcBitSize&7) && "Shouldn't get byte sized case here");
- Constant *Res = C->getOperand(0);
+ Constant *Res = CE->getOperand(0);
if (ByteStart)
Res = ConstantExpr::getLShr(Res,
ConstantInt::get(Res->getType(), ByteStart*8));
}
}
+/// getFoldedSizeOf - Return a ConstantExpr with type DestTy for sizeof
+/// on Ty, with any known factors factored out. If Folded is false,
+/// return null if no factoring was possible, to avoid endlessly
+/// bouncing an unfoldable expression back into the top-level folder.
+///
+static Constant *getFoldedSizeOf(const Type *Ty, const Type *DestTy,
+ bool Folded) {
+ if (const ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
+ Constant *N = ConstantInt::get(DestTy, ATy->getNumElements());
+ Constant *E = getFoldedSizeOf(ATy->getElementType(), DestTy, true);
+ return ConstantExpr::getNUWMul(E, N);
+ }
+ if (const VectorType *VTy = dyn_cast<VectorType>(Ty)) {
+ Constant *N = ConstantInt::get(DestTy, VTy->getNumElements());
+ Constant *E = getFoldedSizeOf(VTy->getElementType(), DestTy, true);
+ return ConstantExpr::getNUWMul(E, N);
+ }
+ if (const StructType *STy = dyn_cast<StructType>(Ty))
+ if (!STy->isPacked()) {
+ unsigned NumElems = STy->getNumElements();
+ // An empty struct has size zero.
+ if (NumElems == 0)
+ return ConstantExpr::getNullValue(DestTy);
+ // Check for a struct with all members having the same type.
+ const Type *MemberTy = STy->getElementType(0);
+ bool AllSame = true;
+ for (unsigned i = 1; i != NumElems; ++i)
+ if (MemberTy != STy->getElementType(i)) {
+ AllSame = false;
+ break;
+ }
+ if (AllSame) {
+ Constant *N = ConstantInt::get(DestTy, NumElems);
+ Constant *E = getFoldedSizeOf(MemberTy, DestTy, true);
+ return ConstantExpr::getNUWMul(E, N);
+ }
+ }
+
+ // If there's no interesting folding happening, bail so that we don't create
+ // a constant that looks like it needs folding but really doesn't.
+ if (!Folded)
+ return 0;
+
+ // Base case: Get a regular sizeof expression.
+ Constant *C = ConstantExpr::getSizeOf(Ty);
+ C = ConstantExpr::getCast(CastInst::getCastOpcode(C, false,
+ DestTy, false),
+ C, DestTy);
+ return C;
+}
+
+/// getFoldedOffsetOf - Return a ConstantExpr with type DestTy for offsetof
+/// on Ty and FieldNo, with any known factors factored out. If Folded is false,
+/// return null if no factoring was possible, to avoid endlessly
+/// bouncing an unfoldable expression back into the top-level folder.
+///
+static Constant *getFoldedOffsetOf(const Type *Ty, Constant *FieldNo,
+ const Type *DestTy,
+ bool Folded) {
+ if (const ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
+ Constant *N = ConstantExpr::getCast(CastInst::getCastOpcode(FieldNo, false,
+ DestTy, false),
+ FieldNo, DestTy);
+ Constant *E = getFoldedSizeOf(ATy->getElementType(), DestTy, true);
+ return ConstantExpr::getNUWMul(E, N);
+ }
+ if (const VectorType *VTy = dyn_cast<VectorType>(Ty)) {
+ Constant *N = ConstantExpr::getCast(CastInst::getCastOpcode(FieldNo, false,
+ DestTy, false),
+ FieldNo, DestTy);
+ Constant *E = getFoldedSizeOf(VTy->getElementType(), DestTy, true);
+ return ConstantExpr::getNUWMul(E, N);
+ }
+ if (const StructType *STy = dyn_cast<StructType>(Ty))
+ if (!STy->isPacked()) {
+ unsigned NumElems = STy->getNumElements();
+ // An empty struct has no members.
+ if (NumElems == 0)
+ return 0;
+ // Check for a struct with all members having the same type.
+ const Type *MemberTy = STy->getElementType(0);
+ bool AllSame = true;
+ for (unsigned i = 1; i != NumElems; ++i)
+ if (MemberTy != STy->getElementType(i)) {
+ AllSame = false;
+ break;
+ }
+ if (AllSame) {
+ Constant *N = ConstantExpr::getCast(CastInst::getCastOpcode(FieldNo,
+ false,
+ DestTy,
+ false),
+ FieldNo, DestTy);
+ Constant *E = getFoldedSizeOf(MemberTy, DestTy, true);
+ return ConstantExpr::getNUWMul(E, N);
+ }
+ }
+
+ // If there's no interesting folding happening, bail so that we don't create
+ // a constant that looks like it needs folding but really doesn't.
+ if (!Folded)
+ return 0;
+
+ // Base case: Get a regular offsetof expression.
+ Constant *C = ConstantExpr::getOffsetOf(Ty, FieldNo);
+ C = ConstantExpr::getCast(CastInst::getCastOpcode(C, false,
+ DestTy, false),
+ C, DestTy);
+ return C;
+}
Constant *llvm::ConstantFoldCastInstruction(LLVMContext &Context,
unsigned opc, Constant *V,
return ConstantPointerNull::get(cast<PointerType>(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?
+ // Is it a null pointer value?
+ if (V->isNullValue())
return ConstantInt::get(DestTy, 0);
- return 0; // Other pointer types cannot be casted
+ // If this is a sizeof-like expression, pull out multiplications by
+ // known factors to expose them to subsequent folding. If it's an
+ // alignof-like expression, factor out known factors.
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
+ if (CE->getOpcode() == Instruction::GetElementPtr &&
+ CE->getOperand(0)->isNullValue()) {
+ const Type *Ty =
+ cast<PointerType>(CE->getOperand(0)->getType())->getElementType();
+ if (CE->getNumOperands() == 2) {
+ // Handle a sizeof-like expression.
+ Constant *Idx = CE->getOperand(1);
+ bool isOne = isa<ConstantInt>(Idx) && cast<ConstantInt>(Idx)->isOne();
+ if (Constant *C = getFoldedSizeOf(Ty, DestTy, !isOne)) {
+ Idx = ConstantExpr::getCast(CastInst::getCastOpcode(Idx, true,
+ DestTy, false),
+ Idx, DestTy);
+ return ConstantExpr::getMul(C, Idx);
+ }
+ } else if (CE->getNumOperands() == 3 &&
+ CE->getOperand(1)->isNullValue()) {
+ // Handle an alignof-like expression.
+ if (const StructType *STy = dyn_cast<StructType>(Ty))
+ if (!STy->isPacked()) {
+ ConstantInt *CI = cast<ConstantInt>(CE->getOperand(2));
+ if (CI->isOne() &&
+ STy->getNumElements() == 2 &&
+ STy->getElementType(0)->isInteger(1)) {
+ // The alignment of an array is equal to the alignment of the
+ // array element. Note that this is not always true for vectors.
+ if (const ArrayType *ATy =
+ dyn_cast<ArrayType>(STy->getElementType(1))) {
+ Constant *C = ConstantExpr::getAlignOf(ATy->getElementType());
+ C = ConstantExpr::getCast(CastInst::getCastOpcode(C, false,
+ DestTy,
+ false),
+ C, DestTy);
+ return C;
+ }
+ // Packed structs always have an alignment of 1.
+ if (const StructType *InnerSTy =
+ dyn_cast<StructType>(STy->getElementType(1)))
+ if (InnerSTy->isPacked())
+ return ConstantInt::get(DestTy, 1);
+ }
+ }
+ // Handle an offsetof-like expression.
+ if (isa<StructType>(Ty) || isa<ArrayType>(Ty) || isa<VectorType>(Ty)){
+ if (Constant *C = getFoldedOffsetOf(Ty, CE->getOperand(2),
+ DestTy, false))
+ return C;
+ }
+ }
+ }
+ // Other pointer types cannot be casted
+ return 0;
case Instruction::UIToFP:
case Instruction::SIToFP:
if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
Idxs + NumIdx));
// Otherwise recurse.
- return ConstantFoldExtractValueInstruction(Context, Agg->getOperand(*Idxs),
+ if (ConstantStruct *CS = dyn_cast<ConstantStruct>(Agg))
+ return ConstantFoldExtractValueInstruction(Context, CS->getOperand(*Idxs),
+ Idxs+1, NumIdx-1);
+
+ if (ConstantArray *CA = dyn_cast<ConstantArray>(Agg))
+ return ConstantFoldExtractValueInstruction(Context, CA->getOperand(*Idxs),
+ Idxs+1, NumIdx-1);
+ ConstantVector *CV = cast<ConstantVector>(Agg);
+ return ConstantFoldExtractValueInstruction(Context, CV->getOperand(*Idxs),
Idxs+1, NumIdx-1);
}
// Insertion of constant into aggregate constant.
std::vector<Constant*> Ops(Agg->getNumOperands());
for (unsigned i = 0; i < Agg->getNumOperands(); ++i) {
- Constant *Op =
- (*Idxs == i) ?
- ConstantFoldInsertValueInstruction(Context, Agg->getOperand(i),
- Val, Idxs+1, NumIdx-1) :
- Agg->getOperand(i);
+ Constant *Op = cast<Constant>(Agg->getOperand(i));
+ if (*Idxs == i)
+ Op = ConstantFoldInsertValueInstruction(Context, Op,
+ Val, Idxs+1, NumIdx-1);
Ops[i] = Op;
}
}
}
- if (isa<ConstantExpr>(C1)) {
+ if (ConstantExpr *CE1 = dyn_cast<ConstantExpr>(C1)) {
// 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.
+
+ // Given ((a + b) + c), if (b + c) folds to something interesting, return
+ // (a + (b + c)).
+ if (Instruction::isAssociative(Opcode, C1->getType()) &&
+ CE1->getOpcode() == Opcode) {
+ Constant *T = ConstantExpr::get(Opcode, CE1->getOperand(1), C2);
+ if (!isa<ConstantExpr>(T) || cast<ConstantExpr>(T)->getOpcode() != Opcode)
+ return ConstantExpr::get(Opcode, CE1->getOperand(0), T);
+ }
} else if (isa<ConstantExpr>(C2)) {
// If C2 is a constant expr and C1 isn't, flop them around and fold the
// other way if possible.
}
// i1 can be simplified in many cases.
- if (C1->getType() == Type::getInt1Ty(Context)) {
+ if (C1->getType()->isInteger(1)) {
switch (Opcode) {
case Instruction::Add:
case Instruction::Sub:
// Ok, we have two differing integer indices. Sign extend them to be the same
// type. Long is always big enough, so we use it.
- if (C1->getType() != Type::getInt64Ty(Context))
+ if (!C1->getType()->isInteger(64))
C1 = ConstantExpr::getSExt(C1, Type::getInt64Ty(Context));
- if (C2->getType() != Type::getInt64Ty(Context))
+ if (!C2->getType()->isInteger(64))
C2 = ConstantExpr::getSExt(C2, Type::getInt64Ty(Context));
if (C1 == C2) return 0; // They are equal
}
// If the comparison is a comparison between two i1's, simplify it.
- if (C1->getType() == Type::getInt1Ty(Context)) {
+ if (C1->getType()->isInteger(1)) {
switch(pred) {
case ICmpInst::ICMP_EQ:
if (isa<ConstantInt>(C2))
SmallVector<Constant*, 16> C1Elts, C2Elts;
C1->getVectorElements(Context, C1Elts);
C2->getVectorElements(Context, C2Elts);
+ if (C1Elts.empty() || C2Elts.empty())
+ return 0;
// If we can constant fold the comparison of each element, constant fold
// the whole vector comparison.
SmallVector<Constant*, 4> ResElts;
for (unsigned i = 0, e = C1Elts.size(); i != e; ++i) {
// Compare the elements, producing an i1 result or constant expr.
- ResElts.push_back(
- ConstantExpr::getCompare(pred, C1Elts[i], C2Elts[i]));
+ ResElts.push_back(ConstantExpr::getCompare(pred, C1Elts[i], C2Elts[i]));
}
return ConstantVector::get(&ResElts[0], ResElts.size());
}
}
}
- if (!isa<ConstantExpr>(C1) && isa<ConstantExpr>(C2)) {
+ if ((!isa<ConstantExpr>(C1) && isa<ConstantExpr>(C2)) ||
+ (C1->isNullValue() && !C2->isNullValue())) {
// If C2 is a constant expr and C1 isn't, flip them around and fold the
// other way if possible.
+ // Also, if C1 is null and C2 isn't, flip them around.
switch (pred) {
case ICmpInst::ICMP_EQ:
case ICmpInst::ICMP_NE:
// No change of predicate required.
- return ConstantFoldCompareInstruction(Context, pred, C2, C1);
+ return ConstantExpr::getICmp(pred, C2, C1);
case ICmpInst::ICMP_ULT:
case ICmpInst::ICMP_SLT:
case ICmpInst::ICMP_SGE:
// Change the predicate as necessary to swap the operands.
pred = ICmpInst::getSwappedPredicate((ICmpInst::Predicate)pred);
- return ConstantFoldCompareInstruction(Context, pred, C2, C1);
+ return ConstantExpr::getICmp(pred, C2, C1);
default: // These predicates cannot be flopped around.
break;
}
// Implement folding of:
- // int* getelementptr ([2 x int]* cast ([3 x int]* %X to [2 x int]*),
+ // int* getelementptr ([2 x int]* bitcast ([3 x int]* %X to [2 x int]*),
// long 0, long 0)
// To: int* getelementptr ([3 x int]* %X, long 0, long 0)
//
ConstantExpr::getGetElementPtr(
(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<ConstantInt>(CE->getOperand(0)) && isa<ConstantInt>(Idxs[0]) &&
- cast<PointerType>(CE->getType())->getElementType() ==
- Type::getInt8Ty(Context)) {
- 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, Offset->getType());
-
- Base = ConstantExpr::getAdd(Base, Offset);
- return ConstantExpr::getIntToPtr(Base, CE->getType());
- }
}
// Check to see if any array indices are not within the corresponding
// Before adding, extend both operands to i64 to avoid
// overflow trouble.
- if (PrevIdx->getType() != Type::getInt64Ty(Context))
+ if (!PrevIdx->getType()->isInteger(64))
PrevIdx = ConstantExpr::getSExt(PrevIdx,
Type::getInt64Ty(Context));
- if (Div->getType() != Type::getInt64Ty(Context))
+ if (!Div->getType()->isInteger(64))
Div = ConstantExpr::getSExt(Div,
Type::getInt64Ty(Context));