[PATCH] D19353: [GVN] Replace an inverted comparison with a logical not

Daniel Berlin via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 21 07:50:07 PDT 2016


This looks fine to me.


On Wed, Apr 20, 2016 at 9:29 PM, David Majnemer <david.majnemer at gmail.com>
wrote:

> majnemer created this revision.
> majnemer added reviewers: nlewycky, dberlin.
> majnemer added a subscriber: llvm-commits.
>
> If we have two comparisons:
>
>   %iszero = icmp eq i32 %A, 0
>   %isnotzero = icmp ne i32 %A, 0
>
> we should be able to turn one into the logical not of the other:
>
>   %iszero = icmp eq i32 %A, 0
>   %isnotzero = xor i1 %iszero, true
>
> This fixes PR27431.
>
> http://reviews.llvm.org/D19353
>
> Files:
>   lib/Transforms/Scalar/GVN.cpp
>   test/Transforms/GVN/pr27431.ll
>
> Index: test/Transforms/GVN/pr27431.ll
> ===================================================================
> --- /dev/null
> +++ test/Transforms/GVN/pr27431.ll
> @@ -0,0 +1,17 @@
> +; RUN: opt -S -gvn < %s | FileCheck %s
> +
> +declare void @use(i1)
> +
> +define void @test1(i32 %A) {
> +entry:
> +  %iszero = icmp eq i32 %A, 0
> +  %isnotzero = icmp ne i32 %A, 0
> +  call void @use(i1 %iszero)
> +  call void @use(i1 %isnotzero)
> +  ret void
> +; CHECK-LABEL: define void @test1(
> +; CHECK: %[[iszero:.*]] = icmp eq i32 %A, 0
> +; CHECK: %[[isnotzero:.*]] = xor i1 %[[iszero]], true
> +; CHECK: call void @use(i1 %[[iszero]])
> +; CHECK: call void @use(i1 %[[isnotzero]])
> +}
> Index: lib/Transforms/Scalar/GVN.cpp
> ===================================================================
> --- lib/Transforms/Scalar/GVN.cpp
> +++ lib/Transforms/Scalar/GVN.cpp
> @@ -1964,6 +1964,13 @@
>        continue;
>      }
>
> +    // If "!A" is known true then A is known false.
> +    // If "!A" is known false then A is known true.
> +    if (match(LHS, m_Not(m_Value(A)))) {
> +      Worklist.push_back(std::make_pair(A, ConstantExpr::getNot(CI)));
> +      continue;
> +    }
> +
>      // If we are propagating an equality like "(A == B)" == "true" then
> also
>      // propagate the equality A == B.  When propagating a comparison such
> as
>      // "(A >= B)" == "true", replace all instances of "A < B" with
> "false".
> @@ -2123,6 +2130,32 @@
>    uint32_t NextNum = VN.getNextUnusedValueNumber();
>    unsigned Num = VN.lookup_or_add(I);
>
> +  // Try to transform:
> +  //   %isnotzero = icmp ne i32 %A, 0
> +  //   %iszero = icmp eq i32 %A, 0
> +  // to:
> +  //   %isnotzero = icmp ne i32 %A, 0
> +  //   %iszero = xor i1 %isnotzero, true
> +  if (auto *Cmp = dyn_cast<CmpInst>(I)) {
> +    CmpInst::Predicate NotPred = Cmp->getInversePredicate();
> +    Value *LHS = Cmp->getOperand(0), *RHS = Cmp->getOperand(1);
> +    uint32_t InverseNum =
> +        VN.lookup_or_add_cmp(Cmp->getOpcode(), NotPred, LHS, RHS);
> +    if (InverseNum < NextNum) {
> +      if (Value *NotCmp = findLeader(Cmp->getParent(), InverseNum)) {
> +        auto *InvertedNotCmp =
> +            BinaryOperator::CreateNot(NotCmp, NotCmp->getName() + ".not",
> Cmp);
> +        InvertedNotCmp->setDebugLoc(Cmp->getDebugLoc());
> +        patchAndReplaceAllUsesWith(Cmp, InvertedNotCmp);
> +        markInstructionForDeletion(Cmp);
> +
> +        // Update the availability map to include the new instruction.
> +        addToLeaderTable(Num, InvertedNotCmp,
> InvertedNotCmp->getParent());
> +        return true;
> +      }
> +    }
> +  }
> +
>    // Allocations are always uniquely numbered, so we can save time and
> memory
>    // by fast failing them.
>    if (isa<AllocaInst>(I) || isa<TerminatorInst>(I) || isa<PHINode>(I)) {
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160421/17bfdc82/attachment.html>


More information about the llvm-commits mailing list