[llvm-commits] [llvm] r62487 - in /llvm/trunk: lib/Transforms/Utils/SimplifyCFG.cpp test/Transforms/SimplifyCFG/2009-01-18-PHIPropCrash.ll

Bill Wendling isanbard at gmail.com
Mon Jan 19 00:51:29 PST 2009


Chris,

This is causing a bootstrap failure in Release mode. Attached is  
the .i file that is generated. I temporarily reverted this patch.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: testcase.i
Type: application/octet-stream
Size: 737589 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20090119/589f5827/attachment.obj>
-------------- next part --------------



-bw

On Jan 18, 2009, at 6:46 PM, Chris Lattner wrote:

> Author: lattner
> Date: Sun Jan 18 20:46:28 2009
> New Revision: 62487
>
> URL: http://llvm.org/viewvc/llvm-project?rev=62487&view=rev
> Log:
> Fix PR3016, a bug which can occur do to an invalid assumption:
> we assumed a CFG structure that would be valid when all code in
> the function is reachable, but not all code is necessarily
> reachable.  Do a simple, but horrible, CFG walk to check for this
> case.
>
> Added:
>    llvm/trunk/test/Transforms/SimplifyCFG/2009-01-18-PHIPropCrash.ll
> Modified:
>    llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp
>
> Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp?rev=62487&r1=62486&r2=62487&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp (original)
> +++ llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Sun Jan 18  
> 20:46:28 2009
> @@ -21,6 +21,7 @@
> #include "llvm/Support/Debug.h"
> #include "llvm/Analysis/ConstantFolding.h"
> #include "llvm/Transforms/Utils/BasicBlockUtils.h"
> +#include "llvm/ADT/DenseMap.h"
> #include "llvm/ADT/SmallVector.h"
> #include "llvm/ADT/SmallPtrSet.h"
> #include "llvm/ADT/Statistic.h"
> @@ -172,6 +173,74 @@
>   return true;
> }
>
> +/// BlockIsReachableFrom - Return true if there is a path from  
> StartBB to
> +/// DestBB.  We do this by recursively walking the CFG from DestBB  
> up to StartBB
> +/// unwind we either reach StartBB or find an unreachable chunk of  
> the CFG.
> +///
> +/// Each entry in VisitedBlocks is either 0 -> not visited, 1 ->  
> known reachable
> +/// 2 -> known unreachable, 3 -> visitation in progress.
> +static bool BlockIsReachableFrom(BasicBlock *StartBB, BasicBlock  
> *DestBB,
> +                               DenseMap<BasicBlock*, unsigned>  
> &VisitedBlocks) {
> +  if (StartBB == DestBB) return true;
> +
> +  unsigned &BlockEntry = VisitedBlocks[DestBB];
> +  if (BlockEntry == 1) return true;       // Known reachable!
> +  if (BlockEntry == 2 ||                  // Known unreachable.
> +      BlockEntry == 3)                    // Found a loop.
> +    return false;
> +
> +  // If BlockEntry is 0, this is the first time we've seen this  
> block.  Mark it
> +  // as being visited and recurse up predecessors.
> +  BlockEntry = 3;
> +
> +  for (pred_iterator PI = pred_begin(DestBB), E = pred_end(DestBB);  
> PI != E;
> +       ++PI) {
> +    if (BlockIsReachableFrom(StartBB, *PI, VisitedBlocks)) {
> +      VisitedBlocks[DestBB] = 1;
> +      return true;
> +    }
> +  }
> +
> +  // If we scanned all of our predecessors and we couldn't find a  
> path to
> +  // StartBB, then this block must be unreachable for sure.  Record  
> this to
> +  // prevent visitation of this block in the future.
> +  VisitedBlocks[DestBB] = 2;
> +  return false;
> +}
> +
> +/// RemoveUnreachableUsersOf - For each user of Inst, scan up the  
> CFG until we
> +/// find Inst.  If Inst is found, then the user is live, otherwise  
> it is dead.
> +/// Remove dead users.  This is basically a poor-man's dominance  
> query, and is
> +/// worst-case linear time in the number of blocks in the function.
> +static void RemoveUnreachableUsersOf(Instruction *Inst) {
> +  DenseMap<BasicBlock*, unsigned> VisitedBlocks;
> +
> +  BasicBlock *InstBB = Inst->getParent();
> +  for (Instruction::use_iterator UI = Inst->use_begin(), E = Inst- 
> >use_end();
> +       UI != E;) {
> +    Instruction *User = cast<Instruction>(*UI);
> +    Use &TheUse = UI.getUse();
> +
> +    if (PHINode *PN = dyn_cast<PHINode>(User)) {
> +      unsigned UseOp = UI.getOperandNo();
> +      ++UI;
> +
> +      if (BlockIsReachableFrom(InstBB, PN->getIncomingBlock(UseOp/2),
> +                               VisitedBlocks))
> +        continue;
> +    } else {
> +      ++UI;
> +      if (BlockIsReachableFrom(InstBB, User->getParent(),
> +                               VisitedBlocks))
> +        continue;
> +    }
> +    // If there is no path from Inst to this User, then this user  
> is in dead
> +    // code.  Just replace uses of Inst with undef.
> +    TheUse = UndefValue::get(Inst->getType());
> +  }
> +}
> +
> +
> /// TryToSimplifyUncondBranchFromEmptyBlock - BB contains an  
> unconditional
> /// branch to Succ, and contains no instructions other than PHI  
> nodes and the
> /// branch.  If possible, eliminate BB.
> @@ -216,12 +285,18 @@
>   }
>
>   if (isa<PHINode>(&BB->front())) {
> -    SmallVector<BasicBlock*, 16>
> -    OldSuccPreds(pred_begin(Succ), pred_end(Succ));
> +    SmallVector<BasicBlock*, 16> OldSuccPreds(pred_begin(Succ),
> +                                              pred_end(Succ));
>
>     // Move all PHI nodes in BB to Succ if they are alive, otherwise
>     // delete them.
>     while (PHINode *PN = dyn_cast<PHINode>(&BB->front())) {
> +      // The algorithm below will not work if there are users of PN  
> that are in
> +      // unreachable blocks.  These users will not be properly  
> dominated by the
> +      // instruction, but the IR is valid because dead code does  
> not need to
> +      // obey dominance properties.
> +      RemoveUnreachableUsersOf(PN);
> +
>       if (PN->use_empty()) {
>         // Just remove the dead phi.  This happens if Succ's PHIs  
> were the only
>         // users of the PHI nodes.
>
> Added: llvm/trunk/test/Transforms/SimplifyCFG/2009-01-18- 
> PHIPropCrash.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimplifyCFG/2009-01-18-PHIPropCrash.ll?rev=62487&view=auto
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/test/Transforms/SimplifyCFG/2009-01-18- 
> PHIPropCrash.ll (added)
> +++ llvm/trunk/test/Transforms/SimplifyCFG/2009-01-18- 
> PHIPropCrash.ll Sun Jan 18 20:46:28 2009
> @@ -0,0 +1,30 @@
> +; RUN: llvm-as < %s | opt -simplifycfg | llvm-dis
> +; PR3016
> +; Dead use caused invariant violation.
> +
> +define i32 @func_105(i1 %tmp5, i1 %tmp7) nounwind {
> +BB:
> +	br i1 true, label %BB2, label %BB1
> +
> +BB1:		; preds = %BB
> +	br label %BB2
> +
> +BB2:		; preds = %BB1, %BB
> +	%tmp3 = phi i1 [ true, %BB ], [ false, %BB1 ]		; <i1> [#uses=1]
> +	br label %BB9
> +
> +BB9:		; preds = %BB11, %BB2
> +	%tmp10 = phi i32 [ 0, %BB2 ], [ %tmp12, %BB11 ]		; <i32> [#uses=1]
> +	br i1 %tmp5, label %BB11, label %BB13
> +
> +BB11:		; preds = %BB13, %BB9
> +	%tmp12 = phi i32 [ 0, %BB13 ], [ %tmp10, %BB9 ]		; <i32> [#uses=2]
> +	br i1 %tmp3, label %BB9, label %BB20
> +
> +BB13:		; preds = %BB13, %BB9
> +	%tmp14 = phi i32 [ 0, %BB9 ], [ %tmp14, %BB13 ]		; <i32> [#uses=1]
> +	br i1 %tmp7, label %BB13, label %BB11
> +
> +BB20:		; preds = %BB11
> +	ret i32 %tmp12
> +}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits



More information about the llvm-commits mailing list