[InstCombine] Teach foldICmpUsingKnownBits to simplify SLE/SGE/ULE/UGE to equality comparisons when the min/max ranges intersect in a single value.
This is the inverse of what we do for SGT/SLT/UGT/ULT. llvm-svn: 314032
This commit is contained in:
parent
73a998908f
commit
ea927baee2
@ -4272,6 +4272,8 @@ Instruction *InstCombiner::foldICmpUsingKnownBits(ICmpInst &I) {
|
||||
return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType()));
|
||||
if (Op0Max.slt(Op1Min)) // A >=s B -> false if max(A) < min(B)
|
||||
return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType()));
|
||||
if (Op1Min == Op0Max) // A >=s B -> A == B if max(A) == min(B)
|
||||
return new ICmpInst(ICmpInst::ICMP_EQ, Op0, Op1);
|
||||
break;
|
||||
case ICmpInst::ICMP_SLE:
|
||||
assert(!isa<ConstantInt>(Op1) && "ICMP_SLE with ConstantInt not folded!");
|
||||
@ -4279,6 +4281,8 @@ Instruction *InstCombiner::foldICmpUsingKnownBits(ICmpInst &I) {
|
||||
return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType()));
|
||||
if (Op0Min.sgt(Op1Max)) // A <=s B -> false if min(A) > max(B)
|
||||
return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType()));
|
||||
if (Op1Max == Op0Min) // A <=s B -> A == B if min(A) == max(B)
|
||||
return new ICmpInst(ICmpInst::ICMP_EQ, Op0, Op1);
|
||||
break;
|
||||
case ICmpInst::ICMP_UGE:
|
||||
assert(!isa<ConstantInt>(Op1) && "ICMP_UGE with ConstantInt not folded!");
|
||||
@ -4286,6 +4290,8 @@ Instruction *InstCombiner::foldICmpUsingKnownBits(ICmpInst &I) {
|
||||
return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType()));
|
||||
if (Op0Max.ult(Op1Min)) // A >=u B -> false if max(A) < min(B)
|
||||
return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType()));
|
||||
if (Op1Min == Op0Max) // A >=u B -> A == B if max(A) == min(B)
|
||||
return new ICmpInst(ICmpInst::ICMP_EQ, Op0, Op1);
|
||||
break;
|
||||
case ICmpInst::ICMP_ULE:
|
||||
assert(!isa<ConstantInt>(Op1) && "ICMP_ULE with ConstantInt not folded!");
|
||||
@ -4293,6 +4299,8 @@ Instruction *InstCombiner::foldICmpUsingKnownBits(ICmpInst &I) {
|
||||
return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType()));
|
||||
if (Op0Min.ugt(Op1Max)) // A <=u B -> false if min(A) > max(B)
|
||||
return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType()));
|
||||
if (Op1Max == Op0Min) // A <=u B -> A == B if min(A) == max(B)
|
||||
return new ICmpInst(ICmpInst::ICMP_EQ, Op0, Op1);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@ -3070,14 +3070,13 @@ define <8 x i1> @bitreverse_vec_ne(<8 x i16> %x, <8 x i16> %y) {
|
||||
|
||||
; These perform a comparison of a value known to be between 4 and 5 with a value between 5 and 7.
|
||||
; They should all simplify to equality compares.
|
||||
; FIXME this should simplify to an equality comparison
|
||||
define i1 @knownbits1(i8 %a, i8 %b) {
|
||||
; CHECK-LABEL: @knownbits1(
|
||||
; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], 1
|
||||
; CHECK-NEXT: [[A2:%.*]] = or i8 [[A1]], 4
|
||||
; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2
|
||||
; CHECK-NEXT: [[B2:%.*]] = or i8 [[B1]], 5
|
||||
; CHECK-NEXT: [[C:%.*]] = icmp uge i8 [[A2]], [[B2]]
|
||||
; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[A2]], [[B2]]
|
||||
; CHECK-NEXT: ret i1 [[C]]
|
||||
;
|
||||
%a1 = and i8 %a, 5
|
||||
@ -3105,14 +3104,13 @@ define i1 @knownbits2(i8 %a, i8 %b) {
|
||||
ret i1 %c
|
||||
}
|
||||
|
||||
; FIXME this should simplify to an equality comparison
|
||||
define i1 @knownbits3(i8 %a, i8 %b) {
|
||||
; CHECK-LABEL: @knownbits3(
|
||||
; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], 1
|
||||
; CHECK-NEXT: [[A2:%.*]] = or i8 [[A1]], 4
|
||||
; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2
|
||||
; CHECK-NEXT: [[B2:%.*]] = or i8 [[B1]], 5
|
||||
; CHECK-NEXT: [[C:%.*]] = icmp ule i8 [[B2]], [[A2]]
|
||||
; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[B2]], [[A2]]
|
||||
; CHECK-NEXT: ret i1 [[C]]
|
||||
;
|
||||
%a1 = and i8 %a, 5
|
||||
@ -3142,14 +3140,13 @@ define <2 x i1> @knownbits4(<2 x i8> %a, <2 x i8> %b) {
|
||||
|
||||
; These are the signed versions of the above. One value is less than or equal to 5, but maybe negative.
|
||||
; The other is known to be a value 5-7. These should simplify to equality comparisons.
|
||||
; FIXME this should simplify to an equality comparison
|
||||
define i1 @knownbits5(i8 %a, i8 %b) {
|
||||
; CHECK-LABEL: @knownbits5(
|
||||
; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], -127
|
||||
; CHECK-NEXT: [[A2:%.*]] = or i8 [[A1]], 4
|
||||
; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2
|
||||
; CHECK-NEXT: [[B2:%.*]] = or i8 [[B1]], 5
|
||||
; CHECK-NEXT: [[C:%.*]] = icmp sge i8 [[A2]], [[B2]]
|
||||
; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[A2]], [[B2]]
|
||||
; CHECK-NEXT: ret i1 [[C]]
|
||||
;
|
||||
%a1 = and i8 %a, 133
|
||||
@ -3177,14 +3174,13 @@ define i1 @knownbits6(i8 %a, i8 %b) {
|
||||
ret i1 %c
|
||||
}
|
||||
|
||||
; FIXME this should simplify to an equality comparison
|
||||
define <2 x i1> @knownbits7(<2 x i8> %a, <2 x i8> %b) {
|
||||
; CHECK-LABEL: @knownbits7(
|
||||
; CHECK-NEXT: [[A1:%.*]] = and <2 x i8> [[A:%.*]], <i8 -127, i8 -127>
|
||||
; CHECK-NEXT: [[A2:%.*]] = or <2 x i8> [[A1]], <i8 4, i8 4>
|
||||
; CHECK-NEXT: [[B1:%.*]] = and <2 x i8> [[B:%.*]], <i8 2, i8 2>
|
||||
; CHECK-NEXT: [[B2:%.*]] = or <2 x i8> [[B1]], <i8 5, i8 5>
|
||||
; CHECK-NEXT: [[C:%.*]] = icmp sle <2 x i8> [[B2]], [[A2]]
|
||||
; CHECK-NEXT: [[C:%.*]] = icmp eq <2 x i8> [[B2]], [[A2]]
|
||||
; CHECK-NEXT: ret <2 x i1> [[C]]
|
||||
;
|
||||
%a1 = and <2 x i8> %a, <i8 133, i8 133>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user