[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / Transforms / ConstraintElimination / loops-bottom-tested-pointer-cmps.ll
blob55b1b89b8aac7aeef39789ecafa42263173f37e9
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -constraint-elimination -S %s | FileCheck %s
4 declare void @use(i1)
5 define void @checks_in_loops_removable(i8* %ptr, i8* %lower, i8* %upper, i32 %n) {
6 ; CHECK-LABEL: @checks_in_loops_removable(
7 ; CHECK-NEXT:  entry:
8 ; CHECK-NEXT:    [[CMP_PTR_LOWER:%.*]] = icmp ult i8* [[PTR:%.*]], [[LOWER:%.*]]
9 ; CHECK-NEXT:    br i1 [[CMP_PTR_LOWER]], label [[TRAP:%.*]], label [[PRE_1:%.*]]
10 ; CHECK:       pre.1:
11 ; CHECK-NEXT:    [[IDX_EXT:%.*]] = zext i32 [[N:%.*]] to i64
12 ; CHECK-NEXT:    [[PTR_N:%.*]] = getelementptr inbounds i8, i8* [[PTR]], i64 [[IDX_EXT]]
13 ; CHECK-NEXT:    [[CMP_PTR_N_UPPER:%.*]] = icmp ult i8* [[PTR_N]], [[UPPER:%.*]]
14 ; CHECK-NEXT:    br i1 [[CMP_PTR_N_UPPER]], label [[PRE_2:%.*]], label [[TRAP]]
15 ; CHECK:       pre.2:
16 ; CHECK-NEXT:    [[CMP_N_NOT_ZERO:%.*]] = icmp eq i32 [[N]], 0
17 ; CHECK-NEXT:    br i1 [[CMP_N_NOT_ZERO]], label [[EXIT:%.*]], label [[LOOP_HEADER:%.*]]
18 ; CHECK:       trap:
19 ; CHECK-NEXT:    ret void
20 ; CHECK:       loop.header:
21 ; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[PRE_2]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
22 ; CHECK-NEXT:    [[PTR_IV:%.*]] = getelementptr inbounds i8, i8* [[PTR]], i64 [[IV]]
23 ; CHECK-NEXT:    [[CMP_PTR_IV_LOWER:%.*]] = icmp ugt i8* [[LOWER]], [[PTR_IV]]
24 ; CHECK-NEXT:    [[CMP_PTR_IV_UPPER:%.*]] = icmp ule i8* [[UPPER]], [[PTR_IV]]
25 ; CHECK-NEXT:    [[OR:%.*]] = or i1 [[CMP_PTR_IV_LOWER]], [[CMP_PTR_IV_UPPER]]
26 ; CHECK-NEXT:    br i1 [[OR]], label [[TRAP]], label [[LOOP_LATCH]]
27 ; CHECK:       loop.latch:
28 ; CHECK-NEXT:    store i8 0, i8* [[PTR_IV]], align 4
29 ; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
30 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[IV_NEXT]], [[IDX_EXT]]
31 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP_HEADER]], label [[EXIT]]
32 ; CHECK:       exit:
33 ; CHECK-NEXT:    ret void
35 entry:
36   %cmp.ptr.lower = icmp ult i8* %ptr, %lower
37   br i1 %cmp.ptr.lower, label %trap, label %pre.1
39 pre.1:
40   %idx.ext = zext i32 %n to i64
41   %ptr.n = getelementptr inbounds i8, i8* %ptr, i64 %idx.ext
42   %cmp.ptr.n.upper = icmp ult i8* %ptr.n, %upper
43   br i1 %cmp.ptr.n.upper, label %pre.2, label %trap
45 pre.2:
46   %cmp.n.not.zero = icmp eq i32 %n, 0
47   br i1 %cmp.n.not.zero, label %exit, label %loop.header
49 trap:
50   ret void
52 loop.header:
53   %iv = phi i64 [ 0, %pre.2 ], [ %iv.next, %loop.latch ]
54   %ptr.iv = getelementptr inbounds i8, i8* %ptr, i64 %iv
55   %cmp.ptr.iv.lower = icmp ugt i8* %lower, %ptr.iv
56   %cmp.ptr.iv.upper = icmp ule i8* %upper, %ptr.iv
57   %or = or i1 %cmp.ptr.iv.lower, %cmp.ptr.iv.upper
58   br i1 %or, label %trap, label %loop.latch
60 loop.latch:
61   store i8 0, i8* %ptr.iv, align 4
62   %iv.next = add nuw nsw i64 %iv, 1
63   %exitcond = icmp ne i64 %iv.next, %idx.ext
64   br i1 %exitcond, label %loop.header, label %exit
66 exit:
67   ret void
70 define void @some_checks_in_loops_removable(i8* %ptr, i8* %lower, i8* %upper, i32 %n) {
71 ; CHECK-LABEL: @some_checks_in_loops_removable(
72 ; CHECK-NEXT:  entry:
73 ; CHECK-NEXT:    [[CMP_PTR_LOWER:%.*]] = icmp ult i8* [[PTR:%.*]], [[LOWER:%.*]]
74 ; CHECK-NEXT:    br i1 [[CMP_PTR_LOWER]], label [[TRAP:%.*]], label [[PRE_1:%.*]]
75 ; CHECK:       pre.1:
76 ; CHECK-NEXT:    [[IDX_EXT:%.*]] = zext i32 [[N:%.*]] to i64
77 ; CHECK-NEXT:    [[PTR_N:%.*]] = getelementptr inbounds i8, i8* [[PTR]], i64 [[IDX_EXT]]
78 ; CHECK-NEXT:    [[CMP_PTR_N_UPPER:%.*]] = icmp ult i8* [[PTR_N]], [[UPPER:%.*]]
79 ; CHECK-NEXT:    br i1 [[CMP_PTR_N_UPPER]], label [[PRE_2:%.*]], label [[TRAP]]
80 ; CHECK:       pre.2:
81 ; CHECK-NEXT:    [[CMP_N_NOT_ZERO:%.*]] = icmp eq i32 [[N]], 0
82 ; CHECK-NEXT:    br i1 [[CMP_N_NOT_ZERO]], label [[EXIT:%.*]], label [[LOOP_HEADER:%.*]]
83 ; CHECK:       trap:
84 ; CHECK-NEXT:    ret void
85 ; CHECK:       loop.header:
86 ; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[PRE_2]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
87 ; CHECK-NEXT:    [[PTR_IV:%.*]] = getelementptr inbounds i8, i8* [[PTR]], i64 [[IV]]
88 ; CHECK-NEXT:    [[CMP_PTR_IV_LOWER:%.*]] = icmp ugt i8* [[LOWER]], [[PTR_IV]]
89 ; CHECK-NEXT:    [[CMP_PTR_IV_UPPER:%.*]] = icmp ule i8* [[UPPER]], [[PTR_IV]]
90 ; CHECK-NEXT:    [[OR:%.*]] = or i1 [[CMP_PTR_IV_LOWER]], [[CMP_PTR_IV_UPPER]]
91 ; CHECK-NEXT:    br i1 [[OR]], label [[TRAP]], label [[LOOP_BODY:%.*]]
92 ; CHECK:       loop.body:
93 ; CHECK-NEXT:    [[IV_1:%.*]] = add nuw nsw i64 [[IV]], 1
94 ; CHECK-NEXT:    [[PTR_IV_1:%.*]] = getelementptr inbounds i8, i8* [[PTR]], i64 [[IV_1]]
95 ; CHECK-NEXT:    [[CMP_PTR_IV_1_LOWER:%.*]] = icmp ugt i8* [[LOWER]], [[PTR_IV_1]]
96 ; CHECK-NEXT:    [[CMP_PTR_IV_1_UPPER:%.*]] = icmp ule i8* [[UPPER]], [[PTR_IV_1]]
97 ; CHECK-NEXT:    [[OR_1:%.*]] = or i1 false, [[CMP_PTR_IV_1_UPPER]]
98 ; CHECK-NEXT:    br i1 [[OR]], label [[TRAP]], label [[LOOP_LATCH]]
99 ; CHECK:       loop.latch:
100 ; CHECK-NEXT:    store i8 0, i8* [[PTR_IV]], align 4
101 ; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
102 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[IV_NEXT]], [[IDX_EXT]]
103 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP_HEADER]], label [[EXIT]]
104 ; CHECK:       exit:
105 ; CHECK-NEXT:    ret void
107 entry:
108   %cmp.ptr.lower = icmp ult i8* %ptr, %lower
109   br i1 %cmp.ptr.lower, label %trap, label %pre.1
111 pre.1:
112   %idx.ext = zext i32 %n to i64
113   %ptr.n = getelementptr inbounds i8, i8* %ptr, i64 %idx.ext
114   %cmp.ptr.n.upper = icmp ult i8* %ptr.n, %upper
115   br i1 %cmp.ptr.n.upper, label %pre.2, label %trap
117 pre.2:
118   %cmp.n.not.zero = icmp eq i32 %n, 0
119   br i1 %cmp.n.not.zero, label %exit, label %loop.header
121 trap:
122   ret void
124 loop.header:
125   %iv = phi i64 [ 0, %pre.2 ], [ %iv.next, %loop.latch ]
126   %ptr.iv = getelementptr inbounds i8, i8* %ptr, i64 %iv
127   %cmp.ptr.iv.lower = icmp ugt i8* %lower, %ptr.iv
128   %cmp.ptr.iv.upper = icmp ule i8* %upper, %ptr.iv
129   %or = or i1 %cmp.ptr.iv.lower, %cmp.ptr.iv.upper
130   br i1 %or, label %trap, label %loop.body
132 loop.body:
133   %iv.1 = add nuw nsw i64 %iv, 1
134   %ptr.iv.1 = getelementptr inbounds i8, i8* %ptr, i64 %iv.1
135   %cmp.ptr.iv.1.lower = icmp ugt i8* %lower, %ptr.iv.1
136   %cmp.ptr.iv.1.upper = icmp ule i8* %upper, %ptr.iv.1
137   %or.1 = or i1 %cmp.ptr.iv.1.lower, %cmp.ptr.iv.1.upper
138   br i1 %or, label %trap, label %loop.latch
140 loop.latch:
141   store i8 0, i8* %ptr.iv, align 4
142   %iv.next = add nuw nsw i64 %iv, 1
143   %exitcond = icmp ne i64 %iv.next, %idx.ext
144   br i1 %exitcond, label %loop.header, label %exit
146 exit:
147   ret void
151 ; N might be zero, cannot remove upper checks.
152 define void @no_checks_in_loops_removable(i8* %ptr, i8* %lower, i8* %upper, i32 %n) {
153 ; CHECK-LABEL: @no_checks_in_loops_removable(
154 ; CHECK-NEXT:  entry:
155 ; CHECK-NEXT:    [[CMP_PTR_LOWER:%.*]] = icmp ult i8* [[PTR:%.*]], [[LOWER:%.*]]
156 ; CHECK-NEXT:    br i1 [[CMP_PTR_LOWER]], label [[TRAP:%.*]], label [[PRE_1:%.*]]
157 ; CHECK:       pre.1:
158 ; CHECK-NEXT:    [[IDX_EXT:%.*]] = zext i32 [[N:%.*]] to i64
159 ; CHECK-NEXT:    [[PTR_N:%.*]] = getelementptr inbounds i8, i8* [[PTR]], i64 [[IDX_EXT]]
160 ; CHECK-NEXT:    [[CMP_PTR_N_UPPER:%.*]] = icmp ult i8* [[PTR_N]], [[UPPER:%.*]]
161 ; CHECK-NEXT:    br i1 [[CMP_PTR_N_UPPER]], label [[LOOP_HEADER:%.*]], label [[TRAP]]
162 ; CHECK:       trap:
163 ; CHECK-NEXT:    ret void
164 ; CHECK:       loop.header:
165 ; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[PRE_1]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
166 ; CHECK-NEXT:    [[PTR_IV:%.*]] = getelementptr inbounds i8, i8* [[PTR]], i64 [[IV]]
167 ; CHECK-NEXT:    [[CMP_PTR_IV_LOWER:%.*]] = icmp ugt i8* [[LOWER]], [[PTR_IV]]
168 ; CHECK-NEXT:    [[CMP_PTR_IV_UPPER:%.*]] = icmp ule i8* [[UPPER]], [[PTR_IV]]
169 ; CHECK-NEXT:    [[OR:%.*]] = or i1 [[CMP_PTR_IV_LOWER]], [[CMP_PTR_IV_UPPER]]
170 ; CHECK-NEXT:    br i1 [[OR]], label [[TRAP]], label [[LOOP_BODY:%.*]]
171 ; CHECK:       loop.body:
172 ; CHECK-NEXT:    [[IV_1:%.*]] = add nuw nsw i64 [[IV]], 1
173 ; CHECK-NEXT:    [[PTR_IV_1:%.*]] = getelementptr inbounds i8, i8* [[PTR]], i64 [[IV_1]]
174 ; CHECK-NEXT:    [[CMP_PTR_IV_1_LOWER:%.*]] = icmp ugt i8* [[LOWER]], [[PTR_IV_1]]
175 ; CHECK-NEXT:    [[CMP_PTR_IV_1_UPPER:%.*]] = icmp ule i8* [[UPPER]], [[PTR_IV_1]]
176 ; CHECK-NEXT:    [[OR_1:%.*]] = or i1 false, [[CMP_PTR_IV_1_UPPER]]
177 ; CHECK-NEXT:    br i1 [[OR]], label [[TRAP]], label [[LOOP_LATCH]]
178 ; CHECK:       loop.latch:
179 ; CHECK-NEXT:    store i8 0, i8* [[PTR_IV]], align 4
180 ; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
181 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[IV_NEXT]], [[IDX_EXT]]
182 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[LOOP_HEADER]], label [[EXIT:%.*]]
183 ; CHECK:       exit:
184 ; CHECK-NEXT:    ret void
186 entry:
187   %cmp.ptr.lower = icmp ult i8* %ptr, %lower
188   br i1 %cmp.ptr.lower, label %trap, label %pre.1
190 pre.1:
191   %idx.ext = zext i32 %n to i64
192   %ptr.n = getelementptr inbounds i8, i8* %ptr, i64 %idx.ext
193   %cmp.ptr.n.upper = icmp ult i8* %ptr.n, %upper
194   br i1 %cmp.ptr.n.upper, label %loop.header, label %trap
196 trap:
197   ret void
199 loop.header:
200   %iv = phi i64 [ 0, %pre.1 ], [ %iv.next, %loop.latch ]
201   %ptr.iv = getelementptr inbounds i8, i8* %ptr, i64 %iv
202   %cmp.ptr.iv.lower = icmp ugt i8* %lower, %ptr.iv
203   %cmp.ptr.iv.upper = icmp ule i8* %upper, %ptr.iv
204   %or = or i1 %cmp.ptr.iv.lower, %cmp.ptr.iv.upper
205   br i1 %or, label %trap, label %loop.body
207 loop.body:
208   %iv.1 = add nuw nsw i64 %iv, 1
209   %ptr.iv.1 = getelementptr inbounds i8, i8* %ptr, i64 %iv.1
210   %cmp.ptr.iv.1.lower = icmp ugt i8* %lower, %ptr.iv.1
211   %cmp.ptr.iv.1.upper = icmp ule i8* %upper, %ptr.iv.1
212   %or.1 = or i1 %cmp.ptr.iv.1.lower, %cmp.ptr.iv.1.upper
213   br i1 %or, label %trap, label %loop.latch
215 loop.latch:
216   store i8 0, i8* %ptr.iv, align 4
217   %iv.next = add nuw nsw i64 %iv, 1
218   %exitcond = icmp ne i64 %iv.next, %idx.ext
219   br i1 %exitcond, label %loop.header, label %exit
221 exit:
222   ret void