xref: /llvm-project/llvm/test/Transforms/ConstraintElimination/gep-arithmetic-signed-predicates.ll (revision 18170d0f281c2cae5252c501cbcd174783de78b7)
16b1396e3SFlorian Hahn; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
26b1396e3SFlorian Hahn; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
36b1396e3SFlorian Hahn
46b1396e3SFlorian Hahndeclare void @llvm.assume(i1 noundef) #0
56b1396e3SFlorian Hahn
66b1396e3SFlorian Hahndefine i1 @gep_constant_positive_index(ptr %dst, ptr %lower, ptr %upper) {
76b1396e3SFlorian Hahn; CHECK-LABEL: @gep_constant_positive_index(
86b1396e3SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_4:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i64 4
96b1396e3SFlorian Hahn; CHECK-NEXT:    [[PRE_DST_LOWER:%.*]] = icmp sge ptr [[DST]], [[LOWER:%.*]]
106b1396e3SFlorian Hahn; CHECK-NEXT:    [[PRE_DST_UPPER:%.*]] = icmp slt ptr [[DST_ADD_4]], [[UPPER:%.*]]
116b1396e3SFlorian Hahn; CHECK-NEXT:    [[AND:%.*]] = and i1 [[PRE_DST_LOWER]], [[PRE_DST_UPPER]]
126b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
136b1396e3SFlorian Hahn; CHECK:       then:
146b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_DST_UPPER:%.*]] = icmp slt ptr [[DST]], [[UPPER]]
156b1396e3SFlorian Hahn; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 true, [[CMP_DST_UPPER]]
166b1396e3SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 3
176b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_DST_ADD_3_LOWER:%.*]] = icmp sge ptr [[DST_ADD_3]], [[LOWER]]
186b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_DST_ADD_3_UPPER:%.*]] = icmp slt ptr [[DST_ADD_3]], [[UPPER]]
196b1396e3SFlorian Hahn; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_DST_ADD_3_LOWER]]
206b1396e3SFlorian Hahn; CHECK-NEXT:    [[RES_3:%.*]] = xor i1 [[RES_2]], [[CMP_DST_ADD_3_UPPER]]
216b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_DST_ADD_4_LOWER:%.*]] = icmp sge ptr [[DST_ADD_4]], [[LOWER]]
226b1396e3SFlorian Hahn; CHECK-NEXT:    [[RES_4:%.*]] = xor i1 [[RES_3]], [[CMP_DST_ADD_4_LOWER]]
236b1396e3SFlorian Hahn; CHECK-NEXT:    [[RES_5:%.*]] = xor i1 [[RES_4]], true
246b1396e3SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_5:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 5
256b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_DST_ADD_5_LOWER:%.*]] = icmp sge ptr [[DST_ADD_5]], [[LOWER]]
266b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_DST_ADD_5_UPPER:%.*]] = icmp slt ptr [[DST_ADD_5]], [[UPPER]]
276b1396e3SFlorian Hahn; CHECK-NEXT:    [[RES_6:%.*]] = xor i1 [[RES_5]], [[CMP_DST_ADD_5_LOWER]]
286b1396e3SFlorian Hahn; CHECK-NEXT:    [[RES_7:%.*]] = xor i1 [[RES_6]], [[CMP_DST_ADD_5_UPPER]]
296b1396e3SFlorian Hahn; CHECK-NEXT:    ret i1 [[RES_7]]
306b1396e3SFlorian Hahn; CHECK:       else:
316b1396e3SFlorian Hahn; CHECK-NEXT:    ret i1 false
326b1396e3SFlorian Hahn;
336b1396e3SFlorian Hahn  %dst.add.4 = getelementptr inbounds i8, ptr %dst, i64 4
346b1396e3SFlorian Hahn  %pre.dst.lower = icmp sge ptr %dst, %lower
356b1396e3SFlorian Hahn  %pre.dst.upper = icmp slt ptr %dst.add.4, %upper
366b1396e3SFlorian Hahn  %and = and i1 %pre.dst.lower, %pre.dst.upper
376b1396e3SFlorian Hahn  br i1 %and, label %then, label %else
386b1396e3SFlorian Hahn
396b1396e3SFlorian Hahnthen:
406b1396e3SFlorian Hahn  %cmp.dst.lower = icmp sge ptr %dst, %lower
416b1396e3SFlorian Hahn  %cmp.dst.upper = icmp slt ptr %dst, %upper
426b1396e3SFlorian Hahn  %res.1 = xor i1 %cmp.dst.lower, %cmp.dst.upper
436b1396e3SFlorian Hahn  %dst.add.3 = getelementptr inbounds i8, ptr %dst, i64 3
446b1396e3SFlorian Hahn  %cmp.dst.add.3.lower = icmp sge ptr %dst.add.3, %lower
456b1396e3SFlorian Hahn  %cmp.dst.add.3.upper = icmp slt ptr %dst.add.3, %upper
466b1396e3SFlorian Hahn  %res.2 = xor i1 %res.1, %cmp.dst.add.3.lower
476b1396e3SFlorian Hahn  %res.3 = xor i1 %res.2, %cmp.dst.add.3.upper
486b1396e3SFlorian Hahn  %cmp.dst.add.4.lower = icmp sge ptr %dst.add.4, %lower
496b1396e3SFlorian Hahn  %cmp.dst.add.4.upper = icmp slt ptr %dst.add.4, %upper
506b1396e3SFlorian Hahn  %res.4 = xor i1 %res.3, %cmp.dst.add.4.lower
516b1396e3SFlorian Hahn  %res.5 = xor i1 %res.4, %cmp.dst.add.4.upper
526b1396e3SFlorian Hahn  %dst.add.5 = getelementptr inbounds i8, ptr %dst, i64 5
536b1396e3SFlorian Hahn  %cmp.dst.add.5.lower = icmp sge ptr %dst.add.5, %lower
546b1396e3SFlorian Hahn  %cmp.dst.add.5.upper = icmp slt ptr %dst.add.5, %upper
556b1396e3SFlorian Hahn  %res.6 = xor i1 %res.5, %cmp.dst.add.5.lower
566b1396e3SFlorian Hahn  %res.7 = xor i1 %res.6, %cmp.dst.add.5.upper
576b1396e3SFlorian Hahn  ret i1 %res.7
586b1396e3SFlorian Hahn
596b1396e3SFlorian Hahnelse:
606b1396e3SFlorian Hahn  ret i1 false
616b1396e3SFlorian Hahn}
626b1396e3SFlorian Hahn
636b1396e3SFlorian Hahndefine i1 @gep_constant_negative_index(ptr %dst, ptr %lower, ptr %upper) {
646b1396e3SFlorian Hahn; CHECK-LABEL: @gep_constant_negative_index(
656b1396e3SFlorian Hahn; CHECK-NEXT:    [[DST_SUB_4:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i64 -4
666b1396e3SFlorian Hahn; CHECK-NEXT:    [[PRE_DST_LOWER:%.*]] = icmp sge ptr [[DST]], [[LOWER:%.*]]
676b1396e3SFlorian Hahn; CHECK-NEXT:    [[PRE_DST_UPPER:%.*]] = icmp slt ptr [[DST_SUB_4]], [[UPPER:%.*]]
686b1396e3SFlorian Hahn; CHECK-NEXT:    [[AND:%.*]] = and i1 [[PRE_DST_LOWER]], [[PRE_DST_UPPER]]
696b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
706b1396e3SFlorian Hahn; CHECK:       then:
716b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_DST_UPPER:%.*]] = icmp slt ptr [[DST]], [[UPPER]]
726b1396e3SFlorian Hahn; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 true, [[CMP_DST_UPPER]]
736b1396e3SFlorian Hahn; CHECK-NEXT:    [[DST_SUB_3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 -3
746b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_DST_SUB_3_LOWER:%.*]] = icmp sge ptr [[DST_SUB_3]], [[LOWER]]
756b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_DST_SUB_3_UPPER:%.*]] = icmp slt ptr [[DST_SUB_3]], [[UPPER]]
766b1396e3SFlorian Hahn; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_DST_SUB_3_LOWER]]
776b1396e3SFlorian Hahn; CHECK-NEXT:    [[RES_3:%.*]] = xor i1 [[RES_2]], [[CMP_DST_SUB_3_UPPER]]
786b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_DST_SUB_4_LOWER:%.*]] = icmp sge ptr [[DST_SUB_4]], [[LOWER]]
796b1396e3SFlorian Hahn; CHECK-NEXT:    [[RES_4:%.*]] = xor i1 [[RES_3]], [[CMP_DST_SUB_4_LOWER]]
806b1396e3SFlorian Hahn; CHECK-NEXT:    [[RES_5:%.*]] = xor i1 [[RES_4]], true
816b1396e3SFlorian Hahn; CHECK-NEXT:    [[DST_SUB_5:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 -5
826b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_DST_SUB_5_LOWER:%.*]] = icmp sge ptr [[DST_SUB_5]], [[LOWER]]
836b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_DST_SUB_5_UPPER:%.*]] = icmp slt ptr [[DST_SUB_5]], [[UPPER]]
846b1396e3SFlorian Hahn; CHECK-NEXT:    [[RES_6:%.*]] = xor i1 [[RES_5]], [[CMP_DST_SUB_5_LOWER]]
856b1396e3SFlorian Hahn; CHECK-NEXT:    [[RES_7:%.*]] = xor i1 [[RES_6]], [[CMP_DST_SUB_5_UPPER]]
866b1396e3SFlorian Hahn; CHECK-NEXT:    ret i1 [[RES_7]]
876b1396e3SFlorian Hahn; CHECK:       else:
886b1396e3SFlorian Hahn; CHECK-NEXT:    [[ELSE_CMP_DST_LOWER:%.*]] = icmp sge ptr [[DST]], [[LOWER]]
896b1396e3SFlorian Hahn; CHECK-NEXT:    [[ELSE_CMP_DST_UPPER:%.*]] = icmp slt ptr [[DST]], [[UPPER]]
906b1396e3SFlorian Hahn; CHECK-NEXT:    [[ELSE_RES_1:%.*]] = xor i1 [[ELSE_CMP_DST_LOWER]], [[ELSE_CMP_DST_UPPER]]
916b1396e3SFlorian Hahn; CHECK-NEXT:    [[ELSE_DST_SUB_3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 -3
926b1396e3SFlorian Hahn; CHECK-NEXT:    [[ELSE_CMP_DST_SUB_3_LOWER:%.*]] = icmp sge ptr [[ELSE_DST_SUB_3]], [[LOWER]]
936b1396e3SFlorian Hahn; CHECK-NEXT:    [[ELSE_CMP_DST_SUB_3_UPPER:%.*]] = icmp slt ptr [[ELSE_DST_SUB_3]], [[UPPER]]
946b1396e3SFlorian Hahn; CHECK-NEXT:    [[ELSE_RES_2:%.*]] = xor i1 [[ELSE_RES_1]], [[ELSE_CMP_DST_SUB_3_LOWER]]
956b1396e3SFlorian Hahn; CHECK-NEXT:    [[ELSE_RES_3:%.*]] = xor i1 [[ELSE_RES_2]], [[ELSE_CMP_DST_SUB_3_UPPER]]
966b1396e3SFlorian Hahn; CHECK-NEXT:    [[ELSE_CMP_DST_SUB_4_LOWER:%.*]] = icmp sge ptr [[DST_SUB_4]], [[LOWER]]
976b1396e3SFlorian Hahn; CHECK-NEXT:    [[ELSE_CMP_DST_SUB_4_UPPER:%.*]] = icmp slt ptr [[DST_SUB_4]], [[UPPER]]
986b1396e3SFlorian Hahn; CHECK-NEXT:    [[ELSE_RES_4:%.*]] = xor i1 [[ELSE_RES_3]], [[ELSE_CMP_DST_SUB_4_LOWER]]
996b1396e3SFlorian Hahn; CHECK-NEXT:    [[ELSE_RES_5:%.*]] = xor i1 [[ELSE_RES_4]], [[ELSE_CMP_DST_SUB_4_UPPER]]
1006b1396e3SFlorian Hahn; CHECK-NEXT:    [[ELSE_DST_SUB_5:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 -5
1016b1396e3SFlorian Hahn; CHECK-NEXT:    [[ELSE_CMP_DST_SUB_5_LOWER:%.*]] = icmp sge ptr [[ELSE_DST_SUB_5]], [[LOWER]]
1026b1396e3SFlorian Hahn; CHECK-NEXT:    [[ELSE_CMP_DST_SUB_5_UPPER:%.*]] = icmp slt ptr [[ELSE_DST_SUB_5]], [[UPPER]]
1036b1396e3SFlorian Hahn; CHECK-NEXT:    [[ELSE_RES_6:%.*]] = xor i1 [[ELSE_RES_5]], [[ELSE_CMP_DST_SUB_5_LOWER]]
1046b1396e3SFlorian Hahn; CHECK-NEXT:    [[ELSE_RES_7:%.*]] = xor i1 [[ELSE_RES_6]], [[ELSE_CMP_DST_SUB_5_UPPER]]
1056b1396e3SFlorian Hahn; CHECK-NEXT:    ret i1 [[ELSE_RES_7]]
1066b1396e3SFlorian Hahn;
1076b1396e3SFlorian Hahn  %dst.sub.4 = getelementptr inbounds i8, ptr %dst, i64 -4
1086b1396e3SFlorian Hahn  %pre.dst.lower = icmp sge ptr %dst, %lower
1096b1396e3SFlorian Hahn  %pre.dst.upper = icmp slt ptr %dst.sub.4, %upper
1106b1396e3SFlorian Hahn  %and = and i1 %pre.dst.lower, %pre.dst.upper
1116b1396e3SFlorian Hahn  br i1 %and, label %then, label %else
1126b1396e3SFlorian Hahn
1136b1396e3SFlorian Hahnthen:
1146b1396e3SFlorian Hahn  %cmp.dst.lower = icmp sge ptr %dst, %lower
1156b1396e3SFlorian Hahn  %cmp.dst.upper = icmp slt ptr %dst, %upper
1166b1396e3SFlorian Hahn  %res.1 = xor i1 %cmp.dst.lower, %cmp.dst.upper
1176b1396e3SFlorian Hahn  %dst.sub.3 = getelementptr inbounds i8, ptr %dst, i64 -3
1186b1396e3SFlorian Hahn  %cmp.dst.sub.3.lower = icmp sge ptr %dst.sub.3, %lower
1196b1396e3SFlorian Hahn  %cmp.dst.sub.3.upper = icmp slt ptr %dst.sub.3, %upper
1206b1396e3SFlorian Hahn  %res.2 = xor i1 %res.1, %cmp.dst.sub.3.lower
1216b1396e3SFlorian Hahn  %res.3 = xor i1 %res.2, %cmp.dst.sub.3.upper
1226b1396e3SFlorian Hahn  %cmp.dst.sub.4.lower = icmp sge ptr %dst.sub.4, %lower
1236b1396e3SFlorian Hahn  %cmp.dst.sub.4.upper = icmp slt ptr %dst.sub.4, %upper
1246b1396e3SFlorian Hahn  %res.4 = xor i1 %res.3, %cmp.dst.sub.4.lower
1256b1396e3SFlorian Hahn  %res.5 = xor i1 %res.4, %cmp.dst.sub.4.upper
1266b1396e3SFlorian Hahn  %dst.sub.5 = getelementptr inbounds i8, ptr %dst, i64 -5
1276b1396e3SFlorian Hahn  %cmp.dst.sub.5.lower = icmp sge ptr %dst.sub.5, %lower
1286b1396e3SFlorian Hahn  %cmp.dst.sub.5.upper = icmp slt ptr %dst.sub.5, %upper
1296b1396e3SFlorian Hahn  %res.6 = xor i1 %res.5, %cmp.dst.sub.5.lower
1306b1396e3SFlorian Hahn  %res.7 = xor i1 %res.6, %cmp.dst.sub.5.upper
1316b1396e3SFlorian Hahn  ret i1 %res.7
1326b1396e3SFlorian Hahn
1336b1396e3SFlorian Hahnelse:
1346b1396e3SFlorian Hahn  %else.cmp.dst.lower = icmp sge ptr %dst, %lower
1356b1396e3SFlorian Hahn  %else.cmp.dst.upper = icmp slt ptr %dst, %upper
1366b1396e3SFlorian Hahn  %else.res.1 = xor i1 %else.cmp.dst.lower, %else.cmp.dst.upper
1376b1396e3SFlorian Hahn  %else.dst.sub.3 = getelementptr inbounds i8, ptr %dst, i64 -3
1386b1396e3SFlorian Hahn  %else.cmp.dst.sub.3.lower = icmp sge ptr %else.dst.sub.3, %lower
1396b1396e3SFlorian Hahn  %else.cmp.dst.sub.3.upper = icmp slt ptr %else.dst.sub.3, %upper
1406b1396e3SFlorian Hahn  %else.res.2 = xor i1 %else.res.1, %else.cmp.dst.sub.3.lower
1416b1396e3SFlorian Hahn  %else.res.3 = xor i1 %else.res.2, %else.cmp.dst.sub.3.upper
1426b1396e3SFlorian Hahn  %else.cmp.dst.sub.4.lower = icmp sge ptr %dst.sub.4, %lower
1436b1396e3SFlorian Hahn  %else.cmp.dst.sub.4.upper = icmp slt ptr %dst.sub.4, %upper
1446b1396e3SFlorian Hahn  %else.res.4 = xor i1 %else.res.3, %else.cmp.dst.sub.4.lower
1456b1396e3SFlorian Hahn  %else.res.5 = xor i1 %else.res.4, %else.cmp.dst.sub.4.upper
1466b1396e3SFlorian Hahn  %else.dst.sub.5 = getelementptr inbounds i8, ptr %dst, i64 -5
1476b1396e3SFlorian Hahn  %else.cmp.dst.sub.5.lower = icmp sge ptr %else.dst.sub.5, %lower
1486b1396e3SFlorian Hahn  %else.cmp.dst.sub.5.upper = icmp slt ptr %else.dst.sub.5, %upper
1496b1396e3SFlorian Hahn  %else.res.6 = xor i1 %else.res.5, %else.cmp.dst.sub.5.lower
1506b1396e3SFlorian Hahn  %else.res.7 = xor i1 %else.res.6, %else.cmp.dst.sub.5.upper
1516b1396e3SFlorian Hahn  ret i1 %else.res.7
1526b1396e3SFlorian Hahn}
1536b1396e3SFlorian Hahn
1546b1396e3SFlorian Hahndefine i4 @ptr_N_signed_positive_explicit_check_constant_step(ptr %src, ptr %lower, ptr %upper, i16 %N) {
1556b1396e3SFlorian Hahn; CHECK-LABEL: @ptr_N_signed_positive_explicit_check_constant_step(
1566b1396e3SFlorian Hahn; CHECK-NEXT:  entry:
1576b1396e3SFlorian Hahn; CHECK-NEXT:    [[N_POS:%.*]] = icmp sge i16 [[N:%.*]], 0
1586b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[N_POS]], label [[ENTRY_1:%.*]], label [[TRAP_BB:%.*]]
1596b1396e3SFlorian Hahn; CHECK:       entry.1:
1606b1396e3SFlorian Hahn; CHECK-NEXT:    [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i16 [[N]]
1616b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_START:%.*]] = icmp slt ptr [[SRC]], [[LOWER:%.*]]
1626b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_END:%.*]] = icmp sge ptr [[SRC_END]], [[UPPER:%.*]]
1636b1396e3SFlorian Hahn; CHECK-NEXT:    [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
1646b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[OR_PRECOND_0]], label [[TRAP_BB]], label [[STEP_CHECK:%.*]]
1656b1396e3SFlorian Hahn; CHECK:       trap.bb:
1666b1396e3SFlorian Hahn; CHECK-NEXT:    ret i4 2
1676b1396e3SFlorian Hahn; CHECK:       step.check:
1686b1396e3SFlorian Hahn; CHECK-NEXT:    [[STEP_SLT_N:%.*]] = icmp slt i16 1, [[N]]
1696b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[STEP_SLT_N]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
1706b1396e3SFlorian Hahn; CHECK:       ptr.check:
1716b1396e3SFlorian Hahn; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i16 1
1726b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_STEP_START:%.*]] = icmp slt ptr [[SRC_STEP]], [[LOWER]]
1736b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_STEP_END:%.*]] = icmp sge ptr [[SRC_STEP]], [[UPPER]]
1746b1396e3SFlorian Hahn; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
1756b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
1766b1396e3SFlorian Hahn; CHECK:       exit:
1776b1396e3SFlorian Hahn; CHECK-NEXT:    ret i4 3
1786b1396e3SFlorian Hahn;
1796b1396e3SFlorian Hahnentry:
1806b1396e3SFlorian Hahn  %N.pos = icmp sge i16 %N, 0
1816b1396e3SFlorian Hahn  br i1 %N.pos, label %entry.1, label %trap.bb
1826b1396e3SFlorian Hahn
1836b1396e3SFlorian Hahnentry.1:
1846b1396e3SFlorian Hahn  %src.end = getelementptr inbounds i8, ptr %src, i16 %N
1856b1396e3SFlorian Hahn  %cmp.src.start = icmp slt ptr %src, %lower
1866b1396e3SFlorian Hahn  %cmp.src.end = icmp sge ptr %src.end, %upper
1876b1396e3SFlorian Hahn  %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
1886b1396e3SFlorian Hahn  br i1 %or.precond.0, label %trap.bb, label %step.check
1896b1396e3SFlorian Hahn
1906b1396e3SFlorian Hahntrap.bb:
1916b1396e3SFlorian Hahn  ret i4 2
1926b1396e3SFlorian Hahn
1936b1396e3SFlorian Hahnstep.check:
1946b1396e3SFlorian Hahn  %step.slt.N = icmp slt i16 1, %N
1956b1396e3SFlorian Hahn  br i1 %step.slt.N, label %ptr.check, label %exit
1966b1396e3SFlorian Hahn
1976b1396e3SFlorian Hahnptr.check:
1986b1396e3SFlorian Hahn  %src.step = getelementptr inbounds i8, ptr %src, i16 1
1996b1396e3SFlorian Hahn  %cmp.step.start = icmp slt ptr %src.step, %lower
2006b1396e3SFlorian Hahn  %cmp.step.end = icmp sge ptr %src.step, %upper
2016b1396e3SFlorian Hahn  %or.check = or i1 %cmp.step.start, %cmp.step.end
2026b1396e3SFlorian Hahn  br i1 %or.check, label %trap.bb, label %exit
2036b1396e3SFlorian Hahn
2046b1396e3SFlorian Hahnexit:
2056b1396e3SFlorian Hahn  ret i4 3
2066b1396e3SFlorian Hahn}
2076b1396e3SFlorian Hahn
2086b1396e3SFlorian Hahn; Same as ptr_N_signed_positive_explicit_check_constant_step, but without inbounds.
2096b1396e3SFlorian Hahndefine i4 @ptr_N_signed_positive_explicit_check_constant_step_no_inbonds(ptr %src, ptr %lower, ptr %upper, i16 %N) {
2106b1396e3SFlorian Hahn; CHECK-LABEL: @ptr_N_signed_positive_explicit_check_constant_step_no_inbonds(
2116b1396e3SFlorian Hahn; CHECK-NEXT:  entry:
2126b1396e3SFlorian Hahn; CHECK-NEXT:    [[N_POS:%.*]] = icmp sge i16 [[N:%.*]], 0
2136b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[N_POS]], label [[ENTRY_1:%.*]], label [[TRAP_BB:%.*]]
2146b1396e3SFlorian Hahn; CHECK:       entry.1:
2156b1396e3SFlorian Hahn; CHECK-NEXT:    [[SRC_END:%.*]] = getelementptr i8, ptr [[SRC:%.*]], i16 [[N]]
2166b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_START:%.*]] = icmp slt ptr [[SRC]], [[LOWER:%.*]]
2176b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_END:%.*]] = icmp sge ptr [[SRC_END]], [[UPPER:%.*]]
2186b1396e3SFlorian Hahn; CHECK-NEXT:    [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
2196b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[OR_PRECOND_0]], label [[TRAP_BB]], label [[STEP_CHECK:%.*]]
2206b1396e3SFlorian Hahn; CHECK:       trap.bb:
2216b1396e3SFlorian Hahn; CHECK-NEXT:    ret i4 2
2226b1396e3SFlorian Hahn; CHECK:       step.check:
2236b1396e3SFlorian Hahn; CHECK-NEXT:    [[STEP_SLT_N:%.*]] = icmp slt i16 1, [[N]]
2246b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[STEP_SLT_N]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
2256b1396e3SFlorian Hahn; CHECK:       ptr.check:
2266b1396e3SFlorian Hahn; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr i8, ptr [[SRC]], i16 1
2276b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_STEP_START:%.*]] = icmp slt ptr [[SRC_STEP]], [[LOWER]]
2286b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_STEP_END:%.*]] = icmp sge ptr [[SRC_STEP]], [[UPPER]]
2296b1396e3SFlorian Hahn; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
2306b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
2316b1396e3SFlorian Hahn; CHECK:       exit:
2326b1396e3SFlorian Hahn; CHECK-NEXT:    ret i4 3
2336b1396e3SFlorian Hahn;
2346b1396e3SFlorian Hahnentry:
2356b1396e3SFlorian Hahn  %N.pos = icmp sge i16 %N, 0
2366b1396e3SFlorian Hahn  br i1 %N.pos, label %entry.1, label %trap.bb
2376b1396e3SFlorian Hahn
2386b1396e3SFlorian Hahnentry.1:
2396b1396e3SFlorian Hahn  %src.end = getelementptr i8, ptr %src, i16 %N
2406b1396e3SFlorian Hahn  %cmp.src.start = icmp slt ptr %src, %lower
2416b1396e3SFlorian Hahn  %cmp.src.end = icmp sge ptr %src.end, %upper
2426b1396e3SFlorian Hahn  %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
2436b1396e3SFlorian Hahn  br i1 %or.precond.0, label %trap.bb, label %step.check
2446b1396e3SFlorian Hahn
2456b1396e3SFlorian Hahntrap.bb:
2466b1396e3SFlorian Hahn  ret i4 2
2476b1396e3SFlorian Hahn
2486b1396e3SFlorian Hahnstep.check:
2496b1396e3SFlorian Hahn  %step.slt.N = icmp slt i16 1, %N
2506b1396e3SFlorian Hahn  br i1 %step.slt.N, label %ptr.check, label %exit
2516b1396e3SFlorian Hahn
2526b1396e3SFlorian Hahnptr.check:
2536b1396e3SFlorian Hahn  %src.step = getelementptr i8, ptr %src, i16 1
2546b1396e3SFlorian Hahn  %cmp.step.start = icmp slt ptr %src.step, %lower
2556b1396e3SFlorian Hahn  %cmp.step.end = icmp sge ptr %src.step, %upper
2566b1396e3SFlorian Hahn  %or.check = or i1 %cmp.step.start, %cmp.step.end
2576b1396e3SFlorian Hahn  br i1 %or.check, label %trap.bb, label %exit
2586b1396e3SFlorian Hahn
2596b1396e3SFlorian Hahnexit:
2606b1396e3SFlorian Hahn  ret i4 3
2616b1396e3SFlorian Hahn}
2626b1396e3SFlorian Hahn
2636b1396e3SFlorian Hahndefine i4 @ptr_N_and_step_signed_positive_explicit_check_constant_step(ptr %src, ptr %lower, ptr %upper, i16 %N, i16 %step) {
2646b1396e3SFlorian Hahn; CHECK-LABEL: @ptr_N_and_step_signed_positive_explicit_check_constant_step(
2656b1396e3SFlorian Hahn; CHECK-NEXT:  entry:
2666b1396e3SFlorian Hahn; CHECK-NEXT:    [[N_POS:%.*]] = icmp sge i16 [[N:%.*]], 0
2676b1396e3SFlorian Hahn; CHECK-NEXT:    [[STEP_POS:%.*]] = icmp sge i16 [[STEP:%.*]], 0
2686b1396e3SFlorian Hahn; CHECK-NEXT:    [[AND_1:%.*]] = and i1 [[N_POS]], [[STEP_POS]]
2696b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[AND_1]], label [[ENTRY_1:%.*]], label [[TRAP_BB:%.*]]
2706b1396e3SFlorian Hahn; CHECK:       entry.1:
2716b1396e3SFlorian Hahn; CHECK-NEXT:    [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i16 [[N]]
2726b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_START:%.*]] = icmp slt ptr [[SRC]], [[LOWER:%.*]]
2736b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_END:%.*]] = icmp sge ptr [[SRC_END]], [[UPPER:%.*]]
2746b1396e3SFlorian Hahn; CHECK-NEXT:    [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
2756b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[OR_PRECOND_0]], label [[TRAP_BB]], label [[STEP_CHECK:%.*]]
2766b1396e3SFlorian Hahn; CHECK:       trap.bb:
2776b1396e3SFlorian Hahn; CHECK-NEXT:    ret i4 2
2786b1396e3SFlorian Hahn; CHECK:       step.check:
2796b1396e3SFlorian Hahn; CHECK-NEXT:    [[STEP_SLT_N:%.*]] = icmp slt i16 [[STEP]], [[N]]
2806b1396e3SFlorian Hahn; CHECK-NEXT:    [[AND_2:%.*]] = and i1 true, [[STEP_SLT_N]]
2816b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[AND_2]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
2826b1396e3SFlorian Hahn; CHECK:       ptr.check:
2836b1396e3SFlorian Hahn; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i16 1
2846b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_STEP_START:%.*]] = icmp slt ptr [[SRC_STEP]], [[LOWER]]
2856b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_STEP_END:%.*]] = icmp sge ptr [[SRC_STEP]], [[UPPER]]
2866b1396e3SFlorian Hahn; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
2876b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
2886b1396e3SFlorian Hahn; CHECK:       exit:
2896b1396e3SFlorian Hahn; CHECK-NEXT:    ret i4 3
2906b1396e3SFlorian Hahn;
2916b1396e3SFlorian Hahnentry:
2926b1396e3SFlorian Hahn  %N.pos = icmp sge i16 %N, 0
2936b1396e3SFlorian Hahn  %step.pos = icmp sge i16 %step, 0
2946b1396e3SFlorian Hahn  %and.1 = and i1 %N.pos, %step.pos
2956b1396e3SFlorian Hahn  br i1 %and.1, label %entry.1, label %trap.bb
2966b1396e3SFlorian Hahn
2976b1396e3SFlorian Hahnentry.1:
2986b1396e3SFlorian Hahn  %src.end = getelementptr inbounds i8, ptr %src, i16 %N
2996b1396e3SFlorian Hahn  %cmp.src.start = icmp slt ptr %src, %lower
3006b1396e3SFlorian Hahn  %cmp.src.end = icmp sge ptr %src.end, %upper
3016b1396e3SFlorian Hahn  %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
3026b1396e3SFlorian Hahn  br i1 %or.precond.0, label %trap.bb, label %step.check
3036b1396e3SFlorian Hahn
3046b1396e3SFlorian Hahntrap.bb:
3056b1396e3SFlorian Hahn  ret i4 2
3066b1396e3SFlorian Hahn
3076b1396e3SFlorian Hahnstep.check:
3086b1396e3SFlorian Hahn  %step.sge.0 = icmp sge i16 %step, 0
3096b1396e3SFlorian Hahn  %step.slt.N = icmp slt i16 %step, %N
3106b1396e3SFlorian Hahn  %and.2 = and i1 %step.sge.0, %step.slt.N
3116b1396e3SFlorian Hahn  br i1 %and.2, label %ptr.check, label %exit
3126b1396e3SFlorian Hahn
3136b1396e3SFlorian Hahnptr.check:
3146b1396e3SFlorian Hahn  %src.step = getelementptr inbounds i8, ptr %src, i16 1
3156b1396e3SFlorian Hahn  %cmp.step.start = icmp slt ptr %src.step, %lower
3166b1396e3SFlorian Hahn  %cmp.step.end = icmp sge ptr %src.step, %upper
3176b1396e3SFlorian Hahn  %or.check = or i1 %cmp.step.start, %cmp.step.end
3186b1396e3SFlorian Hahn  br i1 %or.check, label %trap.bb, label %exit
3196b1396e3SFlorian Hahn
3206b1396e3SFlorian Hahnexit:
3216b1396e3SFlorian Hahn  ret i4 3
3226b1396e3SFlorian Hahn}
3236b1396e3SFlorian Hahn
3246b1396e3SFlorian Hahndefine i4 @ptr_N_and_step_signed_positive_unsigned_checks_only(ptr %src, ptr %lower, ptr %upper, i16 %N, i16 %step) {
3256b1396e3SFlorian Hahn; CHECK-LABEL: @ptr_N_and_step_signed_positive_unsigned_checks_only(
3266b1396e3SFlorian Hahn; CHECK-NEXT:  entry:
3276b1396e3SFlorian Hahn; CHECK-NEXT:    [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i16 [[N:%.*]]
3286b1396e3SFlorian Hahn; CHECK-NEXT:    [[NO_OVERFLOW:%.*]] = icmp sle ptr [[SRC]], [[SRC_END]]
3296b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[NO_OVERFLOW]], label [[ENTRY_1:%.*]], label [[TRAP_BB:%.*]]
3306b1396e3SFlorian Hahn; CHECK:       entry.1:
3316b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_START:%.*]] = icmp slt ptr [[SRC]], [[LOWER:%.*]]
3326b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_END:%.*]] = icmp sge ptr [[SRC_END]], [[UPPER:%.*]]
3336b1396e3SFlorian Hahn; CHECK-NEXT:    [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
3346b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[OR_PRECOND_0]], label [[TRAP_BB]], label [[STEP_CHECK:%.*]]
3356b1396e3SFlorian Hahn; CHECK:       trap.bb:
3366b1396e3SFlorian Hahn; CHECK-NEXT:    ret i4 2
3376b1396e3SFlorian Hahn; CHECK:       step.check:
3386b1396e3SFlorian Hahn; CHECK-NEXT:    [[STEP_SGE_0:%.*]] = icmp sge i16 [[STEP:%.*]], 0
3396b1396e3SFlorian Hahn; CHECK-NEXT:    [[STEP_SLT_N:%.*]] = icmp slt i16 [[STEP]], [[N]]
3406b1396e3SFlorian Hahn; CHECK-NEXT:    [[AND_2:%.*]] = and i1 [[STEP_SGE_0]], [[STEP_SLT_N]]
3416b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[AND_2]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
3426b1396e3SFlorian Hahn; CHECK:       ptr.check:
3436b1396e3SFlorian Hahn; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i16 1
3446b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_STEP_START:%.*]] = icmp slt ptr [[SRC_STEP]], [[LOWER]]
3456b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_STEP_END:%.*]] = icmp sge ptr [[SRC_STEP]], [[UPPER]]
3466b1396e3SFlorian Hahn; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
3476b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
3486b1396e3SFlorian Hahn; CHECK:       exit:
3496b1396e3SFlorian Hahn; CHECK-NEXT:    ret i4 3
3506b1396e3SFlorian Hahn;
3516b1396e3SFlorian Hahnentry:
3526b1396e3SFlorian Hahn  %src.end = getelementptr inbounds i8, ptr %src, i16 %N
3536b1396e3SFlorian Hahn  %no.overflow = icmp sle ptr %src, %src.end
3546b1396e3SFlorian Hahn  br i1 %no.overflow, label %entry.1, label %trap.bb
3556b1396e3SFlorian Hahn
3566b1396e3SFlorian Hahnentry.1:
3576b1396e3SFlorian Hahn  %cmp.src.start = icmp slt ptr %src, %lower
3586b1396e3SFlorian Hahn  %cmp.src.end = icmp sge ptr %src.end, %upper
3596b1396e3SFlorian Hahn  %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
3606b1396e3SFlorian Hahn  br i1 %or.precond.0, label %trap.bb, label %step.check
3616b1396e3SFlorian Hahn
3626b1396e3SFlorian Hahntrap.bb:
3636b1396e3SFlorian Hahn  ret i4 2
3646b1396e3SFlorian Hahn
3656b1396e3SFlorian Hahnstep.check:
3666b1396e3SFlorian Hahn  %step.sge.0 = icmp sge i16 %step, 0
3676b1396e3SFlorian Hahn  %step.slt.N = icmp slt i16 %step, %N
3686b1396e3SFlorian Hahn  %and.2 = and i1 %step.sge.0, %step.slt.N
3696b1396e3SFlorian Hahn  br i1 %and.2, label %ptr.check, label %exit
3706b1396e3SFlorian Hahn
3716b1396e3SFlorian Hahnptr.check:
3726b1396e3SFlorian Hahn  %src.step = getelementptr inbounds i8, ptr %src, i16 1
3736b1396e3SFlorian Hahn  %cmp.step.start = icmp slt ptr %src.step, %lower
3746b1396e3SFlorian Hahn  %cmp.step.end = icmp sge ptr %src.step, %upper
3756b1396e3SFlorian Hahn  %or.check = or i1 %cmp.step.start, %cmp.step.end
3766b1396e3SFlorian Hahn  br i1 %or.check, label %trap.bb, label %exit
3776b1396e3SFlorian Hahn
3786b1396e3SFlorian Hahnexit:
3796b1396e3SFlorian Hahn  ret i4 3
3806b1396e3SFlorian Hahn}
3816b1396e3SFlorian Hahn
3826b1396e3SFlorian Hahndefine i4 @ptr_N_signed_positive(ptr %src, ptr %lower, ptr %upper, i16 %N, i16 %step) {
3836b1396e3SFlorian Hahn; CHECK-LABEL: @ptr_N_signed_positive(
3846b1396e3SFlorian Hahn; CHECK-NEXT:  entry:
3856b1396e3SFlorian Hahn; CHECK-NEXT:    [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i16 [[N:%.*]]
3866b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_START:%.*]] = icmp slt ptr [[SRC]], [[LOWER:%.*]]
3876b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_END:%.*]] = icmp sge ptr [[SRC_END]], [[UPPER:%.*]]
3886b1396e3SFlorian Hahn; CHECK-NEXT:    [[N_NEG:%.*]] = icmp slt i16 [[N]], 0
3896b1396e3SFlorian Hahn; CHECK-NEXT:    [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
3906b1396e3SFlorian Hahn; CHECK-NEXT:    [[OR_PRECOND_1:%.*]] = or i1 [[OR_PRECOND_0]], [[N_NEG]]
3916b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[OR_PRECOND_1]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]
3926b1396e3SFlorian Hahn; CHECK:       trap.bb:
3936b1396e3SFlorian Hahn; CHECK-NEXT:    ret i4 2
3946b1396e3SFlorian Hahn; CHECK:       step.check:
3956b1396e3SFlorian Hahn; CHECK-NEXT:    [[STEP_POS:%.*]] = icmp sge i16 [[STEP:%.*]], 0
3966b1396e3SFlorian Hahn; CHECK-NEXT:    [[STEP_SLT_N:%.*]] = icmp slt i16 [[STEP]], [[N]]
3976b1396e3SFlorian Hahn; CHECK-NEXT:    [[AND_STEP:%.*]] = and i1 [[STEP_POS]], [[STEP_SLT_N]]
3986b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[AND_STEP]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
3996b1396e3SFlorian Hahn; CHECK:       ptr.check:
4006b1396e3SFlorian Hahn; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i16 [[STEP]]
4016b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_STEP_START:%.*]] = icmp slt ptr [[SRC_STEP]], [[LOWER]]
4026b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_STEP_END:%.*]] = icmp sge ptr [[SRC_STEP]], [[UPPER]]
4036b1396e3SFlorian Hahn; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
4046b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
4056b1396e3SFlorian Hahn; CHECK:       exit:
4066b1396e3SFlorian Hahn; CHECK-NEXT:    ret i4 3
4076b1396e3SFlorian Hahn;
4086b1396e3SFlorian Hahnentry:
4096b1396e3SFlorian Hahn  %src.end = getelementptr inbounds i8, ptr %src, i16 %N
4106b1396e3SFlorian Hahn  %cmp.src.start = icmp slt ptr %src, %lower
4116b1396e3SFlorian Hahn  %cmp.src.end = icmp sge ptr %src.end, %upper
4126b1396e3SFlorian Hahn  %N.neg = icmp slt i16 %N, 0
4136b1396e3SFlorian Hahn  %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
4146b1396e3SFlorian Hahn  %or.precond.1 = or i1 %or.precond.0, %N.neg
4156b1396e3SFlorian Hahn  br i1 %or.precond.1, label %trap.bb, label %step.check
4166b1396e3SFlorian Hahn
4176b1396e3SFlorian Hahntrap.bb:
4186b1396e3SFlorian Hahn  ret i4 2
4196b1396e3SFlorian Hahn
4206b1396e3SFlorian Hahnstep.check:
4216b1396e3SFlorian Hahn  %step.pos = icmp sge i16 %step, 0
4226b1396e3SFlorian Hahn  %step.slt.N = icmp slt i16 %step, %N
4236b1396e3SFlorian Hahn  %and.step = and i1 %step.pos, %step.slt.N
4246b1396e3SFlorian Hahn  br i1 %and.step, label %ptr.check, label %exit
4256b1396e3SFlorian Hahn
4266b1396e3SFlorian Hahnptr.check:
4276b1396e3SFlorian Hahn  %src.step = getelementptr inbounds i8, ptr %src, i16 %step
4286b1396e3SFlorian Hahn  %cmp.step.start = icmp slt ptr %src.step, %lower
4296b1396e3SFlorian Hahn  %cmp.step.end = icmp sge ptr %src.step, %upper
4306b1396e3SFlorian Hahn  %or.check = or i1 %cmp.step.start, %cmp.step.end
4316b1396e3SFlorian Hahn  br i1 %or.check, label %trap.bb, label %exit
4326b1396e3SFlorian Hahn
4336b1396e3SFlorian Hahnexit:
4346b1396e3SFlorian Hahn  ret i4 3
4356b1396e3SFlorian Hahn}
4366b1396e3SFlorian Hahn
4376b1396e3SFlorian Hahndefine i4 @ptr_N_could_be_negative(ptr %src, ptr %lower, ptr %upper, i8 %N, i8 %step) {
4386b1396e3SFlorian Hahn; CHECK-LABEL: @ptr_N_could_be_negative(
4396b1396e3SFlorian Hahn; CHECK-NEXT:  entry:
4406b1396e3SFlorian Hahn; CHECK-NEXT:    [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i8 [[N:%.*]]
4416b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_START:%.*]] = icmp slt ptr [[SRC]], [[LOWER:%.*]]
4426b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_END:%.*]] = icmp sge ptr [[SRC_END]], [[UPPER:%.*]]
4436b1396e3SFlorian Hahn; CHECK-NEXT:    [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
4446b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[OR_PRECOND_0]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]
4456b1396e3SFlorian Hahn; CHECK:       trap.bb:
4466b1396e3SFlorian Hahn; CHECK-NEXT:    ret i4 2
4476b1396e3SFlorian Hahn; CHECK:       step.check:
4486b1396e3SFlorian Hahn; CHECK-NEXT:    [[STEP_POS:%.*]] = icmp sge i8 [[STEP:%.*]], 0
4496b1396e3SFlorian Hahn; CHECK-NEXT:    [[STEP_SLT_N:%.*]] = icmp slt i8 [[STEP]], [[N]]
4506b1396e3SFlorian Hahn; CHECK-NEXT:    [[AND_STEP:%.*]] = and i1 [[STEP_POS]], [[STEP_SLT_N]]
4516b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[AND_STEP]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
4526b1396e3SFlorian Hahn; CHECK:       ptr.check:
4536b1396e3SFlorian Hahn; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i8 [[STEP]]
4546b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_STEP_START:%.*]] = icmp slt ptr [[SRC_STEP]], [[LOWER]]
4556b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_STEP_END:%.*]] = icmp sge ptr [[SRC_STEP]], [[UPPER]]
4566b1396e3SFlorian Hahn; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
4576b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
4586b1396e3SFlorian Hahn; CHECK:       exit:
4596b1396e3SFlorian Hahn; CHECK-NEXT:    ret i4 3
4606b1396e3SFlorian Hahn;
4616b1396e3SFlorian Hahnentry:
4626b1396e3SFlorian Hahn  %src.end = getelementptr inbounds i8, ptr %src, i8 %N
4636b1396e3SFlorian Hahn  %cmp.src.start = icmp slt ptr %src, %lower
4646b1396e3SFlorian Hahn  %cmp.src.end = icmp sge ptr %src.end, %upper
4656b1396e3SFlorian Hahn  %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
4666b1396e3SFlorian Hahn  br i1 %or.precond.0, label %trap.bb, label %step.check
4676b1396e3SFlorian Hahn
4686b1396e3SFlorian Hahntrap.bb:
4696b1396e3SFlorian Hahn  ret i4 2
4706b1396e3SFlorian Hahn
4716b1396e3SFlorian Hahnstep.check:
4726b1396e3SFlorian Hahn  %step.pos = icmp sge i8 %step, 0
4736b1396e3SFlorian Hahn  %step.slt.N = icmp slt i8 %step, %N
4746b1396e3SFlorian Hahn  %and.step = and i1 %step.pos, %step.slt.N
4756b1396e3SFlorian Hahn  br i1 %and.step, label %ptr.check, label %exit
4766b1396e3SFlorian Hahn
4776b1396e3SFlorian Hahnptr.check:
4786b1396e3SFlorian Hahn  %src.step = getelementptr inbounds i8, ptr %src, i8 %step
4796b1396e3SFlorian Hahn  %cmp.step.start = icmp slt ptr %src.step, %lower
4806b1396e3SFlorian Hahn  %cmp.step.end = icmp sge ptr %src.step, %upper
4816b1396e3SFlorian Hahn  %or.check = or i1 %cmp.step.start, %cmp.step.end
4826b1396e3SFlorian Hahn  br i1 %or.check, label %trap.bb, label %exit
4836b1396e3SFlorian Hahn
4846b1396e3SFlorian Hahnexit:
4856b1396e3SFlorian Hahn  ret i4 3
4866b1396e3SFlorian Hahn}
4876b1396e3SFlorian Hahn
4886b1396e3SFlorian Hahndefine i4 @ptr_src_sge_end(ptr %src, ptr %lower, ptr %upper, i8 %N, i8 %step) {
4896b1396e3SFlorian Hahn; CHECK-LABEL: @ptr_src_sge_end(
4906b1396e3SFlorian Hahn; CHECK-NEXT:  entry:
4916b1396e3SFlorian Hahn; CHECK-NEXT:    [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i8 [[N:%.*]]
4926b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_START:%.*]] = icmp slt ptr [[SRC]], [[LOWER:%.*]]
4936b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_END:%.*]] = icmp sge ptr [[SRC_END]], [[UPPER:%.*]]
4946b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_OVERFLOW:%.*]] = icmp sgt ptr [[SRC]], [[SRC_END]]
4956b1396e3SFlorian Hahn; CHECK-NEXT:    [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
4966b1396e3SFlorian Hahn; CHECK-NEXT:    [[OR_PRECOND_1:%.*]] = or i1 [[OR_PRECOND_0]], [[CMP_OVERFLOW]]
4976b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[OR_PRECOND_1]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]
4986b1396e3SFlorian Hahn; CHECK:       trap.bb:
4996b1396e3SFlorian Hahn; CHECK-NEXT:    ret i4 2
5006b1396e3SFlorian Hahn; CHECK:       step.check:
5016b1396e3SFlorian Hahn; CHECK-NEXT:    [[STEP_POS:%.*]] = icmp sge i8 [[STEP:%.*]], 0
5026b1396e3SFlorian Hahn; CHECK-NEXT:    [[STEP_SLT_N:%.*]] = icmp slt i8 [[STEP]], [[N]]
5036b1396e3SFlorian Hahn; CHECK-NEXT:    [[AND_STEP:%.*]] = and i1 [[STEP_POS]], [[STEP_SLT_N]]
5046b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[AND_STEP]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
5056b1396e3SFlorian Hahn; CHECK:       ptr.check:
5066b1396e3SFlorian Hahn; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i8 [[STEP]]
5076b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_STEP_START:%.*]] = icmp slt ptr [[SRC_STEP]], [[LOWER]]
5086b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_STEP_END:%.*]] = icmp sge ptr [[SRC_STEP]], [[UPPER]]
5096b1396e3SFlorian Hahn; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
5106b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
5116b1396e3SFlorian Hahn; CHECK:       exit:
5126b1396e3SFlorian Hahn; CHECK-NEXT:    ret i4 3
5136b1396e3SFlorian Hahn;
5146b1396e3SFlorian Hahnentry:
5156b1396e3SFlorian Hahn  %src.end = getelementptr inbounds i8, ptr %src, i8 %N
5166b1396e3SFlorian Hahn  %cmp.src.start = icmp slt ptr %src, %lower
5176b1396e3SFlorian Hahn  %cmp.src.end = icmp sge ptr %src.end, %upper
5186b1396e3SFlorian Hahn  %cmp.overflow = icmp sgt ptr %src, %src.end
5196b1396e3SFlorian Hahn  %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
5206b1396e3SFlorian Hahn  %or.precond.1 = or i1 %or.precond.0, %cmp.overflow
5216b1396e3SFlorian Hahn  br i1 %or.precond.1, label %trap.bb, label %step.check
5226b1396e3SFlorian Hahn
5236b1396e3SFlorian Hahntrap.bb:
5246b1396e3SFlorian Hahn  ret i4 2
5256b1396e3SFlorian Hahn
5266b1396e3SFlorian Hahnstep.check:
5276b1396e3SFlorian Hahn  %step.pos = icmp sge i8 %step, 0
5286b1396e3SFlorian Hahn  %step.slt.N = icmp slt i8 %step, %N
5296b1396e3SFlorian Hahn  %and.step = and i1 %step.pos, %step.slt.N
5306b1396e3SFlorian Hahn  br i1 %and.step, label %ptr.check, label %exit
5316b1396e3SFlorian Hahn
5326b1396e3SFlorian Hahnptr.check:
5336b1396e3SFlorian Hahn  %src.step = getelementptr inbounds i8, ptr %src, i8 %step
5346b1396e3SFlorian Hahn  %cmp.step.start = icmp slt ptr %src.step, %lower
5356b1396e3SFlorian Hahn  %cmp.step.end = icmp sge ptr %src.step, %upper
5366b1396e3SFlorian Hahn  %or.check = or i1 %cmp.step.start, %cmp.step.end
5376b1396e3SFlorian Hahn  br i1 %or.check, label %trap.bb, label %exit
5386b1396e3SFlorian Hahn
5396b1396e3SFlorian Hahnexit:
5406b1396e3SFlorian Hahn  ret i4 3
5416b1396e3SFlorian Hahn}
5426b1396e3SFlorian Hahn
5436b1396e3SFlorian Hahn; N might be negative, meaning %src.end could be < %src! Cannot remove checks!
5446b1396e3SFlorian Hahndefine i4 @ptr_N_unsigned_positive(ptr %src, ptr %lower, ptr %upper, i16 %N, i16 %step) {
5456b1396e3SFlorian Hahn; CHECK-LABEL: @ptr_N_unsigned_positive(
5466b1396e3SFlorian Hahn; CHECK-NEXT:  entry:
5476b1396e3SFlorian Hahn; CHECK-NEXT:    [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i16 [[N:%.*]]
5486b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_START:%.*]] = icmp slt ptr [[SRC]], [[LOWER:%.*]]
5496b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_END:%.*]] = icmp sge ptr [[SRC_END]], [[UPPER:%.*]]
5506b1396e3SFlorian Hahn; CHECK-NEXT:    [[N_NEG:%.*]] = icmp slt i16 [[N]], 0
5516b1396e3SFlorian Hahn; CHECK-NEXT:    [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
5526b1396e3SFlorian Hahn; CHECK-NEXT:    [[OR_PRECOND_1:%.*]] = or i1 [[OR_PRECOND_0]], [[N_NEG]]
5536b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[OR_PRECOND_1]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]
5546b1396e3SFlorian Hahn; CHECK:       trap.bb:
5556b1396e3SFlorian Hahn; CHECK-NEXT:    ret i4 2
5566b1396e3SFlorian Hahn; CHECK:       step.check:
5576b1396e3SFlorian Hahn; CHECK-NEXT:    [[STEP_POS:%.*]] = icmp sge i16 [[STEP:%.*]], 0
5586b1396e3SFlorian Hahn; CHECK-NEXT:    [[STEP_SLT_N:%.*]] = icmp slt i16 [[STEP]], [[N]]
5596b1396e3SFlorian Hahn; CHECK-NEXT:    [[AND_STEP:%.*]] = and i1 [[STEP_POS]], [[STEP_SLT_N]]
5606b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[AND_STEP]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
5616b1396e3SFlorian Hahn; CHECK:       ptr.check:
5626b1396e3SFlorian Hahn; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i16 [[STEP]]
5636b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_STEP_START:%.*]] = icmp slt ptr [[SRC_STEP]], [[LOWER]]
5646b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_STEP_END:%.*]] = icmp sge ptr [[SRC_STEP]], [[UPPER]]
5656b1396e3SFlorian Hahn; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
5666b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
5676b1396e3SFlorian Hahn; CHECK:       exit:
5686b1396e3SFlorian Hahn; CHECK-NEXT:    ret i4 3
5696b1396e3SFlorian Hahn;
5706b1396e3SFlorian Hahnentry:
5716b1396e3SFlorian Hahn  %src.end = getelementptr inbounds i8, ptr %src, i16 %N
5726b1396e3SFlorian Hahn  %cmp.src.start = icmp slt ptr %src, %lower
5736b1396e3SFlorian Hahn  %cmp.src.end = icmp sge ptr %src.end, %upper
5746b1396e3SFlorian Hahn  %N.neg = icmp slt i16 %N, 0
5756b1396e3SFlorian Hahn  %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
5766b1396e3SFlorian Hahn  %or.precond.1 = or i1 %or.precond.0, %N.neg
5776b1396e3SFlorian Hahn  br i1 %or.precond.1, label %trap.bb, label %step.check
5786b1396e3SFlorian Hahn
5796b1396e3SFlorian Hahntrap.bb:
5806b1396e3SFlorian Hahn  ret i4 2
5816b1396e3SFlorian Hahn
5826b1396e3SFlorian Hahnstep.check:
5836b1396e3SFlorian Hahn  %step.pos = icmp sge i16 %step, 0
5846b1396e3SFlorian Hahn  %step.slt.N = icmp slt i16 %step, %N
5856b1396e3SFlorian Hahn  %and.step = and i1 %step.pos, %step.slt.N
5866b1396e3SFlorian Hahn  br i1 %and.step, label %ptr.check, label %exit
5876b1396e3SFlorian Hahn
5886b1396e3SFlorian Hahnptr.check:
5896b1396e3SFlorian Hahn  %src.step = getelementptr inbounds i8, ptr %src, i16 %step
5906b1396e3SFlorian Hahn  %cmp.step.start = icmp slt ptr %src.step, %lower
5916b1396e3SFlorian Hahn  %cmp.step.end = icmp sge ptr %src.step, %upper
5926b1396e3SFlorian Hahn  %or.check = or i1 %cmp.step.start, %cmp.step.end
5936b1396e3SFlorian Hahn  br i1 %or.check, label %trap.bb, label %exit
5946b1396e3SFlorian Hahn
5956b1396e3SFlorian Hahnexit:
5966b1396e3SFlorian Hahn  ret i4 3
5976b1396e3SFlorian Hahn}
5986b1396e3SFlorian Hahn
5996b1396e3SFlorian Hahndefine i4 @ptr_N_signed_positive_assume(ptr %src, ptr %lower, ptr %upper, i16 %N, i16 %step) {
6006b1396e3SFlorian Hahn; CHECK-LABEL: @ptr_N_signed_positive_assume(
6016b1396e3SFlorian Hahn; CHECK-NEXT:  entry:
6026b1396e3SFlorian Hahn; CHECK-NEXT:    [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i16 [[N:%.*]]
6036b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_START:%.*]] = icmp slt ptr [[SRC]], [[LOWER:%.*]]
6046b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_END:%.*]] = icmp sge ptr [[SRC_END]], [[UPPER:%.*]]
6056b1396e3SFlorian Hahn; CHECK-NEXT:    [[N_NEG:%.*]] = icmp slt i16 [[N]], 0
6066b1396e3SFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[N_NEG]])
6076b1396e3SFlorian Hahn; CHECK-NEXT:    [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
6086b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[OR_PRECOND_0]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]
6096b1396e3SFlorian Hahn; CHECK:       trap.bb:
6106b1396e3SFlorian Hahn; CHECK-NEXT:    ret i4 2
6116b1396e3SFlorian Hahn; CHECK:       step.check:
6126b1396e3SFlorian Hahn; CHECK-NEXT:    [[STEP_POS:%.*]] = icmp sge i16 [[STEP:%.*]], 0
6136b1396e3SFlorian Hahn; CHECK-NEXT:    [[STEP_SLT_N:%.*]] = icmp slt i16 [[STEP]], [[N]]
6147cf499c6SFlorian Hahn; CHECK-NEXT:    [[AND_STEP:%.*]] = and i1 false, [[STEP_SLT_N]]
6156b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[AND_STEP]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
6166b1396e3SFlorian Hahn; CHECK:       ptr.check:
6176b1396e3SFlorian Hahn; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i16 [[STEP]]
6186b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_STEP_START:%.*]] = icmp slt ptr [[SRC_STEP]], [[LOWER]]
6196b1396e3SFlorian Hahn; CHECK-NEXT:    [[CMP_STEP_END:%.*]] = icmp sge ptr [[SRC_STEP]], [[UPPER]]
620*18170d0fSFlorian Hahn; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 true, [[CMP_STEP_END]]
6216b1396e3SFlorian Hahn; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
6226b1396e3SFlorian Hahn; CHECK:       exit:
6236b1396e3SFlorian Hahn; CHECK-NEXT:    ret i4 3
6246b1396e3SFlorian Hahn;
6256b1396e3SFlorian Hahnentry:
6266b1396e3SFlorian Hahn  %src.end = getelementptr inbounds i8, ptr %src, i16 %N
6276b1396e3SFlorian Hahn  %cmp.src.start = icmp slt ptr %src, %lower
6286b1396e3SFlorian Hahn  %cmp.src.end = icmp sge ptr %src.end, %upper
6296b1396e3SFlorian Hahn  %N.neg = icmp slt i16 %N, 0
6306b1396e3SFlorian Hahn  call void @llvm.assume(i1 %N.neg)
6316b1396e3SFlorian Hahn  %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
6326b1396e3SFlorian Hahn  br i1 %or.precond.0, label %trap.bb, label %step.check
6336b1396e3SFlorian Hahn
6346b1396e3SFlorian Hahntrap.bb:
6356b1396e3SFlorian Hahn  ret i4 2
6366b1396e3SFlorian Hahn
6376b1396e3SFlorian Hahnstep.check:
6386b1396e3SFlorian Hahn  %step.pos = icmp sge i16 %step, 0
6396b1396e3SFlorian Hahn  %step.slt.N = icmp slt i16 %step, %N
6406b1396e3SFlorian Hahn  %and.step = and i1 %step.pos, %step.slt.N
6416b1396e3SFlorian Hahn  br i1 %and.step, label %ptr.check, label %exit
6426b1396e3SFlorian Hahn
6436b1396e3SFlorian Hahnptr.check:
6446b1396e3SFlorian Hahn  %src.step = getelementptr inbounds i8, ptr %src, i16 %step
6456b1396e3SFlorian Hahn  %cmp.step.start = icmp slt ptr %src.step, %lower
6466b1396e3SFlorian Hahn  %cmp.step.end = icmp sge ptr %src.step, %upper
6476b1396e3SFlorian Hahn  %or.check = or i1 %cmp.step.start, %cmp.step.end
6486b1396e3SFlorian Hahn  br i1 %or.check, label %trap.bb, label %exit
6496b1396e3SFlorian Hahn
6506b1396e3SFlorian Hahnexit:
6516b1396e3SFlorian Hahn  ret i4 3
6526b1396e3SFlorian Hahn}
653