[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