Constant *ConstantExpr::getWithOperands(ArrayRef<Constant *> Ops, Type *Ty,
bool OnlyIfReduced) const {
assert(Ops.size() == getNumOperands() && "Operand count mismatch!");
- bool AnyChange = Ty != getType();
- for (unsigned i = 0; i != Ops.size(); ++i)
- AnyChange |= Ops[i] != getOperand(i);
- if (!AnyChange) // No operands changed, return self.
+ // If no operands changed return self.
+ if (Ty == getType() && std::equal(Ops.begin(), Ops.end(), op_begin()))
return const_cast<ConstantExpr*>(this);
Type *OnlyIfReducedTy = OnlyIfReduced ? Ty : nullptr;
return ConstantExpr::getShuffleVector(Ops[0], Ops[1], Ops[2],
OnlyIfReducedTy);
case Instruction::GetElementPtr:
- return ConstantExpr::getGetElementPtr(Ops[0], Ops.slice(1),
+ return ConstantExpr::getGetElementPtr(nullptr, Ops[0], Ops.slice(1),
cast<GEPOperator>(this)->isInBounds(),
OnlyIfReducedTy);
case Instruction::ICmp:
// Note that a non-inbounds gep is used, as null isn't within any object.
Constant *GEPIdx = ConstantInt::get(Type::getInt32Ty(Ty->getContext()), 1);
Constant *GEP = getGetElementPtr(
- Constant::getNullValue(PointerType::getUnqual(Ty)), GEPIdx);
+ Ty, Constant::getNullValue(PointerType::getUnqual(Ty)), GEPIdx);
return getPtrToInt(GEP,
Type::getInt64Ty(Ty->getContext()));
}
Constant *Zero = ConstantInt::get(Type::getInt64Ty(Ty->getContext()), 0);
Constant *One = ConstantInt::get(Type::getInt32Ty(Ty->getContext()), 1);
Constant *Indices[2] = { Zero, One };
- Constant *GEP = getGetElementPtr(NullPtr, Indices);
+ Constant *GEP = getGetElementPtr(AligningTy, NullPtr, Indices);
return getPtrToInt(GEP,
Type::getInt64Ty(Ty->getContext()));
}
FieldNo
};
Constant *GEP = getGetElementPtr(
- Constant::getNullValue(PointerType::getUnqual(Ty)), GEPIdx);
+ Ty, Constant::getNullValue(PointerType::getUnqual(Ty)), GEPIdx);
return getPtrToInt(GEP,
Type::getInt64Ty(Ty->getContext()));
}
return pImpl->ExprConstants.getOrCreate(V1->getType(), Key);
}
-Constant *ConstantExpr::getGetElementPtr(Constant *C, ArrayRef<Value *> Idxs,
- bool InBounds, Type *OnlyIfReducedTy) {
- assert(C->getType()->isPtrOrPtrVectorTy() &&
- "Non-pointer type for constant GetElementPtr expression");
-
+Constant *ConstantExpr::getGetElementPtr(Type *Ty, Constant *C,
+ ArrayRef<Value *> Idxs, bool InBounds,
+ Type *OnlyIfReducedTy) {
if (Constant *FC = ConstantFoldGetElementPtr(C, InBounds, Idxs))
return FC; // Fold a few common cases.
+ if (!Ty)
+ Ty = cast<PointerType>(C->getType()->getScalarType())->getElementType();
+ else
+ assert(Ty ==
+ cast<PointerType>(C->getType()->getScalarType())->getElementType());
// Get the result type of the getelementptr!
- Type *Ty = GetElementPtrInst::getIndexedType(C->getType(), Idxs);
- assert(Ty && "GEP indices invalid!");
+ Type *DestTy = GetElementPtrInst::getIndexedType(Ty, Idxs);
+ assert(DestTy && "GEP indices invalid!");
unsigned AS = C->getType()->getPointerAddressSpace();
- Type *ReqTy = Ty->getPointerTo(AS);
+ Type *ReqTy = DestTy->getPointerTo(AS);
if (VectorType *VecTy = dyn_cast<VectorType>(C->getType()))
ReqTy = VectorType::get(ReqTy, VecTy->getNumElements());
case Instruction::ShuffleVector:
return new ShuffleVectorInst(Ops[0], Ops[1], Ops[2]);
- case Instruction::GetElementPtr:
- if (cast<GEPOperator>(this)->isInBounds())
- return GetElementPtrInst::CreateInBounds(Ops[0], Ops.slice(1));
- else
- return GetElementPtrInst::Create(Ops[0], Ops.slice(1));
-
+ case Instruction::GetElementPtr: {
+ const auto *GO = cast<GEPOperator>(this);
+ if (GO->isInBounds())
+ return GetElementPtrInst::CreateInBounds(GO->getSourceElementType(),
+ Ops[0], Ops.slice(1));
+ return GetElementPtrInst::Create(GO->getSourceElementType(), Ops[0],
+ Ops.slice(1));
+ }
case Instruction::ICmp:
case Instruction::FCmp:
return CmpInst::Create((Instruction::OtherOps)getOpcode(),