[llvm] 3c9f3f7 - [ConstantFold] Fold zero-index GEPs with opaque pointers
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 4 04:04:39 PDT 2022
Author: Nikita Popov
Date: 2022-04-04T13:04:27+02:00
New Revision: 3c9f3f76f105196cd354a34f597b1ce88bee9b5d
URL: https://github.com/llvm/llvm-project/commit/3c9f3f76f105196cd354a34f597b1ce88bee9b5d
DIFF: https://github.com/llvm/llvm-project/commit/3c9f3f76f105196cd354a34f597b1ce88bee9b5d.diff
LOG: [ConstantFold] Fold zero-index GEPs with opaque pointers
With opaque pointers, we can eliminate zero-index GEPs even if
they have multiple indices, as this no longer impacts the result
type of the GEP.
This optimization is already done for instructions in InstSimplify,
but we were missing the corresponding constant expression handling.
The constexpr transform is a bit more powerful, because it can
produce a vector splat constant and also handles undef values --
it is an extension of an existing single-index transform.
Added:
Modified:
llvm/lib/IR/ConstantFold.cpp
llvm/test/Transforms/IndVarSimplify/lftr-opaque-pointers.ll
llvm/test/Transforms/InstSimplify/opaque-ptr.ll
Removed:
################################################################################
diff --git a/llvm/lib/IR/ConstantFold.cpp b/llvm/lib/IR/ConstantFold.cpp
index 74200b99367ca..e38cd820da29f 100644
--- a/llvm/lib/IR/ConstantFold.cpp
+++ b/llvm/lib/IR/ConstantFold.cpp
@@ -2036,8 +2036,18 @@ Constant *llvm::ConstantFoldGetElementPtr(Type *PointeeTy, Constant *C,
// If inbounds, we can choose an out-of-bounds pointer as a base pointer.
return InBounds ? PoisonValue::get(GEPTy) : UndefValue::get(GEPTy);
- Constant *Idx0 = cast<Constant>(Idxs[0]);
- if (Idxs.size() == 1 && (Idx0->isNullValue() || isa<UndefValue>(Idx0)))
+ auto IsNoOp = [&]() {
+ // For non-opaque pointers having multiple indices will change the result
+ // type of the GEP.
+ if (!C->getType()->getScalarType()->isOpaquePointerTy() && Idxs.size() != 1)
+ return false;
+
+ return all_of(Idxs, [](Value *Idx) {
+ Constant *IdxC = cast<Constant>(Idx);
+ return IdxC->isNullValue() || isa<UndefValue>(IdxC);
+ });
+ };
+ if (IsNoOp())
return GEPTy->isVectorTy() && !C->getType()->isVectorTy()
? ConstantVector::getSplat(
cast<VectorType>(GEPTy)->getElementCount(), C)
@@ -2090,6 +2100,7 @@ Constant *llvm::ConstantFoldGetElementPtr(Type *PointeeTy, Constant *C,
// i32* getelementptr ([3 x i32]* %X, i64 0, i64 0)
//
// Don't fold if the cast is changing address spaces.
+ Constant *Idx0 = cast<Constant>(Idxs[0]);
if (CE->isCast() && Idxs.size() > 1 && Idx0->isNullValue()) {
PointerType *SrcPtrTy =
dyn_cast<PointerType>(CE->getOperand(0)->getType());
diff --git a/llvm/test/Transforms/IndVarSimplify/lftr-opaque-pointers.ll b/llvm/test/Transforms/IndVarSimplify/lftr-opaque-pointers.ll
index 94e0288e534b1..4edcf5b3414e1 100644
--- a/llvm/test/Transforms/IndVarSimplify/lftr-opaque-pointers.ll
+++ b/llvm/test/Transforms/IndVarSimplify/lftr-opaque-pointers.ll
@@ -11,7 +11,7 @@ define void @test_zext(ptr %a) {
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
-; CHECK-NEXT: [[P_0:%.*]] = phi ptr [ getelementptr inbounds ([240 x i8], ptr @data, i64 0, i64 0), [[ENTRY:%.*]] ], [ [[T3:%.*]], [[LOOP]] ]
+; CHECK-NEXT: [[P_0:%.*]] = phi ptr [ @data, [[ENTRY:%.*]] ], [ [[T3:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[DOT0:%.*]] = phi ptr [ [[A:%.*]], [[ENTRY]] ], [ [[T:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[T]] = getelementptr inbounds i8, ptr [[DOT0]], i64 1
; CHECK-NEXT: [[T2:%.*]] = load i8, ptr [[DOT0]], align 1
diff --git a/llvm/test/Transforms/InstSimplify/opaque-ptr.ll b/llvm/test/Transforms/InstSimplify/opaque-ptr.ll
index 30c81b1065b21..d0d3ac1128e67 100644
--- a/llvm/test/Transforms/InstSimplify/opaque-ptr.ll
+++ b/llvm/test/Transforms/InstSimplify/opaque-ptr.ll
@@ -56,56 +56,56 @@ define <2 x ptr> @vector_base_scalar_index(<2 x ptr> %p) {
define ptr @constexpr_zero_gep_scalar_base_scalar_index() {
; CHECK-LABEL: @constexpr_zero_gep_scalar_base_scalar_index(
-; CHECK-NEXT: ret ptr getelementptr inbounds ([2 x i32], ptr @g, i64 0, i64 0)
+; CHECK-NEXT: ret ptr @g
;
ret ptr getelementptr ([2 x i32], ptr @g, i64 0, i64 0)
}
define <2 x ptr> @constexpr_zero_gep_vector_base_scalar_index() {
; CHECK-LABEL: @constexpr_zero_gep_vector_base_scalar_index(
-; CHECK-NEXT: ret <2 x ptr> getelementptr ([2 x i32], <2 x ptr> <ptr @g, ptr @g>, <2 x i64> zeroinitializer, <2 x i64> zeroinitializer)
+; CHECK-NEXT: ret <2 x ptr> <ptr @g, ptr @g>
;
ret <2 x ptr> getelementptr ([2 x i32], <2 x ptr> <ptr @g, ptr @g>, i64 0, i64 0)
}
define <2 x ptr> @constexpr_zero_gep_scalar_base_vector_index() {
; CHECK-LABEL: @constexpr_zero_gep_scalar_base_vector_index(
-; CHECK-NEXT: ret <2 x ptr> getelementptr ([2 x i32], ptr @g, <2 x i64> zeroinitializer, <2 x i64> zeroinitializer)
+; CHECK-NEXT: ret <2 x ptr> <ptr @g, ptr @g>
;
ret <2 x ptr> getelementptr ([2 x i32], ptr @g, <2 x i64> zeroinitializer, i64 0)
}
define <2 x ptr> @constexpr_zero_gep_vector_base_vector_index() {
; CHECK-LABEL: @constexpr_zero_gep_vector_base_vector_index(
-; CHECK-NEXT: ret <2 x ptr> getelementptr ([2 x i32], <2 x ptr> <ptr @g, ptr @g>, <2 x i64> zeroinitializer, <2 x i64> zeroinitializer)
+; CHECK-NEXT: ret <2 x ptr> <ptr @g, ptr @g>
;
ret <2 x ptr> getelementptr ([2 x i32], <2 x ptr> <ptr @g, ptr @g>, <2 x i64> zeroinitializer, i64 0)
}
define ptr @constexpr_undef_gep_scalar_base_scalar_index() {
; CHECK-LABEL: @constexpr_undef_gep_scalar_base_scalar_index(
-; CHECK-NEXT: ret ptr getelementptr ([2 x i32], ptr @g, i64 0, i64 undef)
+; CHECK-NEXT: ret ptr @g
;
ret ptr getelementptr ([2 x i32], ptr @g, i64 0, i64 undef)
}
define <2 x ptr> @constexpr_undef_gep_vector_base_scalar_index() {
; CHECK-LABEL: @constexpr_undef_gep_vector_base_scalar_index(
-; CHECK-NEXT: ret <2 x ptr> getelementptr ([2 x i32], <2 x ptr> <ptr @g, ptr @g>, <2 x i64> undef, <2 x i64> undef)
+; CHECK-NEXT: ret <2 x ptr> <ptr @g, ptr @g>
;
ret <2 x ptr> getelementptr ([2 x i32], <2 x ptr> <ptr @g, ptr @g>, i64 undef, i64 undef)
}
define <2 x ptr> @constexpr_undef_gep_scalar_base_vector_index() {
; CHECK-LABEL: @constexpr_undef_gep_scalar_base_vector_index(
-; CHECK-NEXT: ret <2 x ptr> getelementptr ([2 x i32], ptr @g, <2 x i64> undef, <2 x i64> zeroinitializer)
+; CHECK-NEXT: ret <2 x ptr> <ptr @g, ptr @g>
;
ret <2 x ptr> getelementptr ([2 x i32], ptr @g, <2 x i64> undef, i64 0)
}
define <2 x ptr> @constexpr_undef_gep_vector_base_vector_index() {
; CHECK-LABEL: @constexpr_undef_gep_vector_base_vector_index(
-; CHECK-NEXT: ret <2 x ptr> getelementptr ([2 x i32], <2 x ptr> <ptr @g, ptr @g>, <2 x i64> undef, <2 x i64> zeroinitializer)
+; CHECK-NEXT: ret <2 x ptr> <ptr @g, ptr @g>
;
ret <2 x ptr> getelementptr ([2 x i32], <2 x ptr> <ptr @g, ptr @g>, <2 x i64> undef, i64 0)
}
More information about the llvm-commits
mailing list