[llvm] r279670 - IfConversion: Rescan diamonds.

Krzysztof Parzyszek via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 26 08:17:29 PDT 2016


Hi Kyle,
This commit seems to cause a crash on Hexagon:

--- if-crash.ll ---
target triple = "hexagon"

%struct.0 = type { i16, i16 }

@t = external local_unnamed_addr global %struct.0, align 2

define void @foo(i32 %p) local_unnamed_addr #0 {
entry:
   %conv90 = trunc i32 %p to i16
   %call105 = call signext i16 @bar(i16 signext 16384, i16 signext undef) #0
   %call175 = call signext i16 @bar(i16 signext %conv90, i16 signext 4) #0
   %call197 = call signext i16 @bar(i16 signext %conv90, i16 signext 4) #0
   %cmp199 = icmp eq i16 %call197, 0
   br i1 %cmp199, label %if.then200, label %if.else201

if.then200:                                       ; preds = %entry
   store i16 4, i16* getelementptr inbounds (%struct.0, %struct.0* @t, 
i32 0, i32 0), align 2
   store i16 0, i16* getelementptr inbounds (%struct.0, %struct.0* @t, 
i32 0, i32 1), align 2
   br label %if.end202

if.else201:                                       ; preds = %entry
   store i16 3, i16* getelementptr inbounds (%struct.0, %struct.0* @t, 
i32 0, i32 0), align 2
   br label %if.end202

if.end202:                                        ; preds = %if.else201, 
%if.then200
   ret void
}

declare signext i16 @bar(i16 signext, i16 signext) local_unnamed_addr #0

attributes #0 = { optsize "target-cpu"="hexagonv55" }
-------------------


$ llc -march=hexagon < if-crash.ll


llc: lib/Target/Hexagon/HexagonInstrInfo.cpp:1374: virtual bool 
llvm::HexagonInstrInfo::PredicateInstruction(llvm::MachineInstr &, 
ArrayRef<llvm::MachineOperand>) const: Assertion `isPredicable(MI) && 
"Expected predicable instruction"' failed.


-Krzysztof


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

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, 
hosted by The Linux Foundation


More information about the llvm-commits mailing list