//
struct BoolRules : public TemplateRules<ConstantBool, BoolRules> {
- static Constant *LessThan(const ConstantBool *V1, const ConstantBool *V2){
+ static Constant *LessThan(const ConstantBool *V1, const ConstantBool *V2) {
return ConstantBool::get(V1->getValue() < V2->getValue());
}
if (isa<UndefValue>(V1)) return const_cast<Constant*>(V2);
if (isa<UndefValue>(V2)) return const_cast<Constant*>(V1);
if (isa<UndefValue>(Cond)) return const_cast<Constant*>(V1);
+ if (V1 == V2) return const_cast<Constant*>(V1);
+ return 0;
+}
+
+Constant *llvm::ConstantFoldExtractElementInstruction(const Constant *Val,
+ const Constant *Idx) {
+ if (const ConstantPacked *CVal = dyn_cast<ConstantPacked>(Val)) {
+ if (const ConstantUInt *CIdx = dyn_cast<ConstantUInt>(Idx)) {
+ return const_cast<Constant*>(CVal->getOperand(CIdx->getValue()));
+ }
+ }
+ return 0;
+}
+
+Constant *llvm::ConstantFoldInsertElementInstruction(const Constant *Val,
+ const Constant *Elt,
+ const Constant *Idx) {
+ const ConstantUInt *CIdx = dyn_cast<ConstantUInt>(Idx);
+ if (!CIdx) return 0;
+ unsigned idxVal = CIdx->getValue();
+ if (const UndefValue *UVal = dyn_cast<UndefValue>(Val)) {
+ // Insertion of scalar constant into packed undef
+ // Optimize away insertion of undef
+ if (isa<UndefValue>(Elt))
+ return const_cast<Constant*>(Val);
+ // Otherwise break the aggregate undef into multiple undefs and do
+ // the insertion
+ unsigned numOps =
+ cast<PackedType>(Val->getType())->getNumElements();
+ std::vector<Constant*> Ops;
+ Ops.reserve(numOps);
+ for (unsigned i = 0; i < numOps; ++i) {
+ const Constant *Op =
+ (i == idxVal) ? Elt : UndefValue::get(Elt->getType());
+ Ops.push_back(const_cast<Constant*>(Op));
+ }
+ return ConstantPacked::get(Ops);
+ }
+ if (const ConstantAggregateZero *CVal =
+ dyn_cast<ConstantAggregateZero>(Val)) {
+ // Insertion of scalar constant into packed aggregate zero
+ // Optimize away insertion of zero
+ if (Elt->isNullValue())
+ return const_cast<Constant*>(Val);
+ // Otherwise break the aggregate zero into multiple zeros and do
+ // the insertion
+ unsigned numOps =
+ cast<PackedType>(Val->getType())->getNumElements();
+ std::vector<Constant*> Ops;
+ Ops.reserve(numOps);
+ for (unsigned i = 0; i < numOps; ++i) {
+ const Constant *Op =
+ (i == idxVal) ? Elt : Constant::getNullValue(Elt->getType());
+ Ops.push_back(const_cast<Constant*>(Op));
+ }
+ return ConstantPacked::get(Ops);
+ }
+ if (const ConstantPacked *CVal = dyn_cast<ConstantPacked>(Val)) {
+ // Insertion of scalar constant into packed constant
+ std::vector<Constant*> Ops;
+ Ops.reserve(CVal->getNumOperands());
+ for (unsigned i = 0; i < CVal->getNumOperands(); ++i) {
+ const Constant *Op =
+ (i == idxVal) ? Elt : cast<Constant>(CVal->getOperand(i));
+ Ops.push_back(const_cast<Constant*>(Op));
+ }
+ return ConstantPacked::get(Ops);
+ }
return 0;
}
/// constants (like ConstantInt) to be the simplest, followed by
/// GlobalValues, followed by ConstantExpr's (the most complex).
///
-static Instruction::BinaryOps evaluateRelation(const Constant *V1,
- const Constant *V2) {
+static Instruction::BinaryOps evaluateRelation(Constant *V1, Constant *V2) {
assert(V1->getType() == V2->getType() &&
"Cannot compare different types of values!");
if (V1 == V2) return Instruction::SetEQ;
if (!isa<ConstantExpr>(V1) && !isa<GlobalValue>(V1)) {
+ if (!isa<GlobalValue>(V2) && !isa<ConstantExpr>(V2)) {
+ // We distilled this down to a simple case, use the standard constant
+ // folder.
+ ConstantBool *R = dyn_cast<ConstantBool>(ConstantExpr::getSetEQ(V1, V2));
+ if (R == ConstantBool::True) return Instruction::SetEQ;
+ R = dyn_cast<ConstantBool>(ConstantExpr::getSetLT(V1, V2));
+ if (R == ConstantBool::True) return Instruction::SetLT;
+ R = dyn_cast<ConstantBool>(ConstantExpr::getSetGT(V1, V2));
+ if (R == ConstantBool::True) return Instruction::SetGT;
+
+ // If we couldn't figure it out, bail.
+ return Instruction::BinaryOpsEnd;
+ }
+
// If the first operand is simple, swap operands.
- assert((isa<GlobalValue>(V2) || isa<ConstantExpr>(V2)) &&
- "Simple cases should have been handled by caller!");
Instruction::BinaryOps SwappedRelation = evaluateRelation(V2, V1);
if (SwappedRelation != Instruction::BinaryOpsEnd)
return SetCondInst::getSwappedCondition(SwappedRelation);
- } else if (const GlobalValue *CPR1 = dyn_cast<GlobalValue>(V1)){
+ } else if (const GlobalValue *CPR1 = dyn_cast<GlobalValue>(V1)) {
if (isa<ConstantExpr>(V2)) { // Swap as necessary.
- Instruction::BinaryOps SwappedRelation = evaluateRelation(V2, V1);
- if (SwappedRelation != Instruction::BinaryOpsEnd)
- return SetCondInst::getSwappedCondition(SwappedRelation);
- else
- return Instruction::BinaryOpsEnd;
+ Instruction::BinaryOps SwappedRelation = evaluateRelation(V2, V1);
+ if (SwappedRelation != Instruction::BinaryOpsEnd)
+ return SetCondInst::getSwappedCondition(SwappedRelation);
+ else
+ return Instruction::BinaryOpsEnd;
}
// Now we know that the RHS is a GlobalValue or simple constant,
} else {
// Ok, the LHS is known to be a constantexpr. The RHS can be any of a
// constantexpr, a CPR, or a simple constant.
- const ConstantExpr *CE1 = cast<ConstantExpr>(V1);
+ ConstantExpr *CE1 = cast<ConstantExpr>(V1);
Constant *CE1Op0 = CE1->getOperand(0);
switch (CE1->getOpcode()) {
// If the cast is not actually changing bits, and the second operand is a
// null pointer, do the comparison with the pre-casted value.
if (V2->isNullValue() &&
- CE1->getType()->isLosslesslyConvertibleTo(CE1Op0->getType()))
+ (isa<PointerType>(CE1->getType()) || CE1->getType()->isIntegral()))
return evaluateRelation(CE1Op0,
Constant::getNullValue(CE1Op0->getType()));
+
+ // If the dest type is a pointer type, and the RHS is a constantexpr cast
+ // from the same type as the src of the LHS, evaluate the inputs. This is
+ // important for things like "seteq (cast 4 to int*), (cast 5 to int*)",
+ // which happens a lot in compilers with tagged integers.
+ if (ConstantExpr *CE2 = dyn_cast<ConstantExpr>(V2))
+ if (isa<PointerType>(CE1->getType()) &&
+ CE2->getOpcode() == Instruction::Cast &&
+ CE1->getOperand(0)->getType() == CE2->getOperand(0)->getType() &&
+ CE1->getOperand(0)->getType()->isIntegral()) {
+ return evaluateRelation(CE1->getOperand(0), CE2->getOperand(0));
+ }
break;
case Instruction::GetElementPtr:
if (SetCondInst::isRelational(Opcode)) {
if (isa<UndefValue>(V1) || isa<UndefValue>(V2))
return UndefValue::get(Type::BoolTy);
- switch (evaluateRelation(V1, V2)) {
+ switch (evaluateRelation(const_cast<Constant*>(V1),
+ const_cast<Constant*>(V2))) {
default: assert(0 && "Unknown relational!");
case Instruction::BinaryOpsEnd:
break; // Couldn't determine anything about these constants.