xref: /llvm-project/llvm/test/Transforms/ConstraintElimination/gep-arithmetic.ll (revision a608607fd70503c20854bbc0f6f5182b51489b4f)
114da287eSFlorian Hahn; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
28ebb3eacSBjorn Pettersson; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
314da287eSFlorian Hahn
4c5e1ddb6SFlorian Hahndeclare void @llvm.assume(i1 noundef) #0
514da287eSFlorian Hahn
6c5e1ddb6SFlorian Hahndefine i1 @gep_constant_positive_index(ptr %dst, ptr %lower, ptr %upper) {
7a405ecffSFlorian Hahn; CHECK-LABEL: @gep_constant_positive_index(
8c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_4:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i64 4
9c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[PRE_DST_LOWER:%.*]] = icmp uge ptr [[DST]], [[LOWER:%.*]]
10c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[PRE_DST_UPPER:%.*]] = icmp ult ptr [[DST_ADD_4]], [[UPPER:%.*]]
11a405ecffSFlorian Hahn; CHECK-NEXT:    [[AND:%.*]] = and i1 [[PRE_DST_LOWER]], [[PRE_DST_UPPER]]
12a405ecffSFlorian Hahn; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
13a405ecffSFlorian Hahn; CHECK:       then:
14a405ecffSFlorian Hahn; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 true, true
15c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 3
16a405ecffSFlorian Hahn; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], true
17a405ecffSFlorian Hahn; CHECK-NEXT:    [[RES_3:%.*]] = xor i1 [[RES_2]], true
18a405ecffSFlorian Hahn; CHECK-NEXT:    [[RES_4:%.*]] = xor i1 [[RES_3]], true
19a405ecffSFlorian Hahn; CHECK-NEXT:    [[RES_5:%.*]] = xor i1 [[RES_4]], true
20c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[DST_ADD_5:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 5
21c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[CMP_DST_ADD_5_UPPER:%.*]] = icmp ult ptr [[DST_ADD_5]], [[UPPER]]
22a405ecffSFlorian Hahn; CHECK-NEXT:    [[RES_6:%.*]] = xor i1 [[RES_5]], true
23a405ecffSFlorian Hahn; CHECK-NEXT:    [[RES_7:%.*]] = xor i1 [[RES_6]], [[CMP_DST_ADD_5_UPPER]]
24a405ecffSFlorian Hahn; CHECK-NEXT:    ret i1 [[RES_7]]
25a405ecffSFlorian Hahn; CHECK:       else:
26a405ecffSFlorian Hahn; CHECK-NEXT:    ret i1 false
27a405ecffSFlorian Hahn;
28c5e1ddb6SFlorian Hahn  %dst.add.4 = getelementptr inbounds i8, ptr %dst, i64 4
29c5e1ddb6SFlorian Hahn  %pre.dst.lower = icmp uge ptr %dst, %lower
30c5e1ddb6SFlorian Hahn  %pre.dst.upper = icmp ult ptr %dst.add.4, %upper
31a405ecffSFlorian Hahn  %and = and i1 %pre.dst.lower, %pre.dst.upper
32a405ecffSFlorian Hahn  br i1 %and, label %then, label %else
33a405ecffSFlorian Hahn
34a405ecffSFlorian Hahnthen:
35c5e1ddb6SFlorian Hahn  %cmp.dst.lower = icmp uge ptr %dst, %lower
36c5e1ddb6SFlorian Hahn  %cmp.dst.upper = icmp ult ptr %dst, %upper
37a405ecffSFlorian Hahn  %res.1 = xor i1 %cmp.dst.lower, %cmp.dst.upper
38c5e1ddb6SFlorian Hahn  %dst.add.3 = getelementptr inbounds i8, ptr %dst, i64 3
39c5e1ddb6SFlorian Hahn  %cmp.dst.add.3.lower = icmp uge ptr %dst.add.3, %lower
40c5e1ddb6SFlorian Hahn  %cmp.dst.add.3.upper = icmp ult ptr %dst.add.3, %upper
41a405ecffSFlorian Hahn  %res.2 = xor i1 %res.1, %cmp.dst.add.3.lower
42a405ecffSFlorian Hahn  %res.3 = xor i1 %res.2, %cmp.dst.add.3.upper
43c5e1ddb6SFlorian Hahn  %cmp.dst.add.4.lower = icmp uge ptr %dst.add.4, %lower
44c5e1ddb6SFlorian Hahn  %cmp.dst.add.4.upper = icmp ult ptr %dst.add.4, %upper
45a405ecffSFlorian Hahn  %res.4 = xor i1 %res.3, %cmp.dst.add.4.lower
46a405ecffSFlorian Hahn  %res.5 = xor i1 %res.4, %cmp.dst.add.4.upper
47c5e1ddb6SFlorian Hahn  %dst.add.5 = getelementptr inbounds i8, ptr %dst, i64 5
48c5e1ddb6SFlorian Hahn  %cmp.dst.add.5.lower = icmp uge ptr %dst.add.5, %lower
49c5e1ddb6SFlorian Hahn  %cmp.dst.add.5.upper = icmp ult ptr %dst.add.5, %upper
50a405ecffSFlorian Hahn  %res.6 = xor i1 %res.5, %cmp.dst.add.5.lower
51a405ecffSFlorian Hahn  %res.7 = xor i1 %res.6, %cmp.dst.add.5.upper
52a405ecffSFlorian Hahn  ret i1 %res.7
53a405ecffSFlorian Hahn
54a405ecffSFlorian Hahnelse:
55a405ecffSFlorian Hahn  ret i1 false
56a405ecffSFlorian Hahn}
57a405ecffSFlorian Hahn
58c5e1ddb6SFlorian Hahndefine i1 @gep_constant_negative_index(ptr %dst, ptr %lower, ptr %upper) {
59a405ecffSFlorian Hahn; CHECK-LABEL: @gep_constant_negative_index(
60c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[DST_SUB_4:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i64 -4
61c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[PRE_DST_LOWER:%.*]] = icmp uge ptr [[DST]], [[LOWER:%.*]]
62c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[PRE_DST_UPPER:%.*]] = icmp ult ptr [[DST_SUB_4]], [[UPPER:%.*]]
63a405ecffSFlorian Hahn; CHECK-NEXT:    [[AND:%.*]] = and i1 [[PRE_DST_LOWER]], [[PRE_DST_UPPER]]
64a405ecffSFlorian Hahn; CHECK-NEXT:    br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
65a405ecffSFlorian Hahn; CHECK:       then:
66c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[CMP_DST_UPPER:%.*]] = icmp ult ptr [[DST]], [[UPPER]]
67a405ecffSFlorian Hahn; CHECK-NEXT:    [[RES_1:%.*]] = xor i1 true, [[CMP_DST_UPPER]]
68c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[DST_SUB_3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 -3
69c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[CMP_DST_SUB_3_LOWER:%.*]] = icmp uge ptr [[DST_SUB_3]], [[LOWER]]
70c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[CMP_DST_SUB_3_UPPER:%.*]] = icmp ult ptr [[DST_SUB_3]], [[UPPER]]
71a405ecffSFlorian Hahn; CHECK-NEXT:    [[RES_2:%.*]] = xor i1 [[RES_1]], [[CMP_DST_SUB_3_LOWER]]
72a405ecffSFlorian Hahn; CHECK-NEXT:    [[RES_3:%.*]] = xor i1 [[RES_2]], [[CMP_DST_SUB_3_UPPER]]
73c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[CMP_DST_SUB_4_LOWER:%.*]] = icmp uge ptr [[DST_SUB_4]], [[LOWER]]
74a405ecffSFlorian Hahn; CHECK-NEXT:    [[RES_4:%.*]] = xor i1 [[RES_3]], [[CMP_DST_SUB_4_LOWER]]
756a834d2fSFlorian Hahn; CHECK-NEXT:    [[RES_5:%.*]] = xor i1 [[RES_4]], true
76c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[DST_SUB_5:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 -5
77c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[CMP_DST_SUB_5_LOWER:%.*]] = icmp uge ptr [[DST_SUB_5]], [[LOWER]]
78a405ecffSFlorian Hahn; CHECK-NEXT:    [[RES_6:%.*]] = xor i1 [[RES_5]], [[CMP_DST_SUB_5_LOWER]]
796a834d2fSFlorian Hahn; CHECK-NEXT:    [[RES_7:%.*]] = xor i1 [[RES_6]], true
80a405ecffSFlorian Hahn; CHECK-NEXT:    ret i1 [[RES_7]]
81a405ecffSFlorian Hahn; CHECK:       else:
82c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[ELSE_CMP_DST_LOWER:%.*]] = icmp uge ptr [[DST]], [[LOWER]]
83c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[ELSE_CMP_DST_UPPER:%.*]] = icmp ult ptr [[DST]], [[UPPER]]
84a405ecffSFlorian Hahn; CHECK-NEXT:    [[ELSE_RES_1:%.*]] = xor i1 [[ELSE_CMP_DST_LOWER]], [[ELSE_CMP_DST_UPPER]]
85c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[ELSE_DST_SUB_3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 -3
86c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[ELSE_CMP_DST_SUB_3_LOWER:%.*]] = icmp uge ptr [[ELSE_DST_SUB_3]], [[LOWER]]
87c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[ELSE_CMP_DST_SUB_3_UPPER:%.*]] = icmp ult ptr [[ELSE_DST_SUB_3]], [[UPPER]]
88a405ecffSFlorian Hahn; CHECK-NEXT:    [[ELSE_RES_2:%.*]] = xor i1 [[ELSE_RES_1]], [[ELSE_CMP_DST_SUB_3_LOWER]]
89a405ecffSFlorian Hahn; CHECK-NEXT:    [[ELSE_RES_3:%.*]] = xor i1 [[ELSE_RES_2]], [[ELSE_CMP_DST_SUB_3_UPPER]]
90c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[ELSE_CMP_DST_SUB_4_LOWER:%.*]] = icmp uge ptr [[DST_SUB_4]], [[LOWER]]
91c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[ELSE_CMP_DST_SUB_4_UPPER:%.*]] = icmp ult ptr [[DST_SUB_4]], [[UPPER]]
92a405ecffSFlorian Hahn; CHECK-NEXT:    [[ELSE_RES_4:%.*]] = xor i1 [[ELSE_RES_3]], [[ELSE_CMP_DST_SUB_4_LOWER]]
93a405ecffSFlorian Hahn; CHECK-NEXT:    [[ELSE_RES_5:%.*]] = xor i1 [[ELSE_RES_4]], [[ELSE_CMP_DST_SUB_4_UPPER]]
94c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[ELSE_DST_SUB_5:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 -5
95c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[ELSE_CMP_DST_SUB_5_LOWER:%.*]] = icmp uge ptr [[ELSE_DST_SUB_5]], [[LOWER]]
96c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[ELSE_CMP_DST_SUB_5_UPPER:%.*]] = icmp ult ptr [[ELSE_DST_SUB_5]], [[UPPER]]
97a405ecffSFlorian Hahn; CHECK-NEXT:    [[ELSE_RES_6:%.*]] = xor i1 [[ELSE_RES_5]], [[ELSE_CMP_DST_SUB_5_LOWER]]
98a405ecffSFlorian Hahn; CHECK-NEXT:    [[ELSE_RES_7:%.*]] = xor i1 [[ELSE_RES_6]], [[ELSE_CMP_DST_SUB_5_UPPER]]
99a405ecffSFlorian Hahn; CHECK-NEXT:    ret i1 [[ELSE_RES_7]]
100a405ecffSFlorian Hahn;
101c5e1ddb6SFlorian Hahn  %dst.sub.4 = getelementptr inbounds i8, ptr %dst, i64 -4
102c5e1ddb6SFlorian Hahn  %pre.dst.lower = icmp uge ptr %dst, %lower
103c5e1ddb6SFlorian Hahn  %pre.dst.upper = icmp ult ptr %dst.sub.4, %upper
104a405ecffSFlorian Hahn  %and = and i1 %pre.dst.lower, %pre.dst.upper
105a405ecffSFlorian Hahn  br i1 %and, label %then, label %else
106a405ecffSFlorian Hahn
107a405ecffSFlorian Hahnthen:
108c5e1ddb6SFlorian Hahn  %cmp.dst.lower = icmp uge ptr %dst, %lower
109c5e1ddb6SFlorian Hahn  %cmp.dst.upper = icmp ult ptr %dst, %upper
110a405ecffSFlorian Hahn  %res.1 = xor i1 %cmp.dst.lower, %cmp.dst.upper
111c5e1ddb6SFlorian Hahn  %dst.sub.3 = getelementptr inbounds i8, ptr %dst, i64 -3
112c5e1ddb6SFlorian Hahn  %cmp.dst.sub.3.lower = icmp uge ptr %dst.sub.3, %lower
113c5e1ddb6SFlorian Hahn  %cmp.dst.sub.3.upper = icmp ult ptr %dst.sub.3, %upper
114a405ecffSFlorian Hahn  %res.2 = xor i1 %res.1, %cmp.dst.sub.3.lower
115a405ecffSFlorian Hahn  %res.3 = xor i1 %res.2, %cmp.dst.sub.3.upper
116c5e1ddb6SFlorian Hahn  %cmp.dst.sub.4.lower = icmp uge ptr %dst.sub.4, %lower
117c5e1ddb6SFlorian Hahn  %cmp.dst.sub.4.upper = icmp ult ptr %dst.sub.4, %upper
118a405ecffSFlorian Hahn  %res.4 = xor i1 %res.3, %cmp.dst.sub.4.lower
119a405ecffSFlorian Hahn  %res.5 = xor i1 %res.4, %cmp.dst.sub.4.upper
120c5e1ddb6SFlorian Hahn  %dst.sub.5 = getelementptr inbounds i8, ptr %dst, i64 -5
121c5e1ddb6SFlorian Hahn  %cmp.dst.sub.5.lower = icmp uge ptr %dst.sub.5, %lower
122c5e1ddb6SFlorian Hahn  %cmp.dst.sub.5.upper = icmp ult ptr %dst.sub.5, %upper
123a405ecffSFlorian Hahn  %res.6 = xor i1 %res.5, %cmp.dst.sub.5.lower
124a405ecffSFlorian Hahn  %res.7 = xor i1 %res.6, %cmp.dst.sub.5.upper
125a405ecffSFlorian Hahn  ret i1 %res.7
126a405ecffSFlorian Hahn
127a405ecffSFlorian Hahnelse:
128c5e1ddb6SFlorian Hahn  %else.cmp.dst.lower = icmp uge ptr %dst, %lower
129c5e1ddb6SFlorian Hahn  %else.cmp.dst.upper = icmp ult ptr %dst, %upper
130a405ecffSFlorian Hahn  %else.res.1 = xor i1 %else.cmp.dst.lower, %else.cmp.dst.upper
131c5e1ddb6SFlorian Hahn  %else.dst.sub.3 = getelementptr inbounds i8, ptr %dst, i64 -3
132c5e1ddb6SFlorian Hahn  %else.cmp.dst.sub.3.lower = icmp uge ptr %else.dst.sub.3, %lower
133c5e1ddb6SFlorian Hahn  %else.cmp.dst.sub.3.upper = icmp ult ptr %else.dst.sub.3, %upper
134a405ecffSFlorian Hahn  %else.res.2 = xor i1 %else.res.1, %else.cmp.dst.sub.3.lower
135a405ecffSFlorian Hahn  %else.res.3 = xor i1 %else.res.2, %else.cmp.dst.sub.3.upper
136c5e1ddb6SFlorian Hahn  %else.cmp.dst.sub.4.lower = icmp uge ptr %dst.sub.4, %lower
137c5e1ddb6SFlorian Hahn  %else.cmp.dst.sub.4.upper = icmp ult ptr %dst.sub.4, %upper
138a405ecffSFlorian Hahn  %else.res.4 = xor i1 %else.res.3, %else.cmp.dst.sub.4.lower
139a405ecffSFlorian Hahn  %else.res.5 = xor i1 %else.res.4, %else.cmp.dst.sub.4.upper
140c5e1ddb6SFlorian Hahn  %else.dst.sub.5 = getelementptr inbounds i8, ptr %dst, i64 -5
141c5e1ddb6SFlorian Hahn  %else.cmp.dst.sub.5.lower = icmp uge ptr %else.dst.sub.5, %lower
142c5e1ddb6SFlorian Hahn  %else.cmp.dst.sub.5.upper = icmp ult ptr %else.dst.sub.5, %upper
143a405ecffSFlorian Hahn  %else.res.6 = xor i1 %else.res.5, %else.cmp.dst.sub.5.lower
144a405ecffSFlorian Hahn  %else.res.7 = xor i1 %else.res.6, %else.cmp.dst.sub.5.upper
145a405ecffSFlorian Hahn  ret i1 %else.res.7
146a405ecffSFlorian Hahn}
147a405ecffSFlorian Hahn
148c5e1ddb6SFlorian Hahndefine i4 @ptr_N_signed_positive_explicit_check_constant_step(ptr %src, ptr %lower, ptr %upper, i16 %N) {
14914da287eSFlorian Hahn; CHECK-LABEL: @ptr_N_signed_positive_explicit_check_constant_step(
15014da287eSFlorian Hahn; CHECK-NEXT:  entry:
15114da287eSFlorian Hahn; CHECK-NEXT:    [[N_POS:%.*]] = icmp sge i16 [[N:%.*]], 0
15214da287eSFlorian Hahn; CHECK-NEXT:    br i1 [[N_POS]], label [[ENTRY_1:%.*]], label [[TRAP_BB:%.*]]
15314da287eSFlorian Hahn; CHECK:       entry.1:
154c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i16 [[N]]
155c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_START:%.*]] = icmp ult ptr [[SRC]], [[LOWER:%.*]]
156c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_END:%.*]] = icmp uge ptr [[SRC_END]], [[UPPER:%.*]]
15714da287eSFlorian Hahn; CHECK-NEXT:    [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
15814da287eSFlorian Hahn; CHECK-NEXT:    br i1 [[OR_PRECOND_0]], label [[TRAP_BB]], label [[STEP_CHECK:%.*]]
15914da287eSFlorian Hahn; CHECK:       trap.bb:
16014da287eSFlorian Hahn; CHECK-NEXT:    ret i4 2
16114da287eSFlorian Hahn; CHECK:       step.check:
16214da287eSFlorian Hahn; CHECK-NEXT:    [[STEP_ULT_N:%.*]] = icmp ult i16 1, [[N]]
16314da287eSFlorian Hahn; CHECK-NEXT:    br i1 [[STEP_ULT_N]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
16414da287eSFlorian Hahn; CHECK:       ptr.check:
165c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i16 1
1660a781d98SFlorian Hahn; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 false, false
16714da287eSFlorian Hahn; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
16814da287eSFlorian Hahn; CHECK:       exit:
16914da287eSFlorian Hahn; CHECK-NEXT:    ret i4 3
17014da287eSFlorian Hahn;
17114da287eSFlorian Hahnentry:
17214da287eSFlorian Hahn  %N.pos = icmp sge i16 %N, 0
17314da287eSFlorian Hahn  br i1 %N.pos, label %entry.1, label %trap.bb
17414da287eSFlorian Hahn
17514da287eSFlorian Hahnentry.1:
176c5e1ddb6SFlorian Hahn  %src.end = getelementptr inbounds i8, ptr %src, i16 %N
177c5e1ddb6SFlorian Hahn  %cmp.src.start = icmp ult ptr %src, %lower
178c5e1ddb6SFlorian Hahn  %cmp.src.end = icmp uge ptr %src.end, %upper
17914da287eSFlorian Hahn  %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
18014da287eSFlorian Hahn  br i1 %or.precond.0, label %trap.bb, label %step.check
18114da287eSFlorian Hahn
18214da287eSFlorian Hahntrap.bb:
18314da287eSFlorian Hahn  ret i4 2
18414da287eSFlorian Hahn
18514da287eSFlorian Hahnstep.check:
18614da287eSFlorian Hahn  %step.ult.N = icmp ult i16 1, %N
18714da287eSFlorian Hahn  br i1 %step.ult.N, label %ptr.check, label %exit
18814da287eSFlorian Hahn
18914da287eSFlorian Hahnptr.check:
190c5e1ddb6SFlorian Hahn  %src.step = getelementptr inbounds i8, ptr %src, i16 1
191c5e1ddb6SFlorian Hahn  %cmp.step.start = icmp ult ptr %src.step, %lower
192c5e1ddb6SFlorian Hahn  %cmp.step.end = icmp uge ptr %src.step, %upper
19314da287eSFlorian Hahn  %or.check = or i1 %cmp.step.start, %cmp.step.end
19414da287eSFlorian Hahn  br i1 %or.check, label %trap.bb, label %exit
19514da287eSFlorian Hahn
19614da287eSFlorian Hahnexit:
19714da287eSFlorian Hahn  ret i4 3
19814da287eSFlorian Hahn}
19914da287eSFlorian Hahn
20014da287eSFlorian Hahn; Same as ptr_N_signed_positive_explicit_check_constant_step, but without inbounds.
201c5e1ddb6SFlorian Hahndefine i4 @ptr_N_signed_positive_explicit_check_constant_step_no_inbonds(ptr %src, ptr %lower, ptr %upper, i16 %N) {
20214da287eSFlorian Hahn; CHECK-LABEL: @ptr_N_signed_positive_explicit_check_constant_step_no_inbonds(
20314da287eSFlorian Hahn; CHECK-NEXT:  entry:
20414da287eSFlorian Hahn; CHECK-NEXT:    [[N_POS:%.*]] = icmp sge i16 [[N:%.*]], 0
20514da287eSFlorian Hahn; CHECK-NEXT:    br i1 [[N_POS]], label [[ENTRY_1:%.*]], label [[TRAP_BB:%.*]]
20614da287eSFlorian Hahn; CHECK:       entry.1:
207c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[SRC_END:%.*]] = getelementptr i8, ptr [[SRC:%.*]], i16 [[N]]
208c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_START:%.*]] = icmp ult ptr [[SRC]], [[LOWER:%.*]]
209c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_END:%.*]] = icmp uge ptr [[SRC_END]], [[UPPER:%.*]]
21014da287eSFlorian Hahn; CHECK-NEXT:    [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
21114da287eSFlorian Hahn; CHECK-NEXT:    br i1 [[OR_PRECOND_0]], label [[TRAP_BB]], label [[STEP_CHECK:%.*]]
21214da287eSFlorian Hahn; CHECK:       trap.bb:
21314da287eSFlorian Hahn; CHECK-NEXT:    ret i4 2
21414da287eSFlorian Hahn; CHECK:       step.check:
21514da287eSFlorian Hahn; CHECK-NEXT:    [[STEP_ULT_N:%.*]] = icmp ult i16 1, [[N]]
21614da287eSFlorian Hahn; CHECK-NEXT:    br i1 [[STEP_ULT_N]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
21714da287eSFlorian Hahn; CHECK:       ptr.check:
218c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr i8, ptr [[SRC]], i16 1
219c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[CMP_STEP_START:%.*]] = icmp ult ptr [[SRC_STEP]], [[LOWER]]
220c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[CMP_STEP_END:%.*]] = icmp uge ptr [[SRC_STEP]], [[UPPER]]
221853c52c9SFlorian Hahn; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
22214da287eSFlorian Hahn; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
22314da287eSFlorian Hahn; CHECK:       exit:
22414da287eSFlorian Hahn; CHECK-NEXT:    ret i4 3
22514da287eSFlorian Hahn;
22614da287eSFlorian Hahnentry:
22714da287eSFlorian Hahn  %N.pos = icmp sge i16 %N, 0
22814da287eSFlorian Hahn  br i1 %N.pos, label %entry.1, label %trap.bb
22914da287eSFlorian Hahn
23014da287eSFlorian Hahnentry.1:
231c5e1ddb6SFlorian Hahn  %src.end = getelementptr i8, ptr %src, i16 %N
232c5e1ddb6SFlorian Hahn  %cmp.src.start = icmp ult ptr %src, %lower
233c5e1ddb6SFlorian Hahn  %cmp.src.end = icmp uge ptr %src.end, %upper
23414da287eSFlorian Hahn  %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
23514da287eSFlorian Hahn  br i1 %or.precond.0, label %trap.bb, label %step.check
23614da287eSFlorian Hahn
23714da287eSFlorian Hahntrap.bb:
23814da287eSFlorian Hahn  ret i4 2
23914da287eSFlorian Hahn
24014da287eSFlorian Hahnstep.check:
24114da287eSFlorian Hahn  %step.ult.N = icmp ult i16 1, %N
24214da287eSFlorian Hahn  br i1 %step.ult.N, label %ptr.check, label %exit
24314da287eSFlorian Hahn
24414da287eSFlorian Hahnptr.check:
245c5e1ddb6SFlorian Hahn  %src.step = getelementptr i8, ptr %src, i16 1
246c5e1ddb6SFlorian Hahn  %cmp.step.start = icmp ult ptr %src.step, %lower
247c5e1ddb6SFlorian Hahn  %cmp.step.end = icmp uge ptr %src.step, %upper
24814da287eSFlorian Hahn  %or.check = or i1 %cmp.step.start, %cmp.step.end
24914da287eSFlorian Hahn  br i1 %or.check, label %trap.bb, label %exit
25014da287eSFlorian Hahn
25114da287eSFlorian Hahnexit:
25214da287eSFlorian Hahn  ret i4 3
25314da287eSFlorian Hahn}
25414da287eSFlorian Hahn
255c5e1ddb6SFlorian Hahndefine i4 @ptr_N_and_step_signed_positive_explicit_check_constant_step(ptr %src, ptr %lower, ptr %upper, i16 %N, i16 %step) {
25614da287eSFlorian Hahn; CHECK-LABEL: @ptr_N_and_step_signed_positive_explicit_check_constant_step(
25714da287eSFlorian Hahn; CHECK-NEXT:  entry:
25814da287eSFlorian Hahn; CHECK-NEXT:    [[N_POS:%.*]] = icmp sge i16 [[N:%.*]], 0
25914da287eSFlorian Hahn; CHECK-NEXT:    [[STEP_POS:%.*]] = icmp sge i16 [[STEP:%.*]], 0
26014da287eSFlorian Hahn; CHECK-NEXT:    [[AND_1:%.*]] = and i1 [[N_POS]], [[STEP_POS]]
26114da287eSFlorian Hahn; CHECK-NEXT:    br i1 [[AND_1]], label [[ENTRY_1:%.*]], label [[TRAP_BB:%.*]]
26214da287eSFlorian Hahn; CHECK:       entry.1:
263c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i16 [[N]]
264c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_START:%.*]] = icmp ult ptr [[SRC]], [[LOWER:%.*]]
265c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_END:%.*]] = icmp uge ptr [[SRC_END]], [[UPPER:%.*]]
26614da287eSFlorian Hahn; CHECK-NEXT:    [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
26714da287eSFlorian Hahn; CHECK-NEXT:    br i1 [[OR_PRECOND_0]], label [[TRAP_BB]], label [[STEP_CHECK:%.*]]
26814da287eSFlorian Hahn; CHECK:       trap.bb:
26914da287eSFlorian Hahn; CHECK-NEXT:    ret i4 2
27014da287eSFlorian Hahn; CHECK:       step.check:
27114da287eSFlorian Hahn; CHECK-NEXT:    [[STEP_ULT_N:%.*]] = icmp ult i16 [[STEP]], [[N]]
272098b0b18SFlorian Hahn; CHECK-NEXT:    [[AND_2:%.*]] = and i1 true, [[STEP_ULT_N]]
27314da287eSFlorian Hahn; CHECK-NEXT:    br i1 [[AND_2]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
27414da287eSFlorian Hahn; CHECK:       ptr.check:
275c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i16 1
2760a781d98SFlorian Hahn; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 false, false
27714da287eSFlorian Hahn; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
27814da287eSFlorian Hahn; CHECK:       exit:
27914da287eSFlorian Hahn; CHECK-NEXT:    ret i4 3
28014da287eSFlorian Hahn;
28114da287eSFlorian Hahnentry:
28214da287eSFlorian Hahn  %N.pos = icmp sge i16 %N, 0
28314da287eSFlorian Hahn  %step.pos = icmp sge i16 %step, 0
28414da287eSFlorian Hahn  %and.1 = and i1 %N.pos, %step.pos
28514da287eSFlorian Hahn  br i1 %and.1, label %entry.1, label %trap.bb
28614da287eSFlorian Hahn
28714da287eSFlorian Hahnentry.1:
288c5e1ddb6SFlorian Hahn  %src.end = getelementptr inbounds i8, ptr %src, i16 %N
289c5e1ddb6SFlorian Hahn  %cmp.src.start = icmp ult ptr %src, %lower
290c5e1ddb6SFlorian Hahn  %cmp.src.end = icmp uge ptr %src.end, %upper
29114da287eSFlorian Hahn  %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
29214da287eSFlorian Hahn  br i1 %or.precond.0, label %trap.bb, label %step.check
29314da287eSFlorian Hahn
29414da287eSFlorian Hahntrap.bb:
29514da287eSFlorian Hahn  ret i4 2
29614da287eSFlorian Hahn
29714da287eSFlorian Hahnstep.check:
29814da287eSFlorian Hahn  %step.uge.0 = icmp uge i16 %step, 0
29914da287eSFlorian Hahn  %step.ult.N = icmp ult i16 %step, %N
30014da287eSFlorian Hahn  %and.2 = and i1 %step.uge.0, %step.ult.N
30114da287eSFlorian Hahn  br i1 %and.2, label %ptr.check, label %exit
30214da287eSFlorian Hahn
30314da287eSFlorian Hahnptr.check:
304c5e1ddb6SFlorian Hahn  %src.step = getelementptr inbounds i8, ptr %src, i16 1
305c5e1ddb6SFlorian Hahn  %cmp.step.start = icmp ult ptr %src.step, %lower
306c5e1ddb6SFlorian Hahn  %cmp.step.end = icmp uge ptr %src.step, %upper
30714da287eSFlorian Hahn  %or.check = or i1 %cmp.step.start, %cmp.step.end
30814da287eSFlorian Hahn  br i1 %or.check, label %trap.bb, label %exit
30914da287eSFlorian Hahn
31014da287eSFlorian Hahnexit:
31114da287eSFlorian Hahn  ret i4 3
31214da287eSFlorian Hahn}
31314da287eSFlorian Hahn
314c5e1ddb6SFlorian Hahndefine i4 @ptr_N_and_step_signed_positive_unsigned_checks_only(ptr %src, ptr %lower, ptr %upper, i16 %N, i16 %step) {
31514da287eSFlorian Hahn; CHECK-LABEL: @ptr_N_and_step_signed_positive_unsigned_checks_only(
31614da287eSFlorian Hahn; CHECK-NEXT:  entry:
317c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i16 [[N:%.*]]
318c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[NO_OVERFLOW:%.*]] = icmp ule ptr [[SRC]], [[SRC_END]]
31914da287eSFlorian Hahn; CHECK-NEXT:    br i1 [[NO_OVERFLOW]], label [[ENTRY_1:%.*]], label [[TRAP_BB:%.*]]
32014da287eSFlorian Hahn; CHECK:       entry.1:
321c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_START:%.*]] = icmp ult ptr [[SRC]], [[LOWER:%.*]]
322c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_END:%.*]] = icmp uge ptr [[SRC_END]], [[UPPER:%.*]]
32314da287eSFlorian Hahn; CHECK-NEXT:    [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
32414da287eSFlorian Hahn; CHECK-NEXT:    br i1 [[OR_PRECOND_0]], label [[TRAP_BB]], label [[STEP_CHECK:%.*]]
32514da287eSFlorian Hahn; CHECK:       trap.bb:
32614da287eSFlorian Hahn; CHECK-NEXT:    ret i4 2
32714da287eSFlorian Hahn; CHECK:       step.check:
32898e016d9SFlorian Hahn; CHECK-NEXT:    [[STEP_ULT_N:%.*]] = icmp ult i16 [[STEP:%.*]], [[N]]
32998e016d9SFlorian Hahn; CHECK-NEXT:    [[AND_2:%.*]] = and i1 true, [[STEP_ULT_N]]
33014da287eSFlorian Hahn; CHECK-NEXT:    br i1 [[AND_2]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
33114da287eSFlorian Hahn; CHECK:       ptr.check:
332c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i16 1
333c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[CMP_STEP_END:%.*]] = icmp uge ptr [[SRC_STEP]], [[UPPER]]
33406f3ef66SFlorian Hahn; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 false, [[CMP_STEP_END]]
33514da287eSFlorian Hahn; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
33614da287eSFlorian Hahn; CHECK:       exit:
33714da287eSFlorian Hahn; CHECK-NEXT:    ret i4 3
33814da287eSFlorian Hahn;
33914da287eSFlorian Hahnentry:
340c5e1ddb6SFlorian Hahn  %src.end = getelementptr inbounds i8, ptr %src, i16 %N
341c5e1ddb6SFlorian Hahn  %no.overflow = icmp ule ptr %src, %src.end
34214da287eSFlorian Hahn  br i1 %no.overflow, label %entry.1, label %trap.bb
34314da287eSFlorian Hahn
34414da287eSFlorian Hahnentry.1:
345c5e1ddb6SFlorian Hahn  %cmp.src.start = icmp ult ptr %src, %lower
346c5e1ddb6SFlorian Hahn  %cmp.src.end = icmp uge ptr %src.end, %upper
34714da287eSFlorian Hahn  %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
34814da287eSFlorian Hahn  br i1 %or.precond.0, label %trap.bb, label %step.check
34914da287eSFlorian Hahn
35014da287eSFlorian Hahntrap.bb:
35114da287eSFlorian Hahn  ret i4 2
35214da287eSFlorian Hahn
35314da287eSFlorian Hahnstep.check:
35414da287eSFlorian Hahn  %step.uge.0 = icmp uge i16 %step, 0
35514da287eSFlorian Hahn  %step.ult.N = icmp ult i16 %step, %N
35614da287eSFlorian Hahn  %and.2 = and i1 %step.uge.0, %step.ult.N
35714da287eSFlorian Hahn  br i1 %and.2, label %ptr.check, label %exit
35814da287eSFlorian Hahn
35914da287eSFlorian Hahnptr.check:
360c5e1ddb6SFlorian Hahn  %src.step = getelementptr inbounds i8, ptr %src, i16 1
361c5e1ddb6SFlorian Hahn  %cmp.step.start = icmp ult ptr %src.step, %lower
362c5e1ddb6SFlorian Hahn  %cmp.step.end = icmp uge ptr %src.step, %upper
36314da287eSFlorian Hahn  %or.check = or i1 %cmp.step.start, %cmp.step.end
36414da287eSFlorian Hahn  br i1 %or.check, label %trap.bb, label %exit
36514da287eSFlorian Hahn
36614da287eSFlorian Hahnexit:
36714da287eSFlorian Hahn  ret i4 3
36814da287eSFlorian Hahn}
36914da287eSFlorian Hahn
370c5e1ddb6SFlorian Hahndefine i4 @ptr_N_signed_positive(ptr %src, ptr %lower, ptr %upper, i16 %N, i16 %step) {
37114da287eSFlorian Hahn; CHECK-LABEL: @ptr_N_signed_positive(
37214da287eSFlorian Hahn; CHECK-NEXT:  entry:
373c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i16 [[N:%.*]]
374c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_START:%.*]] = icmp ult ptr [[SRC]], [[LOWER:%.*]]
375c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_END:%.*]] = icmp uge ptr [[SRC_END]], [[UPPER:%.*]]
37614da287eSFlorian Hahn; CHECK-NEXT:    [[N_NEG:%.*]] = icmp slt i16 [[N]], 0
37714da287eSFlorian Hahn; CHECK-NEXT:    [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
37814da287eSFlorian Hahn; CHECK-NEXT:    [[OR_PRECOND_1:%.*]] = or i1 [[OR_PRECOND_0]], [[N_NEG]]
37914da287eSFlorian Hahn; CHECK-NEXT:    br i1 [[OR_PRECOND_1]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]
38014da287eSFlorian Hahn; CHECK:       trap.bb:
38114da287eSFlorian Hahn; CHECK-NEXT:    ret i4 2
38214da287eSFlorian Hahn; CHECK:       step.check:
38398e016d9SFlorian Hahn; CHECK-NEXT:    [[STEP_ULT_N:%.*]] = icmp ult i16 [[STEP:%.*]], [[N]]
38498e016d9SFlorian Hahn; CHECK-NEXT:    [[AND_STEP:%.*]] = and i1 true, [[STEP_ULT_N]]
38514da287eSFlorian Hahn; CHECK-NEXT:    br i1 [[AND_STEP]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
38614da287eSFlorian Hahn; CHECK:       ptr.check:
387c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i16 [[STEP]]
388349375d0SFlorian Hahn; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 false, false
38914da287eSFlorian Hahn; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
39014da287eSFlorian Hahn; CHECK:       exit:
39114da287eSFlorian Hahn; CHECK-NEXT:    ret i4 3
39214da287eSFlorian Hahn;
39314da287eSFlorian Hahnentry:
394c5e1ddb6SFlorian Hahn  %src.end = getelementptr inbounds i8, ptr %src, i16 %N
395c5e1ddb6SFlorian Hahn  %cmp.src.start = icmp ult ptr %src, %lower
396c5e1ddb6SFlorian Hahn  %cmp.src.end = icmp uge ptr %src.end, %upper
39714da287eSFlorian Hahn  %N.neg = icmp slt i16 %N, 0
39814da287eSFlorian Hahn  %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
39914da287eSFlorian Hahn  %or.precond.1 = or i1 %or.precond.0, %N.neg
40014da287eSFlorian Hahn  br i1 %or.precond.1, label %trap.bb, label %step.check
40114da287eSFlorian Hahn
40214da287eSFlorian Hahntrap.bb:
40314da287eSFlorian Hahn  ret i4 2
40414da287eSFlorian Hahn
40514da287eSFlorian Hahnstep.check:
40614da287eSFlorian Hahn  %step.pos = icmp uge i16 %step, 0
40714da287eSFlorian Hahn  %step.ult.N = icmp ult i16 %step, %N
40814da287eSFlorian Hahn  %and.step = and i1 %step.pos, %step.ult.N
40914da287eSFlorian Hahn  br i1 %and.step, label %ptr.check, label %exit
41014da287eSFlorian Hahn
41114da287eSFlorian Hahnptr.check:
412c5e1ddb6SFlorian Hahn  %src.step = getelementptr inbounds i8, ptr %src, i16 %step
413c5e1ddb6SFlorian Hahn  %cmp.step.start = icmp ult ptr %src.step, %lower
414c5e1ddb6SFlorian Hahn  %cmp.step.end = icmp uge ptr %src.step, %upper
41514da287eSFlorian Hahn  %or.check = or i1 %cmp.step.start, %cmp.step.end
41614da287eSFlorian Hahn  br i1 %or.check, label %trap.bb, label %exit
41714da287eSFlorian Hahn
41814da287eSFlorian Hahnexit:
41914da287eSFlorian Hahn  ret i4 3
42014da287eSFlorian Hahn}
42114da287eSFlorian Hahn
422c5e1ddb6SFlorian Hahndefine i4 @ptr_N_could_be_negative(ptr %src, ptr %lower, ptr %upper, i8 %N, i8 %step) {
42314da287eSFlorian Hahn; CHECK-LABEL: @ptr_N_could_be_negative(
42414da287eSFlorian Hahn; CHECK-NEXT:  entry:
425c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i8 [[N:%.*]]
426c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_START:%.*]] = icmp ult ptr [[SRC]], [[LOWER:%.*]]
427c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_END:%.*]] = icmp uge ptr [[SRC_END]], [[UPPER:%.*]]
42814da287eSFlorian Hahn; CHECK-NEXT:    [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
42914da287eSFlorian Hahn; CHECK-NEXT:    br i1 [[OR_PRECOND_0]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]
43014da287eSFlorian Hahn; CHECK:       trap.bb:
43114da287eSFlorian Hahn; CHECK-NEXT:    ret i4 2
43214da287eSFlorian Hahn; CHECK:       step.check:
43398e016d9SFlorian Hahn; CHECK-NEXT:    [[STEP_ULT_N:%.*]] = icmp ult i8 [[STEP:%.*]], [[N]]
43498e016d9SFlorian Hahn; CHECK-NEXT:    [[AND_STEP:%.*]] = and i1 true, [[STEP_ULT_N]]
43514da287eSFlorian Hahn; CHECK-NEXT:    br i1 [[AND_STEP]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
43614da287eSFlorian Hahn; CHECK:       ptr.check:
437c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i8 [[STEP]]
438c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[CMP_STEP_START:%.*]] = icmp ult ptr [[SRC_STEP]], [[LOWER]]
439c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[CMP_STEP_END:%.*]] = icmp uge ptr [[SRC_STEP]], [[UPPER]]
44006f3ef66SFlorian Hahn; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
44114da287eSFlorian Hahn; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
44214da287eSFlorian Hahn; CHECK:       exit:
44314da287eSFlorian Hahn; CHECK-NEXT:    ret i4 3
44414da287eSFlorian Hahn;
44514da287eSFlorian Hahnentry:
446c5e1ddb6SFlorian Hahn  %src.end = getelementptr inbounds i8, ptr %src, i8 %N
447c5e1ddb6SFlorian Hahn  %cmp.src.start = icmp ult ptr %src, %lower
448c5e1ddb6SFlorian Hahn  %cmp.src.end = icmp uge ptr %src.end, %upper
44914da287eSFlorian Hahn  %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
45014da287eSFlorian Hahn  br i1 %or.precond.0, label %trap.bb, label %step.check
45114da287eSFlorian Hahn
45214da287eSFlorian Hahntrap.bb:
45314da287eSFlorian Hahn  ret i4 2
45414da287eSFlorian Hahn
45514da287eSFlorian Hahnstep.check:
4560bcfd4cbSFlorian Hahn  %step.pos = icmp uge i8 %step, 0
4570bcfd4cbSFlorian Hahn  %step.ult.N = icmp ult i8 %step, %N
45814da287eSFlorian Hahn  %and.step = and i1 %step.pos, %step.ult.N
45914da287eSFlorian Hahn  br i1 %and.step, label %ptr.check, label %exit
46014da287eSFlorian Hahn
46114da287eSFlorian Hahnptr.check:
462c5e1ddb6SFlorian Hahn  %src.step = getelementptr inbounds i8, ptr %src, i8 %step
463c5e1ddb6SFlorian Hahn  %cmp.step.start = icmp ult ptr %src.step, %lower
464c5e1ddb6SFlorian Hahn  %cmp.step.end = icmp uge ptr %src.step, %upper
46514da287eSFlorian Hahn  %or.check = or i1 %cmp.step.start, %cmp.step.end
46614da287eSFlorian Hahn  br i1 %or.check, label %trap.bb, label %exit
46714da287eSFlorian Hahn
46814da287eSFlorian Hahnexit:
46914da287eSFlorian Hahn  ret i4 3
47014da287eSFlorian Hahn}
47114da287eSFlorian Hahn
472c5e1ddb6SFlorian Hahndefine i4 @ptr_src_uge_end(ptr %src, ptr %lower, ptr %upper, i8 %N, i8 %step) {
47314da287eSFlorian Hahn; CHECK-LABEL: @ptr_src_uge_end(
47414da287eSFlorian Hahn; CHECK-NEXT:  entry:
475c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i8 [[N:%.*]]
476c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_START:%.*]] = icmp ult ptr [[SRC]], [[LOWER:%.*]]
477c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_END:%.*]] = icmp uge ptr [[SRC_END]], [[UPPER:%.*]]
478c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[CMP_OVERFLOW:%.*]] = icmp ugt ptr [[SRC]], [[SRC_END]]
47914da287eSFlorian Hahn; CHECK-NEXT:    [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
48014da287eSFlorian Hahn; CHECK-NEXT:    [[OR_PRECOND_1:%.*]] = or i1 [[OR_PRECOND_0]], [[CMP_OVERFLOW]]
48114da287eSFlorian Hahn; CHECK-NEXT:    br i1 [[OR_PRECOND_1]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]
48214da287eSFlorian Hahn; CHECK:       trap.bb:
48314da287eSFlorian Hahn; CHECK-NEXT:    ret i4 2
48414da287eSFlorian Hahn; CHECK:       step.check:
48598e016d9SFlorian Hahn; CHECK-NEXT:    [[STEP_ULT_N:%.*]] = icmp ult i8 [[STEP:%.*]], [[N]]
48698e016d9SFlorian Hahn; CHECK-NEXT:    [[AND_STEP:%.*]] = and i1 true, [[STEP_ULT_N]]
48714da287eSFlorian Hahn; CHECK-NEXT:    br i1 [[AND_STEP]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
48814da287eSFlorian Hahn; CHECK:       ptr.check:
489c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i8 [[STEP]]
490c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[CMP_STEP_START:%.*]] = icmp ult ptr [[SRC_STEP]], [[LOWER]]
491c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[CMP_STEP_END:%.*]] = icmp uge ptr [[SRC_STEP]], [[UPPER]]
49214da287eSFlorian Hahn; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
49314da287eSFlorian Hahn; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
49414da287eSFlorian Hahn; CHECK:       exit:
49514da287eSFlorian Hahn; CHECK-NEXT:    ret i4 3
49614da287eSFlorian Hahn;
49714da287eSFlorian Hahnentry:
498c5e1ddb6SFlorian Hahn  %src.end = getelementptr inbounds i8, ptr %src, i8 %N
499c5e1ddb6SFlorian Hahn  %cmp.src.start = icmp ult ptr %src, %lower
500c5e1ddb6SFlorian Hahn  %cmp.src.end = icmp uge ptr %src.end, %upper
501c5e1ddb6SFlorian Hahn  %cmp.overflow = icmp ugt ptr %src, %src.end
50214da287eSFlorian Hahn  %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
50314da287eSFlorian Hahn  %or.precond.1 = or i1 %or.precond.0, %cmp.overflow
50414da287eSFlorian Hahn  br i1 %or.precond.1, label %trap.bb, label %step.check
50514da287eSFlorian Hahn
50614da287eSFlorian Hahntrap.bb:
50714da287eSFlorian Hahn  ret i4 2
50814da287eSFlorian Hahn
50914da287eSFlorian Hahnstep.check:
5100bcfd4cbSFlorian Hahn  %step.pos = icmp uge i8 %step, 0
5110bcfd4cbSFlorian Hahn  %step.ult.N = icmp ult i8 %step, %N
51214da287eSFlorian Hahn  %and.step = and i1 %step.pos, %step.ult.N
51314da287eSFlorian Hahn  br i1 %and.step, label %ptr.check, label %exit
51414da287eSFlorian Hahn
51514da287eSFlorian Hahnptr.check:
516c5e1ddb6SFlorian Hahn  %src.step = getelementptr inbounds i8, ptr %src, i8 %step
517c5e1ddb6SFlorian Hahn  %cmp.step.start = icmp ult ptr %src.step, %lower
518c5e1ddb6SFlorian Hahn  %cmp.step.end = icmp uge ptr %src.step, %upper
51914da287eSFlorian Hahn  %or.check = or i1 %cmp.step.start, %cmp.step.end
52014da287eSFlorian Hahn  br i1 %or.check, label %trap.bb, label %exit
52114da287eSFlorian Hahn
52214da287eSFlorian Hahnexit:
52314da287eSFlorian Hahn  ret i4 3
52414da287eSFlorian Hahn}
52514da287eSFlorian Hahn
52614da287eSFlorian Hahn; N might be negative, meaning %src.end could be < %src! Cannot remove checks!
527c5e1ddb6SFlorian Hahndefine i4 @ptr_N_unsigned_positive(ptr %src, ptr %lower, ptr %upper, i16 %N, i16 %step) {
52814da287eSFlorian Hahn; CHECK-LABEL: @ptr_N_unsigned_positive(
52914da287eSFlorian Hahn; CHECK-NEXT:  entry:
530c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i16 [[N:%.*]]
531c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_START:%.*]] = icmp ult ptr [[SRC]], [[LOWER:%.*]]
532c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_END:%.*]] = icmp uge ptr [[SRC_END]], [[UPPER:%.*]]
53314da287eSFlorian Hahn; CHECK-NEXT:    [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
534fbcf8a8cSFlorian Hahn; CHECK-NEXT:    [[OR_PRECOND_1:%.*]] = or i1 [[OR_PRECOND_0]], false
53514da287eSFlorian Hahn; CHECK-NEXT:    br i1 [[OR_PRECOND_1]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]
53614da287eSFlorian Hahn; CHECK:       trap.bb:
53714da287eSFlorian Hahn; CHECK-NEXT:    ret i4 2
53814da287eSFlorian Hahn; CHECK:       step.check:
53998e016d9SFlorian Hahn; CHECK-NEXT:    [[STEP_ULT_N:%.*]] = icmp ult i16 [[STEP:%.*]], [[N]]
54098e016d9SFlorian Hahn; CHECK-NEXT:    [[AND_STEP:%.*]] = and i1 true, [[STEP_ULT_N]]
54114da287eSFlorian Hahn; CHECK-NEXT:    br i1 [[AND_STEP]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
54214da287eSFlorian Hahn; CHECK:       ptr.check:
543c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i16 [[STEP]]
544c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[CMP_STEP_START:%.*]] = icmp ult ptr [[SRC_STEP]], [[LOWER]]
545c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[CMP_STEP_END:%.*]] = icmp uge ptr [[SRC_STEP]], [[UPPER]]
54614da287eSFlorian Hahn; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
54714da287eSFlorian Hahn; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
54814da287eSFlorian Hahn; CHECK:       exit:
54914da287eSFlorian Hahn; CHECK-NEXT:    ret i4 3
55014da287eSFlorian Hahn;
55114da287eSFlorian Hahnentry:
552c5e1ddb6SFlorian Hahn  %src.end = getelementptr inbounds i8, ptr %src, i16 %N
553c5e1ddb6SFlorian Hahn  %cmp.src.start = icmp ult ptr %src, %lower
554c5e1ddb6SFlorian Hahn  %cmp.src.end = icmp uge ptr %src.end, %upper
55514da287eSFlorian Hahn  %N.neg = icmp ult i16 %N, 0
55614da287eSFlorian Hahn  %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
55714da287eSFlorian Hahn  %or.precond.1 = or i1 %or.precond.0, %N.neg
55814da287eSFlorian Hahn  br i1 %or.precond.1, label %trap.bb, label %step.check
55914da287eSFlorian Hahn
56014da287eSFlorian Hahntrap.bb:
56114da287eSFlorian Hahn  ret i4 2
56214da287eSFlorian Hahn
56314da287eSFlorian Hahnstep.check:
56414da287eSFlorian Hahn  %step.pos = icmp uge i16 %step, 0
56514da287eSFlorian Hahn  %step.ult.N = icmp ult i16 %step, %N
56614da287eSFlorian Hahn  %and.step = and i1 %step.pos, %step.ult.N
56714da287eSFlorian Hahn  br i1 %and.step, label %ptr.check, label %exit
56814da287eSFlorian Hahn
56914da287eSFlorian Hahnptr.check:
570c5e1ddb6SFlorian Hahn  %src.step = getelementptr inbounds i8, ptr %src, i16 %step
571c5e1ddb6SFlorian Hahn  %cmp.step.start = icmp ult ptr %src.step, %lower
572c5e1ddb6SFlorian Hahn  %cmp.step.end = icmp uge ptr %src.step, %upper
57314da287eSFlorian Hahn  %or.check = or i1 %cmp.step.start, %cmp.step.end
57414da287eSFlorian Hahn  br i1 %or.check, label %trap.bb, label %exit
57514da287eSFlorian Hahn
57614da287eSFlorian Hahnexit:
57714da287eSFlorian Hahn  ret i4 3
57814da287eSFlorian Hahn}
57914da287eSFlorian Hahn
580c5e1ddb6SFlorian Hahndefine i4 @ptr_N_signed_positive_assume(ptr %src, ptr %lower, ptr %upper, i16 %N, i16 %step) {
58114da287eSFlorian Hahn; CHECK-LABEL: @ptr_N_signed_positive_assume(
58214da287eSFlorian Hahn; CHECK-NEXT:  entry:
583c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[SRC_END:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i16 [[N:%.*]]
584c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_START:%.*]] = icmp ult ptr [[SRC]], [[LOWER:%.*]]
585c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[CMP_SRC_END:%.*]] = icmp uge ptr [[SRC_END]], [[UPPER:%.*]]
58614da287eSFlorian Hahn; CHECK-NEXT:    [[N_NEG:%.*]] = icmp slt i16 [[N]], 0
58714da287eSFlorian Hahn; CHECK-NEXT:    call void @llvm.assume(i1 [[N_NEG]])
58814da287eSFlorian Hahn; CHECK-NEXT:    [[OR_PRECOND_0:%.*]] = or i1 [[CMP_SRC_START]], [[CMP_SRC_END]]
58914da287eSFlorian Hahn; CHECK-NEXT:    br i1 [[OR_PRECOND_0]], label [[TRAP_BB:%.*]], label [[STEP_CHECK:%.*]]
59014da287eSFlorian Hahn; CHECK:       trap.bb:
59114da287eSFlorian Hahn; CHECK-NEXT:    ret i4 2
59214da287eSFlorian Hahn; CHECK:       step.check:
59398e016d9SFlorian Hahn; CHECK-NEXT:    [[STEP_ULT_N:%.*]] = icmp ult i16 [[STEP:%.*]], [[N]]
59498e016d9SFlorian Hahn; CHECK-NEXT:    [[AND_STEP:%.*]] = and i1 true, [[STEP_ULT_N]]
59514da287eSFlorian Hahn; CHECK-NEXT:    br i1 [[AND_STEP]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
59614da287eSFlorian Hahn; CHECK:       ptr.check:
597c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i16 [[STEP]]
598c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[CMP_STEP_START:%.*]] = icmp ult ptr [[SRC_STEP]], [[LOWER]]
599c5e1ddb6SFlorian Hahn; CHECK-NEXT:    [[CMP_STEP_END:%.*]] = icmp uge ptr [[SRC_STEP]], [[UPPER]]
60006f3ef66SFlorian Hahn; CHECK-NEXT:    [[OR_CHECK:%.*]] = or i1 [[CMP_STEP_START]], [[CMP_STEP_END]]
60114da287eSFlorian Hahn; CHECK-NEXT:    br i1 [[OR_CHECK]], label [[TRAP_BB]], label [[EXIT]]
60214da287eSFlorian Hahn; CHECK:       exit:
60314da287eSFlorian Hahn; CHECK-NEXT:    ret i4 3
60414da287eSFlorian Hahn;
60514da287eSFlorian Hahnentry:
606c5e1ddb6SFlorian Hahn  %src.end = getelementptr inbounds i8, ptr %src, i16 %N
607c5e1ddb6SFlorian Hahn  %cmp.src.start = icmp ult ptr %src, %lower
608c5e1ddb6SFlorian Hahn  %cmp.src.end = icmp uge ptr %src.end, %upper
60914da287eSFlorian Hahn  %N.neg = icmp slt i16 %N, 0
61014da287eSFlorian Hahn  call void @llvm.assume(i1 %N.neg)
61114da287eSFlorian Hahn  %or.precond.0 = or i1 %cmp.src.start, %cmp.src.end
61214da287eSFlorian Hahn  br i1 %or.precond.0, label %trap.bb, label %step.check
61314da287eSFlorian Hahn
61414da287eSFlorian Hahntrap.bb:
61514da287eSFlorian Hahn  ret i4 2
61614da287eSFlorian Hahn
61714da287eSFlorian Hahnstep.check:
61814da287eSFlorian Hahn  %step.pos = icmp uge i16 %step, 0
61914da287eSFlorian Hahn  %step.ult.N = icmp ult i16 %step, %N
62014da287eSFlorian Hahn  %and.step = and i1 %step.pos, %step.ult.N
62114da287eSFlorian Hahn  br i1 %and.step, label %ptr.check, label %exit
62214da287eSFlorian Hahn
62314da287eSFlorian Hahnptr.check:
624c5e1ddb6SFlorian Hahn  %src.step = getelementptr inbounds i8, ptr %src, i16 %step
625c5e1ddb6SFlorian Hahn  %cmp.step.start = icmp ult ptr %src.step, %lower
626c5e1ddb6SFlorian Hahn  %cmp.step.end = icmp uge ptr %src.step, %upper
62714da287eSFlorian Hahn  %or.check = or i1 %cmp.step.start, %cmp.step.end
62814da287eSFlorian Hahn  br i1 %or.check, label %trap.bb, label %exit
62914da287eSFlorian Hahn
63014da287eSFlorian Hahnexit:
63114da287eSFlorian Hahn  ret i4 3
63214da287eSFlorian Hahn}
63310223c72SNikita Popov
63410223c72SNikita Popovdefine i1 @test_nusw(ptr %p, i32 %x, i32 %y) {
63510223c72SNikita Popov; CHECK-LABEL: @test_nusw(
63610223c72SNikita Popov; CHECK-NEXT:    [[X_EXT:%.*]] = zext i32 [[X:%.*]] to i64
63710223c72SNikita Popov; CHECK-NEXT:    [[Y_EXT:%.*]] = zext i32 [[Y:%.*]] to i64
63810223c72SNikita Popov; CHECK-NEXT:    [[CMP1:%.*]] = icmp ugt i64 [[X_EXT]], [[Y_EXT]]
63910223c72SNikita Popov; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP1]])
64010223c72SNikita Popov; CHECK-NEXT:    [[GEP_X:%.*]] = getelementptr nusw i8, ptr [[P:%.*]], i64 [[X_EXT]]
64110223c72SNikita Popov; CHECK-NEXT:    [[GEP_Y:%.*]] = getelementptr nusw i8, ptr [[P]], i64 [[Y_EXT]]
64210223c72SNikita Popov; CHECK-NEXT:    ret i1 true
64310223c72SNikita Popov;
64410223c72SNikita Popov  %x.ext = zext i32 %x to i64
64510223c72SNikita Popov  %y.ext = zext i32 %y to i64
64610223c72SNikita Popov  %cmp1 = icmp ugt i64 %x.ext, %y.ext
64710223c72SNikita Popov  call void @llvm.assume(i1 %cmp1)
64810223c72SNikita Popov  %gep.x = getelementptr nusw i8, ptr %p, i64 %x.ext
64910223c72SNikita Popov  %gep.y = getelementptr nusw i8, ptr %p, i64 %y.ext
65010223c72SNikita Popov  %cmp2 = icmp ugt ptr %gep.x, %gep.y
65110223c72SNikita Popov  ret i1 %cmp2
65210223c72SNikita Popov}
65310223c72SNikita Popov
65410223c72SNikita Popovdefine i1 @test_nusw_nested(ptr %p, i32 %x, i32 %y) {
65510223c72SNikita Popov; CHECK-LABEL: @test_nusw_nested(
65610223c72SNikita Popov; CHECK-NEXT:    [[X_EXT:%.*]] = zext i32 [[X:%.*]] to i64
65710223c72SNikita Popov; CHECK-NEXT:    [[Y_EXT:%.*]] = zext i32 [[Y:%.*]] to i64
65810223c72SNikita Popov; CHECK-NEXT:    [[CMP1:%.*]] = icmp ugt i64 [[X_EXT]], [[Y_EXT]]
65910223c72SNikita Popov; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP1]])
66010223c72SNikita Popov; CHECK-NEXT:    [[GEP_X:%.*]] = getelementptr nusw i8, ptr [[P:%.*]], i64 [[X_EXT]]
66110223c72SNikita Popov; CHECK-NEXT:    [[GEP_X1:%.*]] = getelementptr nusw i8, ptr [[GEP_X]], i64 1
66210223c72SNikita Popov; CHECK-NEXT:    [[GEP_Y:%.*]] = getelementptr nusw i8, ptr [[P]], i64 [[Y_EXT]]
66310223c72SNikita Popov; CHECK-NEXT:    ret i1 true
66410223c72SNikita Popov;
66510223c72SNikita Popov  %x.ext = zext i32 %x to i64
66610223c72SNikita Popov  %y.ext = zext i32 %y to i64
66710223c72SNikita Popov  %cmp1 = icmp ugt i64 %x.ext, %y.ext
66810223c72SNikita Popov  call void @llvm.assume(i1 %cmp1)
66910223c72SNikita Popov  %gep.x = getelementptr nusw i8, ptr %p, i64 %x.ext
67010223c72SNikita Popov  %gep.x1 = getelementptr nusw i8, ptr %gep.x, i64 1
67110223c72SNikita Popov  %gep.y = getelementptr nusw i8, ptr %p, i64 %y.ext
67210223c72SNikita Popov  %cmp2 = icmp ugt ptr %gep.x1, %gep.y
67310223c72SNikita Popov  ret i1 %cmp2
67410223c72SNikita Popov}
67510223c72SNikita Popov
67610223c72SNikita Popovdefine i1 @test_missing_nusw(ptr %p, i32 %x, i32 %y) {
67710223c72SNikita Popov; CHECK-LABEL: @test_missing_nusw(
67810223c72SNikita Popov; CHECK-NEXT:    [[X_EXT:%.*]] = zext i32 [[X:%.*]] to i64
67910223c72SNikita Popov; CHECK-NEXT:    [[Y_EXT:%.*]] = zext i32 [[Y:%.*]] to i64
68010223c72SNikita Popov; CHECK-NEXT:    [[CMP1:%.*]] = icmp ugt i64 [[X_EXT]], [[Y_EXT]]
68110223c72SNikita Popov; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP1]])
68210223c72SNikita Popov; CHECK-NEXT:    [[GEP_X:%.*]] = getelementptr nusw i8, ptr [[P:%.*]], i64 [[X_EXT]]
68310223c72SNikita Popov; CHECK-NEXT:    [[GEP_X1:%.*]] = getelementptr i8, ptr [[GEP_X]], i64 1
68410223c72SNikita Popov; CHECK-NEXT:    [[GEP_Y:%.*]] = getelementptr nusw i8, ptr [[P]], i64 [[Y_EXT]]
68510223c72SNikita Popov; CHECK-NEXT:    [[CMP2:%.*]] = icmp ugt ptr [[GEP_X1]], [[GEP_Y]]
68610223c72SNikita Popov; CHECK-NEXT:    ret i1 [[CMP2]]
68710223c72SNikita Popov;
68810223c72SNikita Popov  %x.ext = zext i32 %x to i64
68910223c72SNikita Popov  %y.ext = zext i32 %y to i64
69010223c72SNikita Popov  %cmp1 = icmp ugt i64 %x.ext, %y.ext
69110223c72SNikita Popov  call void @llvm.assume(i1 %cmp1)
69210223c72SNikita Popov  %gep.x = getelementptr nusw i8, ptr %p, i64 %x.ext
69310223c72SNikita Popov  %gep.x1 = getelementptr i8, ptr %gep.x, i64 1
69410223c72SNikita Popov  %gep.y = getelementptr nusw i8, ptr %p, i64 %y.ext
69510223c72SNikita Popov  %cmp2 = icmp ugt ptr %gep.x1, %gep.y
69610223c72SNikita Popov  ret i1 %cmp2
69710223c72SNikita Popov}
69875af6283SNikita Popov
69975af6283SNikita Popovdefine i1 @test_nuw(ptr %p, i64 %x, i64 %y) {
70075af6283SNikita Popov; CHECK-LABEL: @test_nuw(
70175af6283SNikita Popov; CHECK-NEXT:    [[CMP1:%.*]] = icmp ugt i64 [[X:%.*]], [[Y:%.*]]
70275af6283SNikita Popov; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP1]])
70375af6283SNikita Popov; CHECK-NEXT:    [[GEP_X:%.*]] = getelementptr nuw i8, ptr [[P:%.*]], i64 [[X]]
70475af6283SNikita Popov; CHECK-NEXT:    [[GEP_Y:%.*]] = getelementptr nuw i8, ptr [[P]], i64 [[Y]]
705*a608607fSNikita Popov; CHECK-NEXT:    ret i1 true
70675af6283SNikita Popov;
70775af6283SNikita Popov  %cmp1 = icmp ugt i64 %x, %y
70875af6283SNikita Popov  call void @llvm.assume(i1 %cmp1)
70975af6283SNikita Popov  %gep.x = getelementptr nuw i8, ptr %p, i64 %x
71075af6283SNikita Popov  %gep.y = getelementptr nuw i8, ptr %p, i64 %y
71175af6283SNikita Popov  %cmp2 = icmp ugt ptr %gep.x, %gep.y
71275af6283SNikita Popov  ret i1 %cmp2
71375af6283SNikita Popov}
71475af6283SNikita Popov
71575af6283SNikita Popovdefine i1 @test_nuw_nested(ptr %p, i64 %x, i64 %y) {
71675af6283SNikita Popov; CHECK-LABEL: @test_nuw_nested(
71775af6283SNikita Popov; CHECK-NEXT:    [[CMP1:%.*]] = icmp ugt i64 [[X:%.*]], [[Y:%.*]]
71875af6283SNikita Popov; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP1]])
71975af6283SNikita Popov; CHECK-NEXT:    [[GEP_X:%.*]] = getelementptr nuw i8, ptr [[P:%.*]], i64 [[X]]
72075af6283SNikita Popov; CHECK-NEXT:    [[GEP_X1:%.*]] = getelementptr nuw i8, ptr [[GEP_X]], i64 1
72175af6283SNikita Popov; CHECK-NEXT:    [[GEP_Y:%.*]] = getelementptr nuw i8, ptr [[P]], i64 [[Y]]
722*a608607fSNikita Popov; CHECK-NEXT:    ret i1 true
72375af6283SNikita Popov;
72475af6283SNikita Popov  %cmp1 = icmp ugt i64 %x, %y
72575af6283SNikita Popov  call void @llvm.assume(i1 %cmp1)
72675af6283SNikita Popov  %gep.x = getelementptr nuw i8, ptr %p, i64 %x
72775af6283SNikita Popov  %gep.x1 = getelementptr nuw i8, ptr %gep.x, i64 1
72875af6283SNikita Popov  %gep.y = getelementptr nuw i8, ptr %p, i64 %y
72975af6283SNikita Popov  %cmp2 = icmp ugt ptr %gep.x1, %gep.y
73075af6283SNikita Popov  ret i1 %cmp2
73175af6283SNikita Popov}
73275af6283SNikita Popov
73375af6283SNikita Popovdefine i1 @test_nuw_nested_missing_nuw(ptr %p, i64 %x, i64 %y) {
73475af6283SNikita Popov; CHECK-LABEL: @test_nuw_nested_missing_nuw(
73575af6283SNikita Popov; CHECK-NEXT:    [[CMP1:%.*]] = icmp ugt i64 [[X:%.*]], [[Y:%.*]]
73675af6283SNikita Popov; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP1]])
73775af6283SNikita Popov; CHECK-NEXT:    [[GEP_X:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[X]]
73875af6283SNikita Popov; CHECK-NEXT:    [[GEP_X1:%.*]] = getelementptr nuw i8, ptr [[GEP_X]], i64 1
73975af6283SNikita Popov; CHECK-NEXT:    [[GEP_Y:%.*]] = getelementptr nuw i8, ptr [[P]], i64 [[Y]]
74075af6283SNikita Popov; CHECK-NEXT:    [[CMP2:%.*]] = icmp ugt ptr [[GEP_X1]], [[GEP_Y]]
74175af6283SNikita Popov; CHECK-NEXT:    ret i1 [[CMP2]]
74275af6283SNikita Popov;
74375af6283SNikita Popov  %cmp1 = icmp ugt i64 %x, %y
74475af6283SNikita Popov  call void @llvm.assume(i1 %cmp1)
74575af6283SNikita Popov  %gep.x = getelementptr i8, ptr %p, i64 %x
74675af6283SNikita Popov  %gep.x1 = getelementptr nuw i8, ptr %gep.x, i64 1
74775af6283SNikita Popov  %gep.y = getelementptr nuw i8, ptr %p, i64 %y
74875af6283SNikita Popov  %cmp2 = icmp ugt ptr %gep.x1, %gep.y
74975af6283SNikita Popov  ret i1 %cmp2
75075af6283SNikita Popov}
75175af6283SNikita Popov
75275af6283SNikita Popovdefine i1 @test_nuw_incorrect_precondition(ptr %p, i64 %x, i64 %y) {
75375af6283SNikita Popov; CHECK-LABEL: @test_nuw_incorrect_precondition(
75475af6283SNikita Popov; CHECK-NEXT:    [[CMP1:%.*]] = icmp uge i64 [[X:%.*]], [[Y:%.*]]
75575af6283SNikita Popov; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP1]])
75675af6283SNikita Popov; CHECK-NEXT:    [[GEP_X:%.*]] = getelementptr nuw i8, ptr [[P:%.*]], i64 [[X]]
75775af6283SNikita Popov; CHECK-NEXT:    [[GEP_Y:%.*]] = getelementptr nuw i8, ptr [[P]], i64 [[Y]]
75875af6283SNikita Popov; CHECK-NEXT:    [[CMP2:%.*]] = icmp ugt ptr [[GEP_X]], [[GEP_Y]]
75975af6283SNikita Popov; CHECK-NEXT:    ret i1 [[CMP2]]
76075af6283SNikita Popov;
76175af6283SNikita Popov  %cmp1 = icmp uge i64 %x, %y
76275af6283SNikita Popov  call void @llvm.assume(i1 %cmp1)
76375af6283SNikita Popov  %gep.x = getelementptr nuw i8, ptr %p, i64 %x
76475af6283SNikita Popov  %gep.y = getelementptr nuw i8, ptr %p, i64 %y
76575af6283SNikita Popov  %cmp2 = icmp ugt ptr %gep.x, %gep.y
76675af6283SNikita Popov  ret i1 %cmp2
76775af6283SNikita Popov}
768