From e402b549badd6aa7066802d91b711c8a995da317 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Fri, 22 Sep 2017 21:47:22 +0000 Subject: [PATCH] [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 --- lib/Transforms/InstCombine/InstCombineCompares.cpp | 8 ++++++++ test/Transforms/InstCombine/icmp.ll | 12 ++++-------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/lib/Transforms/InstCombine/InstCombineCompares.cpp b/lib/Transforms/InstCombine/InstCombineCompares.cpp index a9911f42cba..f38618e85e8 100644 --- a/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -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(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(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(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; } diff --git a/test/Transforms/InstCombine/icmp.ll b/test/Transforms/InstCombine/icmp.ll index 014d8152248..68d98de0b4e 100644 --- a/test/Transforms/InstCombine/icmp.ll +++ b/test/Transforms/InstCombine/icmp.ll @@ -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:%.*]], ; CHECK-NEXT: [[A2:%.*]] = or <2 x i8> [[A1]], ; CHECK-NEXT: [[B1:%.*]] = and <2 x i8> [[B:%.*]], ; CHECK-NEXT: [[B2:%.*]] = or <2 x i8> [[B1]], -; 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, -- 2.40.0