[llvm] [InstCombine] Fold `getelementptr inbounds null, idx -> null` (PR #130742)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 12 05:22:25 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: Yingwei Zheng (dtcxzyw)
<details>
<summary>Changes</summary>
Proof: https://alive2.llvm.org/ce/z/5ZkPx-
---
Full diff: https://github.com/llvm/llvm-project/pull/130742.diff
4 Files Affected:
- (modified) llvm/lib/Transforms/InstCombine/InstructionCombining.cpp (+7)
- (modified) llvm/test/Transforms/InstCombine/getelementptr.ll (+35-4)
- (modified) llvm/test/Transforms/InstCombine/store.ll (+1-2)
- (modified) llvm/test/Transforms/InstCombine/sub-gep.ll (+2-2)
``````````diff
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index 4c14dcfb4d75f..dcb17ee8d7b43 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -2910,6 +2910,13 @@ Instruction *InstCombinerImpl::visitGetElementPtrInst(GetElementPtrInst &GEP) {
SQ.getWithInstruction(&GEP)))
return replaceInstUsesWith(GEP, V);
+ // getelementptr inbounds null, idx -> null
+ if (auto *BaseC = dyn_cast<Constant>(PtrOp))
+ if (GEP.isInBounds() && BaseC->isNullValue() &&
+ !NullPointerIsDefined(GEP.getFunction(),
+ GEPType->getPointerAddressSpace()))
+ return replaceInstUsesWith(GEP, Constant::getNullValue(GEPType));
+
// For vector geps, use the generic demanded vector support.
// Skip if GEP return type is scalable. The number of elements is unknown at
// compile-time.
diff --git a/llvm/test/Transforms/InstCombine/getelementptr.ll b/llvm/test/Transforms/InstCombine/getelementptr.ll
index ec03d9a2dae2b..c1bd6806eae86 100644
--- a/llvm/test/Transforms/InstCombine/getelementptr.ll
+++ b/llvm/test/Transforms/InstCombine/getelementptr.ll
@@ -1328,8 +1328,7 @@ define ptr @PR45084_extra_use(i1 %cond, ptr %p) {
define ptr @gep_null_inbounds(i64 %idx) {
; CHECK-LABEL: @gep_null_inbounds(
-; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr null, i64 [[IDX:%.*]]
-; CHECK-NEXT: ret ptr [[GEP]]
+; CHECK-NEXT: ret ptr null
;
%gep = getelementptr inbounds i8, ptr null, i64 %idx
ret ptr %gep
@@ -1355,8 +1354,7 @@ define ptr @gep_null_defined(i64 %idx) null_pointer_is_valid {
define ptr @gep_null_inbounds_different_type(i64 %idx1, i64 %idx2) {
; CHECK-LABEL: @gep_null_inbounds_different_type(
-; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds [0 x i8], ptr null, i64 0, i64 [[IDX2:%.*]]
-; CHECK-NEXT: ret ptr [[GEP]]
+; CHECK-NEXT: ret ptr null
;
%gep = getelementptr inbounds [0 x i8], ptr null, i64 %idx1, i64 %idx2
ret ptr %gep
@@ -2019,5 +2017,38 @@ define ptr @gep_merge_nusw_const(ptr %p, i64 %idx, i64 %idx2) {
ret ptr %gep
}
+define <2 x ptr> @gep_inbounds_null_vec(i64 %idx) {
+; CHECK-LABEL: @gep_inbounds_null_vec(
+; CHECK-NEXT: ret <2 x ptr> zeroinitializer
+;
+ %p = getelementptr inbounds i8, <2 x ptr> zeroinitializer, i64 %idx
+ ret <2 x ptr> %p
+}
+
+define <2 x ptr> @gep_inbounds_null_vec_broadcast(<2 x i64> %idx) {
+; CHECK-LABEL: @gep_inbounds_null_vec_broadcast(
+; CHECK-NEXT: ret <2 x ptr> zeroinitializer
+;
+ %p = getelementptr inbounds i8, ptr null, <2 x i64> %idx
+ ret <2 x ptr> %p
+}
+
+define ptr @gep_noinbounds_null(i64 %idx) {
+; CHECK-LABEL: @gep_noinbounds_null(
+; CHECK-NEXT: [[P:%.*]] = getelementptr i8, ptr null, i64 [[IDX:%.*]]
+; CHECK-NEXT: ret ptr [[P]]
+;
+ %p = getelementptr i8, ptr null, i64 %idx
+ ret ptr %p
+}
+
+define ptr @gep_inbounds_null_null_is_valid(i64 %idx) null_pointer_is_valid {
+; CHECK-LABEL: @gep_inbounds_null_null_is_valid(
+; CHECK-NEXT: [[P:%.*]] = getelementptr inbounds i8, ptr null, i64 [[IDX:%.*]]
+; CHECK-NEXT: ret ptr [[P]]
+;
+ %p = getelementptr inbounds i8, ptr null, i64 %idx
+ ret ptr %p
+}
!0 = !{!"branch_weights", i32 2, i32 10}
diff --git a/llvm/test/Transforms/InstCombine/store.ll b/llvm/test/Transforms/InstCombine/store.ll
index daa40da1828b5..48c63c6f24c72 100644
--- a/llvm/test/Transforms/InstCombine/store.ll
+++ b/llvm/test/Transforms/InstCombine/store.ll
@@ -49,8 +49,7 @@ define void @test2(ptr %P) {
define void @store_at_gep_off_null_inbounds(i64 %offset) {
; CHECK-LABEL: @store_at_gep_off_null_inbounds(
-; CHECK-NEXT: [[PTR:%.*]] = getelementptr inbounds i32, ptr null, i64 [[OFFSET:%.*]]
-; CHECK-NEXT: store i32 poison, ptr [[PTR]], align 4
+; CHECK-NEXT: store i32 poison, ptr null, align 4
; CHECK-NEXT: ret void
;
%ptr = getelementptr inbounds i32, ptr null, i64 %offset
diff --git a/llvm/test/Transforms/InstCombine/sub-gep.ll b/llvm/test/Transforms/InstCombine/sub-gep.ll
index 3f8728d3a4381..c86a1a37bd7ad 100644
--- a/llvm/test/Transforms/InstCombine/sub-gep.ll
+++ b/llvm/test/Transforms/InstCombine/sub-gep.ll
@@ -741,7 +741,7 @@ define i64 @nullptrtoint_scalable_c() {
; CHECK-NEXT: ret i64 [[PTR_IDX]]
;
entry:
- %ptr = getelementptr inbounds <vscale x 4 x i32>, ptr null, i64 8
+ %ptr = getelementptr nusw <vscale x 4 x i32>, ptr null, i64 8
%ret = ptrtoint ptr %ptr to i64
ret i64 %ret
}
@@ -755,7 +755,7 @@ define i64 @nullptrtoint_scalable_x(i64 %x) {
; CHECK-NEXT: ret i64 [[PTR_IDX]]
;
entry:
- %ptr = getelementptr inbounds <vscale x 4 x i32>, ptr null, i64 %x
+ %ptr = getelementptr nusw <vscale x 4 x i32>, ptr null, i64 %x
%ret = ptrtoint ptr %ptr to i64
ret i64 %ret
}
``````````
</details>
https://github.com/llvm/llvm-project/pull/130742
More information about the llvm-commits
mailing list