[InstSimplify] Fold getelementptr inbounds null, idx -> null
by dtcxzyw · Pull Request #130742 · llvm/llvm-project (original) (raw)
@llvm/pr-subscribers-llvm-analysis
@llvm/pr-subscribers-llvm-transforms
Author: Yingwei Zheng (dtcxzyw)
Changes
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 --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(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 }