[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