[ConstraintElim] Replace custom GEP index handling by using existing code
authorFlorian Hahn <flo@fhahn.com>
Sun, 16 Oct 2022 20:53:11 +0000 (21:53 +0100)
committerFlorian Hahn <flo@fhahn.com>
Sun, 16 Oct 2022 20:53:11 +0000 (21:53 +0100)
Instead of duplicating the existing decomposition code for GEP indices
just use the existing code by calling the existing decompose function on
the index expression and multiply the result's coefficients by the scale of
the index.

This both reduces code duplication and generalizes the pattern we can
handle.

llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
llvm/test/Transforms/ConstraintElimination/gep-arithmetic-different-types.ll
llvm/test/Transforms/ConstraintElimination/geps-unsigned-predicates.ll
llvm/test/Transforms/ConstraintElimination/large-constant-ints.ll

index db1da1fd8e70f53d63adb2f712868b81ce168947..1be235898be718d6a64ff091eba8eef97343f9a4 100644 (file)
@@ -265,55 +265,20 @@ decomposeGEP(GetElementPtrInst &GEP,
     // For an array/pointer, add the element offset, explicitly scaled.
     unsigned Scale = DL.getTypeAllocSize(GTI.getIndexedType()).getFixedSize();
 
-    Value *Op0, *Op1;
-    ConstantInt *CI;
-    // If the index is zero-extended, it is guaranteed to be positive.
-    if (match(Index, m_ZExt(m_Value(Op0)))) {
-      if (match(Op0, m_NUWShl(m_Value(Op1), m_ConstantInt(CI))) &&
-          canUseSExt(CI)) {
-        Result.emplace_back(
-            multiplyWithOverflow(
-                Scale, int64_t(std::pow(int64_t(2), CI->getSExtValue()))),
-            Op1);
-        continue;
-      }
-
-      if (match(Op0, m_NSWAdd(m_Value(Op1), m_ConstantInt(CI))) &&
-          canUseSExt(CI) && match(Op0, m_NUWAdd(m_Value(), m_Value()))) {
-        Result[0].Coefficient +=
-            multiplyWithOverflow(Scale, CI->getSExtValue());
-        Result.emplace_back(Scale, Op1);
-        continue;
-      }
-
-      Result.emplace_back(Scale, Op0, true);
-      continue;
-    }
-
-    if (match(Index, m_ConstantInt(CI)) && !CI->isNegative() &&
-        canUseSExt(CI)) {
-      Result[0].Coefficient += multiplyWithOverflow(Scale, CI->getSExtValue());
-      continue;
-    }
-
-    if (match(Index, m_NSWShl(m_Value(Op0), m_ConstantInt(CI))) &&
-        canUseSExt(CI)) {
-      Result.emplace_back(
-          multiplyWithOverflow(
-              Scale, int64_t(std::pow(int64_t(2), CI->getSExtValue()))),
-          Op0);
-    } else if (match(Index, m_NSWAdd(m_Value(Op0), m_ConstantInt(CI))) &&
-               canUseSExt(CI)) {
-      Result[0].Coefficient += multiplyWithOverflow(Scale, CI->getSExtValue());
-      Result.emplace_back(Scale, Op0);
+    auto IdxResult = decompose(Index, Preconditions, IsSigned, DL);
+    if (IdxResult.empty()) {
+      Result.emplace_back(Scale, Index);
     } else {
-      Op0 = Index;
-      Result.emplace_back(Scale, Op0);
+      for (auto &KV : IdxResult)
+        KV.Coefficient *= Scale;
+      Result[0].Coefficient += IdxResult[0].Coefficient;
+      append_range(Result, ArrayRef<DecompEntry>(IdxResult).drop_front());
     }
     // If Op0 is signed non-negative, the GEP is increasing monotonically and
     // can be de-composed.
-    Preconditions.emplace_back(CmpInst::ICMP_SGE, Op0,
-                               ConstantInt::get(Op0->getType(), 0));
+    if (!isKnownNonNegative(Index, DL, /*Depth=*/MaxAnalysisRecursionDepth - 1))
+      Preconditions.emplace_back(CmpInst::ICMP_SGE, Index,
+                                 ConstantInt::get(Index->getType(), 0));
   }
   return Result;
 }
index 3cc3e03eedf1700d08b76a630812f0ccbe378041..149a9bc35b42158d6dd67088324b457a8bc3b75c 100644 (file)
@@ -136,7 +136,7 @@ define i1 @gep_shl_nsw_positive_index(ptr %A, ptr %upper, i8 %idx) {
 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ult ptr [[ADD_I32_IDX_1]], [[UPPER]]
 ; CHECK-NEXT:    [[ADD_I8_IDX_1:%.*]] = getelementptr inbounds i8, ptr [[A]], i8 [[IDX_1]]
 ; CHECK-NEXT:    [[T_1:%.*]] = icmp ult ptr [[ADD_I8_IDX_1]], [[UPPER]]
-; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 [[C_1]], true
+; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 [[C_1]], [[T_1]]
 ; CHECK-NEXT:    ret i1 [[RES_1]]
 ;
   %idx.pos = icmp sge i8 %idx, 0
@@ -208,7 +208,7 @@ define i1 @gep_zext_add_nuw_index(ptr %A, ptr %upper, i8 %idx) {
 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ult ptr [[ADD_I32_IDX_1]], [[UPPER]]
 ; CHECK-NEXT:    [[ADD_I8_IDX_1:%.*]] = getelementptr inbounds i8, ptr [[A]], i16 [[IDX_1_EXT]]
 ; CHECK-NEXT:    [[T_1:%.*]] = icmp ult ptr [[ADD_I8_IDX_1]], [[UPPER]]
-; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 [[C_1]], [[T_1]]
+; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 [[C_1]], true
 ; CHECK-NEXT:    ret i1 [[RES_1]]
 ;
   %idx.2 = add nuw i8 %idx, 2
index 51eb96c38c1c8297062f8448ec2e16ae76acd55f..524a13fadf66141d6a379f21970795fe313002c0 100644 (file)
@@ -513,7 +513,7 @@ define void @test.ult.gep.shl(ptr readonly %src, ptr readnone %max, i8 %idx) {
 ; CHECK-NEXT:    [[IDX_SHL_1:%.*]] = shl nuw nsw i8 [[IDX]], 1
 ; CHECK-NEXT:    [[ADD_PTR_SHL_1:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i8 [[IDX_SHL_1]]
 ; CHECK-NEXT:    [[C_MAX_0:%.*]] = icmp ult ptr [[ADD_PTR_SHL_1]], [[MAX]]
-; CHECK-NEXT:    call void @use(i1 true)
+; CHECK-NEXT:    call void @use(i1 [[C_MAX_0]])
 ; CHECK-NEXT:    [[IDX_SHL_2:%.*]] = shl nuw i8 [[IDX]], 2
 ; CHECK-NEXT:    [[ADD_PTR_SHL_2:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i8 [[IDX_SHL_2]]
 ; CHECK-NEXT:    [[C_MAX_1:%.*]] = icmp ult ptr [[ADD_PTR_SHL_2]], [[MAX]]
index 32c53833975d6fb0c653d3308e9bc1a57846ea8d..9c65f0ec10a4c87ba471ea98b99a1970c10d6e2b 100644 (file)
@@ -132,7 +132,7 @@ define i1 @gep_decomp_i80(ptr %a) {
 ; CHECK:       then:
 ; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr inbounds i8, ptr [[A]], i80 1973801615886922022913
 ; CHECK-NEXT:    [[C_1:%.*]] = icmp eq ptr [[GEP_1]], null
-; CHECK-NEXT:    ret i1 [[C_1]]
+; CHECK-NEXT:    ret i1 true
 ; CHECK:       else:
 ; CHECK-NEXT:    ret i1 false
 ;