diff options
author | Craig Topper <craig.topper@intel.com> | 2017-09-22 21:47:22 +0000 |
---|---|---|
committer | Craig Topper <craig.topper@intel.com> | 2017-09-22 21:47:22 +0000 |
commit | ea927baee2ab71dde4b4c8f4df5c565ea2ff9f2b (patch) | |
tree | 193a956bef78c32fd9686f999dcba588caa673db | |
parent | 73a998908f9ef62a5d899820310c211e3a700a43 (diff) | |
download | bcm5719-llvm-ea927baee2ab71dde4b4c8f4df5c565ea2ff9f2b.tar.gz bcm5719-llvm-ea927baee2ab71dde4b4c8f4df5c565ea2ff9f2b.zip |
[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
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp | 8 | ||||
-rw-r--r-- | llvm/test/Transforms/InstCombine/icmp.ll | 12 |
2 files changed, 12 insertions, 8 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index a9911f42cba..f38618e85e8 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/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<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; } diff --git a/llvm/test/Transforms/InstCombine/icmp.ll b/llvm/test/Transforms/InstCombine/icmp.ll index 014d8152248..68d98de0b4e 100644 --- a/llvm/test/Transforms/InstCombine/icmp.ll +++ b/llvm/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:%.*]], <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> |