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
; 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
; 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]]