[llvm] 68dc90b - [ConstraintElimination] Decompose a few more GEP indices.

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 8 10:07:09 PST 2021


Author: Florian Hahn
Date: 2021-02-08T18:06:38Z
New Revision: 68dc90b3472de440118e76ed2e2cd99ae593b072

URL: https://github.com/llvm/llvm-project/commit/68dc90b3472de440118e76ed2e2cd99ae593b072
DIFF: https://github.com/llvm/llvm-project/commit/68dc90b3472de440118e76ed2e2cd99ae593b072.diff

LOG: [ConstraintElimination] Decompose a few more GEP indices.

This patch adds handling for zero-extended GEP indices.

Added: 
    

Modified: 
    llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
    llvm/test/Transforms/ConstraintElimination/gep-arithmetic.ll
    llvm/test/Transforms/ConstraintElimination/loops-bottom-tested-pointer-cmps.ll
    llvm/test/Transforms/ConstraintElimination/loops-header-tested-pointer-cmps.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
index 46a56f4c31fb..09b0b4a8618b 100644
--- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
@@ -54,28 +54,43 @@ static SmallVector<std::pair<int64_t, Value *>, 4> decompose(Value *V) {
   }
   auto *GEP = dyn_cast<GetElementPtrInst>(V);
   if (GEP && GEP->getNumOperands() == 2 && GEP->isInBounds()) {
-    if (isa<ConstantInt>(GEP->getOperand(GEP->getNumOperands() - 1))) {
-      return {{cast<ConstantInt>(GEP->getOperand(GEP->getNumOperands() - 1))
-                   ->getSExtValue(),
-               nullptr},
-              {1, GEP->getPointerOperand()}};
-    }
     Value *Op0;
     ConstantInt *CI;
+
+    // If the index is zero-extended, it is guaranteed to be positive.
     if (match(GEP->getOperand(GEP->getNumOperands() - 1),
-              m_NUWShl(m_Value(Op0), m_ConstantInt(CI))))
-      return {{0, nullptr},
-              {1, GEP->getPointerOperand()},
-              {std::pow(int64_t(2), CI->getSExtValue()), Op0}};
+              m_ZExt(m_Value(Op0)))) {
+      if (match(Op0, m_NUWShl(m_Value(Op0), m_ConstantInt(CI))))
+        return {{0, nullptr},
+                {1, GEP->getPointerOperand()},
+                {std::pow(int64_t(2), CI->getSExtValue()), Op0}};
+      if (match(Op0, m_NSWAdd(m_Value(Op0), m_ConstantInt(CI))))
+        return {{CI->getSExtValue(), nullptr},
+                {1, GEP->getPointerOperand()},
+                {1, Op0}};
+      return {{0, nullptr}, {1, GEP->getPointerOperand()}, {1, Op0}};
+    }
+
+    if (match(GEP->getOperand(GEP->getNumOperands() - 1), m_ConstantInt(CI)) &&
+        !CI->isNegative())
+      return {{CI->getSExtValue(), nullptr}, {1, GEP->getPointerOperand()}};
+
+    SmallVector<std::pair<int64_t, Value *>, 4> Result;
     if (match(GEP->getOperand(GEP->getNumOperands() - 1),
-              m_ZExt(m_NUWShl(m_Value(Op0), m_ConstantInt(CI)))))
-      return {{0, nullptr},
-              {1, GEP->getPointerOperand()},
-              {std::pow(int64_t(2), CI->getSExtValue()), Op0}};
-
-    return {{0, nullptr},
-            {1, GEP->getPointerOperand()},
-            {1, GEP->getOperand(GEP->getNumOperands() - 1)}};
+              m_NUWShl(m_Value(Op0), m_ConstantInt(CI))))
+      Result = {{0, nullptr},
+                {1, GEP->getPointerOperand()},
+                {std::pow(int64_t(2), CI->getSExtValue()), Op0}};
+    else if (match(GEP->getOperand(GEP->getNumOperands() - 1),
+                   m_NSWAdd(m_Value(Op0), m_ConstantInt(CI))))
+      Result = {{CI->getSExtValue(), nullptr},
+                {1, GEP->getPointerOperand()},
+                {1, Op0}};
+    else {
+      Op0 = GEP->getOperand(GEP->getNumOperands() - 1);
+      Result = {{0, nullptr}, {1, GEP->getPointerOperand()}, {1, Op0}};
+    }
+    return Result;
   }
 
   Value *Op0;

diff  --git a/llvm/test/Transforms/ConstraintElimination/gep-arithmetic.ll b/llvm/test/Transforms/ConstraintElimination/gep-arithmetic.ll
index c8691caf727a..220c8fa14402 100644
--- a/llvm/test/Transforms/ConstraintElimination/gep-arithmetic.ll
+++ b/llvm/test/Transforms/ConstraintElimination/gep-arithmetic.ll
@@ -803,7 +803,7 @@ define i4 @ptr_N_step_zext_n_zext(i8* %src, i8* %lower, i8* %upper, i16 %N, i16
 ; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr inbounds i8, i8* [[SRC]], i32 [[STEP_ADD_1_EXT]]
 ; CHECK-NEXT:    [[CMP_STEP_START:%.*]] = icmp ult i8* [[SRC_STEP]], [[LOWER]]
 ; CHECK-NEXT:    [[CMP_STEP_END:%.*]] = icmp uge i8* [[SRC_STEP]], [[UPPER]]
-; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
+; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], false
 ; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
 ; CHECK:       exit:
 ; CHECK-NEXT:    ret i4 3

diff  --git a/llvm/test/Transforms/ConstraintElimination/loops-bottom-tested-pointer-cmps.ll b/llvm/test/Transforms/ConstraintElimination/loops-bottom-tested-pointer-cmps.ll
index d703a5f8274d..55b1b89b8aac 100644
--- a/llvm/test/Transforms/ConstraintElimination/loops-bottom-tested-pointer-cmps.ll
+++ b/llvm/test/Transforms/ConstraintElimination/loops-bottom-tested-pointer-cmps.ll
@@ -94,7 +94,7 @@ define void @some_checks_in_loops_removable(i8* %ptr, i8* %lower, i8* %upper, i3
 ; CHECK-NEXT:    [[PTR_IV_1:%.*]] = getelementptr inbounds i8, i8* [[PTR]], i64 [[IV_1]]
 ; CHECK-NEXT:    [[CMP_PTR_IV_1_LOWER:%.*]] = icmp ugt i8* [[LOWER]], [[PTR_IV_1]]
 ; CHECK-NEXT:    [[CMP_PTR_IV_1_UPPER:%.*]] = icmp ule i8* [[UPPER]], [[PTR_IV_1]]
-; CHECK-NEXT:    [[OR_1:%.*]] = or i1 [[CMP_PTR_IV_1_LOWER]], [[CMP_PTR_IV_1_UPPER]]
+; CHECK-NEXT:    [[OR_1:%.*]] = or i1 false, [[CMP_PTR_IV_1_UPPER]]
 ; CHECK-NEXT:    br i1 [[OR]], label [[TRAP]], label [[LOOP_LATCH]]
 ; CHECK:       loop.latch:
 ; CHECK-NEXT:    store i8 0, i8* [[PTR_IV]], align 4
@@ -173,7 +173,7 @@ define void @no_checks_in_loops_removable(i8* %ptr, i8* %lower, i8* %upper, i32
 ; CHECK-NEXT:    [[PTR_IV_1:%.*]] = getelementptr inbounds i8, i8* [[PTR]], i64 [[IV_1]]
 ; CHECK-NEXT:    [[CMP_PTR_IV_1_LOWER:%.*]] = icmp ugt i8* [[LOWER]], [[PTR_IV_1]]
 ; CHECK-NEXT:    [[CMP_PTR_IV_1_UPPER:%.*]] = icmp ule i8* [[UPPER]], [[PTR_IV_1]]
-; CHECK-NEXT:    [[OR_1:%.*]] = or i1 [[CMP_PTR_IV_1_LOWER]], [[CMP_PTR_IV_1_UPPER]]
+; CHECK-NEXT:    [[OR_1:%.*]] = or i1 false, [[CMP_PTR_IV_1_UPPER]]
 ; CHECK-NEXT:    br i1 [[OR]], label [[TRAP]], label [[LOOP_LATCH]]
 ; CHECK:       loop.latch:
 ; CHECK-NEXT:    store i8 0, i8* [[PTR_IV]], align 4

diff  --git a/llvm/test/Transforms/ConstraintElimination/loops-header-tested-pointer-cmps.ll b/llvm/test/Transforms/ConstraintElimination/loops-header-tested-pointer-cmps.ll
index d628f8fac496..6a347db138a4 100644
--- a/llvm/test/Transforms/ConstraintElimination/loops-header-tested-pointer-cmps.ll
+++ b/llvm/test/Transforms/ConstraintElimination/loops-header-tested-pointer-cmps.ll
@@ -30,7 +30,7 @@ define void @test1(i8* %src, i8* noundef %lower, i8* noundef %upper, i8 %N) {
 ; CHECK-NEXT:    [[SRC_IV_1:%.*]] = getelementptr inbounds i8, i8* [[SRC]], i8 [[ADD_1]]
 ; CHECK-NEXT:    [[CMP_IV_1_START:%.*]] = icmp ult i8* [[SRC_IV_1]], [[LOWER]]
 ; CHECK-NEXT:    [[CMP_IV_1_END:%.*]] = icmp uge i8* [[SRC_IV_1]], [[UPPER]]
-; CHECK-NEXT:    [[OR_2:%.*]] = or i1 [[CMP_IV_1_START]], [[CMP_IV_1_END]]
+; CHECK-NEXT:    [[OR_2:%.*]] = or i1 false, false
 ; CHECK-NEXT:    br i1 [[OR_2]], label [[TRAP_BB]], label [[LOOP_BODY_2:%.*]]
 ; CHECK:       loop.body.2:
 ; CHECK-NEXT:    [[PTR_SRC_IV_1:%.*]] = bitcast i8* [[SRC_IV_1]] to i32*
@@ -39,7 +39,7 @@ define void @test1(i8* %src, i8* noundef %lower, i8* noundef %upper, i8 %N) {
 ; CHECK-NEXT:    [[SRC_IV_2:%.*]] = getelementptr inbounds i8, i8* [[SRC]], i8 [[ADD_2]]
 ; CHECK-NEXT:    [[CMP_IV_2_START:%.*]] = icmp ult i8* [[SRC_IV_2]], [[LOWER]]
 ; CHECK-NEXT:    [[CMP_IV_2_END:%.*]] = icmp uge i8* [[SRC_IV_2]], [[UPPER]]
-; CHECK-NEXT:    [[OR_3:%.*]] = or i1 [[CMP_IV_2_START]], [[CMP_IV_2_END]]
+; CHECK-NEXT:    [[OR_3:%.*]] = or i1 false, [[CMP_IV_2_END]]
 ; CHECK-NEXT:    br i1 [[OR_3]], label [[TRAP_BB]], label [[LOOP_LATCH]]
 ; CHECK:       loop.latch:
 ; CHECK-NEXT:    [[PTR_SRC_IV_2:%.*]] = bitcast i8* [[SRC_IV_2]] to i32*
@@ -130,14 +130,14 @@ define void @test2(i8* %src, i8* %lower, i8* %upper, i8 %N) {
 ; CHECK-NEXT:    [[SRC_IV_1:%.*]] = getelementptr inbounds i8, i8* [[SRC]], i8 [[ADD_1]]
 ; CHECK-NEXT:    [[CMP_IV_1_START:%.*]] = icmp ult i8* [[SRC_IV_1]], [[LOWER]]
 ; CHECK-NEXT:    [[CMP_IV_1_END:%.*]] = icmp uge i8* [[SRC_IV_1]], [[UPPER]]
-; CHECK-NEXT:    [[OR_2:%.*]] = or i1 [[CMP_IV_1_START]], [[CMP_IV_1_END]]
+; CHECK-NEXT:    [[OR_2:%.*]] = or i1 false, [[CMP_IV_1_END]]
 ; CHECK-NEXT:    br i1 [[OR_2]], label [[TRAP_BB]], label [[LOOP_BODY_2:%.*]]
 ; CHECK:       loop.body.2:
 ; CHECK-NEXT:    [[ADD_2:%.*]] = add nuw nsw i8 [[IV]], 2
 ; CHECK-NEXT:    [[SRC_IV_2:%.*]] = getelementptr inbounds i8, i8* [[SRC]], i8 [[ADD_2]]
 ; CHECK-NEXT:    [[CMP_IV_2_START:%.*]] = icmp ult i8* [[SRC_IV_2]], [[LOWER]]
 ; CHECK-NEXT:    [[CMP_IV_2_END:%.*]] = icmp uge i8* [[SRC_IV_2]], [[UPPER]]
-; CHECK-NEXT:    [[OR_3:%.*]] = or i1 [[CMP_IV_2_START]], [[CMP_IV_2_END]]
+; CHECK-NEXT:    [[OR_3:%.*]] = or i1 false, [[CMP_IV_2_END]]
 ; CHECK-NEXT:    br i1 [[OR_3]], label [[TRAP_BB]], label [[LOOP_LATCH]]
 ; CHECK:       loop.latch:
 ; CHECK-NEXT:    [[PTR:%.*]] = bitcast i8* [[SRC_IV]] to i32*
@@ -226,14 +226,14 @@ define void @test2_with_ne(i8* %src, i8* %lower, i8* %upper, i8 %N) {
 ; CHECK-NEXT:    [[SRC_IV_1:%.*]] = getelementptr inbounds i8, i8* [[SRC]], i8 [[ADD_1]]
 ; CHECK-NEXT:    [[CMP_IV_1_START:%.*]] = icmp ult i8* [[SRC_IV_1]], [[LOWER]]
 ; CHECK-NEXT:    [[CMP_IV_1_END:%.*]] = icmp uge i8* [[SRC_IV_1]], [[UPPER]]
-; CHECK-NEXT:    [[OR_2:%.*]] = or i1 [[CMP_IV_1_START]], [[CMP_IV_1_END]]
+; CHECK-NEXT:    [[OR_2:%.*]] = or i1 false, [[CMP_IV_1_END]]
 ; CHECK-NEXT:    br i1 [[OR_2]], label [[TRAP_BB]], label [[LOOP_BODY_2:%.*]]
 ; CHECK:       loop.body.2:
 ; CHECK-NEXT:    [[ADD_2:%.*]] = add nuw nsw i8 [[IV]], 2
 ; CHECK-NEXT:    [[SRC_IV_2:%.*]] = getelementptr inbounds i8, i8* [[SRC]], i8 [[ADD_2]]
 ; CHECK-NEXT:    [[CMP_IV_2_START:%.*]] = icmp ult i8* [[SRC_IV_2]], [[LOWER]]
 ; CHECK-NEXT:    [[CMP_IV_2_END:%.*]] = icmp uge i8* [[SRC_IV_2]], [[UPPER]]
-; CHECK-NEXT:    [[OR_3:%.*]] = or i1 [[CMP_IV_2_START]], [[CMP_IV_2_END]]
+; CHECK-NEXT:    [[OR_3:%.*]] = or i1 false, [[CMP_IV_2_END]]
 ; CHECK-NEXT:    br i1 [[OR_3]], label [[TRAP_BB]], label [[LOOP_LATCH]]
 ; CHECK:       loop.latch:
 ; CHECK-NEXT:    [[PTR:%.*]] = bitcast i8* [[SRC_IV]] to i32*
@@ -329,7 +329,7 @@ define void @test3(i8* %src, i8* %lower, i8* %upper, i8 %N) {
 ; CHECK-NEXT:    [[SRC_IV_2:%.*]] = getelementptr inbounds i8, i8* [[SRC]], i8 [[ADD_2]]
 ; CHECK-NEXT:    [[CMP_IV_2_START:%.*]] = icmp ult i8* [[SRC_IV_2]], [[LOWER]]
 ; CHECK-NEXT:    [[CMP_IV_2_END:%.*]] = icmp uge i8* [[SRC_IV_2]], [[UPPER]]
-; CHECK-NEXT:    [[OR_3:%.*]] = or i1 [[CMP_IV_2_START]], [[CMP_IV_2_END]]
+; CHECK-NEXT:    [[OR_3:%.*]] = or i1 false, [[CMP_IV_2_END]]
 ; CHECK-NEXT:    br i1 [[OR_3]], label [[TRAP_BB]], label [[LOOP_LATCH]]
 ; CHECK:       loop.latch:
 ; CHECK-NEXT:    [[PTR:%.*]] = bitcast i8* [[SRC_IV]] to i32*
@@ -418,7 +418,7 @@ define void @ne_check_in_loop_no_zext_n_may_be_negative(i8* %ptr, i8* %lower, i8
 ; CHECK-NEXT:    [[GEP_IV_1:%.*]] = getelementptr inbounds i8, i8* [[PTR]], i16 [[ADD]]
 ; CHECK-NEXT:    [[CMP_IV_1_LOWER:%.*]] = icmp ugt i8* [[LOWER]], [[GEP_IV_1]]
 ; CHECK-NEXT:    [[CMP_IV_1_UPPER:%.*]] = icmp ule i8* [[UPPER]], [[GEP_IV_1]]
-; CHECK-NEXT:    [[OR_1:%.*]] = or i1 [[CMP_IV_1_LOWER]], [[CMP_IV_1_UPPER]]
+; CHECK-NEXT:    [[OR_1:%.*]] = or i1 false, [[CMP_IV_1_UPPER]]
 ; CHECK-NEXT:    br i1 [[OR_1]], label [[TRAP]], label [[FOR_LATCH]]
 ; CHECK:       for.latch:
 ; CHECK-NEXT:    store i8 0, i8* [[GEP_IV]], align 4
@@ -502,7 +502,7 @@ define void @ne_check_in_loop_no_zext_n_positive_check(i8* %ptr, i8* %lower, i8*
 ; CHECK-NEXT:    [[GEP_IV_1:%.*]] = getelementptr inbounds i8, i8* [[PTR]], i16 [[ADD]]
 ; CHECK-NEXT:    [[CMP_IV_1_LOWER:%.*]] = icmp ugt i8* [[LOWER]], [[GEP_IV_1]]
 ; CHECK-NEXT:    [[CMP_IV_1_UPPER:%.*]] = icmp ule i8* [[UPPER]], [[GEP_IV_1]]
-; CHECK-NEXT:    [[OR_1:%.*]] = or i1 [[CMP_IV_1_LOWER]], [[CMP_IV_1_UPPER]]
+; CHECK-NEXT:    [[OR_1:%.*]] = or i1 false, [[CMP_IV_1_UPPER]]
 ; CHECK-NEXT:    br i1 [[OR_1]], label [[TRAP]], label [[FOR_LATCH]]
 ; CHECK:       for.latch:
 ; CHECK-NEXT:    store i8 0, i8* [[GEP_IV]], align 4
@@ -588,7 +588,7 @@ define void @ne_check_in_loop_with_zext(i8* %ptr, i8* %lower, i8* %upper, i8 %n)
 ; CHECK-NEXT:    [[GEP_IV_1:%.*]] = getelementptr inbounds i8, i8* [[PTR]], i16 [[ADD]]
 ; CHECK-NEXT:    [[CMP_IV_1_LOWER:%.*]] = icmp ugt i8* [[LOWER]], [[GEP_IV_1]]
 ; CHECK-NEXT:    [[CMP_IV_1_UPPER:%.*]] = icmp ule i8* [[UPPER]], [[GEP_IV_1]]
-; CHECK-NEXT:    [[OR_1:%.*]] = or i1 [[CMP_IV_1_LOWER]], [[CMP_IV_1_UPPER]]
+; CHECK-NEXT:    [[OR_1:%.*]] = or i1 false, [[CMP_IV_1_UPPER]]
 ; CHECK-NEXT:    br i1 [[OR_1]], label [[TRAP]], label [[FOR_LATCH]]
 ; CHECK:       for.latch:
 ; CHECK-NEXT:    store i8 0, i8* [[GEP_IV]], align 4


        


More information about the llvm-commits mailing list