llvm.org GIT mirror llvm / a6da8aa
[LVI] Handle any predicate in comparisons like icmp <pred> (add Val, Offset), ... Currently LVI can only gather value constraints from comparisons like: * icmp <pred> Val, ... * icmp ult (add Val, Offset), ... In fact we can handle any predicate in latter comparisons. Reviewed By: sanjoy Differential Revision: https://reviews.llvm.org/D23357 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@278493 91177308-0d34-0410-b5e6-96231b3b80d8 Artur Pilipenko 3 years ago
2 changed file(s) with 132 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
11901190 // range of Val guaranteed by the condition. Recognize comparisons in the from
11911191 // of:
11921192 // icmp Val, ...
1193 // icmp ult (add Val, Offset), ...
1193 // icmp (add Val, Offset), ...
11941194 // The latter is the range checking idiom that InstCombine produces. Subtract
11951195 // the offset from the allowed range for RHS in this case.
11961196
12011201 }
12021202
12031203 ConstantInt *Offset = nullptr;
1204 if (Predicate == ICmpInst::ICMP_ULT)
1204 if (LHS != Val)
12051205 match(LHS, m_Add(m_Specific(Val), m_ConstantInt(Offset)));
12061206
12071207 if (LHS == Val || Offset) {
314314 end:
315315 ret i32 2
316316 }
317
318 define i1 @test14_slt(i32 %a) {
319 ; CHECK-LABEL: @test14_slt(
320 ; CHECK: then:
321 ; CHECK-NEXT: %result = or i1 false, false
322 %a.off = add i32 %a, -8
323 %cmp = icmp slt i32 %a.off, 8
324 br i1 %cmp, label %then, label %else
325
326 then:
327 %dead.1 = icmp eq i32 %a, -2147483641
328 %dead.2 = icmp eq i32 %a, 16
329 %result = or i1 %dead.1, %dead.2
330 ret i1 %result
331
332 else:
333 ret i1 false
334 }
335
336 define i1 @test14_sle(i32 %a) {
337 ; CHECK-LABEL: @test14_sle(
338 ; CHECK: then:
339 ; CHECK-NEXT: %alive = icmp eq i32 %a, 16
340 ; CHECK-NEXT: %result = or i1 false, %alive
341 %a.off = add i32 %a, -8
342 %cmp = icmp sle i32 %a.off, 8
343 br i1 %cmp, label %then, label %else
344
345 then:
346 %dead = icmp eq i32 %a, -2147483641
347 %alive = icmp eq i32 %a, 16
348 %result = or i1 %dead, %alive
349 ret i1 %result
350
351 else:
352 ret i1 false
353 }
354
355 define i1 @test14_sgt(i32 %a) {
356 ; CHECK-LABEL: @test14_sgt(
357 ; CHECK: then:
358 ; CHECK-NEXT: %result = or i1 false, false
359 %a.off = add i32 %a, -8
360 %cmp = icmp sgt i32 %a.off, 8
361 br i1 %cmp, label %then, label %else
362
363 then:
364 %dead.1 = icmp eq i32 %a, -2147483640
365 %dead.2 = icmp eq i32 %a, 16
366 %result = or i1 %dead.1, %dead.2
367 ret i1 %result
368
369 else:
370 ret i1 false
371 }
372
373 define i1 @test14_sge(i32 %a) {
374 ; CHECK-LABEL: @test14_sge(
375 ; CHECK: then:
376 ; CHECK-NEXT: %alive = icmp eq i32 %a, 16
377 ; CHECK-NEXT: %result = or i1 false, %alive
378 %a.off = add i32 %a, -8
379 %cmp = icmp sge i32 %a.off, 8
380 br i1 %cmp, label %then, label %else
381
382 then:
383 %dead = icmp eq i32 %a, -2147483640
384 %alive = icmp eq i32 %a, 16
385 %result = or i1 %dead, %alive
386 ret i1 %result
387
388 else:
389 ret i1 false
390 }
391
392 define i1 @test14_ule(i32 %a) {
393 ; CHECK-LABEL: @test14_ule(
394 ; CHECK: then:
395 ; CHECK-NEXT: %alive = icmp eq i32 %a, 16
396 ; CHECK-NEXT: %result = or i1 false, %alive
397 %a.off = add i32 %a, -8
398 %cmp = icmp ule i32 %a.off, 8
399 br i1 %cmp, label %then, label %else
400
401 then:
402 %dead = icmp eq i32 %a, 7
403 %alive = icmp eq i32 %a, 16
404 %result = or i1 %dead, %alive
405 ret i1 %result
406
407 else:
408 ret i1 false
409 }
410
411 define i1 @test14_ugt(i32 %a) {
412 ; CHECK-LABEL: @test14_ugt(
413 ; CHECK: then:
414 ; CHECK-NEXT: %result = or i1 false, false
415 %a.off = add i32 %a, -8
416 %cmp = icmp ugt i32 %a.off, 8
417 br i1 %cmp, label %then, label %else
418
419 then:
420 %dead.1 = icmp eq i32 %a, 8
421 %dead.2 = icmp eq i32 %a, 16
422 %result = or i1 %dead.1, %dead.2
423 ret i1 %result
424
425 else:
426 ret i1 false
427 }
428
429 define i1 @test14_uge(i32 %a) {
430 ; CHECK-LABEL: @test14_uge(
431 ; CHECK: then:
432 ; CHECK-NEXT: %alive = icmp eq i32 %a, 16
433 ; CHECK-NEXT: %result = or i1 false, %alive
434 %a.off = add i32 %a, -8
435 %cmp = icmp uge i32 %a.off, 8
436 br i1 %cmp, label %then, label %else
437
438 then:
439 %dead = icmp eq i32 %a, 8
440 %alive = icmp eq i32 %a, 16
441 %result = or i1 %dead, %alive
442 ret i1 %result
443
444 else:
445 ret i1 false
446 }