<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Committed in r223784 - r223786<div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Dec 8, 2014, at 6:45 PM, Juergen Ributzka <<a href="mailto:juergen@apple.com" class="">juergen@apple.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=us-ascii" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Hi Jim,<div class=""><br class=""></div><div class="">I updated the patch with your comments. I originally tried to enable it also for SelectionDAG, but there were some regressions in the unit tests for PPC and X86 which I have to look into first.</div><div class=""><br class=""></div><div class="">Here is the updated patch. I modified and included also the pattern match code, but I will break that out before I commit it.</div><div class=""><br class=""></div><div class="">Cheers,</div><div class="">Juergen</div><div class=""><br class=""></div><div class=""></div></div><span id="cid:B4672DBF-FA72-4DF6-9714-1415563FE9F1@apple.com"><0001-CodeGenPrepare-Split-branch-conditions-into-multiple.patch></span><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""></div><div class=""><br class=""></div><div class=""><div class=""><blockquote type="cite" class=""><div class="">On Dec 8, 2014, at 11:06 AM, Jim Grosbach <<a href="mailto:grosbach@apple.com" class="">grosbach@apple.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">Hi Juergen,</div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br class=""></div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">This looks great. A few comments and questions inline.</div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br class=""><blockquote type="cite" class=""><div class="">From f8a3aecf2439256286bbe585d03161ac8750f7b1 Mon Sep 17 00:00:00 2001</div><div class="">From: Juergen Ributzka <<a href="mailto:juergen@apple.com" class="">juergen@apple.com</a>></div><div class="">Date: Thu, 4 Dec 2014 14:31:43 -0800</div><div class="">Subject: [PATCH 2/2] [CodeGenPrepare] Split branch conditions into multiple</div><div class=""> conditional branches.</div><div class=""><br class=""></div><div class="">This optimization transforms code like:</div><div class="">bb1:</div><div class="">  %0 = icmp ne i32 %a, 0</div><div class="">  %1 = icmp ne i32 %b, 0</div><div class="">  %or.cond = or i1 %0, %1</div><div class="">  br i1 %or.cond, label %TrueBB, label %FalseBB</div><div class=""><br class=""></div><div class="">into a multiple branch instructions like:</div><div class=""><br class=""></div><div class="">bb1:</div><div class="">  %0 = icmp ne i32 %a, 0</div><div class="">  br i1 %0, label %TrueBB, label %bb2</div><div class="">bb2:</div><div class="">  %1 = icmp ne i32 %b, 0</div><div class="">  br i1 %1, label %TrueBB, label %FalseBB</div><div class=""><br class=""></div><div class="">This optimization is already performed by SelectionDAG, but not by</div><div class="">FastISel. FastISel cannot perform this optimization, because it cannot</div><div class="">generate new MachineBasicBlocks.</div><div class=""><br class=""></div></blockquote><div class=""><br class=""></div><div class="">Should we allow CGP to do this for SDag as well? It seems strange to do the same thing in two places.</div><div class=""><br class=""></div><br class=""><blockquote type="cite" class=""><div class="">This fixes<span class="Apple-converted-space"> </span><a href="rdar://problem/19034919" class="">rdar://problem/19034919</a>.</div><div class="">---</div><div class=""> lib/CodeGen/CodeGenPrepare.cpp                     | 151 ++++++++++++++++++++-</div><div class=""> .../CodeGen/AArch64/fast-isel-branch-cond-split.ll |  42 ++++++</div><div class=""> 2 files changed, 192 insertions(+), 1 deletion(-)</div><div class=""> create mode 100644 test/CodeGen/AArch64/fast-isel-branch-cond-split.ll</div><div class=""><br class=""></div><div class="">diff --git a/lib/CodeGen/CodeGenPrepare.cpp b/lib/CodeGen/CodeGenPrepare.cpp</div><div class="">index 8d20848..eaee445 100644</div><div class="">--- a/lib/CodeGen/CodeGenPrepare.cpp</div><div class="">+++ b/lib/CodeGen/CodeGenPrepare.cpp</div><div class="">@@ -30,6 +30,7 @@</div><div class=""> #include "llvm/IR/InlineAsm.h"</div><div class=""> #include "llvm/IR/Instructions.h"</div><div class=""> #include "llvm/IR/IntrinsicInst.h"</div><div class="">+#include "llvm/IR/MDBuilder.h"</div><div class=""> #include "llvm/IR/PatternMatch.h"</div><div class=""> #include "llvm/IR/ValueHandle.h"</div><div class=""> #include "llvm/IR/ValueMap.h"</div><div class="">@@ -165,6 +166,7 @@ typedef DenseMap<Instruction *, TypeIsSExt> InstrToOrigTy;</div><div class="">     bool DupRetToEnableTailCallOpts(BasicBlock *BB);</div><div class="">     bool PlaceDbgValues(Function &F);</div><div class="">     bool sinkAndCmp(Function &F);</div><div class="">+    bool splitBranchCondition(Function &F);</div><div class="">   };</div><div class=""> }</div><div class=""> </div><div class="">@@ -218,8 +220,10 @@ bool CodeGenPrepare::runOnFunction(Function &F) {</div><div class="">   // into a single target instruction, push the mask and compare into branch</div><div class="">   // users. Do this before OptimizeBlock -> OptimizeInst -></div><div class="">   // OptimizeCmpExpression, which perturbs the pattern being searched for.</div><div class="">-  if (!DisableBranchOpts)</div><div class="">+  if (!DisableBranchOpts) {</div><div class="">     EverMadeChange |= sinkAndCmp(F);</div><div class="">+    EverMadeChange |= splitBranchCondition(F);</div><div class="">+  }</div><div class=""> </div><div class="">   bool MadeChange = true;</div><div class="">   while (MadeChange) {</div><div class="">@@ -3793,3 +3797,148 @@ bool CodeGenPrepare::sinkAndCmp(Function &F) {</div><div class="">   }</div><div class="">   return MadeChange;</div><div class=""> }</div><div class="">+</div><div class="">+/// \brief Scale down both weights to fit into uint32_t.</div><div class="">+static void scaleWeights(uint64_t &NewTrue, uint64_t &NewFalse) {</div><div class="">+  uint64_t NewMax = (NewTrue > NewFalse) ? NewTrue : NewFalse;</div><div class="">+  uint32_t Scale = (NewMax / UINT32_MAX) + 1;</div><div class="">+  NewTrue = NewTrue / Scale;</div><div class="">+  NewFalse = NewFalse / Scale;</div><div class="">+}</div><div class="">+</div><div class="">+/// \brief Some target prefer to split a conditional branch like:</div></blockquote><div class=""><br class=""></div><div class="">s/target/targets/</div><div class=""><br class=""></div><div class="">Probably worth indicating the criteria by which those targets are identified. In the code it’s just whether branches are considered expensive, so we can just mention that explicitly here, too.</div><br class=""><blockquote type="cite" class=""><div class="">+/// \code</div><div class="">+///   %0 = icmp ne i32 %a, 0</div><div class="">+///   %1 = icmp ne i32 %b, 0</div><div class="">+///   %or.cond = or i1 %0, %1</div><div class="">+///   br i1 %or.cond, label %TrueBB, label %FalseBB</div><div class="">+/// \endcode</div><div class="">+/// into a multiple branch instructions like:</div><div class="">+/// \code</div><div class="">+///   bb1:</div><div class="">+///     %0 = icmp ne i32 %a, 0</div><div class="">+///     br i1 %0, label %TrueBB, label %bb2</div><div class="">+///   bb2:</div><div class="">+///     %1 = icmp ne i32 %b, 0</div><div class="">+///     br i1 %1, label %TrueBB, label %FalseBB</div><div class="">+/// \endcode</div><div class="">+/// This usually allows instruction selection to do even further optimizations</div><div class="">+/// and combine the compare with the branch instruction.</div><div class="">+bool CodeGenPrepare::splitBranchCondition(Function &F) {</div><div class="">+  if (!TM || TM->Options.EnableFastISel != true ||</div><div class="">+      !TLI || TLI->isJumpExpensive())</div><div class="">+    return false;</div><div class="">+</div><div class="">+  bool MadeChange = false;</div><div class="">+  for (auto BB = F.begin(), E = F.end(); BB != E; ++BB) {</div></blockquote><div class=""><br class=""></div><div class="">Why not a range-based for loop?</div><br class=""><blockquote type="cite" class=""><div class="">+    // Does this BB end with the following?</div><div class="">+    //   %cond1 = icmp|fcmp|binary instruction ...</div><div class="">+    //   %cond2 = icmp|fcmp|binary instruction ...</div><div class="">+    //   %cond.or = or|and i1 %cond1, cond2</div><div class="">+    //   br i1 %cond.or label %dest1, label %dest2"</div><div class="">+    auto *Br1 = dyn_cast<BranchInst>(BB->getTerminator());</div><div class="">+    if (!Br1)</div><div class="">+      continue;</div><div class="">+</div><div class="">+    if (Br1->isUnconditional())</div><div class="">+      continue;</div><div class="">+</div><div class="">+    auto *LogicOp = dyn_cast<BinaryOperator>(Br1->getCondition());</div><div class="">+    if (!LogicOp)</div><div class="">+      continue;</div><div class="">+</div><div class="">+    unsigned Idx;</div><div class="">+    if (LogicOp->hasOneUse() && (LogicOp->getOpcode() == Instruction::And))</div><div class="">+      Idx = 0;</div><div class="">+    else if (LogicOp->hasOneUse() && (LogicOp->getOpcode() == Instruction::Or))</div><div class="">+      Idx = 1;</div><div class="">+    else</div><div class="">+      continue;</div><div class="">+</div><div class="">+    auto *Cond1 = dyn_cast<Instruction>(LogicOp->getOperand(0));</div><div class="">+    auto *Cond2 = dyn_cast<Instruction>(LogicOp->getOperand(1));</div><div class="">+</div><div class="">+    if (!Cond1 || (!isa<CmpInst>(Cond1) && !isa<BinaryOperator>(Cond1)) ||</div><div class="">+        !Cond2 || (!isa<CmpInst>(Cond2) && !isa<BinaryOperator>(Cond2))   )</div><div class="">+      continue;</div><div class="">+</div><div class="">+    if (!Cond1->hasOneUse() || !Cond2->hasOneUse())</div><div class="">+      continue;</div></blockquote><div class=""><br class=""></div><div class="">This matching sequence might be simpler to express with PatternMatch.h.</div><br class=""><blockquote type="cite" class=""><div class="">+</div><div class="">+    BasicBlock *TrueDest = Br1->getSuccessor(0);</div><div class="">+    BasicBlock *FalseDest = Br1->getSuccessor(1);</div><div class="">+</div><div class="">+    DEBUG(dbgs() << "Before branch condition splitting\n"; BB->dump());</div><div class="">+</div><div class="">+    // Create a new BB.</div><div class="">+    auto *InsertBefore = std::next(Function::iterator(BB))</div><div class="">+        .getNodePtrUnchecked();</div><div class="">+    auto NewBB = BasicBlock::Create(BB->getContext(),</div><div class="">+                                    BB->getName() + ".cond.split",</div><div class="">+                                    BB->getParent(), InsertBefore);</div><div class="">+</div><div class="">+    // Update original basic block by using the first condition directly by the</div><div class="">+    // branch instruction and removing the no longer needed and/or instruction.</div><div class="">+    Br1->setCondition(Cond1);</div><div class="">+    LogicOp->eraseFromParent();</div><div class="">+    Cond2->removeFromParent();</div><div class="">+    Br1->setSuccessor(Idx, NewBB);</div><div class="">+</div><div class="">+    // Fill in the new basic block.</div><div class="">+    auto *Br2 = BranchInst::Create(TrueDest, FalseDest, Cond2, NewBB);</div><div class="">+    Cond2->insertBefore(Br2);</div></blockquote><div class=""><br class=""></div><div class="">Using IRBuilder rather than explicit BranchInstr::Create may be cleaner/clearer.</div><br class=""><blockquote type="cite" class=""><div class="">+</div><div class="">+    // Update PHI nodes in both successors.</div><div class="">+    if (Idx == 1)</div><div class="">+      std::swap(TrueDest, FalseDest);</div><div class="">+</div></blockquote><div class=""><br class=""></div><div class="">Creating a new conditional branch instruction for TrueDest and FalseDest then immediately swapping the values for those pointers is odd. Probably correct based on the rest of the code, but a more detailed comment about what’s going on would be handy.</div><div class=""><br class=""></div><br class=""><blockquote type="cite" class=""><div class="">+    // Replace the old BB with the new BB.</div><div class="">+    for (auto I = TrueDest->begin(), IE = TrueDest->end(); I != IE; ++I) {</div></blockquote><div class=""><br class=""></div><div class="">Range based loop?</div><br class=""><blockquote type="cite" class=""><div class="">+      PHINode *PN = dyn_cast<PHINode>(I);</div><div class="">+      if (!PN)</div><div class="">+        break;</div><div class="">+      int i;</div><div class="">+      while ((i = PN->getBasicBlockIndex(BB)) >= 0)</div><div class="">+        PN->setIncomingBlock(i, NewBB);</div><div class="">+    }</div><div class="">+</div><div class="">+    // Add another incoming edge form the new BB.</div><div class="">+    for (auto I = FalseDest->begin(), IE = FalseDest->end(); I != IE; ++I) {</div></blockquote><div class=""><br class=""></div><div class="">Range based loop?</div><br class=""><blockquote type="cite" class=""><div class="">+      PHINode *PN = dyn_cast<PHINode>(I);</div><div class="">+      if (!PN)</div></blockquote><blockquote type="cite" class=""><div class="">+        break;</div><div class="">+      auto *Val = PN->getIncomingValueForBlock(BB);</div><div class="">+      PN->addIncoming(Val, NewBB);</div><div class="">+    }</div><div class="">+</div><div class="">+    // Update the branch weights (based on SelectionDAGBuilder::</div><div class="">+    // FindMergedConditions).</div><div class="">+    uint64_t TrueWeight, FalseWeight;</div><div class="">+    if (Br1->getBranchWeights(TrueWeight, FalseWeight)) {</div><div class="">+      uint64_t NewTrueWeight = TrueWeight;</div><div class="">+      uint64_t NewFalseWeight = TrueWeight + 2 * FalseWeight;</div><div class="">+</div></blockquote><div class=""><br class=""></div><div class="">These numbers could use a bit of explanation.</div><br class=""><blockquote type="cite" class=""><div class="">     scaleWeights(NewTrueWeight, NewFalseWeight);</div><div class="">+      Br1->setMetadata(LLVMContext::MD_prof, MDBuilder(Br1->getContext())</div><div class="">+          .createBranchWeights(TrueWeight, FalseWeight));</div><div class="">+</div><div class="">+      NewTrueWeight = TrueWeight;</div><div class="">+      NewFalseWeight = 2 * FalseWeight;</div><div class="">+      scaleWeights(NewTrueWeight, NewFalseWeight);</div><div class="">+      Br2->setMetadata(LLVMContext::MD_prof, MDBuilder(Br2->getContext())</div><div class="">+          .createBranchWeights(TrueWeight, FalseWeight));</div><div class="">+    }</div><div class="">+</div><div class="">+    // Request DOM Tree update.</div><div class="">+    // Note: No point in getting fancy here, since the DT info is never</div><div class="">+    // available to CodeGenPrepare and the existing update code is broken</div><div class="">+    // anyways.</div><div class="">+    ModifiedDT = true;</div><div class="">+</div><div class="">+    MadeChange = true;</div><div class="">+</div><div class="">+    DEBUG(dbgs() << "After branch condition splitting\n"; BB->dump();</div><div class="">+          NewBB->dump());</div><div class="">+  }</div><div class="">+</div><div class="">+  return MadeChange;</div><div class="">+}</div><div class="">diff --git a/test/CodeGen/AArch64/fast-isel-branch-cond-split.ll b/test/CodeGen/AArch64/fast-isel-branch-cond-split.ll</div><div class="">new file mode 100644</div><div class="">index 0000000..058007b</div><div class="">--- /dev/null</div><div class="">+++ b/test/CodeGen/AArch64/fast-isel-branch-cond-split.ll</div><div class="">@@ -0,0 +1,42 @@</div><div class="">+; RUN: llc -mtriple=aarch64-apple-darwin -fast-isel -fast-isel-abort -verify-machineinstrs < %s | FileCheck %s</div><div class="">+</div><div class="">+; CHECK-label: test_or</div><div class="">+; CHECK:       cbnz w0, {{LBB[0-9]+_2}}</div><div class="">+; CHECK:       cbz w1, {{LBB[0-9]+_1}}</div><div class="">+define i64 @test_or(i32 %a, i32 %b) {</div><div class="">+bb1:</div><div class="">+  %0 = icmp eq i32 %a, 0</div><div class="">+  %1 = icmp eq i32 %b, 0</div><div class="">+  %or.cond = or i1 %0, %1</div><div class="">+  br i1 %or.cond, label %bb3, label %bb4, !prof !0</div><div class="">+</div><div class="">+bb3:</div><div class="">+  ret i64 0</div><div class="">+</div><div class="">+bb4:</div><div class="">+  %2 = call i64 @bar()</div><div class="">+  ret i64 %2</div><div class="">+}</div><div class="">+</div><div class="">+; CHECK-label: test_ans</div><div class="">+; CHECK:       cbz w0, {{LBB[0-9]+_2}}</div><div class="">+; CHECK:       cbnz w1, {{LBB[0-9]+_3}}</div><div class="">+define i64 @test_and(i32 %a, i32 %b) {</div><div class="">+bb1:</div><div class="">+  %0 = icmp ne i32 %a, 0</div><div class="">+  %1 = icmp ne i32 %b, 0</div><div class="">+  %or.cond = and i1 %0, %1</div><div class="">+  br i1 %or.cond, label %bb4, label %bb3, !prof !1</div><div class="">+</div><div class="">+bb3:</div><div class="">+  ret i64 0</div><div class="">+</div><div class="">+bb4:</div><div class="">+  %2 = call i64 @bar()</div><div class="">+  ret i64 %2</div><div class="">+}</div><div class="">+</div><div class="">+declare i64 @bar()</div><div class="">+</div><div class="">+!0 = metadata !{metadata !"branch_weights", i32 5128, i32 32}</div><div class="">+!1 = metadata !{metadata !"branch_weights", i32 1024, i32 4136}</div><div class="">-- </div><div class="">2.1.3</div><div class=""><br class=""></div></blockquote></div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br class=""></div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br class=""></div><br class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" class=""><div class="">On Dec 4, 2014, at 3:59 PM, Juergen Ributzka <<a href="mailto:juergen@apple.com" class="">juergen@apple.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><span class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;">Updated patch. This time with a test case and the optimization only kicks in when FastISel is enabled.</span><br class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><span id="cid:3EA8BEF9-DAD0-4A5B-B5FA-7D79924A833C@apple.com" class=""><0002-CodeGenPrepare-Split-branch-conditions-into-multiple-v2.patch></span><br class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><blockquote type="cite" class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">On Dec 4, 2014, at 2:57 PM, Juergen Ributzka <<a href="mailto:juergen@apple.com" class="">juergen@apple.com</a>> wrote:<br class=""><br class="">Hi @ll,<br class=""><br class="">SimplifyCFG likes to fold conditional branches to a common destination into a single conditional branch, where the original conditions can be combined with an and/or instruction (FoldBranchToCommonDest).<br class=""><br class="">Example:<br class="">bb1:<br class="">%0 = icmp eq i32 %a, 0<br class="">br i1 %0, label %bb3, label %bb2, !prof !0<br class=""><br class="">bb2:<br class="">%1 = icmp eq i32 %b, 0<br class="">br i1 %1, label %bb3, label %bb4, !prof !1<br class=""><br class="">is optimized to:<br class=""><br class="">bb1:<br class="">%0 = icmp eq i32 %a, 0<br class="">%1 = icmp eq i32 %b, 0<br class="">%or.cond = or i1 %0, %1<br class="">br i1 %or.cond, label %bb3, label %bb4, !prof !0<br class=""><br class=""><br class="">During SelectionDAG time this transformation is reversed, because it is usually more efficient (code size and performance) to express this code as multiple branches. SelectionDAG can do this, because it can generate new MachineBasicBlocks. FastISel on the other side cannot do this and generates inefficient code (I see 10% regression on some benchmarks).<br class=""><br class="">The attached patch fixes this by performing the splitting early during CodeGenPrepare. In theory this code can be shared now by SelectionDAG and FastISel and the original implementation in SelectionDAG could be removed.<br class=""><br class=""><br class="">Any comments and/or ideas about this approach in general? Is there a better way to do this?<br class=""><br class="">Thanks<br class=""><br class="">Cheers,<br class="">Juergen<br class=""><br class=""><0001-Move-function-to-obtain-branch-weights-into-the-Bran.patch><0002-CodeGenPrepare-Split-branch-conditions-into-multiple.patch><br class=""><br class="">_______________________________________________<br class="">llvm-commits mailing list<br class=""><a href="mailto:llvm-commits@cs.uiuc.edu" class="">llvm-commits@cs.uiuc.edu</a><br class=""><a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" class="">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br class=""></blockquote><br class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><span class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;">_______________________________________________</span><br class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><span class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;">llvm-commits mailing list</span><br class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><a href="mailto:llvm-commits@cs.uiuc.edu" class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">llvm-commits@cs.uiuc.edu</a><br class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a></div></blockquote></div></div></blockquote></div><br class=""></div></div>_______________________________________________<br class="">llvm-commits mailing list<br class=""><a href="mailto:llvm-commits@cs.uiuc.edu" class="">llvm-commits@cs.uiuc.edu</a><br class="">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits<br class=""></div></blockquote></div><br class=""></div></body></html>