[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