&Ops[0], Ops.size(), TD);
}
+/// ConstantFoldConstantExpression - Attempt to fold the constant expression
+/// using the specified TargetData. If successful, the constant result is
+/// result is returned, if not, null is returned.
+Constant *llvm::ConstantFoldConstantExpression(ConstantExpr *CE,
+ const TargetData *TD) {
+ assert(TD && "ConstantFoldConstantExpression requires a valid TargetData.");
+
+ SmallVector<Constant*, 8> Ops;
+ for (User::op_iterator i = CE->op_begin(), e = CE->op_end(); i != e; ++i)
+ Ops.push_back(cast<Constant>(*i));
+
+ if (CE->isCompare())
+ return ConstantFoldCompareInstOperands(CE->getPredicate(),
+ &Ops[0], Ops.size(), TD);
+ else
+ return ConstantFoldInstOperands(CE->getOpcode(), CE->getType(),
+ &Ops[0], Ops.size(), TD);
+}
+
/// ConstantFoldInstOperands - Attempt to constant fold an instruction with the
/// specified opcode and operands. If successful, the constant result is
/// returned, if not, null is returned. Note that this function can fail when
return 0;
case Instruction::ICmp:
case Instruction::FCmp:
+ case Instruction::VICmp:
+ case Instruction::VFCmp:
assert(0 &&"This function is invalid for compares: no predicate specified");
case Instruction::PtrToInt:
// If the input is a inttoptr, eliminate the pair. This requires knowing
if (TD && CE->getOpcode() == Instruction::IntToPtr) {
Constant *Input = CE->getOperand(0);
unsigned InWidth = Input->getType()->getPrimitiveSizeInBits();
- Constant *Mask =
- ConstantInt::get(APInt::getLowBitsSet(InWidth,
- TD->getPointerSizeInBits()));
- Input = ConstantExpr::getAnd(Input, Mask);
+ if (TD->getPointerSizeInBits() < InWidth) {
+ Constant *Mask =
+ ConstantInt::get(APInt::getLowBitsSet(InWidth,
+ TD->getPointerSizeInBits()));
+ Input = ConstantExpr::getAnd(Input, Mask);
+ }
// Do a zext or trunc to get to the dest size.
return ConstantExpr::getIntegerCast(Input, DestTy, false);
}
}
return ConstantExpr::getCast(Opcode, Ops[0], DestTy);
case Instruction::IntToPtr:
+ // If the input is a ptrtoint, turn the pair into a ptr to ptr bitcast if
+ // the int size is >= the ptr size. This requires knowing the width of a
+ // pointer, so it can't be done in ConstantExpr::getCast.
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Ops[0])) {
+ if (TD && CE->getOpcode() == Instruction::PtrToInt &&
+ TD->getPointerSizeInBits() <=
+ CE->getType()->getPrimitiveSizeInBits()) {
+ Constant *Input = CE->getOperand(0);
+ Constant *C = FoldBitCast(Input, DestTy, *TD);
+ return C ? C : ConstantExpr::getBitCast(Input, DestTy);
+ }
+ }
+ return ConstantExpr::getCast(Opcode, Ops[0], DestTy);
case Instruction::Trunc:
case Instruction::ZExt:
case Instruction::SExt:
const TargetData *TD) {
// fold: icmp (inttoptr x), null -> icmp x, 0
// fold: icmp (ptrtoint x), 0 -> icmp x, null
- // fold: icmp (inttoptr x), (inttoptr y) -> icmp x, y
+ // fold: icmp (inttoptr x), (inttoptr y) -> icmp trunc/zext x, trunc/zext y
// fold: icmp (ptrtoint x), (ptrtoint y) -> icmp x, y
//
// ConstantExpr::getCompare cannot do this, because it doesn't have TD
}
}
- if (TD && isa<ConstantExpr>(Ops[1]) &&
- cast<ConstantExpr>(Ops[1])->getOpcode() == CE0->getOpcode()) {
- const Type *IntPtrTy = TD->getIntPtrType();
- // Only do this transformation if the int is intptrty in size, otherwise
- // there is a truncation or extension that we aren't modeling.
- if ((CE0->getOpcode() == Instruction::IntToPtr &&
- CE0->getOperand(0)->getType() == IntPtrTy &&
- Ops[1]->getOperand(0)->getType() == IntPtrTy) ||
- (CE0->getOpcode() == Instruction::PtrToInt &&
- CE0->getType() == IntPtrTy &&
- CE0->getOperand(0)->getType() == Ops[1]->getOperand(0)->getType())) {
- Constant *NewOps[] = {
- CE0->getOperand(0), cast<ConstantExpr>(Ops[1])->getOperand(0)
- };
- return ConstantFoldCompareInstOperands(Predicate, NewOps, 2, TD);
+ if (ConstantExpr *CE1 = dyn_cast<ConstantExpr>(Ops[1])) {
+ if (TD && CE0->getOpcode() == CE1->getOpcode()) {
+ const Type *IntPtrTy = TD->getIntPtrType();
+
+ if (CE0->getOpcode() == Instruction::IntToPtr) {
+ // Convert the integer value to the right size to ensure we get the
+ // proper extension or truncation.
+ Constant *C0 = ConstantExpr::getIntegerCast(CE0->getOperand(0),
+ IntPtrTy, false);
+ Constant *C1 = ConstantExpr::getIntegerCast(CE1->getOperand(0),
+ IntPtrTy, false);
+ Constant *NewOps[] = { C0, C1 };
+ return ConstantFoldCompareInstOperands(Predicate, NewOps, 2, TD);
+ }
+
+ // Only do this transformation if the int is intptrty in size, otherwise
+ // there is a truncation or extension that we aren't modeling.
+ if ((CE0->getOpcode() == Instruction::PtrToInt &&
+ CE0->getType() == IntPtrTy &&
+ CE0->getOperand(0)->getType() == CE1->getOperand(0)->getType())) {
+ Constant *NewOps[] = {
+ CE0->getOperand(0), CE1->getOperand(0)
+ };
+ return ConstantFoldCompareInstOperands(Predicate, NewOps, 2, TD);
+ }
}
}
}
- return ConstantExpr::getCompare(Predicate, Ops[0], Ops[1]);
+ return ConstantExpr::getCompare(Predicate, Ops[0], Ops[1]);
}