if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
if (CE->getOpcode() == Instruction::GetElementPtr &&
CE->getOperand(0)->isNullValue()) {
- Type *Ty =
- cast<PointerType>(CE->getOperand(0)->getType())->getElementType();
+ GEPOperator *GEPO = cast<GEPOperator>(CE);
+ Type *Ty = GEPO->getSourceElementType();
if (CE->getNumOperands() == 2) {
// Handle a sizeof-like expression.
Constant *Idx = CE->getOperand(1);
return UndefValue::get(Val->getType()->getVectorElementType());
if (ConstantInt *CIdx = dyn_cast<ConstantInt>(Idx)) {
- uint64_t Index = CIdx->getZExtValue();
// ee({w,x,y,z}, wrong_value) -> undef
- if (Index >= Val->getType()->getVectorNumElements())
+ if (CIdx->uge(Val->getType()->getVectorNumElements()))
return UndefValue::get(Val->getType()->getVectorElementType());
- return Val->getAggregateElement(Index);
+ return Val->getAggregateElement(CIdx->getZExtValue());
}
return nullptr;
}
Constant *llvm::ConstantFoldInsertElementInstruction(Constant *Val,
Constant *Elt,
Constant *Idx) {
+ if (isa<UndefValue>(Idx))
+ return UndefValue::get(Val->getType());
+
ConstantInt *CIdx = dyn_cast<ConstantInt>(Idx);
if (!CIdx) return nullptr;
- const APInt &IdxVal = CIdx->getValue();
-
+
+ unsigned NumElts = Val->getType()->getVectorNumElements();
+ if (CIdx->uge(NumElts))
+ return UndefValue::get(Val->getType());
+
SmallVector<Constant*, 16> Result;
- Type *Ty = IntegerType::get(Val->getContext(), 32);
- for (unsigned i = 0, e = Val->getType()->getVectorNumElements(); i != e; ++i){
+ Result.reserve(NumElts);
+ auto *Ty = Type::getInt32Ty(Val->getContext());
+ uint64_t IdxVal = CIdx->getZExtValue();
+ for (unsigned i = 0; i != NumElts; ++i) {
if (i == IdxVal) {
Result.push_back(Elt);
continue;
}
- Constant *C =
- ConstantExpr::getExtractElement(Val, ConstantInt::get(Ty, i));
+ Constant *C = ConstantExpr::getExtractElement(Val, ConstantInt::get(Ty, i));
Result.push_back(C);
}
-
+
return ConstantVector::get(Result);
}
if (GV->hasExternalWeakLinkage() || GV->hasWeakAnyLinkage())
return true;
if (const auto *GVar = dyn_cast<GlobalVariable>(GV)) {
- Type *Ty = GVar->getType()->getPointerElementType();
+ Type *Ty = GVar->getValueType();
// A global with opaque type might end up being zero sized.
if (!Ty->isSized())
return true;
}
/// \brief Test whether a given ConstantInt is in-range for a SequentialType.
-static bool isIndexInRangeOfSequentialType(const SequentialType *STy,
+static bool isIndexInRangeOfSequentialType(SequentialType *STy,
const ConstantInt *CI) {
- if (const PointerType *PTy = dyn_cast<PointerType>(STy))
+ if (auto *PTy = dyn_cast<PointerType>(STy))
// Only handle pointers to sized types, not pointers to functions.
return PTy->getElementType()->isSized();
uint64_t NumElements = 0;
// Determine the number of elements in our sequential type.
- if (const ArrayType *ATy = dyn_cast<ArrayType>(STy))
+ if (auto *ATy = dyn_cast<ArrayType>(STy))
NumElements = ATy->getNumElements();
- else if (const VectorType *VTy = dyn_cast<VectorType>(STy))
+ else if (auto *VTy = dyn_cast<VectorType>(STy))
NumElements = VTy->getNumElements();
assert((isa<ArrayType>(STy) || NumElements > 0) &&
}
template<typename IndexTy>
-static Constant *ConstantFoldGetElementPtrImpl(Constant *C,
+static Constant *ConstantFoldGetElementPtrImpl(Type *PointeeTy, Constant *C,
bool inBounds,
ArrayRef<IndexTy> Idxs) {
if (Idxs.empty()) return C;
// Check to see if any array indices are not within the corresponding
// notional array or vector bounds. If so, try to determine if they can be
// factored out into preceding dimensions.
- bool Unknown = false;
SmallVector<Constant *, 8> NewIdxs;
- Type *Ty = C->getType();
- Type *Prev = nullptr;
- for (unsigned i = 0, e = Idxs.size(); i != e;
+ Type *Ty = PointeeTy;
+ Type *Prev = C->getType();
+ bool Unknown = !isa<ConstantInt>(Idxs[0]);
+ for (unsigned i = 1, e = Idxs.size(); i != e;
Prev = Ty, Ty = cast<CompositeType>(Ty)->getTypeAtIndex(Idxs[i]), ++i) {
if (ConstantInt *CI = dyn_cast<ConstantInt>(Idxs[i])) {
if (isa<ArrayType>(Ty) || isa<VectorType>(Ty))
// dimension.
NewIdxs.resize(Idxs.size());
uint64_t NumElements = 0;
- if (const ArrayType *ATy = dyn_cast<ArrayType>(Ty))
+ if (auto *ATy = dyn_cast<ArrayType>(Ty))
NumElements = ATy->getNumElements();
else
NumElements = cast<VectorType>(Ty)->getNumElements();
if (!NewIdxs.empty()) {
for (unsigned i = 0, e = Idxs.size(); i != e; ++i)
if (!NewIdxs[i]) NewIdxs[i] = cast<Constant>(Idxs[i]);
- return ConstantExpr::getGetElementPtr(nullptr, C, NewIdxs, inBounds);
+ return ConstantExpr::getGetElementPtr(PointeeTy, C, NewIdxs, inBounds);
}
// If all indices are known integers and normalized, we can do a simple
if (!Unknown && !inBounds)
if (auto *GV = dyn_cast<GlobalVariable>(C))
if (!GV->hasExternalWeakLinkage() && isInBoundsIndices(Idxs))
- return ConstantExpr::getInBoundsGetElementPtr(nullptr, C, Idxs);
+ return ConstantExpr::getInBoundsGetElementPtr(PointeeTy, C, Idxs);
return nullptr;
}
Constant *llvm::ConstantFoldGetElementPtr(Constant *C,
bool inBounds,
ArrayRef<Constant *> Idxs) {
- return ConstantFoldGetElementPtrImpl(C, inBounds, Idxs);
+ return ConstantFoldGetElementPtrImpl(
+ cast<PointerType>(C->getType()->getScalarType())->getElementType(), C,
+ inBounds, Idxs);
}
Constant *llvm::ConstantFoldGetElementPtr(Constant *C,
bool inBounds,
ArrayRef<Value *> Idxs) {
- return ConstantFoldGetElementPtrImpl(C, inBounds, Idxs);
+ return ConstantFoldGetElementPtrImpl(
+ cast<PointerType>(C->getType()->getScalarType())->getElementType(), C,
+ inBounds, Idxs);
+}
+
+Constant *llvm::ConstantFoldGetElementPtr(Type *Ty, Constant *C,
+ bool inBounds,
+ ArrayRef<Constant *> Idxs) {
+ return ConstantFoldGetElementPtrImpl(Ty, C, inBounds, Idxs);
+}
+
+Constant *llvm::ConstantFoldGetElementPtr(Type *Ty, Constant *C,
+ bool inBounds,
+ ArrayRef<Value *> Idxs) {
+ return ConstantFoldGetElementPtrImpl(Ty, C, inBounds, Idxs);
}