if (const ConstantVector *CVal = dyn_cast<ConstantVector>(Val)) {
if (const ConstantInt *CIdx = dyn_cast<ConstantInt>(Idx)) {
- return const_cast<Constant*>(CVal->getOperand(CIdx->getZExtValue()));
+ return CVal->getOperand(CIdx->getZExtValue());
} else if (isa<UndefValue>(Idx)) {
// ee({w,x,y,z}, undef) -> w (an arbitrary value).
- return const_cast<Constant*>(CVal->getOperand(0));
+ return CVal->getOperand(0);
}
}
return 0;
/// return the specified element value. Otherwise return null.
static Constant *GetVectorElement(const Constant *C, unsigned EltNo) {
if (const ConstantVector *CV = dyn_cast<ConstantVector>(C))
- return const_cast<Constant*>(CV->getOperand(EltNo));
+ return CV->getOperand(EltNo);
const Type *EltTy = cast<VectorType>(C->getType())->getElementType();
if (isa<ConstantAggregateZero>(C))
return ConstantVector::get(&Result[0], Result.size());
}
+Constant *llvm::ConstantFoldExtractValue(const Constant *Agg,
+ Constant* const *Idxs,
+ unsigned NumIdx) {
+ // FIXME: implement some constant folds
+ return 0;
+}
+
+Constant *llvm::ConstantFoldInsertValue(const Constant *Agg,
+ const Constant *Val,
+ Constant* const *Idxs,
+ unsigned NumIdx) {
+ // FIXME: implement some constant folds
+ return 0;
+}
+
/// EvalVectorOp - Given two vector constants and a function pointer, apply the
/// function pointer to each element pair, producing a new ConstantVector
/// constant. Either or both of V1 and V2 may be NULL, meaning a
if (GVAlign > 1) {
unsigned DstWidth = CI2->getType()->getBitWidth();
- unsigned SrcWidth = std::min(SrcWidth, Log2_32(GVAlign));
+ unsigned SrcWidth = std::min(DstWidth, Log2_32(GVAlign));
APInt BitsNotSet(APInt::getLowBitsSet(DstWidth, SrcWidth));
// If checking bits we know are clear, return zero.
}
}
- if (isa<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.
- } 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.
- switch (Opcode) {
- case Instruction::Add:
- case Instruction::Mul:
- case Instruction::And:
- case Instruction::Or:
- case Instruction::Xor:
- // No change of opcode required.
- return ConstantFoldBinaryInstruction(Opcode, C2, C1);
-
- case Instruction::Shl:
- case Instruction::LShr:
- case Instruction::AShr:
- case Instruction::Sub:
- case Instruction::SDiv:
- case Instruction::UDiv:
- case Instruction::FDiv:
- case Instruction::URem:
- case Instruction::SRem:
- case Instruction::FRem:
- default: // These instructions cannot be flopped around.
- return 0;
- }
- }
-
- // At this point we know neither constant is an UndefValue nor a ConstantExpr
- // so look at directly computing the value.
+ // At this point we know neither constant is an UndefValue.
if (const ConstantInt *CI1 = dyn_cast<ConstantInt>(C1)) {
if (const ConstantInt *CI2 = dyn_cast<ConstantInt>(C2)) {
using namespace APIntOps;
- APInt C1V = CI1->getValue();
- APInt C2V = CI2->getValue();
+ const APInt &C1V = CI1->getValue();
+ const APInt &C2V = CI2->getValue();
switch (Opcode) {
default:
break;
return ConstantInt::get(C1V | C2V);
case Instruction::Xor:
return ConstantInt::get(C1V ^ C2V);
- case Instruction::Shl:
- if (uint32_t shiftAmt = C2V.getZExtValue()) {
- if (shiftAmt < C1V.getBitWidth())
- return ConstantInt::get(C1V.shl(shiftAmt));
- else
- return UndefValue::get(C1->getType()); // too big shift is undef
- }
- return const_cast<ConstantInt*>(CI1); // Zero shift is identity
- case Instruction::LShr:
- if (uint32_t shiftAmt = C2V.getZExtValue()) {
- if (shiftAmt < C1V.getBitWidth())
- return ConstantInt::get(C1V.lshr(shiftAmt));
- else
- return UndefValue::get(C1->getType()); // too big shift is undef
- }
- return const_cast<ConstantInt*>(CI1); // Zero shift is identity
- case Instruction::AShr:
- if (uint32_t shiftAmt = C2V.getZExtValue()) {
- if (shiftAmt < C1V.getBitWidth())
- return ConstantInt::get(C1V.ashr(shiftAmt));
- else
- return UndefValue::get(C1->getType()); // too big shift is undef
- }
- return const_cast<ConstantInt*>(CI1); // Zero shift is identity
+ case Instruction::Shl: {
+ uint32_t shiftAmt = C2V.getZExtValue();
+ if (shiftAmt < C1V.getBitWidth())
+ return ConstantInt::get(C1V.shl(shiftAmt));
+ else
+ return UndefValue::get(C1->getType()); // too big shift is undef
+ }
+ case Instruction::LShr: {
+ uint32_t shiftAmt = C2V.getZExtValue();
+ if (shiftAmt < C1V.getBitWidth())
+ return ConstantInt::get(C1V.lshr(shiftAmt));
+ else
+ return UndefValue::get(C1->getType()); // too big shift is undef
+ }
+ case Instruction::AShr: {
+ uint32_t shiftAmt = C2V.getZExtValue();
+ if (shiftAmt < C1V.getBitWidth())
+ return ConstantInt::get(C1V.ashr(shiftAmt));
+ else
+ return UndefValue::get(C1->getType()); // too big shift is undef
+ }
}
}
} else if (const ConstantFP *CFP1 = dyn_cast<ConstantFP>(C1)) {
}
}
- // We don't know how to fold this
+ if (isa<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.
+ } 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.
+ switch (Opcode) {
+ case Instruction::Add:
+ case Instruction::Mul:
+ case Instruction::And:
+ case Instruction::Or:
+ case Instruction::Xor:
+ // No change of opcode required.
+ return ConstantFoldBinaryInstruction(Opcode, C2, C1);
+
+ case Instruction::Shl:
+ case Instruction::LShr:
+ case Instruction::AShr:
+ case Instruction::Sub:
+ case Instruction::SDiv:
+ case Instruction::UDiv:
+ case Instruction::FDiv:
+ case Instruction::URem:
+ case Instruction::SRem:
+ case Instruction::FRem:
+ default: // These instructions cannot be flopped around.
+ break;
+ }
+ }
+
+ // We don't know how to fold this.
return 0;
}
if (const ConstantVector *CP2 = dyn_cast<ConstantVector>(C2)) {
if (pred == FCmpInst::FCMP_OEQ || pred == FCmpInst::FCMP_UEQ) {
for (unsigned i = 0, e = CP1->getNumOperands(); i != e; ++i) {
- Constant *C= ConstantExpr::getFCmp(FCmpInst::FCMP_OEQ,
- const_cast<Constant*>(CP1->getOperand(i)),
- const_cast<Constant*>(CP2->getOperand(i)));
+ Constant *C = ConstantExpr::getFCmp(FCmpInst::FCMP_OEQ,
+ CP1->getOperand(i),
+ CP2->getOperand(i));
if (ConstantInt *CB = dyn_cast<ConstantInt>(C))
return CB;
}
} else if (pred == ICmpInst::ICMP_EQ) {
for (unsigned i = 0, e = CP1->getNumOperands(); i != e; ++i) {
Constant *C = ConstantExpr::getICmp(ICmpInst::ICMP_EQ,
- const_cast<Constant*>(CP1->getOperand(i)),
- const_cast<Constant*>(CP2->getOperand(i)));
+ CP1->getOperand(i),
+ CP2->getOperand(i));
if (ConstantInt *CB = dyn_cast<ConstantInt>(C))
return CB;
}
const PointerType *Ptr = cast<PointerType>(C->getType());
const Type *Ty = GetElementPtrInst::getIndexedType(Ptr,
(Value **)Idxs,
- (Value **)Idxs+NumIdx,
- true);
+ (Value **)Idxs+NumIdx);
assert(Ty != 0 && "Invalid indices for GEP!");
return UndefValue::get(PointerType::get(Ty, Ptr->getAddressSpace()));
}
const PointerType *Ptr = cast<PointerType>(C->getType());
const Type *Ty = GetElementPtrInst::getIndexedType(Ptr,
(Value**)Idxs,
- (Value**)Idxs+NumIdx,
- true);
+ (Value**)Idxs+NumIdx);
assert(Ty != 0 && "Invalid indices for GEP!");
return
ConstantPointerNull::get(PointerType::get(Ty,Ptr->getAddressSpace()));