if (DestTy->isFloatingPoint()) {
assert((DestTy == Type::DoubleTy || DestTy == Type::FloatTy) &&
"Unknown FP type!");
- return ConstantFP::get(DestTy, APFloat(CI->getValue()));
+ return ConstantFP::get(APFloat(CI->getValue()));
}
// Otherwise, can't fold this (vector?)
return 0;
DestTy == Type::FP128Ty ? APFloat::IEEEquad :
APFloat::Bogus,
APFloat::rmNearestTiesToEven);
- return ConstantFP::get(DestTy, Val);
+ return ConstantFP::get(Val);
}
return 0; // Can't fold.
case Instruction::FPToUI:
(void)apf.convertFromAPInt(api,
opc==Instruction::SIToFP,
APFloat::rmNearestTiesToEven);
- return ConstantFP::get(DestTy, apf);
+ return ConstantFP::get(apf);
}
if (const ConstantVector *CV = dyn_cast<ConstantVector>(V)) {
std::vector<Constant*> res;
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 (const ConstantExpr *CE1 = dyn_cast<ConstantExpr>(C1)) {
- if (isa<ConstantExpr>(C2)) {
- // There are many possible foldings we could do here. We should probably
- // at least fold add of a pointer with an integer into the appropriate
- // getelementptr. This will improve alias analysis a bit.
- } else {
- // Just implement a couple of simple identities.
- switch (Opcode) {
- case Instruction::Add:
- if (C2->isNullValue()) return const_cast<Constant*>(C1); // X + 0 == X
- break;
- case Instruction::Sub:
- if (C2->isNullValue()) return const_cast<Constant*>(C1); // X - 0 == X
- break;
- case Instruction::Mul:
- if (C2->isNullValue()) return const_cast<Constant*>(C2); // X * 0 == 0
- if (const ConstantInt *CI = dyn_cast<ConstantInt>(C2))
- if (CI->equalsInt(1))
- return const_cast<Constant*>(C1); // X * 1 == X
- break;
- case Instruction::UDiv:
- case Instruction::SDiv:
- if (const ConstantInt *CI = dyn_cast<ConstantInt>(C2))
- if (CI->equalsInt(1))
- return const_cast<Constant*>(C1); // X / 1 == X
- break;
- case Instruction::URem:
- case Instruction::SRem:
- if (const ConstantInt *CI = dyn_cast<ConstantInt>(C2))
- if (CI->equalsInt(1))
- return Constant::getNullValue(CI->getType()); // X % 1 == 0
- break;
- case Instruction::And:
- if (const ConstantInt *CI = dyn_cast<ConstantInt>(C2)) {
- if (CI->isZero()) return const_cast<Constant*>(C2); // X & 0 == 0
- if (CI->isAllOnesValue())
- return const_cast<Constant*>(C1); // X & -1 == X
-
- // (zext i32 to i64) & 4294967295 -> (zext i32 to i64)
- if (CE1->getOpcode() == Instruction::ZExt) {
- APInt PossiblySetBits
- = cast<IntegerType>(CE1->getOperand(0)->getType())->getMask();
- PossiblySetBits.zext(C1->getType()->getPrimitiveSizeInBits());
- if ((PossiblySetBits & CI->getValue()) == PossiblySetBits)
- return const_cast<Constant*>(C1);
- }
- }
- if (CE1->isCast() && isa<GlobalValue>(CE1->getOperand(0))) {
- GlobalValue *CPR = cast<GlobalValue>(CE1->getOperand(0));
-
- // Functions are at least 4-byte aligned. If and'ing the address of a
- // function with a constant < 4, fold it to zero.
- if (const ConstantInt *CI = dyn_cast<ConstantInt>(C2))
- if (CI->getValue().ult(APInt(CI->getType()->getBitWidth(),4)) &&
- isa<Function>(CPR))
- return Constant::getNullValue(CI->getType());
- }
- break;
- case Instruction::Or:
- if (C2->isNullValue()) return const_cast<Constant*>(C1); // X | 0 == X
- if (const ConstantInt *CI = dyn_cast<ConstantInt>(C2))
- if (CI->isAllOnesValue())
- return const_cast<Constant*>(C2); // X | -1 == -1
- break;
- case Instruction::Xor:
- if (C2->isNullValue()) return const_cast<Constant*>(C1); // X ^ 0 == X
- break;
- case Instruction::AShr:
- // ashr (zext C to Ty), C2 -> lshr (zext C, CSA), C2
- if (CE1->getOpcode() == Instruction::ZExt) // Top bits known zero.
- return ConstantExpr::getLShr(const_cast<Constant*>(C1),
- const_cast<Constant*>(C2));
- break;
- }
- }
- } 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.
+ // Handle simplifications of the RHS when a constant int.
+ if (const ConstantInt *CI2 = dyn_cast<ConstantInt>(C2)) {
switch (Opcode) {
case Instruction::Add:
+ if (CI2->equalsInt(0)) return const_cast<Constant*>(C1); // X + 0 == X
+ break;
+ case Instruction::Sub:
+ if (CI2->equalsInt(0)) return const_cast<Constant*>(C1); // X - 0 == X
+ break;
case Instruction::Mul:
+ if (CI2->equalsInt(0)) return const_cast<Constant*>(C2); // X * 0 == 0
+ if (CI2->equalsInt(1))
+ return const_cast<Constant*>(C1); // X * 1 == X
+ break;
+ case Instruction::UDiv:
+ case Instruction::SDiv:
+ if (CI2->equalsInt(1))
+ return const_cast<Constant*>(C1); // X / 1 == X
+ break;
+ case Instruction::URem:
+ case Instruction::SRem:
+ if (CI2->equalsInt(1))
+ return Constant::getNullValue(CI2->getType()); // X % 1 == 0
+ break;
case Instruction::And:
+ if (CI2->isZero()) return const_cast<Constant*>(C2); // X & 0 == 0
+ if (CI2->isAllOnesValue())
+ return const_cast<Constant*>(C1); // X & -1 == X
+
+ if (const ConstantExpr *CE1 = dyn_cast<ConstantExpr>(C1)) {
+ // (zext i32 to i64) & 4294967295 -> (zext i32 to i64)
+ if (CE1->getOpcode() == Instruction::ZExt) {
+ unsigned DstWidth = CI2->getType()->getBitWidth();
+ unsigned SrcWidth =
+ CE1->getOperand(0)->getType()->getPrimitiveSizeInBits();
+ APInt PossiblySetBits(APInt::getLowBitsSet(DstWidth, SrcWidth));
+ if ((PossiblySetBits & CI2->getValue()) == PossiblySetBits)
+ return const_cast<Constant*>(C1);
+ }
+
+ // If and'ing the address of a global with a constant, fold it.
+ if (CE1->getOpcode() == Instruction::PtrToInt &&
+ isa<GlobalValue>(CE1->getOperand(0))) {
+ GlobalValue *GV = cast<GlobalValue>(CE1->getOperand(0));
+
+ // Functions are at least 4-byte aligned.
+ unsigned GVAlign = GV->getAlignment();
+ if (isa<Function>(GV))
+ GVAlign = std::max(GVAlign, 4U);
+
+ if (GVAlign > 1) {
+ unsigned DstWidth = CI2->getType()->getBitWidth();
+ unsigned SrcWidth = std::min(DstWidth, Log2_32(GVAlign));
+ APInt BitsNotSet(APInt::getLowBitsSet(DstWidth, SrcWidth));
+
+ // If checking bits we know are clear, return zero.
+ if ((CI2->getValue() & BitsNotSet) == CI2->getValue())
+ return Constant::getNullValue(CI2->getType());
+ }
+ }
+ }
+ break;
case Instruction::Or:
+ if (CI2->equalsInt(0)) return const_cast<Constant*>(C1); // X | 0 == X
+ if (CI2->isAllOnesValue())
+ return const_cast<Constant*>(C2); // X | -1 == -1
+ break;
case Instruction::Xor:
- // No change of opcode required.
- return ConstantFoldBinaryInstruction(Opcode, C2, C1);
-
- case Instruction::Shl:
- case Instruction::LShr:
+ if (CI2->equalsInt(0)) return const_cast<Constant*>(C1); // X ^ 0 == X
+ break;
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;
+ // ashr (zext C to Ty), C2 -> lshr (zext C, CSA), C2
+ if (const ConstantExpr *CE1 = dyn_cast<ConstantExpr>(C1))
+ if (CE1->getOpcode() == Instruction::ZExt) // Top bits known zero.
+ return ConstantExpr::getLShr(const_cast<Constant*>(C1),
+ const_cast<Constant*>(C2));
+ break;
}
}
-
- // 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)) {
APFloat C1V = CFP1->getValueAPF();
APFloat C2V = CFP2->getValueAPF();
APFloat C3V = C1V; // copy for modification
- bool isDouble = CFP1->getType()==Type::DoubleTy;
switch (Opcode) {
default:
break;
case Instruction::Add:
(void)C3V.add(C2V, APFloat::rmNearestTiesToEven);
- return ConstantFP::get(CFP1->getType(), C3V);
+ return ConstantFP::get(C3V);
case Instruction::Sub:
(void)C3V.subtract(C2V, APFloat::rmNearestTiesToEven);
- return ConstantFP::get(CFP1->getType(), C3V);
+ return ConstantFP::get(C3V);
case Instruction::Mul:
(void)C3V.multiply(C2V, APFloat::rmNearestTiesToEven);
- return ConstantFP::get(CFP1->getType(), C3V);
+ return ConstantFP::get(C3V);
case Instruction::FDiv:
(void)C3V.divide(C2V, APFloat::rmNearestTiesToEven);
- return ConstantFP::get(CFP1->getType(), C3V);
+ return ConstantFP::get(C3V);
case Instruction::FRem:
- if (C2V.isZero())
+ if (C2V.isZero()) {
// IEEE 754, Section 7.1, #5
- return ConstantFP::get(CFP1->getType(), isDouble ?
- APFloat(std::numeric_limits<double>::quiet_NaN()) :
- APFloat(std::numeric_limits<float>::quiet_NaN()));
+ if (CFP1->getType() == Type::DoubleTy)
+ return ConstantFP::get(APFloat(std::numeric_limits<double>::
+ quiet_NaN()));
+ if (CFP1->getType() == Type::FloatTy)
+ return ConstantFP::get(APFloat(std::numeric_limits<float>::
+ quiet_NaN()));
+ break;
+ }
(void)C3V.mod(C2V, APFloat::rmNearestTiesToEven);
- return ConstantFP::get(CFP1->getType(), C3V);
+ return ConstantFP::get(C3V);
}
}
} else if (const VectorType *VTy = dyn_cast<VectorType>(C1->getType())) {
if ((CP1 != NULL || isa<ConstantAggregateZero>(C1)) &&
(CP2 != NULL || isa<ConstantAggregateZero>(C2))) {
switch (Opcode) {
- default:
- break;
- case Instruction::Add:
+ default:
+ break;
+ case Instruction::Add:
return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getAdd);
- case Instruction::Sub:
+ case Instruction::Sub:
return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getSub);
- case Instruction::Mul:
+ case Instruction::Mul:
return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getMul);
- case Instruction::UDiv:
+ case Instruction::UDiv:
return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getUDiv);
- case Instruction::SDiv:
+ case Instruction::SDiv:
return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getSDiv);
- case Instruction::FDiv:
+ case Instruction::FDiv:
return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getFDiv);
- case Instruction::URem:
+ case Instruction::URem:
return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getURem);
- case Instruction::SRem:
+ case Instruction::SRem:
return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getSRem);
- case Instruction::FRem:
+ case Instruction::FRem:
return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getFRem);
- case Instruction::And:
+ case Instruction::And:
return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getAnd);
- case Instruction::Or:
+ case Instruction::Or:
return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getOr);
- case Instruction::Xor:
+ case Instruction::Xor:
return EvalVectorOp(CP1, CP2, VTy, ConstantExpr::getXor);
}
}
}
- // 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;
}
}
break;
+ case Instruction::PtrToInt:
+ case Instruction::IntToPtr:
+ // inttoptr(x1) != inttoptr(x2) iff x1 != x2
+ if (const ConstantExpr *CE2 = dyn_cast<ConstantExpr>(V2))
+ if (CE1->getOpcode() == CE2->getOpcode()) {
+ Constant *Op1 = const_cast<Constant*>(CE1Op0);
+ Constant *Op2 = CE2->getOperand(0);
+ if (Op1->getType() == Op2->getType()) {
+ ConstantInt *R = 0;
+
+ ICmpInst::Predicate pred = ICmpInst::ICMP_EQ;
+ R = dyn_cast<ConstantInt>(ConstantExpr::getICmp(pred, Op1, Op2));
+ if (R && !R->isZero())
+ return pred;
+
+ pred = ICmpInst::ICMP_NE;
+ R = dyn_cast<ConstantInt>(ConstantExpr::getICmp(pred, Op1, Op2));
+ if (R && !R->isZero())
+ return pred;
+ }
+ }
+ break;
+
case Instruction::GetElementPtr:
// Ok, since this is a getelementptr, we know that the constant has a
// pointer type. Check the various cases.
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()));