[llvm] 359bc5c - [ConstraintElim] Bail out for GEPs when index size > 64 bits.

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 13 02:19:52 PDT 2022


Author: Florian Hahn
Date: 2022-10-13T10:19:30+01:00
New Revision: 359bc5c541ae4b02ad74bb9a9c3cb64e61464a4a

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

LOG: [ConstraintElim] Bail out for GEPs when index size > 64 bits.

Limit pointer decomposition to pointers with index sizes of at most 64
bits. int64_t is used for coefficients, so as long as the index size <=
64 bits we should be able to represent all pointer offsets.

Pointer decomposition is limited to inbounds GEPs, so if a index
computation would overflow the result is poison, so it doesn't matter
that the coefficient overflows.

This allows replacing MulOverflow with regular multiplications.

Added: 
    

Modified: 
    llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
    llvm/test/Transforms/ConstraintElimination/large-constant-ints.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
index 6e47ae57625f9..210347a9936ef 100644
--- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
@@ -193,6 +193,13 @@ static SmallVector<DecompEntry, 4>
 decomposeGEP(GetElementPtrInst &GEP,
              SmallVector<PreconditionTy, 4> &Preconditions, bool IsSigned,
              const DataLayout &DL) {
+  // Do not reason about pointers where the index size is larger than 64 bits,
+  // as the coefficients used to encode constraints are 64 bit integers.
+  unsigned AS =
+      cast<PointerType>(GEP.getPointerOperand()->getType())->getAddressSpace();
+  if (DL.getIndexSizeInBits(AS) > 64)
+    return {};
+
   auto GTI = gep_type_begin(GEP);
   if (GEP.getNumOperands() != 2 || !GEP.isInBounds() ||
       isa<ScalableVectorType>(GTI.getIndexedType()))
@@ -200,7 +207,6 @@ decomposeGEP(GetElementPtrInst &GEP,
 
   int64_t Scale = static_cast<int64_t>(
       DL.getTypeAllocSize(GTI.getIndexedType()).getFixedSize());
-  int64_t MulRes;
   // 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());
@@ -208,52 +214,53 @@ decomposeGEP(GetElementPtrInst &GEP,
       isa<ConstantInt>(GEP.getOperand(1))) {
     APInt Offset = cast<ConstantInt>(GEP.getOperand(1))->getValue();
     auto Result = decompose(InnerGEP, Preconditions, IsSigned, DL);
-    if (!MulOverflow(Scale, Offset.getSExtValue(), MulRes)) {
-      Result[0].Coefficient += MulRes;
-      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;
+    Result[0].Coefficient += Scale * 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;
   }
 
   Value *Op0, *Op1;
   ConstantInt *CI;
   // If the index is zero-extended, it is guaranteed to be positive.
   if (match(GEP.getOperand(GEP.getNumOperands() - 1), m_ZExt(m_Value(Op0)))) {
-    if (match(Op0, m_NUWShl(m_Value(Op1), m_ConstantInt(CI))) &&
-        canUseSExt(CI) &&
-        !MulOverflow(Scale, int64_t(std::pow(int64_t(2), CI->getSExtValue())),
-                     MulRes))
-      return {{0, nullptr}, {1, GEP.getPointerOperand()}, {MulRes, Op1}};
+    if (match(Op0, m_NUWShl(m_Value(Op1), m_ConstantInt(CI))) && canUseSExt(CI))
+      return {{0, nullptr},
+              {1, GEP.getPointerOperand()},
+              {Scale * int64_t(std::pow(int64_t(2), CI->getSExtValue())), Op1}};
     if (match(Op0, m_NSWAdd(m_Value(Op1), m_ConstantInt(CI))) &&
-        canUseSExt(CI) && match(Op0, m_NUWAdd(m_Value(), m_Value())) &&
-        !MulOverflow(Scale, CI->getSExtValue(), MulRes))
-      return {{MulRes, nullptr}, {1, GEP.getPointerOperand()}, {Scale, Op1}};
+        canUseSExt(CI) && match(Op0, m_NUWAdd(m_Value(), m_Value())))
+      return {{Scale * CI->getSExtValue(), nullptr},
+              {1, GEP.getPointerOperand()},
+              {Scale, Op1}};
+
     return {{0, nullptr}, {1, GEP.getPointerOperand()}, {Scale, Op0, true}};
   }
 
   if (match(GEP.getOperand(GEP.getNumOperands() - 1), m_ConstantInt(CI)) &&
-      !CI->isNegative() && canUseSExt(CI) &&
-      !MulOverflow(Scale, CI->getSExtValue(), MulRes))
-    return {{MulRes, nullptr}, {1, GEP.getPointerOperand()}};
+      !CI->isNegative() && canUseSExt(CI))
+    return {{Scale * CI->getSExtValue(), nullptr},
+            {1, GEP.getPointerOperand()}};
 
   SmallVector<DecompEntry, 4> Result;
   if (match(GEP.getOperand(GEP.getNumOperands() - 1),
             m_NSWShl(m_Value(Op0), m_ConstantInt(CI))) &&
-      canUseSExt(CI) &&
-      !MulOverflow(Scale, int64_t(std::pow(int64_t(2), CI->getSExtValue())),
-                   MulRes))
-    Result = {{0, nullptr}, {1, GEP.getPointerOperand()}, {MulRes, Op0}};
+      canUseSExt(CI))
+    Result = {{0, nullptr},
+              {1, GEP.getPointerOperand()},
+              {Scale * int64_t(std::pow(int64_t(2), CI->getSExtValue())), Op0}};
   else if (match(GEP.getOperand(GEP.getNumOperands() - 1),
                  m_NSWAdd(m_Value(Op0), m_ConstantInt(CI))) &&
-           canUseSExt(CI) && !MulOverflow(Scale, CI->getSExtValue(), MulRes))
-    Result = {{MulRes, nullptr}, {1, GEP.getPointerOperand()}, {Scale, Op0}};
+           canUseSExt(CI))
+    Result = {{Scale * CI->getSExtValue(), nullptr},
+              {1, GEP.getPointerOperand()},
+              {Scale, Op0}};
   else {
     Op0 = GEP.getOperand(GEP.getNumOperands() - 1);
     Result = {{0, nullptr}, {1, GEP.getPointerOperand()}, {Scale, Op0}};

diff  --git a/llvm/test/Transforms/ConstraintElimination/large-constant-ints.ll b/llvm/test/Transforms/ConstraintElimination/large-constant-ints.ll
index 411a0fe05502a..32c53833975d6 100644
--- a/llvm/test/Transforms/ConstraintElimination/large-constant-ints.ll
+++ b/llvm/test/Transforms/ConstraintElimination/large-constant-ints.ll
@@ -336,7 +336,7 @@ define i1 @gep_decomp_large_index_63_bits(ptr %a) {
 ; CHECK-NEXT:    call void @llvm.assume(i1 [[NE]])
 ; CHECK-NEXT:    [[CMP_ULE:%.*]] = icmp ule ptr [[GEP_1]], [[GEP_2]]
 ; CHECK-NEXT:    [[CMP_UGE:%.*]] = icmp uge ptr [[GEP_1]], [[GEP_2]]
-; CHECK-NEXT:    [[RES:%.*]] = xor i1 [[CMP_ULE]], [[CMP_ULE]]
+; CHECK-NEXT:    [[RES:%.*]] = xor i1 true, true
 ; CHECK-NEXT:    ret i1 [[RES]]
 ;
 entry:


        


More information about the llvm-commits mailing list