[llvm] 6db71b8 - [ConstraintElim] Use helper to allow overflow for coefficients of GEPs

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 17 12:31:15 PDT 2022


Author: Florian Hahn
Date: 2022-10-17T20:30:43+01:00
New Revision: 6db71b8f1418170324b49d20f1f7b3f7c5086066

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

LOG: [ConstraintElim] Use helper to allow overflow for coefficients of GEPs

If the arithmetic for indices of inbounds GEPs overflows, the result is
poison. This means it is also OK for the coefficients to overflow. GEP
decomposition is limited to cases where the index size is <= 64 bit,
which can be represented by int64_t used for the coefficients in the
constraint system.

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 c208eb36449c9..2e59557a08971 100644
--- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
@@ -196,6 +196,13 @@ static int64_t multiplyWithOverflow(int64_t A, int64_t B) {
   return Result;
 }
 
+// A helper to add 2 signed integers where overflowing is allowed.
+static int64_t addWithOverflow(int64_t A, int64_t B) {
+  int64_t Result;
+  AddOverflow(A, B, Result);
+  return Result;
+}
+
 static SmallVector<DecompEntry, 4>
 decomposeGEP(GetElementPtrInst &GEP,
              SmallVector<PreconditionTy, 4> &Preconditions, bool IsSigned,
@@ -225,7 +232,9 @@ decomposeGEP(GetElementPtrInst &GEP,
     int64_t Scale = static_cast<int64_t>(
         DL.getTypeAllocSize(GTI.getIndexedType()).getFixedSize());
 
-    Result[0].Coefficient += multiplyWithOverflow(Scale, Offset.getSExtValue());
+    Result[0].Coefficient =
+        addWithOverflow(Result[0].Coefficient,
+                        multiplyWithOverflow(Scale, Offset.getSExtValue()));
     if (Offset.isNegative()) {
       // Add pre-condition ensuring the GEP is increasing monotonically and
       // can be de-composed.
@@ -257,8 +266,9 @@ decomposeGEP(GetElementPtrInst &GEP,
         continue;
 
       // Add offset to constant factor.
-      Result[0].Coefficient +=
-          DL.getStructLayout(STy)->getElementOffset(FieldNo);
+      Result[0].Coefficient = addWithOverflow(
+          Result[0].Coefficient,
+          int64_t(DL.getStructLayout(STy)->getElementOffset(FieldNo)));
       continue;
     }
 

diff  --git a/llvm/test/Transforms/ConstraintElimination/large-constant-ints.ll b/llvm/test/Transforms/ConstraintElimination/large-constant-ints.ll
index 9c65f0ec10a4c..ac4b32443962b 100644
--- a/llvm/test/Transforms/ConstraintElimination/large-constant-ints.ll
+++ b/llvm/test/Transforms/ConstraintElimination/large-constant-ints.ll
@@ -350,4 +350,54 @@ entry:
   ret i1 %res
 }
 
+define i1 @gep_decomp_large_index_63_bits_chained_overflow(ptr %a) {
+; CHECK-LABEL: @gep_decomp_large_index_63_bits_chained_overflow(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr inbounds i64, ptr [[A:%.*]], i64 9223372036854775804
+; CHECK-NEXT:    [[GEP_2:%.*]] = getelementptr inbounds ptr, ptr [[A]], i64 1152921504606846976
+; CHECK-NEXT:    [[GEP_3:%.*]] = getelementptr inbounds i64, ptr [[GEP_2]], i64 1152921504606846976
+; CHECK-NEXT:    [[NE:%.*]] = icmp ne ptr [[GEP_1]], [[GEP_3]]
+; CHECK-NEXT:    call void @llvm.assume(i1 [[NE]])
+; CHECK-NEXT:    [[CMP_ULE:%.*]] = icmp ule ptr [[GEP_1]], [[GEP_3]]
+; CHECK-NEXT:    [[CMP_UGE:%.*]] = icmp uge ptr [[GEP_1]], [[GEP_3]]
+; CHECK-NEXT:    [[RES:%.*]] = xor i1 true, true
+; CHECK-NEXT:    ret i1 [[RES]]
+;
+entry:
+  %gep.1 = getelementptr inbounds i64, ptr %a, i64 9223372036854775804
+  %gep.2 = getelementptr inbounds ptr, ptr %a, i64 1152921504606846976
+  %gep.3 = getelementptr inbounds i64, ptr %gep.2, i64 1152921504606846976
+  %ne = icmp ne ptr %gep.1, %gep.3
+  call void @llvm.assume(i1 %ne)
+  %cmp.ule = icmp ule ptr %gep.1, %gep.3
+  %cmp.uge = icmp uge ptr %gep.1, %gep.3
+  %res = xor i1 %cmp.ule, %cmp.ule
+  ret i1 %res
+}
+
+%struct = type { [128 x i64], [2 x i32] }
+
+define i1 @gep_decomp_large_index_63_bits_overflow_struct(ptr %a) {
+; CHECK-LABEL: @gep_decomp_large_index_63_bits_overflow_struct(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr inbounds i64, ptr [[A:%.*]], i64 9223372036854775804
+; CHECK-NEXT:    [[GEP_2:%.*]] = getelementptr inbounds [[STRUCT:%.*]], ptr [[A]], i64 8937376004704240, i32 1, i32 1
+; CHECK-NEXT:    [[NE:%.*]] = icmp ne ptr [[GEP_1]], [[GEP_2]]
+; 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 false, false
+; CHECK-NEXT:    ret i1 [[RES]]
+;
+entry:
+  %gep.1 = getelementptr inbounds i64, ptr %a, i64 9223372036854775804
+  %gep.2 = getelementptr inbounds %struct, ptr %a, i64 8937376004704240, i32 1, i32 1
+  %ne = icmp ne ptr %gep.1, %gep.2
+  call void @llvm.assume(i1 %ne)
+  %cmp.ule = icmp ule ptr %gep.1, %gep.2
+  %cmp.uge = icmp uge ptr %gep.1, %gep.2
+  %res = xor i1 %cmp.ule, %cmp.ule
+  ret i1 %res
+}
+
 declare void @llvm.assume(i1)


        


More information about the llvm-commits mailing list