================
@@ -2710,6 +2710,81 @@ Constant *ConstantExpr::getGetElementPtr(Type *Ty,
Constant *C,
return pImpl->ExprConstants.getOrCreate(ReqTy, Key);
}
+Constant *ConstantExpr::getGetElementPtr(const DataLayout &DL, Type *Ty,
+ Constant *C, ArrayRef<Value *> Idxs,
+ GEPNoWrapFlags NW,
+ std::optional<ConstantRange> InRange,
+ Type *OnlyIfReducedTy) {
+ // Handle already canonical GEP.
+ if (Ty->isIntegerTy(8))
+ return getPtrAdd(C, cast<Constant>(Idxs[0]), NW, InRange, OnlyIfReducedTy);
+
+ assert(isSupportedGetElementPtr(Ty) && "Element type is unsupported!");
+ assert(GetElementPtrInst::getIndexedType(Ty, Idxs) && "GEP indices
invalid!");
+
+ Type *RetTy = GetElementPtrInst::getGEPReturnType(C, Idxs);
+ Type *IdxTy = DL.getIndexType(RetTy);
+
+ Constant *Offset = Constant::getNullValue(IdxTy);
+ auto GTI = gep_type_begin(Ty, Idxs), GTE = gep_type_end(Ty, Idxs);
+ for (; GTI != GTE; ++GTI) {
+ auto *Idx = cast<Constant>(GTI.getOperand());
+ if (Idx->isNullValue())
+ continue;
+
+ if (StructType *STy = GTI.getStructTypeOrNull()) {
+ uint64_t OpValue = Idx->getUniqueInteger().getZExtValue();
+ uint64_t Size = DL.getStructLayout(STy)->getElementOffset(OpValue);
+ if (!Size)
+ continue;
+
+ Offset = ConstantFoldBinaryInstruction(unsigned(Instruction::Add),
Offset,
+ ConstantInt::get(IdxTy, Size));
+ if (!Offset)
+ return nullptr;
+
+ continue;
+ }
+
+ // Splat the index if needed.
+ if (IdxTy->isVectorTy() && !Idx->getType()->isVectorTy())
+ Idx =
ConstantVector::getSplat(cast<VectorType>(IdxTy)->getElementCount(),
+ Idx);
+
+ // Convert to correct type.
+ if (Idx->getType() != IdxTy) {
+ Idx = ConstantFoldCastInstruction(Idx->getType()->getScalarSizeInBits() >
+ IdxTy->getScalarSizeInBits()
----------------
nikic wrote:
Fixed, and added some unit tests.
https://github.com/llvm/llvm-project/pull/224652
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits