<div dir="ltr">Working on it. If I can't fix it in a few hours, I'll revert it.</div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Aug 26, 2016 at 8:17 AM, Krzysztof Parzyszek <span dir="ltr"><<a href="mailto:kparzysz@codeaurora.org" target="_blank">kparzysz@codeaurora.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi Kyle,<br>
This commit seems to cause a crash on Hexagon:<br>
<br>
--- if-crash.ll ---<br>
target triple = "hexagon"<br>
<br>
%struct.0 = type { i16, i16 }<br>
<br>
@t = external local_unnamed_addr global %struct.0, align 2<br>
<br>
define void @foo(i32 %p) local_unnamed_addr #0 {<br>
entry:<br>
  %conv90 = trunc i32 %p to i16<br>
  %call105 = call signext i16 @bar(i16 signext 16384, i16 signext undef) #0<br>
  %call175 = call signext i16 @bar(i16 signext %conv90, i16 signext 4) #0<br>
  %call197 = call signext i16 @bar(i16 signext %conv90, i16 signext 4) #0<br>
  %cmp199 = icmp eq i16 %call197, 0<br>
  br i1 %cmp199, label %if.then200, label %if.else201<br>
<br>
if.then200:                                       ; preds = %entry<br>
  store i16 4, i16* getelementptr inbounds (%struct.0, %struct.0* @t, i32 0, i32 0), align 2<br>
  store i16 0, i16* getelementptr inbounds (%struct.0, %struct.0* @t, i32 0, i32 1), align 2<br>
  br label %if.end202<br>
<br>
if.else201:                                       ; preds = %entry<br>
  store i16 3, i16* getelementptr inbounds (%struct.0, %struct.0* @t, i32 0, i32 0), align 2<br>
  br label %if.end202<br>
<br>
if.end202:                                        ; preds = %if.else201, %if.then200<br>
  ret void<br>
}<br>
<br>
declare signext i16 @bar(i16 signext, i16 signext) local_unnamed_addr #0<br>
<br>
attributes #0 = { optsize "target-cpu"="hexagonv55" }<br>
-------------------<br>
<br>
<br>
$ llc -march=hexagon < if-crash.ll<br>
<br>
<br>
llc: lib/Target/Hexagon/HexagonInst<wbr>rInfo.cpp:1374: virtual bool llvm::HexagonInstrInfo::Predic<wbr>ateInstruction(llvm::MachineIn<wbr>str &, ArrayRef<llvm::MachineOperand><wbr>) const: Assertion `isPredicable(MI) && "Expected predicable instruction"' failed.<br>
<br>
<br>
-Krzysztof<div class="HOEnZb"><div class="h5"><br>
<br>
<br>
On 8/24/2016 4:34 PM, Kyle Butt via llvm-commits wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Author: iteratee<br>
Date: Wed Aug 24 16:34:24 2016<br>
New Revision: 279670<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=279670&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject?rev=279670&view=rev</a><br>
Log:<br>
IfConversion: Rescan diamonds.<br>
<br>
The cost of predicating a diamond is only the instructions that are not shared<br>
between the two branches. Additionally If a predicate clobbering instruction<br>
occurs in the shared portion of the branches (e.g. a cond move), it may still<br>
be possible to if convert the sub-cfg. This change handles these two facts by<br>
rescanning the non-shared portion of a diamond sub-cfg to recalculate both the<br>
predication cost and whether both blocks are pred-clobbering.<br>
<br>
Fixed 2 bugs before recommitting. Branch instructions must be compared and found<br>
identical before diamond conversion. Also, predicate-clobbering instructions in<br>
the shared prefix disqualifies a potential diamond conversion. Includes tests<br>
for both.<br>
<br>
Added:<br>
    llvm/trunk/test/CodeGen/Thumb2<wbr>/ifcvt-rescan-bug-2016-08-22.<wbr>ll<br>
Modified:<br>
    llvm/trunk/lib/CodeGen/IfConve<wbr>rsion.cpp<br>
    llvm/trunk/test/CodeGen/ARM/in<wbr>directbr-3.ll<br>
<br>
Modified: llvm/trunk/lib/CodeGen/IfConve<wbr>rsion.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/IfConversion.cpp?rev=279670&r1=279669&r2=279670&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/llvm/trunk/lib/CodeGen/<wbr>IfConversion.cpp?rev=279670&<wbr>r1=279669&r2=279670&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/lib/CodeGen/IfConve<wbr>rsion.cpp (original)<br>
+++ llvm/trunk/lib/CodeGen/IfConve<wbr>rsion.cpp Wed Aug 24 16:34:24 2016<br>
@@ -149,11 +149,15 @@ namespace {<br>
     struct IfcvtToken {<br>
       BBInfo &BBI;<br>
       IfcvtKind Kind;<br>
-      bool NeedSubsumption;<br>
       unsigned NumDups;<br>
       unsigned NumDups2;<br>
-      IfcvtToken(BBInfo &b, IfcvtKind k, bool s, unsigned d, unsigned d2 = 0)<br>
-        : BBI(b), Kind(k), NeedSubsumption(s), NumDups(d), NumDups2(d2) {}<br>
+      bool NeedSubsumption : 1;<br>
+      bool TClobbersPred : 1;<br>
+      bool FClobbersPred : 1;<br>
+      IfcvtToken(BBInfo &b, IfcvtKind k, bool s, unsigned d, unsigned d2 = 0,<br>
+                 bool tc = false, bool fc = false)<br>
+        : BBI(b), Kind(k), NumDups(d), NumDups2(d2), NeedSubsumption(s),<br>
+          TClobbersPred(tc), FClobbersPred(fc) {}<br>
     };<br>
<br>
     /// Results of if-conversion feasibility analysis indexed by basic block<br>
@@ -202,16 +206,29 @@ namespace {<br>
     bool ValidTriangle(BBInfo &TrueBBI, BBInfo &FalseBBI,<br>
                        bool FalseBranch, unsigned &Dups,<br>
                        BranchProbability Prediction) const;<br>
+    bool CountDuplicatedInstructions(<br>
+        MachineBasicBlock::iterator &TIB, MachineBasicBlock::iterator &FIB,<br>
+        MachineBasicBlock::iterator &TIE, MachineBasicBlock::iterator &FIE,<br>
+        unsigned &Dups1, unsigned &Dups2,<br>
+        MachineBasicBlock &TBB, MachineBasicBlock &FBB,<br>
+        bool SkipUnconditionalBranches) const;<br>
     bool ValidDiamond(BBInfo &TrueBBI, BBInfo &FalseBBI,<br>
-                      unsigned &Dups1, unsigned &Dups2) const;<br>
+                      unsigned &Dups1, unsigned &Dups2,<br>
+                      BBInfo &TrueBBICalc, BBInfo &FalseBBICalc) const;<br>
     void AnalyzeBranches(BBInfo &BBI);<br>
     void ScanInstructions(BBInfo &BBI,<br>
                           MachineBasicBlock::iterator &Begin,<br>
-                          MachineBasicBlock::iterator &End) const;<br>
+                          MachineBasicBlock::iterator &End,<br>
+                          bool BranchUnpredicable = false) const;<br>
+    bool RescanInstructions(<br>
+        MachineBasicBlock::iterator &TIB, MachineBasicBlock::iterator &FIB,<br>
+        MachineBasicBlock::iterator &TIE, MachineBasicBlock::iterator &FIE,<br>
+        BBInfo &TrueBBI, BBInfo &FalseBBI) const;<br>
     void AnalyzeBlock(MachineBasicBlock &MBB,<br>
                       std::vector<std::unique_ptr<I<wbr>fcvtToken>> &Tokens);<br>
     bool FeasibilityAnalysis(BBInfo &BBI, SmallVectorImpl<MachineOperand<wbr>> &Cond,<br>
-                             bool isTriangle = false, bool RevBranch = false);<br>
+                             bool isTriangle = false, bool RevBranch = false,<br>
+                             bool hasCommonTail = false);<br>
     void AnalyzeBlocks(MachineFunction &MF,<br>
                        std::vector<std::unique_ptr<If<wbr>cvtToken>> &Tokens);<br>
     void InvalidatePreds(MachineBasicBl<wbr>ock &MBB);<br>
@@ -219,7 +236,8 @@ namespace {<br>
     bool IfConvertSimple(BBInfo &BBI, IfcvtKind Kind);<br>
     bool IfConvertTriangle(BBInfo &BBI, IfcvtKind Kind);<br>
     bool IfConvertDiamond(BBInfo &BBI, IfcvtKind Kind,<br>
-                          unsigned NumDups1, unsigned NumDups2);<br>
+                          unsigned NumDups1, unsigned NumDups2,<br>
+                          bool TClobbers, bool FClobbers);<br>
     void PredicateBlock(BBInfo &BBI,<br>
                         MachineBasicBlock::iterator E,<br>
                         SmallVectorImpl<MachineOperan<wbr>d> &Cond,<br>
@@ -406,7 +424,9 @@ bool IfConverter::runOnMachineFunct<wbr>ion(M<br>
         DEBUG(dbgs() << "Ifcvt (Diamond): BB#" << BBI.BB->getNumber() << " (T:"<br>
                      << BBI.TrueBB->getNumber() << ",F:"<br>
                      << BBI.FalseBB->getNumber() << ") ");<br>
-        RetVal = IfConvertDiamond(BBI, Kind, NumDups, NumDups2);<br>
+        RetVal = IfConvertDiamond(BBI, Kind, NumDups, NumDups2,<br>
+                                  Token->TClobbersPred,<br>
+                                  Token->FClobbersPred);<br>
         DEBUG(dbgs() << (RetVal ? "succeeded!" : "failed!") << "\n");<br>
         if (RetVal) ++NumDiamonds;<br>
         break;<br>
@@ -591,14 +611,22 @@ static inline bool skipDebugInstructions<br>
 /// finally point to the first shared instruction in the tail.<br>
 /// Upon return [TIB, TIE), and [FIB, FIE) mark the un-duplicated portions of<br>
 /// two blocks.<br>
-static void countDuplicatedInstructions(<br>
+/// @param Dups1 count of duplicated instructions at the beginning of the 2<br>
+/// blocks.<br>
+/// @param Dups2 count of duplicated instructions at the end of the 2 blocks.<br>
+/// @param SkipUnconditionalBranches if true, Don't make sure that<br>
+/// unconditional branches at the end of the blocks are the same. True is<br>
+/// passed when the blocks are analyzable to allow for fallthrough to be<br>
+/// handled.<br>
+/// @return false if the shared portion prevents if conversion.<br>
+bool IfConverter::CountDuplicatedIn<wbr>structions(<br>
     MachineBasicBlock::iterator &TIB,<br>
     MachineBasicBlock::iterator &FIB,<br>
     MachineBasicBlock::iterator &TIE,<br>
     MachineBasicBlock::iterator &FIE,<br>
     unsigned &Dups1, unsigned &Dups2,<br>
     MachineBasicBlock &TBB, MachineBasicBlock &FBB,<br>
-    bool SkipConditionalBranches) {<br>
+    bool SkipUnconditionalBranches) const {<br>
<br>
   while (TIB != TIE && FIB != FIE) {<br>
     // Skip dbg_value instructions. These do not count.<br>
@@ -608,6 +636,11 @@ static void countDuplicatedInstructions(<br>
       break;<br>
     if (!TIB->isIdenticalTo(*FIB))<br>
       break;<br>
+    // A pred-clobbering instruction in the shared portion prevents<br>
+    // if-conversion.<br>
+    std::vector<MachineOperand> PredDefs;<br>
+    if (TII->DefinesPredicate(*TIB, PredDefs))<br>
+      return false;<br>
     ++Dups1;<br>
     ++TIB;<br>
     ++FIB;<br>
@@ -618,7 +651,7 @@ static void countDuplicatedInstructions(<br>
   // can be left unpredicated.<br>
   // Check for already containing all of the block.<br>
   if (TIB == TIE || FIB == FIE)<br>
-    return;<br>
+    return true;<br>
   // Now, in preparation for counting duplicate instructions at the ends of the<br>
   // blocks, move the end iterators up past any branch instructions.<br>
   --TIE;<br>
@@ -641,12 +674,7 @@ static void countDuplicatedInstructions(<br>
   });<br>
<br>
   if (!TBB.succ_empty() || !FBB.succ_empty()) {<br>
-    if (SkipConditionalBranches) {<br>
-      while (!TEmpty && TIE->isBranch())<br>
-        shrinkInclusiveRange(TIB, TIE, TEmpty);<br>
-      while (!FEmpty && FIE->isBranch())<br>
-        shrinkInclusiveRange(FIB, FIE, FEmpty);<br>
-    } else {<br>
+    if (SkipUnconditionalBranches) {<br>
       while (!TEmpty && TIE->isUnconditionalBranch())<br>
         shrinkInclusiveRange(TIB, TIE, TEmpty);<br>
       while (!FEmpty && FIE->isUnconditionalBranch())<br>
@@ -657,7 +685,7 @@ static void countDuplicatedInstructions(<br>
   // If Dups1 includes all of a block, then don't count duplicate<br>
   // instructions at the end of the blocks.<br>
   if (TEmpty || FEmpty)<br>
-    return;<br>
+    return true;<br>
<br>
   // Count duplicate instructions at the ends of the blocks.<br>
   while (!TEmpty && !FEmpty) {<br>
@@ -668,19 +696,48 @@ static void countDuplicatedInstructions(<br>
       break;<br>
     if (!TIE->isIdenticalTo(*FIE))<br>
       break;<br>
-    // If we are trying to make sure the conditional branches are the same, we<br>
-    // still don't want to count them.<br>
-    if (SkipConditionalBranches || !TIE->isBranch())<br>
+    // We have to verify that any branch instructions are the same, and then we<br>
+    // don't count them toward the # of duplicate instructions.<br>
+    if (!TIE->isBranch())<br>
       ++Dups2;<br>
     shrinkInclusiveRange(TIB, TIE, TEmpty);<br>
     shrinkInclusiveRange(FIB, FIE, FEmpty);<br>
   }<br>
+  return true;<br>
+}<br>
+<br>
+/// RescanInstructions - Run ScanInstructions on a pair of blocks.<br>
+/// @param TIB - True Iterator Begin, points to first non-shared instruction<br>
+/// @param FIB - False Iterator Begin, points to first non-shared instruction<br>
+/// @param TIE - True Iterator End, points past last non-shared instruction<br>
+/// @param FIE - False Iterator End, points past last non-shared instruction<br>
+/// @param TrueBBI  - BBInfo to update for the true block.<br>
+/// @param FalseBBI - BBInfo to update for the false block.<br>
+/// @returns - false if either block cannot be predicated or if both blocks end<br>
+///   with a predicate-clobbering instruction.<br>
+bool IfConverter::RescanInstruction<wbr>s(<br>
+    MachineBasicBlock::iterator &TIB, MachineBasicBlock::iterator &FIB,<br>
+    MachineBasicBlock::iterator &TIE, MachineBasicBlock::iterator &FIE,<br>
+    BBInfo &TrueBBI, BBInfo &FalseBBI) const {<br>
+  bool BranchUnpredicable = true;<br>
+  TrueBBI.IsUnpredicable = FalseBBI.IsUnpredicable = false;<br>
+  ScanInstructions(TrueBBI, TIB, TIE, BranchUnpredicable);<br>
+  if (TrueBBI.IsUnpredicable)<br>
+    return false;<br>
+  ScanInstructions(FalseBBI, FIB, FIE, BranchUnpredicable);<br>
+  if (FalseBBI.IsUnpredicable)<br>
+    return false;<br>
+  if (TrueBBI.ClobbersPred && FalseBBI.ClobbersPred)<br>
+    return false;<br>
+  return true;<br>
 }<br>
<br>
 /// ValidDiamond - Returns true if the 'true' and 'false' blocks (along<br>
 /// with their common predecessor) forms a valid diamond shape for ifcvt.<br>
-bool IfConverter::ValidDiamond(BBIn<wbr>fo &TrueBBI, BBInfo &FalseBBI,<br>
-                               unsigned &Dups1, unsigned &Dups2) const {<br>
+bool IfConverter::ValidDiamond(<br>
+    BBInfo &TrueBBI, BBInfo &FalseBBI,<br>
+    unsigned &Dups1, unsigned &Dups2,<br>
+    BBInfo &TrueBBICalc, BBInfo &FalseBBICalc) const {<br>
   Dups1 = Dups2 = 0;<br>
   if (TrueBBI.IsBeingAnalyzed || TrueBBI.IsDone ||<br>
       FalseBBI.IsBeingAnalyzed || FalseBBI.IsDone)<br>
@@ -701,19 +758,33 @@ bool IfConverter::ValidDiamond(BBIn<wbr>fo &T<br>
     return false;<br>
<br>
   // FIXME: Allow true block to have an early exit?<br>
-  if (TrueBBI.FalseBB || FalseBBI.FalseBB ||<br>
-      (TrueBBI.ClobbersPred && FalseBBI.ClobbersPred))<br>
+  if (TrueBBI.FalseBB || FalseBBI.FalseBB)<br>
     return false;<br>
<br>
   // Count duplicate instructions at the beginning and end of the true and<br>
   // false blocks.<br>
+  // Skip unconditional branches only if we are considering an analyzable<br>
+  // diamond. Otherwise the branches must be the same.<br>
+  bool SkipUnconditionalBranches =<br>
+      TrueBBI.IsBrAnalyzable && FalseBBI.IsBrAnalyzable;<br>
   MachineBasicBlock::iterator TIB = TrueBBI.BB->begin();<br>
   MachineBasicBlock::iterator FIB = FalseBBI.BB->begin();<br>
   MachineBasicBlock::iterator TIE = TrueBBI.BB->end();<br>
   MachineBasicBlock::iterator FIE = FalseBBI.BB->end();<br>
-  countDuplicatedInstructions(TI<wbr>B, FIB, TIE, FIE, Dups1, Dups2,<br>
-                              *TrueBBI.BB, *FalseBBI.BB,<br>
-                              /* SkipConditionalBranches */ true);<br>
+  if(!CountDuplicatedInstruction<wbr>s(TIB, FIB, TIE, FIE, Dups1, Dups2,<br>
+                                  *TrueBBI.BB, *FalseBBI.BB,<br>
+                                  SkipUnconditionalBranches))<br>
+    return false;<br>
+<br>
+  TrueBBICalc.BB = TrueBBI.BB;<br>
+  FalseBBICalc.BB = FalseBBI.BB;<br>
+  if (!RescanInstructions(TIB, FIB, TIE, FIE, TrueBBICalc, FalseBBICalc))<br>
+    return false;<br>
+  // The size is used to decide whether to if-convert, and the shared portions<br>
+  // are subtracted off. Because of the subtraction, we just use the size that<br>
+  // was calculated by the original ScanInstructions, as it is correct.<br>
+  TrueBBICalc.NonPredSize = TrueBBI.NonPredSize;<br>
+  FalseBBICalc.NonPredSize = FalseBBI.NonPredSize;<br>
   return true;<br>
 }<br>
<br>
@@ -748,7 +819,8 @@ void IfConverter::AnalyzeBranches(B<wbr>BInfo<br>
 /// If so, the block is not predicable unless it's the last instruction.<br>
 void IfConverter::ScanInstructions(<wbr>BBInfo &BBI,<br>
                                    MachineBasicBlock::iterator &Begin,<br>
-                                   MachineBasicBlock::iterator &End) const {<br>
+                                   MachineBasicBlock::iterator &End,<br>
+                                   bool BranchUnpredicable) const {<br>
   if (BBI.IsDone || BBI.IsUnpredicable)<br>
     return;<br>
<br>
@@ -798,6 +870,11 @@ void IfConverter::ScanInstructions(<wbr>BBInf<br>
     bool isPredicated = TII->isPredicated(MI);<br>
     bool isCondBr = BBI.IsBrAnalyzable && MI.isConditionalBranch();<br>
<br>
+    if (BranchUnpredicable && MI.isBranch()) {<br>
+      BBI.IsUnpredicable = true;<br>
+      return;<br>
+    }<br>
+<br>
     // A conditional branch is not predicable, but it may be eliminated.<br>
     if (isCondBr)<br>
       continue;<br>
@@ -841,11 +918,22 @@ void IfConverter::ScanInstructions(<wbr>BBInf<br>
<br>
 /// Determine if the block is a suitable candidate to be predicated by the<br>
 /// specified predicate.<br>
+/// @param BBI BBInfo for the block to check<br>
+/// @param Pred Predicate array for the branch that leads to BBI<br>
+/// @param isTriangle true if the Analysis is for a triangle<br>
+/// @param RevBranch true if Reverse(Pred) leads to BBI (e.g. BBI is the false<br>
+///        case<br>
+/// @param hasCommonTail true if BBI shares a tail with a sibling block that<br>
+///        contains any instruction that would make the block unpredicable.<br>
 bool IfConverter::FeasibilityAnalys<wbr>is(BBInfo &BBI,<br>
                                       SmallVectorImpl<MachineOperan<wbr>d> &Pred,<br>
-                                      bool isTriangle, bool RevBranch) {<br>
+                                      bool isTriangle, bool RevBranch,<br>
+                                      bool hasCommonTail) {<br>
   // If the block is dead or unpredicable, then it cannot be predicated.<br>
-  if (BBI.IsDone || BBI.IsUnpredicable)<br>
+  // Two blocks may share a common unpredicable tail, but this doesn't prevent<br>
+  // them from being if-converted. The non-shared portion is assumed to have<br>
+  // been checked<br>
+  if (BBI.IsDone || (BBI.IsUnpredicable && !hasCommonTail))<br>
     return false;<br>
<br>
   // If it is already predicated but we couldn't analyze its terminator, the<br>
@@ -859,7 +947,7 @@ bool IfConverter::FeasibilityAnalys<wbr>is(BB<br>
   if (BBI.Predicate.size() && !TII->SubsumesPredicate(Pred, BBI.Predicate))<br>
     return false;<br>
<br>
-  if (BBI.BrCond.size()) {<br>
+  if (!hasCommonTail && BBI.BrCond.size()) {<br>
     if (!isTriangle)<br>
       return false;<br>
<br>
@@ -966,25 +1054,37 @@ void IfConverter::AnalyzeBlock(<br>
<br>
     BranchProbability Prediction = MBPI->getEdgeProbability(BB, TrueBBI.BB);<br>
<br>
-    if (CanRevCond && ValidDiamond(TrueBBI, FalseBBI, Dups, Dups2) &&<br>
+    if (CanRevCond) {<br>
+      BBInfo TrueBBICalc, FalseBBICalc;<br>
+      if (ValidDiamond(TrueBBI, FalseBBI, Dups, Dups2,<br>
+                       TrueBBICalc, FalseBBICalc) &&<br>
         MeetIfcvtSizeLimit(*TrueBBI.B<wbr>B, (TrueBBI.NonPredSize - (Dups + Dups2) +<br>
-                                         TrueBBI.ExtraCost), TrueBBI.ExtraCost2,<br>
+                                         TrueBBICalc.ExtraCost),<br>
+                           TrueBBICalc.ExtraCost2,<br>
                            *FalseBBI.BB, (FalseBBI.NonPredSize - (Dups + Dups2) +<br>
-                                        FalseBBI.ExtraCost),FalseBBI.E<wbr>xtraCost2,<br>
-                         Prediction) &&<br>
-        FeasibilityAnalysis(TrueBBI, BBI.BrCond) &&<br>
-        FeasibilityAnalysis(FalseBBI, RevCond)) {<br>
-      // Diamond:<br>
-      //   EBB<br>
-      //   / \_<br>
-      //  |   |<br>
-      // TBB FBB<br>
-      //   \ /<br>
-      //  TailBB<br>
-      // Note TailBB can be empty.<br>
-      Tokens.push_back(llvm::make_un<wbr>ique<IfcvtToken>(<br>
-          BBI, ICDiamond, TNeedSub | FNeedSub, Dups, Dups2));<br>
-      Enqueued = true;<br>
+                                          FalseBBICalc.ExtraCost),<br>
+                           FalseBBICalc.ExtraCost2,<br>
+                           Prediction) &&<br>
+        FeasibilityAnalysis(TrueBBI, BBI.BrCond,<br>
+                            /* IsTriangle */ false, /* RevCond */ false,<br>
+                            /* hasCommonTail */ true) &&<br>
+        FeasibilityAnalysis(FalseBBI, RevCond,<br>
+                            /* IsTriangle */ false, /* RevCond */ false,<br>
+                            /* hasCommonTail */ true)) {<br>
+        // Diamond:<br>
+        //   EBB<br>
+        //   / \_<br>
+        //  |   |<br>
+        // TBB FBB<br>
+        //   \ /<br>
+        //  TailBB<br>
+        // Note TailBB can be empty.<br>
+        Tokens.push_back(llvm::make_un<wbr>ique<IfcvtToken>(<br>
+                BBI, ICDiamond, TNeedSub | FNeedSub, Dups, Dups2,<br>
+                (bool) TrueBBICalc.ClobbersPred,<br>
+                (bool) FalseBBICalc.ClobbersPred));<br>
+        Enqueued = true;<br>
+      }<br>
     }<br>
<br>
     if (ValidTriangle(TrueBBI, FalseBBI, false, Dups, Prediction) &&<br>
@@ -1429,8 +1529,18 @@ bool IfConverter::IfConvertTriangle<wbr>(BBIn<br>
 }<br>
<br>
 /// If convert a diamond sub-CFG.<br>
+/// \p BBI is the head of the diamond<br>
+/// \p NumDups1 - number of shared instructions at the beginning of TrueBBI and<br>
+///               FalseBBI<br>
+/// \p NumDups2 - number of shared instructions at the end of TrueBBI and<br>
+///               FalseBBI<br>
+/// \p TClobbersPred - True if the true block clobbers the predicate in the<br>
+///                    non-shared portion.<br>
+/// \p TClobbersPred - True if the false block clobbers the predicate in the<br>
+///                    non-shared portion.<br>
 bool IfConverter::IfConvertDiamond(<wbr>BBInfo &BBI, IfcvtKind Kind,<br>
-                                   unsigned NumDups1, unsigned NumDups2) {<br>
+                                   unsigned NumDups1, unsigned NumDups2,<br>
+                                   bool TClobbersPred, bool FClobbersPred) {<br>
   BBInfo &TrueBBI  = BBAnalysis[BBI.TrueBB->getNumb<wbr>er()];<br>
   BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNum<wbr>ber()];<br>
   MachineBasicBlock *TailBB = TrueBBI.TrueBB;<br>
@@ -1468,9 +1578,9 @@ bool IfConverter::IfConvertDiamond(<wbr>BBInf<br>
<br>
   // Figure out the more profitable ordering.<br>
   bool DoSwap = false;<br>
-  if (TrueBBI.ClobbersPred && !FalseBBI.ClobbersPred)<br>
+  if (TClobbersPred && !FClobbersPred)<br>
     DoSwap = true;<br>
-  else if (TrueBBI.ClobbersPred == FalseBBI.ClobbersPred) {<br>
+  else if (TClobbersPred == FClobbersPred) {<br>
     if (TrueBBI.NonPredSize > FalseBBI.NonPredSize)<br>
       DoSwap = true;<br>
   }<br>
<br>
Modified: llvm/trunk/test/CodeGen/ARM/in<wbr>directbr-3.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/indirectbr-3.ll?rev=279670&r1=279669&r2=279670&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/llvm/trunk/test/CodeGen/<wbr>ARM/indirectbr-3.ll?rev=<wbr>279670&r1=279669&r2=279670&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/test/CodeGen/ARM/in<wbr>directbr-3.ll (original)<br>
+++ llvm/trunk/test/CodeGen/ARM/in<wbr>directbr-3.ll Wed Aug 24 16:34:24 2016<br>
@@ -1,4 +1,4 @@<br>
-; RUN: llc < %s -mtriple=thumbv7-apple-ios -arm-atomic-cfg-tidy=0 | FileCheck %s<br>
+; RUN: llc < %s -mtriple=thumbv7-apple-ios -arm-atomic-cfg-tidy=0 -stats 2>&1 | FileCheck %s<br>
<br>
 ; If ARMBaseInstrInfo::AnalyzeBlock<wbr>s returns the wrong value, which was possible<br>
 ; for blocks with indirect branches, the IfConverter could end up deleting<br>
@@ -9,9 +9,17 @@<br>
 define i32 @preserve_blocks(i32 %x) {<br>
 ; preserve_blocks:<br>
 ; CHECK: Block address taken<br>
-; CHECK: movs r0, #2<br>
 ; CHECK: movs r0, #1<br>
+; CHECK: Block address taken<br>
+; CHECK: movs r0, #2<br>
 ; CHECK-NOT: Address of block that was removed by CodeGen<br>
+<br>
+; Separate bug. There are no valid diamonds to if-convert in this file.<br>
+; There was a bug in the if-conversion code that would if-convert a false<br>
+; diamond where one side had a return and the other had an indirect branch.<br>
+; Make sure no diamond conversions occurred while compiling this file.<br>
+; CHECK: Statistics Collected<br>
+; CHECK-NOT: 1 ifcvt          - Number of diamond if-conversions performed<br>
 entry:<br>
   %c2 = icmp slt i32 %x, 3<br>
   %blockaddr = select i1 %c2, i8* blockaddress(@preserve_blocks, %ibt1), i8* blockaddress(@preserve_blocks, %ibt2)<br>
<br>
Added: llvm/trunk/test/CodeGen/Thumb2<wbr>/ifcvt-rescan-bug-2016-08-22.<wbr>ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb2/ifcvt-rescan-bug-2016-08-22.ll?rev=279670&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/llvm/trunk/test/CodeGen/<wbr>Thumb2/ifcvt-rescan-bug-2016-<wbr>08-22.ll?rev=279670&view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/test/CodeGen/Thumb2<wbr>/ifcvt-rescan-bug-2016-08-22.<wbr>ll (added)<br>
+++ llvm/trunk/test/CodeGen/Thumb2<wbr>/ifcvt-rescan-bug-2016-08-22.<wbr>ll Wed Aug 24 16:34:24 2016<br>
@@ -0,0 +1,36 @@<br>
+; RUN: llc -O2 -o - %s | FileCheck %s<br>
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:<wbr>128-a:0:32-n32-S64"<br>
+target triple = "thumbv7-unknown-linux-gnueabi<wbr>hf"<br>
+<br>
+; Function Attrs: argmemonly nounwind<br>
+declare void @llvm.lifetime.start(i64, i8* nocapture) #0<br>
+<br>
+; Function Attrs: nounwind<br>
+declare void @_ZNSaIcEC2Ev() unnamed_addr #0 align 2<br>
+<br>
+declare void @_ZNSsC1EPKcRKSaIcE() unnamed_addr #0<br>
+<br>
+; It isn't valid to If-Convert the following function, even though the calls<br>
+; are in common. The calls clobber the predicate info.<br>
+; CHECK: cbnz r{{[0-9]+}}, .LBB0_2<br>
+; CHECK: BB#1<br>
+; CHECK: .LBB0_2<br>
+; Function Attrs: nounwind<br>
+define hidden void @_ZN4llvm14DOTGraphTraitsIPNS_<wbr>13ScheduleDAGMIEE17getEdgeAttr<wbr>ibutesEPKNS_5SUnitENS_13SUnitI<wbr>teratorEPKNS_11ScheduleDAGE() #0 align 2 {<br>
+  br i1 undef, label %1, label %2<br>
+<br>
+; <label>:1:                                      ; preds = %0<br>
+  call void @_ZNSaIcEC2Ev() #0<br>
+  call void @_ZNSsC1EPKcRKSaIcE()<br>
+  br label %3<br>
+<br>
+; <label>:2:                                      ; preds = %0<br>
+  call void @llvm.lifetime.start(i64 1, i8* undef) #0<br>
+  call void @_ZNSaIcEC2Ev() #0<br>
+  br label %3<br>
+<br>
+; <label>:3:                                      ; preds = %2, %1<br>
+  ret void<br>
+}<br>
+<br>
+attributes #0 = { nounwind }<br>
<br>
<br>
______________________________<wbr>_________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/llvm-commits</a><br>
<br>
</blockquote>
<br></div></div><span class="HOEnZb"><font color="#888888">
-- <br>
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation<br>
</font></span></blockquote></div><br></div>