[clang] [llvm] [IR] Add ConstantExpr::getGetElementPtr() accepting DataLayout (PR #224652)

Antonio Frighetto via cfe-commits cfe-commits at lists.llvm.org
Fri Sep 18 09:07:35 PDT 2026


================
@@ -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()
----------------
antoniofrighetto wrote:

Did we get the operands swapped here? I wonder though, do you think it would be feasible to somehow reuse accumulateConstantOffset() for the offset computation here (or perhaps extend getIndexedOffsetInType())? (I think it would be nice to avoid duplicating the index to offset logic).

https://github.com/llvm/llvm-project/pull/224652


More information about the cfe-commits mailing list