Skip to content

Commit 0f937f6

Browse files
author
ctopper
committed
[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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@314032 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 9c11776 commit 0f937f6

File tree

2 files changed

+12
-8
lines changed

2 files changed

+12
-8
lines changed

lib/Transforms/InstCombine/InstCombineCompares.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4272,27 +4272,35 @@ Instruction *InstCombiner::foldICmpUsingKnownBits(ICmpInst &I) {
42724272
return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType()));
42734273
if (Op0Max.slt(Op1Min)) // A >=s B -> false if max(A) < min(B)
42744274
return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType()));
4275+
if (Op1Min == Op0Max) // A >=s B -> A == B if max(A) == min(B)
4276+
return new ICmpInst(ICmpInst::ICMP_EQ, Op0, Op1);
42754277
break;
42764278
case ICmpInst::ICMP_SLE:
42774279
assert(!isa<ConstantInt>(Op1) && "ICMP_SLE with ConstantInt not folded!");
42784280
if (Op0Max.sle(Op1Min)) // A <=s B -> true if max(A) <= min(B)
42794281
return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType()));
42804282
if (Op0Min.sgt(Op1Max)) // A <=s B -> false if min(A) > max(B)
42814283
return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType()));
4284+
if (Op1Max == Op0Min) // A <=s B -> A == B if min(A) == max(B)
4285+
return new ICmpInst(ICmpInst::ICMP_EQ, Op0, Op1);
42824286
break;
42834287
case ICmpInst::ICMP_UGE:
42844288
assert(!isa<ConstantInt>(Op1) && "ICMP_UGE with ConstantInt not folded!");
42854289
if (Op0Min.uge(Op1Max)) // A >=u B -> true if min(A) >= max(B)
42864290
return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType()));
42874291
if (Op0Max.ult(Op1Min)) // A >=u B -> false if max(A) < min(B)
42884292
return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType()));
4293+
if (Op1Min == Op0Max) // A >=u B -> A == B if max(A) == min(B)
4294+
return new ICmpInst(ICmpInst::ICMP_EQ, Op0, Op1);
42894295
break;
42904296
case ICmpInst::ICMP_ULE:
42914297
assert(!isa<ConstantInt>(Op1) && "ICMP_ULE with ConstantInt not folded!");
42924298
if (Op0Max.ule(Op1Min)) // A <=u B -> true if max(A) <= min(B)
42934299
return replaceInstUsesWith(I, ConstantInt::getTrue(I.getType()));
42944300
if (Op0Min.ugt(Op1Max)) // A <=u B -> false if min(A) > max(B)
42954301
return replaceInstUsesWith(I, ConstantInt::getFalse(I.getType()));
4302+
if (Op1Max == Op0Min) // A <=u B -> A == B if min(A) == max(B)
4303+
return new ICmpInst(ICmpInst::ICMP_EQ, Op0, Op1);
42964304
break;
42974305
}
42984306

test/Transforms/InstCombine/icmp.ll

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3070,14 +3070,13 @@ define <8 x i1> @bitreverse_vec_ne(<8 x i16> %x, <8 x i16> %y) {
30703070

30713071
; These perform a comparison of a value known to be between 4 and 5 with a value between 5 and 7.
30723072
; They should all simplify to equality compares.
3073-
; FIXME this should simplify to an equality comparison
30743073
define i1 @knownbits1(i8 %a, i8 %b) {
30753074
; CHECK-LABEL: @knownbits1(
30763075
; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], 1
30773076
; CHECK-NEXT: [[A2:%.*]] = or i8 [[A1]], 4
30783077
; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2
30793078
; CHECK-NEXT: [[B2:%.*]] = or i8 [[B1]], 5
3080-
; CHECK-NEXT: [[C:%.*]] = icmp uge i8 [[A2]], [[B2]]
3079+
; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[A2]], [[B2]]
30813080
; CHECK-NEXT: ret i1 [[C]]
30823081
;
30833082
%a1 = and i8 %a, 5
@@ -3105,14 +3104,13 @@ define i1 @knownbits2(i8 %a, i8 %b) {
31053104
ret i1 %c
31063105
}
31073106

3108-
; FIXME this should simplify to an equality comparison
31093107
define i1 @knownbits3(i8 %a, i8 %b) {
31103108
; CHECK-LABEL: @knownbits3(
31113109
; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], 1
31123110
; CHECK-NEXT: [[A2:%.*]] = or i8 [[A1]], 4
31133111
; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2
31143112
; CHECK-NEXT: [[B2:%.*]] = or i8 [[B1]], 5
3115-
; CHECK-NEXT: [[C:%.*]] = icmp ule i8 [[B2]], [[A2]]
3113+
; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[B2]], [[A2]]
31163114
; CHECK-NEXT: ret i1 [[C]]
31173115
;
31183116
%a1 = and i8 %a, 5
@@ -3142,14 +3140,13 @@ define <2 x i1> @knownbits4(<2 x i8> %a, <2 x i8> %b) {
31423140

31433141
; These are the signed versions of the above. One value is less than or equal to 5, but maybe negative.
31443142
; The other is known to be a value 5-7. These should simplify to equality comparisons.
3145-
; FIXME this should simplify to an equality comparison
31463143
define i1 @knownbits5(i8 %a, i8 %b) {
31473144
; CHECK-LABEL: @knownbits5(
31483145
; CHECK-NEXT: [[A1:%.*]] = and i8 [[A:%.*]], -127
31493146
; CHECK-NEXT: [[A2:%.*]] = or i8 [[A1]], 4
31503147
; CHECK-NEXT: [[B1:%.*]] = and i8 [[B:%.*]], 2
31513148
; CHECK-NEXT: [[B2:%.*]] = or i8 [[B1]], 5
3152-
; CHECK-NEXT: [[C:%.*]] = icmp sge i8 [[A2]], [[B2]]
3149+
; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[A2]], [[B2]]
31533150
; CHECK-NEXT: ret i1 [[C]]
31543151
;
31553152
%a1 = and i8 %a, 133
@@ -3177,14 +3174,13 @@ define i1 @knownbits6(i8 %a, i8 %b) {
31773174
ret i1 %c
31783175
}
31793176

3180-
; FIXME this should simplify to an equality comparison
31813177
define <2 x i1> @knownbits7(<2 x i8> %a, <2 x i8> %b) {
31823178
; CHECK-LABEL: @knownbits7(
31833179
; CHECK-NEXT: [[A1:%.*]] = and <2 x i8> [[A:%.*]], <i8 -127, i8 -127>
31843180
; CHECK-NEXT: [[A2:%.*]] = or <2 x i8> [[A1]], <i8 4, i8 4>
31853181
; CHECK-NEXT: [[B1:%.*]] = and <2 x i8> [[B:%.*]], <i8 2, i8 2>
31863182
; CHECK-NEXT: [[B2:%.*]] = or <2 x i8> [[B1]], <i8 5, i8 5>
3187-
; CHECK-NEXT: [[C:%.*]] = icmp sle <2 x i8> [[B2]], [[A2]]
3183+
; CHECK-NEXT: [[C:%.*]] = icmp eq <2 x i8> [[B2]], [[A2]]
31883184
; CHECK-NEXT: ret <2 x i1> [[C]]
31893185
;
31903186
%a1 = and <2 x i8> %a, <i8 133, i8 133>

0 commit comments

Comments
 (0)