+Constant *llvm::ConstantFoldExtractElementInstruction(const Constant *Val,
+ const Constant *Idx) {
+ if (isa<UndefValue>(Val)) // ee(undef, x) -> undef
+ return UndefValue::get(cast<VectorType>(Val->getType())->getElementType());
+ if (Val->isNullValue()) // ee(zero, x) -> zero
+ return Constant::getNullValue(
+ cast<VectorType>(Val->getType())->getElementType());
+
+ if (const ConstantVector *CVal = dyn_cast<ConstantVector>(Val)) {
+ if (const ConstantInt *CIdx = dyn_cast<ConstantInt>(Idx)) {
+ return const_cast<Constant*>(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 0;
+}
+
+Constant *llvm::ConstantFoldInsertElementInstruction(const Constant *Val,
+ const Constant *Elt,
+ const Constant *Idx) {
+ const ConstantInt *CIdx = dyn_cast<ConstantInt>(Idx);
+ if (!CIdx) return 0;
+ APInt idxVal = CIdx->getValue();
+ if (isa<UndefValue>(Val)) {
+ // Insertion of scalar constant into vector 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<VectorType>(Val->getType())->getNumElements();
+ std::vector<Constant*> Ops;
+ Ops.reserve(numOps);
+ for (unsigned i = 0; i < numOps; ++i) {
+ const Constant *Op =
+ (idxVal == i) ? Elt : UndefValue::get(Elt->getType());
+ Ops.push_back(const_cast<Constant*>(Op));
+ }
+ return ConstantVector::get(Ops);
+ }
+ if (isa<ConstantAggregateZero>(Val)) {
+ // Insertion of scalar constant into vector 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<VectorType>(Val->getType())->getNumElements();
+ std::vector<Constant*> Ops;
+ Ops.reserve(numOps);
+ for (unsigned i = 0; i < numOps; ++i) {
+ const Constant *Op =
+ (idxVal == i) ? Elt : Constant::getNullValue(Elt->getType());
+ Ops.push_back(const_cast<Constant*>(Op));
+ }
+ return ConstantVector::get(Ops);
+ }
+ if (const ConstantVector *CVal = dyn_cast<ConstantVector>(Val)) {
+ // Insertion of scalar constant into vector constant
+ std::vector<Constant*> Ops;
+ Ops.reserve(CVal->getNumOperands());
+ for (unsigned i = 0; i < CVal->getNumOperands(); ++i) {
+ const Constant *Op =
+ (idxVal == i) ? Elt : cast<Constant>(CVal->getOperand(i));
+ Ops.push_back(const_cast<Constant*>(Op));
+ }
+ return ConstantVector::get(Ops);
+ }
+ return 0;
+}
+
+/// GetVectorElement - If C is a ConstantVector, ConstantAggregateZero or Undef
+/// 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));
+
+ const Type *EltTy = cast<VectorType>(C->getType())->getElementType();
+ if (isa<ConstantAggregateZero>(C))
+ return Constant::getNullValue(EltTy);
+ if (isa<UndefValue>(C))
+ return UndefValue::get(EltTy);
+ return 0;
+}
+
+Constant *llvm::ConstantFoldShuffleVectorInstruction(const Constant *V1,
+ const Constant *V2,
+ const Constant *Mask) {
+ // Undefined shuffle mask -> undefined value.
+ if (isa<UndefValue>(Mask)) return UndefValue::get(V1->getType());
+
+ unsigned NumElts = cast<VectorType>(V1->getType())->getNumElements();
+ const Type *EltTy = cast<VectorType>(V1->getType())->getElementType();
+
+ // Loop over the shuffle mask, evaluating each element.
+ SmallVector<Constant*, 32> Result;
+ for (unsigned i = 0; i != NumElts; ++i) {
+ Constant *InElt = GetVectorElement(Mask, i);
+ if (InElt == 0) return 0;
+
+ if (isa<UndefValue>(InElt))
+ InElt = UndefValue::get(EltTy);
+ else if (ConstantInt *CI = dyn_cast<ConstantInt>(InElt)) {
+ unsigned Elt = CI->getZExtValue();
+ if (Elt >= NumElts*2)
+ InElt = UndefValue::get(EltTy);
+ else if (Elt >= NumElts)
+ InElt = GetVectorElement(V2, Elt-NumElts);
+ else
+ InElt = GetVectorElement(V1, Elt);
+ if (InElt == 0) return 0;
+ } else {
+ // Unknown value.
+ return 0;
+ }
+ Result.push_back(InElt);
+ }
+
+ return ConstantVector::get(&Result[0], Result.size());
+}
+
+/// 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
+/// ConstantAggregateZero operand.
+static Constant *EvalVectorOp(const ConstantVector *V1,
+ const ConstantVector *V2,
+ const VectorType *VTy,
+ Constant *(*FP)(Constant*, Constant*)) {
+ std::vector<Constant*> Res;
+ const Type *EltTy = VTy->getElementType();
+ for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) {
+ const Constant *C1 = V1 ? V1->getOperand(i) : Constant::getNullValue(EltTy);
+ const Constant *C2 = V2 ? V2->getOperand(i) : Constant::getNullValue(EltTy);
+ Res.push_back(FP(const_cast<Constant*>(C1),
+ const_cast<Constant*>(C2)));
+ }
+ return ConstantVector::get(Res);
+}
+
+Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode,
+ const Constant *C1,
+ const Constant *C2) {
+ // No compile-time operations on this type yet.
+ if (C1->getType() == Type::PPC_FP128Ty)
+ return 0;
+
+ // Handle UndefValue up front
+ if (isa<UndefValue>(C1) || isa<UndefValue>(C2)) {
+ switch (Opcode) {
+ case Instruction::Add:
+ case Instruction::Sub:
+ case Instruction::Xor:
+ return UndefValue::get(C1->getType());
+ case Instruction::Mul:
+ case Instruction::And:
+ return Constant::getNullValue(C1->getType());
+ case Instruction::UDiv:
+ case Instruction::SDiv:
+ case Instruction::FDiv:
+ case Instruction::URem:
+ case Instruction::SRem:
+ case Instruction::FRem:
+ if (!isa<UndefValue>(C2)) // undef / X -> 0
+ return Constant::getNullValue(C1->getType());
+ return const_cast<Constant*>(C2); // X / undef -> undef
+ case Instruction::Or: // X | undef -> -1
+ if (const VectorType *PTy = dyn_cast<VectorType>(C1->getType()))
+ return ConstantVector::getAllOnesValue(PTy);
+ return ConstantInt::getAllOnesValue(C1->getType());
+ case Instruction::LShr:
+ if (isa<UndefValue>(C2) && isa<UndefValue>(C1))
+ return const_cast<Constant*>(C1); // undef lshr undef -> undef
+ return Constant::getNullValue(C1->getType()); // X lshr undef -> 0
+ // undef lshr X -> 0
+ case Instruction::AShr:
+ if (!isa<UndefValue>(C2))
+ return const_cast<Constant*>(C1); // undef ashr X --> undef
+ else if (isa<UndefValue>(C1))
+ return const_cast<Constant*>(C1); // undef ashr undef -> undef
+ else
+ return const_cast<Constant*>(C1); // X ashr undef --> X
+ case Instruction::Shl:
+ // undef << X -> 0 or X << undef -> 0
+ return Constant::getNullValue(C1->getType());
+ }
+ }
+
+ 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;
+ }