[llvm] e0136a6 - [ConstraintElimination] Support chained GEPs with constant offsets.
Florian Hahn via llvm-commits
llvm-commits at lists.llvm.org
Sat Oct 8 09:00:00 PDT 2022
Author: Florian Hahn
Date: 2022-10-08T16:59:27+01:00
New Revision: e0136a62cc2e264d019d75dc36702ac77bf3680f
URL: https://github.com/llvm/llvm-project/commit/e0136a62cc2e264d019d75dc36702ac77bf3680f
DIFF: https://github.com/llvm/llvm-project/commit/e0136a62cc2e264d019d75dc36702ac77bf3680f.diff
LOG: [ConstraintElimination] Support chained GEPs with constant offsets.
Handle the (gep (gep ....), C) case by incrementing the constant
coefficient of the inner GEP, if C is a constant.
Added:
Modified:
llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
llvm/test/Transforms/ConstraintElimination/gep-add.ll
llvm/test/Transforms/ConstraintElimination/gep-sub.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
index 6b7905d83323..be7939ac6434 100644
--- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
@@ -197,6 +197,25 @@ decompose(Value *V, SmallVector<PreconditionTy, 4> &Preconditions,
Value *Op0, *Op1;
ConstantInt *CI;
+ // Handle the (gep (gep ....), C) case by incrementing the constant
+ // coefficient of the inner GEP, if C is a constant.
+ auto *InnerGEP = dyn_cast<GetElementPtrInst>(GEP->getPointerOperand());
+ if (InnerGEP && InnerGEP->getNumOperands() == 2 &&
+ isa<ConstantInt>(GEP->getOperand(1))) {
+ APInt Offset = cast<ConstantInt>(GEP->getOperand(1))->getValue();
+ auto Result = decompose(InnerGEP, Preconditions, IsSigned);
+ Result[0].Coefficient += Offset.getSExtValue();
+ if (Offset.isNegative()) {
+ // Add pre-condition ensuring the GEP is increasing monotonically and
+ // can be de-composed.
+ Preconditions.emplace_back(
+ CmpInst::ICMP_SGE, InnerGEP->getOperand(1),
+ ConstantInt::get(InnerGEP->getOperand(1)->getType(),
+ -1 * Offset.getSExtValue()));
+ }
+ return Result;
+ }
+
// If the index is zero-extended, it is guaranteed to be positive.
if (match(GEP->getOperand(GEP->getNumOperands() - 1),
m_ZExt(m_Value(Op0)))) {
diff --git a/llvm/test/Transforms/ConstraintElimination/gep-add.ll b/llvm/test/Transforms/ConstraintElimination/gep-add.ll
index f1f532109945..e0fb5c20935b 100644
--- a/llvm/test/Transforms/ConstraintElimination/gep-add.ll
+++ b/llvm/test/Transforms/ConstraintElimination/gep-add.ll
@@ -15,7 +15,7 @@ define i1 @gep_add_1_uge(ptr %dst, ptr %lower) {
; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, true
; CHECK-NEXT: [[DST_ADD_4:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_3]], i64 3
; CHECK-NEXT: [[CMP_ADD_4:%.*]] = icmp uge ptr [[DST_ADD_4]], [[LOWER]]
-; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_ADD_4]]
+; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], true
; CHECK-NEXT: ret i1 [[RES_2]]
;
%pre = icmp uge ptr %dst, %lower
@@ -42,7 +42,7 @@ define i1 @gep_add_1_ult(ptr %dst, ptr %lower, ptr %upper) {
; CHECK-NEXT: [[CMP_ADD_3:%.*]] = icmp ult ptr [[DST_ADD_3]], [[UPPER]]
; CHECK-NEXT: [[DST_ADD_4:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_1]], i64 3
; CHECK-NEXT: [[CMP_ADD_4:%.*]] = icmp ult ptr [[DST_ADD_4]], [[UPPER]]
-; CHECK-NEXT: [[RES_1:%.*]] = xor i1 [[CMP_ADD_3]], [[CMP_ADD_4]]
+; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, true
; CHECK-NEXT: [[DST_ADD_5:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_1]], i64 4
; CHECK-NEXT: [[CMP_ADD_5:%.*]] = icmp ult ptr [[DST_ADD_5]], [[UPPER]]
; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_ADD_5]]
@@ -75,7 +75,7 @@ define i1 @gep_add_ult_var_idx(ptr %dst, ptr %upper, i8 %idx) {
; CHECK-NEXT: [[CMP_ADD_1:%.*]] = icmp ule ptr [[DST_ADD_1]], [[UPPER]]
; CHECK-NEXT: [[DST_ADD_2:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_IDX]], i64 2
; CHECK-NEXT: [[CMP_ADD_2:%.*]] = icmp ule ptr [[DST_ADD_2]], [[UPPER]]
-; CHECK-NEXT: [[RES_1:%.*]] = xor i1 [[CMP_ADD_1]], [[CMP_ADD_2]]
+; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, [[CMP_ADD_2]]
; CHECK-NEXT: ret i1 [[RES_1]]
;
%not.zero = icmp ne i8 %idx, 0
@@ -104,7 +104,7 @@ define i1 @gep_add_ult_var_idx_sgt_1(ptr %dst, ptr %upper, i8 %idx) {
; CHECK-NEXT: [[CMP_ADD_1:%.*]] = icmp ule ptr [[DST_ADD_1]], [[UPPER]]
; CHECK-NEXT: [[DST_ADD_2:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_IDX]], i64 2
; CHECK-NEXT: [[CMP_ADD_2:%.*]] = icmp ule ptr [[DST_ADD_2]], [[UPPER]]
-; CHECK-NEXT: [[RES_1:%.*]] = xor i1 [[CMP_ADD_1]], [[CMP_ADD_2]]
+; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, [[CMP_ADD_2]]
; CHECK-NEXT: ret i1 [[RES_1]]
;
%sgt.1 = icmp sgt i8 %idx, 1
@@ -138,7 +138,7 @@ define i1 @gep_add_1_ult_var_idx(ptr %dst, ptr %upper, i8 %len, i8 %idx) {
; CHECK-NEXT: [[CMP_IDX_1:%.*]] = icmp ult ptr [[DST_ADD_IDX_1]], [[UPPER]]
; CHECK-NEXT: [[DST_ADD_IDX_2:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_IDX]], i64 2
; CHECK-NEXT: [[CMP_IDX_2:%.*]] = icmp ult ptr [[DST_ADD_IDX_2]], [[UPPER]]
-; CHECK-NEXT: [[RES_1:%.*]] = xor i1 [[CMP_IDX_1]], [[CMP_IDX_2]]
+; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, true
; CHECK-NEXT: [[DST_ADD_IDX_3:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_IDX]], i64 3
; CHECK-NEXT: [[CMP_IDX_3:%.*]] = icmp ult ptr [[DST_ADD_IDX_3]], [[UPPER]]
; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_IDX_3]]
diff --git a/llvm/test/Transforms/ConstraintElimination/gep-sub.ll b/llvm/test/Transforms/ConstraintElimination/gep-sub.ll
index 7825d03502c3..ab65d250fe19 100644
--- a/llvm/test/Transforms/ConstraintElimination/gep-sub.ll
+++ b/llvm/test/Transforms/ConstraintElimination/gep-sub.ll
@@ -12,7 +12,7 @@ define i1 @gep_sub_1_uge(ptr %dst, ptr %lower) {
; CHECK-NEXT: [[CMP_SUB_1:%.*]] = icmp uge ptr [[DST_SUB_1]], [[LOWER]]
; CHECK-NEXT: [[DST_SUB_3:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_3]], i64 -3
; CHECK-NEXT: [[CMP_SUB_3:%.*]] = icmp uge ptr [[DST_SUB_3]], [[LOWER]]
-; CHECK-NEXT: [[RES_1:%.*]] = xor i1 [[CMP_SUB_1]], [[CMP_SUB_3]]
+; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, true
; CHECK-NEXT: [[DST_SUB_4:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_3]], i64 -4
; CHECK-NEXT: [[CMP_SUB_4:%.*]] = icmp uge ptr [[DST_SUB_4]], [[LOWER]]
; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_SUB_4]]
@@ -42,7 +42,7 @@ define i1 @gep_sub_1_ult(ptr %dst, ptr %upper) {
; CHECK-NEXT: [[CMP_SUB_1:%.*]] = icmp ult ptr [[DST_SUB_1]], [[UPPER]]
; CHECK-NEXT: [[DST_SUB_3:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_3]], i64 -3
; CHECK-NEXT: [[CMP_SUB_3:%.*]] = icmp ult ptr [[DST_SUB_3]], [[UPPER]]
-; CHECK-NEXT: [[RES_1:%.*]] = xor i1 [[CMP_SUB_1]], [[CMP_SUB_3]]
+; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, true
; CHECK-NEXT: ret i1 [[RES_1]]
;
%dst.add.4 = getelementptr inbounds i8, ptr %dst, i64 4
More information about the llvm-commits
mailing list