[InstCombine] (icmp sgt smin(PosA, B) 0) -> (icmp sgt B 0)

When checking whether an smin is positive, we can move the comparison to one of the inputs if the other is known positive. If the known positive one is the min, then the other can't be negative. If the other is the min, then we compute the min.

Differential Revision: http://reviews.llvm.org/D17873



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@263059 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Philip Reames 2016-03-09 21:05:07 +00:00
parent cc638e59fd
commit 37f4f50139
2 changed files with 47 additions and 0 deletions

View File

@ -3173,6 +3173,19 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) {
return Res;
}
// (icmp sgt smin(PosA, B) 0) -> (icmp sgt B 0)
if (CI->isZero() && I.getPredicate() == ICmpInst::ICMP_SGT)
if (auto *SI = dyn_cast<SelectInst>(Op0)) {
SelectPatternResult SPR = matchSelectPattern(SI, A, B);
if (SPR.Flavor == SPF_SMIN) {
if (isKnownNonNegative(A, DL) && isKnownNonZero(A, DL))
return new ICmpInst(I.getPredicate(), B, CI);
if (isKnownNonNegative(B, DL) && isKnownNonZero(B, DL))
return new ICmpInst(I.getPredicate(), A, CI);
}
}
// The following transforms are only 'worth it' if the only user of the
// subtraction is the icmp.
if (Op0->hasOneUse()) {

View File

@ -0,0 +1,34 @@
; RUN: opt -S -instcombine < %s | FileCheck %s
@g = external global i32
define i1 @test(i32 %other) {
; CHECK-LABEL: @test
; CHECK: %test = icmp sgt i32 %other, 0
%positive = load i32, i32* @g, !range !{i32 1, i32 2048}
%cmp = icmp slt i32 %positive, %other
%sel = select i1 %cmp, i32 %positive, i32 %other
%test = icmp sgt i32 %sel, 0
ret i1 %test
}
define i1 @test2(i32 %other) {
; CHECK-LABEL: @test2
; CHECK: %test = icmp sgt i32 %other, 0
%positive = load i32, i32* @g, !range !{i32 1, i32 2048}
%cmp = icmp slt i32 %other, %positive
%sel = select i1 %cmp, i32 %other, i32 %positive
%test = icmp sgt i32 %sel, 0
ret i1 %test
}
; %positive might be zero
define i1 @test3(i32 %other) {
; CHECK-LABEL: @test3
; CHECK: %test = icmp sgt i32 %sel, 0
%positive = load i32, i32* @g, !range !{i32 0, i32 2048}
%cmp = icmp slt i32 %positive, %other
%sel = select i1 %cmp, i32 %positive, i32 %other
%test = icmp sgt i32 %sel, 0
ret i1 %test
}