[llvm] ee605b0 - [ConstraintElim] Use collectOffset result for chained gep support.

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 1 09:01:26 PST 2022


Author: Florian Hahn
Date: 2022-12-01T17:01:07Z
New Revision: ee605b0acccea92bb2375921955008e1d6ca22d2

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

LOG: [ConstraintElim] Use collectOffset result for chained gep support.

This slightly simplifies the code and addresses a correctness issue
where the index scaling for the precondition was not considered
properly.

Thanks to @nikic for pointing that out in D137840.

Added: 
    

Modified: 
    llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
    llvm/test/Transforms/ConstraintElimination/gep-add-multiple-indices.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 f823a38ca14b0..dd0abe223afab 100644
--- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
@@ -243,40 +243,36 @@ decomposeGEP(GetElementPtrInst &GEP,
   if (!GEP.isInBounds())
     return &GEP;
 
+  Type *PtrTy = GEP.getType()->getScalarType();
+  unsigned BitWidth = DL.getIndexTypeSizeInBits(PtrTy);
+  MapVector<Value *, APInt> VariableOffsets;
+  APInt ConstantOffset(BitWidth, 0);
+  if (!GEP.collectOffset(DL, BitWidth, VariableOffsets, ConstantOffset))
+    return &GEP;
+
   // 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 && GEP.getNumOperands() == 2 &&
-      isa<ConstantInt>(GEP.getOperand(1))) {
-    APInt Offset = cast<ConstantInt>(GEP.getOperand(1))->getValue();
+  if (VariableOffsets.empty() && InnerGEP && InnerGEP->getNumOperands() == 2) {
     auto Result = decompose(InnerGEP, Preconditions, IsSigned, DL);
+    Result.add(ConstantOffset.getSExtValue());
 
-    auto GTI = gep_type_begin(GEP);
-    // Bail out for scalable vectors for now.
-    if (isa<ScalableVectorType>(GTI.getIndexedType()))
-      return &GEP;
-    int64_t Scale = static_cast<int64_t>(
-        DL.getTypeAllocSize(GTI.getIndexedType()).getFixedSize());
-
-    Result.add(multiplyWithOverflow(Scale, Offset.getSExtValue()));
-    if (Offset.isNegative()) {
+    if (ConstantOffset.isNegative()) {
+      unsigned Scale = DL.getTypeAllocSize(InnerGEP->getResultElementType());
+      int64_t ConstantOffsetI = ConstantOffset.getSExtValue();
+      if (ConstantOffsetI % Scale != 0)
+        return &GEP;
       // Add pre-condition ensuring the GEP is increasing monotonically and
       // can be de-composed.
+      // Both sides are normalized by being divided by Scale.
       Preconditions.emplace_back(
           CmpInst::ICMP_SGE, InnerGEP->getOperand(1),
           ConstantInt::get(InnerGEP->getOperand(1)->getType(),
-                           -1 * Offset.getSExtValue()));
+                           -1 * (ConstantOffsetI / Scale)));
     }
     return Result;
   }
 
-  Type *PtrTy = GEP.getType()->getScalarType();
-  unsigned BitWidth = DL.getIndexTypeSizeInBits(PtrTy);
-  MapVector<Value *, APInt> VariableOffsets;
-  APInt ConstantOffset(BitWidth, 0);
-  if (!GEP.collectOffset(DL, BitWidth, VariableOffsets, ConstantOffset))
-    return &GEP;
-
   Decomposition Result(ConstantOffset.getSExtValue(),
                        DecompEntry(1, GEP.getPointerOperand()));
   for (auto [Index, Scale] : VariableOffsets) {

diff  --git a/llvm/test/Transforms/ConstraintElimination/gep-add-multiple-indices.ll b/llvm/test/Transforms/ConstraintElimination/gep-add-multiple-indices.ll
index c85841b4c68d2..ef899c5c8282a 100644
--- a/llvm/test/Transforms/ConstraintElimination/gep-add-multiple-indices.ll
+++ b/llvm/test/Transforms/ConstraintElimination/gep-add-multiple-indices.ll
@@ -9,7 +9,7 @@ define i1 @test_outer_gep_last_index_no_overflow_all_inbounds_1(ptr %dst) {
 ; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds ptr, ptr [[DST]], i64 2
 ; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST_0]], i64 1, i64 1
 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ult ptr [[GEP_1]], [[UPPER]]
-; CHECK-NEXT:    ret i1 [[C_1]]
+; CHECK-NEXT:    ret i1 true
 ;
   %dst.0 = getelementptr inbounds ptr, ptr %dst, i64 0
   %upper = getelementptr inbounds ptr, ptr %dst, i64 2
@@ -24,7 +24,7 @@ define i1 @test_outer_gep_last_index_no_overflow_all_inbounds_2(ptr %dst) {
 ; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds ptr, ptr [[DST]], i64 3
 ; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST_0]], i64 1, i64 1
 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ult ptr [[GEP_1]], [[UPPER]]
-; CHECK-NEXT:    ret i1 [[C_1]]
+; CHECK-NEXT:    ret i1 true
 ;
   %dst.0 = getelementptr inbounds ptr, ptr %dst, i64 0
   %upper = getelementptr inbounds ptr, ptr %dst, i64 3
@@ -39,7 +39,7 @@ define i1 @test_outer_gep_last_index_overflow_all_inbounds(ptr %dst) {
 ; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds ptr, ptr [[DST]], i64 2
 ; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST_0]], i64 1, i64 2
 ; CHECK-NEXT:    [[C:%.*]] = icmp ult ptr [[GEP_1]], [[UPPER]]
-; CHECK-NEXT:    ret i1 [[C]]
+; CHECK-NEXT:    ret i1 false
 ;
   %dst.0 = getelementptr inbounds ptr, ptr %dst, i64 0
   %upper = getelementptr inbounds ptr, ptr %dst, i64 2
@@ -54,7 +54,7 @@ define i1 @test_inner_gep_multiple_indices_ult_true_all_inbounds(ptr %dst) {
 ; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST]], i64 0, i64 2
 ; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[DST_0]], i64 1
 ; CHECK-NEXT:    [[C:%.*]] = icmp ult ptr [[GEP_1]], [[UPPER]]
-; CHECK-NEXT:    ret i1 true
+; CHECK-NEXT:    ret i1 [[C]]
 ;
   %dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 0
   %upper = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 2
@@ -69,7 +69,7 @@ define i1 @test_inner_gep_multiple_indices_uge_true_all_inbounds(ptr %dst) {
 ; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST]], i64 0, i64 2
 ; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[DST_0]], i64 1
 ; CHECK-NEXT:    [[C:%.*]] = icmp uge ptr [[GEP_1]], [[DST_0]]
-; CHECK-NEXT:    ret i1 true
+; CHECK-NEXT:    ret i1 [[C]]
 ;
   %dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 0
   %upper = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 2
@@ -85,7 +85,7 @@ define i1 @test_inner_gep_multiple_indices_ult_false_all_inbounds(ptr %dst) {
 ; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST]], i64 0, i64 2
 ; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[DST_0]], i64 2
 ; CHECK-NEXT:    [[C:%.*]] = icmp ult ptr [[GEP_1]], [[UPPER]]
-; CHECK-NEXT:    ret i1 false
+; CHECK-NEXT:    ret i1 [[C]]
 ;
 entry:
   %dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 0
@@ -102,7 +102,7 @@ define i1 @test_inner_gep_multiple_indices_uge_true_all_inbounds_2(ptr %dst) {
 ; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST]], i64 0, i64 2
 ; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[DST_0]], i64 2
 ; CHECK-NEXT:    [[C:%.*]] = icmp uge ptr [[GEP_1]], [[DST_0]]
-; CHECK-NEXT:    ret i1 true
+; CHECK-NEXT:    ret i1 [[C]]
 ;
 entry:
   %dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 0
@@ -203,7 +203,7 @@ define i1 @test_inner_gep_multi_index(ptr %dst) {
 ; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds ptr, ptr [[DST]], i64 2
 ; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr inbounds [2 x i32], ptr [[DST_0]], i64 1, i64 1
 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ult ptr [[GEP_1]], [[UPPER]]
-; CHECK-NEXT:    ret i1 [[C_1]]
+; CHECK-NEXT:    ret i1 true
 ;
   %dst.0 = getelementptr inbounds ptr, ptr %dst, i64 0
   %upper = getelementptr inbounds ptr, ptr %dst, i64 2
@@ -233,7 +233,7 @@ define i1 @test_inner_gep_multi_index_no_overflow_all_inbounds_1(ptr %dst) {
 ; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 2
 ; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[DST_0]], i64 1
 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ult ptr [[GEP_1]], [[UPPER]]
-; CHECK-NEXT:    ret i1 false
+; CHECK-NEXT:    ret i1 [[C_1]]
 ;
   %dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 0, i64 1
   %upper = getelementptr inbounds i32, ptr %dst, i64 2
@@ -248,7 +248,7 @@ define i1 @test_inner_gep_multi_index_no_overflow_all_inbounds_2(ptr %dst) {
 ; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 2
 ; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[DST_0]], i64 1
 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ult ptr [[GEP_1]], [[UPPER]]
-; CHECK-NEXT:    ret i1 false
+; CHECK-NEXT:    ret i1 [[C_1]]
 ;
   %dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 1, i64 0
   %upper = getelementptr inbounds i32, ptr %dst, i64 2
@@ -263,7 +263,7 @@ define i1 @test_inner_gep_multi_index_no_overflow_all_inbounds_3(ptr %dst) {
 ; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 3
 ; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[DST_0]], i64 1
 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ult ptr [[GEP_1]], [[UPPER]]
-; CHECK-NEXT:    ret i1 false
+; CHECK-NEXT:    ret i1 [[C_1]]
 ;
   %dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 1, i64 0
   %upper = getelementptr inbounds i32, ptr %dst, i64 3
@@ -278,7 +278,7 @@ define i1 @test_inner_gep_multi_index_no_overflow_all_inbounds_4(ptr %dst) {
 ; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 4
 ; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[DST_0]], i64 1
 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ult ptr [[GEP_1]], [[UPPER]]
-; CHECK-NEXT:    ret i1 true
+; CHECK-NEXT:    ret i1 [[C_1]]
 ;
   %dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 1, i64 0
   %upper = getelementptr inbounds i32, ptr %dst, i64 4
@@ -294,7 +294,7 @@ define i1 @test_inner_gep_multi_index_no_overflow_all_inbounds_5(i64 %off, ptr %
 ; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 5
 ; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[DST_0]], i64 1
 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ule ptr [[GEP_1]], [[UPPER]]
-; CHECK-NEXT:    ret i1 true
+; CHECK-NEXT:    ret i1 [[C_1]]
 ;
   %off.ult = icmp ule i64 %off, 2
   %dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 2, i64 0
@@ -311,7 +311,7 @@ define i1 @test_inner_gep_multi_index_no_overflow_all_inbounds_6(i64 %off, ptr %
 ; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 5
 ; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[DST_0]], i64 1
 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ult ptr [[GEP_1]], [[UPPER]]
-; CHECK-NEXT:    ret i1 false
+; CHECK-NEXT:    ret i1 [[C_1]]
 ;
   %off.ult = icmp ule i64 %off, 2
   %dst.0 = getelementptr inbounds [2 x i32], ptr %dst, i64 2, i64 0

diff  --git a/llvm/test/Transforms/ConstraintElimination/gep-sub.ll b/llvm/test/Transforms/ConstraintElimination/gep-sub.ll
index be83e7b91a4d7..b499e280c1e37 100644
--- a/llvm/test/Transforms/ConstraintElimination/gep-sub.ll
+++ b/llvm/test/Transforms/ConstraintElimination/gep-sub.ll
@@ -529,7 +529,7 @@ define i1 @gep_i16_sub_1_uge_inbounds(ptr %dst, ptr %lower) {
 ; CHECK-NEXT:    [[CMP_SUB_1:%.*]] = icmp ule ptr [[DST_SUB_1]], [[LOWER]]
 ; CHECK-NEXT:    [[DST_SUB_2:%.*]] = getelementptr inbounds i16, ptr [[DST_ADD_3]], i64 -2
 ; CHECK-NEXT:    [[CMP_SUB_2:%.*]] = icmp ule ptr [[DST_SUB_2]], [[DST]]
-; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 false, true
+; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 false, [[CMP_SUB_2]]
 ; CHECK-NEXT:    [[DST_SUB_3:%.*]] = getelementptr inbounds i16, ptr [[DST_ADD_3]], i64 -3
 ; CHECK-NEXT:    [[CMP_SUB_3:%.*]] = icmp ule ptr [[DST_SUB_3]], [[LOWER]]
 ; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_SUB_3]]


        


More information about the llvm-commits mailing list