[llvm] [CVP] Remove Zero-Index GEP (PR #144831)

via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 18 21:00:39 PDT 2025


https://github.com/veera-sivarajan created https://github.com/llvm/llvm-project/pull/144831

Fixes: #137168

Proof: https://alive2.llvm.org/ce/z/Xoyiar

Replaces all uses of a GEP with its base pointer when all its indices are known to be in the range [0, 1).

This is the same transform as https://github.com/llvm/llvm-project/commit/87a0b1bd233a3680c32a6e17acf147d0fe90c9e9 but in CVP.

>From e8650a0ce0a618e4b3e5fa2ba24424127c05c9ae Mon Sep 17 00:00:00 2001
From: Veera <sveera.2001 at gmail.com>
Date: Thu, 19 Jun 2025 03:19:28 +0000
Subject: [PATCH 1/2] Add Test

---
 .../CorrelatedValuePropagation/gep.ll         | 45 +++++++++++++++++++
 1 file changed, 45 insertions(+)
 create mode 100644 llvm/test/Transforms/CorrelatedValuePropagation/gep.ll

diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/gep.ll b/llvm/test/Transforms/CorrelatedValuePropagation/gep.ll
new file mode 100644
index 0000000000000..deb192551ccf7
--- /dev/null
+++ b/llvm/test/Transforms/CorrelatedValuePropagation/gep.ll
@@ -0,0 +1,45 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt < %s -passes=correlated-propagation -S | FileCheck %s
+
+define ptr @noop_gep(ptr %ptr, i8 range(i8 0, 1) %index) {
+; CHECK-LABEL: define ptr @noop_gep(
+; CHECK-SAME: ptr [[PTR:%.*]], i8 range(i8 0, 1) [[INDEX:%.*]]) {
+; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i1, ptr [[PTR]], i8 [[INDEX]]
+; CHECK-NEXT:    ret ptr [[GEP]]
+;
+  %gep = getelementptr i1, ptr %ptr, i8 %index
+  ret ptr %gep
+}
+
+
+define ptr @noop_gep_with_constant(ptr %ptr, i8 range(i8 0, 1) %index) {
+; CHECK-LABEL: define ptr @noop_gep_with_constant(
+; CHECK-SAME: ptr [[PTR:%.*]], i8 range(i8 0, 1) [[INDEX:%.*]]) {
+; CHECK-NEXT:    [[GEP:%.*]] = getelementptr [2 x i1], ptr [[PTR]], i8 0, i8 [[INDEX]]
+; CHECK-NEXT:    ret ptr [[GEP]]
+;
+  %gep = getelementptr [2 x i1], ptr %ptr, i8 0, i8 %index
+  ret ptr %gep
+}
+
+
+define ptr @noop_gep_nonzero_index_negative(ptr %ptr, i8 range(i8 0, 2) %index) {
+; CHECK-LABEL: define ptr @noop_gep_nonzero_index_negative(
+; CHECK-SAME: ptr [[PTR:%.*]], i8 range(i8 0, 2) [[INDEX:%.*]]) {
+; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i1, ptr [[PTR]], i8 [[INDEX]]
+; CHECK-NEXT:    ret ptr [[GEP]]
+;
+  %gep = getelementptr i1, ptr %ptr, i8 %index
+  ret ptr %gep
+}
+
+
+define ptr @gep_no_range_negative(ptr %ptr, i8 %index) {
+; CHECK-LABEL: define ptr @gep_no_range_negative(
+; CHECK-SAME: ptr [[PTR:%.*]], i8 [[INDEX:%.*]]) {
+; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i1, ptr [[PTR]], i8 [[INDEX]]
+; CHECK-NEXT:    ret ptr [[GEP]]
+;
+  %gep = getelementptr i1, ptr %ptr, i8 %index
+  ret ptr %gep
+}

>From a014cef6d36da245ca2d76d342a9cee722538469 Mon Sep 17 00:00:00 2001
From: Veera <sveera.2001 at gmail.com>
Date: Thu, 19 Jun 2025 03:45:26 +0000
Subject: [PATCH 2/2] [CVP] Remove Zero-Index GEP

---
 .../Scalar/CorrelatedValuePropagation.cpp     | 21 +++++++++++++++++++
 .../CorrelatedValuePropagation/gep.ll         |  4 ++--
 2 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
index 4627f537dc16b..11a3a35d1ae7c 100644
--- a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
+++ b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
@@ -47,6 +47,7 @@ using namespace llvm;
 
 #define DEBUG_TYPE "correlated-value-propagation"
 
+STATISTIC(NumGEPs,      "Number of geps propagated");
 STATISTIC(NumPhis,      "Number of phis propagated");
 STATISTIC(NumPhiCommon, "Number of phis deleted via common incoming value");
 STATISTIC(NumSelects,   "Number of selects propagated");
@@ -1252,6 +1253,23 @@ static bool processTrunc(TruncInst *TI, LazyValueInfo *LVI) {
   return Changed;
 }
 
+// remove a GEP if all indices are in range [0, 1)
+static bool processGEP(GetElementPtrInst *GEP, LazyValueInfo *LVI) {
+  for (unsigned i = 1, e = GEP->getNumOperands(); i != e; ++i) {
+    ConstantRange Range = LVI->getConstantRangeAtUse(GEP->getOperandUse(i),
+                                                     /*UndefAllowed=*/false);
+    const APInt *C = Range.getSingleElement();
+    if (!C || !C->isZero())
+      return false;
+  }
+
+  // all indices are zero
+  Value *Ptr = GEP->getPointerOperand();
+  GEP->replaceAllUsesWith(Ptr);
+  ++NumGEPs;
+  return true;
+}
+
 static bool runImpl(Function &F, LazyValueInfo *LVI, DominatorTree *DT,
                     const SimplifyQuery &SQ) {
   bool FnChanged = false;
@@ -1318,6 +1336,9 @@ static bool runImpl(Function &F, LazyValueInfo *LVI, DominatorTree *DT,
       case Instruction::Trunc:
         BBChanged |= processTrunc(cast<TruncInst>(&II), LVI);
         break;
+      case Instruction::GetElementPtr:
+        BBChanged |= processGEP(cast<GetElementPtrInst>(&II), LVI);
+        break;
       }
     }
 
diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/gep.ll b/llvm/test/Transforms/CorrelatedValuePropagation/gep.ll
index deb192551ccf7..d5c122b3f665e 100644
--- a/llvm/test/Transforms/CorrelatedValuePropagation/gep.ll
+++ b/llvm/test/Transforms/CorrelatedValuePropagation/gep.ll
@@ -5,7 +5,7 @@ define ptr @noop_gep(ptr %ptr, i8 range(i8 0, 1) %index) {
 ; CHECK-LABEL: define ptr @noop_gep(
 ; CHECK-SAME: ptr [[PTR:%.*]], i8 range(i8 0, 1) [[INDEX:%.*]]) {
 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i1, ptr [[PTR]], i8 [[INDEX]]
-; CHECK-NEXT:    ret ptr [[GEP]]
+; CHECK-NEXT:    ret ptr [[PTR]]
 ;
   %gep = getelementptr i1, ptr %ptr, i8 %index
   ret ptr %gep
@@ -16,7 +16,7 @@ define ptr @noop_gep_with_constant(ptr %ptr, i8 range(i8 0, 1) %index) {
 ; CHECK-LABEL: define ptr @noop_gep_with_constant(
 ; CHECK-SAME: ptr [[PTR:%.*]], i8 range(i8 0, 1) [[INDEX:%.*]]) {
 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr [2 x i1], ptr [[PTR]], i8 0, i8 [[INDEX]]
-; CHECK-NEXT:    ret ptr [[GEP]]
+; CHECK-NEXT:    ret ptr [[PTR]]
 ;
   %gep = getelementptr [2 x i1], ptr %ptr, i8 0, i8 %index
   ret ptr %gep



More information about the llvm-commits mailing list