[llvm] r295581 - PredicateInfo: Clean up predicate info a little, using insertion

Daniel Berlin via llvm-commits llvm-commits at lists.llvm.org
Sat Feb 18 15:06:38 PST 2017


Author: dannyb
Date: Sat Feb 18 17:06:38 2017
New Revision: 295581

URL: http://llvm.org/viewvc/llvm-project?rev=295581&view=rev
Log:
PredicateInfo: Clean up predicate info a little, using insertion
helpers, and fixing support for the renaming the comparison.

Modified:
    llvm/trunk/include/llvm/Transforms/Utils/PredicateInfo.h
    llvm/trunk/lib/Transforms/Utils/PredicateInfo.cpp
    llvm/trunk/test/Transforms/Util/PredicateInfo/condprop.ll
    llvm/trunk/test/Transforms/Util/PredicateInfo/testandor.ll

Modified: llvm/trunk/include/llvm/Transforms/Utils/PredicateInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/PredicateInfo.h?rev=295581&r1=295580&r2=295581&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Transforms/Utils/PredicateInfo.h (original)
+++ llvm/trunk/include/llvm/Transforms/Utils/PredicateInfo.h Sat Feb 18 17:06:38 2017
@@ -103,15 +103,15 @@ public:
   // This can be use by passes, when destroying predicateinfo, to know
   // whether they can just drop the intrinsic, or have to merge metadata.
   Value *OriginalOp;
-  CmpInst *Comparison;
+  Value *Condition;
   PredicateBase(const PredicateBase &) = delete;
   PredicateBase &operator=(const PredicateBase &) = delete;
   PredicateBase() = delete;
   virtual ~PredicateBase() = default;
 
 protected:
-  PredicateBase(PredicateType PT, Value *Op, CmpInst *Comparison)
-      : Type(PT), OriginalOp(Op), Comparison(Comparison) {}
+  PredicateBase(PredicateType PT, Value *Op, Value *Condition)
+      : Type(PT), OriginalOp(Op), Condition(Condition) {}
 };
 
 // Provides predicate information for assumes.  Since assumes are always true,
@@ -120,8 +120,8 @@ protected:
 class PredicateAssume : public PredicateBase {
 public:
   IntrinsicInst *AssumeInst;
-  PredicateAssume(Value *Op, IntrinsicInst *AssumeInst, CmpInst *Comparison)
-      : PredicateBase(PT_Assume, Op, Comparison), AssumeInst(AssumeInst) {}
+  PredicateAssume(Value *Op, IntrinsicInst *AssumeInst, Value *Condition)
+      : PredicateBase(PT_Assume, Op, Condition), AssumeInst(AssumeInst) {}
   PredicateAssume() = delete;
   static inline bool classof(const PredicateBase *PB) {
     return PB->Type == PT_Assume;
@@ -131,15 +131,15 @@ public:
 // Provides predicate information for branches.
 class PredicateBranch : public PredicateBase {
 public:
-  // This is the block that is conditional upon the comparison.
+  // This is the block that is conditional upon the condition.
   BasicBlock *BranchBB;
   // This is one of the true/false successors of BranchBB.
   BasicBlock *SplitBB;
   // If true, SplitBB is the true successor, otherwise it's the false successor.
   bool TrueEdge;
   PredicateBranch(Value *Op, BasicBlock *BranchBB, BasicBlock *SplitBB,
-                  CmpInst *Comparison, bool TakenEdge)
-      : PredicateBase(PT_Branch, Op, Comparison), BranchBB(BranchBB),
+                  Value *Condition, bool TakenEdge)
+      : PredicateBase(PT_Branch, Op, Condition), BranchBB(BranchBB),
         SplitBB(SplitBB), TrueEdge(TakenEdge) {}
   PredicateBranch() = delete;
   static inline bool classof(const PredicateBase *PB) {
@@ -197,6 +197,8 @@ private:
   bool stackIsInScope(const ValueDFSStack &, const ValueDFS &) const;
   void popStackUntilDFSScope(ValueDFSStack &, const ValueDFS &);
   ValueInfo &getOrCreateValueInfo(Value *);
+  void addInfoFor(SmallPtrSetImpl<Value *> &OpsToRename, Value *Op,
+                  PredicateBase *PB);
   const ValueInfo &getValueInfo(Value *) const;
   Function &F;
   DominatorTree &DT;
@@ -217,7 +219,7 @@ private:
   DenseMap<const BasicBlock *, std::unique_ptr<OrderedBasicBlock>> OBBMap;
   // The set of edges along which we can only handle phi uses, due to critical
   // edges.
-  DenseSet<BasicBlockEdge> PhiUsesOnly;
+  DenseSet<std::pair<BasicBlock *, BasicBlock *>> EdgeUsesOnly;
 };
 
 // This pass does eager building and then printing of PredicateInfo. It is used

Modified: llvm/trunk/lib/Transforms/Utils/PredicateInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/PredicateInfo.cpp?rev=295581&r1=295580&r2=295581&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/PredicateInfo.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/PredicateInfo.cpp Sat Feb 18 17:06:38 2017
@@ -69,9 +69,9 @@ struct ValueDFS {
   // Only one of Def or Use will be set.
   Value *Def = nullptr;
   Use *U = nullptr;
-  // Neither PInfo nor PhiOnly participate in the ordering
+  // Neither PInfo nor EdgeOnly participate in the ordering
   PredicateBase *PInfo = nullptr;
-  bool PhiOnly = false;
+  bool EdgeOnly = false;
 };
 
 // This compares ValueDFS structures, creating OrderedBasicBlocks where
@@ -195,22 +195,26 @@ bool PredicateInfo::stackIsInScope(const
     return false;
   // If it's a phi only use, make sure it's for this phi node edge, and that the
   // use is in a phi node.  If it's anything else, and the top of the stack is
-  // phionly, we need to pop the stack.  We deliberately sort phi uses next to
+  // EdgeOnly, we need to pop the stack.  We deliberately sort phi uses next to
   // the defs they must go with so that we can know it's time to pop the stack
   // when we hit the end of the phi uses for a given def.
-  if (Stack.back().PhiOnly) {
+  if (Stack.back().EdgeOnly) {
     if (!VDUse.U)
       return false;
     auto *PHI = dyn_cast<PHINode>(VDUse.U->getUser());
     if (!PHI)
       return false;
-    // The only phionly defs should be branch info.
+    // The only EdgeOnly defs should be branch info.
     auto *PBranch = dyn_cast<PredicateBranch>(Stack.back().PInfo);
-    assert(PBranch && "Only branches should have PHIOnly defs");
-    // Check edge
+    assert(PBranch && "Only branches should have EdgeOnly defs");
+    // Check edge matches us.
     BasicBlock *EdgePred = PHI->getIncomingBlock(*VDUse.U);
     if (EdgePred != PBranch->BranchBB)
       return false;
+
+    // Use dominates, which knows how to handle edge dominance.
+    return DT.dominates(BasicBlockEdge(PBranch->BranchBB, PBranch->SplitBB),
+                        *VDUse.U);
   }
 
   return (VDUse.DFSIn >= Stack.back().DFSIn &&
@@ -267,49 +271,57 @@ void collectCmpOps(CmpInst *Comparison,
   // are only being used in the comparison, which means they will not be useful
   // for us to consider for predicateinfo.
   //
-  // FIXME: LLVM crashes trying to create an intrinsic declaration of some
-  // pointer to function types that return structs, so we avoid them.
-  if ((isa<Instruction>(Op0) || isa<Argument>(Op0)) && !Op0->hasOneUse() &&
-      !(Op0->getType()->isPointerTy() &&
-        Op0->getType()->getPointerElementType()->isFunctionTy()))
+  if ((isa<Instruction>(Op0) || isa<Argument>(Op0)) && !Op0->hasOneUse())
     CmpOperands.push_back(Op0);
-  if ((isa<Instruction>(Op1) || isa<Argument>(Op1)) && !Op1->hasOneUse() &&
-      !(Op1->getType()->isPointerTy() &&
-        Op1->getType()->getPointerElementType()->isFunctionTy()))
+  if ((isa<Instruction>(Op1) || isa<Argument>(Op1)) && !Op1->hasOneUse())
     CmpOperands.push_back(Op1);
 }
 
+// Add Op, PB to the list of value infos for Op, and mark Op to be renamed.
+void PredicateInfo::addInfoFor(SmallPtrSetImpl<Value *> &OpsToRename, Value *Op,
+                               PredicateBase *PB) {
+  OpsToRename.insert(Op);
+  auto &OperandInfo = getOrCreateValueInfo(Op);
+  AllInfos.push_back(PB);
+  OperandInfo.Infos.push_back(PB);
+}
+
 // Process an assume instruction and place relevant operations we want to rename
 // into OpsToRename.
 void PredicateInfo::processAssume(IntrinsicInst *II, BasicBlock *AssumeBB,
                                   SmallPtrSetImpl<Value *> &OpsToRename) {
+  // See if we have a comparison we support
   SmallVector<Value *, 8> CmpOperands;
-  // Second, see if we have a comparison we support
-  SmallVector<Value *, 2> ComparisonsToProcess;
+  SmallVector<Value *, 2> ConditionsToProcess;
   CmpInst::Predicate Pred;
   Value *Operand = II->getOperand(0);
   if (m_c_And(m_Cmp(Pred, m_Value(), m_Value()),
               m_Cmp(Pred, m_Value(), m_Value()))
           .match(II->getOperand(0))) {
-    ComparisonsToProcess.push_back(
-        cast<BinaryOperator>(Operand)->getOperand(0));
-    ComparisonsToProcess.push_back(
-        cast<BinaryOperator>(Operand)->getOperand(1));
-  } else {
-    ComparisonsToProcess.push_back(Operand);
+    ConditionsToProcess.push_back(cast<BinaryOperator>(Operand)->getOperand(0));
+    ConditionsToProcess.push_back(cast<BinaryOperator>(Operand)->getOperand(1));
+    ConditionsToProcess.push_back(Operand);
+  } else if (isa<CmpInst>(Operand)) {
+
+    ConditionsToProcess.push_back(Operand);
   }
-  for (auto Comparison : ComparisonsToProcess) {
-    if (auto *Cmp = dyn_cast<CmpInst>(Comparison)) {
+  for (auto Cond : ConditionsToProcess) {
+    if (auto *Cmp = dyn_cast<CmpInst>(Cond)) {
       collectCmpOps(Cmp, CmpOperands);
       // Now add our copy infos for our operands
       for (auto *Op : CmpOperands) {
-        OpsToRename.insert(Op);
-        auto &OperandInfo = getOrCreateValueInfo(Op);
-        PredicateBase *PB = new PredicateAssume(Op, II, Cmp);
-        AllInfos.push_back(PB);
-        OperandInfo.Infos.push_back(PB);
+        auto *PA = new PredicateAssume(Op, II, Cmp);
+        addInfoFor(OpsToRename, Op, PA);
       }
       CmpOperands.clear();
+    } else if (auto *BinOp = dyn_cast<BinaryOperator>(Cond)) {
+      // Otherwise, it should be an AND.
+      assert(BinOp->getOpcode() == Instruction::And &&
+             "Should have been an and");
+      auto *PA = new PredicateAssume(Cond, II, Cond);
+      addInfoFor(OpsToRename, Cond, PA);
+    } else {
+      llvm_unreachable("Unknown type of condition");
     }
   }
 }
@@ -318,19 +330,37 @@ void PredicateInfo::processAssume(Intrin
 // renamed into OpsToRename.
 void PredicateInfo::processBranch(BranchInst *BI, BasicBlock *BranchBB,
                                   SmallPtrSetImpl<Value *> &OpsToRename) {
-  SmallVector<Value *, 8> CmpOperands;
   BasicBlock *FirstBB = BI->getSuccessor(0);
   BasicBlock *SecondBB = BI->getSuccessor(1);
   SmallVector<BasicBlock *, 2> SuccsToProcess;
-  bool isAnd = false;
-  bool isOr = false;
   SuccsToProcess.push_back(FirstBB);
   SuccsToProcess.push_back(SecondBB);
-  // Second, see if we have a comparison we support
-  SmallVector<Value *, 2> ComparisonsToProcess;
-  CmpInst::Predicate Pred;
+  SmallVector<Value *, 2> ConditionsToProcess;
+
+  auto InsertHelper = [&](Value *Op, bool isAnd, bool isOr, Value *Cond) {
+    for (auto *Succ : SuccsToProcess) {
+      // Don't try to insert on a self-edge. This is mainly because we will
+      // eliminate during renaming anyway.
+      if (Succ == BranchBB)
+        continue;
+      bool TakenEdge = (Succ == FirstBB);
+      // For and, only insert on the true edge
+      // For or, only insert on the false edge
+      if ((isAnd && !TakenEdge) || (isOr && TakenEdge))
+        continue;
+      PredicateBase *PB =
+          new PredicateBranch(Op, BranchBB, Succ, Cond, TakenEdge);
+      addInfoFor(OpsToRename, Op, PB);
+      if (!Succ->getSinglePredecessor())
+        EdgeUsesOnly.insert({BranchBB, Succ});
+    }
+  };
 
   // Match combinations of conditions.
+  CmpInst::Predicate Pred;
+  bool isAnd = false;
+  bool isOr = false;
+  SmallVector<Value *, 8> CmpOperands;
   if (match(BI->getCondition(), m_And(m_Cmp(Pred, m_Value(), m_Value()),
                                       m_Cmp(Pred, m_Value(), m_Value()))) ||
       match(BI->getCondition(), m_Or(m_Cmp(Pred, m_Value(), m_Value()),
@@ -340,34 +370,30 @@ void PredicateInfo::processBranch(Branch
       isAnd = true;
     else if (BinOp->getOpcode() == Instruction::Or)
       isOr = true;
-    ComparisonsToProcess.push_back(BinOp->getOperand(0));
-    ComparisonsToProcess.push_back(BinOp->getOperand(1));
-  } else {
-    ComparisonsToProcess.push_back(BI->getCondition());
+    ConditionsToProcess.push_back(BinOp->getOperand(0));
+    ConditionsToProcess.push_back(BinOp->getOperand(1));
+    ConditionsToProcess.push_back(BI->getCondition());
+  } else if (isa<CmpInst>(BI->getCondition())) {
+    ConditionsToProcess.push_back(BI->getCondition());
   }
-  for (auto Comparison : ComparisonsToProcess) {
-    if (auto *Cmp = dyn_cast<CmpInst>(Comparison)) {
+  for (auto Cond : ConditionsToProcess) {
+    if (auto *Cmp = dyn_cast<CmpInst>(Cond)) {
       collectCmpOps(Cmp, CmpOperands);
       // Now add our copy infos for our operands
-      for (auto *Op : CmpOperands) {
-        OpsToRename.insert(Op);
-        auto &OperandInfo = getOrCreateValueInfo(Op);
-        for (auto *Succ : SuccsToProcess) {
-          bool TakenEdge = (Succ == FirstBB);
-          // For and, only insert on the true edge
-          // For or, only insert on the false edge
-          if ((isAnd && !TakenEdge) || (isOr && TakenEdge))
-            continue;
-          PredicateBase *PB =
-              new PredicateBranch(Op, BranchBB, Succ, Cmp, TakenEdge);
-          AllInfos.push_back(PB);
-          OperandInfo.Infos.push_back(PB);
-          if (!Succ->getSinglePredecessor())
-            PhiUsesOnly.insert({BranchBB, Succ});
-        }
-      }
-      CmpOperands.clear();
+      for (auto *Op : CmpOperands)
+        InsertHelper(Op, isAnd, isOr, Cmp);
+    } else if (auto *BinOp = dyn_cast<BinaryOperator>(Cond)) {
+      // This must be an AND or an OR.
+      assert((BinOp->getOpcode() == Instruction::And ||
+              BinOp->getOpcode() == Instruction::Or) &&
+             "Should have been an AND or an OR");
+      // The actual value of the binop is not subject to the same restrictions
+      // as the comparison. It's either true or false on the true/false branch.
+      InsertHelper(Cond, false, false, Cond);
+    } else {
+      llvm_unreachable("Unknown type of condition");
     }
+    CmpOperands.clear();
   }
 }
 
@@ -421,7 +447,8 @@ Value *PredicateInfo::materializeStack(u
       IRBuilder<> B(PBranch->BranchBB->getTerminator());
       Function *IF = Intrinsic::getDeclaration(
           F.getParent(), Intrinsic::ssa_copy, Op->getType());
-      Value *PIC = B.CreateCall(IF, Op, Op->getName() + "." + Twine(Counter++));
+      CallInst *PIC =
+          B.CreateCall(IF, Op, Op->getName() + "." + Twine(Counter++));
       PredicateMap.insert({PIC, ValInfo});
       Result.Def = PIC;
     } else {
@@ -431,7 +458,7 @@ Value *PredicateInfo::materializeStack(u
       IRBuilder<> B(PAssume->AssumeInst);
       Function *IF = Intrinsic::getDeclaration(
           F.getParent(), Intrinsic::ssa_copy, Op->getType());
-      Value *PIC = B.CreateCall(IF, Op);
+      CallInst *PIC = B.CreateCall(IF, Op);
       PredicateMap.insert({PIC, ValInfo});
       Result.Def = PIC;
     }
@@ -489,14 +516,14 @@ void PredicateInfo::renameUses(SmallPtrS
         // If we can only do phi uses, we treat it like it's in the branch
         // block, and handle it specially. We know that it goes last, and only
         // dominate phi uses.
-        if (PhiUsesOnly.count({PBranch->BranchBB, PBranch->SplitBB})) {
+        if (EdgeUsesOnly.count({PBranch->BranchBB, PBranch->SplitBB})) {
           VD.LocalNum = LN_Last;
           auto *DomNode = DT.getNode(PBranch->BranchBB);
           if (DomNode) {
             VD.DFSIn = DomNode->getDFSNumIn();
             VD.DFSOut = DomNode->getDFSNumOut();
             VD.PInfo = PossibleCopy;
-            VD.PhiOnly = true;
+            VD.EdgeOnly = true;
             OrderedUses.push_back(VD);
           }
         } else {
@@ -540,7 +567,6 @@ void PredicateInfo::renameUses(SmallPtrS
       if (OutOfScope || ShouldPush) {
         // Sync to our current scope.
         popStackUntilDFSScope(RenameStack, VD);
-        ShouldPush |= (VD.Def || PossibleCopy);
         if (ShouldPush) {
           RenameStack.push_back(VD);
         }
@@ -655,10 +681,10 @@ public:
       OS << "; Has predicate info\n";
       if (const auto *PB = dyn_cast<PredicateBranch>(PI))
         OS << "; branch predicate info { TrueEdge: " << PB->TrueEdge
-           << " Comparison:" << *PB->Comparison << " }\n";
+           << " Comparison:" << *PB->Condition << " }\n";
       else if (const auto *PA = dyn_cast<PredicateAssume>(PI))
         OS << "; assume predicate info {"
-           << " Comparison:" << *PA->Comparison << " }\n";
+           << " Comparison:" << *PA->Condition << " }\n";
     }
   }
 };

Modified: llvm/trunk/test/Transforms/Util/PredicateInfo/condprop.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Util/PredicateInfo/condprop.ll?rev=295581&r1=295580&r2=295581&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/Util/PredicateInfo/condprop.ll (original)
+++ llvm/trunk/test/Transforms/Util/PredicateInfo/condprop.ll Sat Feb 18 17:06:38 2017
@@ -102,6 +102,7 @@ define void @test3(i32 %x, i32 %y) {
 ; CHECK:         [[X_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X]])
 ; CHECK:         [[YZ_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[YZ]])
 ; CHECK:         [[Y_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[Y]])
+; CHECK:         [[Z_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[Z]])
 ; CHECK-NEXT:    br i1 [[Z]], label [[BOTH_ZERO:%.*]], label [[NOPE:%.*]]
 ; CHECK:       both_zero:
 ; CHECK-NEXT:    call void @foo(i1 [[XZ_0]])
@@ -110,7 +111,7 @@ define void @test3(i32 %x, i32 %y) {
 ; CHECK-NEXT:    call void @bar(i32 [[Y_0]])
 ; CHECK-NEXT:    ret void
 ; CHECK:       nope:
-; CHECK-NEXT:    call void @foo(i1 [[Z]])
+; CHECK-NEXT:    call void @foo(i1 [[Z_0]])
 ; CHECK-NEXT:    ret void
 ;
   %xz = icmp eq i32 %x, 0

Modified: llvm/trunk/test/Transforms/Util/PredicateInfo/testandor.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Util/PredicateInfo/testandor.ll?rev=295581&r1=295580&r2=295581&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/Util/PredicateInfo/testandor.ll (original)
+++ llvm/trunk/test/Transforms/Util/PredicateInfo/testandor.ll Sat Feb 18 17:06:38 2017
@@ -14,6 +14,7 @@ define void @testor(i32 %x, i32 %y) {
 ; CHECK:         [[X_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X]])
 ; CHECK:         [[YZ_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[YZ]])
 ; CHECK:         [[Y_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[Y]])
+; CHECK:         [[Z_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[Z]])
 ; CHECK-NEXT:    br i1 [[Z]], label [[ONEOF:%.*]], label [[NEITHER:%.*]]
 ; CHECK:       oneof:
 ; CHECK-NEXT:    call void @foo(i1 [[XZ]])
@@ -26,7 +27,7 @@ define void @testor(i32 %x, i32 %y) {
 ; CHECK-NEXT:    call void @foo(i1 [[YZ_0]])
 ; CHECK-NEXT:    call void @bar(i32 [[X_0]])
 ; CHECK-NEXT:    call void @bar(i32 [[Y_0]])
-; CHECK-NEXT:    call void @foo(i1 [[Z]])
+; CHECK-NEXT:    call void @foo(i1 [[Z_0]])
 ; CHECK-NEXT:    ret void
 ;
   %xz = icmp eq i32 %x, 0
@@ -57,6 +58,7 @@ define void @testand(i32 %x, i32 %y) {
 ; CHECK:         [[X_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X]])
 ; CHECK:         [[YZ_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[YZ]])
 ; CHECK:         [[Y_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[Y]])
+; CHECK:         [[Z_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[Z]])
 ; CHECK-NEXT:    br i1 [[Z]], label [[BOTH:%.*]], label [[NOPE:%.*]]
 ; CHECK:       both:
 ; CHECK-NEXT:    call void @foo(i1 [[XZ_0]])
@@ -69,7 +71,7 @@ define void @testand(i32 %x, i32 %y) {
 ; CHECK-NEXT:    call void @foo(i1 [[YZ]])
 ; CHECK-NEXT:    call void @bar(i32 [[X]])
 ; CHECK-NEXT:    call void @bar(i32 [[Y]])
-; CHECK-NEXT:    call void @foo(i1 [[Z]])
+; CHECK-NEXT:    call void @foo(i1 [[Z_0]])
 ; CHECK-NEXT:    ret void
 ;
   %xz = icmp eq i32 %x, 0
@@ -100,6 +102,7 @@ define void @testandsame(i32 %x, i32 %y)
 ; CHECK:         [[X_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X]])
 ; CHECK:         [[X_0_1:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X_0]])
 ; CHECK:         [[XLT_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[XLT]])
+; CHECK:         [[Z_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[Z]])
 ; CHECK-NEXT:    br i1 [[Z]], label [[BOTH:%.*]], label [[NOPE:%.*]]
 ; CHECK:       both:
 ; CHECK-NEXT:    call void @foo(i1 [[XGT_0]])
@@ -109,7 +112,7 @@ define void @testandsame(i32 %x, i32 %y)
 ; CHECK:       nope:
 ; CHECK-NEXT:    call void @foo(i1 [[XGT]])
 ; CHECK-NEXT:    call void @foo(i1 [[XLT]])
-; CHECK-NEXT:    call void @foo(i1 [[Z]])
+; CHECK-NEXT:    call void @foo(i1 [[Z_0]])
 ; CHECK-NEXT:    ret void
 ;
   %xgt = icmp sgt i32 %x, 0
@@ -137,12 +140,14 @@ define void @testandassume(i32 %x, i32 %
 ; CHECK:         [[TMP2:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X]])
 ; CHECK:         [[TMP3:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[YZ]])
 ; CHECK:         [[TMP4:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[Y]])
-; CHECK-NEXT:    call void @llvm.assume(i1 [[Z]])
+; CHECK:         [[TMP5:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[Z]])
+; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP5]])
 ; CHECK:         [[DOT0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[TMP1]])
 ; CHECK:         [[DOT01:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[TMP2]])
 ; CHECK:         [[DOT02:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[TMP3]])
 ; CHECK:         [[DOT03:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[TMP4]])
-; CHECK-NEXT:    br i1 [[Z]], label [[BOTH:%.*]], label [[NOPE:%.*]]
+; CHECK:         [[DOT04:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[TMP5]])
+; CHECK-NEXT:    br i1 [[TMP5]], label [[BOTH:%.*]], label [[NOPE:%.*]]
 ; CHECK:       both:
 ; CHECK-NEXT:    call void @foo(i1 [[DOT0]])
 ; CHECK-NEXT:    call void @foo(i1 [[DOT02]])
@@ -150,7 +155,7 @@ define void @testandassume(i32 %x, i32 %
 ; CHECK-NEXT:    call void @bar(i32 [[DOT03]])
 ; CHECK-NEXT:    ret void
 ; CHECK:       nope:
-; CHECK-NEXT:    call void @foo(i1 [[Z]])
+; CHECK-NEXT:    call void @foo(i1 [[DOT04]])
 ; CHECK-NEXT:    ret void
 ;
   %xz = icmp eq i32 %x, 0
@@ -177,6 +182,7 @@ define void @testorassume(i32 %x, i32 %y
 ; CHECK-NEXT:    [[YZ:%.*]] = icmp eq i32 [[Y:%.*]], 0
 ; CHECK-NEXT:    [[Z:%.*]] = or i1 [[XZ]], [[YZ]]
 ; CHECK-NEXT:    call void @llvm.assume(i1 [[Z]])
+; CHECK:         [[Z_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[Z]])
 ; CHECK-NEXT:    br i1 [[Z]], label [[BOTH:%.*]], label [[NOPE:%.*]]
 ; CHECK:       both:
 ; CHECK-NEXT:    call void @foo(i1 [[XZ]])
@@ -185,7 +191,7 @@ define void @testorassume(i32 %x, i32 %y
 ; CHECK-NEXT:    call void @bar(i32 [[Y]])
 ; CHECK-NEXT:    ret void
 ; CHECK:       nope:
-; CHECK-NEXT:    call void @foo(i1 [[Z]])
+; CHECK-NEXT:    call void @foo(i1 [[Z_0]])
 ; CHECK-NEXT:    ret void
 ;
   %xz = icmp eq i32 %x, 0




More information about the llvm-commits mailing list