[ConstraintElim] Use collectOffset instead of custom GEP idx iteration.
authorFlorian Hahn <flo@fhahn.com>
Mon, 28 Nov 2022 16:54:58 +0000 (16:54 +0000)
committerFlorian Hahn <flo@fhahn.com>
Mon, 28 Nov 2022 16:54:58 +0000 (16:54 +0000)
Use collectOffset to collect scaled indices and constant offset for GEP
instead of custom code. This simplifies the logic in decomposeGEP and
allows to handle all cases supported by the generic helper.

llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
llvm/test/Transforms/ConstraintElimination/constants-unsigned-predicates.ll
llvm/test/Transforms/ConstraintElimination/gep-arithmetic.ll

index 624420a..f823a38 100644 (file)
@@ -270,34 +270,18 @@ decomposeGEP(GetElementPtrInst &GEP,
     return Result;
   }
 
-  Decomposition Result = GEP.getPointerOperand();
-  gep_type_iterator GTI = gep_type_begin(GEP);
-  for (User::const_op_iterator I = GEP.op_begin() + 1, E = GEP.op_end(); I != E;
-       ++I, ++GTI) {
-    Value *Index = *I;
-
-    // Bail out for scalable vectors for now.
-    if (isa<ScalableVectorType>(GTI.getIndexedType()))
-      return &GEP;
-
-    // Struct indices must be constants (and reference an existing field). Add
-    // them to the constant factor.
-    if (StructType *STy = GTI.getStructTypeOrNull()) {
-      // For a struct, add the member offset.
-      unsigned FieldNo = cast<ConstantInt>(Index)->getZExtValue();
-      if (FieldNo == 0)
-        continue;
-
-      // Add offset to constant factor.
-      Result.add(int64_t(DL.getStructLayout(STy)->getElementOffset(FieldNo)));
-      continue;
-    }
-
-    // For an array/pointer, add the element offset, explicitly scaled.
-    unsigned Scale = DL.getTypeAllocSize(GTI.getIndexedType()).getFixedSize();
+  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) {
     auto IdxResult = decompose(Index, Preconditions, IsSigned, DL);
-    IdxResult.mul(Scale);
+    IdxResult.mul(Scale.getSExtValue());
     Result.add(IdxResult);
 
     // If Op0 is signed non-negative, the GEP is increasing monotonically and
index e6aa6f6..86c7dd3 100644 (file)
@@ -52,7 +52,7 @@ define i1 @test_ult_gep_2(ptr %base) {
 ; CHECK-LABEL: @test_ult_gep_2(
 ; CHECK-NEXT:    [[GEP_SUB_1:%.*]] = getelementptr inbounds i8, ptr [[BASE:%.*]], i8 -1
 ; CHECK-NEXT:    [[C_1:%.*]] = icmp ult ptr [[BASE]], [[GEP_SUB_1]]
-; CHECK-NEXT:    ret i1 [[C_1]]
+; CHECK-NEXT:    ret i1 false
 ;
   %gep.sub.1 = getelementptr inbounds i8, ptr %base, i8 -1
   %c.1 = icmp ult ptr %base, %gep.sub.1
index fbbb37f..2978b83 100644 (file)
@@ -81,12 +81,12 @@ define i1 @gep_constant_negative_index(ptr %dst, ptr %lower, ptr %upper) {
 ; CHECK-NEXT:    [[CMP_DST_SUB_4_LOWER:%.*]] = icmp uge ptr [[DST_SUB_4]], [[LOWER]]
 ; CHECK-NEXT:    [[CMP_DST_SUB_4_UPPER:%.*]] = icmp ult ptr [[DST_SUB_4]], [[UPPER]]
 ; CHECK-NEXT:    [[RES_4:%.*]] = xor i1 [[RES_3]], [[CMP_DST_SUB_4_LOWER]]
-; CHECK-NEXT:    [[RES_5:%.*]] = xor i1 [[RES_4]], [[CMP_DST_SUB_4_UPPER]]
+; CHECK-NEXT:    [[RES_5:%.*]] = xor i1 [[RES_4]], true
 ; CHECK-NEXT:    [[DST_SUB_5:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 -5
 ; CHECK-NEXT:    [[CMP_DST_SUB_5_LOWER:%.*]] = icmp uge ptr [[DST_SUB_5]], [[LOWER]]
 ; CHECK-NEXT:    [[CMP_DST_SUB_5_UPPER:%.*]] = icmp ult ptr [[DST_SUB_5]], [[UPPER]]
 ; CHECK-NEXT:    [[RES_6:%.*]] = xor i1 [[RES_5]], [[CMP_DST_SUB_5_LOWER]]
-; CHECK-NEXT:    [[RES_7:%.*]] = xor i1 [[RES_6]], [[CMP_DST_SUB_5_UPPER]]
+; CHECK-NEXT:    [[RES_7:%.*]] = xor i1 [[RES_6]], true
 ; CHECK-NEXT:    ret i1 [[RES_7]]
 ; CHECK:       else:
 ; CHECK-NEXT:    [[ELSE_CMP_DST_LOWER:%.*]] = icmp uge ptr [[DST]], [[LOWER]]