llvm.org GIT mirror llvm / 9c13e87
[LVI] Teach LVI to reason about ORs of icmps similar to how it reasons about ANDs of icmps Summary: LVI can reason about an AND of icmps on the true dest of a branch. I believe we can do similar for the false dest of ORs. This allows us to get the same answer for the demorganed versions of some of the AND test cases as you can see. Reviewers: anna, reames Reviewed By: reames Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D34431 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@306076 91177308-0d34-0410-b5e6-96231b3b80d8 Craig Topper 2 years ago
2 changed file(s) with 100 addition(s) and 5 deletion(s). Raw diff Collapse all Expand all
13231323 return getValueFromICmpCondition(Val, ICI, isTrueDest);
13241324
13251325 // Handle conditions in the form of (cond1 && cond2), we know that on the
1326 // true dest path both of the conditions hold.
1327 if (!isTrueDest)
1328 return LVILatticeVal::getOverdefined();
1329
1326 // true dest path both of the conditions hold. Similarly for conditions of
1327 // the form (cond1 || cond2), we know that on the false dest path neither
1328 // condition holds.
13301329 BinaryOperator *BO = dyn_cast(Cond);
1331 if (!BO || BO->getOpcode() != BinaryOperator::And)
1330 if (!BO || (isTrueDest && BO->getOpcode() != BinaryOperator::And) ||
1331 (!isTrueDest && BO->getOpcode() != BinaryOperator::Or))
13321332 return LVILatticeVal::getOverdefined();
13331333
13341334 auto RHS = getValueFromCondition(Val, BO->getOperand(0), isTrueDest, Visited);
211211 else:
212212 ret i32 0
213213 }
214
215 ; Check that we can gather information for conditions is the form of
216 ; or ( i s>= 100, Unknown )
217 ; CHECK-LABEL: @test12(
218 define void @test12(i32 %a, i1 %flag) {
219 entry:
220 %cmp.1 = icmp sge i32 %a, 100
221 %cmp = or i1 %cmp.1, %flag
222 br i1 %cmp, label %exit, label %bb
223
224 bb:
225 ; CHECK: %add = add nsw i32 %a, 1
226 %add = add i32 %a, 1
227 br label %exit
228
229 exit:
230 ret void
231 }
232
233 ; Check that we can gather information for conditions is the form of
234 ; or ( i s>= 100, i s<= 0 )
235 ; CHECK-LABEL: @test13(
236 define void @test13(i32 %a) {
237 entry:
238 %cmp.1 = icmp sge i32 %a, 100
239 %cmp.2 = icmp sle i32 %a, 0
240 %cmp = or i1 %cmp.1, %cmp.2
241 br i1 %cmp, label %exit, label %bb
242
243 bb:
244 ; CHECK: %add = add nuw nsw i32 %a, 1
245 %add = add i32 %a, 1
246 br label %exit
247
248 exit:
249 ret void
250 }
251
252 ; Check that for conditions is the form of cond1 || cond2 we don't mistakenly
253 ; assume that cond1 || cond2 holds down to true path.
254 ; CHECK-LABEL: @test13_neg(
255 define void @test13_neg(i32 %a) {
256 entry:
257 %cmp.1 = icmp slt i32 %a, 100
258 %cmp.2 = icmp sgt i32 %a, 0
259 %cmp = or i1 %cmp.1, %cmp.2
260 br i1 %cmp, label %bb, label %exit
261
262 bb:
263 ; CHECK: %add = add i32 %a, 1
264 %add = add i32 %a, 1
265 br label %exit
266
267 exit:
268 ret void
269 }
270
271 ; Check that we can gather information for conditions is the form of
272 ; or ( i s>=100, or (i s<= 0, Unknown )
273 ; CHECK-LABEL: @test14(
274 define void @test14(i32 %a, i1 %flag) {
275 entry:
276 %cmp.1 = icmp sge i32 %a, 100
277 %cmp.2 = icmp sle i32 %a, 0
278 %cmp.3 = or i1 %cmp.2, %flag
279 %cmp = or i1 %cmp.1, %cmp.3
280 br i1 %cmp, label %exit, label %bb
281
282 bb:
283 ; CHECK: %add = add nuw nsw i32 %a, 1
284 %add = add i32 %a, 1
285 br label %exit
286
287 exit:
288 ret void
289 }
290
291 ; Check that we can gather information for conditions is the form of
292 ; or ( i s>= Unknown, ... )
293 ; CHECK-LABEL: @test15(
294 define void @test15(i32 %a, i32 %b, i1 %flag) {
295 entry:
296 %cmp.1 = icmp sge i32 %a, %b
297 %cmp = or i1 %cmp.1, %flag
298 br i1 %cmp, label %exit, label %bb
299
300 bb:
301 ; CHECK: %add = add nsw i32 %a, 1
302 %add = add i32 %a, 1
303 br label %exit
304
305 exit:
306 ret void
307 }
308