[llvm] [InstCombine] fold `gepi _, (srem x, y)` to `gepi _, (urem x, y)` if `y` is power-of-2 (PR #180148)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 6 03:22:36 PST 2026


================
@@ -3347,6 +3347,31 @@ Instruction *InstCombinerImpl::visitGetElementPtrInst(GetElementPtrInst &GEP) {
     }
   }
 
+  // srem -> (and/urem) for inbounds+nuw GEP ---
+  if (Indices.size() == 1 && GEP.isInBounds() &&
+      GEP.getNoWrapFlags().hasNoUnsignedWrap()) {
+    Value *X = nullptr;
+    Value *Y = nullptr;
+
+    // Match: idx = srem X, Y -- where Y is a power-of-two value.
+    if (match(Indices[0], m_SRem(m_Value(X), m_Value(Y)))) {
+      if (isKnownToBeAPowerOfTwo(Y, false, &GEP)) {
+        // If GEP is inbounds+nuw, the offset cannot be negative
+        // -> srem by power-of-two can be treated as urem,
+        // and urem by power-of-two folds to 'and' later.
+        Instruction *OldIdxI = dyn_cast<Instruction>(Indices[0]);
+        Value *NewIdx = Builder.CreateURem(X, Y, OldIdxI->getName());
+
+        auto *NewGEP = GetElementPtrInst::Create(
+            GEPEltType, PtrOp, {NewIdx}, GEP.getNoWrapFlags(), GEP.getName(),
+            GEP.getIterator());
+        NewGEP->setDebugLoc(GEP.getDebugLoc());
+
+        return replaceInstUsesWith(GEP, NewGEP);
----------------
nikic wrote:

```suggestion
        return GetElementPtrInst::Create(
            GEPEltType, PtrOp, {NewIdx}, GEP.getNoWrapFlags(), GEP.getName();
```

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


More information about the llvm-commits mailing list