From ba212c241ab233b4830941f36c4608bee4eca4a3 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Wed, 17 May 2017 22:29:40 +0000 Subject: [PATCH] [InstCombine] handle icmp i1 X, C early to avoid creating an unknown pattern The missing optimization for xor-of-icmps still needs to be added, but by being more efficient (not generating unnecessary logic ops with constants) we avoid the bug. See discussion in post-commit comments: https://reviews.llvm.org/D32143 llvm-svn: 303312 --- .../InstCombine/InstCombineCompares.cpp | 23 +++++++++++++++++++ llvm/test/Transforms/InstCombine/set.ll | 6 ++--- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index 6a6e831726b9..e2729516b409 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -4266,6 +4266,29 @@ static Instruction *canonicalizeICmpBool(ICmpInst &I, Value *A = I.getOperand(0), *B = I.getOperand(1); assert(A->getType()->getScalarType()->isIntegerTy(1) && "Bools only"); + // A boolean compared to true/false can be simplified to Op0/true/false in + // 14 out of the 20 (10 predicates * 2 constants) possible combinations. + // Cases not handled by InstSimplify are always 'not' of Op0. + if (match(B, m_Zero())) { + switch (I.getPredicate()) { + case CmpInst::ICMP_EQ: // A == 0 -> !A + case CmpInst::ICMP_ULE: // A <=u 0 -> !A + case CmpInst::ICMP_SGE: // A >=s 0 -> !A + return BinaryOperator::CreateNot(A); + default: + llvm_unreachable("ICmp i1 X, C not simplified as expected."); + } + } else if (match(B, m_One())) { + switch (I.getPredicate()) { + case CmpInst::ICMP_NE: // A != 1 -> !A + case CmpInst::ICMP_ULT: // A !A + case CmpInst::ICMP_SGT: // A >s -1 -> !A + return BinaryOperator::CreateNot(A); + default: + llvm_unreachable("ICmp i1 X, C not simplified as expected."); + } + } + switch (I.getPredicate()) { default: llvm_unreachable("Invalid icmp instruction!"); diff --git a/llvm/test/Transforms/InstCombine/set.ll b/llvm/test/Transforms/InstCombine/set.ll index f1bbc6cda0b6..5955eaea2c28 100644 --- a/llvm/test/Transforms/InstCombine/set.ll +++ b/llvm/test/Transforms/InstCombine/set.ll @@ -152,10 +152,8 @@ define <3 x i1> @test14vec(<3 x i1> %A, <3 x i1> %B) { define i1 @bool_eq0(i64 %a) { ; CHECK-LABEL: @bool_eq0( -; CHECK-NEXT: [[B:%.*]] = icmp sgt i64 %a, 0 -; CHECK-NEXT: [[C:%.*]] = icmp eq i64 %a, 1 -; CHECK-NEXT: [[AND:%.*]] = xor i1 [[C]], [[B]] -; CHECK-NEXT: ret i1 [[AND]] +; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i64 %a, 1 +; CHECK-NEXT: ret i1 [[TMP1]] ; %b = icmp sgt i64 %a, 0 %c = icmp eq i64 %a, 1