[llvm] 3fd64cc - [ValueTracking] Handle two PHIs in isKnownNonEqual()

Philip Reames via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 25 17:10:34 PDT 2021


Just wanted to comment that this evolved into a set of patches which 
look really generic and useful.  Thank you for doing the following 
through here, and thanks to Nikita for driving the review along.

Philip

On 3/25/21 3:57 PM, Jingu Kang via llvm-commits wrote:
> Author: Jingu Kang
> Date: 2021-03-25T22:56:05Z
> New Revision: 3fd64cc7a361ae02f4c0f84f5f6a85a6f05c100c
>
> URL: https://github.com/llvm/llvm-project/commit/3fd64cc7a361ae02f4c0f84f5f6a85a6f05c100c
> DIFF: https://github.com/llvm/llvm-project/commit/3fd64cc7a361ae02f4c0f84f5f6a85a6f05c100c.diff
>
> LOG: [ValueTracking] Handle two PHIs in isKnownNonEqual()
>
> loop:
>    %cmp.0 = phi i32 [ 3, %entry ], [ %inc, %loop ]
>    %pos.0 = phi i32 [ 1, %entry ], [ %cmp.0, %loop ]
>    ...
>    %inc = add i32 %cmp.0, 1
>    br label %loop
>
> On above example, %pos.0 uses previous iteration's %cmp.0 with backedge
> according to PHI's instruction's defintion. If the %inc is not same among
> iterations, we can say the two PHIs are not same.
>
> Differential Revision: https://reviews.llvm.org/D98422
>
> Added:
>      
>
> Modified:
>      llvm/lib/Analysis/ValueTracking.cpp
>      llvm/test/Analysis/ValueTracking/known-non-equal.ll
>
> Removed:
>      
>
>
> ################################################################################
> diff  --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
> index 7b43ce0f95e1..4b9afdad8ff7 100644
> --- a/llvm/lib/Analysis/ValueTracking.cpp
> +++ b/llvm/lib/Analysis/ValueTracking.cpp
> @@ -2548,6 +2548,36 @@ static bool isNonEqualMul(const Value *V1, const Value *V2, unsigned Depth,
>     return false;
>   }
>   
> +static bool isNonEqualPHIs(const PHINode *PN1, const PHINode *PN2,
> +                           unsigned Depth, const Query &Q) {
> +  // Check two PHIs are in same block.
> +  if (PN1->getParent() != PN2->getParent())
> +    return false;
> +
> +  SmallPtrSet<const BasicBlock *, 8> VisitedBBs;
> +  bool UsedFullRecursion = false;
> +  for (const BasicBlock *IncomBB : PN1->blocks()) {
> +    if (!VisitedBBs.insert(IncomBB).second)
> +      continue; // Don't reprocess blocks that we have dealt with already.
> +    const Value *IV1 = PN1->getIncomingValueForBlock(IncomBB);
> +    const Value *IV2 = PN2->getIncomingValueForBlock(IncomBB);
> +    const APInt *C1, *C2;
> +    if (match(IV1, m_APInt(C1)) && match(IV2, m_APInt(C2)) && *C1 != *C2)
> +      continue;
> +
> +    // Only one pair of phi operands is allowed for full recursion.
> +    if (UsedFullRecursion)
> +      return false;
> +
> +    Query RecQ = Q;
> +    RecQ.CxtI = IncomBB->getTerminator();
> +    if (!isKnownNonEqual(IV1, IV2, Depth + 1, RecQ))
> +      return false;
> +    UsedFullRecursion = true;
> +  }
> +  return true;
> +}
> +
>   /// Return true if it is known that V1 != V2.
>   static bool isKnownNonEqual(const Value *V1, const Value *V2, unsigned Depth,
>                               const Query &Q) {
> @@ -2599,12 +2629,20 @@ static bool isKnownNonEqual(const Value *V1, const Value *V2, unsigned Depth,
>       case Instruction::SExt:
>       case Instruction::ZExt:
>         if (O1->getOperand(0)->getType() == O2->getOperand(0)->getType())
> -        return isKnownNonEqual(O1->getOperand(0), O2->getOperand(0),
> -                               Depth + 1, Q);
> +        return isKnownNonEqual(O1->getOperand(0), O2->getOperand(0), Depth + 1,
> +                               Q);
> +      break;
> +    case Instruction::PHI:
> +      const PHINode *PN1 = cast<PHINode>(V1);
> +      const PHINode *PN2 = cast<PHINode>(V2);
> +      // FIXME: This is missing a generalization to handle the case where one is
> +      // a PHI and another one isn't.
> +      if (isNonEqualPHIs(PN1, PN2, Depth, Q))
> +        return true;
>         break;
>       };
>     }
> -
> +
>     if (isAddOfNonZero(V1, V2, Depth, Q) || isAddOfNonZero(V2, V1, Depth, Q))
>       return true;
>   
>
> diff  --git a/llvm/test/Analysis/ValueTracking/known-non-equal.ll b/llvm/test/Analysis/ValueTracking/known-non-equal.ll
> index 362db26bed84..ec2db64ab4ba 100644
> --- a/llvm/test/Analysis/ValueTracking/known-non-equal.ll
> +++ b/llvm/test/Analysis/ValueTracking/known-non-equal.ll
> @@ -291,4 +291,56 @@ define i1 @mul_other_may_be_zero_or_one(i16 %x, i16 %y) {
>     ret i1 %cmp
>   }
>   
> +define i1 @known_non_equal_phis(i8 %p, i8* %pq, i8 %n, i8 %r) {
> +; CHECK-LABEL: @known_non_equal_phis(
> +; CHECK-NEXT:  entry:
> +; CHECK-NEXT:    br label [[LOOP:%.*]]
> +; CHECK:       loop:
> +; CHECK-NEXT:    [[A:%.*]] = phi i8 [ 2, [[ENTRY:%.*]] ], [ [[NEXT:%.*]], [[LOOP]] ]
> +; CHECK-NEXT:    [[NEXT]] = mul nsw i8 [[A]], 2
> +; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[A]], [[N:%.*]]
> +; CHECK-NEXT:    br i1 [[CMP1]], label [[EXIT:%.*]], label [[LOOP]]
> +; CHECK:       exit:
> +; CHECK-NEXT:    ret i1 true
> +;
> +entry:
> +  br label %loop
> +loop:
> +  %A = phi i8 [ 2, %entry ], [ %next, %loop ]
> +  %B = phi i8 [ 3, %entry ], [ %A, %loop ]
> +  %next = mul nsw i8 %A, 2
> +  %cmp1 = icmp eq i8 %A, %n
> +  br i1 %cmp1, label %exit, label %loop
> +exit:
> +  %cmp = icmp ne i8 %A, %B
> +  ret i1 %cmp
> +}
> +
> +define i1 @known_non_equal_phis_fail(i8 %p, i8* %pq, i8 %n, i8 %r) {
> +; CHECK-LABEL: @known_non_equal_phis_fail(
> +; CHECK-NEXT:  entry:
> +; CHECK-NEXT:    br label [[LOOP:%.*]]
> +; CHECK:       loop:
> +; CHECK-NEXT:    [[A:%.*]] = phi i8 [ 2, [[ENTRY:%.*]] ], [ [[NEXT:%.*]], [[LOOP]] ]
> +; CHECK-NEXT:    [[B:%.*]] = phi i8 [ 2, [[ENTRY]] ], [ [[A]], [[LOOP]] ]
> +; CHECK-NEXT:    [[NEXT]] = mul nsw i8 [[A]], 2
> +; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[A]], [[N:%.*]]
> +; CHECK-NEXT:    br i1 [[CMP1]], label [[EXIT:%.*]], label [[LOOP]]
> +; CHECK:       exit:
> +; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 [[A]], [[B]]
> +; CHECK-NEXT:    ret i1 [[CMP]]
> +;
> +entry:
> +  br label %loop
> +loop:
> +  %A = phi i8 [ 2, %entry ], [ %next, %loop ]
> +  %B = phi i8 [ 2, %entry ], [ %A, %loop ]
> +  %next = mul nsw i8 %A, 2
> +  %cmp1 = icmp eq i8 %A, %n
> +  br i1 %cmp1, label %exit, label %loop
> +exit:
> +  %cmp = icmp ne i8 %A, %B
> +  ret i1 %cmp
> +}
> +
>   !0 = !{ i8 1, i8 5 }
>
>
>          
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits


More information about the llvm-commits mailing list