xref: /llvm-project/llvm/test/Transforms/ConstraintElimination/gep-sub.ll (revision d045e23c2d00a445e40a8c97471df023d8364f59)
122fe4006SFlorian Hahn; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
222fe4006SFlorian Hahn; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
322fe4006SFlorian Hahn
422fe4006SFlorian Hahndeclare void @llvm.assume(i1 noundef)
522fe4006SFlorian Hahn
61ae40514SFlorian Hahndefine i1 @gep_sub_1_uge_inbounds(ptr %dst, ptr %lower) {
71ae40514SFlorian Hahn; CHECK-LABEL: @gep_sub_1_uge_inbounds(
822fe4006SFlorian Hahn; CHECK-NEXT:    [[PRE:%.*]] = icmp uge ptr [[DST:%.*]], [[LOWER:%.*]]
922fe4006SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[PRE]])
1022fe4006SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 3
1122fe4006SFlorian Hahn; CHECK-NEXT:    [[DST_SUB_1:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_3]], i64 -1
1222fe4006SFlorian Hahn; CHECK-NEXT:    [[DST_SUB_3:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_3]], i64 -3
13e0136a62SFlorian Hahn; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 true, true
1422fe4006SFlorian Hahn; CHECK-NEXT:    [[DST_SUB_4:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_3]], i64 -4
1522fe4006SFlorian Hahn; CHECK-NEXT:    [[CMP_SUB_4:%.*]] = icmp uge ptr [[DST_SUB_4]], [[LOWER]]
1622fe4006SFlorian Hahn; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_SUB_4]]
1722fe4006SFlorian Hahn; CHECK-NEXT:    ret i1 [[RES_2]]
1822fe4006SFlorian Hahn;
1922fe4006SFlorian Hahn  %pre = icmp uge ptr %dst, %lower
2022fe4006SFlorian Hahn  call void @llvm.assume(i1 %pre)
2122fe4006SFlorian Hahn  %dst.add.3 = getelementptr inbounds i8, ptr %dst, i64 3
2222fe4006SFlorian Hahn  %dst.sub.1 = getelementptr inbounds i8, ptr %dst.add.3, i64 -1
2322fe4006SFlorian Hahn  %cmp.sub.1 = icmp uge ptr %dst.sub.1, %lower
2422fe4006SFlorian Hahn  %dst.sub.3 = getelementptr inbounds i8, ptr %dst.add.3, i64 -3
2522fe4006SFlorian Hahn  %cmp.sub.3 = icmp uge ptr %dst.sub.3, %lower
2622fe4006SFlorian Hahn  %res.1 = xor i1 %cmp.sub.1, %cmp.sub.3
2722fe4006SFlorian Hahn  %dst.sub.4 = getelementptr inbounds i8, ptr %dst.add.3, i64 -4
2822fe4006SFlorian Hahn  %cmp.sub.4 = icmp uge ptr %dst.sub.4, %lower
2922fe4006SFlorian Hahn  %res.2 = xor i1 %res.1, %cmp.sub.4
3022fe4006SFlorian Hahn  ret i1 %res.2
3122fe4006SFlorian Hahn}
3222fe4006SFlorian Hahn
331ae40514SFlorian Hahndefine i1 @gep_sub_1_uge_only_inner_inbounds(ptr %dst, ptr %lower) {
341ae40514SFlorian Hahn; CHECK-LABEL: @gep_sub_1_uge_only_inner_inbounds(
351ae40514SFlorian Hahn; CHECK-NEXT:    [[PRE:%.*]] = icmp uge ptr [[DST:%.*]], [[LOWER:%.*]]
361ae40514SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[PRE]])
371ae40514SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 3
381ae40514SFlorian Hahn; CHECK-NEXT:    [[DST_SUB_1:%.*]] = getelementptr i8, ptr [[DST_ADD_3]], i64 -1
391ae40514SFlorian Hahn; CHECK-NEXT:    [[CMP_SUB_1:%.*]] = icmp uge ptr [[DST_SUB_1]], [[LOWER]]
401ae40514SFlorian Hahn; CHECK-NEXT:    [[DST_SUB_3:%.*]] = getelementptr i8, ptr [[DST_ADD_3]], i64 -3
411ae40514SFlorian Hahn; CHECK-NEXT:    [[CMP_SUB_3:%.*]] = icmp uge ptr [[DST_SUB_3]], [[LOWER]]
421ae40514SFlorian Hahn; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 [[CMP_SUB_1]], [[CMP_SUB_3]]
431ae40514SFlorian Hahn; CHECK-NEXT:    [[DST_SUB_4:%.*]] = getelementptr i8, ptr [[DST_ADD_3]], i64 -4
441ae40514SFlorian Hahn; CHECK-NEXT:    [[CMP_SUB_4:%.*]] = icmp uge ptr [[DST_SUB_4]], [[LOWER]]
451ae40514SFlorian Hahn; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_SUB_4]]
461ae40514SFlorian Hahn; CHECK-NEXT:    ret i1 [[RES_2]]
471ae40514SFlorian Hahn;
481ae40514SFlorian Hahn  %pre = icmp uge ptr %dst, %lower
491ae40514SFlorian Hahn  call void @llvm.assume(i1 %pre)
501ae40514SFlorian Hahn  %dst.add.3 = getelementptr inbounds i8, ptr %dst, i64 3
511ae40514SFlorian Hahn  %dst.sub.1 = getelementptr i8, ptr %dst.add.3, i64 -1
521ae40514SFlorian Hahn  %cmp.sub.1 = icmp uge ptr %dst.sub.1, %lower
531ae40514SFlorian Hahn  %dst.sub.3 = getelementptr i8, ptr %dst.add.3, i64 -3
541ae40514SFlorian Hahn  %cmp.sub.3 = icmp uge ptr %dst.sub.3, %lower
551ae40514SFlorian Hahn  %res.1 = xor i1 %cmp.sub.1, %cmp.sub.3
561ae40514SFlorian Hahn  %dst.sub.4 = getelementptr i8, ptr %dst.add.3, i64 -4
571ae40514SFlorian Hahn  %cmp.sub.4 = icmp uge ptr %dst.sub.4, %lower
581ae40514SFlorian Hahn  %res.2 = xor i1 %res.1, %cmp.sub.4
591ae40514SFlorian Hahn  ret i1 %res.2
601ae40514SFlorian Hahn}
611ae40514SFlorian Hahn
621ae40514SFlorian Hahndefine i1 @gep_sub_1_uge_only_outer_inbounds(ptr %dst, ptr %lower) {
631ae40514SFlorian Hahn; CHECK-LABEL: @gep_sub_1_uge_only_outer_inbounds(
641ae40514SFlorian Hahn; CHECK-NEXT:    [[PRE:%.*]] = icmp uge ptr [[DST:%.*]], [[LOWER:%.*]]
651ae40514SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[PRE]])
661ae40514SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_3:%.*]] = getelementptr i8, ptr [[DST]], i64 3
671ae40514SFlorian Hahn; CHECK-NEXT:    [[DST_SUB_1:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_3]], i64 -1
681ae40514SFlorian Hahn; CHECK-NEXT:    [[CMP_SUB_1:%.*]] = icmp uge ptr [[DST_SUB_1]], [[LOWER]]
691ae40514SFlorian Hahn; CHECK-NEXT:    [[DST_SUB_3:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_3]], i64 -3
701ae40514SFlorian Hahn; CHECK-NEXT:    [[CMP_SUB_3:%.*]] = icmp uge ptr [[DST_SUB_3]], [[LOWER]]
711ae40514SFlorian Hahn; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 [[CMP_SUB_1]], [[CMP_SUB_3]]
721ae40514SFlorian Hahn; CHECK-NEXT:    [[DST_SUB_4:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_3]], i64 -4
731ae40514SFlorian Hahn; CHECK-NEXT:    [[CMP_SUB_4:%.*]] = icmp uge ptr [[DST_SUB_4]], [[LOWER]]
741ae40514SFlorian Hahn; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_SUB_4]]
751ae40514SFlorian Hahn; CHECK-NEXT:    ret i1 [[RES_2]]
761ae40514SFlorian Hahn;
771ae40514SFlorian Hahn  %pre = icmp uge ptr %dst, %lower
781ae40514SFlorian Hahn  call void @llvm.assume(i1 %pre)
791ae40514SFlorian Hahn  %dst.add.3 = getelementptr i8, ptr %dst, i64 3
801ae40514SFlorian Hahn  %dst.sub.1 = getelementptr inbounds i8, ptr %dst.add.3, i64 -1
811ae40514SFlorian Hahn  %cmp.sub.1 = icmp uge ptr %dst.sub.1, %lower
821ae40514SFlorian Hahn  %dst.sub.3 = getelementptr inbounds i8, ptr %dst.add.3, i64 -3
831ae40514SFlorian Hahn  %cmp.sub.3 = icmp uge ptr %dst.sub.3, %lower
841ae40514SFlorian Hahn  %res.1 = xor i1 %cmp.sub.1, %cmp.sub.3
851ae40514SFlorian Hahn  %dst.sub.4 = getelementptr inbounds i8, ptr %dst.add.3, i64 -4
861ae40514SFlorian Hahn  %cmp.sub.4 = icmp uge ptr %dst.sub.4, %lower
871ae40514SFlorian Hahn  %res.2 = xor i1 %res.1, %cmp.sub.4
881ae40514SFlorian Hahn  ret i1 %res.2
891ae40514SFlorian Hahn}
901ae40514SFlorian Hahn
911ae40514SFlorian Hahndefine i1 @gep_sub_1_uge_no_inbounds(ptr %dst, ptr %lower) {
921ae40514SFlorian Hahn; CHECK-LABEL: @gep_sub_1_uge_no_inbounds(
931ae40514SFlorian Hahn; CHECK-NEXT:    [[PRE:%.*]] = icmp uge ptr [[DST:%.*]], [[LOWER:%.*]]
941ae40514SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[PRE]])
951ae40514SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_3:%.*]] = getelementptr i8, ptr [[DST]], i64 3
961ae40514SFlorian Hahn; CHECK-NEXT:    [[DST_SUB_1:%.*]] = getelementptr i8, ptr [[DST_ADD_3]], i64 -1
971ae40514SFlorian Hahn; CHECK-NEXT:    [[CMP_SUB_1:%.*]] = icmp uge ptr [[DST_SUB_1]], [[LOWER]]
981ae40514SFlorian Hahn; CHECK-NEXT:    [[DST_SUB_3:%.*]] = getelementptr i8, ptr [[DST_ADD_3]], i64 -3
991ae40514SFlorian Hahn; CHECK-NEXT:    [[CMP_SUB_3:%.*]] = icmp uge ptr [[DST_SUB_3]], [[LOWER]]
1001ae40514SFlorian Hahn; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 [[CMP_SUB_1]], [[CMP_SUB_3]]
1011ae40514SFlorian Hahn; CHECK-NEXT:    [[DST_SUB_4:%.*]] = getelementptr i8, ptr [[DST_ADD_3]], i64 -4
1021ae40514SFlorian Hahn; CHECK-NEXT:    [[CMP_SUB_4:%.*]] = icmp uge ptr [[DST_SUB_4]], [[LOWER]]
1031ae40514SFlorian Hahn; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_SUB_4]]
1041ae40514SFlorian Hahn; CHECK-NEXT:    ret i1 [[RES_2]]
1051ae40514SFlorian Hahn;
1061ae40514SFlorian Hahn  %pre = icmp uge ptr %dst, %lower
1071ae40514SFlorian Hahn  call void @llvm.assume(i1 %pre)
1081ae40514SFlorian Hahn  %dst.add.3 = getelementptr i8, ptr %dst, i64 3
1091ae40514SFlorian Hahn  %dst.sub.1 = getelementptr i8, ptr %dst.add.3, i64 -1
1101ae40514SFlorian Hahn  %cmp.sub.1 = icmp uge ptr %dst.sub.1, %lower
1111ae40514SFlorian Hahn  %dst.sub.3 = getelementptr i8, ptr %dst.add.3, i64 -3
1121ae40514SFlorian Hahn  %cmp.sub.3 = icmp uge ptr %dst.sub.3, %lower
1131ae40514SFlorian Hahn  %res.1 = xor i1 %cmp.sub.1, %cmp.sub.3
1141ae40514SFlorian Hahn  %dst.sub.4 = getelementptr i8, ptr %dst.add.3, i64 -4
1151ae40514SFlorian Hahn  %cmp.sub.4 = icmp uge ptr %dst.sub.4, %lower
1161ae40514SFlorian Hahn  %res.2 = xor i1 %res.1, %cmp.sub.4
1171ae40514SFlorian Hahn  ret i1 %res.2
1181ae40514SFlorian Hahn}
1191ae40514SFlorian Hahn
12022fe4006SFlorian Hahndefine i1 @gep_sub_1_ult(ptr %dst, ptr %upper) {
12122fe4006SFlorian Hahn; CHECK-LABEL: @gep_sub_1_ult(
12222fe4006SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_4:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i64 4
12322fe4006SFlorian Hahn; CHECK-NEXT:    [[PRE:%.*]] = icmp ult ptr [[DST_ADD_4]], [[UPPER:%.*]]
12422fe4006SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[PRE]])
12522fe4006SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 3
12622fe4006SFlorian Hahn; CHECK-NEXT:    [[DST_SUB_1:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_3]], i64 -1
12722fe4006SFlorian Hahn; CHECK-NEXT:    [[DST_SUB_3:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_3]], i64 -3
128e0136a62SFlorian Hahn; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 true, true
12922fe4006SFlorian Hahn; CHECK-NEXT:    ret i1 [[RES_1]]
13022fe4006SFlorian Hahn;
13122fe4006SFlorian Hahn  %dst.add.4 = getelementptr inbounds i8, ptr %dst, i64 4
13222fe4006SFlorian Hahn  %pre = icmp ult ptr %dst.add.4, %upper
13322fe4006SFlorian Hahn  call void @llvm.assume(i1 %pre)
13422fe4006SFlorian Hahn  %dst.add.3 = getelementptr inbounds i8, ptr %dst, i64 3
13522fe4006SFlorian Hahn  %dst.sub.1 = getelementptr inbounds i8, ptr %dst.add.3, i64 -1
13622fe4006SFlorian Hahn  %cmp.sub.1 = icmp ult ptr %dst.sub.1, %upper
13722fe4006SFlorian Hahn  %dst.sub.3 = getelementptr inbounds i8, ptr %dst.add.3, i64 -3
13822fe4006SFlorian Hahn  %cmp.sub.3 = icmp ult ptr %dst.sub.3, %upper
13922fe4006SFlorian Hahn  %res.1 = xor i1 %cmp.sub.1, %cmp.sub.3
14022fe4006SFlorian Hahn  ret i1 %res.1
14122fe4006SFlorian Hahn}
14222fe4006SFlorian Hahn
14322fe4006SFlorian Hahndefine i1 @gep_sub_ult_var_idx(ptr %dst, ptr %upper, i8 %idx) {
14422fe4006SFlorian Hahn; CHECK-LABEL: @gep_sub_ult_var_idx(
14522fe4006SFlorian Hahn; CHECK-NEXT:    [[NOT_ZERO:%.*]] = icmp ne i8 [[IDX:%.*]], 0
14622fe4006SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[NOT_ZERO]])
14722fe4006SFlorian Hahn; CHECK-NEXT:    [[IDX_EXT:%.*]] = zext i8 [[IDX]] to i16
14822fe4006SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i16 [[IDX_EXT]]
14922fe4006SFlorian Hahn; CHECK-NEXT:    [[PRE:%.*]] = icmp ult ptr [[DST_ADD_IDX]], [[UPPER:%.*]]
15022fe4006SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[PRE]])
15122fe4006SFlorian Hahn; CHECK-NEXT:    [[DST_SUB_1:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_IDX]], i64 -1
15222fe4006SFlorian Hahn; CHECK-NEXT:    [[DST_SUB_2:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_IDX]], i64 -2
153*d045e23cSFlorian Hahn; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 true, true
15422fe4006SFlorian Hahn; CHECK-NEXT:    [[DST_SUB_1_SUB_1:%.*]] = getelementptr inbounds i8, ptr [[DST_SUB_1]], i64 -1
15522fe4006SFlorian Hahn; CHECK-NEXT:    [[CMP_SUB_1_SUB_1:%.*]] = icmp ult ptr [[DST_SUB_1_SUB_1]], [[UPPER]]
15622fe4006SFlorian Hahn; CHECK-NEXT:    [[CMP_SUB_1_SUB_1_EQ:%.*]] = icmp eq ptr [[DST_SUB_1_SUB_1]], [[DST_SUB_2]]
15722fe4006SFlorian Hahn; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_SUB_1_SUB_1]]
15822fe4006SFlorian Hahn; CHECK-NEXT:    [[RES_3:%.*]] = xor i1 [[RES_2]], [[CMP_SUB_1_SUB_1_EQ]]
15922fe4006SFlorian Hahn; CHECK-NEXT:    ret i1 [[RES_3]]
16022fe4006SFlorian Hahn;
16122fe4006SFlorian Hahn  %not.zero = icmp ne i8 %idx, 0
16222fe4006SFlorian Hahn  call void @llvm.assume(i1 %not.zero)
16322fe4006SFlorian Hahn  %idx.ext = zext i8 %idx to i16
16422fe4006SFlorian Hahn  %dst.add.idx = getelementptr inbounds i8, ptr %dst, i16 %idx.ext
16522fe4006SFlorian Hahn  %pre = icmp ult ptr %dst.add.idx, %upper
16622fe4006SFlorian Hahn  call void @llvm.assume(i1 %pre)
16722fe4006SFlorian Hahn  %dst.sub.1 = getelementptr inbounds i8, ptr %dst.add.idx, i64 -1
16822fe4006SFlorian Hahn  %cmp.sub.1 = icmp ult ptr %dst.sub.1, %upper
16922fe4006SFlorian Hahn  %dst.sub.2 = getelementptr inbounds i8, ptr %dst.add.idx, i64 -2
17022fe4006SFlorian Hahn  %cmp.sub.2 = icmp ult ptr %dst.sub.2, %upper
17122fe4006SFlorian Hahn  %res.1 = xor i1 %cmp.sub.1, %cmp.sub.2
17222fe4006SFlorian Hahn  %dst.sub.1.sub.1 = getelementptr inbounds i8, ptr %dst.sub.1, i64 -1
17322fe4006SFlorian Hahn  %cmp.sub.1.sub.1 = icmp ult ptr %dst.sub.1.sub.1, %upper
17422fe4006SFlorian Hahn  %cmp.sub.1.sub.1.eq = icmp eq ptr %dst.sub.1.sub.1, %dst.sub.2
17522fe4006SFlorian Hahn  %res.2 = xor i1 %res.1, %cmp.sub.1.sub.1
17622fe4006SFlorian Hahn  %res.3 = xor i1 %res.2, %cmp.sub.1.sub.1.eq
17722fe4006SFlorian Hahn  ret i1 %res.3
17822fe4006SFlorian Hahn}
17922fe4006SFlorian Hahn
18022fe4006SFlorian Hahndefine i1 @gep_sub_ult_var_idx_sgt_1(ptr %dst, ptr %upper, i8 %idx) {
18122fe4006SFlorian Hahn; CHECK-LABEL: @gep_sub_ult_var_idx_sgt_1(
18222fe4006SFlorian Hahn; CHECK-NEXT:    [[SGT_1:%.*]] = icmp sgt i8 [[IDX:%.*]], 1
18322fe4006SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[SGT_1]])
18422fe4006SFlorian Hahn; CHECK-NEXT:    [[IDX_EXT:%.*]] = zext i8 [[IDX]] to i16
18522fe4006SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i16 [[IDX_EXT]]
18622fe4006SFlorian Hahn; CHECK-NEXT:    [[PRE:%.*]] = icmp ult ptr [[DST_ADD_IDX]], [[UPPER:%.*]]
18722fe4006SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[PRE]])
18822fe4006SFlorian Hahn; CHECK-NEXT:    [[DST_SUB_1:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_IDX]], i64 -1
18922fe4006SFlorian Hahn; CHECK-NEXT:    [[DST_SUB_2:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_IDX]], i64 -2
190721ecc9dSZain Jaffal; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 true, true
19122fe4006SFlorian Hahn; CHECK-NEXT:    [[DST_SUB_3:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_IDX]], i64 -3
192*d045e23cSFlorian Hahn; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], true
19322fe4006SFlorian Hahn; CHECK-NEXT:    ret i1 [[RES_2]]
19422fe4006SFlorian Hahn;
19522fe4006SFlorian Hahn  %sgt.1 = icmp sgt i8 %idx, 1
19622fe4006SFlorian Hahn  call void @llvm.assume(i1 %sgt.1)
19722fe4006SFlorian Hahn  %idx.ext = zext i8 %idx to i16
19822fe4006SFlorian Hahn  %dst.add.idx = getelementptr inbounds i8, ptr %dst, i16 %idx.ext
19922fe4006SFlorian Hahn  %pre = icmp ult ptr %dst.add.idx, %upper
20022fe4006SFlorian Hahn  call void @llvm.assume(i1 %pre)
20122fe4006SFlorian Hahn  %dst.sub.1 = getelementptr inbounds i8, ptr %dst.add.idx, i64 -1
20222fe4006SFlorian Hahn  %cmp.sub.1 = icmp ult ptr %dst.sub.1, %upper
20322fe4006SFlorian Hahn  %dst.sub.2 = getelementptr inbounds i8, ptr %dst.add.idx, i64 -2
20422fe4006SFlorian Hahn  %cmp.sub.2 = icmp ult ptr %dst.sub.2, %upper
20522fe4006SFlorian Hahn  %res.1 = xor i1 %cmp.sub.1, %cmp.sub.2
20622fe4006SFlorian Hahn  %dst.sub.3 = getelementptr inbounds i8, ptr %dst.add.idx, i64 -3
20722fe4006SFlorian Hahn  %cmp.sub.3 = icmp ult ptr %dst.sub.3, %upper
20822fe4006SFlorian Hahn  %res.2 = xor i1 %res.1, %cmp.sub.3
20922fe4006SFlorian Hahn  ret i1 %res.2
21022fe4006SFlorian Hahn}
21122fe4006SFlorian Hahn
2121ae40514SFlorian Hahndefine i1 @gep_sub_1_ult_var_idx_inbounds(ptr %dst, ptr %upper, i8 %len, i8 %idx) {
2131ae40514SFlorian Hahn; CHECK-LABEL: @gep_sub_1_ult_var_idx_inbounds(
21422fe4006SFlorian Hahn; CHECK-NEXT:    [[NOT_ZERO:%.*]] = icmp ne i8 [[LEN:%.*]], 0
21522fe4006SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[NOT_ZERO]])
21622fe4006SFlorian Hahn; CHECK-NEXT:    [[LEN_EXT:%.*]] = zext i8 [[LEN]] to i16
21722fe4006SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_LEN:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i16 [[LEN_EXT]]
21822fe4006SFlorian Hahn; CHECK-NEXT:    [[DST_SUB_1:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_LEN]], i64 -1
21922fe4006SFlorian Hahn; CHECK-NEXT:    [[CMP_SUB_1:%.*]] = icmp ult ptr [[DST_SUB_1]], [[UPPER:%.*]]
22022fe4006SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_SUB_1]])
22122fe4006SFlorian Hahn; CHECK-NEXT:    [[CMP_IDX_ULT_LEN:%.*]] = icmp ult i8 [[IDX:%.*]], [[LEN]]
22222fe4006SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_IDX_ULT_LEN]])
22322fe4006SFlorian Hahn; CHECK-NEXT:    [[IDX_EXT:%.*]] = zext i8 [[IDX]] to i16
22422fe4006SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST]], i16 [[IDX_EXT]]
22511a6e64bSFlorian Hahn; CHECK-NEXT:    ret i1 true
22622fe4006SFlorian Hahn;
22722fe4006SFlorian Hahn  %not.zero = icmp ne i8 %len, 0
22822fe4006SFlorian Hahn  call void @llvm.assume(i1 %not.zero)
22922fe4006SFlorian Hahn  %len.ext = zext i8 %len to i16
23022fe4006SFlorian Hahn  %dst.add.len = getelementptr inbounds i8, ptr %dst, i16 %len.ext
23122fe4006SFlorian Hahn  %dst.sub.1 = getelementptr inbounds i8, ptr %dst.add.len, i64 -1
23222fe4006SFlorian Hahn  %cmp.sub.1 = icmp ult ptr %dst.sub.1, %upper
23322fe4006SFlorian Hahn  call void @llvm.assume(i1 %cmp.sub.1)
23422fe4006SFlorian Hahn  %cmp.idx.ult.len = icmp ult i8 %idx, %len
23522fe4006SFlorian Hahn  call void @llvm.assume(i1 %cmp.idx.ult.len)
23622fe4006SFlorian Hahn  %idx.ext = zext i8 %idx to i16
23722fe4006SFlorian Hahn  %dst.add.idx = getelementptr inbounds i8, ptr %dst, i16 %idx.ext
23822fe4006SFlorian Hahn  %cmp.idx = icmp ult ptr %dst.add.idx, %upper
23922fe4006SFlorian Hahn  ret i1 %cmp.idx
24022fe4006SFlorian Hahn}
24122fe4006SFlorian Hahn
2421ae40514SFlorian Hahndefine i1 @gep_sub_1_ult_var_idx_only_inner_inbounds(ptr %dst, ptr %upper, i8 %len, i8 %idx) {
2431ae40514SFlorian Hahn; CHECK-LABEL: @gep_sub_1_ult_var_idx_only_inner_inbounds(
2441ae40514SFlorian Hahn; CHECK-NEXT:    [[NOT_ZERO:%.*]] = icmp ne i8 [[LEN:%.*]], 0
2451ae40514SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[NOT_ZERO]])
2461ae40514SFlorian Hahn; CHECK-NEXT:    [[LEN_EXT:%.*]] = zext i8 [[LEN]] to i16
2471ae40514SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_LEN:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i16 [[LEN_EXT]]
2481ae40514SFlorian Hahn; CHECK-NEXT:    [[DST_SUB_1:%.*]] = getelementptr i8, ptr [[DST_ADD_LEN]], i64 -1
2491ae40514SFlorian Hahn; CHECK-NEXT:    [[CMP_SUB_1:%.*]] = icmp ult ptr [[DST_SUB_1]], [[UPPER:%.*]]
2501ae40514SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_SUB_1]])
2511ae40514SFlorian Hahn; CHECK-NEXT:    [[CMP_IDX_ULT_LEN:%.*]] = icmp ult i8 [[IDX:%.*]], [[LEN]]
2521ae40514SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_IDX_ULT_LEN]])
2531ae40514SFlorian Hahn; CHECK-NEXT:    [[IDX_EXT:%.*]] = zext i8 [[IDX]] to i16
2541ae40514SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST]], i16 [[IDX_EXT]]
2551ae40514SFlorian Hahn; CHECK-NEXT:    [[CMP_IDX:%.*]] = icmp ult ptr [[DST_ADD_IDX]], [[UPPER]]
2561ae40514SFlorian Hahn; CHECK-NEXT:    ret i1 [[CMP_IDX]]
2571ae40514SFlorian Hahn;
2581ae40514SFlorian Hahn  %not.zero = icmp ne i8 %len, 0
2591ae40514SFlorian Hahn  call void @llvm.assume(i1 %not.zero)
2601ae40514SFlorian Hahn  %len.ext = zext i8 %len to i16
2611ae40514SFlorian Hahn  %dst.add.len = getelementptr inbounds i8, ptr %dst, i16 %len.ext
2621ae40514SFlorian Hahn  %dst.sub.1 = getelementptr i8, ptr %dst.add.len, i64 -1
2631ae40514SFlorian Hahn  %cmp.sub.1 = icmp ult ptr %dst.sub.1, %upper
2641ae40514SFlorian Hahn  call void @llvm.assume(i1 %cmp.sub.1)
2651ae40514SFlorian Hahn  %cmp.idx.ult.len = icmp ult i8 %idx, %len
2661ae40514SFlorian Hahn  call void @llvm.assume(i1 %cmp.idx.ult.len)
2671ae40514SFlorian Hahn  %idx.ext = zext i8 %idx to i16
2681ae40514SFlorian Hahn  %dst.add.idx = getelementptr inbounds i8, ptr %dst, i16 %idx.ext
2691ae40514SFlorian Hahn  %cmp.idx = icmp ult ptr %dst.add.idx, %upper
2701ae40514SFlorian Hahn  ret i1 %cmp.idx
2711ae40514SFlorian Hahn}
2721ae40514SFlorian Hahn
2731ae40514SFlorian Hahndefine i1 @gep_sub_1_ult_var_idx_no_inbounds(ptr %dst, ptr %upper, i8 %len, i8 %idx) {
2741ae40514SFlorian Hahn; CHECK-LABEL: @gep_sub_1_ult_var_idx_no_inbounds(
2751ae40514SFlorian Hahn; CHECK-NEXT:    [[NOT_ZERO:%.*]] = icmp ne i8 [[LEN:%.*]], 0
2761ae40514SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[NOT_ZERO]])
2771ae40514SFlorian Hahn; CHECK-NEXT:    [[LEN_EXT:%.*]] = zext i8 [[LEN]] to i16
2781ae40514SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_LEN:%.*]] = getelementptr i8, ptr [[DST:%.*]], i16 [[LEN_EXT]]
2791ae40514SFlorian Hahn; CHECK-NEXT:    [[DST_SUB_1:%.*]] = getelementptr i8, ptr [[DST_ADD_LEN]], i64 -1
2801ae40514SFlorian Hahn; CHECK-NEXT:    [[CMP_SUB_1:%.*]] = icmp ult ptr [[DST_SUB_1]], [[UPPER:%.*]]
2811ae40514SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_SUB_1]])
2821ae40514SFlorian Hahn; CHECK-NEXT:    [[CMP_IDX_ULT_LEN:%.*]] = icmp ult i8 [[IDX:%.*]], [[LEN]]
2831ae40514SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_IDX_ULT_LEN]])
2841ae40514SFlorian Hahn; CHECK-NEXT:    [[IDX_EXT:%.*]] = zext i8 [[IDX]] to i16
2851ae40514SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_IDX:%.*]] = getelementptr i8, ptr [[DST]], i16 [[IDX_EXT]]
2861ae40514SFlorian Hahn; CHECK-NEXT:    [[CMP_IDX:%.*]] = icmp ult ptr [[DST_ADD_IDX]], [[UPPER]]
2871ae40514SFlorian Hahn; CHECK-NEXT:    ret i1 [[CMP_IDX]]
2881ae40514SFlorian Hahn;
2891ae40514SFlorian Hahn  %not.zero = icmp ne i8 %len, 0
2901ae40514SFlorian Hahn  call void @llvm.assume(i1 %not.zero)
2911ae40514SFlorian Hahn  %len.ext = zext i8 %len to i16
2921ae40514SFlorian Hahn  %dst.add.len = getelementptr i8, ptr %dst, i16 %len.ext
2931ae40514SFlorian Hahn  %dst.sub.1 = getelementptr i8, ptr %dst.add.len, i64 -1
2941ae40514SFlorian Hahn  %cmp.sub.1 = icmp ult ptr %dst.sub.1, %upper
2951ae40514SFlorian Hahn  call void @llvm.assume(i1 %cmp.sub.1)
2961ae40514SFlorian Hahn  %cmp.idx.ult.len = icmp ult i8 %idx, %len
2971ae40514SFlorian Hahn  call void @llvm.assume(i1 %cmp.idx.ult.len)
2981ae40514SFlorian Hahn  %idx.ext = zext i8 %idx to i16
2991ae40514SFlorian Hahn  %dst.add.idx = getelementptr i8, ptr %dst, i16 %idx.ext
3001ae40514SFlorian Hahn  %cmp.idx = icmp ult ptr %dst.add.idx, %upper
3011ae40514SFlorian Hahn  ret i1 %cmp.idx
3021ae40514SFlorian Hahn}
3031ae40514SFlorian Hahn
30422fe4006SFlorian Hahndefine i1 @gep_sub_2_ult_var_idx(ptr %dst, ptr %upper, i8 %len, i8 %idx) {
30522fe4006SFlorian Hahn; CHECK-LABEL: @gep_sub_2_ult_var_idx(
30622fe4006SFlorian Hahn; CHECK-NEXT:    [[NOT_ZERO:%.*]] = icmp ne i8 [[LEN:%.*]], 0
30722fe4006SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[NOT_ZERO]])
30822fe4006SFlorian Hahn; CHECK-NEXT:    [[LEN_EXT:%.*]] = zext i8 [[LEN]] to i16
30922fe4006SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_LEN:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i16 [[LEN_EXT]]
31022fe4006SFlorian Hahn; CHECK-NEXT:    [[DST_SUB_1:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_LEN]], i64 -2
31122fe4006SFlorian Hahn; CHECK-NEXT:    [[CMP_SUB_1:%.*]] = icmp ult ptr [[DST_SUB_1]], [[UPPER:%.*]]
31222fe4006SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_SUB_1]])
31322fe4006SFlorian Hahn; CHECK-NEXT:    [[CMP_IDX_ULT_LEN:%.*]] = icmp ult i8 [[IDX:%.*]], [[LEN]]
31422fe4006SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_IDX_ULT_LEN]])
31522fe4006SFlorian Hahn; CHECK-NEXT:    [[IDX_EXT:%.*]] = zext i8 [[IDX]] to i16
31622fe4006SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST]], i16 [[IDX_EXT]]
31722fe4006SFlorian Hahn; CHECK-NEXT:    [[CMP_IDX:%.*]] = icmp ult ptr [[DST_ADD_IDX]], [[UPPER]]
31822fe4006SFlorian Hahn; CHECK-NEXT:    ret i1 [[CMP_IDX]]
31922fe4006SFlorian Hahn;
32022fe4006SFlorian Hahn  %not.zero = icmp ne i8 %len, 0
32122fe4006SFlorian Hahn  call void @llvm.assume(i1 %not.zero)
32222fe4006SFlorian Hahn  %len.ext = zext i8 %len to i16
32322fe4006SFlorian Hahn  %dst.add.len = getelementptr inbounds i8, ptr %dst, i16 %len.ext
32422fe4006SFlorian Hahn  %dst.sub.1 = getelementptr inbounds i8, ptr %dst.add.len, i64 -2
32522fe4006SFlorian Hahn  %cmp.sub.1 = icmp ult ptr %dst.sub.1, %upper
32622fe4006SFlorian Hahn  call void @llvm.assume(i1 %cmp.sub.1)
32722fe4006SFlorian Hahn  %cmp.idx.ult.len = icmp ult i8 %idx, %len
32822fe4006SFlorian Hahn  call void @llvm.assume(i1 %cmp.idx.ult.len)
32922fe4006SFlorian Hahn  %idx.ext = zext i8 %idx to i16
33022fe4006SFlorian Hahn  %dst.add.idx = getelementptr inbounds i8, ptr %dst, i16 %idx.ext
33122fe4006SFlorian Hahn  %cmp.idx = icmp ult ptr %dst.add.idx, %upper
33222fe4006SFlorian Hahn  ret i1 %cmp.idx
33322fe4006SFlorian Hahn}
33422fe4006SFlorian Hahn
3350b574650SFlorian Hahndefine i1 @gep_sub_2_ult_var_idx_inbounds_len_sge_2(ptr %dst, ptr %upper, i8 %len, i8 %idx) {
3360b574650SFlorian Hahn; CHECK-LABEL: @gep_sub_2_ult_var_idx_inbounds_len_sge_2(
3370b574650SFlorian Hahn; CHECK-NEXT:    [[SGE_2:%.*]] = icmp sge i8 [[LEN:%.*]], 2
3380b574650SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[SGE_2]])
3390b574650SFlorian Hahn; CHECK-NEXT:    [[LEN_EXT:%.*]] = zext i8 [[LEN]] to i16
3400b574650SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_LEN:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i16 [[LEN_EXT]]
3410b574650SFlorian Hahn; CHECK-NEXT:    [[DST_SUB_1:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_LEN]], i64 -1
3420b574650SFlorian Hahn; CHECK-NEXT:    [[CMP_SUB_1:%.*]] = icmp ult ptr [[DST_SUB_1]], [[UPPER:%.*]]
3430b574650SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_SUB_1]])
3440b574650SFlorian Hahn; CHECK-NEXT:    [[CMP_IDX_ULT_LEN:%.*]] = icmp ult i8 [[IDX:%.*]], [[LEN]]
3450b574650SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_IDX_ULT_LEN]])
3460b574650SFlorian Hahn; CHECK-NEXT:    [[IDX_EXT:%.*]] = zext i8 [[IDX]] to i16
3470b574650SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST]], i16 [[IDX_EXT]]
3480b574650SFlorian Hahn; CHECK-NEXT:    ret i1 true
3490b574650SFlorian Hahn;
3500b574650SFlorian Hahn  %sge.2 = icmp sge i8 %len, 2
3510b574650SFlorian Hahn  call void @llvm.assume(i1 %sge.2)
3520b574650SFlorian Hahn  %len.ext = zext i8 %len to i16
3530b574650SFlorian Hahn  %dst.add.len = getelementptr inbounds i8, ptr %dst, i16 %len.ext
3540b574650SFlorian Hahn  %dst.sub.1 = getelementptr inbounds i8, ptr %dst.add.len, i64 -1
3550b574650SFlorian Hahn  %cmp.sub.1 = icmp ult ptr %dst.sub.1, %upper
3560b574650SFlorian Hahn  call void @llvm.assume(i1 %cmp.sub.1)
3570b574650SFlorian Hahn  %cmp.idx.ult.len = icmp ult i8 %idx, %len
3580b574650SFlorian Hahn  call void @llvm.assume(i1 %cmp.idx.ult.len)
3590b574650SFlorian Hahn  %idx.ext = zext i8 %idx to i16
3600b574650SFlorian Hahn  %dst.add.idx = getelementptr inbounds i8, ptr %dst, i16 %idx.ext
3610b574650SFlorian Hahn  %cmp.idx = icmp ult ptr %dst.add.idx, %upper
3620b574650SFlorian Hahn  ret i1 %cmp.idx
3630b574650SFlorian Hahn}
3640b574650SFlorian Hahn
3650b574650SFlorian Hahndefine i1 @gep_sub_2_ult_var_idx_inbounds_len_uge_2(ptr %dst, ptr %upper, i8 %len, i8 %idx) {
3660b574650SFlorian Hahn; CHECK-LABEL: @gep_sub_2_ult_var_idx_inbounds_len_uge_2(
3670b574650SFlorian Hahn; CHECK-NEXT:    [[UGE_2:%.*]] = icmp uge i8 [[LEN:%.*]], 2
3680b574650SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[UGE_2]])
3690b574650SFlorian Hahn; CHECK-NEXT:    [[LEN_EXT:%.*]] = zext i8 [[LEN]] to i16
3700b574650SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_LEN:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i16 [[LEN_EXT]]
3710b574650SFlorian Hahn; CHECK-NEXT:    [[DST_SUB_1:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_LEN]], i64 -1
3720b574650SFlorian Hahn; CHECK-NEXT:    [[CMP_SUB_1:%.*]] = icmp ult ptr [[DST_SUB_1]], [[UPPER:%.*]]
3730b574650SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_SUB_1]])
3740b574650SFlorian Hahn; CHECK-NEXT:    [[CMP_IDX_ULT_LEN:%.*]] = icmp ult i8 [[IDX:%.*]], [[LEN]]
3750b574650SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_IDX_ULT_LEN]])
3760b574650SFlorian Hahn; CHECK-NEXT:    [[IDX_EXT:%.*]] = zext i8 [[IDX]] to i16
3770b574650SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST]], i16 [[IDX_EXT]]
3780b574650SFlorian Hahn; CHECK-NEXT:    ret i1 true
3790b574650SFlorian Hahn;
3800b574650SFlorian Hahn  %uge.2 = icmp uge i8 %len, 2
3810b574650SFlorian Hahn  call void @llvm.assume(i1 %uge.2)
3820b574650SFlorian Hahn  %len.ext = zext i8 %len to i16
3830b574650SFlorian Hahn  %dst.add.len = getelementptr inbounds i8, ptr %dst, i16 %len.ext
3840b574650SFlorian Hahn  %dst.sub.1 = getelementptr inbounds i8, ptr %dst.add.len, i64 -1
3850b574650SFlorian Hahn  %cmp.sub.1 = icmp ult ptr %dst.sub.1, %upper
3860b574650SFlorian Hahn  call void @llvm.assume(i1 %cmp.sub.1)
3870b574650SFlorian Hahn  %cmp.idx.ult.len = icmp ult i8 %idx, %len
3880b574650SFlorian Hahn  call void @llvm.assume(i1 %cmp.idx.ult.len)
3890b574650SFlorian Hahn  %idx.ext = zext i8 %idx to i16
3900b574650SFlorian Hahn  %dst.add.idx = getelementptr inbounds i8, ptr %dst, i16 %idx.ext
3910b574650SFlorian Hahn  %cmp.idx = icmp ult ptr %dst.add.idx, %upper
3920b574650SFlorian Hahn  ret i1 %cmp.idx
3930b574650SFlorian Hahn}
3940b574650SFlorian Hahn
39522fe4006SFlorian Hahndefine i1 @gep_sub_ult_var_idx_len_sgt_1(ptr %dst, ptr %upper, i8 %len, i8 %idx) {
39622fe4006SFlorian Hahn; CHECK-LABEL: @gep_sub_ult_var_idx_len_sgt_1(
39722fe4006SFlorian Hahn; CHECK-NEXT:    [[SGT_1:%.*]] = icmp sgt i8 [[LEN:%.*]], 1
39822fe4006SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[SGT_1]])
39922fe4006SFlorian Hahn; CHECK-NEXT:    [[LEN_EXT:%.*]] = zext i8 [[LEN]] to i16
40022fe4006SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_LEN:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i16 [[LEN_EXT]]
40122fe4006SFlorian Hahn; CHECK-NEXT:    [[DST_SUB_1:%.*]] = getelementptr inbounds i8, ptr [[DST_ADD_LEN]], i64 -2
40222fe4006SFlorian Hahn; CHECK-NEXT:    [[CMP_SUB_1:%.*]] = icmp ult ptr [[DST_SUB_1]], [[UPPER:%.*]]
40322fe4006SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_SUB_1]])
40422fe4006SFlorian Hahn; CHECK-NEXT:    [[CMP_IDX_ULT_LEN:%.*]] = icmp ult i8 [[IDX:%.*]], [[LEN]]
40522fe4006SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_IDX_ULT_LEN]])
40622fe4006SFlorian Hahn; CHECK-NEXT:    [[IDX_EXT:%.*]] = zext i8 [[IDX]] to i16
40722fe4006SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST]], i16 [[IDX_EXT]]
40822fe4006SFlorian Hahn; CHECK-NEXT:    [[CMP_IDX:%.*]] = icmp ult ptr [[DST_ADD_IDX]], [[UPPER]]
40922fe4006SFlorian Hahn; CHECK-NEXT:    ret i1 [[CMP_IDX]]
41022fe4006SFlorian Hahn;
41122fe4006SFlorian Hahn  %sgt.1 = icmp sgt i8 %len, 1
41222fe4006SFlorian Hahn  call void @llvm.assume(i1 %sgt.1)
41322fe4006SFlorian Hahn  %len.ext = zext i8 %len to i16
41422fe4006SFlorian Hahn  %dst.add.len = getelementptr inbounds i8, ptr %dst, i16 %len.ext
41522fe4006SFlorian Hahn  %dst.sub.1 = getelementptr inbounds i8, ptr %dst.add.len, i64 -2
41622fe4006SFlorian Hahn  %cmp.sub.1 = icmp ult ptr %dst.sub.1, %upper
41722fe4006SFlorian Hahn  call void @llvm.assume(i1 %cmp.sub.1)
41822fe4006SFlorian Hahn  %cmp.idx.ult.len = icmp ult i8 %idx, %len
41922fe4006SFlorian Hahn  call void @llvm.assume(i1 %cmp.idx.ult.len)
42022fe4006SFlorian Hahn  %idx.ext = zext i8 %idx to i16
42122fe4006SFlorian Hahn  %dst.add.idx = getelementptr inbounds i8, ptr %dst, i16 %idx.ext
42222fe4006SFlorian Hahn  %cmp.idx = icmp ult ptr %dst.add.idx, %upper
42322fe4006SFlorian Hahn  ret i1 %cmp.idx
42422fe4006SFlorian Hahn}
4250b574650SFlorian Hahn
4260b574650SFlorian Hahndefine i1 @gep_sub_1_ult_var_idx_lower_bound(ptr %lower, ptr %src, i8 %len) {
4270b574650SFlorian Hahn; CHECK-LABEL: @gep_sub_1_ult_var_idx_lower_bound(
4280b574650SFlorian Hahn; CHECK-NEXT:  entry:
4290b574650SFlorian Hahn; CHECK-NEXT:    [[SRC_UGE_LOWER:%.*]] = icmp uge ptr [[SRC:%.*]], [[LOWER:%.*]]
4300b574650SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[SRC_UGE_LOWER]])
4310b574650SFlorian Hahn; CHECK-NEXT:    [[LEN_POS:%.*]] = icmp sge i8 [[LEN:%.*]], 0
4320b574650SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[LEN_POS]])
4330b574650SFlorian Hahn; CHECK-NEXT:    [[GEP_LEN:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i8 [[LEN]]
4340b574650SFlorian Hahn; CHECK-NEXT:    [[GEP_SUB_1:%.*]] = getelementptr inbounds i8, ptr [[GEP_LEN]], i8 -1
4350b574650SFlorian Hahn; CHECK-NEXT:    [[RES:%.*]] = icmp ult ptr [[GEP_SUB_1]], [[LOWER]]
4360b574650SFlorian Hahn; CHECK-NEXT:    ret i1 [[RES]]
4370b574650SFlorian Hahn;
4380b574650SFlorian Hahnentry:
4390b574650SFlorian Hahn  %src.uge.lower = icmp uge ptr %src, %lower
4400b574650SFlorian Hahn  call void @llvm.assume(i1 %src.uge.lower)
4410b574650SFlorian Hahn
4420b574650SFlorian Hahn  %len.pos = icmp sge i8 %len, 0
4430b574650SFlorian Hahn  call void @llvm.assume(i1 %len.pos)
4440b574650SFlorian Hahn
4450b574650SFlorian Hahn  %gep.len = getelementptr inbounds i8, ptr %src, i8 %len
4460b574650SFlorian Hahn  %gep.sub.1 = getelementptr inbounds i8, ptr %gep.len, i8 -1
4470b574650SFlorian Hahn  %res = icmp ult ptr %gep.sub.1, %lower
4480b574650SFlorian Hahn  ret i1 %res
4490b574650SFlorian Hahn}
4500b574650SFlorian Hahn
4510b574650SFlorian Hahndefine i1 @gep_sub_1_ult_var_idx_lower_bound_len_ne_0(ptr %lower, ptr %src, i8 %len) {
4520b574650SFlorian Hahn; CHECK-LABEL: @gep_sub_1_ult_var_idx_lower_bound_len_ne_0(
4530b574650SFlorian Hahn; CHECK-NEXT:  entry:
4540b574650SFlorian Hahn; CHECK-NEXT:    [[LEN_NE_0:%.*]] = icmp ne i8 [[LEN:%.*]], 0
4550b574650SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[LEN_NE_0]])
4560b574650SFlorian Hahn; CHECK-NEXT:    [[SRC_UGE_LOWER:%.*]] = icmp uge ptr [[SRC:%.*]], [[LOWER:%.*]]
4570b574650SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[SRC_UGE_LOWER]])
4580b574650SFlorian Hahn; CHECK-NEXT:    [[LEN_POS:%.*]] = icmp sge i8 [[LEN]], 0
4590b574650SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[LEN_POS]])
4600b574650SFlorian Hahn; CHECK-NEXT:    [[GEP_LEN:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i8 [[LEN]]
4610b574650SFlorian Hahn; CHECK-NEXT:    [[GEP_SUB_1:%.*]] = getelementptr inbounds i8, ptr [[GEP_LEN]], i8 -1
462*d045e23cSFlorian Hahn; CHECK-NEXT:    ret i1 false
4630b574650SFlorian Hahn;
4640b574650SFlorian Hahnentry:
4650b574650SFlorian Hahn  %len.ne.0 = icmp ne i8 %len, 0
4660b574650SFlorian Hahn  call void @llvm.assume(i1 %len.ne.0)
4670b574650SFlorian Hahn
4680b574650SFlorian Hahn  %src.uge.lower = icmp uge ptr %src, %lower
4690b574650SFlorian Hahn  call void @llvm.assume(i1 %src.uge.lower)
4700b574650SFlorian Hahn
4710b574650SFlorian Hahn  %len.pos = icmp sge i8 %len, 0
4720b574650SFlorian Hahn  call void @llvm.assume(i1 %len.pos)
4730b574650SFlorian Hahn
4740b574650SFlorian Hahn  %gep.len = getelementptr inbounds i8, ptr %src, i8 %len
4750b574650SFlorian Hahn  %gep.sub.1 = getelementptr inbounds i8, ptr %gep.len, i8 -1
4760b574650SFlorian Hahn  %res = icmp ult ptr %gep.sub.1, %lower
4770b574650SFlorian Hahn  ret i1 %res
4780b574650SFlorian Hahn}
4790b574650SFlorian Hahn
4800b574650SFlorian Hahndefine i1 @gep_sub_2_ult_var_idx_lower_bound_len_ne_0(ptr %lower, ptr %src, i8 %len) {
4810b574650SFlorian Hahn; CHECK-LABEL: @gep_sub_2_ult_var_idx_lower_bound_len_ne_0(
4820b574650SFlorian Hahn; CHECK-NEXT:  entry:
4830b574650SFlorian Hahn; CHECK-NEXT:    [[LEN_NE_0:%.*]] = icmp ne i8 [[LEN:%.*]], 0
4840b574650SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[LEN_NE_0]])
4850b574650SFlorian Hahn; CHECK-NEXT:    [[SRC_UGE_LOWER:%.*]] = icmp uge ptr [[SRC:%.*]], [[LOWER:%.*]]
4860b574650SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[SRC_UGE_LOWER]])
4870b574650SFlorian Hahn; CHECK-NEXT:    [[LEN_POS:%.*]] = icmp sge i8 [[LEN]], 0
4880b574650SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[LEN_POS]])
4890b574650SFlorian Hahn; CHECK-NEXT:    [[GEP_LEN:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i8 [[LEN]]
4900b574650SFlorian Hahn; CHECK-NEXT:    [[GEP_SUB_2:%.*]] = getelementptr inbounds i8, ptr [[GEP_LEN]], i8 -2
4910b574650SFlorian Hahn; CHECK-NEXT:    [[RES:%.*]] = icmp ult ptr [[GEP_SUB_2]], [[LOWER]]
4920b574650SFlorian Hahn; CHECK-NEXT:    ret i1 [[RES]]
4930b574650SFlorian Hahn;
4940b574650SFlorian Hahnentry:
4950b574650SFlorian Hahn  %len.ne.0 = icmp ne i8 %len, 0
4960b574650SFlorian Hahn  call void @llvm.assume(i1 %len.ne.0)
4970b574650SFlorian Hahn
4980b574650SFlorian Hahn  %src.uge.lower = icmp uge ptr %src, %lower
4990b574650SFlorian Hahn  call void @llvm.assume(i1 %src.uge.lower)
5000b574650SFlorian Hahn
5010b574650SFlorian Hahn  %len.pos = icmp sge i8 %len, 0
5020b574650SFlorian Hahn  call void @llvm.assume(i1 %len.pos)
5030b574650SFlorian Hahn
5040b574650SFlorian Hahn  %gep.len = getelementptr inbounds i8, ptr %src, i8 %len
5050b574650SFlorian Hahn  %gep.sub.2 = getelementptr inbounds i8, ptr %gep.len, i8 -2
5060b574650SFlorian Hahn  %res = icmp ult ptr %gep.sub.2, %lower
5070b574650SFlorian Hahn  ret i1 %res
5080b574650SFlorian Hahn}
5092de8f1f6SFlorian Hahn
5102de8f1f6SFlorian Hahndefine i1 @gep_i16_sub_1_uge_inbounds(ptr %dst, ptr %lower) {
5112de8f1f6SFlorian Hahn; CHECK-LABEL: @gep_i16_sub_1_uge_inbounds(
5122de8f1f6SFlorian Hahn; CHECK-NEXT:    [[PRE:%.*]] = icmp uge ptr [[DST:%.*]], [[LOWER:%.*]]
5132de8f1f6SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[PRE]])
5142de8f1f6SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 3
5152de8f1f6SFlorian Hahn; CHECK-NEXT:    [[DST_SUB_1:%.*]] = getelementptr inbounds i16, ptr [[DST_ADD_3]], i64 -1
5162de8f1f6SFlorian Hahn; CHECK-NEXT:    [[DST_SUB_2:%.*]] = getelementptr inbounds i16, ptr [[DST_ADD_3]], i64 -2
517*d045e23cSFlorian Hahn; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 false, true
5182de8f1f6SFlorian Hahn; CHECK-NEXT:    [[DST_SUB_3:%.*]] = getelementptr inbounds i16, ptr [[DST_ADD_3]], i64 -3
5192de8f1f6SFlorian Hahn; CHECK-NEXT:    [[CMP_SUB_3:%.*]] = icmp ule ptr [[DST_SUB_3]], [[LOWER]]
5202de8f1f6SFlorian Hahn; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_SUB_3]]
5212de8f1f6SFlorian Hahn; CHECK-NEXT:    ret i1 [[RES_2]]
5222de8f1f6SFlorian Hahn;
5232de8f1f6SFlorian Hahn  %pre = icmp uge ptr %dst, %lower
5242de8f1f6SFlorian Hahn  call void @llvm.assume(i1 %pre)
5252de8f1f6SFlorian Hahn  %dst.add.3 = getelementptr inbounds i8, ptr %dst, i64 3
5262de8f1f6SFlorian Hahn  %dst.sub.1 = getelementptr inbounds i16, ptr %dst.add.3, i64 -1
5272de8f1f6SFlorian Hahn  %cmp.sub.1 = icmp ule ptr %dst.sub.1, %lower
5282de8f1f6SFlorian Hahn  %dst.sub.2 = getelementptr inbounds i16, ptr %dst.add.3, i64 -2
5292de8f1f6SFlorian Hahn  %cmp.sub.2 = icmp ule ptr %dst.sub.2, %dst
5302de8f1f6SFlorian Hahn  %res.1 = xor i1 %cmp.sub.1, %cmp.sub.2
5312de8f1f6SFlorian Hahn  %dst.sub.3 = getelementptr inbounds i16, ptr %dst.add.3, i64 -3
5322de8f1f6SFlorian Hahn  %cmp.sub.3 = icmp ule ptr %dst.sub.3, %lower
5332de8f1f6SFlorian Hahn  %res.2 = xor i1 %res.1, %cmp.sub.3
5342de8f1f6SFlorian Hahn  ret i1 %res.2
5352de8f1f6SFlorian Hahn}
5362de8f1f6SFlorian Hahn
5372de8f1f6SFlorian Hahndefine i1 @gep_i16_sub_1_uge_inbounds_var_idx(ptr %dst, i64 %off) {
5382de8f1f6SFlorian Hahn; CHECK-LABEL: @gep_i16_sub_1_uge_inbounds_var_idx(
5392de8f1f6SFlorian Hahn; CHECK-NEXT:    [[OFF_UGE:%.*]] = icmp sge i64 [[OFF:%.*]], 1
5402de8f1f6SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[OFF_UGE]])
5412de8f1f6SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_3:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i64 [[OFF]]
5422de8f1f6SFlorian Hahn; CHECK-NEXT:    [[DST_SUB_1:%.*]] = getelementptr inbounds i16, ptr [[DST_ADD_3]], i32 -1
5432de8f1f6SFlorian Hahn; CHECK-NEXT:    [[CMP_SUB_1:%.*]] = icmp ule ptr [[DST_SUB_1]], [[DST]]
5442de8f1f6SFlorian Hahn; CHECK-NEXT:    [[DST_SUB_2:%.*]] = getelementptr inbounds i16, ptr [[DST_ADD_3]], i64 -2
5452de8f1f6SFlorian Hahn; CHECK-NEXT:    [[CMP_SUB_2:%.*]] = icmp ule ptr [[DST_SUB_2]], [[DST]]
5462de8f1f6SFlorian Hahn; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 [[CMP_SUB_1]], [[CMP_SUB_2]]
5472de8f1f6SFlorian Hahn; CHECK-NEXT:    [[DST_SUB_3:%.*]] = getelementptr inbounds i16, ptr [[DST_ADD_3]], i64 -3
5482de8f1f6SFlorian Hahn; CHECK-NEXT:    [[CMP_SUB_3:%.*]] = icmp ule ptr [[DST_SUB_3]], [[DST]]
5492de8f1f6SFlorian Hahn; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_SUB_3]]
5502de8f1f6SFlorian Hahn; CHECK-NEXT:    ret i1 [[RES_2]]
5512de8f1f6SFlorian Hahn;
5522de8f1f6SFlorian Hahn  %off.uge = icmp sge i64 %off, 1
5532de8f1f6SFlorian Hahn  call void @llvm.assume(i1 %off.uge)
5542de8f1f6SFlorian Hahn  %dst.add.3 = getelementptr inbounds i8, ptr %dst, i64 %off
5552de8f1f6SFlorian Hahn  %dst.sub.1 = getelementptr inbounds i16, ptr %dst.add.3, i32 -1
5562de8f1f6SFlorian Hahn  %cmp.sub.1 = icmp ule ptr %dst.sub.1, %dst
5572de8f1f6SFlorian Hahn  %dst.sub.2 = getelementptr inbounds i16, ptr %dst.add.3, i64 -2
5582de8f1f6SFlorian Hahn  %cmp.sub.2 = icmp ule ptr %dst.sub.2, %dst
5592de8f1f6SFlorian Hahn  %res.1 = xor i1 %cmp.sub.1, %cmp.sub.2
5602de8f1f6SFlorian Hahn  %dst.sub.3 = getelementptr inbounds i16, ptr %dst.add.3, i64 -3
5612de8f1f6SFlorian Hahn  %cmp.sub.3 = icmp ule ptr %dst.sub.3, %dst
5622de8f1f6SFlorian Hahn  %res.2 = xor i1 %res.1, %cmp.sub.3
5632de8f1f6SFlorian Hahn  ret i1 %res.2
5642de8f1f6SFlorian Hahn}
56517a1104dSFlorian Hahn
56617a1104dSFlorian Hahndefine i1 @gep_i32_two_indices_known_lt_and_positive(ptr %a, i8 %idx.1, i8 %idx.2) {
56717a1104dSFlorian Hahn; CHECK-LABEL: @gep_i32_two_indices_known_lt_and_positive(
56817a1104dSFlorian Hahn; CHECK-NEXT:    [[LT:%.*]] = icmp ult i8 [[IDX_1:%.*]], [[IDX_2:%.*]]
56917a1104dSFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[LT]])
57017a1104dSFlorian Hahn; CHECK-NEXT:    [[IDX_1_POS:%.*]] = icmp sge i8 [[IDX_1]], 0
57117a1104dSFlorian Hahn; CHECK-NEXT:    [[IDX_2_POS:%.*]] = icmp sge i8 [[IDX_2]], 0
57217a1104dSFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[IDX_1_POS]])
57317a1104dSFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[IDX_2_POS]])
57417a1104dSFlorian Hahn; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i8 [[IDX_1]]
57517a1104dSFlorian Hahn; CHECK-NEXT:    [[GEP_2:%.*]] = getelementptr inbounds i32, ptr [[GEP_1]], i8 -3
57617a1104dSFlorian Hahn; CHECK-NEXT:    [[GEP_3:%.*]] = getelementptr inbounds i32, ptr [[A]], i8 [[IDX_2]]
57717a1104dSFlorian Hahn; CHECK-NEXT:    [[GEP_4:%.*]] = getelementptr inbounds i32, ptr [[GEP_3]], i8 -3
578*d045e23cSFlorian Hahn; CHECK-NEXT:    ret i1 true
57917a1104dSFlorian Hahn;
58017a1104dSFlorian Hahn  %lt = icmp ult i8 %idx.1, %idx.2
58117a1104dSFlorian Hahn  call void @llvm.assume(i1 %lt)
58217a1104dSFlorian Hahn  %idx.1.pos = icmp sge i8 %idx.1, 0
58317a1104dSFlorian Hahn  %idx.2.pos = icmp sge i8 %idx.2, 0
58417a1104dSFlorian Hahn  call void @llvm.assume(i1 %idx.1.pos)
58517a1104dSFlorian Hahn  call void @llvm.assume(i1 %idx.2.pos)
58617a1104dSFlorian Hahn  %gep.1 = getelementptr inbounds i32, ptr %a, i8 %idx.1
58717a1104dSFlorian Hahn  %gep.2 = getelementptr inbounds i32, ptr %gep.1, i8 -3
58817a1104dSFlorian Hahn  %gep.3 = getelementptr inbounds i32, ptr %a, i8 %idx.2
58917a1104dSFlorian Hahn  %gep.4 = getelementptr inbounds i32, ptr %gep.3, i8 -3
59017a1104dSFlorian Hahn  %c = icmp ult ptr %gep.2, %gep.4
59117a1104dSFlorian Hahn  ret i1 %c
59217a1104dSFlorian Hahn}
59317a1104dSFlorian Hahn
59417a1104dSFlorian Hahndefine i1 @gep_i32_two_indices_known_lt_and_not_known_positive(ptr %a, i8 %idx.1, i8 %idx.2) {
59517a1104dSFlorian Hahn; CHECK-LABEL: @gep_i32_two_indices_known_lt_and_not_known_positive(
59617a1104dSFlorian Hahn; CHECK-NEXT:    [[LT:%.*]] = icmp ult i8 [[IDX_1:%.*]], [[IDX_2:%.*]]
59717a1104dSFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[LT]])
59817a1104dSFlorian Hahn; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i8 [[IDX_1]]
59917a1104dSFlorian Hahn; CHECK-NEXT:    [[GEP_2:%.*]] = getelementptr inbounds i32, ptr [[GEP_1]], i8 -3
60017a1104dSFlorian Hahn; CHECK-NEXT:    [[GEP_3:%.*]] = getelementptr inbounds i32, ptr [[A]], i8 [[IDX_2]]
60117a1104dSFlorian Hahn; CHECK-NEXT:    [[GEP_4:%.*]] = getelementptr inbounds i32, ptr [[GEP_3]], i8 -3
60217a1104dSFlorian Hahn; CHECK-NEXT:    [[C:%.*]] = icmp ult ptr [[GEP_2]], [[GEP_4]]
60317a1104dSFlorian Hahn; CHECK-NEXT:    ret i1 [[C]]
60417a1104dSFlorian Hahn;
60517a1104dSFlorian Hahn  %lt = icmp ult i8 %idx.1, %idx.2
60617a1104dSFlorian Hahn  call void @llvm.assume(i1 %lt)
60717a1104dSFlorian Hahn  %gep.1 = getelementptr inbounds i32, ptr %a, i8 %idx.1
60817a1104dSFlorian Hahn  %gep.2 = getelementptr inbounds i32, ptr %gep.1, i8 -3
60917a1104dSFlorian Hahn  %gep.3 = getelementptr inbounds i32, ptr %a, i8 %idx.2
61017a1104dSFlorian Hahn  %gep.4 = getelementptr inbounds i32, ptr %gep.3, i8 -3
61117a1104dSFlorian Hahn  %c = icmp ult ptr %gep.2, %gep.4
61217a1104dSFlorian Hahn  ret i1 %c
61317a1104dSFlorian Hahn}
61417a1104dSFlorian Hahn
61517a1104dSFlorian Hahndefine i1 @gep_i32_two_indices_known_positive_but_not_lt(ptr %a, i8 %idx.1, i8 %idx.2) {
61617a1104dSFlorian Hahn; CHECK-LABEL: @gep_i32_two_indices_known_positive_but_not_lt(
61717a1104dSFlorian Hahn; CHECK-NEXT:    [[IDX_1_POS:%.*]] = icmp sge i8 [[IDX_1:%.*]], 0
61817a1104dSFlorian Hahn; CHECK-NEXT:    [[IDX_2_POS:%.*]] = icmp sge i8 [[IDX_2:%.*]], 0
61917a1104dSFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[IDX_1_POS]])
62017a1104dSFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[IDX_2_POS]])
62117a1104dSFlorian Hahn; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i8 [[IDX_1]]
62217a1104dSFlorian Hahn; CHECK-NEXT:    [[GEP_2:%.*]] = getelementptr inbounds i32, ptr [[GEP_1]], i8 -3
62317a1104dSFlorian Hahn; CHECK-NEXT:    [[GEP_3:%.*]] = getelementptr inbounds i32, ptr [[A]], i8 [[IDX_2]]
62417a1104dSFlorian Hahn; CHECK-NEXT:    [[GEP_4:%.*]] = getelementptr inbounds i32, ptr [[GEP_3]], i8 -3
62517a1104dSFlorian Hahn; CHECK-NEXT:    [[C:%.*]] = icmp ult ptr [[GEP_2]], [[GEP_4]]
62617a1104dSFlorian Hahn; CHECK-NEXT:    ret i1 [[C]]
62717a1104dSFlorian Hahn;
62817a1104dSFlorian Hahn  %idx.1.pos = icmp sge i8 %idx.1, 0
62917a1104dSFlorian Hahn  %idx.2.pos = icmp sge i8 %idx.2, 0
63017a1104dSFlorian Hahn  call void @llvm.assume(i1 %idx.1.pos)
63117a1104dSFlorian Hahn  call void @llvm.assume(i1 %idx.2.pos)
63217a1104dSFlorian Hahn  %gep.1 = getelementptr inbounds i32, ptr %a, i8 %idx.1
63317a1104dSFlorian Hahn  %gep.2 = getelementptr inbounds i32, ptr %gep.1, i8 -3
63417a1104dSFlorian Hahn  %gep.3 = getelementptr inbounds i32, ptr %a, i8 %idx.2
63517a1104dSFlorian Hahn  %gep.4 = getelementptr inbounds i32, ptr %gep.3, i8 -3
63617a1104dSFlorian Hahn  %c = icmp ult ptr %gep.2, %gep.4
63717a1104dSFlorian Hahn  ret i1 %c
63817a1104dSFlorian Hahn}
639