[llvm] [InstCombine] Fold chained GEP with constant base into single GEP (PR #170439)

Jianjian Guan via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 11 22:23:07 PST 2025


================
@@ -2803,6 +2803,51 @@ Instruction *InstCombinerImpl::visitGEPOfGEP(GetElementPtrInst &GEP,
   if (Src->getResultElementType() != GEP.getSourceElementType())
     return nullptr;
 
+  // Fold chained GEP with constant base into single GEP:
+  // gep i8, (gep i8, %base, C1), (select Cond, C2, C3)
+  // -> gep i8, %base, (select Cond, C1+C2, C1+C3)
+  if (GEP.getNumIndices() == 1 && Src->getNumIndices() == 1) {
+    Value *SrcIdx = *Src->idx_begin();
+    Value *GEPIdx = *GEP.idx_begin();
+    const APInt *ConstOffset, *TrueVal, *FalseVal;
+    Value *Cond;
+
+    if ((match(SrcIdx, m_APInt(ConstOffset)) &&
+         match(GEPIdx,
+               m_Select(m_Value(Cond), m_APInt(TrueVal), m_APInt(FalseVal)))) ||
+        (match(GEPIdx, m_APInt(ConstOffset)) &&
+         match(SrcIdx,
+               m_Select(m_Value(Cond), m_APInt(TrueVal), m_APInt(FalseVal))))) {
+      auto *Select = isa<SelectInst>(GEPIdx) ? cast<SelectInst>(GEPIdx)
+                                             : cast<SelectInst>(SrcIdx);
+
+      // Make sure the select has only one use.
+      if (!Select->hasOneUse())
+        return nullptr;
+
+      if (TrueVal->getBitWidth() != ConstOffset->getBitWidth() ||
+          FalseVal->getBitWidth() != ConstOffset->getBitWidth())
+        return nullptr;
+
+      APInt NewTrueVal = *ConstOffset + *TrueVal;
+      APInt NewFalseVal = *ConstOffset + *FalseVal;
+      Constant *NewTrue = Builder.getInt(NewTrueVal);
+      Constant *NewFalse = Builder.getInt(NewFalseVal);
+      // Consider vector splat.
+      if (auto *VT = dyn_cast<VectorType>(Select->getType())) {
+        NewTrue = ConstantVector::getSplat(VT->getElementCount(), NewTrue);
+        NewFalse = ConstantVector::getSplat(VT->getElementCount(), NewFalse);
+      }
----------------
jacquesguan wrote:

Changed.

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


More information about the llvm-commits mailing list