Author: Roman Lebedev Date: 2021-01-22T17:22:49+03:00 New Revision: 0895b836d74ed333468ddece2102140494eb33b6
URL: https://github.com/llvm/llvm-project/commit/0895b836d74ed333468ddece2102140494eb33b6 DIFF: https://github.com/llvm/llvm-project/commit/0895b836d74ed333468ddece2102140494eb33b6.diff LOG: [SimplifyCFG] FoldBranchToCommonDest(): don't deal with unconditional branches The case where BB ends with an unconditional branch, and has a single predecessor w/ conditional branch to BB and a single successor of BB is exactly the pattern SpeculativelyExecuteBB() transform deals with. (and in this case they both allow speculating only a single instruction) Well, or FoldTwoEntryPHINode(), if the final block has only those two predecessors. Here, in FoldBranchToCommonDest(), only a weird subset of that transform is supported, and it's glued on the side in a weird way. In particular, it took me a bit to understand that the Cond isn't actually a branch condition in that case, but just the value we allow to speculate (otherwise it reads as a miscompile to me). Additionally, this only supports for the speculated instruction to be an ICmp. So let's just unclutter FoldBranchToCommonDest(), and leave this transform up to SpeculativelyExecuteBB(). As far as i can tell, this shouldn't really impact optimization potential, but if it does, improving SpeculativelyExecuteBB() will be more beneficial anyways. Notably, this only affects a single test, but EarlyCSE should have run beforehand in the pipeline, and then FoldTwoEntryPHINode() would have caught it. This reverts commit rL158392 / commit d33f4efbfdef6ffccf212ab3e40a7673589085fd. Added: Modified: llvm/lib/Transforms/Utils/SimplifyCFG.cpp llvm/test/Transforms/SimplifyCFG/branch-fold.ll Removed: llvm/test/Transforms/SimplifyCFG/X86/fold-branch-debuginvariant.ll ################################################################################ diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index a243a2e37950..d0028c013fa3 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -314,46 +314,6 @@ SafeToMergeTerminators(Instruction *SI1, Instruction *SI2, return !Fail; } -/// Return true if it is safe and profitable to merge these two terminator -/// instructions together, where SI1 is an unconditional branch. PhiNodes will -/// store all PHI nodes in common successors. -static bool -isProfitableToFoldUnconditional(BranchInst *SI1, BranchInst *SI2, - Instruction *Cond, - SmallVectorImpl<PHINode *> &PhiNodes) { - if (SI1 == SI2) - return false; // Can't merge with self! - assert(SI1->isUnconditional() && SI2->isConditional()); - - // We fold the unconditional branch if we can easily update all PHI nodes in - // common successors: - // 1> We have a constant incoming value for the conditional branch; - // 2> We have "Cond" as the incoming value for the unconditional branch; - // 3> SI2->getCondition() and Cond have same operands. - CmpInst *Ci2 = dyn_cast<CmpInst>(SI2->getCondition()); - if (!Ci2) - return false; - if (!(Cond->getOperand(0) == Ci2->getOperand(0) && - Cond->getOperand(1) == Ci2->getOperand(1)) && - !(Cond->getOperand(0) == Ci2->getOperand(1) && - Cond->getOperand(1) == Ci2->getOperand(0))) - return false; - - BasicBlock *SI1BB = SI1->getParent(); - BasicBlock *SI2BB = SI2->getParent(); - SmallPtrSet<BasicBlock *, 16> SI1Succs(succ_begin(SI1BB), succ_end(SI1BB)); - for (BasicBlock *Succ : successors(SI2BB)) - if (SI1Succs.count(Succ)) - for (BasicBlock::iterator BBI = Succ->begin(); isa<PHINode>(BBI); ++BBI) { - PHINode *PN = cast<PHINode>(BBI); - if (PN->getIncomingValueForBlock(SI1BB) != Cond || - !isa<ConstantInt>(PN->getIncomingValueForBlock(SI2BB))) - return false; - PhiNodes.push_back(PN); - } - return true; -} - /// Update PHI nodes in Succ to indicate that there will now be entries in it /// from the 'NewPred' block. The values that will be flowing into the PHI nodes /// will be the same as those coming in from ExistPred, an existing predecessor @@ -2783,23 +2743,6 @@ bool SimplifyCFGOpt::SimplifyCondBranchToTwoReturns(BranchInst *BI, return true; } -/// Return true if the given instruction is available -/// in its predecessor block. If yes, the instruction will be removed. -static bool tryCSEWithPredecessor(Instruction *Inst, BasicBlock *PB) { - if (!isa<BinaryOperator>(Inst) && !isa<CmpInst>(Inst)) - return false; - for (Instruction &I : *PB) { - Instruction *PBI = &I; - // Check whether Inst and PBI generate the same value. - if (Inst->isIdenticalTo(PBI)) { - Inst->replaceAllUsesWith(PBI); - Inst->eraseFromParent(); - return true; - } - } - return false; -} - /// Return true if either PBI or BI has branch weight available, and store /// the weights in {Pred|Succ}{True|False}Weight. If one of PBI and BI does /// not have branch weight, use 1:1 as its weight. @@ -2830,6 +2773,11 @@ bool llvm::FoldBranchToCommonDest(BranchInst *BI, DomTreeUpdater *DTU, MemorySSAUpdater *MSSAU, const TargetTransformInfo *TTI, unsigned BonusInstThreshold) { + // If this block ends with an unconditional branch, + // let SpeculativelyExecuteBB() deal with it. + if (!BI->isConditional()) + return false; + BasicBlock *BB = BI->getParent(); const unsigned PredCount = pred_size(BB); @@ -2845,37 +2793,7 @@ bool llvm::FoldBranchToCommonDest(BranchInst *BI, DomTreeUpdater *DTU, BB->getParent()->hasMinSize() ? TargetTransformInfo::TCK_CodeSize : TargetTransformInfo::TCK_SizeAndLatency; - Instruction *Cond = nullptr; - if (BI->isConditional()) - Cond = dyn_cast<Instruction>(BI->getCondition()); - else { - // For unconditional branch, check for a simple CFG pattern, where - // BB has a single predecessor and BB's successor is also its predecessor's - // successor. If such pattern exists, check for CSE between BB and its - // predecessor. - if (BasicBlock *PB = BB->getSinglePredecessor()) - if (BranchInst *PBI = dyn_cast<BranchInst>(PB->getTerminator())) - if (PBI->isConditional() && - (BI->getSuccessor(0) == PBI->getSuccessor(0) || - BI->getSuccessor(0) == PBI->getSuccessor(1))) { - for (auto I = BB->instructionsWithoutDebug().begin(), - E = BB->instructionsWithoutDebug().end(); - I != E;) { - Instruction *Curr = &*I++; - if (isa<CmpInst>(Curr)) { - Cond = Curr; - break; - } - // Quit if we can't remove this instruction. - if (!tryCSEWithPredecessor(Curr, PB)) - return Changed; - Changed = true; - } - } - - if (!Cond) - return Changed; - } + Instruction *Cond = dyn_cast<Instruction>(BI->getCondition()); if (!Cond || (!isa<CmpInst>(Cond) && !isa<BinaryOperator>(Cond)) || Cond->getParent() != BB || !Cond->hasOneUse()) @@ -2934,7 +2852,7 @@ bool llvm::FoldBranchToCommonDest(BranchInst *BI, DomTreeUpdater *DTU, // Finally, don't infinitely unroll conditional loops. BasicBlock *TrueDest = BI->getSuccessor(0); - BasicBlock *FalseDest = (BI->isConditional()) ? BI->getSuccessor(1) : nullptr; + BasicBlock *FalseDest = BI->getSuccessor(1); if (TrueDest == BB || FalseDest == BB) return Changed; @@ -2945,39 +2863,30 @@ bool llvm::FoldBranchToCommonDest(BranchInst *BI, DomTreeUpdater *DTU, // Check that we have two conditional branches. If there is a PHI node in // the common successor, verify that the same value flows in from both // blocks. - SmallVector<PHINode *, 4> PHIs; - if (!PBI || PBI->isUnconditional() || - (BI->isConditional() && !SafeToMergeTerminators(BI, PBI)) || - (!BI->isConditional() && - !isProfitableToFoldUnconditional(BI, PBI, Cond, PHIs))) + if (!PBI || PBI->isUnconditional() || !SafeToMergeTerminators(BI, PBI)) continue; // Determine if the two branches share a common destination. Instruction::BinaryOps Opc = Instruction::BinaryOpsEnd; bool InvertPredCond = false; - if (BI->isConditional()) { - if (PBI->getSuccessor(0) == TrueDest) { - Opc = Instruction::Or; - } else if (PBI->getSuccessor(1) == FalseDest) { - Opc = Instruction::And; - } else if (PBI->getSuccessor(0) == FalseDest) { - Opc = Instruction::And; - InvertPredCond = true; - } else if (PBI->getSuccessor(1) == TrueDest) { - Opc = Instruction::Or; - InvertPredCond = true; - } else { - continue; - } + if (PBI->getSuccessor(0) == TrueDest) { + Opc = Instruction::Or; + } else if (PBI->getSuccessor(1) == FalseDest) { + Opc = Instruction::And; + } else if (PBI->getSuccessor(0) == FalseDest) { + Opc = Instruction::And; + InvertPredCond = true; + } else if (PBI->getSuccessor(1) == TrueDest) { + Opc = Instruction::Or; + InvertPredCond = true; } else { - if (PBI->getSuccessor(0) != TrueDest && PBI->getSuccessor(1) != TrueDest) - continue; + continue; } // Check the cost of inserting the necessary logic before performing the // transformation. - if (TTI && Opc != Instruction::BinaryOpsEnd) { + if (TTI) { Type *Ty = BI->getCondition()->getType(); unsigned Cost = TTI->getArithmeticInstrCost(Opc, Ty, CostKind); if (InvertPredCond && (!PBI->getCondition()->hasOneUse() || @@ -2991,8 +2900,6 @@ bool llvm::FoldBranchToCommonDest(BranchInst *BI, DomTreeUpdater *DTU, LLVM_DEBUG(dbgs() << "FOLDING BRANCH TO COMMON DEST:\n" << *PBI << *BB); Changed = true; - SmallVector<DominatorTree::UpdateType, 3> Updates; - IRBuilder<> Builder(PBI); // The builder is used to create instructions to eliminate the branch in BB. // If BB's terminator has !annotation metadata, add it to the new @@ -3015,16 +2922,12 @@ bool llvm::FoldBranchToCommonDest(BranchInst *BI, DomTreeUpdater *DTU, PBI->swapSuccessors(); } - BasicBlock *UniqueSucc = - BI->isConditional() - ? (PBI->getSuccessor(0) == BB ? TrueDest : FalseDest) - : TrueDest; + BasicBlock *UniqueSucc = PBI->getSuccessor(0) == BB ? TrueDest : FalseDest; // Before cloning instructions, notify the successor basic block that it // is about to have a new predecessor. This will update PHI nodes, // which will allow us to update live-out uses of bonus instructions. - if (BI->isConditional()) - AddPredecessorToBlock(UniqueSucc, PredBlock, BB, MSSAU); + AddPredecessorToBlock(UniqueSucc, PredBlock, BB, MSSAU); // If we have bonus instructions, clone them into the predecessor block. // Note that there may be multiple predecessor blocks, so we cannot move @@ -3094,120 +2997,64 @@ bool llvm::FoldBranchToCommonDest(BranchInst *BI, DomTreeUpdater *DTU, if (User->getParent() != UniqueSucc) return false; // Update the incoming value for the new predecessor. - return PN->getIncomingBlock(U) == - (BI->isConditional() ? PredBlock : BB); + return PN->getIncomingBlock(U) == PredBlock; }); } // Now that the Cond was cloned into the predecessor basic block, // or/and the two conditions together. - if (BI->isConditional()) { - Instruction *NewCond = cast<Instruction>( - Builder.CreateBinOp(Opc, PBI->getCondition(), CondInPred, "or.cond")); - PBI->setCondition(NewCond); - - uint64_t PredTrueWeight, PredFalseWeight, SuccTrueWeight, SuccFalseWeight; - bool HasWeights = - extractPredSuccWeights(PBI, BI, PredTrueWeight, PredFalseWeight, - SuccTrueWeight, SuccFalseWeight); - SmallVector<uint64_t, 8> NewWeights; - - if (PBI->getSuccessor(0) == BB) { - if (HasWeights) { - // PBI: br i1 %x, BB, FalseDest - // BI: br i1 %y, UniqueSucc, FalseDest - // TrueWeight is TrueWeight for PBI * TrueWeight for BI. - NewWeights.push_back(PredTrueWeight * SuccTrueWeight); - // FalseWeight is FalseWeight for PBI * TotalWeight for BI + - // TrueWeight for PBI * FalseWeight for BI. - // We assume that total weights of a BranchInst can fit into 32 bits. - // Therefore, we will not have overflow using 64-bit arithmetic. - NewWeights.push_back(PredFalseWeight * - (SuccFalseWeight + SuccTrueWeight) + - PredTrueWeight * SuccFalseWeight); - } - PBI->setSuccessor(0, UniqueSucc); - } - if (PBI->getSuccessor(1) == BB) { - if (HasWeights) { - // PBI: br i1 %x, TrueDest, BB - // BI: br i1 %y, TrueDest, UniqueSucc - // TrueWeight is TrueWeight for PBI * TotalWeight for BI + - // FalseWeight for PBI * TrueWeight for BI. - NewWeights.push_back(PredTrueWeight * - (SuccFalseWeight + SuccTrueWeight) + - PredFalseWeight * SuccTrueWeight); - // FalseWeight is FalseWeight for PBI * FalseWeight for BI. - NewWeights.push_back(PredFalseWeight * SuccFalseWeight); - } - PBI->setSuccessor(1, UniqueSucc); - } - if (NewWeights.size() == 2) { - // Halve the weights if any of them cannot fit in an uint32_t - FitWeights(NewWeights); + Instruction *NewCond = cast<Instruction>( + Builder.CreateBinOp(Opc, PBI->getCondition(), CondInPred, "or.cond")); + PBI->setCondition(NewCond); - SmallVector<uint32_t, 8> MDWeights(NewWeights.begin(), - NewWeights.end()); - setBranchWeights(PBI, MDWeights[0], MDWeights[1]); - } else - PBI->setMetadata(LLVMContext::MD_prof, nullptr); + uint64_t PredTrueWeight, PredFalseWeight, SuccTrueWeight, SuccFalseWeight; + bool HasWeights = + extractPredSuccWeights(PBI, BI, PredTrueWeight, PredFalseWeight, + SuccTrueWeight, SuccFalseWeight); + SmallVector<uint64_t, 8> NewWeights; - Updates.push_back({DominatorTree::Insert, PredBlock, UniqueSucc}); - Updates.push_back({DominatorTree::Delete, PredBlock, BB}); - } else { - // Update PHI nodes in the common successors. - for (unsigned i = 0, e = PHIs.size(); i != e; ++i) { - ConstantInt *PBI_C = cast<ConstantInt>( - PHIs[i]->getIncomingValueForBlock(PBI->getParent())); - assert(PBI_C->getType()->isIntegerTy(1)); - Instruction *MergedCond = nullptr; - if (PBI->getSuccessor(0) == UniqueSucc) { - Updates.push_back( - {DominatorTree::Delete, PredBlock, PBI->getSuccessor(1)}); - // Create (PBI_Cond and PBI_C) or (!PBI_Cond and BI_Value) - // PBI_C is true: PBI_Cond or (!PBI_Cond and BI_Value) - // is false: !PBI_Cond and BI_Value - Instruction *NotCond = cast<Instruction>( - Builder.CreateNot(PBI->getCondition(), "not.cond")); - MergedCond = cast<Instruction>( - Builder.CreateBinOp(Instruction::And, NotCond, CondInPred, - "and.cond")); - if (PBI_C->isOne()) - MergedCond = cast<Instruction>(Builder.CreateBinOp( - Instruction::Or, PBI->getCondition(), MergedCond, "or.cond")); - } else { - assert(PBI->getSuccessor(1) == UniqueSucc && "Unexpected branch"); - Updates.push_back( - {DominatorTree::Delete, PredBlock, PBI->getSuccessor(0)}); - // Create (PBI_Cond and BI_Value) or (!PBI_Cond and PBI_C) - // PBI_C is true: (PBI_Cond and BI_Value) or (!PBI_Cond) - // is false: PBI_Cond and BI_Value - MergedCond = cast<Instruction>(Builder.CreateBinOp( - Instruction::And, PBI->getCondition(), CondInPred, "and.cond")); - if (PBI_C->isOne()) { - Instruction *NotCond = cast<Instruction>( - Builder.CreateNot(PBI->getCondition(), "not.cond")); - MergedCond = cast<Instruction>(Builder.CreateBinOp( - Instruction::Or, NotCond, MergedCond, "or.cond")); - } - } - // Update PHI Node. - PHIs[i]->setIncomingValueForBlock(PBI->getParent(), MergedCond); + if (PBI->getSuccessor(0) == BB) { + if (HasWeights) { + // PBI: br i1 %x, BB, FalseDest + // BI: br i1 %y, UniqueSucc, FalseDest + // TrueWeight is TrueWeight for PBI * TrueWeight for BI. + NewWeights.push_back(PredTrueWeight * SuccTrueWeight); + // FalseWeight is FalseWeight for PBI * TotalWeight for BI + + // TrueWeight for PBI * FalseWeight for BI. + // We assume that total weights of a BranchInst can fit into 32 bits. + // Therefore, we will not have overflow using 64-bit arithmetic. + NewWeights.push_back(PredFalseWeight * + (SuccFalseWeight + SuccTrueWeight) + + PredTrueWeight * SuccFalseWeight); } - - // PBI is changed to branch to UniqueSucc below. Remove itself from - // potential phis from all other successors. - if (MSSAU) - MSSAU->changeCondBranchToUnconditionalTo(PBI, UniqueSucc); - - // Change PBI from Conditional to Unconditional. - BranchInst *New_PBI = BranchInst::Create(UniqueSucc, PBI); - EraseTerminatorAndDCECond(PBI, MSSAU); - PBI = New_PBI; + PBI->setSuccessor(0, UniqueSucc); + } + if (PBI->getSuccessor(1) == BB) { + if (HasWeights) { + // PBI: br i1 %x, TrueDest, BB + // BI: br i1 %y, TrueDest, UniqueSucc + // TrueWeight is TrueWeight for PBI * TotalWeight for BI + + // FalseWeight for PBI * TrueWeight for BI. + NewWeights.push_back(PredTrueWeight * + (SuccFalseWeight + SuccTrueWeight) + + PredFalseWeight * SuccTrueWeight); + // FalseWeight is FalseWeight for PBI * FalseWeight for BI. + NewWeights.push_back(PredFalseWeight * SuccFalseWeight); + } + PBI->setSuccessor(1, UniqueSucc); } + if (NewWeights.size() == 2) { + // Halve the weights if any of them cannot fit in an uint32_t + FitWeights(NewWeights); + + SmallVector<uint32_t, 8> MDWeights(NewWeights.begin(), NewWeights.end()); + setBranchWeights(PBI, MDWeights[0], MDWeights[1]); + } else + PBI->setMetadata(LLVMContext::MD_prof, nullptr); if (DTU) - DTU->applyUpdates(Updates); + DTU->applyUpdates({{DominatorTree::Insert, PredBlock, UniqueSucc}, + {DominatorTree::Delete, PredBlock, BB}}); // If BI was a loop latch, it may have had associated loop metadata. // We need to copy it to the new latch, that is, PBI. diff --git a/llvm/test/Transforms/SimplifyCFG/X86/fold-branch-debuginvariant.ll b/llvm/test/Transforms/SimplifyCFG/X86/fold-branch-debuginvariant.ll deleted file mode 100644 index 44accf871359..000000000000 --- a/llvm/test/Transforms/SimplifyCFG/X86/fold-branch-debuginvariant.ll +++ /dev/null @@ -1,48 +0,0 @@ -; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s -; RUN: opt < %s -strip-debug -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s - -; Verify that the and.2 instruction is eliminated even in the presence of a -; preceding debug intrinsic. - -; CHECK-LABEL: bb1: -; CHECK: and i1 false, false -; CHECK-NOT: and i1 false, false - -target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" -target triple = "x86_64-unknown-linux-gnu" - -; Function Attrs: norecurse nounwind -define void @foo() local_unnamed_addr #0 !dbg !4 { -bb1: - %and.1 = and i1 false, false - %cmp = icmp eq i16 0, 0 - br i1 %cmp, label %bb2, label %bb3 - -bb2: ; preds = %bb1 - call void @llvm.dbg.value(metadata i16 0, metadata !8, metadata !DIExpression()), !dbg !9 - %and.2 = and i1 false, false - br label %bb3 - -bb3: ; preds = %bb2, %bb1 - ret void -} - -; Function Attrs: nounwind readnone speculatable -declare void @llvm.dbg.value(metadata, metadata, metadata) #1 - -attributes #0 = { norecurse nounwind } -attributes #1 = { nounwind readnone speculatable } - -!llvm.dbg.cu = !{!0} -!llvm.module.flags = !{!3} - -!0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "Foo", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !2, globals: !2) -!1 = !DIFile(filename: "foo.c", directory: "/") -!2 = !{} -!3 = !{i32 2, !"Debug Info Version", i32 3} -!4 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 10, type: !5, isLocal: false, isDefinition: true, scopeLine: 10, isOptimized: false, unit: !0, retainedNodes: !2) -!5 = !DISubroutineType(types: !6) -!6 = !{null, !7} -!7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -!8 = !DILocalVariable(name: "p_1", arg: 1, scope: !4, line: 4, type: !7) -!9 = distinct !DILocation(line: 11, column: 3, scope: !4) diff --git a/llvm/test/Transforms/SimplifyCFG/branch-fold.ll b/llvm/test/Transforms/SimplifyCFG/branch-fold.ll index 5b9f20b97d4e..1caaf16dd591 100644 --- a/llvm/test/Transforms/SimplifyCFG/branch-fold.ll +++ b/llvm/test/Transforms/SimplifyCFG/branch-fold.ll @@ -39,12 +39,16 @@ define zeroext i1 @test2(i64 %i0, i64 %i1) nounwind uwtable readonly ssp { ; CHECK-NEXT: [[SHR_I_I:%.*]] = lshr i64 [[I1]], 48 ; CHECK-NEXT: [[AND_I2_I:%.*]] = and i64 [[SHR_I_I]], 32767 ; CHECK-NEXT: [[CMP9_I:%.*]] = icmp ult i64 [[AND_I5_I]], [[AND_I2_I]] -; CHECK-NEXT: [[PHITMP:%.*]] = icmp uge i64 [[AND_I2_I]], [[AND_I5_I]] -; CHECK-NEXT: [[NOT_COND:%.*]] = xor i1 [[CMP9_I]], true -; CHECK-NEXT: [[AND_COND:%.*]] = and i1 [[NOT_COND]], [[PHITMP]] +; CHECK-NEXT: br i1 [[CMP9_I]], label [[C]], label [[B:%.*]] +; CHECK: b: +; CHECK-NEXT: [[SHR_I13_I9:%.*]] = lshr i64 [[I1]], 48 +; CHECK-NEXT: [[AND_I14_I10:%.*]] = and i64 [[SHR_I13_I9]], 32767 +; CHECK-NEXT: [[SHR_I_I11:%.*]] = lshr i64 [[I0]], 48 +; CHECK-NEXT: [[AND_I11_I12:%.*]] = and i64 [[SHR_I_I11]], 32767 +; CHECK-NEXT: [[PHITMP:%.*]] = icmp uge i64 [[AND_I14_I10]], [[AND_I11_I12]] ; CHECK-NEXT: br label [[C]] ; CHECK: c: -; CHECK-NEXT: [[O2:%.*]] = phi i1 [ [[AND_COND]], [[A]] ], [ false, [[ENTRY:%.*]] ] +; CHECK-NEXT: [[O2:%.*]] = phi i1 [ false, [[A]] ], [ [[PHITMP]], [[B]] ], [ false, [[ENTRY:%.*]] ] ; CHECK-NEXT: ret i1 [[O2]] ; entry: _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits