Skip to content
This repository was archived by the owner on Sep 2, 2018. It is now read-only.

Commit 66c1582

Browse files
author
sanjoy
committed
Simplify x >=u x >> y and x >=u x udiv y
Summary: Extends InstSimplify to handle both `x >=u x >> y` and `x >=u x udiv y`. This is a folloup of rL258422 and rust-lang/rust#30917 where llvm failed to optimize away the bounds checking in a binary search. Patch by Arthur Silva! Reviewers: sanjoy Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D25941 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@285228 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 349fe92 commit 66c1582

File tree

2 files changed

+43
-0
lines changed

2 files changed

+43
-0
lines changed

lib/Analysis/InstructionSimplify.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2857,6 +2857,17 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
28572857
return getTrue(ITy);
28582858
}
28592859

2860+
// x >=u x >> y
2861+
// x >=u x udiv y.
2862+
if (RBO && (match(RBO, m_LShr(m_Specific(LHS), m_Value())) ||
2863+
match(RBO, m_UDiv(m_Specific(LHS), m_Value())))) {
2864+
// icmp pred X, (X op Y)
2865+
if (Pred == ICmpInst::ICMP_ULT)
2866+
return getFalse(ITy);
2867+
if (Pred == ICmpInst::ICMP_UGE)
2868+
return getTrue(ITy);
2869+
}
2870+
28602871
// handle:
28612872
// CI2 << X == CI
28622873
// CI2 << X != CI

test/Transforms/InstSimplify/compare.ll

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,22 @@ define i1 @lshr5(i32 %X, i32 %Y) {
409409
; CHECK: ret i1 false
410410
}
411411

412+
define i1 @lshr6(i32 %X, i32 %Y) {
413+
; CHECK-LABEL: @lshr6(
414+
%A = lshr i32 %X, %Y
415+
%C = icmp ult i32 %X, %A
416+
ret i1 %C
417+
; CHECK: ret i1 false
418+
}
419+
420+
define i1 @lshr7(i32 %X, i32 %Y) {
421+
; CHECK-LABEL: @lshr7(
422+
%A = lshr i32 %X, %Y
423+
%C = icmp uge i32 %X, %A
424+
ret i1 %C
425+
; CHECK: ret i1 true
426+
}
427+
412428
define i1 @ashr1(i32 %x) {
413429
; CHECK-LABEL: @ashr1(
414430
%s = ashr i32 -1, %x
@@ -583,6 +599,22 @@ define i1 @udiv6(i32 %X) nounwind {
583599
; CHECK: ret i1 %C
584600
}
585601

602+
define i1 @udiv7(i32 %X, i32 %Y) {
603+
; CHECK-LABEL: @udiv7(
604+
%A = udiv i32 %X, %Y
605+
%C = icmp ult i32 %X, %A
606+
ret i1 %C
607+
; CHECK: ret i1 false
608+
}
609+
610+
define i1 @udiv8(i32 %X, i32 %Y) {
611+
; CHECK-LABEL: @udiv8(
612+
%A = udiv i32 %X, %Y
613+
%C = icmp uge i32 %X, %A
614+
ret i1 %C
615+
; CHECK: ret i1 true
616+
}
617+
586618
define i1 @mul1(i32 %X) {
587619
; CHECK-LABEL: @mul1(
588620
; Square of a non-zero number is non-zero if there is no overflow.

0 commit comments

Comments
 (0)